Skip to content

Commit

Permalink
feat: lines tangent to arc and hyperbola curve ca199ea
Browse files Browse the repository at this point in the history
  • Loading branch information
plantain-00 committed Nov 4, 2024
1 parent 6393338 commit 7f823bc
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 2 deletions.
2 changes: 1 addition & 1 deletion main.bundle.js

Large diffs are not rendered by default.

93 changes: 92 additions & 1 deletion src/utils/tangent-line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ export function getLinesTangentTo2GeometryLines(line1: GeometryLine, line2: Geom
if (line2.type === 'bezier curve') {
return getLinesTangentToArcAndBezierCurve(line1.curve, line2.curve)
}
return []
if (line2.type === 'hyperbola curve') {
return getLinesTangentToArcAndHyperbola(line1.curve, line2.curve)
}
return getLinesTangentToArcAndNurbsCurve(line1.curve, line2.curve)
}
if (line2.type === 'arc') return getLinesTangentTo2GeometryLines(line2, line1)
if (line1.type === 'ellipse arc') {
Expand Down Expand Up @@ -220,6 +223,94 @@ export function getLinesTangentToArcAndBezierCurve(curve1: Arc, curve2: BezierCu
})
}

export function getLinesTangentToArcAndHyperbola(curve1: Arc, curve2: HyperbolaSegment): Tuple2<Position>[] {
const [p1, d1, d2] = getCircleDerivatives(curve1)
const [p2, e1, e2] = getHyperbolaDerivatives(curve2)
const f1 = (t: Vec2): Vec2 => {
// (y1 - y2)/(x1 - x2) = y1'/x1' = y2'/x2'
// z1 = (y1 - y2)x1' - (x1 - x2)y1'
// z2 = y1'x2' - x1'y2'
const { x: x1, y: y1 } = p1(t[0])
const { x: x11, y: y11 } = d1(t[0])
const { x: x2, y: y2 } = p2(t[1])
const { x: x21, y: y21 } = e1(t[1])
return [(y1 - y2) * x11 - (x1 - x2) * y11, y11 * x21 - x11 * y21]
}
const f2 = (t: Vec2): Matrix2 => {
const { x: x1, y: y1 } = p1(t[0])
const { x: x11, y: y11 } = d1(t[0])
const { x: x12, y: y12 } = d2(t[0])
const { x: x2, y: y2 } = p2(t[1])
const { x: x21, y: y21 } = e1(t[1])
const { x: x22, y: y22 } = e2(t[1])
// dz1/dt1 = y1'x1' + (y1 - y2)x1'' - (x1'y1' + (x1 - x2)y1'')
// dz1/dt2 = -y2'x1' + x2'y1'
// dz2/dt1 = y1''x2' - x1''y2'
// dz2/dt2 = y1'x2'' - x1'y2''
return [
y11 * x11 + (y1 - y2) * x12 - (x11 * y11 + (x1 - x2) * y12),
-y21 * x11 + x21 * y11,
y12 * x21 - x12 * y21,
y11 * x22 - x11 * y22,
]
}
let ts: Vec2[] = []
for (const t1 of [-Math.PI / 2, Math.PI / 2]) {
const t = newtonIterate2([t1, 0], f1, f2, delta2)
if (t !== undefined) {
ts.push(t)
}
}
ts = deduplicate(ts, deepEquals)
return ts.filter(v => angleInRange(v[0], curve1) && isBetween(v[1], curve2.t1, curve2.t2)).map(t => {
return [p1(t[0]), p2(t[1])]
})
}

export function getLinesTangentToArcAndNurbsCurve(curve1: Arc, curve2: NurbsCurve): Tuple2<Position>[] {
const [p1, d1, d2] = getCircleDerivatives(curve1)
const nurbs2 = toVerbNurbsCurve(curve2)
const f1 = (t: Vec2): Vec2 => {
// (y1 - y2)/(x1 - x2) = y1'/x1' = y2'/x2'
// z1 = (y1 - y2)x1' - (x1 - x2)y1'
// z2 = y1'x2' - x1'y2'
const { x: x1, y: y1 } = p1(t[0])
const { x: x11, y: y11 } = d1(t[0])
const [[x2, y2], [x21, y21]] = nurbs2.derivatives(t[1])
return [(y1 - y2) * x11 - (x1 - x2) * y11, y11 * x21 - x11 * y21]
}
const f2 = (t: Vec2): Matrix2 => {
const { x: x1, y: y1 } = p1(t[0])
const { x: x11, y: y11 } = d1(t[0])
const { x: x12, y: y12 } = d2(t[0])
const [[x2, y2], [x21, y21], [x22, y22]] = nurbs2.derivatives(t[1], 2)
// dz1/dt1 = y1'x1' + (y1 - y2)x1'' - (x1'y1' + (x1 - x2)y1'')
// dz1/dt2 = -y2'x1' + x2'y1'
// dz2/dt1 = y1''x2' - x1''y2'
// dz2/dt2 = y1'x2'' - x1'y2''
return [
y11 * x11 + (y1 - y2) * x12 - (x11 * y11 + (x1 - x2) * y12),
-y21 * x11 + x21 * y11,
y12 * x21 - x12 * y21,
y11 * x22 - x11 * y22,
]
}
let ts: Vec2[] = []
const maxParam2 = getNurbsMaxParam(curve2)
for (const t1 of [-Math.PI / 2, Math.PI / 2]) {
for (let t2 = 0.5; t2 < maxParam2; t2++) {
const t = newtonIterate2([t1, t2], f1, f2, delta2)
if (t !== undefined) {
ts.push(t)
}
}
}
ts = deduplicate(ts, deepEquals)
return ts.filter(v => angleInRange(v[0], curve1) && isBetween(v[1], 0, maxParam2)).map(t => {
return [p1(t[0]), fromVerbPoint(nurbs2.point(t[1]))]
})
}

export function getLinesTangentTo2EllipseArcs(curve1: EllipseArc, curve2: EllipseArc): Tuple2<Position>[] {
const [p1, d1, d2] = getEllipseDerivatives(curve1)
const [p2, e1, e2] = getEllipseDerivatives(curve2)
Expand Down

0 comments on commit 7f823bc

Please sign in to comment.