VS-openGL 绘制五角星


前言

初学计算机图形学以及VS、OpenGL,只作为参考,无权威性可言,有问题欢迎大家在评论区提出,如果帮到你了,可以留个点赞再走。

一、核心思路

五角星的十个顶点由同心圆的十个顶点构成。通过同心圆的圆心坐标、大圆半径R、小圆半径r计算出十个顶点的坐标,然后通过绘制线段/三角形来绘制五角星。(计算比较简单,根据下图即可计算出十个顶点的坐标,这里就省略了)
在这里插入图片描述

二、源码

#include <GL/glew.h>//OpenGL扩展库
#include <GL/glut.h>//OpenGL工具库
#include <stdio.h>
#include <math.h>

// 绘制五角星核心思路:求出五角星的十个顶点再通过绘制线段/三角形连接起来即可

// 定义Π
#define PI 3.14159265

// 定义坐标结构体
struct Vertex {
	double x;
	double y;
};

// 绘制线段函数
void drawLine(Vertex Vertex_Fir, Vertex Vertex_Sec) {
	// 设置颜色
	glColor3f(1, 0, 0);
	// 设置绘制类型
	glBegin(GL_LINES);
	// 第一个坐标
	glVertex2f(Vertex_Fir.x, Vertex_Fir.y);
	// 第二个坐标
	glVertex2f(Vertex_Sec.x, Vertex_Sec.y);
	glEnd();
}

// 绘制红色三角形函数
void drawRedTriangle(Vertex Vertex_Fir, Vertex Vertex_Sec, Vertex Vertex_Thi) {
	// 设置填充的颜色
	glColor3f(1, 0, 0);
	// 设置绘制类型
	glBegin(GL_TRIANGLES);
	// 第一个坐标
	glVertex2f(Vertex_Fir.x, Vertex_Fir.y);
	// 第二个坐标
	glVertex2f(Vertex_Sec.x, Vertex_Sec.y);
	// 第三个坐标
	glVertex2f(Vertex_Thi.x, Vertex_Thi.y);
	glEnd();
}

// 绘制蓝色三角形函数
void drawBlueTriangle(Vertex Vertex_Fir, Vertex Vertex_Sec, Vertex Vertex_Thi) {
	// 设置填充的颜色
	glColor3f(0, 0, 255);//深蓝色
	// 设置绘制类型
	glBegin(GL_TRIANGLES);
	// 第一个坐标
	glVertex2f(Vertex_Fir.x, Vertex_Fir.y);
	// 第二个坐标
	glVertex2f(Vertex_Sec.x, Vertex_Sec.y);
	// 第三个坐标
	glVertex2f(Vertex_Thi.x, Vertex_Thi.y);
	glEnd();
}

// 获取外圆五角星的五顶点(参数:大圆圆心坐标以及半径)
Vertex* getExternalVertex(Vertex Center_Vertex, double R) {
	// 定义Vertex结构体数组,包括五个顶点和一个圆心
	Vertex* externalVertex = new Vertex[6];
	double alpha = 2*PI / 5;
	double thet = PI / 10;
	double bet = 2*PI / 10;
	// 圆心坐标
	externalVertex[0].x = Center_Vertex.x, externalVertex[0].y = Center_Vertex.y;
	// 其余五个顶点
	externalVertex[1].x = Center_Vertex.x, externalVertex[1].y = Center_Vertex.y+R;
	externalVertex[2].x = Center_Vertex.x+R*cos(thet), externalVertex[2].y = Center_Vertex.y+R*sin(thet);
	externalVertex[3].x = Center_Vertex.x+R*sin(bet), externalVertex[3].y = Center_Vertex .y-R*cos(bet);
	externalVertex[4].x = Center_Vertex.x-R*sin(bet), externalVertex[4].y = Center_Vertex.y-R*cos(bet);
	externalVertex[5].x = Center_Vertex.x-R*cos(thet), externalVertex[5].y = Center_Vertex.y+R*sin(thet);
	
	return externalVertex;
}

// 获取内圆五角星的五顶点(参数:小圆圆心坐标以及半径)
Vertex* getInternalVertex(Vertex Center_Vertex, double r) {
	// 定义Vertex结构体数组,包括五个顶点和一个圆心
	Vertex* internalVertex = new Vertex[6];
	double alpha = 2 * PI / 5;
	double thet = PI / 10;
	double bet = (PI-alpha) / 2;
	// 圆心坐标
	internalVertex[0].x = Center_Vertex.x, internalVertex[0].y = Center_Vertex.y;
	// 其余五个顶点
	internalVertex[1].x = Center_Vertex.x + r * cos(bet), internalVertex[1].y = Center_Vertex.y + r * sin(bet);
	internalVertex[2].x = Center_Vertex.x + r * cos(thet), internalVertex[2].y = Center_Vertex.y - r * sin(thet);//
	internalVertex[3].x = Center_Vertex.x, internalVertex[3].y = Center_Vertex.y - r;//
	internalVertex[4].x = Center_Vertex.x - r * cos(thet), internalVertex[4].y = Center_Vertex.y - r * sin(thet);
	internalVertex[5].x = Center_Vertex.x - r * cos(bet), internalVertex[5].y = Center_Vertex.y + r * sin(bet);
	
	return internalVertex;
}

// 设置背景颜色
void setBackgroundColor(void) {
	glClearColor(0.2, 0.3, 0.3, 0.5);
}

// 绘制五角星
void draw(void) {
	// 清除清缓存
	glClear(GL_COLOR_BUFFER_BIT);

	// ### 绘制线框五角星 ###
	// 1. 定义圆心、大小圆半径
	Vertex Center_Vertex;
	Center_Vertex.x = 500, Center_Vertex.y =150;//圆心以显示窗口的左下角为原点,向右x轴正方向,向上y轴正方向
	double R = 100;
	double r = 40;
	// 2. 获取内外顶点
	Vertex* externalVertex = getExternalVertex(Center_Vertex, R);
	Vertex* internalVertex = getInternalVertex(Center_Vertex, r);
	// 3. 绘制线框五角星
	for (int i = 1; i < 6; i++) {
		drawLine(externalVertex[i], internalVertex[i]);
		if (i < 5) {
			drawLine(internalVertex[i], externalVertex[i + 1]);
		}
		else {
			drawLine(internalVertex[i], externalVertex[1]);
		}
	}

	// ### 绘制红色五角星 ###
	// 1. 定义圆心、大小圆半径
	Center_Vertex.x = 500, Center_Vertex.y = 350;
	R = 100, r = 40;
	// 2. 获取内外顶点
	externalVertex = getExternalVertex(Center_Vertex, R);
	internalVertex = getInternalVertex(Center_Vertex, r);
	// 3. 绘制红色五角星
	for (int i = 1; i < 6; i++) {
		drawRedTriangle(Center_Vertex, internalVertex[i], externalVertex[i]);
		if (i < 5) {
			drawRedTriangle(Center_Vertex, internalVertex[i], externalVertex[i+1]);
		}
		else {
			drawRedTriangle(Center_Vertex, internalVertex[i], externalVertex[1]);
		}
	}

	// ### 绘制多色五角星 ###
	// 1. 定义圆心、大小圆半径
	Center_Vertex.x = 500, Center_Vertex.y = 550;
	R = 100, r = 40;
	// 2. 获取内外顶点
	externalVertex = getExternalVertex(Center_Vertex, R);
	internalVertex = getInternalVertex(Center_Vertex, r);
	// 3. 绘制多色五角星
	for (int i = 1; i < 6; i++) {
		// 绘制红色三角形
		drawRedTriangle(Center_Vertex, internalVertex[i], externalVertex[i]);
		// 绘制蓝色三角形
		if (i < 5) {
			drawBlueTriangle(Center_Vertex, internalVertex[i], externalVertex[i + 1]);
		}
		else {
			drawBlueTriangle(Center_Vertex, internalVertex[i], externalVertex[1]);
		}
	}
	glutSwapBuffers();//交换缓冲(双缓冲时使用)
}

void reshape(int width, int height)
{
	glViewport(0, 0, width, height);//设置视区

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0, width, 0, height);//设置图形数据范围
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

int main() {
	// 窗口的坐标是电脑屏幕左上角为原点,向右为x轴正方向;向下为y轴正方向
	glutInitWindowPosition(100, 100); //定义窗口位置与大小
	glutInitWindowSize(1200, 700);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); //初始化显示模式
	glutCreateWindow("五角星"); //定义窗口名称

	setBackgroundColor(); // 设置背景色

	glutDisplayFunc(draw); //图形绘制函数
	glutReshapeFunc(reshape); //窗口重绘函数
	glutMainLoop(); //无限循环函数 
	return 0;
}

三、其他小知识

  1. 定义显示窗口位置与大小时:参考坐标系是电脑屏幕左上角为原点,向右为x轴正方向;向下为y轴正方向
    在这里插入图片描述

  2. 绘制图形时使用的坐标:参考坐标系是显示窗口的左下角为原点,向右x轴正方向,向上y轴正方向
    在这里插入图片描述

  • 6
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值