Почему мои эллипсы 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();
}

Маленькие эллипсы кажутся хорошими, но большие — заостренными и плоскими на концах.

Есть идеи почему?

Вот текущий скриншот:

Вот's an image

1

Решение

Я думаю, что вы столкнулись с переполнением. Я играл с вашим кодом. Хотя на ваших снимках я никогда не видел точно такие же фигуры типа «лимон», при больших размерах вещи определенно развалились, и это было вызвано переполнением диапазона int переменные, используемые в коде.

Например, посмотрите на одно из первых заданий:

int py = twoRx2 * y;

Если вы замените, это становится:

int py = 2 * Rx * Rx * Ry;

Если вы используете значение 1000 для каждого Rx а также Ryэто 2 000 000 000 Что очень близко к вершине 2 ^ 31 — 1 диапазона 32-битного int,

Если вы хотите использовать этот алгоритм для больших размеров, вы можете использовать 64-битные целочисленные переменные. В зависимости от вашей системы, тип будет long или же long long, Или более надежно, int64_t после включения <stdint.h>,

Теперь, если все, что вы хотите сделать, это нарисовать многоточие с помощью OpenGL, есть гораздо лучшие способы. Алгоритмы типа Брезенхэма, используемые в вашем коде, идеально подходят для рисования кривой пиксель за пикселем. Но 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, которые включают буферы вершин и т. Д.

0

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector