diff --git a/archive/line-segment-intersection-try.ts b/archive/line-segment-intersection-try.ts
new file mode 100644
index 0000000..6e46a90
--- /dev/null
+++ b/archive/line-segment-intersection-try.ts
@@ -0,0 +1,62 @@
+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;
+}
diff --git a/src/components/grid/grid.tsx b/src/components/grid/grid.tsx
index 76efad1..e0fd982 100644
--- a/src/components/grid/grid.tsx
+++ b/src/components/grid/grid.tsx
@@ -11,8 +11,6 @@ import {
import './grid.scss';
-import * as mathjs from 'mathjs';
-
import * as lodash from 'lodash';
import { useRecoilValue } from 'recoil';
import { drawModeState, lineColorState } from '../../atoms';
@@ -37,57 +35,24 @@ interface Line {
stroke: string;
}
+// https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
+// https://stackoverflow.com/questions/9043805/test-if-two-lines-intersect-javascript-function
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;
- }
+ const determinant =
+ (l0.x1 - l0.x0) * (l1.y1 - l1.y0) - (l1.x1 - l1.x0) * (l0.y1 - l0.y0);
+ if (determinant === 0) {
+ // full lines have no intersection (they must be parallel)
+ 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;
+ const lambda =
+ ((l1.y1 - l1.y0) * (l1.x1 - l0.x0) +
+ (l1.x0 - l1.x1) * (l1.y1 - l0.y0)) /
+ determinant;
+ const gamma =
+ ((l0.y0 - l0.y1) * (l1.x1 - l0.x0) +
+ (l0.x1 - l0.x0) * (l1.y1 - l0.y0)) /
+ determinant;
+ return 0 < lambda && lambda < 1 && 0 < gamma && gamma < 1;
}
function pointsToRange(p0: Point, p1: Point): Range {
@@ -198,7 +163,10 @@ const Grid: FC = () => {
setUserRedoLines([]);
- if (lodash.isEqual(userStartPoint, point)) return;
+ if (lodash.isEqual(userStartPoint, point)) {
+ setUserStartPoint(null);
+ return;
+ }
if (lodash.isNull(userStartPoint)) {
setUserStartPoint(point);
return;
@@ -295,16 +263,31 @@ const Grid: FC = () => {
const userLineIndicatorElement = useMemo(() => {
if (lodash.isNull(userStartPoint)) return null;
const point = snapToGrid(mousePoint, GAP);
- return (
-
- );
+ if (userDrawMode === 'line') {
+ return (
+
+ );
+ } else {
+ console.assert(userDrawMode === 'trash');
+ return (
+
+ );
+ }
}, [userStartPoint, mousePoint]);
const userPointIndicatorElement = useMemo(() => {
const point = snapToGrid(mousePoint, GAP);