A Primer on Bezier Curves
Examples
void setupCurve() {
setupDefaultQuadratic();
}
void drawCurve(BezierCurve curve) {
curve.draw();
}
void setupCurve() {
setupDefaultCubic();
}
void drawCurve(BezierCurve curve) {
curve.draw();
}
Component functions
void setupCurve() {
setupDefaultQuadratic();
}
void drawCurve(BezierCurve curve) {
additionals();
curve.draw();
noAdditionals();
usePanelPadding();
nextPanel();
drawAxes("t",0,1, "x",0,panelDim);
BezierCurve x_only = curve.justX(dim-2*pad);
x_only.draw();
nextPanel();
drawAxes("t",0,1, "y",0,panelDim);
BezierCurve y_only = curve.justY(dim-2*pad);
y_only.draw();
}
void setupCurve() {
setupDefaultCubic();
}
void drawCurve(BezierCurve curve) {
additionals();
curve.draw();
noAdditionals();
usePanelPadding();
nextPanel();
drawAxes("t",0,1, "x",0,panelDim);
BezierCurve x_only = curve.justX(dim-2*pad);
x_only.draw();
nextPanel();
drawAxes("t",0,1, "y",0,panelDim);
BezierCurve y_only = curve.justY(dim-2*pad);
y_only.draw();
}
Extremities
void setupCurve() {
setupDefaultQuadratic();
}
/**
* Actual draw code
*/
void drawCurve(BezierCurve curve) {
additionals();
curve.draw();
noAdditionals();
usePanelPadding();
nextPanel();
drawAxes("t",0,1, "x",0,panelDim);
BezierCurve x_only = curve.justX(dim-2*pad);
x_only.draw();
stroke(255,0,0);
float[] tx = x_only.getInflections();
for(float t: tx) {
if(t==0 || t==1) continue;
Point p = x_only.getPoint(t);
ellipse(p.x,p.y,5,5);
line(p.x,p.y-3,p.x,0);
}
nextPanel();
drawAxes("t",0,1, "y",0,panelDim);
BezierCurve y_only = curve.justY(dim-2*pad);
y_only.draw();
stroke(255,0,255);
float[] ty = y_only.getInflections();
for(float t: ty) {
if(t==0 || t==1) continue;
Point p = y_only.getPoint(t);
ellipse(p.x,p.y,5,5);
line(p.x,p.y-3,p.x,0);
}
}
/**
* set up our curve
*/
void setupCurve() {
setupDefaultCubic();
}
/**
* Actual draw code
*/
void drawCurve(BezierCurve curve) {
additionals();
curve.draw();
noAdditionals();
usePanelPadding();
nextPanel();
drawAxes("t",0,1, "x",0,panelDim);
BezierCurve x_only = curve.justX(dim-2*pad);
x_only.draw();
stroke(255,0,0);
float[] tx = x_only.getInflections();
for(float t: tx) {
if(t==0 || t==1) continue;
Point p = x_only.getPoint(t);
ellipse(p.x,p.y,5,5);
line(p.x,p.y-3,p.x,0);
}
nextPanel();
drawAxes("t",0,1, "y",0,panelDim);
BezierCurve y_only = curve.justY(dim-2*pad);
y_only.draw();
stroke(255,0,255);
float[] ty = y_only.getInflections();
for(float t: ty) {
if(t==0 || t==1) continue;
Point p = y_only.getPoint(t);
ellipse(p.x,p.y,5,5);
line(p.x,p.y-3,p.x,0);
}
}
Bounding boxes
void setupCurve() {
setupDefaultQuadratic();
}
void drawCurve(BezierCurve curve) {
curve.draw();
drawBoundingBox(curve.generateBoundingBox());
}
void setupCurve() {
setupDefaultCubic();
}
void drawCurve(BezierCurve curve) {
curve.draw();
drawBoundingBox(curve.generateBoundingBox());
}
Tight boxes
void setupCurve() {
setupDefaultQuadratic();
}
void drawCurve(BezierCurve curve) {
curve.draw();
drawBoundingBox(curve.generateTightBoundingBox());
}
void setupCurve() {
setupDefaultCubic();
}
void drawCurve(BezierCurve curve) {
curve.draw();
drawBoundingBox(curve.generateTightBoundingBox());
}
Intersections
Point p1, p2, p3, p4;
void setupCurve() {
p1 = new Point(50,50);
p2 = new Point(150,110);
curves.add(new BezierCurve(new Point[]{p1,p2}));
p3 = new Point(50,250);
p4 = new Point(170,170);
curves.add(new BezierCurve(new Point[]{p3,p4}));
}
void drawCurve(BezierCurve curve) {
// draw the lines through p1/p2 and p3/p4
stroke(0,50);
float dx = 10*(p2.x-p1.x), dy = 10*(p2.y-p1.y);
line(p1.x-dx,p1.y-dy,p2.x+dx,p2.y+dy);
dx = 10*(p4.x-p3.x); dy = 10*(p4.y-p3.y);
line(p3.x-dx,p3.y-dy,p4.x+dx,p4.y+dy);
// show the line segments
curves.get(0).draw();
curves.get(1).draw();
// show the intersection point
Point ntr = comp.getProjection(p1,p2,p3,p4);
// red if virtual intersection, green if real
boolean oncurves = true;
if(curves.get(0).over(ntr.x,ntr.y) == -1) { oncurves = false; }
if(curves.get(1).over(ntr.x,ntr.y) == -1) { oncurves = false; }
stroke(oncurves?0:255, oncurves?255:0, 0);
ellipse(ntr.x,ntr.y,5,5);
}
Point p1, p2;
void setupCurve() {
p1 = new Point(40,60);
p2 = new Point(260,200);
curves.add(new BezierCurve(new Point[]{
p1, p2
}));
curves.add(new BezierCurve(new Point[]{
new Point(25,150),
new Point(180,30),
new Point(230,250)
}));
}
void drawCurve(BezierCurve curve) {
curves.get(0).draw();
curves.get(1).draw();
BezierCurve aligned = curves.get(1).align(p1,p2);
float[] roots = comp.findAllRoots(0, aligned.y_values);
fill(150,0,150);
float x, y;
for(float t: roots) {
if(t<0 || t>1) continue;
x = curves.get(1).getXValue(t);
y = curves.get(1).getYValue(t);
ellipse(x,y,5,5);
text(""+round(1000*t)/1000,x+10,y);
}
}
Point p1, p2;
void setupCurve() {
p1 = new Point(100,20);
p2 = new Point(195,255);
curves.add(new BezierCurve(new Point[]{
p1, p2
}));
curves.add(new BezierCurve(new Point[]{
new Point(150,125),
new Point(40,30),
new Point(270,115),
new Point(145,200)
}));
}
void drawCurve(BezierCurve curve) {
curves.get(0).draw();
curves.get(1).draw();
BezierCurve aligned = curves.get(1).align(p1,p2);
float[] roots = comp.findAllRoots(0, aligned.y_values);
fill(150,0,150);
float x, y;
for(float t: roots) {
if(t<0 || t>1) continue;
x = curves.get(1).getXValue(t);
y = curves.get(1).getYValue(t);
ellipse(x,y,5,5);
text(""+round(1000*t)/1000,x+10,y);
}
}
de Casteljau's algorithm
void setupCurve() {
setupDefaultQuadratic();
span();
}
void drawCurve(BezierCurve curve) {
curve.draw();
Point p = curve.getPoint(t);
ellipse(p.x, p.y, 5, 5);
drawSpan(curve, t);
BezierCurves[] segments = curve.split(t);
usePanelPadding();
nextPanel();
drawAxes("x",0,panelDim, "y",0,panelDim);
noAdditionals();
curve.draw();
additionals();
segments[0].draw();
nextPanel();
drawAxes("x",0,panelDim, "y",0,panelDim);
noAdditionals();
curve.draw();
additionals();
segments[1].draw();
}
void setupCurve() {
setupDefaultCubic();
span();
}
void drawCurve(BezierCurve curve) {
curve.draw();
Point p = curve.getPoint(t);
ellipse(p.x, p.y, 5, 5);
drawSpan(curve, t);
BezierCurves[] segments = curve.split(t);
usePanelPadding();
nextPanel();
drawAxes("x",0,panelDim, "y",0,panelDim);
noAdditionals();
curve.draw();
additionals();
segments[0].draw();
nextPanel();
drawAxes("x",0,panelDim, "y",0,panelDim);
noAdditionals();
curve.draw();
additionals();
segments[1].draw();
}
Projection ratio
void setupCurve() {
setupDefaultQuadratic();
mould();
}
void mouldCurve(BezierCurve curve, int mx, int my) {
if(Bt != -1) {
B = new Point(mx, my);
BezierCurve newcurve = comp.generateCurve(curve.order, curve.points[0], B, curve.points[curve.order], Bt);
curves.remove(curve);
curves.add(newcurve);
stroke(0,255,0);
line(curve.points[0].x,curve.points[0].y,curve.points[curve.order].x,curve.points[curve.order].y);
Point[] abc = newcurve.getABC(Bt);
stroke(255,0,0);
line(abc[0].x,abc[0].y,abc[1].x,abc[1].y);
stroke(0,255,255);
line(abc[2].x,abc[2].y,abc[1].x,abc[1].y);
}
}
void setupCurve() {
setupDefaultCubic();
mould();
}
void mouldCurve(BezierCurve curve, int mx, int my) {
if(Bt != -1) {
B = new Point(mx, my);
BezierCurve newcurve = comp.generateCurve(curve.order, curve.points[0], B, curve.points[curve.order], Bt, tangents);
curves.remove(curve);
curves.add(newcurve);
stroke(0,255,0);
line(curve.points[0].x,curve.points[0].y,curve.points[curve.order].x,curve.points[curve.order].y);
Point[] abc = newcurve.getABC(Bt);
stroke(255,0,0);
line(abc[0].x,abc[0].y,abc[1].x,abc[1].y);
stroke(0,255,255);
line(abc[2].x,abc[2].y,abc[1].x,abc[1].y);
}
}