I presume you're talking about making a section of a circle with a bezier curve. You can use this formula to approximate the bezier curve to look like a section of a circle.
L = 4 * tan(angle / 4) / 3, where L is the length of each control line.
Also, here's some sample code proving the equation. It's lengthy, but you can input any angle:
float angle = 94; //Change this value for angle of bezier
float lnth;
float radius = 200;
PVector b1 = new PVector(0, -radius);
PVector b2;
void setup() {
size(500, 500);
lnth = 4 * tan(radians(angle/4))/3; //The equation responsible for the distance between control points.
b2 = new PVector(-radius * lnth, -radius);
strokeWeight(0);
b1.rotate(radians(angle));
b2.rotate(radians(angle));
}
void draw() {
translate(width/2, height/2);
noFill();
stroke(0);
bezier(0, -radius, radius * lnth, -radius, b2.x, b2.y, b1.x, b1.y);
ellipseMode(CENTER);
stroke(255, 0, 0);
ellipse(0, 0, 406, 406);
}
the solution seems to work only for angle between 0 and 180 degree (i mean looks still OK in terms of the approximation), is it?
I edit MenteCode's code to use mouseX to control the angle (0-180), but the resulting bezier curve is constantly flicking. Not sure what's the source of the error. Hope you can help to point out what i'm missing here.
// MenteCode: making a section of a circle with a bezier curve
// http://forum.processing.org/two/discussion/1797/how-to-use-bezier-curve-to-approximate-one-quarter-of-a-circle#Item_3
float angle = 90; //Change this value for angle of bezier
float lnth;
float radius = 120;
PVector pStart = new PVector(0, -radius);
PVector pCtrl1;
PVector pCtrl2;
PVector pEnd = new PVector(0, -radius);
void setup() {
size(500, 500);
}
void draw() {
background(150);
angle = map(mouseX, 0,width, 0,180);
//The equation responsible for the distance between control points.
lnth = 4 * tan(radians(angle/4))/3;
pCtrl1 = new PVector(radius * lnth, -radius);
pCtrl2 = new PVector(-radius * lnth, -radius);
pCtrl2.rotate(radians(angle));
pEnd.rotate(radians(angle));
translate(width/2, height/2);
noFill();
stroke(0,255,0);
strokeWeight(15);
point(pStart.x, pStart.y);
point(pCtrl1.x, pCtrl1.y);
point(pCtrl2.x, pCtrl2.y);
point(pEnd.x, pEnd.y);
stroke(0);
strokeWeight(10);
bezier(pStart.x, pStart.y,
pCtrl1.x, pCtrl1.y,
pCtrl2.x, pCtrl2.y,
pEnd.x, pEnd.y);
ellipseMode(CENTER);
stroke(255, 0, 0);
strokeWeight(3);
ellipse(0, 0, radius*2, radius*2);
}
the original transformation was easier, just a case of manipulating the control points, making them gradually closer to the horizontal. um, a diagram would help here, but i'm at work...
step 4 in the above diagram puzzles me. do the lines have width now? if not, how do you expect it to bulge like that? in reality you wouldn't have 4 points though, you'd have 10s, equally spread out along the curve with quads between them.
from rectangle to circle is easy enough - move the points further and further away from the centre, clamp them at the radius. um the bulging between p2 and p3 and between p1 and p4 suggests many points between those two pairs as well though. in any case, you'll need more than the 4 points you show.
Answers
the question is stimulated by the following video demonstrating the morphing of curve shape into rectangle shape: http://vis.berkeley.edu/papers/animated_transitions/
something like the following morphing process:
any advices?
I presume you're talking about making a section of a circle with a bezier curve. You can use this formula to approximate the bezier curve to look like a section of a circle.
L = 4 * tan(angle / 4) / 3
, where L is the length of each control line.Also, here's some sample code proving the equation. It's lengthy, but you can input any angle:
-- MenteCode
You know the rules: 90 degrees for 1/4 of a circle.
Old code: http://bazaar.launchpad.net/~philho/+junk/Processing/view/head:/_QuickExperiments/_Static/CircleWithCorner/CircleWithCorner.pde
Thanks, MenteCode and PhiLho!
I have two questions:
the solution seems to work only for angle between 0 and 180 degree (i mean looks still OK in terms of the approximation), is it?
I edit MenteCode's code to use mouseX to control the angle (0-180), but the resulting bezier curve is constantly flicking. Not sure what's the source of the error. Hope you can help to point out what i'm missing here.
updated code below solves the flicking issue by defining a class for the approximation of circle section by bezier curve:
... further tidy up of the code:
sorry, but the transition from an arc to straight line is still not clear to me ... any suggestions? thanks!
something like the following transition:
any suggestions?
the original transformation was easier, just a case of manipulating the control points, making them gradually closer to the horizontal. um, a diagram would help here, but i'm at work...
step 4 in the above diagram puzzles me. do the lines have width now? if not, how do you expect it to bulge like that? in reality you wouldn't have 4 points though, you'd have 10s, equally spread out along the curve with quads between them.
from rectangle to circle is easy enough - move the points further and further away from the centre, clamp them at the radius. um the bulging between p2 and p3 and between p1 and p4 suggests many points between those two pairs as well though. in any case, you'll need more than the 4 points you show.
Hi, Koogs, thanks! yes, the control points are not shown in the diagram.
I'm thinking about using just arc to achieve this morphing effect (see the code below):
the length of the arc/line is kept as the same
the mouseX is used to control the radius of the circle from which the arc is took, i.e the degree of the arc:
once the radius reaches the infinite (i.e. the angle subtended by the arc is zero), just simply draw a line of the same length:
... update