63 lines
1.9 KiB
TypeScript
63 lines
1.9 KiB
TypeScript
import * as mathjs from 'mathjs';
|
|
|
|
interface Range {
|
|
x0: number;
|
|
y0: number;
|
|
x1: number;
|
|
y1: number;
|
|
}
|
|
|
|
// my first attempt at this
|
|
function lineSegmentIntersection(l0: Range, l1: Range): boolean {
|
|
// convert to y = mx + b
|
|
const m0 = mathjs.fraction(l0.y1 - l0.y0, l0.x1 - l0.x0);
|
|
const m1 = mathjs.fraction(l1.y1 - l1.y0, l1.x1 - l1.x0);
|
|
|
|
const b0 = mathjs.subtract(l0.y0, mathjs.multiply(m0, l0.x0));
|
|
const b1 = mathjs.subtract(l1.y1, mathjs.multiply(m1, l1.x1));
|
|
|
|
if (mathjs.equal(m0, m1)) {
|
|
if (mathjs.equal(b0, b1)) {
|
|
// parallel lines with equal intersect
|
|
return (
|
|
(l1.x0 >= l0.x0 && l1.x0 <= l0.x1) ||
|
|
(l1.x1 >= l1.x0 && l1.x1 <= l1.x1)
|
|
);
|
|
} else {
|
|
// parallel lines with different y-intersect will never intersect
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// solve for l0 = l1
|
|
const M = mathjs.subtract(m0, m1);
|
|
const B = mathjs.subtract(b0, b1);
|
|
|
|
// MX + B = 0 -> X = -B/M
|
|
const X = mathjs.divide(mathjs.unaryMinus(B), M);
|
|
const X_num = mathjs.number(X as mathjs.Fraction);
|
|
|
|
const intersects =
|
|
X_num >= Math.min(l0.x0, l0.x1) &&
|
|
X_num <= Math.max(l0.x0, l0.x1) &&
|
|
X_num >= Math.min(l1.x0, l1.x1) &&
|
|
X_num <= Math.max(l1.x0, l1.x1);
|
|
|
|
// const Y = mathjs.add(mathjs.multiply(m0, X), b0);
|
|
// const Y_num = mathjs.number(Y as mathjs.Fraction);
|
|
// if (intersects) {
|
|
// console.log('intersects at', X_num, Y_num);
|
|
// } else {
|
|
// console.log('would have intersected at', X_num, Y_num, l0, l1);
|
|
// }
|
|
|
|
// to test
|
|
// useEffect(() => {
|
|
// const l0 = { x0: 2, y0: 8, x1: 6, y1: 5, stroke: '' };
|
|
// const l1 = { x0: 3, y0: 9, x1: 7, y1: 8, stroke: '' };
|
|
// console.log('intersection:', l0, l1, lineSegmentIntersection(l0, l1));
|
|
// }, []);
|
|
|
|
return intersects;
|
|
}
|