Codeblocks 利用GLUT 画出矩形,直线,三角形,圆形图案并实现翻转,镜像,变色放大缩小等功能
实验要求:开发一个画图程序,用户可以用鼠标绘制线段、矩形、圆和三角形等。通过菜单让用户选择需要绘制的图元。
注意:一定要加上<windows.h>库否则无法通过编译
#include <time.h>
#include <stdio.h>
#include <math.h>
#include <windows.h>
#include <stdlib.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif#define PI 3.1415926int ww = 500;
int wh = 500;int need_rotate = 0;//旋转标识
//color 便于修改颜色
float red = 1;
float green = 1;
float blue = 1;
//coordinates
struct cor
{float x;float y;
};//存储坐标结构体
//3个坐标,用于存储直线(2个)、三角形(3个)、矩形(2个)绘制时的坐标
struct cor cc1;
struct cor cc2;
struct cor cc3;int mode = 0;//选择绘画模式,line、triangle、rectangle三种,默认为line
int dots_now = 0;//记录已经确定的坐标个数
struct pics
{int mode;struct cor c1;struct cor c2;struct cor c3;
};//一个图形所有点的坐标结构体
struct pics saved_cords[100];//可存储100个图形的坐标和绘制模式
int ptr = -1;//如上结构体的计数指针
int reDrawMode =0;//重画模式,用于绘制新图形后,补画之前的图形
int mirrorMode =0;//镜像模式
//func delc
void reDraw();
void draw_one_line(struct cor c1,struct cor c2);
void draw_triangle(struct cor c1,struct cor c2,struct cor c3);
void draw_rectangle(struct cor c1,struct cor c2);
void display();
void main_menu_func(int option);
void sub_menu_draw_mode_func(int option);
void sub_menu_move_func(int option);
void myinit(void);
void mouse_move(int x, int y);
void mouse(int btn, int state, int x, int y);
void myReshape(GLsizei w, GLsizei h);void draw_one_line(struct cor c1,struct cor c2)
{//绘制直线函数if (need_rotate == 1){//平移-旋转-平移操作int mid_x = (c1.x + c2.x) / 2;int mid_y = (c1.y + c2.y) / 2;glTranslated(mid_x, mid_y, 0);glRotated(60, 0, 0, 1);glTranslated(-mid_x, -mid_y, 0);need_rotate = 0;}if(reDrawMode == 0){//在重画函数调用当前函数时,不需要清除背景glClear(GL_COLOR_BUFFER_BIT);}glColor3f(red, green, blue);if(mirrorMode == 0){glBegin(GL_LINE_LOOP);}else{//mirror mode,镜像画图,四个象限会对称画图glBegin(GL_LINES);//lines,2个2个坐标成对画直线glVertex2f(c1.x,-c1.y);//4thglVertex2f(c2.x,-c2.y);glVertex2f(-c1.x,-c1.y);//3rdglVertex2f(-c2.x,-c2.y);glVertex2f(-c1.x,c1.y);//2ndglVertex2f(-c2.x,c2.y);}glVertex2f(c1.x, c1.y);glVertex2f(c2.x, c2.y);glEnd();glFlush();
}
void draw_triangle(struct cor c1,struct cor c2,struct cor c3)
{//绘制三角形if (need_rotate == 1){//旋转int mid_x = (c1.x + c2.x + c3.x) / 3;int mid_y = (c1.y + c2.y + c3.y) / 3;glTranslated(mid_x, mid_y, 0);glRotated(60, 0, 0, 1);glTranslated(-mid_x, -mid_y, 0);need_rotate = 0;}if(reDrawMode == 0){glClear(GL_COLOR_BUFFER_BIT);//reDraw();}glColor3f(red, green, blue);if(mirrorMode == 0)glBegin(GL_TRIANGLES);else{glBegin(GL_TRIANGLES);//每3个坐标就能绘制一个三角形glVertex2f(c1.x,-c1.y);//4thglVertex2f(c2.x,-c2.y);glVertex2f(c3.x,-c3.y);glVertex2f(-c1.x,-c1.y);//3rdglVertex2f(-c2.x,-c2.y);glVertex2f(-c3.x,-c3.y);glVertex2f(-c1.x,c1.y);//2ndglVertex2f(-c2.x,c2.y);glVertex2f(-c3.x,c3.y);}glVertex2f(c1.x, c1.y);glVertex2f(c2.x, c2.y);glVertex2f(c3.x, c3.y);glEnd();glFlush();}
void draw_rectangle(struct cor c1,struct cor c2)
{//绘制矩形,用两个点绘制,分别是左上和右下点if (need_rotate == 1){//旋转int mid_x = (c1.x + c2.x) / 2;int mid_y = (c1.y + c2.y) / 2;glTranslated(mid_x, mid_y, 0);glRotated(60, 0, 0, 1);glTranslated(-mid_x, -mid_y, 0);need_rotate = 0;}if(reDrawMode == 0){glClear(GL_COLOR_BUFFER_BIT);//reDraw();}glColor3f(red, green, blue);if(mirrorMode == 0)glBegin(GL_QUADS);else{glBegin(GL_QUADS);//每4个坐标就能绘制出一个矩形glVertex2f(c1.x,-c1.y);//4thglVertex2f(c1.x,-c2.y);glVertex2f(c2.x,-c2.y);glVertex2f(c2.x,-c1.y);glVertex2f(-c1.x,-c1.y);//3rdglVertex2f(-c1.x,-c2.y);glVertex2f(-c2.x,-c2.y);glVertex2f(-c2.x,-c1.y);glVertex2f(-c1.x,c1.y);//2ndglVertex2f(-c1.x, c2.y);glVertex2f(-c2.x, c2.y);glVertex2f(-c2.x, c1.y);}// glBegin(GL_LINE_LOOP);glVertex2f(c1.x, c1.y);glVertex2f(c1.x, c2.y);glVertex2f(c2.x, c2.y);glVertex2f(c2.x, c1.y);glEnd();glFlush();
}
void draw_cycle(struct cor c1,struct cor c2)
{//绘制圆形,用两个点绘制,分别是圆心和圆周上一点glBegin(GL_POLYGON);float R= sqrt(float((c1.x-c2.x)*(c1.x-c2.x)+(c1.y-c2.y)*(c1.y-c2.y))) / 2;float dx = (c1.x+c2.x) / 2;float dy = (c1.y+c2.y) / 2;int n=100;for(int i=0;i<n;i++){glVertex2f(R*cos(2*PI*i/n)+dx,R*sin(2*PI*i/n)+dy);}glEnd();glFlush();
}
void display()
{//显示函数if (mode == 0){ //draw linedraw_one_line(cc1,cc2);}if (mode == 1){ //draw triangledraw_triangle(cc1,cc2,cc3);}if (mode == 2){ //draw rectangledraw_rectangle(cc1,cc2);}if (mode == 3){ //draw cycledraw_cycle(cc1,cc2);}//dots_now = 0;
}
void main_menu_func(int option)
{if (option == 0){ //Set pic to random colorsrand(time(NULL));red = rand() % 100 / 100.00;green = rand() % 100 / 100.00;blue = rand() % 100 / 100.00;}if (option == 1){ //zoom in 放大(缩放投影范围)ww -= 50;wh -= 50;glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-ww, ww, -wh, wh, -1.0, 1.0);}if (option == 2){ //zoom outww += 50;wh += 50;glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-ww, ww, -wh, wh, -1.0, 1.0);}if (option == 3){ //rotateneed_rotate = 1;}if (option == 4){ //clear 清除屏幕上的图形glClear(GL_COLOR_BUFFER_BIT);ptr = -1;glFlush();return;}if (option == 5){ //mirror modemirrorMode += 1;mirrorMode %= 2;//两种取值范围,0(关),1(开),重复点击切换}if (option == -1){ //exit testexit(0);}if (mode == 0)draw_one_line(cc1,cc2);if (mode == 1)draw_triangle(cc1,cc2,cc3);if (mode == 2)draw_rectangle(cc1,cc2);if (mode == 3)draw_cycle(cc1,cc2);
}
void sub_menu_draw_mode_func(int option)
{//绘制模式子菜单if (option == 0){mode = 0; //line modedots_now = 0;}if (option == 1){mode = 1; //tri modedots_now = 0;}if (option == 2){mode = 2; //rect modedots_now = 0;}if (option == 3){mode = 3; //cycle modedots_now = 0;}
}
void sub_menu_move_func(int option)
{//移动图形子菜单if (option == 0){ //upcc1.y += 50;cc2.y += 50;cc3.y += 50;}if (option == 1){ //downcc1.y -= 50;cc2.y -= 50;cc3.y -= 50;}if (option == 2){ //leftcc1.x -= 50;cc2.x -= 50;cc3.x -= 50;}if (option == 3){ //rightcc1.x += 50;cc2.x += 50;cc3.x += 50;}if (mode == 0)draw_one_line(cc1,cc2);if (mode == 1)draw_triangle(cc1,cc2,cc3);if (mode == 2)draw_rectangle(cc1,cc2);if (mode == 3)draw_cycle(cc1,cc2);
}
void myinit(void)
{glClearColor(0.0, 0.0, 0.0, 1.0);glShadeModel(GL_FLAT);glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-ww, ww, -wh, wh, -1.0, 1.0);
}
void mouse_move(int x, int y)
{//监听鼠标移动函数,用于实时画图if (dots_now == 1 && (mode == 0 || mode == 1 || mode == 2 || mode ==3)){ //这种情况下只能预览出线条或矩形或圆形printf("mouse loc x:%d,y%d\n", x, y);// sleep(1);y = wh - y;//以下为坐标系变换x -= ww / 2;y -= wh / 2;x *= 2 * ww / 500;y *= 2 * wh / 500;cc2.x = x;cc2.y = y;if (mode == 1)draw_one_line(cc1,cc2);else if(mode ==2)draw_rectangle(cc1,cc2);else if(mode ==3)draw_cycle(cc1,cc2);}if (dots_now == 2 && mode == 1){ //tri 已经画出了一条线,预览即将绘制的三角形的情况printf("mouse loc x:%d,y%d\n", x, y);y = wh - y;//以下为坐标系变换x -= ww / 2;y -= wh / 2;x *= 2 * ww / 500;y *= 2 * wh / 500;cc3.x = x;cc3.y = y;draw_triangle(cc1,cc2,cc3);}
}
void mouse(int btn, int state, int x, int y)
{//每次鼠标左键点击记录画图坐标if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN){printf("click:x:%d,y:%d\n", x, y);printf("\tc1.x=%f,c1.y=%f\n", cc1.x, cc1.y);printf("\tc2.x=%f,c2.y=%f\n", cc2.x, cc2.y);printf("\tc3.x=%f,c3.y=%f\n", cc3.x, cc3.y);//坐标系变换y = wh - y;x -= ww / 2;y -= wh / 2;x *= 2 * ww / 500;y *= 2 * wh / 500;switch (dots_now){case 0:cc1.x = x;cc1.y = y;break;case 1:cc2.x = x;cc2.y = y;if (mode != 1){//不等于三角形模式,说明已经记录了两个点,马上确定绘制dots_now = -1;//重置点的计数器++ptr;if(mode == 0)saved_cords[ptr].mode = 0;//记录当前图形的绘制模式,用于重画else if(mode == 2)saved_cords[ptr].mode = 2;//记录当前图形的绘制模式,用于重画else if(mode == 3)saved_cords[ptr].mode = 3;//记录当前图形的绘制模式,用于重画saved_cords[ptr].c1 = cc1;saved_cords[ptr].c2 = cc2;//reDraw();}break;case 2:cc3.x = x;cc3.y = y;++ptr;saved_cords[ptr].mode = 1;//记录当前图形的绘制模式,用于重画saved_cords[ptr].c1 = cc1;saved_cords[ptr].c2 = cc2;saved_cords[ptr].c3 = cc3;dots_now = -1;//重置点的计数器//reDraw();break;default:break;}++dots_now;}
}
void reDraw()
{//每画一个新的图形后,把以前绘制的图形全部重画一次reDrawMode = 1;for(int i=0;i<=ptr;++i){if(saved_cords[i].mode == 0){draw_one_line(saved_cords[i].c1,saved_cords[i].c2);continue;}if(saved_cords[i].mode == 1){draw_triangle(saved_cords[i].c1,saved_cords[i].c2,saved_cords[i].c3);continue;}if(saved_cords[i].mode == 2){draw_rectangle(saved_cords[i].c1,saved_cords[i].c2);continue;}if(saved_cords[i].mode == 3){draw_cycle(saved_cords[i].c1,saved_cords[i].c2);continue;}}reDrawMode = 0;
}
void myReshape(GLsizei w, GLsizei h)
{/* adjust clipping box */glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-w, w, -h, h, -1.0, 1.0);/* adjust viewport and clear */glViewport(0, 0, w, h);ww = w;wh = h;
}/* Main Loop* Open window with initial window size, title bar,* RGBA display mode, and handle input events.*/
int main(int argc, char **argv)
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(ww, wh);glutCreateWindow("rubber_banding");int sub_menu1 = glutCreateMenu(sub_menu_draw_mode_func);glutAddMenuEntry("line", 0);glutAddMenuEntry("triangle", 1);glutAddMenuEntry("rectangle", 2);glutAddMenuEntry("cycle", 3);int sub_menu2 = glutCreateMenu(sub_menu_move_func);glutAddMenuEntry("Up", 0);glutAddMenuEntry("Down", 1);glutAddMenuEntry("Left", 2);glutAddMenuEntry("Right", 3);glutCreateMenu(main_menu_func);glutAddSubMenu("Draw:", sub_menu1);glutAddSubMenu("Move:", sub_menu2);glutAddMenuEntry("Set new color", 0);glutAddMenuEntry("Zoom In", 1);glutAddMenuEntry("Zoom Out", 2);glutAddMenuEntry("Rotate", 3);glutAddMenuEntry("Mirror",5);glutAddMenuEntry("Clear",4);glutAddMenuEntry("Exit", -1);glutAttachMenu(GLUT_RIGHT_BUTTON);glutDisplayFunc(display);glutReshapeFunc(myReshape);glutPassiveMotionFunc(mouse_move);glutIdleFunc(reDraw);glutMouseFunc(mouse);myinit();glutMainLoop();
}
实验结果截图及功能实现
主菜单:
Draw中有:line,triangle,rectangle,cycle四种选择,分别代表直线,三角形,矩形和圆形。
画图:
2.Move功能:
可实现对已经画出所有图形的上下左右的移动。
3.Set new color
可改变已经画出所有图形的颜色的改变。
- Zoom in 和Zoom out 放大缩小函数
- Rotate 旋转函数
- mirror 镜像函数
实验反思
在实验中,首先是C++中库的问题,添加上了<window.h>库,否则无法通过编译。
在设计重画之前已经存在的函数时没有考虑充分,遇到了许多bug,比如在画三角形以及矩形时会出现画圆时出现的界面。
Codeblocks 利用GLUT 画出矩形,直线,三角形,圆形图案并实现翻转,镜像,变色放大缩小等功能相关推荐
- python打印长方形_利用python打印出菱形、三角形以及矩形的方法实例
前言 本文主要给大家介绍了关于利用python打印出菱形.三角形以及矩形的相关内容,分享出来供大家参考学习,话不多说,来一起看看详细的介绍: 实例代码 #coding:utf-8 rows = int ...
- Linux ubuntu18.04.4下如何利用CPU利用率画出50%直线、正弦曲线、心形曲线
Linux ubuntu18.04.4下如何利用CPU利用率画出50%直线.正弦曲线.心形曲线 记录一下,经过了各种失败以后,本菜鸡在一步步的尝试中终于成功画出了曲线.整理一下,我经历的最主要问题如下 ...
- 利用html5画出五角星画出星空
利用html5画出五角星 (在慕课网学习<canvas>标签后代码总结) 五角星的格定点坐标该如何定位?原理图如下: 源代码: <!DOCTYPE HTML> <html ...
- python画曲线-利用python画出AUC曲线的实例
以load_breast_cancer数据集为例,模型细节不重要,重点是画AUC的代码. 直接上代码: from sklearn.datasets import load_breast_cancer ...
- python中词云图怎样变成特殊图案_如何利用python画出一个多变的词云图?(1)...
问题描述: 如何利用python画出一个多变的词云图? 解决方法:import numpy as np import matplotlib import matplotlib.pyplot as pl ...
- python怎么画出圆润的曲线_利用python画出AUC曲线的实例
以load_breast_cancer数据集为例,模型细节不重要,重点是画AUC的代码. 直接上代码: from sklearn.datasets import load_breast_cancer ...
- python画二维温度云图_利用python画出词云图
本文将介绍如何利用python中相应的模块画出词云图.首先给出效果图: 其中词云图中的词汇是对手机短信中的垃圾短信的统计,字体越大表示在垃圾短信中出现的频次越高.下面给出具体的步骤. 读取" ...
- 检测视频中的人脸,并画出矩形框
检测视频中的人脸,并画出矩形框,这是一个测试程序,由于很多人经常会用到,写下以备不时之需. #include"stdafx.h" #include <opencv2/core ...
- 为什么我的cairo画出的直线不同角度宽度不同???
文章目录 一.为什么我的cairo画出的直线不同角度宽度不同??? 二.再看Cairo官方API介绍 cairo_set_line_width () 三.修改code实现不修改CTM情况下的坐标变换 ...
最新文章
- Facebook发布人工智能产品DeepText:能以人类智商
- kindle 笔记/标注导出
- 你的 GitHub 代码已打包运往北极,传给 1000 年后人类
- PHP的数据类型、浮点型比较
- 论文笔记_S2D.55_2019_SLAM综述_Huang B. A Survey of Simultaneous Localization and Mapping
- linux 查看端口
- 【视频转换】监控视频DAV转mp4
- Excel数据可视化表盘模板
- Matlab常用的滤波函数集合(会陆续更新详解)
- 安徽计算机软件工程学院,安徽软件工程专业大学排名
- Python爬虫实战:《战狼2》豆瓣影评分析
- springboot 官网首页
- win10用易语言需要C环境,win10系统易语言打开支持库配置就崩溃的具体教程
- Maya---骨骼的创建
- 《千字文细谈》2021神级程序员都在用什么工具?-09-02
- vue中使用h5 video标签实现弹窗播放本地视频
- 判断有向图中是否存在从vi到vj的路径
- 旷视科技经典文字检测EAST
- c语言 青蛙上台阶问题
- jQuery选择器(二)