Parse

File Parse chords.js

This tree is parsed live from the source file.

Classes

  • {{ item.name }}

    • {{ key }}

Not Classes

{{ getTree() }}

Comments

{{ getTreeComments() }}

Source

            

function chordEndpoints2(point, chordPoint, chordPoint2, radians) {
      // Circle center: (px, py)
      // Radius: chordPoint.radius
      // Chord reference point: (cx, cy)
      // Angle of chord direction: ca (in radians)
      let px = point.x
        , py = point.y
        , R = point.radius
        , cx = chordPoint.x
        , cy = chordPoint.y
        , ca = chordPoint2? chordPoint.directionTo(chordPoint2): chordPoint.radians
        ;

      /* Remove for covergent chords*/
      if(radians != undefined) {
          ca = radians
      }
      // direction from angle
      const dxAngle = Math.cos(ca);
      const dyAngle = Math.sin(ca);

      // define d_x, d_y
      const dx = cx - px;
      const dy = cy - py;

      // Quadratic coefficients for t^2 + B t + C = 0
      const A = 1;  // because dxAngle^2 + dyAngle^2 = 1
      const B = 2 * (dx * dxAngle + dy * dyAngle);
      const C = (dx * dx) + (dy * dy) - (R * R);

      // Discriminant
      const discriminant = B*B - 4*A*C;

      if(discriminant < 0) {
        // no real intersections -> no chord
        return null;  // or []
      }

      // solve t values
      const sqrtD = Math.sqrt(discriminant);
      const t1 = (-B + sqrtD) / (2 * A);
      const t2 = (-B - sqrtD) / (2 * A);

      // endpoints
      const x1 = cx + t1 * dxAngle;
      const y1 = cy + t1 * dyAngle;
      const x2 = cx + t2 * dxAngle;
      const y2 = cy + t2 * dyAngle;

      return [
            { x: x1, y: y1 },
            { x: x2, y: y2 }
      ];
}



function rectChordEndpoints(
  // rectLeft, rectRight, rectBottom, rectTop,
  topLeft, bottomRight, chordPoint,
  // P_x, P_y,
  angleRad
) {
    // let ps = rectChordEndpoints(tl.x, br.x, tl.y, br.y, p[0], p[1], p.radians)
    let rectLeft = topLeft.x
      , rectRight = bottomRight.x
      , rectBottom = topLeft.y
      , rectTop = bottomRight.y
      , P_x = chordPoint.x
      , P_y = chordPoint.y
      ;

    if(angleRad == undefined) {
        angleRad = chordPoint.radians
    }

    // direction vector from angle
    const dx = Math.cos(angleRad);
    const dy = Math.sin(angleRad);

    // We'll accumulate intersection points in an array
    const intersections = [];

    // Helper to check if y is in [rectBottom, rectTop]
    function inRangeY(val) {
        return val >= rectBottom && val <= rectTop;
    }

    // Helper to check if x is in [rectLeft, rectRight]
    function inRangeX(val) {
        return val >= rectLeft && val <= rectRight;
    }

    // 1) Left edge => x(t) = rectLeft => solve for t
    if (dx !== 0) {
        const tLeft = (rectLeft - P_x) / dx;
        const yLeft = P_y + tLeft * dy;
        if (inRangeY(yLeft)) {
            intersections.push({
                t: tLeft,
                x: rectLeft,
                y: yLeft
            });
        }
    }

    // 2) Right edge => x(t) = rectRight => solve for t
    if (dx !== 0) {
        const tRight = (rectRight - P_x) / dx;
        const yRight = P_y + tRight * dy;
        if (inRangeY(yRight)) {
            intersections.push({
                t: tRight,
                x: rectRight,
                y: yRight
            });
        }
    }

    // 3) Bottom edge => y(t) = rectBottom => solve for t
    if (dy !== 0) {
        const tBottom = (rectBottom - P_y) / dy;
        const xBottom = P_x + tBottom * dx;
        if (inRangeX(xBottom)) {
            intersections.push({
                t: tBottom,
                x: xBottom,
                y: rectBottom
            });
        }
    }

    // 4) Top edge => y(t) = rectTop => solve for t
    if (dy !== 0) {
        const tTop = (rectTop - P_y) / dy;
        const xTop = P_x + tTop * dx;
        if (inRangeX(xTop)) {
            intersections.push({
                t: tTop,
                x: xTop,
                y: rectTop
            });
        }
    }

    // Now we have up to 4 potential intersections.
    // Typically, we'll have at most 2 valid (unique) points for a proper chord.
    // Filter out duplicates (corner hits can appear in two edges)
    // and sort by parameter t if needed.

    // Remove duplicates (within some small epsilon)
    const epsilon = 1e-9;
    const uniqueIntersections = [];
    for (let i = 0; i < intersections.length; i++) {
        const pt = intersections[i];
        let isDuplicate = false;
        for (let j = 0; j < uniqueIntersections.length; j++) {
            const stored = uniqueIntersections[j];
            if (
                Math.abs(pt.x - stored.x) < epsilon &&
                Math.abs(pt.y - stored.y) < epsilon
            ) {
                isDuplicate = true;
                break;
            }
        }
        if (!isDuplicate) {
            uniqueIntersections.push(pt);
        }
    }

    // Sort them by t
    uniqueIntersections.sort((a, b) => a.t - b.t);

    // Return them in a small array. Possibly 0, 1, or 2 points:
    return uniqueIntersections;
}



copy