# Conflicts:
#	packages/math/package.json
#	yarn.lock
This commit is contained in:
feng 2025-04-12 20:44:11 +09:00
commit 671865a141
396 changed files with 8688 additions and 4581 deletions

View file

@ -17,5 +17,3 @@ With PNPM, similarly install the package with this command:
```bash
pnpm add @excalidraw/math
```
## API

View file

@ -2,17 +2,18 @@
"name": "@excalidraw/math",
"version": "0.1.0",
"type": "module",
"types": "./dist/types/math/index.d.ts",
"types": "./dist/types/math/src/index.d.ts",
"main": "./dist/prod/index.js",
"module": "./dist/prod/index.js",
"exports": {
".": {
"types": "./dist/types/math/src/index.d.ts",
"development": "./dist/dev/index.js",
"production": "./dist/prod/index.js",
"default": "./dist/prod/index.js"
},
"./*": {
"types": "./../math/dist/types/math/*"
"types": "./../math/dist/types/math/src/*.d.ts"
}
},
"files": [
@ -53,8 +54,8 @@
"bugs": "https://github.com/excalidraw/excalidraw/issues",
"repository": "https://github.com/excalidraw/excalidraw",
"scripts": {
"gen:types": "rimraf -rf types && tsc",
"build:esm": "rimraf -rf dist && node ../../scripts/buildMath.js && yarn gen:types"
"gen:types": "rimraf types && tsc",
"build:esm": "rimraf dist && node ../../scripts/buildBase.js && yarn gen:types"
},
"devDependencies": {
"rimraf": "6.0.1"

View file

@ -1,8 +1,9 @@
import type { Bounds } from "@excalidraw/element/bounds";
import { isPoint, pointDistance, pointFrom } from "./point";
import { rectangle, rectangleIntersectLineSegment } from "./rectangle";
import type { Curve, GlobalPoint, LineSegment, LocalPoint } from "./types";
import type { Bounds } from "../excalidraw/element/bounds";
/**
*

View file

@ -97,7 +97,7 @@ export function pointsEqual<Point extends GlobalPoint | LocalPoint>(
}
/**
* Roate a point by [angle] radians.
* Rotate a point by [angle] radians.
*
* @param point The point to rotate
* @param center The point to rotate around, the center point
@ -116,7 +116,7 @@ export function pointRotateRads<Point extends GlobalPoint | LocalPoint>(
}
/**
* Roate a point by [angle] degree.
* Rotate a point by [angle] degree.
*
* @param point The point to rotate
* @param center The point to rotate around, the center point

View file

@ -41,6 +41,34 @@ export const polygonIncludesPoint = <Point extends LocalPoint | GlobalPoint>(
return inside;
};
export const polygonIncludesPointNonZero = <Point extends [number, number]>(
point: Point,
polygon: Point[],
): boolean => {
const [x, y] = point;
let windingNumber = 0;
for (let i = 0; i < polygon.length; i++) {
const j = (i + 1) % polygon.length;
const [xi, yi] = polygon[i];
const [xj, yj] = polygon[j];
if (yi <= y) {
if (yj > y) {
if ((xj - xi) * (y - yi) - (x - xi) * (yj - yi) > 0) {
windingNumber++;
}
}
} else if (yj <= y) {
if ((xj - xi) * (y - yi) - (x - xi) * (yj - yi) < 0) {
windingNumber--;
}
}
}
return windingNumber !== 0;
};
export const pointOnPolygon = <Point extends LocalPoint | GlobalPoint>(
p: Point,
poly: Polygon<Point>,

View file

@ -1,4 +1,4 @@
import { toBrandedType } from "@excalidraw/excalidraw/utils";
import { toBrandedType } from "@excalidraw/common";
import type { InclusiveRange } from "./types";

View file

@ -160,13 +160,17 @@ export const distanceToLineSegment = <Point extends LocalPoint | GlobalPoint>(
*/
export function lineSegmentIntersectionPoints<
Point extends GlobalPoint | LocalPoint,
>(l: LineSegment<Point>, s: LineSegment<Point>): Point | null {
>(
l: LineSegment<Point>,
s: LineSegment<Point>,
threshold?: number,
): Point | null {
const candidate = linesIntersectAt(line(l[0], l[1]), line(s[0], s[1]));
if (
!candidate ||
!pointOnLineSegment(candidate, s) ||
!pointOnLineSegment(candidate, l)
!pointOnLineSegment(candidate, s, threshold) ||
!pointOnLineSegment(candidate, l, threshold)
) {
return null;
}

View file

@ -1,13 +1,13 @@
import "../utils/test-utils";
import "@excalidraw/utils/test-utils";
import {
curve,
curveClosestPoint,
curveIntersectLineSegment,
curvePointDistance,
} from "./curve";
import { pointFrom } from "./point";
import { lineSegment } from "./segment";
} from "../src/curve";
import { pointFrom } from "../src/point";
import { lineSegment } from "../src/segment";
describe("Math curve", () => {
describe("line segment intersection", () => {

View file

@ -4,12 +4,12 @@ import {
ellipseIncludesPoint,
ellipseTouchesPoint,
ellipseLineIntersectionPoints,
} from "./ellipse";
import { line } from "./line";
import { pointFrom } from "./point";
import { lineSegment } from "./segment";
} from "../src/ellipse";
import { line } from "../src/line";
import { pointFrom } from "../src/point";
import { lineSegment } from "../src/segment";
import type { Ellipse, GlobalPoint } from "./types";
import type { Ellipse, GlobalPoint } from "../src/types";
describe("point and ellipse", () => {
it("point on ellipse", () => {

View file

@ -1,5 +1,5 @@
import { line, linesIntersectAt } from "./line";
import { pointFrom } from "./point";
import { line, linesIntersectAt } from "../src/line";
import { pointFrom } from "../src/point";
describe("line-line intersections", () => {
it("should correctly detect intersection at origin", () => {

View file

@ -1,6 +1,6 @@
import { pointFrom, pointRotateRads } from "./point";
import { pointFrom, pointRotateRads } from "../src/point";
import type { Radians } from "./types";
import type { Radians } from "../src/types";
describe("rotate", () => {
it("should rotate over (x2, y2) and return the rotated coordinates for (x1, y1)", () => {

View file

@ -1,4 +1,4 @@
import { rangeInclusive, rangeIntersection, rangesOverlap } from "./range";
import { rangeInclusive, rangeIntersection, rangesOverlap } from "../src/range";
describe("range overlap", () => {
const range1_4 = rangeInclusive(1, 4);

View file

@ -1,5 +1,5 @@
import { pointFrom } from "./point";
import { lineSegment, lineSegmentIntersectionPoints } from "./segment";
import { pointFrom } from "../src/point";
import { lineSegment, lineSegmentIntersectionPoints } from "../src/segment";
describe("line-segment intersections", () => {
it("should correctly detect intersection", () => {

View file

@ -1,4 +1,4 @@
import { isVector } from ".";
import { isVector } from "../src/vector";
describe("Vector", () => {
test("isVector", () => {

View file

@ -1,24 +1,8 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist/types",
"target": "ESNext",
"strict": true,
"skipLibCheck": true,
"declaration": true,
"allowSyntheticDefaultImports": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"jsx": "react-jsx",
"emitDeclarationOnly": true,
"paths": {
"@excalidraw/excalidraw": ["../excalidraw/index.tsx"],
"@excalidraw/utils": ["../utils/index.ts"],
"@excalidraw/math": ["../math/index.ts"],
"@excalidraw/excalidraw/*": ["../excalidraw/*"],
"@excalidraw/utils/*": ["../utils/*"],
"@excalidraw/math/*": ["../math/*"]
}
"outDir": "./dist/types"
},
"include": ["src/**/*", "global.d.ts"],
"exclude": ["**/*.test.*", "tests", "types", "examples", "dist"]
}