mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-08-23 00:33:12 +02:00
.
This commit is contained in:
@@ -127,48 +127,3 @@ var Aligning = React.createClass({
|
||||
});
|
||||
|
||||
module.exports = Aligning;
|
||||
|
||||
/*
|
||||
void setupCurve() {
|
||||
setupDefaultQuadratic();
|
||||
}
|
||||
|
||||
void drawCurve(BezierCurve curve) {
|
||||
additionals();
|
||||
curve.draw();
|
||||
|
||||
nextPanel();
|
||||
stroke(0);
|
||||
line(0,0,0,dim);
|
||||
|
||||
stroke(0,50);
|
||||
translate(3*dim/4,dim/2);
|
||||
line(-3*dim/4,0,dim/4,0);
|
||||
line(0,-dim/2,0,dim/2);
|
||||
|
||||
curve.align().draw(color(150));
|
||||
}</textarea>
|
||||
|
||||
|
||||
|
||||
void setupCurve() {
|
||||
setupDefaultCubic();
|
||||
}
|
||||
|
||||
void drawCurve(BezierCurve curve) {
|
||||
additionals();
|
||||
curve.draw();
|
||||
|
||||
nextPanel();
|
||||
stroke(0);
|
||||
line(0,0,0,dim);
|
||||
|
||||
stroke(0,50);
|
||||
translate(3*dim/4,dim/2);
|
||||
line(-3*dim/4,0,dim/4,0);
|
||||
line(0,-dim/2,0,dim/2);
|
||||
|
||||
curve.align().draw(color(150));
|
||||
}</textarea>
|
||||
|
||||
*/
|
@@ -21,12 +21,12 @@ module.exports = {
|
||||
components: require("./components"),
|
||||
extremities: require("./extremities"),
|
||||
boundingbox: require("./boundingbox"),
|
||||
aligning: require("./aligning")
|
||||
aligning: require("./aligning"),
|
||||
tightbounds: require("./tightbounds")
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
tightbounds: require("./tightbounds"),
|
||||
canonical: require("./canonical"),
|
||||
|
||||
arclength: require("./arclength"),
|
||||
@@ -56,23 +56,7 @@ module.exports = {
|
||||
|
||||
/*
|
||||
|
||||
A lightning introduction
|
||||
What is a Bézier curve?
|
||||
The basics of Bézier curves
|
||||
Controlling Bézier curvatures
|
||||
Bézier curvatures as matrix operations
|
||||
de Casteljau's algorithm
|
||||
Simplified drawing
|
||||
Splitting curves
|
||||
Splitting curves using matrices
|
||||
Lowering and elevating curve order
|
||||
Derivatives
|
||||
Tangents and normals
|
||||
Component functions
|
||||
Finding extremities
|
||||
Bounding boxes
|
||||
Aligning curves
|
||||
Tight boxes
|
||||
|
||||
The canonical form (for cubic curves)
|
||||
Arc length
|
||||
Approximated arc length
|
||||
|
106
components/sections/tightbounds/index.js
Normal file
106
components/sections/tightbounds/index.js
Normal file
@@ -0,0 +1,106 @@
|
||||
var React = require("react");
|
||||
var Graphic = require("../../Graphic.jsx");
|
||||
var SectionHeader = require("../../SectionHeader.jsx");
|
||||
|
||||
var TightBounds = React.createClass({
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
title: "Tight boxes"
|
||||
};
|
||||
},
|
||||
|
||||
setupQuadratic: function(api) {
|
||||
var curve = api.getDefaultQuadratic();
|
||||
api.setCurve(curve);
|
||||
},
|
||||
|
||||
setupCubic: function(api) {
|
||||
var curve = api.getDefaultCubic();
|
||||
api.setCurve(curve);
|
||||
},
|
||||
|
||||
align: function(points, line) {
|
||||
var tx = line.p1.x,
|
||||
ty = line.p1.y,
|
||||
a = -Math.atan2(line.p2.y-ty, line.p2.x-tx),
|
||||
cos = Math.cos,
|
||||
sin = Math.sin,
|
||||
d = function(v) {
|
||||
return {
|
||||
x: (v.x-tx)*cos(a) - (v.y-ty)*sin(a),
|
||||
y: (v.x-tx)*sin(a) + (v.y-ty)*cos(a),
|
||||
a: a
|
||||
};
|
||||
};
|
||||
return points.map(d);
|
||||
},
|
||||
|
||||
// FIXME: I'm not satisfied with needing to turn a bbox[] into a point[],
|
||||
// this needs a bezier.js solution, really, with a call curve.tightbbox()
|
||||
transpose: function(points, angle, offset) {
|
||||
var tx = offset.x,
|
||||
ty = offset.y,
|
||||
cos = Math.cos,
|
||||
sin = Math.sin,
|
||||
v = [points.x.min, points.y.min, points.x.max, points.y.max],
|
||||
points = [
|
||||
{x: v[0], y: v[1] },
|
||||
{x: v[2], y: v[1] },
|
||||
{x: v[2], y: v[3] },
|
||||
{x: v[0], y: v[3] }
|
||||
].map(p => {
|
||||
var x=p.x, y=p.y;
|
||||
return {
|
||||
x: x*cos(angle) - y*sin(angle) + tx,
|
||||
y: x*sin(angle) + y*cos(angle) + ty
|
||||
};
|
||||
});
|
||||
return points;
|
||||
},
|
||||
|
||||
draw: function(api, curve) {
|
||||
api.reset();
|
||||
api.drawSkeleton(curve);
|
||||
api.drawCurve(curve);
|
||||
|
||||
var pts = curve.points;
|
||||
var line = {p1: pts[0], p2: pts[pts.length-1]};
|
||||
var apts = this.align(pts, line);
|
||||
var angle = -apts[0].a;
|
||||
var aligned = new api.Bezier(apts);
|
||||
var bbox = aligned.bbox();
|
||||
var tpts = this.transpose(bbox, angle, pts[0]);
|
||||
|
||||
api.setColor("#00FF00");
|
||||
api.drawLine(tpts[0], tpts[1]);
|
||||
api.drawLine(tpts[1], tpts[2]);
|
||||
api.drawLine(tpts[2], tpts[3]);
|
||||
api.drawLine(tpts[3], tpts[0]);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<section>
|
||||
<SectionHeader {...this.props} />
|
||||
|
||||
<p>With our knowledge of bounding boxes, and curve alignment, We can now form the "tight" bounding box for
|
||||
curves. We first align our curve, recording the translation we performed, "T", and the rotation angle we
|
||||
used, "R". We then determine the aligned curve's normal bounding box. Once we have that, we can map that
|
||||
bounding box back to our original curve by rotating it by -R, and then translating it by -T. We now have
|
||||
nice tight bounding boxes for our curves:</p>
|
||||
|
||||
<Graphic preset="twopanel" title="Aligning a quadratic curve" setup={this.setupQuadratic} draw={this.draw} />
|
||||
<Graphic preset="twopanel" title="Aligning a cubic curve" setup={this.setupCubic} draw={this.draw} />
|
||||
|
||||
<p>These are, strictly speaking, not necessarily the tightest possible bounding boxes. It is possible to compute
|
||||
the optimal bounding box by determining which spanning lines we need to effect a minimal box area, but because
|
||||
of the parametric nature of Bézier curves this is actually a rather costly operation, and the gain in bounding
|
||||
precision is often not worth it. If there is high demand for it, I'll add a section on how to precisely compute
|
||||
the best fit bounding box, but the maths is fairly gruelling and just not really worth spending time on.</p>
|
||||
|
||||
</section>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = TightBounds;
|
Reference in New Issue
Block a user