We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello all,
I am looking for a universal formula to draw a nice Bezier for any 2 given anchor points (a1 and a2).
How can I calculate the control points in a way, that my curve always looks cool and compact?
It should look good no matter if a1 is above or under a2 or next or right from it...
Here is my approach- thank you all!
Chrisir ;-)
void setup() {
size(600, 500);
background(0);
stroke(255, 0, 0);
}
void draw() {
background(0);
// anchors
PVector a1=new PVector(mouseX, mouseY);
PVector a2=new PVector(200, 200);
drawBezier (a1, a2);
}
void drawBezier( PVector a1, PVector a2 ) {
// control points
PVector c1, c2;
int offSet = 160;
// detect the positon of both anchors to each other.
if (abs(a1.x-a2.x) > abs(a1.y-a2.y)) {
// they are more next to each other (left right - )
// control points
c1=new PVector((a1.x+a2.x)/2, giveYValue(a1.y, a2.y, offSet) ) ;
// c2=new PVector(c1.x, c1.y);
} else {
// the are more above each other (more | )
// control points
c1=new PVector( giveYValue(a1.x, a2.x, offSet), (a1.y+a2.y)/2);
// c2=new PVector(c1.x, c1.y);
}
c2=new PVector( 0, 0 );
// c2=new PVector( giveYValue(a2.x, a1.x, offSet), giveYValue(a2.y, a1.y, offSet) );
if (true) {
if (a1.x<a2.x)
c2.x = c1.x+120;
else
c2.x = c1.x-120;
if (a1.y<a2.y)
c2.y = c1.y+120;
else
c2.y = c1.y-120;
}
if (false) {
if (a1.x<a2.x)
c1.x = a1.x-30;
else
c1.x = a2.x-30;
if (a1.y<a2.y)
c1.y = a1.y-30;
else
c1.y = a2.y-30;
// -----------
if (a1.x<a2.x)
c2.x = a1.x-30;
else
c2.x = a2.x-30;
if (a1.y<a2.y)
c2.y = a1.y-30;
else
c2.y = a2.y-30;
}
noFill();
bezier(
a1.x, a1.y,
c1.x, c1.y,
c2.x, c2.y,
a2.x, a2.y );
}
//
float giveYValue(float a1, float a2, float offSet) {
// we want buffer **outside** the span of a1 and a2
// and we want c1 be nearer to a1
// so this function is for c1 only when you give the params as a1,a2.
// for c2 give them as a2,a1.
float buffer;
if (a1<a2)
buffer = a1-offSet;
else
buffer = a1+offSet;
return buffer;
}
//
Answers
Compact: just a straight line... But it wouldn't be "cool".
Of course, you can draw an infinity of Bézier lines between two points. But most of them wouldn't be cool nor compact... :-)
More seriously, a quick idea is to compute the horizontal and vertical distances between the points / shapes. If one of them is zero, just draw a straight line. Otherwise, if width is bigger than height, compute two horizontal control vectors (ie. control points are just a move on x from the start point); otherwise, use vertical vectors.
OK, interesting challenge worth spending a quarter hour on it... :-)
As said, it is only a few possibilities, you can adjust the formulae and algorithm to fit your tastes.
Rewritten properly using PVector operations... Compacter, cleaner code.
Thank you so much!
The curve looks great!
Hope this helps others too....
And here's your tweaked version: :-bd
thanks a lot...
nice...