UNPKG

g2o-euclid

Version:
77 lines (73 loc) 3.19 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('g2o'), require('g2o-reactive')) : typeof define === 'function' && define.amd ? define(['exports', 'g2o', 'g2o-reactive'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.MYLIB = {}, global.g2o, global.g2oReactive)); })(this, (function (exports, g2o, g2oReactive) { 'use strict'; class CircleCircleIntersection { #disposables = []; /** * The points representing the intersection of the circles. */ points = []; #change = g2o.variable(0); /** * A monotonically increasing number that increments every time the points are re-computed. */ change$ = this.#change.asObservable(); constructor(circleA, circleB) { const P1 = g2o.G20.vector(0, 0); const P2 = g2o.G20.vector(0, 0); const ca = g2o.G20.vector(0, 0); const cb = g2o.G20.vector(0, 0); /** * The vector from the center of circleA to the center of circleB. */ const D = g2o.G20.vector(0, 0); let R = -1; let r = -1; /** * The following calculation is coordinate-free. * For a coordinate-based solution see * https://mathworld.wolfram.com/Circle-CircleIntersection.html#:~:text=Two%20circles%20may%20intersect%20in,known%20as%20the%20radical%20line. */ const compute = () => { if (R !== -1 && r !== -1) { D.copyVector(cb).sub(ca); const dd = D.quaditude(); const rr = r * r; const RR = R * R; const d = Math.sqrt(dd); const λ = (dd - rr + RR) / (2 * d); const aa = RR - λ * λ; if (aa >= 0) { const a = Math.sqrt(aa); const dhat = D.clone().scale(1 / d); const ahat = dhat.clone().mul(g2o.G20.I); const λdhat = dhat.clone().scale(λ); const avec = ahat.clone().scale(a); P1.copyVector(ca).add(λdhat).add(avec); P2.copyVector(ca).add(λdhat).sub(avec); this.points[0] = P1; this.points[1] = P2; } else { this.points.length = 0; } } }; this.#disposables.push(g2oReactive.effect(() => { ca.copyVector(circleA.X); cb.copyVector(circleB.X); R = circleA.radius; r = circleB.radius; compute(); this.#change.set(this.#change.get() + 1); })); } dispose() { g2o.dispose(this.#disposables); } } exports.CircleCircleIntersection = CircleCircleIntersection; })); //# sourceMappingURL=index.js.map