2015-04-25 3 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 балла только во втором результате (зеркально).

Если вы хотите, чтобы ваш эллипсMidpointCounterClockwise генерировал точно такие же точки, которые вы могли бы - вместо замены x и y - просто перейти в отрицательное x-направление (то есть x-- вместо x ++ в исходном коде). В противном случае вам придется жить с разницей в симметрии.

Вторая проблема заключается в том, что вы не просто заменили 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

его не достаточно, чтобы просто пойти в отрицательном направлении х, потому что Requirment является то, что я начинаю в позиции (гй, 0) означает, я должен начните со второй области и идите с положительным y, а затем перейдите в область 1 и перейдите в отрицательный x. так что вы говорите, что мой алгоритм правильный, и он просто дает разные результаты? –

+0

Я не проверил ваш алгоритм - это вы теперь можете сделать сами :-) Если ваш алгоритм верен, то ellipseMidpointCounterClockwise (0,0, Rx, Ry) будет создавать те же точки, что и эллипс Midpoint (0,0, Ry, Rx) - за исключением того, что x и y обмениваются. – coproc

+0

Нет чертовой вещи не то же самое, и я не могу понять, почему –

Смежные вопросы