2012-09-14 34 views
0

我有贝塞尔曲线的一些原始版本绘图 常规,这里是贝塞尔绘制函数到定点(如何改写)

void DrawBezier(float ax, float ay, 
      float bx, float by, 
      float cx, float cy, 
      float dx, float dy, unsigned color) 
{ 
    float step = 1.0/1000.0; 

    for(float t=0; t<=1; t+=step) 
    { 
    float u = 1.0-t; 

    float a =  u*u*u; 
    float b = 3.0*u*u*t; 
    float c = 3.0*u*t*t; 
    float d =  t*t*t; 

    float x = ax*a + bx*b + cx*c + dx*d; 
    float y = ay*a + by*b + cy*c + dy*d; 

    SetPixel(int(x),int(y), color); 

    } 

} 

这是因为缓慢的浮子的非常慢> INT铸造, 至少在我的旧奔腾4上(这样的铸造在这里真的消耗90%的时间,实际上是3k贝齐尔/秒,而setpixel被评论时为30k贝齐尔/秒)。

所以我有一个想法,重写它到定点arthimetic,但我不是 很多与此有关的经验 - 如何将其重写到固定点? (注意,t是在0.0到1.0的范围内)

编辑: 问题的第二部分:如何估计贝塞尔曲线 的以像素为单位的长度(像素需要绘制)?还是不知道

+2

FWIW,我不知道什么'SetPixel'正在做什么,但我不知道我会通过评论该行的结论得出结论,你会看到由于整型转换造成的差异。你也没有对数据做任何事情。只是FWIW。 –

+1

是的,这不仅仅是投射,而且还会设置像素,这也可能会打到记忆。我认为如果你想加快速度,那么适应的步长将会带来最好的效果。对于大多数曲线,您可能不需要1000步。 – Adam

+0

这是因为铸造我告诉你;-)(可以把一些整数i ++ j ++代替int(x)和int(y),它是一样的)通过setpixel填充屏幕需要大约10毫秒 - 3k贝齐尔witk int(x),int(y)在没有它的情况下需要1000毫秒100 ms:O - 但我不是问这个问题,还需要计算像素的数量是第二个问题 –

回答

1

Allrite我已经做到了这样的方式

void DrawBezierFX(int ax, int ay, 
       int bx, int by, 
       int cx, int cy, 
       int dx, int dy, unsigned color) 
    { 

    for(unsigned i=0; i<=1024; i+=1) 
    { 
    unsigned t = i<<5; 

    unsigned u = (1024-i)<<5; 

    unsigned a = ((((u*u)>>15)*u)>>15); 
    unsigned b = ((((t*u)>>15)*u)>>15)*3; 
    unsigned c = ((((t*t)>>15)*u)>>15)*3; 
    unsigned d = ((((t*t)>>15)*t)>>15); 


    int x = ax*a + bx*b + cx*c + dx*d; 
    int y = ay*a + by*b + cy*c + dy*d; 

    SetPixel(x>>15 ,y>>15, color); 

    } 

    } 

是3.5×更快becouse没有浮到int转换。 当我测量计算的时候,它是大约115毫秒 与80毫秒,(它3K和我的旧处理器),所以整数 在这里不是要快得多(aqbout只有30%:O)

3

除了使用固定点,可以计算方程的前向差分,所以每一步都是一系列加法而不是乘法。这通常更快。

合理解释Dr Dobbs;较短的解释和代码here

+0

atrite,tnx,我会检查它 –