Jump to content
  • Advertisement

Archived

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

ironfroggy

curved LINE

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 .

-Hans [home page] [e-mail]

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

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 points

Bezier mybez(0.1,pts); //init with 0.1 step and use curve-array


for (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.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!