mirror of
				https://github.com/excalidraw/excalidraw.git
				synced 2025-10-31 19:04:35 +01:00 
			
		
		
		
	 88a2b286c7
			
		
	
	88a2b286c7
	
	
	
		
			
			* feat: move utils to utils package and make @excalidraw/utils a workspace * remove esm and update types path * remove esm script * fix package.json and yarn.lock * update path * fix * fix lint and test
		
			
				
	
	
		
			66 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			66 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { Bounds } from "../excalidraw/element/bounds";
 | |
| import { Point } from "../excalidraw/types";
 | |
| 
 | |
| export type LineSegment = [Point, Point];
 | |
| 
 | |
| export function getBBox(line: LineSegment): Bounds {
 | |
|   return [
 | |
|     Math.min(line[0][0], line[1][0]),
 | |
|     Math.min(line[0][1], line[1][1]),
 | |
|     Math.max(line[0][0], line[1][0]),
 | |
|     Math.max(line[0][1], line[1][1]),
 | |
|   ];
 | |
| }
 | |
| 
 | |
| export function crossProduct(a: Point, b: Point) {
 | |
|   return a[0] * b[1] - b[0] * a[1];
 | |
| }
 | |
| 
 | |
| export function doBBoxesIntersect(a: Bounds, b: Bounds) {
 | |
|   return a[0] <= b[2] && a[2] >= b[0] && a[1] <= b[3] && a[3] >= b[1];
 | |
| }
 | |
| 
 | |
| export function translate(a: Point, b: Point): Point {
 | |
|   return [a[0] - b[0], a[1] - b[1]];
 | |
| }
 | |
| 
 | |
| const EPSILON = 0.000001;
 | |
| 
 | |
| export function isPointOnLine(l: LineSegment, p: Point) {
 | |
|   const p1 = translate(l[1], l[0]);
 | |
|   const p2 = translate(p, l[0]);
 | |
| 
 | |
|   const r = crossProduct(p1, p2);
 | |
| 
 | |
|   return Math.abs(r) < EPSILON;
 | |
| }
 | |
| 
 | |
| export function isPointRightOfLine(l: LineSegment, p: Point) {
 | |
|   const p1 = translate(l[1], l[0]);
 | |
|   const p2 = translate(p, l[0]);
 | |
| 
 | |
|   return crossProduct(p1, p2) < 0;
 | |
| }
 | |
| 
 | |
| export function isLineSegmentTouchingOrCrossingLine(
 | |
|   a: LineSegment,
 | |
|   b: LineSegment,
 | |
| ) {
 | |
|   return (
 | |
|     isPointOnLine(a, b[0]) ||
 | |
|     isPointOnLine(a, b[1]) ||
 | |
|     (isPointRightOfLine(a, b[0])
 | |
|       ? !isPointRightOfLine(a, b[1])
 | |
|       : isPointRightOfLine(a, b[1]))
 | |
|   );
 | |
| }
 | |
| 
 | |
| // https://martin-thoma.com/how-to-check-if-two-line-segments-intersect/
 | |
| export function doLineSegmentsIntersect(a: LineSegment, b: LineSegment) {
 | |
|   return (
 | |
|     doBBoxesIntersect(getBBox(a), getBBox(b)) &&
 | |
|     isLineSegmentTouchingOrCrossingLine(a, b) &&
 | |
|     isLineSegmentTouchingOrCrossingLine(b, a)
 | |
|   );
 | |
| }
 |