diff --git a/packages/modeling/src/maths/line2/closestPoint.js b/packages/modeling/src/maths/line2/closestPoint.js index c49fa796b..2f9cdc4b2 100644 --- a/packages/modeling/src/maths/line2/closestPoint.js +++ b/packages/modeling/src/maths/line2/closestPoint.js @@ -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 diff --git a/packages/modeling/src/maths/line2/closestPoint.test.js b/packages/modeling/src/maths/line2/closestPoint.test.js index 49930e3c7..44b08bd9c 100644 --- a/packages/modeling/src/maths/line2/closestPoint.test.js +++ b/packages/modeling/src/maths/line2/closestPoint.test.js @@ -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])) +}) diff --git a/packages/modeling/src/maths/line2/direction.test.js b/packages/modeling/src/maths/line2/direction.test.js index 34dfb18eb..52775a3e7 100644 --- a/packages/modeling/src/maths/line2/direction.test.js +++ b/packages/modeling/src/maths/line2/direction.test.js @@ -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])) }) diff --git a/packages/modeling/src/maths/line2/origin.js b/packages/modeling/src/maths/line2/origin.js index 3dc85e99a..fe1fcdc0c 100644 --- a/packages/modeling/src/maths/line2/origin.js +++ b/packages/modeling/src/maths/line2/origin.js @@ -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 diff --git a/packages/modeling/src/maths/line2/origin.test.js b/packages/modeling/src/maths/line2/origin.test.js index db01891c7..451292ddc 100644 --- a/packages/modeling/src/maths/line2/origin.test.js +++ b/packages/modeling/src/maths/line2/origin.test.js @@ -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])) })