gpt4 book ai didi

c++ - 在 OpenGL 中绘制 N 角星 - C++

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:01:07 39 4
gpt4 key购买 nike

我写了一段代码,输入n,画出N个尖星,

就像这个:

when n=5 and filed

每当 n=7 或 8 或 16 或 25 时的问题...

我在画星星时遇到问题,它变成了这样:

when n=7 and filled

这是我的代码:

#include <iostream>
#include <ctime>
#include <vector>
#include <glut.h>

using namespace std;

float starCenterX, starCenterY, starRadius;
int numPoints;
bool bDrawFill = false;

void DrawStar (float cx, float cy, float radius, int numPoints);
void DrawStarFilled (float cx, float cy, float radius, int numPoints);


float width, height; // global variables to store window width and height

// render text
void renderBitmapString (float x, float y, float z, void* font, const char* string)
{
const char *c;
glRasterPos3f (x, y,z);
for (c = string; *c != '\0'; c++)
glutBitmapCharacter (font, *c);
}

void init ()
{
glClearColor (1.0, 1.0, 1.0, 0.0); // set display-window color to white
}

void reshape (int width, int height)
{
::width = width;
::height = height;

glViewport (0, 0, width, height);

glMatrixMode (GL_PROJECTION); // set projection parameters
glLoadIdentity ();
gluOrtho2D (0.0, width, 0.0, height);

glMatrixMode (GL_MODELVIEW); // set projection parameters
glLoadIdentity ();
}

void display ()
{
glClear (GL_COLOR_BUFFER_BIT); // clear display window

glColor3f (0, 0, 1);
renderBitmapString (10, height - 20, 0, GLUT_BITMAP_TIMES_ROMAN_24, "Name : Saif Badran");
renderBitmapString (10, height - 50, 0, GLUT_BITMAP_TIMES_ROMAN_24, "ID : 0142852");
renderBitmapString (10, height - 80, 0, GLUT_BITMAP_TIMES_ROMAN_24, "Section : 2");

DrawStar(starCenterX,starCenterY,starRadius,numPoints);

if(bDrawFill)
DrawStarFilled(starCenterX,starCenterY,starRadius,numPoints);

glFlush (); // process all openGl routines as quickly as possible
}

void processNormalKeys (unsigned char key, int x, int y)
{
if(key=='w' || key=='W')
starCenterY+=4;
else if(key=='z' || key=='Z')
starCenterY-=4;
else if(key=='a' || key=='A')
starCenterX-=4;
else if(key=='d' || key=='D')
starCenterX+=4;
else if(key=='f' || key=='F')
bDrawFill = (bDrawFill==1?0:1);
}

void mouseClick (int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
starCenterX = x;
starCenterY = height - y;
}
}

void activeMouseMotion (int x, int y)
{
starRadius = abs(starCenterX-x);
}


void main (int argc, char** argv)
{
cout<<"Enter number of points : ";
cin>>numPoints;
numPoints = (numPoints < 2) ? 2 : numPoints;

glutInit (&argc, argv); // initialize GLUT
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); // set display mode
glutInitWindowPosition (20, 20); // set top left display window position
glutInitWindowSize (600, 600); // set display window width and height
glutCreateWindow ("Homework#2 : Star Drawing"); // create display window

init (); // execute initialization function

glutKeyboardFunc (processNormalKeys);
glutMouseFunc (mouseClick);
glutMotionFunc (activeMouseMotion);
glutReshapeFunc (reshape);
glutDisplayFunc (display); // send graphics to display window
glutIdleFunc (display);
glutMainLoop (); // dispaly everthing and wait
}

void DrawStar (float cx, float cy, float radius, int numPoints)
{

const float DegToRad = 3.14159 / 180;
glColor3f(1.0,0.0,0.0);
glBegin (GL_POINTS);
int count = 1;
for (int i = 0; i <= 360; i+=360/(numPoints*2)) {
float DegInRad = i * DegToRad;
if(count%2!=0)
glVertex2d (cx + cos (DegInRad) * radius, cy + sin (DegInRad) * radius);
else
glVertex2d ((cx + cos (DegInRad) * radius/2), (cy + sin (DegInRad) * radius/2));
count++;
}
glEnd();

glBegin (GL_LINE_LOOP);
count = 1;
for (int i = 0; i <= 360; i+=360/(numPoints*2)) {
float DegInRad = i * DegToRad;
if(count%2!=0)
glVertex2d (cx + cos (DegInRad) * radius, cy + sin (DegInRad) * radius);
else
glVertex2d ((cx + cos (DegInRad) * radius/2), (cy + sin (DegInRad) * radius/2));
count++;
}
glEnd();
}

void DrawStarFilled (float cx, float cy, float radius, int numPoints)
{
const float DegToRad = 3.14159 / 180;

glBegin (GL_TRIANGLE_FAN);
int count = 1;
glVertex2f(starCenterX, starCenterY);
for (int i = 0; i <= 360; i+=360/(numPoints*2)) {
float DegInRad = i * DegToRad;
if(count%2!=0)
glVertex2d (cx + cos (DegInRad) * radius, cy + sin (DegInRad) * radius);
else
glVertex2d ((cx + cos (DegInRad) * radius/2), (cy + sin (DegInRad) * radius/2));
count++;
}

glEnd();
}

最佳答案

问题出在这一行:

for (int i = 0; i <= 360; i+=360/(numPoints*2)) {

对于 numPoints = 5 , 对于每一步 i将增加 360/(2*5) = 36 .

对于 numPoints = 7 , 对于每一步 i将增加 360/(2*7) = 25 (整数除法,将 25.714... 截断为 25 )。所以,在每一步都有一个 0.714..度损失。累计起来,就是:360 - 14 * 25 = 10度。这可以在输出图片上看到。

为了解决这个问题,我们可以为计步器使用一个浮点变量,并使用从浮点除法获得的浮点值递增它,例如使用 360.0 作为分子。 (实际上 360.0 存储为 double ,要将其存储为单精度 float 它应该是 360.0f )。

for (float i = 0; i <= 360; i+=360.0/(numPoints*2)) {

但是这样做,我们可能会在 i <= 360 处遇到麻烦相比之下,浮点运算会产生量化误差(i 可能略小于或大于“数学”值)。所以最好保留循环的整数计数器,然后再进行浮点运算。此代码部分:

    for (int i = 0; i <= 360; i+=360/(numPoints*2)) {
float DegInRad = i * DegToRad;

然后将更改为:

    for (int i = 0; i <= numPoints*2; i++) {
float DegInRad = i * 360.0/(numPoints*2) * DegToRad;

关于c++ - 在 OpenGL 中绘制 N 角星 - C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33860826/

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