栅格化曲线算法

时间:2017-10-18 16:59:31

标签: c# c algorithm

我当前的应用程序需要一种算法来绘制给定图像的直线,圆和旋转椭圆。我在互联网上搜索过,发现这篇文章Algorithm for Drawing Curves解释了如何实现它。我正在尝试实现C#中描述的方法,但是在第40行中有一个Int和Bool之间的操作。

有问题的操作是:

  x1 = 2 * err > dy;          // <- this
  y1 = 2 * (err + yy) < -dy); // <- this

  if (2 * err < dx || y1)     // <- this
  { 
      y0 += sy; 
      dy += xy; 
      err += dx += xx; 
   }

   if (2 * err > dx || x1)    // <- this
   { 
       x0 += sx; 
       dx += xy; 
       err += dy += yy; 
   }

变量x1,y1是整数,err,yy和dy是double。我不知道作者使用了哪种编程语言,但显然似乎是在C语言中。

如何在C#中翻译此操作?

我尝试在C#中实现的完整方法:

    private static Point[] plotQuadRationalBezierSeg(int x0, int y0, int x1, int y1, int x2, int y2, double w)
    {                   
        // plot a limited rational Bezier segment, squared weight 
        var points = new List<Point>();

        int sx = x2 - x1, sy = y2 - y1;                   // relative values for checks 
        double dx = x0 - x2, dy = y0 - y2, xx = x0 - x1, yy = y0 - y1;
        double xy = xx * sy + yy * sx, cur = xx * sy - yy * sx, err; // curvature 

        //assert(xx * sx <= 0.0 && yy * sy <= 0.0);   // sign of gradient must not change 

        if (cur != 0.0 && w > 0.0)
        {                            /* no straight line */
            if (sx * (long)sx + sy * (long)sy > xx * xx + yy * yy)
            {   // begin with longer part 
                x2 = x0; 
                x0 -= (int)dx; 
                y2 = y0; 
                y0 -= (int)dy; 
                cur = -cur;         //swap P0 P2 
            }

            xx = 2.0 * (4.0 * w * sx * xx + dx * dx);                   //differences 2nd degree 
            yy = 2.0 * (4.0 * w * sy * yy + dy * dy);
            sx = x0 < x2 ? 1 : -1;                                // x step direction 
            sy = y0 < y2 ? 1 : -1;                                // y step direction 
            xy = -2.0 * sx * sy * (2.0 * w * xy + dx * dy);

            if (cur * sx * sy < 0.0)
            {                             
                // negated curvature?
                xx = -xx; 
                yy = -yy; 
                xy = -xy; 
                cur = -cur;
            }

            dx = 4.0 * w * (x1 - x0) * sy * cur + xx / 2.0 + xy;            //differences 1st degree
            dy = 4.0 * w * (y0 - y1) * sx * cur + yy / 2.0 + xy;

            if (w < 0.5 && (dy > xy || dx < xy))
            {   
                // flat ellipse, algorithm fails 
                cur = (w + 1.0) / 2.0; 
                w = Math.Sqrt(w); 
                xy = 1.0 / (w + 1.0);

                sx = (int)Math.Floor((x0 + 2.0 * w * x1 + x2) * xy / 2.0 + 0.5); //subdivide curve in half 
                sy = (int)Math.Floor((y0 + 2.0 * w * y1 + y2) * xy / 2.0 + 0.5);
                dx = (int)Math.Floor((w * x1 + x0) * xy + 0.5);
                dy = (int)Math.Floor((y1 * w + y0) * xy + 0.5);

                points.AddRange(plotQuadRationalBezierSeg(x0, y0, (int)dx, (int)dy, sx, sy, cur)); //plot separately 

                dx = Math.Floor((w * x1 + x2) * xy + 0.5); dy = Math.Floor((y1 * w + y2) * xy + 0.5);

                points.AddRange(plotQuadRationalBezierSeg(sx, sy, (int)dx, (int)dy, x2, y2, cur));

                return points.ToArray();
            }

            //error 1.step
            err = dx + dy - xy;     

            do
            {
                points.Add(new Point(x0, y0));  // plot curve 

                if (x0 == x2 && y0 == y2) 
                    return points.ToArray(); // last pixel -> curve finished

                x1 = 2 * err > dy; 
                y1 = 2 * (err + yy) < -dy); // save value for test of x step

                if (2 * err < dx || y1) 
                { 
                    y0 += sy; 
                    dy += xy; 
                    err += dx += xx; 
                }/* y step */

                if (2 * err > dx || x1) 
                { 
                    x0 += sx; 
                    dx += xy; 
                    err += dy += yy; 
                }/* x step */

            } while (dy <= xy && dx >= xy);    // gradient negates -> algorithm fails 
        }

        // plot remaining needle to end
        points.AddRange(
                new Point[] { 
                        new Point(x0, y0), 
                        new Point(x2, y2),                  
                });

        return points.ToArray();
    }

0 个答案:

没有答案