g2o-euclid
Version:
g2o Euclidean Geometry Utilities
77 lines (73 loc) • 3.19 kB
JavaScript
(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