计算机图形学上机作业
我将以作业要求的6个问题分别进行解析
圆绘制问题 模仿着长方形线条的步骤 先创立关于圆的一个类
![](https://i-blog.csdnimg.cn/blog_migrate/7db7536862cb565e2f547d51e1ba55e7.png)
重要的是两点的坐标 1个作为圆心 两个点距离作为半径 然后利用OpenGL函数进行多边形作图 无限逼近 即可达成目标 如下
![](https://i-blog.csdnimg.cn/blog_migrate/c1d238c91f87d4cd628f04b5e988a041.png)
如何在菜单中出现 模仿着新建一个工具箱并在工具箱上面新建自己的一个小圆具体如何实现 代码中有注释不再赘述
![](https://i-blog.csdnimg.cn/blog_migrate/71eb17793c63890b2d3716e7128444c3.png)
然后在drawScene函数中引入这两个功能函数即可看见工具箱 之后就是pickPrimitive函数和mouseControl函数 模仿着改一改即可 还得修改primitive的值对应上然后画圆的功能就完成了
画六边形 主体思路和画圆一样 画圆是无限逼近 n可以取很大 画六边形n取6就可以了 然后其他步骤都差不多 最后附加的条件是6边形得方向和鼠标指针的位置一样 利用反三角函数 对两个点的线与水平线夹角取出来在建立时减去就行 就是下面这一行代码
![](https://i-blog.csdnimg.cn/blog_migrate/d82d7ec848c6ec9c0436c73504c8df11.png)
其他的部分都和画圆一样 不再赘述
画折线 其他关于建立类 菜单建立工具箱的步骤都和前面二者一样 不再赘述 主要讲核心思路部分如何做到折线不断 这里我的思路是 既然他是两点为一个单位建立一个线段 那么我第二个线段只要起点和第一个线段的终点重合就可以将这两个线段连起来 做法就是修改线段的那几行mouseControl代码 还有鼠标中键一按就让线段结束也包含其中 有具体注释不再赘述
![](https://i-blog.csdnimg.cn/blog_migrate/9e9191c45ce3783af1f83074c07d7b34.png)
弹出菜单选择修改颜色 具体修改makeMenu中的菜单选项即可在菜单中建立颜色选项 我这边是只建立了三种颜色
![](https://i-blog.csdnimg.cn/blog_migrate/01a7a7c3a3da0f08d7ea4dac65aadd0e.png)
然后就是如何染上颜色 这里就得修改每一个类的代码
![](https://i-blog.csdnimg.cn/blog_migrate/fb88e8442f8e3a498a153cc1f03b8151.png)
在画每个图形前 先给他染上颜色
![](https://i-blog.csdnimg.cn/blog_migrate/c9d39226aea7411142e0010ef9716b14.png)
如此就可以达成染色 如何让染色只影响到当前处理的图形 就得在类中新建一个颜色数组 将每个单元都记录下来 就可达成每个元素一种颜色 如下
![](https://i-blog.csdnimg.cn/blog_migrate/3771d3e81ed0a5527dedeca6e54a628c.png)
填充选项 类似于颜色选项 先在菜单中建立工具箱 然后得在类中加入一个是否填充的布尔判断数 来达成只影响当前的操作
![](https://i-blog.csdnimg.cn/blog_migrate/bf9c8f1f916867eab78cb0a70ce49071.png)
在画图函数中 每次画前 先进行bool数的判断 即可确定是否填充
![](https://i-blog.csdnimg.cn/blog_migrate/270ff3fe7c602592ac2ca9584f13e8fd.png)
关于填充时 菜单也做出相应变化 这个简单 只在工具箱菜单中修改一下图标的填充方式即可 判断是否填充 也根据bool数判断即可 如图
![](https://i-blog.csdnimg.cn/blog_migrate/c74881d4c0cdb0d48d2ffab9e01296b7.png)
选择填充FILL 还是LINE即可达成
最后附上完成后的效果图
![](https://i-blog.csdnimg.cn/blog_migrate/761bb0637fc39df7e0749f7b4abd4f97.png)
由于时间问题我只设置了三种颜色 没有写出RGB颜色的自由选择因此这一点还可以继续改进
下面是源代码
// canvas.cpp
//
// This program allows the user to draw simple shapes on a canvas.
//
// Interaction:
// Left click on a box on the left to select a primitive.
// Then left click on the drawing area: once for point, twice for line or rectangle.
// Right click for menu options.
//
// Sumanta Guha.
#include <cstdlib>
#include <vector>
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#define INACTIVE 0
#define POINT 1
#define LINE 2
#define RECTANGLE 3
#define CIRCULAR 4
#define HEXAGON 5
#define BROKENLINE 6
#define NUMBERPRIMITIVES 6
// Globals.
static int width, height; // OpenGL window size.
static float pointSize = 3.0; // Size of point
static int primitive = INACTIVE; // Current drawing primitive.
static int pointCount = 0; // Number of specified points.
static int tempX, tempY; // Co-ordinates of clicked point.
static int isGrid = 1; // Is there grid?
static int isFilled = 1;//是否填充
float square_color[3] = { 0.5, 0.5, 0.65 }; // Color of the square.
// Point class.
class Point
{
public:
Point(float xVal, float yVal, float sizeVal, float colorVal[3])
{
x = xVal; y = yVal; size = sizeVal;
color[0] = colorVal[0];
color[1] = colorVal[1];
color[2] = colorVal[2];
}
Point() {};
void drawPoint(void); // Function to draw a point.
void getColor();//提取颜色
private:
float x, y; // x and y co-ordinates of point.
float size; // Size of point.
float color[3];
};
void Point::getColor()
{
glColor3fv(color);
}
//float Point::size = pointSize; // Set point size.
// Function to draw a point.
void Point::drawPoint()
{
glPointSize(size);
glBegin(GL_POINTS);
glVertex3f(x, y, 0.0);
glEnd();
}
// Vector of points.
std::vector<Point> points;
// Iterator to traverse a Point array.
std::vector<Point>::iterator pointsIterator;
// Function to draw all points in the points array.
void drawPoints(void)
{
// Loop through the points array drawing each point.
for (auto point : points) {
point.getColor();
point.drawPoint(); }
}
// Line class.
class Line
{
public:
Line(float x1Val, float y1Val, float x2Val, float y2Val, float colorVal[3])
{
x1 = x1Val; y1 = y1Val; x2 = x2Val; y2 = y2Val;
color[0] = colorVal[0];
color[1] = colorVal[1];
color[2] = colorVal[2];
}
Line() {};
void drawLine();
void getColor();//提取颜色
private:
float x1, y1, x2, y2; // x and y co-ordinates of endpoints.
float color[3];//颜色数组
};
void Line::getColor()
{
glColor3fv(color);
}
// Function to draw a line.
void Line::drawLine()
{
glBegin(GL_LINES);
glVertex3f(x1, y1, 0.0);
glVertex3f(x2, y2, 0.0);
glEnd();
}
// Vector of lines.
std::vector<Line> lines;
// Function to draw all lines in the lines array.
void drawLines(void)
{
// Loop through the lines array drawing each line.
for (auto line : lines) {
line.getColor();
line.drawLine(); }
}
// Rectangle class.
class Rect
{
public:
Rect(float x1Val, float y1Val, float x2Val, float y2Val, float colorVal[3],bool fillVal)
{
x1 = x1Val; y1 = y1Val; x2 = x2Val; y2 = y2Val;
color[0] = colorVal[0];
color[1] = colorVal[1];
color[2] = colorVal[2];
fill = fillVal;
}
Rect() {};
void drawRectangle();
void getColor();//提取颜色
private:
float x1, y1, x2, y2; // x and y co-ordinates of diagonally opposite vertices.
float color[3];//颜色数组
bool fill;
};
void Rect::getColor()
{
glColor3fv(color);
}
// Function to draw a Rectangle.
void Rect::drawRectangle()
{
if (fill == true)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glRectf(x1, y1, x2, y2);
glColor3fv(square_color);
}
else
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glRectf(x1, y1, x2, y2);
}
}
// Vector of rectangles.
std::vector<Rect> rectangles;
// Function to draw all rectangles in the rectangles array.
void drawRectangles(void)
{
// Loop through the rectangles array drawing each rectangle.
for (auto rectangle : rectangles) {
rectangle.getColor();
rectangle.drawRectangle();
}
}
//建立关于圆的一个类
class circular
{
public:
circular(float x1Val, float y1Val, float x2Val, float y2Val, float colorVal[3], bool fillVal)//也是两个点 第一个点作为顶点 第二个点与第一个点的距离作为半径
{
x1 = x1Val; y1 = y1Val; x2 = x2Val; y2 = y2Val;
color[0] = colorVal[0];
color[1] = colorVal[1];
color[2] = colorVal[2];
fill = fillVal;
}
circular() {};
void drawCircular();
void getColor();//提取颜色
private:
float x1, x2, y1, y2;//定义四个变量的类型
float color[3];//颜色数组
bool fill;
};
void circular::getColor()
{
glColor3fv(color);
}
void circular::drawCircular()
{
const int n = 10000;//当n为3时为三角形;n为4时是四边形,n为5时为五边形
const GLfloat pi = 3.1415926f;//圆周率
if (fill == true)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBegin(GL_POLYGON);//用此来生成多边图 进行无限逼近
float R = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));//两点坐标求出半径
for (int i = 0; i < n; i++)//循环打点法 打n个点 n足够多就是圆
{
glVertex2f(x1 + R * cos(2 * pi * i / n), y1 + R * sin(2 * pi * i / n));//x1 y1是圆心 用cos sin表示圆心到边的距离 从而进行打点
}
glEnd();
glColor3fv(square_color);
glutPostRedisplay();
}
else
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_POLYGON);//用此来生成多边图 进行无限逼近
float R = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));//两点坐标求出半径
for (int i = 0; i < n; i++)//循环打点法 打n个点 n足够多就是圆
{
glVertex2f(x1 + R * cos(2 * pi * i / n), y1 + R * sin(2 * pi * i / n));//x1 y1是圆心 用cos sin表示圆心到边的距离 从而进行打点
}
glEnd();
glutPostRedisplay();
}
}
std::vector<circular>circulars;//储存变量
void drawCircular(void)//画圆
{
for (auto circular : circulars) {
circular.getColor();
circular.drawCircular(); }
}
class hexagon
{
public:
hexagon(float x1Val, float y1Val, float x2Val, float y2Val, float colorVal[3], bool fillVal)//也是两个点 第一个点作为顶点 第二个点与第一个点的距离作为半径
{
x1 = x1Val; y1 = y1Val; x2 = x2Val; y2 = y2Val;
color[0] = colorVal[0];
color[1] = colorVal[1];
color[2] = colorVal[2];
fill = fillVal;
}
hexagon() {};
void drawHexagon();
void getColor();//提取颜色
private:
float x1, x2, y1, y2;//定义四个变量的类型
float color[3];//颜色数组
bool fill;
};
void hexagon::getColor()
{
glColor3fv(color);
}
void hexagon::drawHexagon()
{
const int n = 6;//6边形
const GLfloat pi = 3.1415926f;//圆周率
if (fill == true)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBegin(GL_POLYGON);//用此来生成多边图
float R = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));//两点坐标求出半径
for (int i = 0; i < n; i++)//循环打点法 打6个点 为正六边形
{
glVertex2f(x1 + R * cos(2 * pi * i / n - atan(fabs(y2 - y1) / fabs(x2 - x1))), y1 + R * sin(2 * pi * i / n - atan(fabs(y2 - y1) / fabs(x2 - x1))));//x1 y1是圆心 用cos sin表示圆心到边的距离 从而进行打点
}//按指定方向只需将两点的坐标的斜率值用反函数表示出来弧度值 在起点时将其减去即可
glEnd();
glColor3fv(square_color);
glutPostRedisplay();
}
else
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_POLYGON);//用此来生成多边图
float R = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));//两点坐标求出半径
for (int i = 0; i < n; i++)//循环打点法 打6个点 为正六边形
{
glVertex2f(x1 + R * cos(2 * pi * i / n - atan(fabs(y2 - y1) / fabs(x2 - x1))), y1 + R * sin(2 * pi * i / n - atan(fabs(y2 - y1) / fabs(x2 - x1))));//x1 y1是圆心 用cos sin表示圆心到边的距离 从而进行打点
}//按指定方向只需将两点的坐标的斜率值用反函数表示出来弧度值 在起点时将其减去即可
glEnd();
glutPostRedisplay();
}
}
std::vector<hexagon>hexagons;//储存变量
void drawHexagon(void)//画六边形
{
for (auto hexagon : hexagons) {
hexagon.getColor();
hexagon.drawHexagon(); }
}
class brokenline
{
public:
brokenline(float x1Val, float y1Val, float x2Val, float y2Val, float colorVal[3])//也是两个点
{
x1 = x1Val; y1 = y1Val; x2 = x2Val; y2 = y2Val;
color[0] = colorVal[0];
color[1] = colorVal[1];
color[2] = colorVal[2];
}
brokenline() {};
void drawBrokenline();
void getColor();//提取颜色
private:
float x1, x2, y1, y2;//变量类型
float color[3];//颜色数组
};
void brokenline::getColor()
{
glColor3fv(color);
}
void brokenline::drawBrokenline()
{
glBegin(GL_LINES);
glVertex2f(x1,y1);
glVertex2f(x2,y2);
glEnd();
}
std::vector<brokenline>brokenlines;
void drawBrokenline(void)
{
for (auto brokenline : brokenlines) {
brokenline.getColor();
brokenline.drawBrokenline(); }
}
// Function to draw point selection box in left selection area.
void drawPointSelectionBox(void)
{
if (primitive == POINT) glColor3f(1.0, 1.0, 1.0); // Highlight.
else glColor3f(0.8, 0.8, 0.8); // No highlight.
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glRectf(0.0, 0.9 * height, 0.1 * width, height);
// Draw black boundary.
glColor3f(0.0, 0.0, 0.0);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glRectf(0.0, 0.9 * height, 0.1 * width, height);
// Draw point icon.
glPointSize(pointSize);
glColor3fv(square_color);
glBegin(GL_POINTS);
glVertex3f(0.05 * width, 0.95 * height, 0.0);
glEnd();
}
// Function to draw line selection box in left selection area.
void drawLineSelectionBox(void)
{
if (primitive == LINE) glColor3f(1.0, 1.0, 1.0); // Highlight.
else glColor3f(0.8, 0.8, 0.8); // No highlight.
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glRectf(0.0, 0.8 * height, 0.1 * width, 0.9 * height);
// Draw black boundary.
glColor3f(0.0, 0.0, 0.0);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glRectf(0.0, 0.8 * height, 0.1 * width, 0.9 * height);
// Draw line icon.
glColor3fv(square_color);
glBegin(GL_LINES);
glVertex3f(0.025 * width, 0.825 * height, 0.0);
glVertex3f(0.075 * width, 0.875 * height, 0.0);
glEnd();
}
// Function to draw rectangle selection box in left selection area.
void drawRectangleSelectionBox(void)
{
if (primitive == RECTANGLE) glColor3f(1.0, 1.0, 1.0); // Highlight.
else glColor3f(0.8, 0.8, 0.8); // No highlight.
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glRectf(0.0, 0.7 * height, 0.1 * width, 0.8 * height);
// Draw black boundary.
glColor3f(0.0, 0.0, 0.0);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glRectf(0.0, 0.7 * height, 0.1 * width, 0.8 * height);
// Draw rectangle icon.
glColor3fv(square_color);
if(isFilled==false)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
glRectf(0.025 * width, 0.735 * height, 0.075 * width, 0.765 * height);
glEnd();
}
void drawCircularSelectionBox(void)//建立画圆的一个工具栏
{
if (primitive == CIRCULAR) glColor3f(1.0, 1.0, 1.0); // 当鼠标点到范围时就高光 表示已经选中了
else glColor3f(0.8, 0.8, 0.8); // 没选中就是低光
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glRectf(0.0, 0.6 * height, 0.1 * width, 0.7 * height);//关于这个高光的范围
//
glColor3f(0.0, 0.0, 0.0);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glRectf(0.0, 0.6 * height, 0.1 * width, 0.7 * height);
//
glColor3fv(square_color);
if (isFilled == false)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
glBegin(GL_POLYGON);//这里利用循环打点法生成一个小的圆 以便于与其他工具区分
int n = 1000;
for (int i = 0; i < n; i++)
{
glVertex2f(0.05 * width + 0.025*width*cos(2 * 3.14 * i / n), 0.65 * height + 0.025*width*sin(2 * 3.14 * i / n));//同理不再赘述
}
glEnd();
}
void drawHexagonSelectionBox(void)//建立画6边形的一个工具栏
{
if (primitive == HEXAGON) glColor3f(1.0, 1.0, 1.0); // 当鼠标点到范围时就高光 表示已经选中了
else glColor3f(0.8, 0.8, 0.8); // 没选中就是低光
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glRectf(0.0, 0.5 * height, 0.1 * width, 0.6 * height);//关于这个高光的范围
//
glColor3f(0.0, 0.0, 0.0);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glRectf(0.0, 0.5 * height, 0.1 * width, 0.6 * height);
//
glColor3fv(square_color);
if (isFilled == false)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
glBegin(GL_POLYGON);//这里利用循环打点法生成一个小的六边形 以便于与其他工具区分
int n = 6;
for (int i = 0; i < n; i++)
{
glVertex2f(0.05 * width + 0.025 * width * cos(2 * 3.14 * i / n), 0.55 * height + 0.025 * width * sin(2 * 3.14 * i / n));//同理不再赘述
}
glEnd();
}
void drawBrokenlineSelectionBox(void)//折线框
{
if (primitive == BROKENLINE) glColor3f(1.0, 1.0, 1.0); // 当鼠标点到范围时就高光 表示已经选中了
else glColor3f(0.8, 0.8, 0.8); // 没选中就是低光
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glRectf(0.0, 0.4 * height, 0.1 * width, 0.5 * height);//关于这个高光的范围
//
glColor3f(0.0, 0.0, 0.0);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glRectf(0.0, 0.4 * height, 0.1 * width, 0.5 * height);
//
glColor3fv(square_color);
glBegin(GL_LINES);
glVertex3f(0.025 * width, 0.425 * height, 0.0);
glVertex3f(0.055 * width, 0.455 * height, 0.0);
glVertex3f(0.055 * width, 0.455 * height, 0.0);
glVertex3f(0.035 * width, 0.475 * height, 0.0);//简单生成一个折线 即两个直线一头相连
glEnd();
}
// Function to draw unused part of left selection area.
void drawInactiveArea(void)
{
glColor3f(0.6, 0.6, 0.6);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glRectf(0.0, 0.0, 0.1 * width, (1 - NUMBERPRIMITIVES * 0.1) * height);
glColor3f(0.0, 0.0, 0.0);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glRectf(0.0, 0.0, 0.1 * width, (1 - NUMBERPRIMITIVES * 0.1) * height);
}
// Function to draw temporary point.
void drawTempPoint(void)
{
glPointSize(pointSize);
glBegin(GL_POINTS);
glVertex3f(tempX, tempY, 0.0);
glEnd();
}
// Function to draw a grid.
void drawGrid(void)
{
int i;
glEnable(GL_LINE_STIPPLE);
glLineStipple(1, 0x5555);
glColor3f(0.75, 0.75, 0.75);
glBegin(GL_LINES);
for (i = 2; i <= 9; i++)
{
glVertex3f(i * 0.1 * width, 0.0, 0.0);
glVertex3f(i * 0.1 * width, height, 0.0);
}
for (i = 1; i <= 9; i++)
{
glVertex3f(0.1 * width, i * 0.1 * height, 0.0);
glVertex3f(width, i * 0.1 * height, 0.0);
}
glEnd();
glDisable(GL_LINE_STIPPLE);
}
// Drawing routine.
void drawScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
drawPointSelectionBox();
drawLineSelectionBox();
drawRectangleSelectionBox();
drawCircularSelectionBox();
drawHexagonSelectionBox();
drawBrokenlineSelectionBox();
drawInactiveArea();
drawPoints();
drawLines();
drawRectangles();
drawCircular();
drawHexagon();
drawBrokenline();
if (((primitive == LINE) || (primitive == RECTANGLE) || (primitive == CIRCULAR)||(primitive==HEXAGON)||(primitive==BROKENLINE)) &&
(pointCount == 1)) drawTempPoint();
if (isGrid) drawGrid();
glutSwapBuffers();
}
// Function to pick primitive if click is in left selection area.
void pickPrimitive(int y)
{
if (y < (1 - NUMBERPRIMITIVES * 0.1) * height) primitive = INACTIVE;
else if (y < (1 - 5 * 0.1) * height) primitive = BROKENLINE;
else if (y < (1 - 4 * 0.1) * height) primitive = HEXAGON;
else if (y < (1 - 3 * 0.1) * height) primitive = CIRCULAR;
else if (y < (1 - 2 * 0.1) * height) primitive = RECTANGLE;
else if (y < (1 - 1 * 0.1) * height) primitive = LINE;
else primitive = POINT;
}
// The mouse callback routine.
void mouseControl(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
y = height - y; // Correct from mouse to OpenGL co-ordinates.
if (x < 0 || x > width || y < 0 || y > height); // Click outside canvas - do nothing.
// Click in left selection area.
else if (x < 0.1 * width)
{
pickPrimitive(y);
pointCount = 0;
}
// Click in canvas.
else
{
if (primitive == POINT) points.push_back(Point(x, y, pointSize,square_color));
else if (primitive == LINE)
{
if (pointCount == 0)
{
tempX = x; tempY = y;
pointCount++;
}
else
{
lines.push_back(Line(tempX, tempY, x, y,square_color));
pointCount = 0;
}
}
else if (primitive == RECTANGLE)
{
if (pointCount == 0)
{
tempX = x; tempY = y;
pointCount++;
}
else
{
rectangles.push_back(Rect(tempX, tempY, x, y,square_color,isFilled));
pointCount = 0;
}
}
else if (primitive == CIRCULAR)
{
if (pointCount == 0)
{
tempX = x; tempY = y;
pointCount++;
}
else
{
circulars.push_back(circular(tempX, tempY, x, y,square_color,isFilled));
pointCount = 0;
}
}
else if (primitive == HEXAGON)
{
if (pointCount == 0)
{
tempX = x; tempY = y;
pointCount++;
}
else
{
hexagons.push_back(hexagon(tempX, tempY, x, y,square_color,isFilled));
pointCount = 0;
}
}
else if (primitive == BROKENLINE)
{
if (pointCount == 0)
{
tempX = x; tempY = y;
pointCount++;
}
else
{
brokenlines.push_back(brokenline(tempX, tempY, x, y,square_color));
tempX = x;
tempY = y;//自动将上一次传递的值x2y2保存给下一次的折线x1y1 达成连续折线
}
}
}
}
else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)//折线的终止判断 点击鼠标中间结束
{
pointCount = 0;
}
}
// OpenGL window reshape routine.
void resize(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set viewing box dimensions equal to window dimensions.
glOrtho(0.0, (float)w, 0.0, (float)h, -1.0, 1.0);
// Pass the size of the OpenGL window to globals.
width = w;
height = h;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
exit(0);
break;
default:
break;
}
}
// Clear the canvas and reset for fresh drawing.
void clearAll(void)
{
points.clear();
lines.clear();
rectangles.clear();
circulars.clear();
hexagons.clear();
brokenlines.clear();
primitive = INACTIVE;
pointCount = 0;
}
// The right button menu callback function.
void rightMenu(int id)
{
if (id == 1)
{
clearAll();
glutPostRedisplay();
}
if (id == 2) exit(0);
}
// The sub-menu callback function.
void grid_menu(int id)
{
if (id == 3) isGrid = 1;
if (id == 4) isGrid = 0;
glutPostRedisplay();
}
void color_menu(int id)
{
if (id == 5)
{
square_color[0] = 1.0; square_color[1] = 0.0; square_color[2] = 0.0;
}
if (id == 6)
{
square_color[0] = 0.0; square_color[1] = 1.0; square_color[2] = 0.0;
}
if (id == 7)
{
square_color[0] = 0.0; square_color[1] = 0.0; square_color[2] = 1.0;
}
glutPostRedisplay();
}
void fill_color(int id)
{
if (id == 8)
{
isFilled = 1;
}
if (id == 9)
{
isFilled = 0;
}
glutPostRedisplay();
}
// Function to create menu.
void makeMenu(void)
{
int sub_menu;
sub_menu = glutCreateMenu(grid_menu);
glutAddMenuEntry("On", 3);
glutAddMenuEntry("Off", 4);
int sub_2menu;
sub_2menu = glutCreateMenu(color_menu);
glutAddMenuEntry("red", 5);
glutAddMenuEntry("green", 6);
glutAddMenuEntry("blue", 7);
int sub_3menu;
sub_3menu = glutCreateMenu(fill_color);
glutAddMenuEntry("on", 8);
glutAddMenuEntry("off", 9);
glutCreateMenu(rightMenu);
glutAddSubMenu("Grid", sub_menu);
glutAddMenuEntry("Clear", 1);
glutAddMenuEntry("Quit", 2);
glutAddSubMenu("Color", sub_2menu);
glutAddSubMenu("Fill", sub_3menu);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
// Initialization routine.
void setup(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
makeMenu(); // Create menu.
}
// Routine to output interaction instructions to the C++ window.
void printInteraction(void)
{
std::cout << "Interaction:" << std::endl;
std::cout << "Left click on a box on the left to select a primitive." << std::endl
<< "Then left click on the drawing area: once for point, twice for line or rectangle." << std::endl
<< "Right click for menu options." << std::endl;
}
// Main routine.
int main(int argc, char** argv)
{
printInteraction();
glutInit(&argc, argv);
glutInitContextVersion(4, 3);
glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("canvas.cpp");
glutDisplayFunc(drawScene);
glutReshapeFunc(resize);
glutKeyboardFunc(keyInput);
glutMouseFunc(mouseControl);
glewExperimental = GL_TRUE;
glewInit();
setup();
glutMainLoop();
}