1
0
mirror of https://github.com/Pomax/BezierInfo-2.git synced 2025-10-03 03:21:56 +02:00
Files
BezierInfo-2/docs/chapters/curveintersection/curve-curve.js
2020-08-30 23:06:34 -07:00

131 lines
3.0 KiB
JavaScript

let curves, curve1, curve2, next;
setup() {
setPanelCount(3);
this.pairReset();
this.setupEventListening();
setSlider(`.slide-control`, `epsilon`, 1.0);
}
pairReset() {
curve1 = new Bezier(this, 50,35, 45,235, 220,235, 220,135);
curve2 = new Bezier(this, 20,150, 120,20, 220,95, 140,240);
curves = [curve1, curve2];
resetMovable(curve1.points, curve2.points);
this.reset();
}
reset() {
if (next && next.disabled) next.disabled = false;
this.pairs = [[curve1, curve2]];
this.finals = [];
this.step = 0;
}
setupEventListening() {
next = find(`.next`);
if (next) next.listen([`click`,`touchstart`], evt => {
this.step++;
redraw();
});
let reset = find(`.reset`);
if (reset) reset.listen([`click`,`touchstart`], evt => {
this.pairReset();
redraw();
});
}
draw() {
clear();
// panel 1: base curves
curves.forEach(c => {
c.drawSkeleton();
c.drawCurve();
c.drawPoints();
});
// panel 2: the current iteration step
nextPanel();
this.drawIteration();
setFill(`black`);
let information = `Initial curves, threshold = ${this.epsilon}px`
if (this.step) {
information = `Curve collection at iteration ${this.step}`;
}
text(information, this.panelWidth/2, 15, CENTER);
if (this.finals.length) {
text(`${this.finals.length} intersections found.`, this.panelWidth/2, this.height - 10, CENTER);
}
// panel 3: intersections
nextPanel();
this.drawIntersections();
}
drawIteration() {
if (this.step > 0) {
const pairs = this.pairs;
this.pairs = [];
pairs.forEach(pair => {
if(pair[0].length() < this.epsilon && pair[1].length() < this.epsilon)
return this.finals.push(pair);
// split two curves into four curves
const s1 = pair[0].split(0.5);
const s2 = pair[1].split(0.5);
// cross check
if (s1.left.overlaps(s2.left)) { this.pairs.push([ s1.left, s2.left ]); }
if (s1.left.overlaps(s2.right)) { this.pairs.push([ s1.left, s2.right ]); }
if (s1.right.overlaps(s2.left)) { this.pairs.push([ s1.right, s2.left ]); }
if (s1.right.overlaps(s2.right)) { this.pairs.push([ s1.right, s2.right ]); }
});
}
if (!this.pairs.length && next) {
next.disabled = true;
}
this.pairs.forEach(pair => {
pair.forEach(b => {
let curve = new Bezier(this, b.points);
curve.drawCurve();
curve.drawBoundingBox( randomColor() );
})
});
setStroke(`red`);
this.finals.forEach(pair => {
let p = pair[0].get(0.5);
circle(p.x, p.y, 3);
})
}
drawIntersections() {
curve1.drawCurve(`lightblue`);
curve2.drawCurve(`lightblue`);
noFill();
setStroke(`blue`);
let intersections = curve1.intersects(curve2);
intersections = intersections.map(v => v.split(`/`).map(t => parseFloat(t)));
intersections.forEach(p => {
p = curve1.get(p[0]);
circle(p.x, p.y, 3);
});
}
onMouseMove() {
if (this.currentPoint && this.step !== 0) {
this.reset();
redraw();
}
}
onEpsilon(value) {
this.reset();
}