2014-06-20 4 views
1

나는 OpenGL을 교과서에서 직접이 타원 코드를 복사 :왜 OpenGL의 타원을 지적하고 있습니까?

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; 

//initial points in both quadrants 
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 setPixel (GLint xPos, GLint yPos) 
{ 
    glBegin (GL_POINTS); 
    glVertex2i(xPos, yPos); 
    glEnd(); 
} 

작은 타원 괜찮을 것 같다하지만 더 큰 사람이 끝에서 종류의 평면 뾰족한하고.

왜 그런가?

Here's an image

+0

질문에 필요하지 않으므로 "자세히"부분을 편집했습니다. – yizzlez

+0

감사합니다.그것을하지 않고 게시 할 수 없었다! – MayNotBe

+0

타원이 "뾰족하게 표시"되어 있지 않습니까? 그것은 서클과 구별되는 것입니다. –

답변

0

난 당신이 오버 플로우가 발생한다고 생각 : 여기

는 현재의 스크린 샷이다. 나는 당신의 코드를 가지고 놀았습니다. 사진에서 정확히 같은 "레몬"유형의 모양을 본 적이 없지만 사물이 큰 크기로 확실히 떨어져 나갔고 코드에 사용 된 int 변수의 범위를 넘쳐서 발생했습니다. 당신은 대체,이지면

int py = twoRx2 * y; 

:

int py = 2 * Rx * Rx * Ry; 

당신이 RxRy 1000 각의 값을 사용하는 경우, 예를 들어

는 첫 번째 과제 중 하나 봐 2,000,000,000입니다. 어느 쪽이 32 비트 int의 2^31 - 1 상단에 매우 가깝습니다.

큰 크기의 경우이 알고리즘을 사용하려면 64 비트 정수 변수를 사용할 수 있습니다. 시스템에 따라 유형은 long 또는 long long이됩니다. 또는 <stdint.h>을 포함하면 int64_t 이후로 더욱 강력합니다.

OpenGL을 사용하여 줄임표를 그릴 때 훨씬 더 좋은 방법이 있습니다. 코드에서 사용되는 Bresenham 유형 알고리즘은 픽셀 단위로 곡선을 그려야하는 경우 이상적입니다. 하지만 OpenGL은 픽셀보다 복잡한 프리미티브를 렌더링하는 방법을 알고있는 고급 API입니다. 커브의 경우 가장 일반적으로 커브를 근사하기 위해 연결된 선분 세트를 사용합니다. 그런 다음 OpenGL은 해당 선분을 픽셀로 변환합니다.

줄임표를 그리는 가장 간단한 방법은 파라 메트릭 표현을 직접 적용하는 것입니다. phi 0과 PI, 당신의 코드에서 이름을 사용 사이의 각도로, 줄임표의 포인트는

x = xCenter + Rx * cos(phi) 
y = yCenter + Ry * sin(phi) 

당신은 당신의 정확한 요구 사항을 충족 phi에 대한 증분을 사용할 수 있으며, 코드가 보일 것입니다 이 같은 모양 DIV_COUNT 포인트 근사 생략 부호를 생성하기 : 당신이 효율성에 대한 관심이 경우

float angInc = 2.0f * m_PI/(float)DIV_COUNT; 
float ang = 0.0f; 
glBegin(GL_LINE_LOOP); 
for (int iDiv = 0; iDiv < DIV_COUNT; ++iDiv) { 
    ang += angInc; 
    float x = xCenter + Rx * cos(ang); 
    float y = yCenter + Ry * sin(ang); 
    glVertex2f(x, y); 
glEnd(); 

, 당신은 각 포인트에 대한 삼각 함수를 계산 피할 수를 이전에서 각 지점을 계산하는 증분 회전을 적용 하나 :

float angInc = 2.0f * M_PI/(float)DIV_COUNT; 
float cosInc = cos(angInc); 
float sinInc = sin(angInc); 
float cosAng = 1.0f; 
float sinAng = 0.0f 
glBegin(GL_LINE_LOOP); 
for (int iDiv = 0; iDiv < DIV_COUNT; ++iDiv) { 
    float newCosAng = cosInc * cosAng - sinInc * sinAng; 
    sinAng = sinInc * cosAng + cosInc * sinAng; 
    cosAng = newCosAng; 
    float x = xCenter + Rx * cosAng; 
    float y = yCenter + Ry * sinAng; 
    glVertex2f(x, y); 
glEnd(); 

이 코드는 물론 수학을 설명하고 시작하기위한 것입니다. 실제로는 버텍스 버퍼 등을 포함하는 현재 OpenGL 렌더링 방법을 사용해야합니다.