mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Line and segment intersection
This commit is contained in:
parent
f347281c21
commit
b7f504796b
3 changed files with 157 additions and 29 deletions
|
@ -1,5 +1,6 @@
|
|||
import { pointCenter, pointRotateRads } from "./point";
|
||||
import type { GenericPoint, Line, Radians } from "./types";
|
||||
import { point, pointCenter, pointRotateRads } from "./point";
|
||||
import { segmentIncludesPoint } from "./segment";
|
||||
import type { GenericPoint, Line, Radians, Segment } from "./types";
|
||||
|
||||
/**
|
||||
* Create a line from two points.
|
||||
|
@ -40,13 +41,55 @@ export function lineFromPointArray<P extends GenericPoint>(
|
|||
|
||||
// return the coordinates resulting from rotating the given line about an origin by an angle in degrees
|
||||
// note that when the origin is not given, the midpoint of the given line is used as the origin
|
||||
export const lineRotate = <Point extends GenericPoint>(
|
||||
export function lineRotate<Point extends GenericPoint>(
|
||||
l: Line<Point>,
|
||||
angle: Radians,
|
||||
origin?: Point,
|
||||
): Line<Point> => {
|
||||
): Line<Point> {
|
||||
return line(
|
||||
pointRotateRads(l[0], origin || pointCenter(l[0], l[1]), angle),
|
||||
pointRotateRads(l[1], origin || pointCenter(l[0], l[1]), angle),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the intersection point of two infinite lines, if any
|
||||
*
|
||||
* @param a One of the line to intersect
|
||||
* @param b Another line to intersect
|
||||
* @returns The intersection point
|
||||
*/
|
||||
export function lineIntersectsLine<Point extends GenericPoint>(
|
||||
[[x1, y1], [x2, y2]]: Line<Point>,
|
||||
[[x3, y3], [x4, y4]]: Line<Point>,
|
||||
): Point | null {
|
||||
const a = x1 * y2 - x2 * y1;
|
||||
const c = x3 * y4 - x4 * y3;
|
||||
const den = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
|
||||
if (den === 0) {
|
||||
return null;
|
||||
}
|
||||
const xnum = a * (x3 - x4) - (x1 - x2) * c;
|
||||
const ynum = a * (y3 - y4) - (y1 - y2) * c;
|
||||
|
||||
return point<Point>(xnum / den, ynum / den);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the intersection point of a segment and a line
|
||||
*
|
||||
* @param l
|
||||
* @param s
|
||||
* @returns
|
||||
*/
|
||||
export function lineIntersectsSegment<Point extends GenericPoint>(
|
||||
l: Line<Point>,
|
||||
s: Segment<Point>,
|
||||
): Point | null {
|
||||
const candidate = lineIntersectsLine(l, line(s[0], s[1]));
|
||||
if (!candidate || !segmentIncludesPoint(candidate, s)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return candidate;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue