角度離散法可以利用已有的直線算法來分段繪製圓弧、橢圓弧。這種方法的優點在於可以自由控制所繪製的弧的角度範圍。
完整代碼:
#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;
}
運行結果: