Diamond collision

This commit is contained in:
Mark Tolmacs 2025-05-14 18:32:05 +02:00
parent 47f12a4d85
commit e25441c8f8
No known key found for this signature in database
3 changed files with 82 additions and 51 deletions

View File

@ -1,5 +1,7 @@
import {
curve,
curveCatmullRomCubicApproxPoints,
curveOffsetPoints,
lineSegment,
pointFrom,
pointFromArray,
@ -299,10 +301,10 @@ export function deconstructDiamondElement(
if (element.roundness?.type == null) {
const [top, right, bottom, left]: GlobalPoint[] = [
pointFrom(element.x + topX, element.y + topY - offset),
pointFrom(element.x + rightX + offset, element.y + rightY),
pointFrom(element.x + bottomX, element.y + bottomY + offset),
pointFrom(element.x + leftX - offset, element.y + leftY),
pointFrom(element.x + topX, element.y + topY),
pointFrom(element.x + rightX, element.y + rightY),
pointFrom(element.x + bottomX, element.y + bottomY),
pointFrom(element.x + leftX, element.y + leftY),
];
// Create the line segment parts of the diamond
@ -336,26 +338,26 @@ export function deconstructDiamondElement(
pointFrom(element.x + leftX, element.y + leftY),
];
const offsets = [
vectorScale(vectorNormalize(vectorFromPoint(right, center)), offset), // RIGHT
vectorScale(vectorNormalize(vectorFromPoint(bottom, center)), offset), // BOTTOM
vectorScale(vectorNormalize(vectorFromPoint(left, center)), offset), // LEFT
vectorScale(vectorNormalize(vectorFromPoint(top, center)), offset), // TOP
const cornerPoints = [
vectorScale(vectorNormalize(vectorFromPoint(right, center)), 0), // RIGHT
vectorScale(vectorNormalize(vectorFromPoint(bottom, center)), 0), // BOTTOM
vectorScale(vectorNormalize(vectorFromPoint(left, center)), 0), // LEFT
vectorScale(vectorNormalize(vectorFromPoint(top, center)), 0), // TOP
];
const corners = [
const baseCorners = [
curve(
pointFromVector(
offsets[0],
cornerPoints[0],
pointFrom<GlobalPoint>(
right[0] - verticalRadius,
right[1] - horizontalRadius,
),
),
pointFromVector(offsets[0], right),
pointFromVector(offsets[0], right),
pointFromVector(cornerPoints[0], right),
pointFromVector(cornerPoints[0], right),
pointFromVector(
offsets[0],
cornerPoints[0],
pointFrom<GlobalPoint>(
right[0] - verticalRadius,
right[1] + horizontalRadius,
@ -364,16 +366,16 @@ export function deconstructDiamondElement(
), // RIGHT
curve(
pointFromVector(
offsets[1],
cornerPoints[1],
pointFrom<GlobalPoint>(
bottom[0] + verticalRadius,
bottom[1] - horizontalRadius,
),
),
pointFromVector(offsets[1], bottom),
pointFromVector(offsets[1], bottom),
pointFromVector(cornerPoints[1], bottom),
pointFromVector(cornerPoints[1], bottom),
pointFromVector(
offsets[1],
cornerPoints[1],
pointFrom<GlobalPoint>(
bottom[0] - verticalRadius,
bottom[1] - horizontalRadius,
@ -382,16 +384,16 @@ export function deconstructDiamondElement(
), // BOTTOM
curve(
pointFromVector(
offsets[2],
cornerPoints[2],
pointFrom<GlobalPoint>(
left[0] + verticalRadius,
left[1] + horizontalRadius,
),
),
pointFromVector(offsets[2], left),
pointFromVector(offsets[2], left),
pointFromVector(cornerPoints[2], left),
pointFromVector(cornerPoints[2], left),
pointFromVector(
offsets[2],
cornerPoints[2],
pointFrom<GlobalPoint>(
left[0] + verticalRadius,
left[1] - horizontalRadius,
@ -400,16 +402,16 @@ export function deconstructDiamondElement(
), // LEFT
curve(
pointFromVector(
offsets[3],
cornerPoints[3],
pointFrom<GlobalPoint>(
top[0] - verticalRadius,
top[1] + horizontalRadius,
),
),
pointFromVector(offsets[3], top),
pointFromVector(offsets[3], top),
pointFromVector(cornerPoints[3], top),
pointFromVector(cornerPoints[3], top),
pointFromVector(
offsets[3],
cornerPoints[3],
pointFrom<GlobalPoint>(
top[0] + verticalRadius,
top[1] + horizontalRadius,
@ -418,12 +420,39 @@ export function deconstructDiamondElement(
), // TOP
];
const sides = [
lineSegment<GlobalPoint>(corners[0][3], corners[1][0]),
lineSegment<GlobalPoint>(corners[1][3], corners[2][0]),
lineSegment<GlobalPoint>(corners[2][3], corners[3][0]),
lineSegment<GlobalPoint>(corners[3][3], corners[0][0]),
const corners =
offset > 0
? baseCorners.map(
(corner) =>
curveCatmullRomCubicApproxPoints(
curveOffsetPoints(corner, offset),
)!,
)
: [
[baseCorners[0]],
[baseCorners[1]],
[baseCorners[2]],
[baseCorners[3]],
];
return [sides, corners];
const sides = [
lineSegment<GlobalPoint>(
corners[0][corners[0].length - 1][3],
corners[1][0][0],
),
lineSegment<GlobalPoint>(
corners[1][corners[1].length - 1][3],
corners[2][0][0],
),
lineSegment<GlobalPoint>(
corners[2][corners[2].length - 1][3],
corners[3][0][0],
),
lineSegment<GlobalPoint>(
corners[3][corners[3].length - 1][3],
corners[0][0][0],
),
];
return [sides, corners.flat()];
}

View File

@ -345,13 +345,13 @@ export const drawHighlightForDiamondWithRotation = (
topApprox[topApprox.length - 1][0],
topApprox[topApprox.length - 1][1],
);
context.lineTo(rightApprox[0][0], rightApprox[0][1]);
context.lineTo(rightApprox[1][0], rightApprox[1][1]);
drawCatmullRomCubicApprox(context, rightApprox);
context.lineTo(bottomApprox[0][0], bottomApprox[0][1]);
context.lineTo(bottomApprox[1][0], bottomApprox[1][1]);
drawCatmullRomCubicApprox(context, bottomApprox);
context.lineTo(leftApprox[0][0], leftApprox[0][1]);
context.lineTo(leftApprox[1][0], leftApprox[1][1]);
drawCatmullRomCubicApprox(context, leftApprox);
context.lineTo(topApprox[0][0], topApprox[0][1]);
context.lineTo(topApprox[1][0], topApprox[1][1]);
drawCatmullRomCubicApprox(context, topApprox);
}
@ -408,13 +408,13 @@ export const drawHighlightForDiamondWithRotation = (
topApprox[topApprox.length - 1][0],
topApprox[topApprox.length - 1][1],
);
context.lineTo(leftApprox[0][0], leftApprox[0][1]);
context.lineTo(leftApprox[1][0], leftApprox[1][1]);
drawCatmullRomCubicApprox(context, leftApprox);
context.lineTo(bottomApprox[0][0], bottomApprox[0][1]);
context.lineTo(bottomApprox[1][0], bottomApprox[1][1]);
drawCatmullRomCubicApprox(context, bottomApprox);
context.lineTo(rightApprox[0][0], rightApprox[0][1]);
context.lineTo(rightApprox[1][0], rightApprox[1][1]);
drawCatmullRomCubicApprox(context, rightApprox);
context.lineTo(topApprox[0][0], topApprox[0][1]);
context.lineTo(topApprox[1][0], topApprox[1][1]);
drawCatmullRomCubicApprox(context, topApprox);
}
context.closePath();

View File

@ -329,15 +329,14 @@ export function curveCatmullRomQuadraticApproxPoints(
return pointSets;
}
export function curveCatmullRomCubicApproxPoints(
points: GlobalPoint[],
tension = 0.5,
) {
export function curveCatmullRomCubicApproxPoints<
Point extends GlobalPoint | LocalPoint,
>(points: Point[], tension = 0.5) {
if (points.length < 2) {
return;
}
const pointSets: [GlobalPoint, GlobalPoint, GlobalPoint][] = [];
const pointSets: Curve<Point>[] = [];
for (let i = 0; i < points.length - 1; i++) {
const p0 = points[i - 1 < 0 ? 0 : i - 1];
const p1 = points[i];
@ -350,11 +349,14 @@ export function curveCatmullRomCubicApproxPoints(
const cp2x = p2[0] - tangent2[0] / 3;
const cp2y = p2[1] - tangent2[1] / 3;
pointSets.push([
pointFrom<GlobalPoint>(cp1x, cp1y),
pointFrom<GlobalPoint>(cp2x, cp2y),
pointFrom<GlobalPoint>(p2[0], p2[1]),
]);
pointSets.push(
curve(
pointFrom(p1[0], p1[1]),
pointFrom(cp1x, cp1y),
pointFrom(cp2x, cp2y),
pointFrom(p2[0], p2[1]),
),
);
}
return pointSets;
@ -362,7 +364,7 @@ export function curveCatmullRomCubicApproxPoints(
export function curveOffsetPoints(
[p0, p1, p2, p3]: Curve<GlobalPoint>,
offsetDist: number,
offset: number,
steps = 50,
) {
const offsetPoints = [];
@ -374,7 +376,7 @@ export function curveOffsetPoints(
const tangent = vectorNormalize(curveTangent(c, t));
const normal = vectorNormal(tangent);
offsetPoints.push(pointFromVector(vectorScale(normal, offsetDist), point));
offsetPoints.push(pointFromVector(vectorScale(normal, offset), point));
}
return offsetPoints;