#### Archived

This topic is now archived and is closed to further replies.

# curved LINE

This topic is 6247 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

how do you draw a curved line? i can do bezier, but i need simpler curves for speed. basically, curves with only one control point (would be rendered like a bezier with the control points at the same spot.)

##### Share on other sites
In fact, there are many unlimited amount of cases in bezier curvers. I assume you can do a bezier with 4 points.

p(t)=p0*t^3 + 3*p1*t^2*(1-t) + 3*p2*t*(1-t)^2 + p3*(1-t)^3

But what you need is 3 point bezier:

p(t)=p0*t^2 + 2*p1*t*(1-t) + p2*(1-t)^2

In that bezier curve you only have 1 control point (p1).

Beziers are the simplest and fastest curves to calculate. If you take a 2 point bezier curve, it's the same as line algo:

p(t)=p0*t + p1*(1-t)

The usual way to draw bezier curves is to calculate e.g. 10 points from the bezier curve, and draw lines to connect those points.

To optimize bezier curve calculations, check out this algo from my home pages. It makes the bezier curve drawing 3.67 times faster .

Edited by - Hans on January 11, 2001 12:01:19 PM

##### Share on other sites
Hello !

for (loop=0 ; loop<1 ; loop=loop+step)
{
//this part is explained in my 'Doing gravity right'- document:
p=p+pddd/6+pdd/2+pd;
pd=pd+pddd/2+pdd;
pdd=pdd+pddd;

drawBezierpoint(p);
}

You could calculate pddd/6 and pddd/2 outside the loop and use pdd*0.5 instead of pdd/2 to make it even faster!

Osku

Edited by - Osku on January 13, 2001 10:21:50 PM

##### Share on other sites
Osku thanks a lot!
At the end of the document I do mention that /2 can be replaced by *0.5. But calculating pddd/6 and pddd/2 in advance; I never even though of it! I''ll fix the document right away .

I saw a document in Gamasutra about improving performance of bezier curve drawing. And even then my algo was faster than any of the algos presented in that gama doc. But now it''s even 3 times faster!! W00t!

-Hans [home]

##### Share on other sites
w00t! I improved the algo slightly more and now it doesn''t need any muls in the loop!

Gamasutra introduced a "fast" algo for calculating bezier curves in one article, but I just calculated that this algo is 10 times faster.

-Hans [home]

##### Share on other sites
Hans, your algo looks pretty sound, but you could maybe flesh out the description a little more. In particular, what does your code look like when you''re evaluating the bezier patch? It''s rather easy to grasp how you can "loop" through a bezier line (by updating the derivatives), but "looping" through a patch is a little less intuitive I think. Also, if you really want to compare your algo to the algos presented in the Gamasutra article, you should compare the memory usage, not just computations.

Also, my \$.02 contribution to your algo: call DrawBezierPoint(p) once before entering your loop, so that you don''t skip the first endpoint

##### Share on other sites
  class Bezier { private: float pd,pdd,pddd,pddd_per_2,pddd_per_6,pdd_per_2; public: //bezier-point float p; Bezier( float stepsize, float *bzr ); Bezier( ); //calculate the next point in bezier curve void getNextPoint();};Bezier::Bezier( float stepsize, float *bzr ){ float temp; //calculate the derivates (and half-derivates :) ) at point 0 p=bzr[0]; pd=3*(bzr[1]-bzr[0]); pdd_per_2=3*(bzr[0]-2*bzr[1]+bzr[2]); pddd_per_2=3*(3*(bzr[1]-bzr[2])+bzr[3]-bzr[0]); temp=stepsize*stepsize; pddd_per_2=pddd_per_2*temp*step; pdd_per_2=pdd_per_2*temp; pd=pd*stepsize; pddd=pddd_per_2+pddd_per_2; pdd=pdd_per_2+pdd_per_2; pddd_per_6=pddd*0.1666666f;}Bezier::Bezier() {}void Bezier::getNextPoint(){ p=p+pddd_per_6+pdd_per_2+pd; pd=pd+pddd_per_2+pdd; pdd=pdd+pddd; pdd_per_2=pdd_per_2+pddd_per_2;}

I wrote that a while ago and now updated it. It *should* work but I''m not 100% sure.

Then the code in the actual program looks like this:

  float pts[4]={0,10,-8,4}; //curve pointsBezier mybez(0.1,pts); //init with 0.1 step and use curve-arrayfor (float t=0;t<1;t+=0.1) { //be sure to use the same step here drawPoint(mybez.p); mybez.getNextPoint();}drawPoint(mybez.p);

Thanks for reminding me about that first endpoint (i had it in my mind some time ago but forgot it )

Also, I don''t know how to measure the memory usage like in Gama article, except that it needs 7 floats = 28 bytes. Doesn''t sound too much to me.