主要是五角星的绘制,怎样才能优雅地绘制出准确的五角星呢?
通过画五个金色的四边形来完成对五角星的绘制
通过P、Q两点的坐标,计算出M、N的坐标,进而绘制出四边形。
然后根据P、Q坐标,计算出其他四个五角星顶点的坐标,依上法绘制其余四边形
完成五角星绘制
根据两个条件:
在QMN中的角度列方程组,计算得Q为36
同时,P 是五分之一圆周角, 72
根据MPH 和 MQH 的tan 关系, 可以得到:
可以得到向量关系:
可根据向量关系由P、Q坐标算M、N的坐标
void mglstar5(GLfloat centerX, GLfloat centerY, GLfloat endX, GLfloat endY){
for (int i = 0; i < 5; i++)
{
mglstar5_part(centerX, centerY, endX, endY);
rotate(centerX, centerY, &endX, &endY, 2*PI/5);
}
}
依次根据(centerX, centerY) (endX, endY)来绘制五分之一五角星四边形
并对该向量进行一次旋转72度操作
void rotate(GLfloat centerX, GLfloat centerY, GLfloat* endX, GLfloat* endY, float rad){
Vector2f vector = { *endX - centerX, *endY - centerY };
Vector2f resultV = {
cos(rad) * vector.x + sin(rad) * vector.y,
cos(rad) * vector.y + sin(rad) * (-vector.x)
};
*endX = centerX + resultV.x;
*endY = centerY + resultV.y;
}
根据上步理论分析
计算出旋转中心到端点的向量
并以此求出新的坐标
将新坐标存入原地址
void mglstar5_part(GLfloat centerX, GLfloat centerY, GLfloat endX, GLfloat endY){
float cf1 = tan(PI / 10) / (tan(PI / 5) + tan(PI / 10));
float cf2 = tan(PI / 5);
Vector2f PQ = { endX - centerX, endY - centerY };
Vector2f PH = { cf1 * PQ.x, cf1 * PQ.y };
Vector2f HM = { cf2 * PH.y, cf2 * (-PH.x) };
Vector2f M = { centerX + PH.x + HM.x, centerY + PH.y + HM.y };
Vector2f N = { centerX + PH.x - HM.x, centerY + PH.y - HM.y };
glBegin(GL_POLYGON);
glVertex2f(centerX, centerY);
glVertex2f(M.x, M.y);
glVertex2f(endX, endY);
glVertex2f(N.x, N.y);
glEnd();
}
先根据上一步的理论分析算出四个顶点,然后再绘制四边形
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1, 0, 0);
glBegin(GL_QUADS);
glVertex2f(-0.9, 0.6);
glVertex2f(0.9, 0.6);
glVertex2f(0.9, -0.6);
glVertex2f(-0.9, -0.6);
glEnd();
glColor3f(1, 1, 0);
//main star
mglstar5(-0.60, 0.30, -0.78, 0.36);
//four-star
mglstar5(-0.30, 0.48, -0.24, 0.48);
mglstar5(-0.18, 0.36, -0.24, 0.36);
mglstar5(-0.18, 0.18, -0.18, 0.24);
mglstar5(-0.30, 0.06, -0.24, 0.06);
glutSwapBuffers();
}
根据国旗比例,在合适位置调用五角星函数绘制
#include "gl/glut.h"
#include
#define PI 3.1415926535898
typedef struct Vector2fDefine
{
GLfloat x;
GLfloat y;
} Vector2f;
void mglstar5(GLfloat centerX, GLfloat centerY, GLfloat endX, GLfloat endY);
void rotate(GLfloat centerX, GLfloat centerY, GLfloat* endX, GLfloat* endY, float rad);
void mglstar5_part(GLfloat centerX, GLfloat centerY, GLfloat endX, GLfloat endY);
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1, 0, 0);
glBegin(GL_QUADS);
glVertex2f(-0.9, 0.6);
glVertex2f(0.9, 0.6);
glVertex2f(0.9, -0.6);
glVertex2f(-0.9, -0.6);
glEnd();
glColor3f(1, 1, 0);
//main star
mglstar5(-0.60, 0.30, -0.78, 0.36);
//four-star
mglstar5(-0.30, 0.48, -0.24, 0.48);
mglstar5(-0.18, 0.36, -0.24, 0.36);
mglstar5(-0.18, 0.18, -0.18, 0.24);
mglstar5(-0.30, 0.06, -0.24, 0.06);
glutSwapBuffers();
}
int main (int argc, char *argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
glutInitWindowPosition(10, 10);
glutInitWindowSize(400, 400);
glutCreateWindow("Simple GLUT App");
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
void mglstar5(GLfloat centerX, GLfloat centerY, GLfloat endX, GLfloat endY){
for (int i = 0; i < 5; i++)
{
mglstar5_part(centerX, centerY, endX, endY);
rotate(centerX, centerY, &endX, &endY, 2*PI/5);
}
}
void mglstar5_part(GLfloat centerX, GLfloat centerY, GLfloat endX, GLfloat endY){
float cf1 = tan(PI / 10) / (tan(PI / 5) + tan(PI / 10));
float cf2 = tan(PI / 5);
Vector2f PQ = { endX - centerX, endY - centerY };
Vector2f PH = { cf1 * PQ.x, cf1 * PQ.y };
Vector2f HM = { cf2 * PH.y, cf2 * (-PH.x) };
Vector2f M = { centerX + PH.x + HM.x, centerY + PH.y + HM.y };
Vector2f N = { centerX + PH.x - HM.x, centerY + PH.y - HM.y };
glBegin(GL_POLYGON);
glVertex2f(centerX, centerY);
glVertex2f(M.x, M.y);
glVertex2f(endX, endY);
glVertex2f(N.x, N.y);
glEnd();
}
void rotate(GLfloat centerX, GLfloat centerY, GLfloat* endX, GLfloat* endY, float rad){
Vector2f vector = { *endX - centerX, *endY - centerY };
Vector2f resultV = {
cos(rad) * vector.x + sin(rad) * vector.y,
cos(rad) * vector.y + sin(rad) * (-vector.x)
};
*endX = centerX + resultV.x;
*endY = centerY + resultV.y;
}