Compare commits
1 Commits
mtolmacs/f
...
master
Author | SHA1 | Date | |
---|---|---|---|
5639bb8e87 |
@ -1,5 +1,3 @@
|
|||||||
MODE="development"
|
|
||||||
|
|
||||||
VITE_APP_BACKEND_V2_GET_URL=https://json-dev.excalidraw.com/api/v2/
|
VITE_APP_BACKEND_V2_GET_URL=https://json-dev.excalidraw.com/api/v2/
|
||||||
VITE_APP_BACKEND_V2_POST_URL=https://json-dev.excalidraw.com/api/v2/post/
|
VITE_APP_BACKEND_V2_POST_URL=https://json-dev.excalidraw.com/api/v2/post/
|
||||||
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
MODE="production"
|
VITE_APP_BACKEND_V2_GET_URL=https://ex.dylanbanta.com/api/v2/scenes/
|
||||||
|
VITE_APP_BACKEND_V2_POST_URL=https://ex.dylanbanta.com/api/v2/scenes/
|
||||||
VITE_APP_BACKEND_V2_GET_URL=https://json.excalidraw.com/api/v2/
|
|
||||||
VITE_APP_BACKEND_V2_POST_URL=https://json.excalidraw.com/api/v2/post/
|
|
||||||
|
|
||||||
VITE_APP_LIBRARY_URL=https://libraries.excalidraw.com
|
VITE_APP_LIBRARY_URL=https://libraries.excalidraw.com
|
||||||
VITE_APP_LIBRARY_BACKEND=https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries
|
VITE_APP_LIBRARY_BACKEND=https://us-central1-excalidraw-room-persistence.cloudfunctions.net/libraries
|
||||||
|
@ -34,9 +34,6 @@
|
|||||||
<a href="https://discord.gg/UexuTaE">
|
<a href="https://discord.gg/UexuTaE">
|
||||||
<img alt="Chat on Discord" src="https://img.shields.io/discord/723672430744174682?color=738ad6&label=Chat%20on%20Discord&logo=discord&logoColor=ffffff&widge=false"/>
|
<img alt="Chat on Discord" src="https://img.shields.io/discord/723672430744174682?color=738ad6&label=Chat%20on%20Discord&logo=discord&logoColor=ffffff&widge=false"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://deepwiki.com/excalidraw/excalidraw">
|
|
||||||
<img alt="Ask DeepWiki" src="https://deepwiki.com/badge.svg" />
|
|
||||||
</a>
|
|
||||||
<a href="https://twitter.com/excalidraw">
|
<a href="https://twitter.com/excalidraw">
|
||||||
<img alt="Follow Excalidraw on Twitter" src="https://img.shields.io/twitter/follow/excalidraw.svg?label=follow+@excalidraw&style=social&logo=twitter"/>
|
<img alt="Follow Excalidraw on Twitter" src="https://img.shields.io/twitter/follow/excalidraw.svg?label=follow+@excalidraw&style=social&logo=twitter"/>
|
||||||
</a>
|
</a>
|
||||||
|
@ -19,7 +19,7 @@ services:
|
|||||||
- ./:/opt/node_app/app:delegated
|
- ./:/opt/node_app/app:delegated
|
||||||
- ./package.json:/opt/node_app/package.json
|
- ./package.json:/opt/node_app/package.json
|
||||||
- ./yarn.lock:/opt/node_app/yarn.lock
|
- ./yarn.lock:/opt/node_app/yarn.lock
|
||||||
- notused:/opt/node_app/app/node_modules
|
# - notused:/opt/node_app/app/node_modules
|
||||||
|
|
||||||
volumes:
|
# volumes:
|
||||||
notused:
|
# notused:
|
||||||
|
@ -926,16 +926,21 @@ const ExcalidrawWrapper = () => {
|
|||||||
<ShareDialog
|
<ShareDialog
|
||||||
collabAPI={collabAPI}
|
collabAPI={collabAPI}
|
||||||
onExportToBackend={async () => {
|
onExportToBackend={async () => {
|
||||||
if (excalidrawAPI) {
|
if (!excalidrawAPI) {
|
||||||
try {
|
return;
|
||||||
await onExportToBackend(
|
}
|
||||||
excalidrawAPI.getSceneElements(),
|
try {
|
||||||
excalidrawAPI.getAppState(),
|
const { url, errorMessage } = await exportToBackend(
|
||||||
excalidrawAPI.getFiles(),
|
excalidrawAPI.getSceneElements(),
|
||||||
);
|
excalidrawAPI.getAppState(),
|
||||||
} catch (error: any) {
|
excalidrawAPI.getFiles(),
|
||||||
setErrorMessage(error.message);
|
);
|
||||||
|
if (errorMessage) {
|
||||||
|
throw new Error(errorMessage);
|
||||||
}
|
}
|
||||||
|
setLatestShareableLink(url);
|
||||||
|
} catch (error: any) {
|
||||||
|
setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -41,8 +41,8 @@
|
|||||||
"prettier": "@excalidraw/prettier-config",
|
"prettier": "@excalidraw/prettier-config",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build-node": "node ./scripts/build-node.js",
|
"build-node": "node ./scripts/build-node.js",
|
||||||
"build:app:docker": "cross-env VITE_APP_DISABLE_SENTRY=true vite build",
|
"build:app:docker": "vite build",
|
||||||
"build:app": "cross-env VITE_APP_GIT_SHA=$VERCEL_GIT_COMMIT_SHA cross-env VITE_APP_ENABLE_TRACKING=true vite build",
|
"build:app": "vite build",
|
||||||
"build:version": "node ../scripts/build-version.js",
|
"build:version": "node ../scripts/build-version.js",
|
||||||
"build": "yarn build:app && yarn build:version",
|
"build": "yarn build:app && yarn build:version",
|
||||||
"start": "yarn && vite",
|
"start": "yarn && vite",
|
||||||
|
@ -974,25 +974,6 @@ export const updateElbowArrowPoints = (
|
|||||||
),
|
),
|
||||||
"Elbow arrow segments must be either horizontal or vertical",
|
"Elbow arrow segments must be either horizontal or vertical",
|
||||||
);
|
);
|
||||||
|
|
||||||
invariant(
|
|
||||||
updates.fixedSegments?.find(
|
|
||||||
(segment) =>
|
|
||||||
segment.index === 1 &&
|
|
||||||
pointsEqual(segment.start, (updates.points ?? arrow.points)[0]),
|
|
||||||
) == null &&
|
|
||||||
updates.fixedSegments?.find(
|
|
||||||
(segment) =>
|
|
||||||
segment.index === (updates.points ?? arrow.points).length - 1 &&
|
|
||||||
pointsEqual(
|
|
||||||
segment.end,
|
|
||||||
(updates.points ?? arrow.points)[
|
|
||||||
(updates.points ?? arrow.points).length - 1
|
|
||||||
],
|
|
||||||
),
|
|
||||||
) == null,
|
|
||||||
"The first and last segments cannot be fixed",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const fixedSegments = updates.fixedSegments ?? arrow.fixedSegments ?? [];
|
const fixedSegments = updates.fixedSegments ?? arrow.fixedSegments ?? [];
|
||||||
|
@ -117,7 +117,6 @@ export class LinearElementEditor {
|
|||||||
public readonly hoverPointIndex: number;
|
public readonly hoverPointIndex: number;
|
||||||
public readonly segmentMidPointHoveredCoords: GlobalPoint | null;
|
public readonly segmentMidPointHoveredCoords: GlobalPoint | null;
|
||||||
public readonly elbowed: boolean;
|
public readonly elbowed: boolean;
|
||||||
public readonly customLineAngle: number | null;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
element: NonDeleted<ExcalidrawLinearElement>,
|
element: NonDeleted<ExcalidrawLinearElement>,
|
||||||
@ -151,7 +150,6 @@ export class LinearElementEditor {
|
|||||||
this.hoverPointIndex = -1;
|
this.hoverPointIndex = -1;
|
||||||
this.segmentMidPointHoveredCoords = null;
|
this.segmentMidPointHoveredCoords = null;
|
||||||
this.elbowed = isElbowArrow(element) && element.elbowed;
|
this.elbowed = isElbowArrow(element) && element.elbowed;
|
||||||
this.customLineAngle = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -255,7 +253,6 @@ export class LinearElementEditor {
|
|||||||
const { elementId } = linearElementEditor;
|
const { elementId } = linearElementEditor;
|
||||||
const elementsMap = scene.getNonDeletedElementsMap();
|
const elementsMap = scene.getNonDeletedElementsMap();
|
||||||
const element = LinearElementEditor.getElement(elementId, elementsMap);
|
const element = LinearElementEditor.getElement(elementId, elementsMap);
|
||||||
let customLineAngle = linearElementEditor.customLineAngle;
|
|
||||||
if (!element) {
|
if (!element) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -296,12 +293,6 @@ export class LinearElementEditor {
|
|||||||
const selectedIndex = selectedPointsIndices[0];
|
const selectedIndex = selectedPointsIndices[0];
|
||||||
const referencePoint =
|
const referencePoint =
|
||||||
element.points[selectedIndex === 0 ? 1 : selectedIndex - 1];
|
element.points[selectedIndex === 0 ? 1 : selectedIndex - 1];
|
||||||
customLineAngle =
|
|
||||||
linearElementEditor.customLineAngle ??
|
|
||||||
Math.atan2(
|
|
||||||
element.points[selectedIndex][1] - referencePoint[1],
|
|
||||||
element.points[selectedIndex][0] - referencePoint[0],
|
|
||||||
);
|
|
||||||
|
|
||||||
const [width, height] = LinearElementEditor._getShiftLockedDelta(
|
const [width, height] = LinearElementEditor._getShiftLockedDelta(
|
||||||
element,
|
element,
|
||||||
@ -309,7 +300,6 @@ export class LinearElementEditor {
|
|||||||
referencePoint,
|
referencePoint,
|
||||||
pointFrom(scenePointerX, scenePointerY),
|
pointFrom(scenePointerX, scenePointerY),
|
||||||
event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),
|
event[KEYS.CTRL_OR_CMD] ? null : app.getEffectiveGridSize(),
|
||||||
customLineAngle,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
LinearElementEditor.movePoints(
|
LinearElementEditor.movePoints(
|
||||||
@ -431,7 +421,6 @@ export class LinearElementEditor {
|
|||||||
? lastClickedPoint
|
? lastClickedPoint
|
||||||
: -1,
|
: -1,
|
||||||
isDragging: true,
|
isDragging: true,
|
||||||
customLineAngle,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,7 +524,6 @@ export class LinearElementEditor {
|
|||||||
: selectedPointsIndices,
|
: selectedPointsIndices,
|
||||||
isDragging: false,
|
isDragging: false,
|
||||||
pointerOffset: { x: 0, y: 0 },
|
pointerOffset: { x: 0, y: 0 },
|
||||||
customLineAngle: null,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1543,7 +1531,6 @@ export class LinearElementEditor {
|
|||||||
referencePoint: LocalPoint,
|
referencePoint: LocalPoint,
|
||||||
scenePointer: GlobalPoint,
|
scenePointer: GlobalPoint,
|
||||||
gridSize: NullableGridSize,
|
gridSize: NullableGridSize,
|
||||||
customLineAngle?: number,
|
|
||||||
) {
|
) {
|
||||||
const referencePointCoords = LinearElementEditor.getPointGlobalCoordinates(
|
const referencePointCoords = LinearElementEditor.getPointGlobalCoordinates(
|
||||||
element,
|
element,
|
||||||
@ -1569,7 +1556,6 @@ export class LinearElementEditor {
|
|||||||
referencePointCoords[1],
|
referencePointCoords[1],
|
||||||
gridX,
|
gridX,
|
||||||
gridY,
|
gridY,
|
||||||
customLineAngle,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return pointRotateRads(
|
return pointRotateRads(
|
||||||
|
@ -2,12 +2,6 @@ import {
|
|||||||
SHIFT_LOCKING_ANGLE,
|
SHIFT_LOCKING_ANGLE,
|
||||||
viewportCoordsToSceneCoords,
|
viewportCoordsToSceneCoords,
|
||||||
} from "@excalidraw/common";
|
} from "@excalidraw/common";
|
||||||
import {
|
|
||||||
normalizeRadians,
|
|
||||||
radiansBetweenAngles,
|
|
||||||
radiansDifference,
|
|
||||||
type Radians,
|
|
||||||
} from "@excalidraw/math";
|
|
||||||
|
|
||||||
import type { AppState, Offsets, Zoom } from "@excalidraw/excalidraw/types";
|
import type { AppState, Offsets, Zoom } from "@excalidraw/excalidraw/types";
|
||||||
|
|
||||||
@ -140,42 +134,13 @@ export const getLockedLinearCursorAlignSize = (
|
|||||||
originY: number,
|
originY: number,
|
||||||
x: number,
|
x: number,
|
||||||
y: number,
|
y: number,
|
||||||
customAngle?: number,
|
|
||||||
) => {
|
) => {
|
||||||
let width = x - originX;
|
let width = x - originX;
|
||||||
let height = y - originY;
|
let height = y - originY;
|
||||||
|
|
||||||
const angle = Math.atan2(height, width) as Radians;
|
const lockedAngle =
|
||||||
let lockedAngle = (Math.round(angle / SHIFT_LOCKING_ANGLE) *
|
Math.round(Math.atan(height / width) / SHIFT_LOCKING_ANGLE) *
|
||||||
SHIFT_LOCKING_ANGLE) as Radians;
|
SHIFT_LOCKING_ANGLE;
|
||||||
|
|
||||||
if (customAngle) {
|
|
||||||
// If custom angle is provided, we check if the angle is close to the
|
|
||||||
// custom angle, snap to that if close engough, otherwise snap to the
|
|
||||||
// higher or lower angle depending on the current angle vs custom angle.
|
|
||||||
const lower = (Math.floor(customAngle / SHIFT_LOCKING_ANGLE) *
|
|
||||||
SHIFT_LOCKING_ANGLE) as Radians;
|
|
||||||
if (
|
|
||||||
radiansBetweenAngles(
|
|
||||||
angle,
|
|
||||||
lower,
|
|
||||||
(lower + SHIFT_LOCKING_ANGLE) as Radians,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
if (
|
|
||||||
radiansDifference(angle, customAngle as Radians) <
|
|
||||||
SHIFT_LOCKING_ANGLE / 6
|
|
||||||
) {
|
|
||||||
lockedAngle = customAngle as Radians;
|
|
||||||
} else if (
|
|
||||||
normalizeRadians(angle) > normalizeRadians(customAngle as Radians)
|
|
||||||
) {
|
|
||||||
lockedAngle = (lower + SHIFT_LOCKING_ANGLE) as Radians;
|
|
||||||
} else {
|
|
||||||
lockedAngle = lower;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lockedAngle === 0) {
|
if (lockedAngle === 0) {
|
||||||
height = 0;
|
height = 0;
|
||||||
|
@ -1411,55 +1411,5 @@ describe("Test Linear Elements", () => {
|
|||||||
expect(line.points[line.points.length - 1][0]).toBe(20);
|
expect(line.points[line.points.length - 1][0]).toBe(20);
|
||||||
expect(line.points[line.points.length - 1][1]).toBe(-20);
|
expect(line.points[line.points.length - 1][1]).toBe(-20);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should preserve original angle when dragging endpoint with SHIFT key", () => {
|
|
||||||
createTwoPointerLinearElement("line");
|
|
||||||
const line = h.elements[0] as ExcalidrawLinearElement;
|
|
||||||
enterLineEditingMode(line);
|
|
||||||
|
|
||||||
const elementsMap = arrayToMap(h.elements);
|
|
||||||
const points = LinearElementEditor.getPointsGlobalCoordinates(
|
|
||||||
line,
|
|
||||||
elementsMap,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Calculate original angle between first and last point
|
|
||||||
const originalAngle = Math.atan2(
|
|
||||||
points[1][1] - points[0][1],
|
|
||||||
points[1][0] - points[0][0],
|
|
||||||
);
|
|
||||||
|
|
||||||
// Drag the second point (endpoint) with SHIFT key pressed
|
|
||||||
const startPoint = pointFrom<GlobalPoint>(points[1][0], points[1][1]);
|
|
||||||
const endPoint = pointFrom<GlobalPoint>(
|
|
||||||
startPoint[0] + 4,
|
|
||||||
startPoint[1] + 4,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Perform drag with SHIFT key modifier
|
|
||||||
Keyboard.withModifierKeys({ shift: true }, () => {
|
|
||||||
mouse.downAt(startPoint[0], startPoint[1]);
|
|
||||||
mouse.moveTo(endPoint[0], endPoint[1]);
|
|
||||||
mouse.upAt(endPoint[0], endPoint[1]);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get updated points after drag
|
|
||||||
const updatedPoints = LinearElementEditor.getPointsGlobalCoordinates(
|
|
||||||
line,
|
|
||||||
elementsMap,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Calculate new angle
|
|
||||||
const newAngle = Math.atan2(
|
|
||||||
updatedPoints[1][1] - updatedPoints[0][1],
|
|
||||||
updatedPoints[1][0] - updatedPoints[0][0],
|
|
||||||
);
|
|
||||||
|
|
||||||
// The angle should be preserved (within a small tolerance for floating point precision)
|
|
||||||
const angleDifference = Math.abs(newAngle - originalAngle);
|
|
||||||
const tolerance = 0.01; // Small tolerance for floating point precision
|
|
||||||
|
|
||||||
expect(angleDifference).toBeLessThan(tolerance);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1483,13 +1483,13 @@ const getArrowheadOptions = (flip: boolean) => {
|
|||||||
value: "crowfoot_one",
|
value: "crowfoot_one",
|
||||||
text: t("labels.arrowhead_crowfoot_one"),
|
text: t("labels.arrowhead_crowfoot_one"),
|
||||||
icon: <ArrowheadCrowfootOneIcon flip={flip} />,
|
icon: <ArrowheadCrowfootOneIcon flip={flip} />,
|
||||||
keyBinding: "x",
|
keyBinding: "c",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "crowfoot_many",
|
value: "crowfoot_many",
|
||||||
text: t("labels.arrowhead_crowfoot_many"),
|
text: t("labels.arrowhead_crowfoot_many"),
|
||||||
icon: <ArrowheadCrowfootIcon flip={flip} />,
|
icon: <ArrowheadCrowfootIcon flip={flip} />,
|
||||||
keyBinding: "c",
|
keyBinding: "x",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "crowfoot_one_or_many",
|
value: "crowfoot_one_or_many",
|
||||||
|
@ -564,7 +564,7 @@ export const convertElementTypes = (
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const fixedSegments: FixedSegment[] = [];
|
const fixedSegments: FixedSegment[] = [];
|
||||||
for (let i = 1; i < nextPoints.length - 2; i++) {
|
for (let i = 0; i < nextPoints.length - 1; i++) {
|
||||||
fixedSegments.push({
|
fixedSegments.push({
|
||||||
start: nextPoints[i],
|
start: nextPoints[i],
|
||||||
end: nextPoints[i + 1],
|
end: nextPoints[i + 1],
|
||||||
@ -581,7 +581,6 @@ export const convertElementTypes = (
|
|||||||
);
|
);
|
||||||
mutateElement(element, app.scene.getNonDeletedElementsMap(), {
|
mutateElement(element, app.scene.getNonDeletedElementsMap(), {
|
||||||
...updates,
|
...updates,
|
||||||
endArrowhead: "arrow",
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// if we're converting to non-elbow linear element, check if
|
// if we're converting to non-elbow linear element, check if
|
||||||
|
@ -8628,7 +8628,6 @@ exports[`regression tests > key 5 selects arrow tool > [end of test] appState 1`
|
|||||||
"selectedElementsAreBeingDragged": false,
|
"selectedElementsAreBeingDragged": false,
|
||||||
"selectedGroupIds": {},
|
"selectedGroupIds": {},
|
||||||
"selectedLinearElement": LinearElementEditor {
|
"selectedLinearElement": LinearElementEditor {
|
||||||
"customLineAngle": null,
|
|
||||||
"elbowed": false,
|
"elbowed": false,
|
||||||
"elementId": "id0",
|
"elementId": "id0",
|
||||||
"endBindingElement": "keep",
|
"endBindingElement": "keep",
|
||||||
@ -8852,7 +8851,6 @@ exports[`regression tests > key 6 selects line tool > [end of test] appState 1`]
|
|||||||
"selectedElementsAreBeingDragged": false,
|
"selectedElementsAreBeingDragged": false,
|
||||||
"selectedGroupIds": {},
|
"selectedGroupIds": {},
|
||||||
"selectedLinearElement": LinearElementEditor {
|
"selectedLinearElement": LinearElementEditor {
|
||||||
"customLineAngle": null,
|
|
||||||
"elbowed": false,
|
"elbowed": false,
|
||||||
"elementId": "id0",
|
"elementId": "id0",
|
||||||
"endBindingElement": "keep",
|
"endBindingElement": "keep",
|
||||||
@ -9269,7 +9267,6 @@ exports[`regression tests > key a selects arrow tool > [end of test] appState 1`
|
|||||||
"selectedElementsAreBeingDragged": false,
|
"selectedElementsAreBeingDragged": false,
|
||||||
"selectedGroupIds": {},
|
"selectedGroupIds": {},
|
||||||
"selectedLinearElement": LinearElementEditor {
|
"selectedLinearElement": LinearElementEditor {
|
||||||
"customLineAngle": null,
|
|
||||||
"elbowed": false,
|
"elbowed": false,
|
||||||
"elementId": "id0",
|
"elementId": "id0",
|
||||||
"endBindingElement": "keep",
|
"endBindingElement": "keep",
|
||||||
@ -9673,7 +9670,6 @@ exports[`regression tests > key l selects line tool > [end of test] appState 1`]
|
|||||||
"selectedElementsAreBeingDragged": false,
|
"selectedElementsAreBeingDragged": false,
|
||||||
"selectedGroupIds": {},
|
"selectedGroupIds": {},
|
||||||
"selectedLinearElement": LinearElementEditor {
|
"selectedLinearElement": LinearElementEditor {
|
||||||
"customLineAngle": null,
|
|
||||||
"elbowed": false,
|
"elbowed": false,
|
||||||
"elementId": "id0",
|
"elementId": "id0",
|
||||||
"endBindingElement": "keep",
|
"endBindingElement": "keep",
|
||||||
|
@ -49,35 +49,3 @@ export function radiansToDegrees(degrees: Radians): Degrees {
|
|||||||
export function isRightAngleRads(rads: Radians): boolean {
|
export function isRightAngleRads(rads: Radians): boolean {
|
||||||
return Math.abs(Math.sin(2 * rads)) < PRECISION;
|
return Math.abs(Math.sin(2 * rads)) < PRECISION;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function radiansBetweenAngles(
|
|
||||||
a: Radians,
|
|
||||||
min: Radians,
|
|
||||||
max: Radians,
|
|
||||||
): boolean {
|
|
||||||
a = normalizeRadians(a);
|
|
||||||
min = normalizeRadians(min);
|
|
||||||
max = normalizeRadians(max);
|
|
||||||
|
|
||||||
if (min < max) {
|
|
||||||
return a >= min && a <= max;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The range wraps around the 0 angle
|
|
||||||
return a >= min || a <= max;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function radiansDifference(a: Radians, b: Radians): Radians {
|
|
||||||
a = normalizeRadians(a);
|
|
||||||
b = normalizeRadians(b);
|
|
||||||
|
|
||||||
let diff = a - b;
|
|
||||||
|
|
||||||
if (diff < -Math.PI) {
|
|
||||||
diff = (diff + 2 * Math.PI) as Radians;
|
|
||||||
} else if (diff > Math.PI) {
|
|
||||||
diff = (diff - 2 * Math.PI) as Radians;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Math.abs(diff) as Radians;
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user