1
0
mirror of https://github.com/Pomax/BezierInfo-2.git synced 2025-08-01 06:20:52 +02:00

super nice ABC section now

This commit is contained in:
Pomax
2016-01-08 13:23:05 -08:00
parent fb39b82444
commit fba01ea536

View File

@@ -43,21 +43,20 @@ var PointCurves = React.createClass({
drawQuadratic: function(api, curve) {
var w = api.getPanelWidth(),
h = api.getPanelHeight(),
offset = {x:w, y:0},
labels = ["start","t=0.5","end"];
api.reset();
api.setColor("lightblue");
api.drawGrid(10,10);
api.setFill("black");
api.setColor("black");
api.lpts.forEach((p,i) => {
api.drawCircle(p,3);
api.text(labels[i], p, {x:5, y:2});
});
api.setColor("black");
api.drawLine({x:0,y:0},{x:0,y:h}, offset);
api.drawLine({x:w,y:0},{x:w,y:h}, offset);
if(api.lpts.length === 3) {
var S = api.lpts[0],
E = api.lpts[2],
@@ -89,20 +88,19 @@ var PointCurves = React.createClass({
drawCubic: function(api, curve) {
var w = api.getPanelWidth(),
h = api.getPanelHeight(),
offset = {x:w, y:0},
labels = ["start","t=0.5","end"];
api.reset();
api.setFill("black");
api.setColor("black");
api.lpts.forEach((p,i) => {
api.drawCircle(p,3);
api.text(labels[i], p, {x:5, y:2});
});
api.setColor("black");
api.drawLine({x:0,y:0},{x:0,y:h}, offset);
api.drawLine({x:w,y:0},{x:w,y:h}, offset);
api.setColor("lightblue");
api.drawGrid(10,10);
if(api.lpts.length === 3) {
var S = api.lpts[0],
@@ -112,23 +110,33 @@ var PointCurves = React.createClass({
x: (S.x + E.x)/2,
y: (S.y + E.y)/2,
};
api.setColor("blue");
api.drawLine(S, E);
api.drawLine(B, C);
api.drawCircle(C, 3);
var ratio = this.getCRatio(0.5),
A = {
x: B.x + (B.x-C.x)/ratio,
y: B.y + (B.y-C.y)/ratio
},
selen = api.utils.dist(S,E),
bclen_min = selen/8,
bclen = api.utils.dist(B,C),
aesthetics = 4,
be12dist = bclen_min + bclen/aesthetics,
bx = be12dist * (E.x-S.x)/selen,
by = be12dist * (E.y-S.y)/selen,
e1 = {
x: B.x - (E.x-S.x)/4,
y: B.y - (E.y-S.y)/4
x: B.x - bx,
y: B.y - by
},
e2 = {
x: B.x + (E.x-S.x)/4,
y: B.y + (E.y-S.y)/4
x: B.x + bx,
y: B.y + by
},
v1 = {
x: A.x + (e1.x-A.x)*2,
y: A.y + (e1.y-A.y)*2
@@ -137,6 +145,7 @@ var PointCurves = React.createClass({
x: A.x + (e2.x-A.x)*2,
y: A.y + (e2.y-A.y)*2
},
nc1 = {
x: S.x + (v1.x-S.x)*2,
y: S.y + (v1.y-S.y)*2
@@ -144,8 +153,9 @@ var PointCurves = React.createClass({
nc2 = {
x: E.x + (v2.x-E.x)*2,
y: E.y + (v2.y-E.y)*2
},
curve = new api.Bezier([S, nc1, nc2, E]);
};
var curve = new api.Bezier([S, nc1, nc2, E]);
api.drawLine(e1, e2);
api.setColor("lightgrey");
api.drawLine(A, C);
@@ -168,29 +178,39 @@ var PointCurves = React.createClass({
<SectionHeader {...this.props} />
<p>Given the preceding section on curve manipulation, we can also generate quadratic and cubic
curves from any three points. However, unlike circle-fitting, which requires only three points,
Bézier curve fitting requires three points, as well as a <i>t</i> value (so we can figure out
where point 'C' needs to be) and in cade of quadratic curves, a tangent that lets us place
those points 'e1' and 'e2' around our point 'B'.</p>
curves from any three points. However, unlike circle-fitting, which requires just three points,
Bézier curve fitting requires three points, as well as a <i>t</i> value, so we can figure out
where point 'C' needs to be.</p>
<p>There's some freedom here, so for illustrative purposes we're going to pretend <i>t</i> is
simply 0.5, which puts C in the middle of the start--end line segment, and then we'll also set
the cubic curve's tangent to half the length of start--end, centered on B.</p>
<p>Using these "default" values for curve creation, we can already get fairly respectable
curves; Click three times on each of the following sketches to set up the points
that should be used to form a quadratic and cubic curve, respectively:</p>
<p>The following graphic lets you place three points, and will use the preceding sections on the
ABC ratio and curve construction to form a quadratic curve through them. You can move the points
you've placed around by click-dragging, or try a new curve by drawing new points with pure clicks.
(There's some freedom here, so for illustrative purposes we clamped <i>t</i> to simply be
0.5, lets us bypass some maths, since a <i>t</i> value of 0.5 always puts C in the middle of
the start--end line segment)</p>
<Graphic preset="generate" title="Fitting a quadratic Bézier curve" setup={this.setup} draw={this.drawQuadratic}
onClick={this.onClick} />
<p>For cubic curves we also need some values to construct the "de Casteljau line through B" with,
and that gives us quite a bit of choice. Since we've clamped <i>t</i> to 0.5, we'll set up a line
through B parallel to the line start--end, with a length that is proportional to the length of the
line B--C: the further away from the baseline B is, the wider its construction line will be, and so
the more "bulby" the curve will look. This still gives us some freedom in terms of exactly how to
scale the length of the construction line as we move B closer or further away from the baseline, so
I simply picked some values that sort-of-kind-of look right in that if a circle through (start,B,end)
forms a perfect hemisphere, the cubic curve constructed forms something close to a hemisphere, too,
and if the points lie on a line, then the curve constructed has the control points very close to
B, while still lying between B and the correct curve end point:</p>
<Graphic preset="generate" title="Fitting a cubic Bézier curve" setup={this.setup} draw={this.drawCubic}
onClick={this.onClick} />
<p>In each graphic, the blue parts are the values that we "just have" simply by setting up
our three points, and deciding on which <i>t</i>-value (and tangent, for cubic curves)
we're working with. There are many ways to determine a combination of <i>t</i> and tangent
values that lead to a more "aesthetic" curve, but this will be left as an exercise to the
reader, since there are many, and aesthetics are often quite personal.</p>
our three points, combined with our decision on which <i>t</i> value to use (and construction line
orientation and length for cubic curves). There are of course many ways to determine a combination
of <i>t</i> and tangent values that lead to a more "aesthetic" curve, but this will be left as an
exercise to the reader, since there are many, and aesthetics are often quite personal.</p>
</section>
);
}