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);

    }

}

这是非常慢的,因为 float->int 转换速度很慢,至少在我的旧 pentium 4 上是这样(这种转换实际上消耗了 90% 的时间,3k beziers/s 而当 setpixel 被注释时为 30k beziers/s)。

所以我有一个想法将它重写为定点算法,但我对此并没有太多经验 - 如何将它重写为定点?(注意 t 在 0.0 到 1.0 的范围内)

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

4

2 回答 2

3

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

Dobbs 博士的合理解释;更短的解释和代码在这里

于 2012-09-14T22:47:46.683 回答
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);

     }

     }

由于没有 float 到 int 的转换,它的速度提高了 3.5 倍。当我测量计算时间时,它大约是 115 毫秒而不是 80 毫秒(其中 3k 在我的旧处理器上),所以这里的整数并没有那么快(aqbout 30% only :O)

于 2012-09-14T21:06:17.307 回答