角度離散法畫畫弧和橢圓

角度離散法可以利用已有的直線算法來分段繪製圓弧、橢圓弧。這種方法的優點在於可以自由控制所繪製的弧的角度範圍。

在這裏插入圖片描述
完整代碼:

#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;
}

運行結果:
在這裏插入圖片描述

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