2015-04-25 47 views
3

我试图转换从书籍“计算机图形学与OpenGL”采取的标准顺时针椭圆中点算法,以便它将从区域2逆时针工作。 我得到它的工作和绘制一个椭圆,但它与原始算法绘制的椭圆不相同,所以我假设我的代码中有一个小错误,我似乎无法找到,可以请一些人帮忙吗?椭圆中点算法逆时针版

这是原来的算法:

void ellipseMidpoint(int xCenter, int yCenter, int Rx, int Ry) 
{ 
    int Rx2 = Rx * Rx; 
    int Ry2 = Ry * Ry; 
    int twoRx2 = 2 * Rx2; 
    int twoRy2 = 2 * Ry2; 
    int p; 
    int x = 0; 
    int y = Ry; 
    int px = 0; 
    int py = twoRx2 * y; 
    void ellipsePlotPoints(int, int, int, int); 

    /* Plot the initial point in each quadrant. */ 
    ellipsePlotPoints(xCenter, yCenter, x, y); 

    /* Region 1 */ 
    p = round(Ry2 - (Rx2 * Ry) + (0.25 * Rx2)); 
    while (px < py) { 
     x++; 
     px += twoRy2; 
     if (p < 0) 
      p += Ry2 + px; 
     else { 
      y--; 
      py -= twoRx2; 
      p += Ry2 + px - py; 
     } 
     ellipsePlotPoints(xCenter, yCenter, x, y); 
    } 

    /* Region 2 */ 
    p = round(Ry2 * (x + 0.5) * (x + 0.5) + Rx2 * (y - 1) * (y - 1) - Rx2 * Ry2); 
    while (y > 0) { 
     y--; 
     py -= twoRx2; 
     if (p > 0) 
      p += Rx2 - py; 
     else { 
      x++; 
      px += twoRy2; 
      p += Rx2 - py + px; 
     } 
     ellipsePlotPoints(xCenter, yCenter, x, y); 
    } 
} 

void ellipsePlotPoints(int xCenter, int yCenter, int x, int y) 
{ 
    setPixel(xCenter + x, yCenter + y); 
    setPixel(xCenter - x, yCenter + y); 
    setPixel(xCenter + x, yCenter - y); 
    setPixel(xCenter - x, yCenter - y); 
} 

,这是我的版本:

void ellipseMidpointCounterClockwise(int xCenter, int yCenter, int Rx, int Ry) 
{ 
    int Rx2 = Rx * Rx; 
    int Ry2 = Ry * Ry; 
    int twoRx2 = 2 * Rx2; 
    int twoRy2 = 2 * Ry2; 
    int p; 
    int x = Rx; 
    int y = 0; 
    int px = twoRy2 * x; 
    int py = 0; 
    void ellipsePlotPoints(int, int, int, int); 

    /* Plot the initial point in each quadrant. */ 
    ellipsePlotPoints(xCenter, yCenter, x, y); 

    /* Region 2 */ 
    p = round(Ry2 * (x - 0.5) * (x - 0.5) + Rx2 * (y + 1) * (y + 1) - Rx2 * Ry2); 
    while (py < px) { 
     y++; 
     py += twoRx2; 
     if (p > 0) 
      p += Rx2 - py; 
     else { 
      x--; 
      px -= twoRy2; 
      p += Rx2 - py + px; 
     } 
     ellipsePlotPoints(xCenter, yCenter, x, y); 
    } 

    /* Region 1 */ 

    p = round(Ry2 * (x - 1.0) * (x - 1.0) + Rx2 * (y + 0.5) * (y + 0.5) - Rx2 * Ry2); 
    while (x > 0) { 
     x--; 
     px -= twoRy2; 
     if (p < 0) 
      p += Ry2 + px; 
     else { 
      y++; 
      py += twoRx2; 
      p += Ry2 + px - py; 
     } 
     ellipsePlotPoints(xCenter, yCenter, x, y); 
    } 
} 

我真的很感激一些帮助找到我做错了什么。

回答

1

第一个问题是原始代码相对于x和y不对称(并且您的ellipseMidpointCounterClockwise实际上只是替换x和y)。

ellipseMidpoint(0,0,3,2)生成用于第一象限

0 2 
1 2 
2 1 
3 0 

而ellipseMidpoint(0,0,2,3)生成用于第一象限

0 3 
1 3 
2 2 
2 1 
2 0 

时交换坐标并倒转我们得到的订单:

0 2 
1 2 
2 2 
3 1 
3 0 

图形上表示:

002 
| 12 
+--0 

其中+表示中心,0表示在两个结果椭圆分,1个在第一个结果点,2点仅在第二结果(镜像)。

如果您希望您的ellipseMidpointCounterClockwise生成完全相同的点,您可以 - 而不是替换x和y--进入负x方向(即x--代替原始代码中的x ++)。否则,你必须忍受对称性的差异。

第二个问题是,你不只是取代x和y,还做了一些其他奇怪的替换。如果你只是在区域内的替换x和y,你得到正确的结果:

void ellipseMidpointCounterClockwise(int xCenter, int yCenter, int Rx, int Ry) 
{ 
    int Rx2 = Rx * Rx; 
    int Ry2 = Ry * Ry; 
    int twoRx2 = 2 * Rx2; 
    int twoRy2 = 2 * Ry2; 
    int p; 
    int x = Rx; 
    int y = 0; 
    int px = twoRy2 * x; 
    int py = 0; 
    void ellipsePlotPoints(int, int, int, int); 

    /* Plot the initial point in each quadrant. */ 
    ellipsePlotPoints(xCenter, yCenter, x, y); 

    /* Region 2 */ 
    p = round(Rx2 - (Ry2 * Rx) + (0.25 * Ry2)); 
    while (py < px) { 
    y++; 
    py += twoRx2; 
    if (p < 0) 
     p += Rx2 + py; 
    else { 
     x--; 
     px -= twoRy2; 
     p += Rx2 + py - px; 
    } 
    ellipsePlotPoints(xCenter, yCenter, x, y); 
    } 

    /* Region 1 */ 
    p = round(Rx2 * (y + 0.5) * (y + 0.5) + Ry2 * (x - 1) * (x - 1) - Ry2 * Rx2); 
    while (x > 0) { 
    x--; 
    px -= twoRy2; 
    if (p > 0) 
     p += Ry2 - px; 
    else { 
     y++; 
     py += twoRx2; 
     p += Ry2 - px + py; 
    } 
    ellipsePlotPoints(xCenter, yCenter, x, y); 
    } 
} 
+0

其不够的,只是走在X负方向,因为需求量的是,我开始在位置(RX,0),这意味着我必须从第二个区域开始,按正y进行,然后进入区域1并进入负x。所以你说我的算法是正确的,它只是产生不同的结果? –

+0

我没有检查过你的算法 - 你现在可以自己做:-)如果你的算法是正确的,那么ellipseMidpointCounterClockwise(0,0,Rx,Ry)将产生与ellipseMidpoint(0,0,Ry,Rx)相同的点 - 除了交换x和y。 – coproc

+0

不该死的东西是不一样的,我不明白为什么 –