Skip to content

Commit

Permalink
fix(modeling): fix line2.closestPoint
Browse files Browse the repository at this point in the history
  • Loading branch information
platypii authored Apr 8, 2023
1 parent fc4ceef commit 4419fe5
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 24 deletions.
20 changes: 7 additions & 13 deletions packages/modeling/src/maths/line2/closestPoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,14 @@ const origin = require('./origin')
* @alias module:modeling/maths/line2.closestPoint
*/
const closestPoint = (line, point) => {
// linear function of AB
const a = origin(line)
const b = direction(line)
const m1 = (b[1] - a[1]) / (b[0] - a[0])
const t1 = a[1] - m1 * a[0]
// linear function of PC
const m2 = -1 / m1 // perpendicular
const t2 = point[1] - m2 * point[0]
// c.x * m1 + t1 === c.x * m2 + t2
const x = (t2 - t1) / (m1 - m2)
const y = m1 * x + t1
const orig = origin(line)
const dir = direction(line)

const closest = vec2.fromValues(x, y)
return closest
const v = vec2.subtract(vec2.create(), point, orig)
const dist = vec2.dot(v, dir)
vec2.scale(v, dir, dist)
vec2.add(v, v, orig)
return v
}

module.exports = closestPoint
28 changes: 17 additions & 11 deletions packages/modeling/src/maths/line2/closestPoint.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,35 @@ test('line2: closestPoint() should return proper values', (t) => {

const line2 = fromPoints(create(), [-5, 5], [5, -5])
const x4 = closestPoint(line2, [0, 0])
t.true(compareVectors(x4, [0.000000000000, 0.000000000000]))
t.true(compareVectors(x4, [0, 0]))
const x5 = closestPoint(line2, [1, 0])
t.true(compareVectors(x5, [0.500000000000, -0.500000000000]))
t.true(compareVectors(x5, [0.5, -0.5]))
const x6 = closestPoint(line2, [2, 0])
t.true(compareVectors(x6, [1.000000000000, -1.000000000000]))
t.true(compareVectors(x6, [1, -1]))
const x7 = closestPoint(line2, [3, 0])
t.true(compareVectors(x7, [1.500000000000, -1.500000000000]))
t.true(compareVectors(x7, [1.5, -1.5]))
const x8 = closestPoint(line2, [4, 0])
t.true(compareVectors(x8, [2.000000000000, -2.000000000000]))
t.true(compareVectors(x8, [2, -2]))
const x9 = closestPoint(line2, [5, 0])
t.true(compareVectors(x9, [2.500000000000, -2.500000000000]))
t.true(compareVectors(x9, [2.5, -2.5]))
const x10 = closestPoint(line2, [50, 0])
t.true(compareVectors(x10, [25.000000000000, -25.000000000000]))
t.true(compareVectors(x10, [25, -25]))

const ya = closestPoint(line2, [-5, 5])
t.true(compareVectors(ya, [-5.000000000000, 5.000000000000]))
t.true(compareVectors(ya, [-5, 5]))
const yb = closestPoint(line2, [5, -5])
t.true(compareVectors(yb, [5.000000000000, -5.000000000000]))
t.true(compareVectors(yb, [5, -5]))

const za = closestPoint(line2, [4, -6])
t.true(compareVectors(za, [5.000000000000, -5.000000000000]))
t.true(compareVectors(za, [5, -5]))
const zb = closestPoint(line2, [3, -7])
t.true(compareVectors(zb, [5.000000000000, -5.000000000000]))
t.true(compareVectors(zb, [5, -5]))

t.true(true)
})

test('line2: closestPoint() should return proper values (issue #1225)', (t) => {
const line = fromPoints(create(), [10, 0], [0, 10])
const closest = closestPoint(line, [0, 0])
t.true(compareVectors(closest, [5, 5]))
})
4 changes: 4 additions & 0 deletions packages/modeling/src/maths/line2/direction.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,8 @@ test('line2: direction() should return proper direction', (t) => {
const line5 = fromPoints(create(), [-5, 5], [5, -5])
const dir5 = direction(line5)
t.true(compareVectors(dir5, [0.7071067811865475, -0.7071067811865475]))

const line6 = fromPoints(create(), [10, 0], [0, 10])
const dir6 = direction(line6)
t.true(compareVectors(dir6, [-0.7071067811865475, 0.7071067811865475]))
})
1 change: 1 addition & 0 deletions packages/modeling/src/maths/line2/origin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const vec2 = require('../vec2')

/**
* Return the origin of the given line.
* The origin is the point on the line which is closest to the origin [0, 0].
*
* @param {line2} line - line of reference
* @return {vec2} the origin of the line
Expand Down
4 changes: 4 additions & 0 deletions packages/modeling/src/maths/line2/origin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ test('line2: origin() should return proper origins', (t) => {
const line5 = fromPoints(create(), [-5, 5], [5, -5])
const org5 = origin(line5)
t.true(compareVectors(org5, [0, 0]))

const line6 = fromPoints(create(), [10, 0], [0, 10])
const org6 = origin(line6)
t.true(compareVectors(org6, [5, 5]))
})

0 comments on commit 4419fe5

Please sign in to comment.