实验要求:开发一个画图程序,用户可以用鼠标绘制线段、矩形、圆和三角形等。通过菜单让用户选择需要绘制的图元。

注意:一定要加上<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

可改变已经画出所有图形的颜色的改变。

  1. Zoom in 和Zoom out 放大缩小函数

 

  1. Rotate 旋转函数

  1. mirror 镜像函数

 

实验反思

在实验中,首先是C++中库的问题,添加上了<window.h>库,否则无法通过编译。

在设计重画之前已经存在的函数时没有考虑充分,遇到了许多bug,比如在画三角形以及矩形时会出现画圆时出现的界面。

Codeblocks 利用GLUT 画出矩形,直线,三角形,圆形图案并实现翻转,镜像,变色放大缩小等功能相关推荐

  1. python打印长方形_利用python打印出菱形、三角形以及矩形的方法实例

    前言 本文主要给大家介绍了关于利用python打印出菱形.三角形以及矩形的相关内容,分享出来供大家参考学习,话不多说,来一起看看详细的介绍: 实例代码 #coding:utf-8 rows = int ...

  2. Linux ubuntu18.04.4下如何利用CPU利用率画出50%直线、正弦曲线、心形曲线

    Linux ubuntu18.04.4下如何利用CPU利用率画出50%直线.正弦曲线.心形曲线 记录一下,经过了各种失败以后,本菜鸡在一步步的尝试中终于成功画出了曲线.整理一下,我经历的最主要问题如下 ...

  3. 利用html5画出五角星画出星空

    利用html5画出五角星 (在慕课网学习<canvas>标签后代码总结) 五角星的格定点坐标该如何定位?原理图如下: 源代码: <!DOCTYPE HTML> <html ...

  4. python画曲线-利用python画出AUC曲线的实例

    以load_breast_cancer数据集为例,模型细节不重要,重点是画AUC的代码. 直接上代码: from sklearn.datasets import load_breast_cancer ...

  5. python中词云图怎样变成特殊图案_如何利用python画出一个多变的词云图?(1)...

    问题描述: 如何利用python画出一个多变的词云图? 解决方法:import numpy as np import matplotlib import matplotlib.pyplot as pl ...

  6. python怎么画出圆润的曲线_利用python画出AUC曲线的实例

    以load_breast_cancer数据集为例,模型细节不重要,重点是画AUC的代码. 直接上代码: from sklearn.datasets import load_breast_cancer ...

  7. python画二维温度云图_利用python画出词云图

    本文将介绍如何利用python中相应的模块画出词云图.首先给出效果图: 其中词云图中的词汇是对手机短信中的垃圾短信的统计,字体越大表示在垃圾短信中出现的频次越高.下面给出具体的步骤. 读取" ...

  8. 检测视频中的人脸,并画出矩形框

    检测视频中的人脸,并画出矩形框,这是一个测试程序,由于很多人经常会用到,写下以备不时之需. #include"stdafx.h" #include <opencv2/core ...

  9. 为什么我的cairo画出的直线不同角度宽度不同???

    文章目录 一.为什么我的cairo画出的直线不同角度宽度不同??? 二.再看Cairo官方API介绍 cairo_set_line_width () 三.修改code实现不修改CTM情况下的坐标变换 ...

最新文章

  1. Facebook发布人工智能产品DeepText:能以人类智商
  2. kindle 笔记/标注导出
  3. 你的 GitHub 代码已打包运往北极,传给 1000 年后人类
  4. PHP的数据类型、浮点型比较
  5. 论文笔记_S2D.55_2019_SLAM综述_Huang B. A Survey of Simultaneous Localization and Mapping
  6. linux 查看端口
  7. 【视频转换】监控视频DAV转mp4
  8. Excel数据可视化表盘模板
  9. Matlab常用的滤波函数集合(会陆续更新详解)
  10. 安徽计算机软件工程学院,安徽软件工程专业大学排名
  11. Python爬虫实战:《战狼2》豆瓣影评分析
  12. springboot 官网首页
  13. win10用易语言需要C环境,win10系统易语言打开支持库配置就崩溃的具体教程
  14. Maya---骨骼的创建
  15. 《千字文细谈》2021神级程序员都在用什么工具?-09-02
  16. vue中使用h5 video标签实现弹窗播放本地视频
  17. 判断有向图中是否存在从vi到vj的路径
  18. 旷视科技经典文字检测EAST
  19. c语言 青蛙上台阶问题
  20. jQuery选择器(二)

热门文章

  1. 三菱数控系统PLC格式转换
  2. html 苹果微信录音js,微信jssdk录音功能开发记录
  3. 聚合支付的优势有哪些?
  4. 健康美容的苹果酒营养解析
  5. 个人网红靠直播卖东西赚钱越来越困难 因为电商平台都杀进来了
  6. linux系统下怎么使用lspci,Linux系统之lspci命令介绍
  7. 启用 WebLogic Server 域之间的信任
  8. 两个或多个开关控制一盏灯的电器接线图
  9. mysql xp_cmdshell_SQL xp_cmdshell
  10. git(实现代码存档和同步)