Efficient algorithm for drawing quadratic bezier curves
Posted: Mon Dec 26, 2022 6:19 am
I've recently come to drawing bezier curves. I found this simple algorithm based on quadratic bezier curve formula:
It works, however, I can not found any informations how to calculate best r value, and also it is not very efficent, because there is multiplication in each cycle. I was searching for something better, but I did not found anything. So I sit down, and recalculate that code above can be rewritten into this:
That's quite fast, but it is still missing best r value computation. After this, I found site https://zingl.github.io/bresenham.html with bresenham algorithm for quadratic beziers. It is faster than my code, but it do not work for all bezier curves. Is there some more efficient algorithm to draw any bezier curve? Or if not, how to calculate best value for r?
Code: Select all
void draw_quadratic_bezier(dword_t x1, dword_t y1, dword_t x2, dword_t y2, dword_t x3, dword_t y3, float r, dword_t color) {
float draw_x1 = x1, draw_y1 = y1, draw_x2, draw_y2, a, b, c, z;
for(float i=0; i<1; i+=r) {
z = (1-i);
a = z*z;
b = z*2*i;
c = i*i;
draw_x2 = a*x1 + b*x2 + c*x3;
draw_y2 = a*y1 + b*y2 + c*y3;
draw_line(draw_x1, draw_y1, draw_x2, draw_y2, color);
draw_x1 = draw_x2;
draw_y1 = draw_y2;
}
draw_line(draw_x1, draw_y1, x3, y3, color);
}
Code: Select all
void draw_quadratic_bezier(dword_t x1, dword_t y1, dword_t x2, dword_t y2, dword_t x3, dword_t y3, float r, dword_t color) {
float x1_inc = r*r*x1;
float x1_step = ((1/r)-1)*x1_inc;
float x2_base = 0;
float x2_base_inc = (x2*2)/(1/r);
float x2_inc = ((r*r*x2)*2);
float x2_step = 0;
float x3_inc = r*r*x3;
float x3_step = 0;
float y1_inc = r*r*y1;
float y1_step = ((1/r)-1)*y1_inc;
float y2_base = 0;
float y2_base_inc = (y2*2)/(1/r);
float y2_inc = ((r*r*y2)*2);
float y2_step = 0;
float y3_inc = r*r*y3;
float y3_step = 0;
float draw_x1 = x1, draw_y1 = y1, draw_x2, draw_y2;
x2 = 0;
x3 = 0;
y2 = 0;
y3 = 0;
for(float i=0; i<1; i+=r) {
draw_x2 = x1 + (x2_base-x2) + x3;
draw_y2 = y1 + (y2_base-y2) + y3;
draw_line(draw_x1, draw_y1, draw_x2, draw_y2, color);
draw_x1 = draw_x2;
draw_y1 = draw_y2;
x1 -= (x1_step+x1_step+x1_inc);
x1_step -= x1_inc;
x2_base += x2_base_inc;
x2 += (x2_step+x2_step+x2_inc);
x2_step += x2_inc;
x3 += (x3_step+x3_step+x3_inc);
x3_step += x3_inc;
y1 -= (y1_step+y1_step+y1_inc);
y1_step -= y1_inc;
y2_base += y2_base_inc;
y2 += (y2_step+y2_step+y2_inc);
y2_step += y2_inc;
y3 += (y3_step+y3_step+y3_inc);
y3_step += y3_inc;
}
}