mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Refactoring points
Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
parent
8ca4cf3260
commit
b4cb314090
40 changed files with 746 additions and 783 deletions
|
@ -4,7 +4,7 @@ import {
|
|||
pointOnEllipse,
|
||||
type GeometricShape,
|
||||
} from "./geometry/shape";
|
||||
import type { Curve } from "../math";
|
||||
import type { Curve, ViewportPoint } from "../math";
|
||||
import {
|
||||
lineSegment,
|
||||
point,
|
||||
|
@ -18,7 +18,9 @@ import {
|
|||
} from "../math";
|
||||
|
||||
// check if the given point is considered on the given shape's border
|
||||
export const isPointOnShape = <Point extends GlobalPoint | LocalPoint>(
|
||||
export const isPointOnShape = <
|
||||
Point extends GlobalPoint | LocalPoint | ViewportPoint,
|
||||
>(
|
||||
point: Point,
|
||||
shape: GeometricShape<Point>,
|
||||
tolerance = 0,
|
||||
|
@ -45,21 +47,21 @@ export const isPointOnShape = <Point extends GlobalPoint | LocalPoint>(
|
|||
|
||||
// check if the given point is considered inside the element's border
|
||||
export const isPointInShape = <Point extends GlobalPoint | LocalPoint>(
|
||||
point: Point,
|
||||
p: Point,
|
||||
shape: GeometricShape<Point>,
|
||||
) => {
|
||||
switch (shape.type) {
|
||||
case "polygon":
|
||||
return polygonIncludesPoint(point, shape.data);
|
||||
return polygonIncludesPoint(p, shape.data);
|
||||
case "line":
|
||||
return false;
|
||||
case "curve":
|
||||
return false;
|
||||
case "ellipse":
|
||||
return pointInEllipse(point, shape.data);
|
||||
return pointInEllipse(p, shape.data);
|
||||
case "polyline": {
|
||||
const polygon = polygonFromPoints(shape.data.flat());
|
||||
return polygonIncludesPoint(point, polygon);
|
||||
return polygonIncludesPoint(p, polygon);
|
||||
}
|
||||
case "polycurve": {
|
||||
return false;
|
||||
|
@ -77,7 +79,9 @@ export const isPointInBounds = <Point extends GlobalPoint | LocalPoint>(
|
|||
return polygonIncludesPoint(point, bounds);
|
||||
};
|
||||
|
||||
const pointOnPolycurve = <Point extends LocalPoint | GlobalPoint>(
|
||||
const pointOnPolycurve = <
|
||||
Point extends LocalPoint | GlobalPoint | ViewportPoint,
|
||||
>(
|
||||
point: Point,
|
||||
polycurve: Polycurve<Point>,
|
||||
tolerance: number,
|
||||
|
@ -85,7 +89,9 @@ const pointOnPolycurve = <Point extends LocalPoint | GlobalPoint>(
|
|||
return polycurve.some((curve) => pointOnCurve(point, curve, tolerance));
|
||||
};
|
||||
|
||||
const cubicBezierEquation = <Point extends LocalPoint | GlobalPoint>(
|
||||
const cubicBezierEquation = <
|
||||
Point extends LocalPoint | GlobalPoint | ViewportPoint,
|
||||
>(
|
||||
curve: Curve<Point>,
|
||||
) => {
|
||||
const [p0, p1, p2, p3] = curve;
|
||||
|
@ -97,7 +103,9 @@ const cubicBezierEquation = <Point extends LocalPoint | GlobalPoint>(
|
|||
p0[idx] * Math.pow(t, 3);
|
||||
};
|
||||
|
||||
const polyLineFromCurve = <Point extends LocalPoint | GlobalPoint>(
|
||||
const polyLineFromCurve = <
|
||||
Point extends LocalPoint | GlobalPoint | ViewportPoint,
|
||||
>(
|
||||
curve: Curve<Point>,
|
||||
segments = 10,
|
||||
): Polyline<Point> => {
|
||||
|
@ -119,7 +127,9 @@ const polyLineFromCurve = <Point extends LocalPoint | GlobalPoint>(
|
|||
return lineSegments;
|
||||
};
|
||||
|
||||
export const pointOnCurve = <Point extends LocalPoint | GlobalPoint>(
|
||||
export const pointOnCurve = <
|
||||
Point extends LocalPoint | GlobalPoint | ViewportPoint,
|
||||
>(
|
||||
point: Point,
|
||||
curve: Curve<Point>,
|
||||
threshold: number,
|
||||
|
@ -127,7 +137,9 @@ export const pointOnCurve = <Point extends LocalPoint | GlobalPoint>(
|
|||
return pointOnPolyline(point, polyLineFromCurve(curve), threshold);
|
||||
};
|
||||
|
||||
export const pointOnPolyline = <Point extends LocalPoint | GlobalPoint>(
|
||||
export const pointOnPolyline = <
|
||||
Point extends LocalPoint | GlobalPoint | ViewportPoint,
|
||||
>(
|
||||
point: Point,
|
||||
polyline: Polyline<Point>,
|
||||
threshold = 10e-5,
|
||||
|
|
|
@ -11,18 +11,6 @@ import {
|
|||
import { pointInEllipse, pointOnEllipse, type Ellipse } from "./shape";
|
||||
|
||||
describe("point and line", () => {
|
||||
// const l: Line<GlobalPoint> = line(point(1, 0), point(1, 2));
|
||||
|
||||
// it("point on left or right of line", () => {
|
||||
// expect(pointLeftofLine(point(0, 1), l)).toBe(true);
|
||||
// expect(pointLeftofLine(point(1, 1), l)).toBe(false);
|
||||
// expect(pointLeftofLine(point(2, 1), l)).toBe(false);
|
||||
|
||||
// expect(pointRightofLine(point(0, 1), l)).toBe(false);
|
||||
// expect(pointRightofLine(point(1, 1), l)).toBe(false);
|
||||
// expect(pointRightofLine(point(2, 1), l)).toBe(true);
|
||||
// });
|
||||
|
||||
const s: LineSegment<GlobalPoint> = lineSegment(point(1, 0), point(1, 2));
|
||||
|
||||
it("point on the line", () => {
|
||||
|
|
|
@ -12,7 +12,13 @@
|
|||
* to pure shapes
|
||||
*/
|
||||
|
||||
import type { Curve, LineSegment, Polygon, Radians } from "../../math";
|
||||
import type {
|
||||
Curve,
|
||||
LineSegment,
|
||||
Polygon,
|
||||
Radians,
|
||||
ViewportPoint,
|
||||
} from "../../math";
|
||||
import {
|
||||
curve,
|
||||
lineSegment,
|
||||
|
@ -56,24 +62,27 @@ import { invariant } from "../../excalidraw/utils";
|
|||
// a polyline (made up term here) is a line consisting of other line segments
|
||||
// this corresponds to a straight line element in the editor but it could also
|
||||
// be used to model other elements
|
||||
export type Polyline<Point extends GlobalPoint | LocalPoint> =
|
||||
export type Polyline<Point extends GlobalPoint | LocalPoint | ViewportPoint> =
|
||||
LineSegment<Point>[];
|
||||
|
||||
// a polycurve is a curve consisting of ther curves, this corresponds to a complex
|
||||
// curve on the canvas
|
||||
export type Polycurve<Point extends GlobalPoint | LocalPoint> = Curve<Point>[];
|
||||
export type Polycurve<Point extends GlobalPoint | LocalPoint | ViewportPoint> =
|
||||
Curve<Point>[];
|
||||
|
||||
// an ellipse is specified by its center, angle, and its major and minor axes
|
||||
// but for the sake of simplicity, we've used halfWidth and halfHeight instead
|
||||
// in replace of semi major and semi minor axes
|
||||
export type Ellipse<Point extends GlobalPoint | LocalPoint> = {
|
||||
export type Ellipse<Point extends GlobalPoint | LocalPoint | ViewportPoint> = {
|
||||
center: Point;
|
||||
angle: Radians;
|
||||
halfWidth: number;
|
||||
halfHeight: number;
|
||||
};
|
||||
|
||||
export type GeometricShape<Point extends GlobalPoint | LocalPoint> =
|
||||
export type GeometricShape<
|
||||
Point extends GlobalPoint | LocalPoint | ViewportPoint,
|
||||
> =
|
||||
| {
|
||||
type: "line";
|
||||
data: LineSegment<Point>;
|
||||
|
@ -239,7 +248,9 @@ export const getCurveShape = <Point extends GlobalPoint | LocalPoint>(
|
|||
};
|
||||
};
|
||||
|
||||
const polylineFromPoints = <Point extends GlobalPoint | LocalPoint>(
|
||||
const polylineFromPoints = <
|
||||
Point extends GlobalPoint | LocalPoint | ViewportPoint,
|
||||
>(
|
||||
points: Point[],
|
||||
): Polyline<Point> => {
|
||||
let previousPoint: Point = points[0];
|
||||
|
@ -254,13 +265,15 @@ const polylineFromPoints = <Point extends GlobalPoint | LocalPoint>(
|
|||
return polyline;
|
||||
};
|
||||
|
||||
export const getFreedrawShape = <Point extends GlobalPoint | LocalPoint>(
|
||||
export const getFreedrawShape = <
|
||||
Point extends GlobalPoint | LocalPoint | ViewportPoint,
|
||||
>(
|
||||
element: ExcalidrawFreeDrawElement,
|
||||
center: Point,
|
||||
isClosed: boolean = false,
|
||||
): GeometricShape<Point> => {
|
||||
const transform = (p: Point) =>
|
||||
pointRotateRads(
|
||||
const transform = (p: Point): Point =>
|
||||
pointRotateRads<Point>(
|
||||
pointFromVector(
|
||||
vectorAdd(vectorFromPoint(p), vector(element.x, element.y)),
|
||||
),
|
||||
|
@ -391,7 +404,9 @@ export const segmentIntersectRectangleElement = <
|
|||
.filter((i): i is Point => !!i);
|
||||
};
|
||||
|
||||
const distanceToEllipse = <Point extends LocalPoint | GlobalPoint>(
|
||||
const distanceToEllipse = <
|
||||
Point extends LocalPoint | GlobalPoint | ViewportPoint,
|
||||
>(
|
||||
p: Point,
|
||||
ellipse: Ellipse<Point>,
|
||||
) => {
|
||||
|
@ -445,7 +460,9 @@ const distanceToEllipse = <Point extends LocalPoint | GlobalPoint>(
|
|||
return pointDistance(point(rotatedPointX, rotatedPointY), point(minX, minY));
|
||||
};
|
||||
|
||||
export const pointOnEllipse = <Point extends LocalPoint | GlobalPoint>(
|
||||
export const pointOnEllipse = <
|
||||
Point extends LocalPoint | GlobalPoint | ViewportPoint,
|
||||
>(
|
||||
point: Point,
|
||||
ellipse: Ellipse<Point>,
|
||||
threshold = PRECISION,
|
||||
|
@ -453,7 +470,9 @@ export const pointOnEllipse = <Point extends LocalPoint | GlobalPoint>(
|
|||
return distanceToEllipse(point, ellipse) <= threshold;
|
||||
};
|
||||
|
||||
export const pointInEllipse = <Point extends LocalPoint | GlobalPoint>(
|
||||
export const pointInEllipse = <
|
||||
Point extends LocalPoint | GlobalPoint | ViewportPoint,
|
||||
>(
|
||||
p: Point,
|
||||
ellipse: Ellipse<Point>,
|
||||
) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue