1
0
mirror of https://github.com/Pomax/BezierInfo-2.git synced 2025-08-31 12:01:54 +02:00

offsetting

This commit is contained in:
Pomax
2020-09-04 22:01:35 -07:00
parent 83dcab57cb
commit 7e5c6e2eba
38 changed files with 15520 additions and 412 deletions

View File

@@ -12,5 +12,10 @@ Like normal offsetting we cut up our curve in sub-curves, and then check at whic
At each of the relevant points (start, end, and the projections of the control points onto the curve) we know the curve's normal, so offsetting is simply a matter of taking our original point, and moving it along the normal vector by the offset distance for each point. Doing so will give us the following result (these have with a starting width of 0, and an end width of 40 pixels, but can be controlled with your up and down arrow keys):
<Graphic title="Offsetting a quadratic Bézier curve" setup={this.setupQuadratic} draw={this.draw} onKeyDown={this.props.onKeyDown}/>
<Graphic title="Offsetting a cubic Bézier curve" setup={this.setupCubic} draw={this.draw} onKeyDown={this.props.onKeyDown}/>
<graphics-element title="Offsetting a quadratic Bézier curve" src="./offsetting.js" data-type="quadratic">
<input type="range" min="5" max="50" step="1" value="20" class="slide-control">
</graphics-element>
<graphics-element title="Offsetting a cubic Bézier curve" src="./offsetting.js" data-type="cubic">
<input type="range" min="5" max="50" step="1" value="20" class="slide-control">
</graphics-element>

View File

@@ -1,37 +0,0 @@
module.exports = {
statics: {
keyHandlingOptions: {
propName: "distance",
values: {
"38": 1, // up arrow
"40": -1 // down arrow
}
}
},
setup: function(api, curve) {
api.setCurve(curve);
api.distance = 20;
},
setupQuadratic: function(api) {
var curve = api.getDefaultQuadratic();
this.setup(api, curve);
},
setupCubic: function(api) {
var curve = api.getDefaultCubic();
this.setup(api, curve);
},
draw: function(api, curve) {
api.reset();
api.drawSkeleton(curve);
api.drawCurve(curve);
api.setColor("blue");
var outline = curve.outline(0,0,api.distance,api.distance);
outline.curves.forEach(c => api.drawCurve(c));
}
};

View File

@@ -0,0 +1,63 @@
let curve;
setup() {
const type = this.parameters.type ?? `quadratic`;
if (type === `quadratic`) {
curve = Bezier.defaultQuadratic(this);
} else {
curve = Bezier.defaultCubic(this);
}
setMovable(curve.points);
setSlider(`.slide-control`, `distance`, 20);
}
draw() {
clear();
noFill();
curve.drawSkeleton();
curve.drawCurve(`lightblue`);
this.outline(curve, this.distance).forEach(c => this.drawCurve(c));
curve.drawPoints();
};
drawCurve(c) {
setStroke( randomColor() );
start()
c.getLUT(16).forEach(p => vertex(p.x, p.y));
end();
}
outline(curve, d) {
const reduced = curve.reduce(),
fcurves = [];
let bcurves = [],
alen = 0,
tlen = curve.length();
// form curve oulines
reduced.forEach(segment => {
let slen = segment.length();
fcurves.push(segment.scale(this.linearDistanceFunction(d, tlen, alen, slen)));
bcurves.push(segment.scale(this.linearDistanceFunction(-d, tlen, alen, slen)));
alen += slen;
});
// reverse the "return" outline
bcurves = bcurves
.map(s => {
s.points = s.points.reverse();
return s;
})
.reverse();
return [...fcurves, ...bcurves];
}
linearDistanceFunction(d, tlen, alen, slen) {
return v => {
const f1 = alen / tlen,
f2 = (alen + slen) / tlen;
return map(v, 0, 1, f1 * d, f2 * d);
};
}