mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-08-29 19:20:39 +02:00
code comments
This commit is contained in:
@@ -56,7 +56,7 @@ draw() {
|
||||
text(`${this.finals.length} intersections found.`, this.panelWidth/2, this.height - 10, CENTER);
|
||||
}
|
||||
|
||||
// panel 3: intersections
|
||||
// panel 3: the (already known) intersections
|
||||
nextPanel();
|
||||
this.drawIntersections();
|
||||
}
|
||||
@@ -73,7 +73,7 @@ drawIteration() {
|
||||
const s1 = pair[0].split(0.5);
|
||||
const s2 = pair[1].split(0.5);
|
||||
|
||||
// cross check
|
||||
// cross check to see if we need to keep any of the pairs
|
||||
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 ]); }
|
||||
@@ -81,10 +81,12 @@ drawIteration() {
|
||||
});
|
||||
}
|
||||
|
||||
// if we have no pairs left, the next button should not be clickable anymore.
|
||||
if (!this.pairs.length && next) {
|
||||
next.disabled = true;
|
||||
}
|
||||
|
||||
// draw any curves we have in our pairs list
|
||||
this.pairs.forEach(pair => {
|
||||
pair.forEach(b => {
|
||||
let curve = new Bezier(this, b.points);
|
||||
@@ -93,6 +95,7 @@ drawIteration() {
|
||||
})
|
||||
});
|
||||
|
||||
// and draw any "finals" as established intersections at this point.
|
||||
setStroke(`red`);
|
||||
this.finals.forEach(pair => {
|
||||
let p = pair[0].get(0.5);
|
||||
|
@@ -23,12 +23,15 @@ draw() {
|
||||
|
||||
this.drawLine(...line);
|
||||
|
||||
// To find our intersections, we align the curve to our line,
|
||||
// so that all we need to do now is find the roots for the curve.
|
||||
const [p1, p2] = line;
|
||||
const aligned = utils.align(curve.points, {p1,p2});
|
||||
const nB = new Bezier(this, aligned);
|
||||
const roots = utils.roots(nB.points);
|
||||
const coords = roots.map(t => curve.get(t));
|
||||
|
||||
// done: any roots we find are intersections on our original curve.
|
||||
if (roots.length) {
|
||||
roots.forEach((t,i) => {
|
||||
var p = coords[i];
|
||||
|
@@ -1,11 +1,13 @@
|
||||
let Point = Vector, points = [];
|
||||
|
||||
setup() {
|
||||
points.push(new Point(50,50));
|
||||
points.push(new Point(150,110));
|
||||
points.push(new Point(50,250));
|
||||
points.push(new Point(170,170));
|
||||
setMovable(points);
|
||||
points = [
|
||||
new Point(50,50),
|
||||
new Point(150,110),
|
||||
new Point(50,250),
|
||||
new Point(170,170),
|
||||
];
|
||||
setMovable(points);
|
||||
}
|
||||
|
||||
draw() {
|
||||
@@ -16,6 +18,9 @@ draw() {
|
||||
this.drawLine(p1,p2);
|
||||
this.drawLine(p3,p4);
|
||||
|
||||
// compute the line/line intesection: note that this does NOT
|
||||
// mean the line *segments* intersect, just that the lines,
|
||||
// which are infinitely long, intersect.
|
||||
const p = this.lli(
|
||||
p1.x, p1.y,
|
||||
p2.x, p2.y,
|
||||
@@ -23,6 +28,7 @@ draw() {
|
||||
p4.x, p4.y
|
||||
);
|
||||
|
||||
// if there is an intersection, is that point on both line *segments*?
|
||||
if (p) {
|
||||
if (this.onLine(p, p1, p2) && this.onLine(p, p3, p4)) {
|
||||
setColor(`lime`);
|
||||
@@ -44,6 +50,7 @@ drawLine(p1, p2) {
|
||||
circle(p2.x, p2.y, 2);
|
||||
}
|
||||
|
||||
// The line/line intersection code can be found all over the web.
|
||||
lli(x1, y1, x2, y2, x3, y3, x4, y4) {
|
||||
const nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4),
|
||||
ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4),
|
||||
@@ -52,6 +59,7 @@ lli(x1, y1, x2, y2, x3, y3, x4, y4) {
|
||||
return { x: nx / d, y: ny / d };
|
||||
}
|
||||
|
||||
// is point p on the line p1--p2?
|
||||
onLine(p, p1, p2) {
|
||||
const mx = min(p1.x, p2.x),
|
||||
my = min(p1.y, p2.y),
|
||||
|
@@ -17,16 +17,19 @@ draw() {
|
||||
|
||||
curve.drawSkeleton();
|
||||
|
||||
// First, reduce our curves into a set of simple sections
|
||||
var reduced = this.reduce(curve);
|
||||
reduced.forEach(c => {
|
||||
setStroke(randomColor() );
|
||||
this.drawCurve(c);
|
||||
circle(c.points[0].x, c.points[0].y, 2);
|
||||
});
|
||||
|
||||
var last = reduced.slice(-1)[0];
|
||||
let p = last.points[3] ?? last.points[2];
|
||||
circle(p.x, p.y, 3);
|
||||
|
||||
// then, we can offset each simple curve by projective scaling
|
||||
setStroke(`#FF000050`);
|
||||
var offset = curve.offset(this.distance);
|
||||
offset.forEach(c => {
|
||||
@@ -38,6 +41,7 @@ draw() {
|
||||
p = last.points[3] ?? last.points[2];
|
||||
circle(p.x, p.y, 3);
|
||||
|
||||
// on both sides, so we need to offset by -distance, too.
|
||||
setStroke(`#0000FF50`);
|
||||
var offset = curve.offset(-this.distance);
|
||||
offset.forEach(c => {
|
||||
@@ -116,3 +120,5 @@ reduce(curve) {
|
||||
|
||||
return pass2;
|
||||
}
|
||||
|
||||
// TODO: duplicate the offset code from utils.js? It's *a lot* of code, though...
|
||||
|
@@ -71,6 +71,9 @@ draw() {
|
||||
|
||||
movePointsQuadratic(i, link) {
|
||||
const l = points.length;
|
||||
|
||||
// Logic for "conventional" moving of an on-curve point,
|
||||
// moving its associated control points, too.
|
||||
if (link === `conventional` && i%2 === 0) {
|
||||
let ppl = points[(l+i-3)%l];
|
||||
let pl = points[(l+i-1)%l];
|
||||
@@ -91,6 +94,8 @@ movePointsQuadratic(i, link) {
|
||||
}
|
||||
}
|
||||
|
||||
// Moving a control points moves literally every
|
||||
// other control points, too.
|
||||
if (i%2 === 1) {
|
||||
let c1 = points[(l+i-2)%l];
|
||||
let p1 = points[(l+i-1)%l];
|
||||
@@ -127,6 +132,9 @@ movePointsQuadratic(i, link) {
|
||||
|
||||
movePointsCubic(i, link) {
|
||||
const l = points.length;
|
||||
|
||||
// Logic for "conventional" moving of an on-curve point,
|
||||
// moving its associated control points, too.
|
||||
if (link === `conventional` && i%3 === 0) {
|
||||
let left = points[(l+i-1)%l];
|
||||
left.x += this.cursor.diff.x;
|
||||
@@ -137,6 +145,7 @@ movePointsCubic(i, link) {
|
||||
right.y += this.cursor.diff.y;
|
||||
}
|
||||
|
||||
// Moving a control points moves the control "across its on-curve point".
|
||||
if (i%3 > 0) {
|
||||
let c, p;
|
||||
if (i%3 === 1) {
|
||||
|
@@ -28,11 +28,15 @@ draw() {
|
||||
|
||||
plotDistanceFunction(w, h, len) {
|
||||
noFill();
|
||||
|
||||
// There is no way we're capturing the distance function as a nice
|
||||
// easy function, so instead we're going to do the next best thing:
|
||||
// sample the curve at a number of points, and then construct the
|
||||
// function plot as we walk from one sample to the next.
|
||||
let LUT = curve.getLUT(this.steps * 10);
|
||||
let d = 0;
|
||||
start();
|
||||
vertex(0,0);
|
||||
for(let i=1, e=LUT.length, p1, p2; i<e; i++) {
|
||||
for(let i=1, e=LUT.length, p1, p2, d=0; i<e; i++) {
|
||||
p1 = LUT[i-1];
|
||||
p2 = LUT[i];
|
||||
d += dist(p1.x, p1.y, p2.x, p2.y);
|
||||
|
@@ -23,9 +23,12 @@ draw() {
|
||||
scale(0.85);
|
||||
translate(30,30);
|
||||
|
||||
// This first part is the same as the previous graphic
|
||||
setFill(`black`);
|
||||
drawAxes("t", 0, 1, "d", 0, len|0, w, h);
|
||||
let LUT = this.plotDistanceFunction(w, h, len);
|
||||
|
||||
// but this part is new.
|
||||
this.drawPlotIntervals(w, h, LUT);
|
||||
|
||||
resetTransform();
|
||||
|
Reference in New Issue
Block a user