角度离散法画画弧和椭圆

角度离散法可以利用已有的直线算法来分段绘制圆弧、椭圆弧。这种方法的优点在于可以自由控制所绘制的弧的角度范围。

在这里插入图片描述
完整代码:

#include<GL/glut.h>
#include<windows.h>
#include<math.h>
void Arcellipse(int xc, int yc, double r, double ts, double te)
{
 double pi = 3.1415926;
 if (te < ts)  //当终止角比起始角还小时,则将终止角加上2π
  te += 2 * pi;
 double dt = 0.4 / r; //取角度离散值,使其与半径r成反比
 int n = (int)((te - ts) / dt + 0.5); //确定总步数
 double ta = ts;
 int x = xc + int(r*cos(ts));
 int y = yc + int(r*sin(ts));
 glBegin(GL_LINE_STRIP); //如果绘制整圆,选GL_LINE_LOOP更好
 glVertex2f(x, y);
 for (int i = 1; i <= n; i++)
 {
  ta += i * dt;
  double cost = cos(ta);
  double sint = sin(ta);
  x = int(xc + r * cost);
  y = int(yc + r * sint);
  glVertex2f(x, y);
 }
 glEnd();
}
void ChangeSize(GLsizei w, GLsizei h)
{
 if (h == 0)     h = 1;
 // 设置视区尺寸
 glViewport(0, 0, w, h);
 // 重置座标系统
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 // 建立修剪空间的范围
 if (w <= h)
  glOrtho(0.0f, 250.0f, 0.0f, 250.0f*h / w, 1.0, -1.0);
 else
  glOrtho(0.0f, 250.0f*w / h, 0.0f, 250.0f, 1.0, -1.0);
}
void display(void) {
 glClear(GL_COLOR_BUFFER_BIT);
 glColor3f(0.0, 0.0f, 1.0f);
 glBegin(GL_LINE_STRIP);
 Arcellipse(100, 100, 100, 0, 100);
 glFlush();
}
int main(int argc, char *argv[])
{
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
 glutInitWindowPosition(100, 100);
 glutInitWindowSize(400, 400);
 glutCreateWindow("角度离散法画圆");
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 gluOrtho2D(-200.0, 200.0, -200.0, 200.0);
 glutDisplayFunc(display);
 glutReshapeFunc(ChangeSize);
 glutMainLoop();
 return 0;
}

运行结果:
在这里插入图片描述

角度离散法画椭圆

椭圆的中心是(0,0)的参数方程:
在这里插入图片描述

完整代码:

#include<GL/glut.h>
#include<windows.h>
#include<math.h>
void swap(int* a, int* b)
{
 int temp;
 temp = *a;
 *a = *b;
 *b = temp;
}
void Arcellipse(int x, int y, int a, int b)
{
 double pi = 3.1415936;
 if (a < b)                          //比较a,b 的值确保a始终是长轴
  swap(&a, &b);
 double d = a * a - b * b;
 double c = sqrt(d);
 double dt = 1 / c;   //取角度离散值,反比,c越大该值越小
 int n = (int)(2 * pi / dt);  //一个圆弧上总共取n个点
 glBegin(GL_POINTS);
 if (a > b) {
  glVertex2f(x + c, y); glVertex2f(x - c, y);
 }
 else {
  glVertex2f(y, x + c); glVertex2f(y, x - c);
 }
 glEnd();
 glBegin(GL_LINE_LOOP);
 for (int i = 0; i < n; i++)
 {
  int cost = a * cos(i*dt);
  int sint = b * sin(i*dt);
  if (a > b)
   glVertex2i(x + cost, y + sint);
  else
   glVertex2i(y + sint, x + cost);
 }
 glEnd();
}
//神奇代码---->控制放大后图像不变形
void ChangeSize(GLsizei w, GLsizei h)
{
 if (h == 0)     h = 1;
 // 设置视区尺寸
 glViewport(0, 0, w, h);
 // 重置座标系统
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 // 建立修剪空间的范围
 if (w <= h)
  glOrtho(0.0f, 250.0f, 0.0f, 250.0f*h / w, 1.0, -1.0);
 else
  glOrtho(0.0f, 250.0f*w / h, 0.0f, 250.0f, 1.0, -1.0);
}
void display(void) {
 glClear(GL_COLOR_BUFFER_BIT);
 glColor3f(1.0, 0.0f, 0.0f);
 glBegin(GL_LINE_STRIP);
 Arcellipse(150, 50, 30, 40);
 glFlush();
}
int main(int argc, char *argv[])
{
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
 glutInitWindowPosition(100, 100);
 glutInitWindowSize(400, 400);
 glutCreateWindow("角度离散法画椭圆");
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 gluOrtho2D(-100.0, 100.0, -100.0, 100.0);
 glutDisplayFunc(display);
 glutReshapeFunc(ChangeSize);
 glutMainLoop();
 return 0;
}

运行结果:
在这里插入图片描述

在这里插入图片描述
完整代码:

#include<GL/glut.h>
#include<windows.h>
#include<math.h>
void Arcellipse(int xc, int yc, double r, double ts, double te)
{
 double pi = 3.1415926;
 if (te < ts)  //当终止角比起始角还小时,则将终止角加上2π
  te += 2 * pi;
 double dt = 0.4 / r;
 double ds = 40 / r; //取角度离散值,使其与半径r成反比
 int n = (int)((te - ts) / dt + 0.5); //确定总步数
 double ta = ts;
 int x = xc + int(r*cos(ts));
 int y = yc + int((r*ds)*sin(ts));
 glBegin(GL_LINE_STRIP); //如果绘制整圆,选GL_LINE_LOOP更好
 glVertex2f(x, y);
 for (int i = 1; i <= n; i++)
 {
  ta += i * dt;
  double cost = cos(ta);
  double sint = sin(ta);
  x = int(xc + r * cost);
  y = int(yc + (r*ds) * sint);
  glVertex2f(x, y);
 }
 glEnd();
}
void ChangeSize(GLsizei w, GLsizei h)
{
 if (h == 0)     h = 1;
 // 设置视区尺寸
 glViewport(0, 0, w, h);
 // 重置座标系统
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 // 建立修剪空间的范围
 if (w <= h)
  glOrtho(0.0f, 250.0f, 0.0f, 250.0f*h / w, 1.0, -1.0);
 else
  glOrtho(0.0f, 250.0f*w / h, 0.0f, 250.0f, 1.0, -1.0);
}
void display(void) {
 glClear(GL_COLOR_BUFFER_BIT);
 glColor3f(0.0, 0.0f, 1.0f);
 glBegin(GL_LINE_STRIP);
 Arcellipse(100, 100, 100, 0, 100);
 glFlush();
}
int main(int argc, char *argv[])
{
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
 glutInitWindowPosition(400, 400);
 glutInitWindowSize(400, 400);
 glutCreateWindow("角度离散法画圆");
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 gluOrtho2D(-200.0, 200.0, -200.0, 200.0);
 glutDisplayFunc(display);
 glutReshapeFunc(ChangeSize);
 glutMainLoop();
 return 0;
}

运行结果:
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章