Pārlūkot izejas kodu

fix: Curve endpoint intersection (#10640)

* fix: Curve endpoint intersection

Signed-off-by: Mark Tolmacs <[email protected]>

* fix debug

---------

Signed-off-by: Mark Tolmacs <[email protected]>
Co-authored-by: dwelle <[email protected]>
Márk Tolmács 1 mēnesi atpakaļ
vecāks
revīzija
da59205846
2 mainītis faili ar 24 papildinājumiem un 6 dzēšanām
  1. 6 6
      excalidraw-app/debug.ts
  2. 18 0
      packages/math/src/curve.ts

+ 6 - 6
excalidraw-app/debug.ts

@@ -10,8 +10,6 @@ const lessPrecise = (num: number, precision = 5) =>
 const getAvgFrameTime = (times: number[]) =>
   lessPrecise(times.reduce((a, b) => a + b) / times.length);
 
-const getFps = (frametime: number) => lessPrecise(1000 / frametime);
-
 export class Debug {
   public static DEBUG_LOG_TIMES = true;
 
@@ -66,12 +64,14 @@ export class Debug {
       }
       for (const [name, { t, times, avg }] of Object.entries(Debug.TIMES_AVG)) {
         if (times.length) {
-          const avgFrameTime = getAvgFrameTime(times);
+          // const avgFrameTime = getAvgFrameTime(times);
+          const totalTime = times.reduce((a, b) => a + b);
+          const avgFrameTime = lessPrecise(totalTime / Debug.FRAME_COUNT);
           console.info(
             name,
-            `${times.length} runs: ${avgFrameTime}ms across ${
+            `- ${times.length} calls - ${avgFrameTime}ms/frame across ${
               Debug.FRAME_COUNT
-            } frames (${getFps(avgFrameTime)} fps ~ ${lessPrecise(
+            } frames (${lessPrecise(
               (avgFrameTime / 16.67) * 100,
               1,
             )}% of frame budget)`,
@@ -136,7 +136,7 @@ export class Debug {
       return (...args: T) => {
         const t0 = performance.now();
         const ret = fn(...args);
-        Debug.logTime(performance.now() - t0, name);
+        Debug[type](performance.now() - t0, name);
         return ret;
       };
     };

+ 18 - 0
packages/math/src/curve.ts

@@ -1,6 +1,7 @@
 import { isPoint, pointDistance, pointFrom, pointFromVector } from "./point";
 import { vector, vectorNormal, vectorNormalize, vectorScale } from "./vector";
 import { LegendreGaussN24CValues, LegendreGaussN24TValues } from "./constants";
+import { lineSegment, lineSegmentIntersectionPoints } from "./segment";
 
 import type { Curve, GlobalPoint, LineSegment, LocalPoint } from "./types";
 
@@ -174,6 +175,23 @@ export function curveIntersectLineSegment<
     return [solution];
   }
 
+  // Fallback: approximate the curve with short segments to catch near-endpoint hits.
+  const startHit = lineSegmentIntersectionPoints(
+    lineSegment(bezierEquation(c, 0), bezierEquation(c, 1 / 20)),
+    l,
+  );
+  if (startHit) {
+    return [startHit];
+  }
+
+  const endHit = lineSegmentIntersectionPoints(
+    lineSegment(bezierEquation(c, 19 / 20), bezierEquation(c, 1)),
+    l,
+  );
+  if (endHit) {
+    return [endHit];
+  }
+
   return [];
 }