gpt4 book ai didi

c++ - 为什么我的 openGL 椭圆是尖的?

转载 作者:太空宇宙 更新时间:2023-11-04 13:49:01 24 4
gpt4 key购买 nike

这段椭圆代码是我直接从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

最佳答案

我认为您遇到了溢出。我玩过你的代码。虽然我从来没有从你的照片中看到完全相同的“柠檬”型形状,但大尺寸的东西肯定会分崩离析,这是由于 int 的范围溢出造成的。代码中使用的变量。

例如,看第一个作业:

int py = twoRx2 * y;

如果你替换,这变成:

int py = 2 * Rx * Rx * Ry;

如果您为 Rx 使用每个值 1000和 Ry , 这是 2,000,000,000。这非常接近 32 位 int 范围的 2^31 - 1 顶部.

如果您想将此算法用于更大的尺寸,您可以使用 64 位整数变量。根据您的系统,类型将是 longlong long .或者更稳健地说,int64_t包括<stdint.h>之后.

现在,如果您只想用 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 渲染方法,包括顶点缓冲区等。

关于c++ - 为什么我的 openGL 椭圆是尖的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24318298/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com