实验要求
设计一个二维卡通任务交互设计系统,实现直线,多边形绘制算法(橡皮筋效果),实现基于鼠标交互的卡通人物设计与绘制。使用颜色填充与反走样技术对卡通人物外貌以及衣着进行绘制。实现对卡通人物轮廓的交互控制,点击鼠标左键可以对人物五官位置进行拖拽移动调整。点击鼠标右键可以对卡通人物进行放缩等操作。
实验结果
本项目分为两个模式
- 一个是画板模式
- 一个是卡通人物交互模式
画板模式下可选择
- 画点
- 画直线
- 画三角形
三个模式,均使用橡皮筋技术来实现
画点模式
画直线模式
画三角形模式
卡通人物交互模式
对人物五官位置进行拖拽移动调整(使用鼠标左键单击拖拽)
对卡通人物进行放缩
- 点击w键 放大
- 点击s键 缩小
- 点击d键 顺时针旋转
- 点击a键 逆时针旋转
以下是主要代码:
完整代码可下载资源
/*
画圆(内部填充)
N: 点的数量 数量越多圆越平滑
radius:圆的半径
angleStart:圆的起始角度(0-360)
angleEnd:圆的起始角度(0-360)
x、y:圆心坐标
a :b:a为水平方向,b为垂直方向的比例,通过调整可转化成椭圆
*/
void drawCircle(int N, double radius, int angleStart = 0, int angleEnd = 360, double x = 0, double y = 0, double a = 1, double b = 1) {
glBegin(GL_POLYGON);
double start = (double)angleStart / 360.0*N;
double end = (double)angleEnd / 360 * N;
for (int i = start; i < end + 1; i++) {
glVertex2f(x + a * cos(i * 2 * PI / N)*radius, y + b * sin(i * 2 * PI / N) *radius);
}
glEnd();
}
/*
画圆(内部不填充)
N: 点的数量 数量越多圆越平滑
radius:圆的半径
angleStart:圆的起始角度(0-360)
angleEnd:圆的起始角度(0-360)
x、y:圆心坐标
a :b:a为水平方向,b为垂直方向的比例,通过调整可转化成椭圆
*/
void drawCircleLine(int N, double radius, int angleStart = 0, int angleEnd = 360, double x = 0, double y = 0, double a = 1, double b = 1) {
glBegin(GL_LINE_STRIP);
double start = (double)angleStart / 360.0*N;
double end = (double)angleEnd / 360 * N;
for (int i = start; i < end + 1; i++) {
glVertex2f(x + a * cos(i * 2 * PI / N)*radius, y + b * sin(i * 2 * PI / N) *radius);
}
glEnd();
}
//使熊猫的各个部位以熊猫为中心进行旋转
void rotate(int x, int y, float scale, float theta) {
//设置中心点,并且通过变换为原来的世界坐标系来进行旋转
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//绕z轴旋转theta度
glTranslatef(scale*x, scale*y, 0);
glRotatef(theta, 0, 0, 1);
glTranslatef(-scale * x, -scale * y, 0);
}
/*
画熊猫的大脸
*/
void drawFace(int x,int y) {
rotate(body[0], body[1], scale, theta);
//白色
glColor3ub(white[0], white[1], white[2]);
drawCircle(200, scale*100, 0, 360, scale*x, scale*y, 0.8, 0.7);
}
/*
熊猫的左眼
*/
void drawLeftEye(int x, int y) {
rotate(body[0], body[1], scale, theta);
//左眼白
//白色
glColor3ub(white[0], white[1], white[2]);
drawCircle(20, scale * 2, 0, 360, scale*(x-2), scale*(y-3));
//左眼珠
//黑色
glColor3ub(black[0], black[1], black[2]);
drawCircle(20, scale * 7, 0, 360, scale*x, scale*(y - 5));
//左黑眼圈
//深灰色
glColor3ub(darkGray[0], darkGray[1], darkGray[2]);
drawCircle(200, scale * 20, 0, 360, scale*x, scale*y, 1, 0.9);
}
/*
熊猫的右眼
*/
void drawRightEye(int x, int y) {
rotate(body[0], body[1], scale, theta);
//右眼白
//白色
glColor3ub(white[0], white[1], white[2]);
drawCircle(20, scale*2, 0, 360, scale*(x-2), scale*(y-3));
//右眼珠
//黑色
glColor3ub(0, 0, 0);
drawCircle(20, scale*7, 0, 360, scale*x, scale*(y - 5));
//右黑眼圈
//深灰色
glColor3ub(darkGray[0], darkGray[1], darkGray[2]);
drawCircle(200, scale*20, 0, 360, scale*x, scale*y, 1, 0.9);
}
/*
熊猫的鼻子
*/
void drawNose(int x, int y) {
rotate(body[0], body[1], scale, theta);
glColor3ub(darkGray[0], darkGray[1], darkGray[2]);
glBegin(GL_POLYGON);
glVertex2f(scale*(x-2), scale*y);
glVertex2f(scale*(x-10), scale*(y+10));
glVertex2f(scale*(x-9), scale*(y+12));
glVertex2f(scale*(x+9), scale*(y+12));
glVertex2f(scale*(x+10), scale*(y+10));
glVertex2f(scale*(x+2), scale*y);
glEnd();
}
/*
熊猫的嘴巴
*/
void drawMouth(int x, int y) {
rotate(body[0], body[1], scale, theta);
glColor3ub(darkGray[0], darkGray[1], darkGray[2]);
glLineWidth(scale*2.5);
drawCircleLine(200, scale*10, 180, 360, scale*(x-10), scale*y);
drawCircleLine(200, scale*10, 180, 360, scale*(x+10), scale*y);
}
/*
熊猫的左耳朵
*/
void drawLeftEar(int x, int y) {
rotate(body[0], body[1], scale, theta);
glColor3ub(darkGray[0], darkGray[1],