From a177d33121a74d5d50ec5723003b9e41cb14e5e1 Mon Sep 17 00:00:00 2001 From: Mark Tolmacs Date: Thu, 3 Oct 2024 14:09:59 +0200 Subject: [PATCH] Add diamond arc alignment --- packages/excalidraw/element/binding.ts | 1 + packages/excalidraw/element/collision.ts | 51 +++++++++++++----------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/packages/excalidraw/element/binding.ts b/packages/excalidraw/element/binding.ts index 0dd4c6954a..bb0a497f0f 100644 --- a/packages/excalidraw/element/binding.ts +++ b/packages/excalidraw/element/binding.ts @@ -71,6 +71,7 @@ import { import { distanceToBindableElement } from "./distance"; import { intersectElementWithLine } from "./collision"; +import { debugDrawPoint } from "../visualdebug"; export type SuggestedBinding = | NonDeleted diff --git a/packages/excalidraw/element/collision.ts b/packages/excalidraw/element/collision.ts index 1bf179771b..f0b5799fbd 100644 --- a/packages/excalidraw/element/collision.ts +++ b/packages/excalidraw/element/collision.ts @@ -42,6 +42,7 @@ import { pointsEqual, } from "../../math"; import { LINE_CONFIRM_THRESHOLD } from "../constants"; +import { debugDrawArc, debugDrawLine } from "../visualdebug"; export const shouldTestInside = (element: ExcalidrawElement) => { if (element.type === "arrow") { @@ -281,17 +282,20 @@ const intersectDiamondWithLine = ( b: GlobalPoint, offset: number = 0, ): GlobalPoint[] => { - const top = pointFrom(element.x + element.width / 2, element.y); + const top = pointFrom( + element.x + element.width / 2, + element.y - offset, + ); const right = pointFrom( - element.x + element.width, + element.x + element.width + offset, element.y + element.height / 2, ); const bottom = pointFrom( element.x + element.width / 2, - element.y + element.height, + element.y + element.height + offset, ); const left = pointFrom( - element.x, + element.x - offset, element.y + element.height / 2, ); const center = pointFrom( @@ -309,25 +313,21 @@ const intersectDiamondWithLine = ( const rotatedA = pointRotateRads(a, center, radians(-element.angle)); const rotatedB = pointRotateRads(b, center, radians(-element.angle)); - const topRight = createDiamondSide( - segment(top, right), - verticalRadius, - horizontalRadius, + const topRight = segment( + pointFrom(top[0] + verticalRadius, top[1] + horizontalRadius), + pointFrom(right[0] - verticalRadius, right[1] - horizontalRadius), ); - const bottomRight = createDiamondSide( - segment(bottom, right), - verticalRadius, - horizontalRadius, + const bottomRight = segment( + pointFrom(bottom[0] + verticalRadius, bottom[1] - horizontalRadius), + pointFrom(right[0] - verticalRadius, right[1] + horizontalRadius), ); - const bottomLeft = createDiamondSide( - segment(bottom, left), - verticalRadius, - horizontalRadius, + const bottomLeft = segment( + pointFrom(bottom[0] - verticalRadius, bottom[1] - horizontalRadius), + pointFrom(left[0] + verticalRadius, left[1] + horizontalRadius), ); - const topLeft = createDiamondSide( - segment(top, left), - verticalRadius, - horizontalRadius, + const topLeft = segment( + pointFrom(top[0] - verticalRadius, top[1] + horizontalRadius), + pointFrom(left[0] + verticalRadius, left[1] - horizontalRadius), ); const arcs: Arc[] = element.roundness @@ -337,7 +337,7 @@ const intersectDiamondWithLine = ( topRight[0], pointFrom( top[0], - top[1] + Math.sqrt(2 * Math.pow(verticalRadius, 2)), + top[1] + Math.sqrt(2 * Math.pow(verticalRadius, 2)) - offset, ), verticalRadius, ), // TOP @@ -345,7 +345,7 @@ const intersectDiamondWithLine = ( topRight[1], bottomRight[1], pointFrom( - right[0] - Math.sqrt(2 * Math.pow(horizontalRadius, 2)), + right[0] - Math.sqrt(2 * Math.pow(horizontalRadius, 2)) + offset, right[1], ), horizontalRadius, @@ -355,7 +355,7 @@ const intersectDiamondWithLine = ( bottomLeft[0], pointFrom( bottom[0], - bottom[1] - Math.sqrt(2 * Math.pow(verticalRadius, 2)), + bottom[1] - Math.sqrt(2 * Math.pow(verticalRadius, 2)) + offset, ), verticalRadius, ), // BOTTOM @@ -363,7 +363,7 @@ const intersectDiamondWithLine = ( bottomLeft[1], topLeft[1], pointFrom( - left[0] + Math.sqrt(2 * Math.pow(horizontalRadius, 2)), + left[0] + Math.sqrt(2 * Math.pow(horizontalRadius, 2)) - offset, left[1], ), horizontalRadius, @@ -371,6 +371,9 @@ const intersectDiamondWithLine = ( ] : []; + arcs.forEach((a) => debugDrawArc(a, { color: "red" })); + debugDrawLine([topRight, bottomRight, bottomLeft, topLeft], {}); + const sides: GlobalPoint[] = [topRight, bottomRight, bottomLeft, topLeft] .map((s) => lineSegmentIntersectionPoints(line(rotatedA, rotatedB), s),