You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
1.6 KiB
78 lines
1.6 KiB
import {RedBlackNode} from "./RedBlackTree"; |
|
import {circles, epsilon2} from "./Diagram"; |
|
|
|
var circlePool = []; |
|
|
|
export var firstCircle; |
|
|
|
function Circle() { |
|
RedBlackNode(this); |
|
this.x = |
|
this.y = |
|
this.arc = |
|
this.site = |
|
this.cy = null; |
|
} |
|
|
|
export function attachCircle(arc) { |
|
var lArc = arc.P, |
|
rArc = arc.N; |
|
|
|
if (!lArc || !rArc) return; |
|
|
|
var lSite = lArc.site, |
|
cSite = arc.site, |
|
rSite = rArc.site; |
|
|
|
if (lSite === rSite) return; |
|
|
|
var bx = cSite[0], |
|
by = cSite[1], |
|
ax = lSite[0] - bx, |
|
ay = lSite[1] - by, |
|
cx = rSite[0] - bx, |
|
cy = rSite[1] - by; |
|
|
|
var d = 2 * (ax * cy - ay * cx); |
|
if (d >= -epsilon2) return; |
|
|
|
var ha = ax * ax + ay * ay, |
|
hc = cx * cx + cy * cy, |
|
x = (cy * ha - ay * hc) / d, |
|
y = (ax * hc - cx * ha) / d; |
|
|
|
var circle = circlePool.pop() || new Circle; |
|
circle.arc = arc; |
|
circle.site = cSite; |
|
circle.x = x + bx; |
|
circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom |
|
|
|
arc.circle = circle; |
|
|
|
var before = null, |
|
node = circles._; |
|
|
|
while (node) { |
|
if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) { |
|
if (node.L) node = node.L; |
|
else { before = node.P; break; } |
|
} else { |
|
if (node.R) node = node.R; |
|
else { before = node; break; } |
|
} |
|
} |
|
|
|
circles.insert(before, circle); |
|
if (!before) firstCircle = circle; |
|
} |
|
|
|
export function detachCircle(arc) { |
|
var circle = arc.circle; |
|
if (circle) { |
|
if (!circle.P) firstCircle = circle.N; |
|
circles.remove(circle); |
|
circlePool.push(circle); |
|
RedBlackNode(circle); |
|
arc.circle = null; |
|
} |
|
}
|
|
|