Dw制作个人网站,房地产最新信息,软文营销的概念是什么,企业系统开发去哪家目录
CG1-v1.0-点和直线的绘制
第1关#xff1a;OpenGL点的绘制 第2关#xff1a;OpenGL简单图形绘制 第3关#xff1a;OpenGL直线绘制
第4关#xff1a;01直线绘制-dda算法 第5关#xff1a;01直线绘制-中点算法 第6关#xff1a;一般直线绘…
目录
CG1-v1.0-点和直线的绘制
第1关OpenGL点的绘制 第2关OpenGL简单图形绘制 第3关OpenGL直线绘制
第4关01直线绘制-dda算法 第5关01直线绘制-中点算法 第6关一般直线绘制
CG1-v2.0-直线绘制
第1关直线光栅化-DDA画线算法
第2关直线光栅化-中点画线算法
第3关直线光栅化-Bresenham画线算法
第4关直线光栅化-任意斜率的Bresenham画线算法
CG2-v2.0-三角形填充
第1关扫描线填充法 第2关重心坐标填充法 第3关同侧判断填充法 直线裁剪v1.0
第1关Cohen-Sutherland编码裁剪算法 第2关中点分割裁剪算法 第3关Liang-Barsky参数化裁剪算法
CG2-v1.0-二维几何变换
第1关正方形的平移与缩放 第2关正方形的平移和旋转 第3关正方形的变换组合 第4关三菱形状
CG3-v2.0-图形几何变换
第1关平移、缩放、旋转正方体 第2关图形的平移与缩放
第3关图形的平移与旋转 第4关图形的旋转与缩放 第5关绘制三菱形状
模型、观察及视口变换v1.0
第1关立方体模型变换 第2关立方体观察变换 第3关立方体视口变换
模型、观察及视口变换v2.0
第1关模型变换-左右两个立方体
第2关观察变换 第3关视口变换
投影变换v1.0
第1关立方体透视投影
第2关立方体平行投影
投影变换v2.0
第1关一点透视
第2关两点透视 第3关三视图与正等测投影 第4关视口变换与三视图
CG1-v1.0-点和直线的绘制
第1关OpenGL点的绘制 一. 任务描述 根据下面要求在右侧修改代码绘制出预期输出的图片。平台会对你编写的代码进行测试。 1.本关任务 熟悉编程环境 了解光栅图形显示器的特点 了解计算机绘图的特点 进行编程以OpenGL为开发平台设计程序以能够在屏幕上生成三个坐标、颜色和尺寸一定的点。 2.预期输出 3.具体要求 (1) 背景色为黑色用 glClearColor()来完成 (2) 渲染的点的直径设置为 3 (3) 选用 GL_POINTS 作为图形类型 (4) 三个点的颜色分别为1.0f, 0.0f, 0.0f), (0.0f,1.0f,0.0f), (0.0f,0.0f,1.0f) (5) 三个点对应的顶点坐标分别为-0.4f,-0.4f), (0.0f,0.0f), (0.4f,0.4f)。 // 提示写完代码请保存之后再进行评测
#include GL/freeglut.h
#includestdio.h// 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束void myDisplay(void)
{// 请在此添加你的代码/********** Begin ********/glClearColor(0.0,0.0,0.0,0.0);glPointSize(3);glBegin(GL_POINTS);glColor3f(1.0,0.0,0.0);glVertex2f(-0.4,-0.4);glColor3f(0.0,1.0,0.0);glVertex2f(0.0,0.0);glColor3f(0.0,0.0,1.0);glVertex2f(0.4,0.4);glEnd();/********** End **********/glFlush();
}int main(int argc, char *argv[])
{glutInit(argc, argv);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow(Hello Point!);glutDisplayFunc(myDisplay);glutMainLoopEvent(); /*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(400 * 400 * 3);//分配内存GLint viewport[4] {0}; glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for(int i 0; i 400; i ) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for(int j 0; j 400; j ) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k1];plane0Ptr[j] pPixelData[k2];}}cv::merge(imgPlanes, img);cv::flip(img, img ,0); cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);//cv::waitKey();cv::imwrite(../img_step1/test.jpg, img);return 0;
} 第2关OpenGL简单图形绘制 一.任务描述 根据下面要求在右侧修改代码绘制出预期输出的图片。平台会对你编写的代码进行测试。 1.本关任务 利用 OpenGL 作为开发平台设计程序生成一个光栅图。 2.预期输出 3.具体要求 (1).使用黑色作为背景采用 glClearColor 来实现 (2).绘制一个矩形颜色为(1.0f,1.0f,1.0f)矩阵位置-0.5f-0.5f0.5f0.5f) (3).绘制一个三角形三个顶点颜色分别为1.0f, 0.0f, 0.0f), (0.0f,1.0f,0.0f) (0.0f,0.0f,1.0f)对应的顶点坐标分别为(0.0f,1.0f), (0.8f,-0.5f), (-0.8f,-0.5f) (4).绘制三个直径为3的点颜色为1.0f, 0.0f, 0.0f) (0.0f,1.0f,0.0f) (0.0f,0.0f,1.0f)对应的顶点坐标分别为-0.4f,-0.4f), (0.0f,0.0f)(0.4f,0.4f)。 // 提示写完代码请保存之后再进行评测
#include GL/freeglut.h
#includestdio.h// 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束void myDisplay(void)
{// 请在此添加你的代码/********** Begin ********/glClearColor(0.0,0.0,0.0,0.0);glColor3f(1.0,1.0,1.0);glRectf(-0.5,-0.5,0.5,0.5);glBegin(GL_TRIANGLES);glColor3f(1.0,0.0,0.0);glVertex2f(0.0,1.0);glColor3f(0.0,1.0,0.0);glVertex2f(0.8,-0.5);glColor3f(0.0,0.0,1.0);glVertex2f(-0.8,-0.5);glEnd();glPointSize(3);glBegin(GL_POINTS);glColor3f(1.0,0.0,0.0);glVertex2f(-0.4,-0.4);glColor3f(0.0,1.0,0.0);glVertex2f(0.0,0.0);glColor3f(0.0,0.0,1.0);glVertex2f(0.4,0.4);glEnd();/********** End **********/glFlush();
}int main(int argc, char *argv[])
{glutInit(argc, argv);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow(Hello Point!);glutDisplayFunc(myDisplay);glutMainLoopEvent(); /*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(400 * 400 * 3);//分配内存GLint viewport[4] {0}; glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for(int i 0; i 400; i ) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for(int j 0; j 400; j ) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k1];plane0Ptr[j] pPixelData[k2];}}cv::merge(imgPlanes, img);cv::flip(img, img ,0); cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);//cv::waitKey();cv::imwrite(../img_step2/test.jpg, img);return 0;
} 第3关OpenGL直线绘制 一.任务描述 根据下面要求在右侧修改代码绘制出预期输出的图片。平台会对你编写的代码进行测试。 1.本关任务 理解基本图形元素光栅化的基本原理 了解和使用OpenGL的生成直线的命令来验证程序运行结果。 2.预期输出 3.具体要求 (1).背景色为黑色用 glclearcolor 来完成 (2).绘制一个矩形颜色为(1.0f,0.0f,0.0f)矩形位置25.025.075.075.0) (3).绘制一个直径为10的点颜色为0.0f, 1.0f, 0.0f)对应的点坐标为原点 (4).利用GL_LINES的绘线方式绘制一条线其中线段的两个顶点颜色分别为(0.0f, 1.0f, 0.0f),(0.0f, 1.0f, 0.0f)两个顶点的坐标分别为(100.0f, 0.0f),(180.0f, 240.0f); 5.调用向glutReshapeFunC注册的函数。 // 提示写完代码请保存之后再进行评测
#include GL/freeglut.h
#includestdio.h// 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束void myDisplay(void)
{// 请在此添加你的代码/********** Begin ********/glClearColor(0.0,0.0,0.0,0.0);glColor3f(1.0,0.0f,0.0f);glRectf(25.0,25.0,75.0,75.0);glPointSize(10);glBegin(GL_POINTS);glColor3f(0.0f,1.0f,0.0f);glVertex2f(0.0f,0.0f);glEnd();glBegin(GL_LINES);glColor3f(0.0f,1.0f,0.0f);glVertex2f(100.0f,0.0f);glColor3f(0.0f,1.0f,0.0f);glVertex2f(180.0f,240.0f);glEnd();/********** End **********/glFlush();
}
void Init()
{glClearColor(0.0, 0.0, 0.0, 0.0);glShadeModel(GL_SMOOTH);
}
void myReshape(int w, int h)
{glViewport(0, 0, (GLsizei)w, (GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}int main(int argc, char *argv[])
{glutInit(argc, argv);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow(Hello Point!);Init();glutDisplayFunc(myDisplay);glutReshapeFunc(myReshape);glutMainLoopEvent(); /*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(400 * 400 * 3);//分配内存GLint viewport[4] {0}; glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for(int i 0; i 400; i ) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for(int j 0; j 400; j ) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k1];plane0Ptr[j] pPixelData[k2];}}cv::merge(imgPlanes, img);cv::flip(img, img ,0); cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);//cv::waitKey();cv::imwrite(../img_step3/test.jpg, img);return 0;
}
第4关0k1直线绘制-DDA算法 一.任务描述 根据下面要求在右侧修改代码绘制出预期输出的图片。平台会对你编写的代码进行测试。 1.本关任务 掌握一种基本图形元素光栅化算法利用OpenGL实现直线光栅化的DDA算法。 2.预期输出 3.具体要求 (1).背景色为黑色用 glclearcolor 来完成 (2).利用DDA算法生成一条直线线粗为1直线颜色为(1.0f,1.0f,0.0f),直线两端点坐标为00200200。 // 提示写完代码请保存之后再进行评测
#include GL/freeglut.h
#includestdio.h// 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束void LineDDA(int x0, int y0, int x1, int y1)
{// 请在此添加你的代码/********** Begin ********/int x;int dy, dx;int y;float k;dx x1 - x0, dy y1 - y0;k dy / dx;y y0;glColor3f(1.0f, 1.0f, 0.0f);glPointSize(1);for (x x0; x x1; x){glBegin(GL_POINTS);glVertex2i(x, (int)(y 0.5)); glEnd();y k;}/********** End **********/glFlush();
}void myDisplay(void)
{// 请在此添加你的代码/********** Begin ********/
glClearColor(0.0, 0.0, 0.0, 0.0);LineDDA( 0, 0, 200, 200);/********** End **********/glFlush();
}
void Init()
{glClearColor(0.0, 0.0, 0.0, 0.0);glShadeModel(GL_SMOOTH);
}
void myReshape(int w, int h)
{glViewport(0, 0, (GLsizei)w, (GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}int main(int argc, char *argv[])
{glutInit(argc, argv);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow(Hello Point!);Init();glutDisplayFunc(myDisplay);glutReshapeFunc(myReshape);glutMainLoopEvent(); /*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(400 * 400 * 3);//分配内存GLint viewport[4] {0};glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for(int i 0; i 400; i ) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for(int j 0; j 400; j ) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k1];plane0Ptr[j] pPixelData[k2];}}cv::merge(imgPlanes, img);cv::flip(img, img ,0); cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);//cv::waitKey();cv::imwrite(../img_step4/test.jpg, img);return 0;
} 第5关0k1直线绘制-中点算法 一.任务描述 根据下面要求在右侧修改代码绘制出预期输出的图片。平台会对你编写的代码进行测试。 1.本关任务 掌握一种基本图形元素光栅化算法利用OpenGL实现直线光栅化的中点画线算法。 2.预期输出 3.具体要求 (1).背景色为黑色用 glclearcolor 来完成 (2).利用中点画线算法生成一条直线线粗为1直线颜色为(0.0f,1.0f,0.0f),直线两端点坐标为1050300260。 // 提示写完代码请保存之后再进行评测
#include GL/freeglut.h
#includestdio.h// 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束void MidPLine(int x0, int y0, int x1, int y1)
{// 请在此添加你的代码/********** Begin ********/int dx, dy, dt, db, d, x, y;dx x1- x0;dy y1 - y0;d dx - 2*dy; dt 2*dx - 2*dy; db -2*dy; x x0; y y0;glColor3f(0.0f, 1.0f, 0.0f);glPointSize(1);glBegin(GL_POINTS);glVertex2i(x, y);glEnd();while (x x1){if (d 0){x;y;d dt;}else{x;d db;}glBegin(GL_POINTS);glVertex2i(x, y);glEnd();}/********** End **********/glFlush();
}void myDisplay(void)
{// 请在此添加你的代码/********** Begin ********/glClear(GL_COLOR_BUFFER_BIT);MidPLine(10,50,300,260);/********** End **********/glFlush();
}
void Init()
{glClearColor(0.0, 0.0, 0.0, 0.0);glShadeModel(GL_SMOOTH);
}
void myReshape(int w, int h)
{glViewport(0, 0, (GLsizei)w, (GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}int main(int argc, char *argv[])
{glutInit(argc, argv);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow(Hello Point!);Init();glutDisplayFunc(myDisplay);glutReshapeFunc(myReshape);glutMainLoopEvent(); /*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(400 * 400 * 3);//分配内存GLint viewport[4] {0};glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for(int i 0; i 400; i ) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for(int j 0; j 400; j ) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k1];plane0Ptr[j] pPixelData[k2];}}cv::merge(imgPlanes, img);cv::flip(img, img ,0); cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);//cv::waitKey();//cv::imwrite(../img_step5/test.jpg, img);return 0;
} 第6关一般直线绘制 一.任务描述 1.本关任务 在前面关卡的基础上根据下面具体要求利用OpenGL画点函数来实现一般直线所有斜率情况的绘制算法。 2.预期输出 3.具体要求 根据下面要求在右侧修改代码绘制出预期输出的图片并进行评测。 (1) 直线颜色为红色(1.0f,0.0f,0.0f), 线粗为1 (2) 实现一般直线所有斜率情况的绘制算法并将代码填写在函数void Line(int x0, int y0, int x1, int y1)中 (3) 绘制一个五角星来测试上述直线绘制算法并将代码填写在函数void myDisplay(void)中指定位置。五角星的顶点坐标分别为(261, 215), (344, 275),(429, 213), (398, 319), (477, 384), (378, 385), (344, 491), (310, 384), (209, 382), (292, 319). // 提示写完代码请保存之后再进行评测
#include GL/freeglut.h
#include algorithm
#include stdio.h
using namespace std;// 评测代码所用头文件-开始
#include opencv2/core/core.hpp
#include opencv2/highgui/highgui.hpp
#include opencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束void Line(int x0, int y0, int x1, int y1)
{// 请在此添加你的代码/********** Begin ********/glColor3f(1.0f, 0.0f, 0.0f);glBegin(GL_POINTS);glPointSize(1);int dx abs(x1 - x0);int dy abs(y1 - y0);if (dx dy) // x方向为步进方向{if (x0 x1) //确保x0x1这样循环中xx1{swap(x0, x1);swap(y0, y1);}int d dx - 2 * dy;int d1 2 * dx - 2 * dy;int d2 -2 * dy;int x x0;int y y0;int yIncr (y1 y0) ? 1 : -1; // 比较两端点y值大小决定y的增量值glVertex2i(x, y);for (int x x0 1; x x1; x){if (d 0){y y yIncr;d d d1;}elsed d d2;glVertex2i(x, y);}}else{if (y0 y1){swap(x0, x1);swap(y0, y1);}int d dy - 2 * dx;int d1 2 * dy - 2 * dx;int d2 -2 * dx;int x x0;int y y0;int xIncr (x1 x0) ? 1 : -1;glVertex2i(x, y);for (int y y0 1; y y1; y){if (d 0){x x xIncr;d d d1;}elsed d d2;glVertex2i(x, y);}}glEnd();/********** End **********/
}void myDisplay(void)
{glClear(GL_COLOR_BUFFER_BIT);// 请在此添加你的代码用来测试直线绘制代码/********** Begin ********/Line(261, 215, 344, 275);Line(344, 275, 429, 213);Line(429, 213, 398, 319);Line(398, 319, 477, 384);Line(477, 384, 378, 385);Line(378, 385, 344, 491);Line(344, 491, 310, 384);Line(310, 384, 209, 382);Line(209, 382, 292, 319);Line(292, 319, 261, 215);/********** End **********/glFlush();
}
void Init()
{glClearColor(0.0, 0.0, 0.0, 0.0);glShadeModel(GL_SMOOTH);
}
void myReshape(int w, int h)
{glViewport(0, 0, (GLsizei)w, (GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}int main(int argc, char *argv[])
{int width 800;int height 600;glutInit(argc, argv);glutInitWindowPosition(100, 100);glutInitWindowSize(width, height);glutCreateWindow(Hello Line!);Init();glutDisplayFunc(myDisplay);glutReshapeFunc(myReshape);glutMainLoopEvent(); /*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(width * height * 3);//分配内存GLint viewport[4] {0};glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(height, width, CV_8UC3);cv::split(img, imgPlanes);for(int i 0; i height; i ) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for(int j 0; j width; j ) {int k 3 * (i * width j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k1];plane0Ptr[j] pPixelData[k2];}}cv::merge(imgPlanes, img);cv::flip(img, img ,0); cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);//cv::waitKey();//cv::imwrite(../img_step6/test.jpg, img);return 0;
}
CG1-v2.0-直线绘制 第1关直线光栅化-DDA画线算法 一.任务描述 1.本关任务 (1)根据直线DDA算法补全line函数其中直线斜率0k1 (2)当直线方程恰好经过P(x,y)和T(x,y1)的中点M时统一选取直线上方的T点为显示的像素点。 2.输入 (1)直线两端点坐标:(13, 20)和(180,140); (2)直线颜色为白色。 3.输出 程序运行结果为一条直线具体结果如下图所示 二.相关知识 1.绘制点函数 image.set(x, y, color)函数是绘制点的函数,参数包括x、y和color。参数x为绘制点的x坐标参数y为绘制点的y坐标参数color为绘制点的颜色。 2.DDA算法 DDA算法相关知识点请参考教材与课件或有关资料。 三.操作说明 (1)按要求补全line函数 (2)点击窗口右下角测评按钮等待测评结果如果通过后可进行下一关任务。 #include tgaimage.hconst TGAColor white TGAColor(255, 255, 255, 255);
const TGAColor red TGAColor(255, 0, 0, 255);void line(int x0, int y0, int x1, int y1, TGAImage image, TGAColor color)
{// Please add the code here/********** Begin ********/int x;float y, k;k (float)(y1 - y0) / (float)(x1 - x0);y y0;for (x x0;x x1;x){image.set(x, int(y 0.5f),color);y y k;}/********** End *********/
}int main(int argc, char** argv)
{TGAImage image(640,480, TGAImage::RGB);line(13, 20, 180, 140, image, white);image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_tga_file(../img_step1/test.tga);return 0;
}
第2关直线光栅化-中点画线算法 一.任务描述 1.本关任务 (1)根据直线中点画线算法补全line函数其中直线斜率0k1并将main函数中的line函数参数补充完整; (2)当直线方程恰好经过P(x,y)和T(x,y1)的中点M时统一选取直线上方的T点为显示的像素点。 2.输入 (1)直线两端点坐标:(100, 100)和(520,300); (2)直线颜色为红色。 3.输出 程序运行结果为一条直线具体结果如下图所示 二.相关知识 1.绘制点函数 image.set(x, y, color)函数是绘制点的函数,参数包括x、y和color。参数x为绘制点的x坐标参数y为绘制点的y坐标参数color为绘制点的颜色。 2.中点画线算法 中点画线算法相关知识点请参考教材与课件或有关资料。 三.操作说明 (1)按要求补全line函数 (2)点击窗口右下角测评按钮等待测评结果如果通过后可进行下一关任务。 #include tgaimage.hconst TGAColor white TGAColor(255, 255, 255, 255);
const TGAColor red TGAColor(255, 0, 0, 255);void line(int x0, int y0, int x1, int y1, TGAImage image, TGAColor color)
{// Please add the code here/********** Begin ********/int dx,dy,dt,db,d,x,y;dx x1 - x0;dy y1 - y0;d dx - 2*dy;dt 2*dx - 2*dy;db -2*dy;x x0;y y0;image.set(x,y,color);while (x x1){if (d 0){ x;y;d dt;}else{x;d db;}image.set(x,y,color);}/********** End *********/
}int main(int argc, char** argv)
{TGAImage image(640,480, TGAImage::RGB);// Please add the code here/********** Begin ********/line( 100, 100 , 520 , 300 , image, red );/********** End *********/image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_tga_file(../img_step4/test.tga);return 0;
}
第3关直线光栅化-Bresenham画线算法 一.任务描述 1.本关任务 (1)根据直线Bresenham算法补全line函数其中直线斜率0k1并将main函数中的line函数参数补充完整; (2)当直线方程恰好经过P(x,y)和T(x,y1)的中点M时统一选取直线上方的T点为显示的像素点。 2.输入 (1)直线两端点坐标:(20, 20)和(180,140); (2)直线颜色为白色。 3.输出 程序运行结果为一条直线具体结果如下图所示 二.相关知识 1.绘制点函数 image.set(x, y, color)函数是绘制点的函数,参数包括x、y和color。参数x为绘制点的x坐标参数y为绘制点的y坐标参数color为绘制点的颜色。 2.Bresenham算法 Bresenham算法相关知识点请参考教材与课件或有关资料。 三.操作说明 (1)按要求补全line函数 (2)点击窗口右下角测评按钮等待测评结果如果通过后可进行下一关任务。 #include tgaimage.hconst TGAColor white TGAColor(255, 255, 255, 255);
const TGAColor red TGAColor(255, 0, 0, 255);void line(int x0, int y0, int x1, int y1, TGAImage image, TGAColor color)
{// Please add the code here/********** Begin ********/int Dxx1-x0,Dyy1-y0,yy0,D-Dx;for(int x x0;x x1;x){image.set(x,y,color);D D 2*Dy;if(D 0){y;D D - 2*Dx;}}/********** End *********/
}int main(int argc, char** argv)
{TGAImage image(640,480, TGAImage::RGB);// Please add the code here/********** Begin ********/line( 20, 20 , 180 , 140 , image, white);/********** End *********/image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_tga_file(../img_step2/test.tga);return 0;
}
第4关直线光栅化-任意斜率的Bresenham画线算法 一.任务描述 1.本关任务 (1)根据直线Bresenham算法补全line函数以绘制白色直线其中直线斜率为任意情况。 (2)当直线方程恰好经过P(x,y)和T(x,y1)的中点M时统一选取直线上方的T点为显示的像素点。 2.输入 代码将自动输入一个OBJ三维人头模型具体模型如下图 3.输出 若编写的任意斜率的Bresenham画线算法代码正确则程序会将模型转换为线条图片具体结果如下图所示 二.相关知识 1.绘制点函数 image.set(x, y, color)函数是绘制点的函数,参数包括x、y和color。参数x为绘制点的x坐标参数y为绘制点的y坐标参数color为绘制点的颜色。 2.Bresenham算法 Bresenham算法相关知识点请参考教材与课件或有关资料。 三.操作说明 (1)按要求补全line函数 (2)点击窗口右下角测评按钮等待测评结果如果通过后可进行下一关任务。 CG2-v2.0-三角形填充
第1关扫描线填充法 一. 任务描述 1. 本关任务 了解和掌握扫描线填充法实现对三角形区域进行填充具体要求如下 (1) 补全triangle函数; (2) 将main函数中的三角形顶点坐标和triangle函数参数补充完整。 2. 输入 (1) 三角形的三个顶点的坐标: t0 {125,50} t1 {300,200} t2 {200,350}; (2) 三角形区域为蓝色。 3. 输出 程序运行结果为一个蓝色三角形区域如下图所示 #include pngimage.h
#includestdio.h
#include iostreamstruct Vec2i
{int x, y;
};void triangle(Vec2i t0, Vec2i t1, Vec2i t2, PNGImage image, PNGColor color) {// Please add your code here/********** Begin ********/ if (t0.yt1.y) std::swap(t0, t1); if (t0.yt2.y) std::swap(t0, t2); if (t1.yt2.y) std::swap(t1, t2);int total_height t2.y-t0.y;for (int yt0.y; yt1.y; y) { int segment_height t1.y-t0.y1; //be careful with divisions by zerofloat alpha (float)(y-t0.y)/total_height,beta (float)(y-t0.y)/segment_height; Vec2i A,B;A.yB.yy;A.x t0.x (t2.x-t0.x)*alpha; B.x t0.x (t1.x-t0.x)*beta; if (A.xB.x) std::swap(A.x, B.x); for (int xA.x; xB.x; x) { image.set(x, y, color); } }for (int y t1.y; y t2.y; y){int segment_height t2.y-t1.y1; float alpha2(float)(y-t0.y)/total_height,beta2 (float)(y-t1.y)/segment_height; Vec2i A2,B2;A2.yB2.yy;A2.x t0.x (t2.x-t0.x)*alpha2; B2.x t1.x - (t1.x-t2.x)*beta2; if (A2.xB2.x) std::swap(A2.x, B2.x); for (int xA2.x; xB2.x; x) { image.set(x, y, color); } }
}/********** End **********/
int main(int argc, char** argv) {PNGColor white PNGColor(255, 255, 255, 255);PNGColor black PNGColor(0, 0, 0, 255);PNGColor red PNGColor(255, 0, 0, 255);PNGColor blue PNGColor(0, 255, 255, 255);int width 400;int height 400;PNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) in.size() in encodeimage.init(black);// Please add your code here/********** Begin ********/Vec2i t0 {125 ,50 }, t1 {300 , 200}, t2 {200 ,350 };triangle( t0,t1 ,t2, image,PNGColor(0, 255, 255, 255) );/********** End **********/image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file(../img_step3/test.png);return 0;
} 第2关重心坐标填充法 一. 任务描述 1. 本关任务 了解和掌握重心坐标法以便能够对三角形区域进行填充具体要求如下 (1) 补全Triangle和Barycenter函数; (2) 将main函数中的三角形顶点坐标和Triangle函数参数补充完整。 2. 输入 (1) 三角形的三个顶点的坐标: t0 {50,50} t1 {300,200} t2 {200,350}; (2) 三角形颜色区域为绿色。 3. 输出 程序运行结果为一个绿色三角形区域如下图所示 #include pngimage.h
#includestdio.h
#include iostream
#include cmath
#include algorithm
#include stdlib.h
struct Vec2i
{int x, y;
};
struct Vec3f
{float x, y, z;
};
//cross Product
Vec3f cross(const Vec3f v1, const Vec3f v2)
{Vec3f v3;v3.x v1.y * v2.z - v1.z * v2.y;v3.y v1.z * v2.x - v1.x * v2.z;v3.z v1.x * v2.y - v1.y * v2.x;return v3;
}
//Determine the point p coordinates are in the triangle abc
Vec3f Barycentre(Vec2i p, Vec2i a, Vec2i b, Vec2i c)
{// Please add your code here/********** Begin ********/Vec3f s[2];s[0].x c.x-a.x;s[0].y b.x-a.x;s[0].z a.x-p.x;s[1].x c.y-a.y;s[1].y b.y-a.y;s[1].z a.y-p.y;Vec3f u cross(s[0], s[1]);Vec3f v;if (abs(u.z) 1e-2) {v.x 1.0-(u.xu.y)/u.z;v.y u.y/u.z;v.z u.x/u.z;} else {v.x -1;v.y 1;v.z 1;}return v;/********** End ********/
}
// Please draw point to make a triangle in bounding box
void Triangle(Vec2i t0, Vec2i t1, Vec2i t2, PNGImage image, PNGColor color)
{// Please add your code here/********** Begin ********/int xmax,ymax,x,y;xmax400,ymax400;Vec2i A;Vec3f v;for(x0;xxmax;x){for(y0;yymax;y){A.xx;A.yy;vBarycentre(A, t0, t1, t2);if(v.x0v.y0v.z0){image.set(x,y,color);}}}
}/********** End **********/
int main(int argc, char** argv) {PNGColor white PNGColor(255, 255, 255, 255);PNGColor black PNGColor(0, 0, 0, 255);PNGColor red PNGColor(255, 0, 0, 255);PNGColor green PNGColor(0, 255, 0, 255); PNGColor blue PNGColor(0, 255, 255, 255);int width 400;int height 400;PNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) in.size() in encodeimage.init(black);// Please add your code here/********** Begin ********/Vec2i t0{50,50},t1{300,200 },t2{200,350};Triangle(t0,t1,t2,image, PNGColor(0,255,0,255));/********** End **********/image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file(../img_step2/test.png);return 0;
} 第3关同侧判断填充法 一. 任务描述 1. 本关任务 了解和掌握同侧判断算法以便能够对三角形区域进行填充具体要求如下 (1) 并补全Triangle、SameSide和PointInTriangle函数; (2) 将main函数中的三角形顶点坐标和Triangle函数参数补充完整。 2. 输入 (1) 三角形的三个顶点的坐标: t0 {50,50} t1 {300,200} t2 {200,350}; (2) 三角形区域为红色。 3. 输出 程序运行结果为一个红色三角形区域如下图所示 #include pngimage.h
#includestdio.h
#include iostream
#include algorithm
using namespace std;
struct Vec2i
{int x, y;
};//Cross product
float CrossProduct(Vec2i a,Vec2i b)
{return a.x * b.y - b.x * a.y;
}
//DotProduct
float DotProduct(float cp1,float cp2)
{return cp1*cp2;
}
//Determine if P1 and P2 are on the same side
bool SameSide( Vec2i p,Vec2i a, Vec2i b, Vec2i c )
{// Please add your code here/********** Begin ********/Vec2i AB {b.x - a.x, b.y - a.y};Vec2i AC {c.x - a.x, c.y - a.y};Vec2i AP {p.x - a.x, p.y - a.y};float v1 CrossProduct(AB, AC);float v2 CrossProduct(AB, AP);if (DotProduct(v1, v2) 0) return 1;else return 0;/********** End **********/
}
//Determine the point coordinates are in the triangle
float PointInTriangle(Vec2i p,Vec2i a, Vec2i b, Vec2i c)
{// Please add your code here/********** Begin ********/return SameSide(a, b, c, p) SameSide(b, c, a, p) SameSide(c, a, b, p); /********** End **********/
}// Please draw point in bounding box
void Triangle(Vec2i t0, Vec2i t1, Vec2i t2, PNGImage image, PNGColor color)
{// Please add your code here/********** Begin ********/int xmax,ymax,x,y;Vec2i A;xmax300,ymax350;for(x0;xxmax;x){for(y0;yymax;y){A.xx;A.yy;if(PointInTriangle(A,t0,t1 ,t2 ))image.set(x,y,color);}}/********** End **********/
}int main(int argc, char** argv) {PNGColor white PNGColor(255, 255, 255, 255);PNGColor black PNGColor(0, 0, 0, 255);PNGColor red PNGColor(255, 0, 0, 255);PNGColor green PNGColor(0, 255, 0, 255); PNGColor blue PNGColor(0, 255, 255, 255);int width 400;int height 400;PNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) in.size() in encodeimage.init(black);// Please add your code here/********** Begin ********/Vec2i t0 { 50 , 50 }, t1 {300 ,200 }, t2 {200 ,350 };Triangle(t0 ,t1 , t2 , image, PNGColor(255, 0, 0, 255));/********** End **********/image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file(../img_step1/test.png);return 0;
} 直线裁剪v1.0
第1关Cohen-Sutherland编码裁剪算法 一. 任务描述 根据下面要求在右侧修改代码绘制出预期输出的图片。平台会对你编写的代码进行测试。 1.本关任务 1理解直线裁剪的原理Cohen-Surtherland算法、中点分割算法、梁友栋算法 2利用VCOpenGL实现直线的编码裁剪算法在屏幕上用一个封闭矩形裁剪任意一条直线 3调试、编译、修改程序 2.运行前 3.输出 4.具体要求 1对CompCode(Point node, MyRect rect)函数进行补全 2对LineClipCohenSurtherland(MyRect rect, Point node1, Point node2)函数进行补全最终实现裁剪后的图片。 // 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束// 提示写完代码请保存之后再进行评测
#include GL/freeglut.h
#include stdio.h#define LEFT 1
#define RIGHT 2
#define BOTTOM 4
#define TOP 8struct MyRect
{int xmin, xmax, ymin, ymax;MyRect() : xmin(), xmax(), ymin(), ymax(){};MyRect(int a, int b, int c, int d) : xmin(a), xmax(b), ymin(c), ymax(d){};
};struct Point
{int x, y;Point() : x(), y() {};Point(int a, int b) :x(a), y(b) {};
};MyRect rect;
Point vPoint[6];void LineGL(Point node1, Point node2)
{glBegin(GL_LINES);glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(node1.x, node1.y);glVertex2f(node2.x, node2.y);glEnd();
}int CompCode(Point node, MyRect rect)
{// 请在此添加你的代码/********** Begin ********/
int code 0;if (node.x rect.xmin)code | LEFT;else if (node.x rect.xmax)code | RIGHT;if (node.y rect.ymin)code | BOTTOM;else if (node.y rect.ymax)code | TOP;return code;/********** End **********/
}void LineClipCohenSurtherland(MyRect rect, Point node1, Point node2)
{bool accept false;// 请在此添加你的代码/********** Begin ********/int code1 CompCode(node1, rect);int code2 CompCode(node2, rect);while (true){if ((code1 | code2) 0){accept true;break;}else if (code1 code2){break;}else{int code (code1 ! 0) ? code1 : code2;Point node;if (code LEFT){node.x rect.xmin;node.y node1.y (node2.y - node1.y) * (rect.xmin - node1.x) / (node2.x - node1.x);}else if (code RIGHT){node.x rect.xmax;node.y node1.y (node2.y - node1.y) * (rect.xmax - node1.x) / (node2.x - node1.x);}else if (code BOTTOM){node.y rect.ymin;node.x node1.x (node2.x - node1.x) * (rect.ymin - node1.y) / (node2.y - node1.y);}else if (code TOP){node.y rect.ymax;node.x node1.x (node2.x - node1.x) * (rect.ymax - node1.y) / (node2.y - node1.y);}if (code code1){node1 node;code1 CompCode(node1, rect);}else{node2 node;code2 CompCode(node2, rect);}}}/********** End **********/if (accept)LineGL(node1, node2);
}void MyDisplay()
{glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0f, 1.0f, 1.0f);glRectf(rect.xmin, rect.ymin, rect.xmax, rect.ymax);for (int i 0; i 5; i2) LineClipCohenSurtherland(rect, vPoint[i], vPoint[i1]);glFlush();
}void Init()
{glClearColor(0.0, 0.0, 0.0, 0.0);glShadeModel(GL_FLAT);rect MyRect(100, 300, 100, 300);vPoint[0] Point(200, 50); vPoint[1] Point(350, 250);vPoint[2] Point(125, 205); vPoint[3] Point(250, 255);vPoint[4] Point(40, 150); vPoint[5] Point(150, 40);
}void MyReshape(int w, int h)
{glViewport(0, 0, (GLsizei)w, (GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}int main(int argc, char* argv[])
{glutInit(argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow(Hello World!);Init();glutDisplayFunc(MyDisplay);glutReshapeFunc(MyReshape); glutMainLoopEvent(); /*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(400 * 400 * 3);//分配内存GLint viewport[4] {0}; glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for(int i 0; i 400; i ) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for(int j 0; j 400; j ) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k1];plane0Ptr[j] pPixelData[k2];}}cv::merge(imgPlanes, img);cv::flip(img, img ,0); cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);cv::imwrite(../img_step1/test.jpg, img);return 0;
} 第2关中点分割裁剪算法 一. 任务描述 根据下面要求在右侧修改代码绘制出预期输出的图片。平台会对你编写的代码进行测试。 1.本关任务 1理解直线裁剪的原理Cohen-Surtherland算法、中点分割算法、梁友栋算法 2利用VCOpenGL实现直线的编码裁剪算法在屏幕上用一个封闭矩形裁剪任意一条直线 3调试、编译、修改程序 2.运行前 3.输出 // 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束// 提示写完代码请保存之后再进行评测
#include GL/freeglut.h
#include stdio.h#define LEFT 1
#define RIGHT 2
#define BOTTOM 4
#define TOP 8struct MyRect
{int xmin, xmax, ymin, ymax;MyRect() : xmin(), xmax(), ymin(), ymax(){};MyRect(int a, int b, int c, int d) : xmin(a), xmax(b), ymin(c), ymax(d){};
};struct Point
{int x, y;Point() : x(), y() {};Point(int a, int b) :x(a), y(b) {};
};MyRect rect;
Point vPoint[6];void LineGL(Point node1, Point node2)
{glBegin(GL_LINES);glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(node1.x, node1.y);glVertex2f(node2.x, node2.y);glEnd();
}int CompCode(Point node, MyRect rect)
{int code 0x00;if (node.y rect.ymin)code code | BOTTOM;if (node.y rect.ymax)code code | TOP;if (node.x rect.xmax)code code | RIGHT;if (node.x rect.xmin)code code | LEFT;return code;
}void LineClipMidPoint(MyRect rect, Point node1, Point node2)
{bool accept true;Point start, end, mid;//分别代表起点终点和中点int code1, code2, codemid;code1 CompCode(node1, rect);code2 CompCode(node2, rect);if(code1 0 code2 0)accept true;else if(code1 code2)accept false;else {if(code2!0){start node1; end node2;mid Point((float)(start.x end.x)/(float)2 0.5, (float)(start.y end.y)/(float)2 0.5);while(abs(start.x - mid.x)1 || abs(start.y - mid.y)1){codemid CompCode(mid, rect);if(codemid0){start mid;} else{end mid;}mid Point((float)(start.x end.x)/(float)2 0.5, (float)(start.y end.y)/(float)2 0.5);}node2 mid;}if(code1!0){start node1; end node2;mid Point((float)(start.x end.x)/(float)2 0.5, (float)(start.y end.y)/(float)2 0.5);while(abs(start.x - mid.x)1 || abs(start.y - mid.y)1){codemid CompCode(mid, rect);if(codemid0){end mid;}else{start mid;}mid Point((float)(start.x end.x)/(float)2 0.5, (float)(start.y end.y)/(float)2 0.5);}node1 mid;}}if (accept)LineGL(node1, node2);
}void MyDisplay()
{glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0f, 1.0f, 1.0f);glRectf(rect.xmin, rect.ymin, rect.xmax, rect.ymax);for (int i 0; i 5; i2) LineClipMidPoint(rect, vPoint[i], vPoint[i1]);glFlush();
}void Init()
{glClearColor(0.0, 0.0, 0.0, 0.0);glShadeModel(GL_FLAT);rect MyRect(100, 300, 100, 300);vPoint[0] Point(200, 50); vPoint[1] Point(350, 250);vPoint[2] Point(125, 205); vPoint[3] Point(250, 255);vPoint[4] Point(40, 150); vPoint[5] Point(150, 40);
}void MyReshape(int w, int h)
{glViewport(0, 0, (GLsizei)w, (GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}int main(int argc, char* argv[])
{glutInit(argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow(Hello World!);Init();glutDisplayFunc(MyDisplay);glutReshapeFunc(MyReshape); glutMainLoopEvent(); /*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(400 * 400 * 3);//分配内存GLint viewport[4] {0}; glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for(int i 0; i 400; i ) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for(int j 0; j 400; j ) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k1];plane0Ptr[j] pPixelData[k2];}}cv::merge(imgPlanes, img);cv::flip(img, img ,0); cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);cv::imwrite(../img_step3/test.jpg, img);return 0;
} 4.具体要求 对LineClipMidPoint(MyRect rect, Point node1, Point node2)函数进行补全最终实现裁剪后的图片。 第3关Liang-Barsky参数化裁剪算法 一. 任务描述 根据下面要求在右侧修改代码绘制出预期输出的图片。平台会对你编写的代码进行测试。 1.本关任务 1理解直线裁剪的原理Cohen-Surtherland算法、中点分割算法、梁友栋算法 2利用VCOpenGL实现直线的编码裁剪算法在屏幕上用一个封闭矩形裁剪任意一条直线 3调试、编译、修改程序 2.运行前 3.输出 4.具体要求 1对ClipTest(float p, float q, float* u1, float* u2)函数进行补全 2对LineClipLiangBarsky(MyRect rect, Point node1, Point node2)函数进行补全最终实现裁剪后的图片。 // 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束// 提示写完代码请保存之后再进行评测
#include GL/freeglut.h
#include stdio.hstruct MyRect
{int xmin, xmax, ymin, ymax;MyRect() : xmin(), xmax(), ymin(), ymax(){};MyRect(int a, int b, int c, int d) : xmin(a), xmax(b), ymin(c), ymax(d){};
};struct Point
{int x, y;Point() : x(), y() {};Point(int a, int b) :x(a), y(b) {};
};MyRect rect;
Point vPoint[6];void LineGL(Point node1, Point node2)
{glBegin(GL_LINES);glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(node1.x, node1.y);glVertex2f(node2.x, node2.y);glEnd();
}int ClipTest(float p, float q, float* u1, float* u2)
{if (p 0.0){float r q / p;if (r *u2){return 0;}else if (r *u1){*u1 r;}}else if (p 0.0){float r q / p;if (r *u1){return 0;}else if (r *u2){*u2 r;}}else if (q 0.0){return 0;}return 1;
}bool LineClipLiangBarsky(MyRect rect, Point node1, Point node2)
{float u1 0.0, u2 1.0;int dx node2.x - node1.x;int dy node2.y - node1.y;if (ClipTest(-dx, node1.x - rect.xmin, u1, u2)){if (ClipTest(dx, rect.xmax - node1.x, u1, u2)){if (ClipTest(-dy, node1.y - rect.ymin, u1, u2)){if (ClipTest(dy, rect.ymax - node1.y, u1, u2)){if (u2 1.0){node2.x node1.x u2*dx;node2.y node1.y u2*dy;}if (u1 0.0){node1.x node1.x u1*dx;node1.y node1.y u1*dy;}return true;}}}}return false;
}void MyDisplay()
{glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0f, 1.0f, 1.0f);glRectf(rect.xmin, rect.ymin, rect.xmax, rect.ymax);for(int i 0; i 5; i2){bool bAccept LineClipLiangBarsky(rect, vPoint[i], vPoint[i1]);if(bAccept)LineGL(vPoint[i], vPoint[i1]);}glFlush();
}void Init()
{glClearColor(0.0, 0.0, 0.0, 0.0);glShadeModel(GL_FLAT);rect MyRect(100, 300, 100, 300);vPoint[0] Point(200, 50); vPoint[1] Point(350, 250);vPoint[2] Point(125, 205); vPoint[3] Point(250, 255);vPoint[4] Point(40, 150); vPoint[5] Point(150, 40);
}void MyReshape(int w, int h)
{glViewport(0, 0, (GLsizei)w, (GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}int main(int argc, char* argv[])
{glutInit(argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow(Hello World!);Init();glutDisplayFunc(MyDisplay);glutReshapeFunc(MyReshape); glutMainLoopEvent(); /*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(400 * 400 * 3);//分配内存GLint viewport[4] {0}; glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for(int i 0; i 400; i ) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for(int j 0; j 400; j ) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k1];plane0Ptr[j] pPixelData[k2];}}cv::merge(imgPlanes, img);cv::flip(img, img ,0); cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);cv::imwrite(../img_step2/test.jpg, img);return 0;
}
CG2-v1.0-二维几何变换
第1关正方形的平移与缩放 一.任务描述 根据提示在右侧修改代码并自己绘制出图形。平台会对你编写的代码进行测试。 1.本关任务 理解并掌握OpenGL二维平移、旋转、缩放变换的方法 阅读实验原理掌握OpenGL程序平移、旋转、缩放变换的方法。 2.预期输出 3.具体要求 (1).背景色为黑色用 glClearColor 来完成 (2).以中心为绘制原点设计一个边长为2的正方形将正方形设置为红色glColor3f(1.0, 0.0, 0.0) (3).将原正方形保留下来并以正方形为基础然后进行二维几何变换。将正方形向上平移2.0同时将正方形沿X方向放大3倍沿Y方向缩小成原来的0.5倍。新生成的矩形颜色为白色glColor3f (1.0, 1.0, 1.0)。 4.本关提示 (1).用glRectf(函数来绘制正方形 (2).每进行一个矩阵操作时需要先保存这个矩阵调用glPushMatrix()函数把当前矩阵压入堆栈。当需要恢复最近一次的保存时调用glPopMatrix()函数它相当于从堆栈栈顶弹出一个矩阵为当前矩阵后边的三关都会用到。 // 提示写完代码请保存之后再进行评测
#include GL/freeglut.h
#includestdio.h// 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束void init(void)
{ glClearColor(0.0, 0.0, 0.0, 0.0); //设置背景颜色glMatrixMode(GL_PROJECTION);gluOrtho2D(-5.0, 5.0, -5.0, 5.0); //设置显示的范围是X:-5.0~5.0, Y:-5.0~5.0glMatrixMode(GL_MODELVIEW);
}void myDraw(void) //二维几何变换
{// 请在此添加你的代码/********** Begin ********/glPushMatrix();glColor3f(1.0, 0.0, 0.0);glRectf(-1.0f, - 1.0f,1.0f,1.0f);glPopMatrix();glPushMatrix();glTranslatef(0.0f,2.0f,0.0f);glPushMatrix();glScalef(3.0,0.5,1.0);glColor3f (1.0, 1.0, 1.0);glRectf(-1.0f, - 1.0f,1.0f,1.0f);glFlush();/********** End **********/ glFlush();
}int main(int argc, char *argv[])
{glutInit(argc, argv);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow(几何变换示例);init();glutDisplayFunc(myDraw);glutMainLoopEvent(); /*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(400 * 400 * 3);//分配内存GLint viewport[4] {0};glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for(int i 0; i 400; i ) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for(int j 0; j 400; j ) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k1];plane0Ptr[j] pPixelData[k2];}}cv::merge(imgPlanes, img);cv::flip(img, img ,0); cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);//cv::waitKey();cv::imwrite(../img_step1/test.jpg, img);return 0;
} 第2关正方形的平移和旋转 一.任务描述 根据提示在右侧修改代码并自己绘制出图形。平台会对你编写的代码进行测试。 1.本关任务 理解并掌握OpenGL二维平移、旋转、缩放变换的方法 阅读实验原理掌握OpenGL程序平移、旋转、缩放变换的方法。 2.预期输出 3.具体要求 (1).背景色为黑色用 glclearcolor 来完成 (2).以中心为绘制原点设计一个边长为2的正方形将正方形设置为红色glColor3f(1.0, 0.0, 0.0) (3).将原正方形保留下来并以正方形为基础然后进行二维几何变换。将正方形向左平移3.0同时将正方形沿X轴逆时针旋转45度生成新的图形颜色为glColor3f (0.0, 1.0, 0.0); (4).再进行二维几何变换将原正方形向右平移3.0同时将正方形沿X轴逆时针旋转45度生成新的图形颜色为glColor3f (0.0, 0.7, 0.0); 4.本关提示 (1).用glRectf(函数来绘制正方形 (2).每进行一个矩阵操作时需要先保存这个矩阵调用glPushMatrix()函数把当前矩阵压入堆栈。当需要恢复最近一次的保存时调用glPopMatrix()函数它相当于从堆栈栈顶弹出一个矩阵为当前矩阵。 // 提示写完代码请保存之后再进行评测
#include GL/freeglut.h
#includestdio.h// 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束void init(void)
{ glClearColor(0.0, 0.0, 0.0, 0.0); //设置背景颜色glMatrixMode(GL_PROJECTION);gluOrtho2D(-5.0, 5.0, -5.0, 5.0); //设置显示的范围是X:-5.0~5.0, Y:-5.0~5.0glMatrixMode(GL_MODELVIEW);
}void myDraw(void) //二维几何变换
{// 请在此添加你的代码glPushMatrix();glColor3f(1.0, 0.0, 0.0);glRectf(-1.0f, - 1.0f,1.0f,1.0f);glPopMatrix();//glPushMatrix();glTranslatef(-3.0f,0.0f,0.0f);glPushMatrix();glRotatef(45.0,0.0,0.0,1.0);glColor3f (0.0, 1.0, 0.0);glRectf(-1.0f, - 1.0f,1.0f,1.0f);glPopMatrix();glTranslatef(6.0f,0.0f,0.0f);glPushMatrix();glRotatef(45.0,0.0,0.0,1.0);glColor3f (0.0, 0.7, 0.0);glRectf(-1.0f, - 1.0f,1.0f,1.0f);glPopMatrix();glFlush();/********** End **********/ glFlush();
}int main(int argc, char *argv[])
{glutInit(argc, argv);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow(几何变换示例);init();glutDisplayFunc(myDraw);glutMainLoopEvent(); /*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(400 * 400 * 3);//分配内存GLint viewport[4] {0};glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for(int i 0; i 400; i ) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for(int j 0; j 400; j ) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k1];plane0Ptr[j] pPixelData[k2];}}cv::merge(imgPlanes, img);cv::flip(img, img ,0); cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);//cv::waitKey();cv::imwrite(../img_step2/test.jpg, img);return 0;
} 第3关正方形的变换组合 一.任务描述 根据提示在右侧修改代码并自己绘制出图形。平台会对你编写的代码进行测试。 1.本关任务 理解并掌握OpenGL二维平移、旋转、缩放变换的方法 阅读实验原理掌握OpenGL程序平移、旋转、缩放变换的方法。 2.预期输出 3.具体要求 (1).背景色为黑色用 glclearcolor 来完成 (2).以中心为绘制原点设计一个边长为2的正方形将正方形设置为红色glColor3f(1.0, 0.0, 0.0) (3).完成前两关的内容 (4).将原正方形进行二维几何变换。将正方形向下平移3.0同时将正方形沿X方向放大4倍沿Y方向扩大成原来的1.5倍。新生成的矩形颜色为蓝色glColor3f (0.0, 0.0, 1.0)。 4.本关提示 (1).用glRectf(函数来绘制正方形 (2).每进行一个矩阵操作时需要先保存这个矩阵调用glPushMatrix()函数把当前矩阵压入堆栈。当需要恢复最近一次的保存时调用glPopMatrix()函数它相当于从堆栈栈顶弹出一个矩阵为当前矩阵。 // 提示写完代码请保存之后再进行评测
#include GL/freeglut.h
#includestdio.h// 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束void init(void)
{ glClearColor(0.0, 0.0, 0.0, 0.0); //设置背景颜色glMatrixMode(GL_PROJECTION);gluOrtho2D(-5.0, 5.0, -5.0, 5.0); //设置显示的范围是X:-5.0~5.0, Y:-5.0~5.0glMatrixMode(GL_MODELVIEW);
}void myDraw(void) //二维几何变换
{// 请在此添加你的代码/********** Begin ********/glClear (GL_COLOR_BUFFER_BIT); //清空glLoadIdentity(); //将当前矩阵设为单位矩阵glPushMatrix();glTranslatef(0.0f,2.0f,0.0f);glScalef(3.0,0.5,1.0);glColor3f (1.0, 1.0, 1.0);glRectf(-1.0f, -1.0f, 1.0f, 1.0f); //上面白色矩形glPopMatrix();glPushMatrix();glTranslatef(-3.0,0.0,0.0);glPushMatrix();glRotatef(45.0,0.0,0.0,1.0);glColor3f (0.0, 1.0, 0.0);glRectf(-1.0f, -1.0f, 1.0f, 1.0f); //中间左菱形glPopMatrix();glTranslatef(3.0,0.0,0.0);glPushMatrix();glColor3f (1.0, 0.0, 0.0);glRectf(-1.0f, -1.0f, 1.0f, 1.0f); //中间中菱形glPopMatrix();glTranslatef(3.0,0.0,0.0);glPushMatrix();glRotatef(45.0,0.0,0.0,1.0);glColor3f (0.0, 0.7, 0.0);glRectf(-1.0f, -1.0f, 1.0f, 1.0f); //中间右菱形glPopMatrix();glPopMatrix();glTranslatef(0.0,-3.0,0.0);glScalef(4.0,1.5,1.0);glColor3f (0.0, 0.0, 1.0);glRectf(-1.0f, -1.0f, 1.0f, 1.0f); //下面蓝色矩形glFlush ( );/********** End **********/ glFlush();
}int main(int argc, char *argv[])
{glutInit(argc, argv);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow(几何变换示例);init();glutDisplayFunc(myDraw);glutMainLoopEvent(); /*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(400 * 400 * 3);//分配内存GLint viewport[4] {0};glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for(int i 0; i 400; i ) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for(int j 0; j 400; j ) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k1];plane0Ptr[j] pPixelData[k2];}}cv::merge(imgPlanes, img);cv::flip(img, img ,0); cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);//cv::waitKey();cv::imwrite(../img_step3/test.jpg, img);return 0;
} 第4关三菱形状 一.任务描述 根据提示在右侧修改代码并自己绘制出图形。平台会对你编写的代码进行测试。 1.本关任务 理解并掌握OpenGL二维平移、旋转、缩放变换的方法 阅读实验原理掌握OpenGL程序平移、旋转、缩放变换的方法 利用虚拟机进行编程以OpenGL为开发平台设计程序设计二维几何变换图形。 2.预期输出 设计如图所示二维图形 3.具体要求 (1).背景色为黑色用 glclearcolor 来完成 (2).三个菱形图形通过二维平移和旋转完成。颜色分别为红色(1.0, 0.0, 0.0)、蓝色(0.0, 0.0, 1.0)和绿色(0.0, 1.0, 0.0) (3).三个菱形的长对角线长度为4.0短对角线长度为2.0三个菱形的交点为原点0.00.0 (4).红色菱形的长对角线与Y轴重合每个菱形的长对角线夹角为120度。 4.本关提示 (1).可将绘制原始的图形设置成一个单独的函数便于调用这样可以省去反复绘制原始图形的步骤 (2).画一个凸多边形可以调用glBegin(GL_POLYGON)后边用glVertex2f( , )指定顶点坐标需要注意凸多边形的顶点指定需要按逆时针方向 (3).保留原始图形可以看做调用平移函数并且平移的距离为(0.00.00.0) (4).每进行一个矩阵操作时需要先保存这个矩阵调用glPushMatrix()函数把当前矩阵压入堆栈。当需要恢复最近一次的保存时调用glPopMatrix()函数它相当于从堆栈栈顶弹出一个矩阵为当前矩阵。 // 提示写完代码请保存之后再进行评测
#include GL/freeglut.h
#includestdio.h// 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束void init(void)
{ glClearColor(0.0, 0.0, 0.0, 0.0); //设置背景颜色glMatrixMode(GL_PROJECTION);gluOrtho2D(-5.0, 5.0, -5.0, 5.0); //设置显示的范围是X:-5.0~5.0, Y:-5.0~5.0glMatrixMode(GL_MODELVIEW);
}
void drawDiamond(void) //绘制一个菱形
{// 请在此添加你的代码/********** Begin ********/glBegin (GL_POLYGON); //顶点指定需要按逆时针方向glVertex2f (0.0f,-1.0f);//下点glVertex2f (2.0f,0.0f);//右点glVertex2f (0.0f, 1.0f);//上点glVertex2f (-2.0f,0.0f);//左点glEnd ( );/********** End **********/
}void myDraw(void) //二维几何变换
{// 请在此添加你的代码/********** Begin ********/glClear(GL_COLOR_BUFFER_BIT); //清空glLoadIdentity(); //将当前矩阵设为单位矩阵glPushMatrix();glRotatef(30.0, 0.0, 0.0, 1.0);glTranslatef(-2.0, 0.0, 0.0);glColor3f(0.0, 1.0, 0.0);drawDiamond();glPopMatrix();glPushMatrix();glRotatef(150.0, 0.0, 0.0, 1.0);glTranslatef(-2.0, 0.0, 0.0);glColor3f(0.0, 0.0, 1.0);drawDiamond();glPopMatrix();glPushMatrix();glRotatef(270.0, 0.0, 0.0, 1.0);glTranslatef(-2.0, 0.0, 0.0);glColor3f(1.0, 0.0, 0.0);drawDiamond();/********** End **********/ glFlush();
}int main(int argc, char *argv[])
{glutInit(argc, argv);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow(几何变换示例);init();glutDisplayFunc(myDraw);glutMainLoopEvent(); /*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(400 * 400 * 3);//分配内存GLint viewport[4] {0};glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for(int i 0; i 400; i ) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for(int j 0; j 400; j ) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k1];plane0Ptr[j] pPixelData[k2];}}cv::merge(imgPlanes, img);cv::flip(img, img ,0); cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);//cv::waitKey();cv::imwrite(../img_step4/test.jpg, img);return 0;
}
CG3-v2.0-图形几何变换 第1关平移、缩放、旋转正方体 一. 任务描述 1. 本关任务 (1) 理解几何变换基本原理, 掌握平移、旋转、缩放变换的方法; (2) 根据平移算法原理补全translation、scale、rotation_x、rotation_y和rotation_z函数; (3) 根据几何变换基本原理,将main函数中的translation、scale、rotation_z参数补充完整。 2. 输入 (1) 代码将自动输入一个边长为2的obj正方体模型具体模型如下图 (2) 代码自动将模型投影到二维平面上生成一个边长为1的白色正方形并且代码会生成红色x轴绿色y轴具体图片如下所示 (3) 将立方体的顶点坐标分别向x,y,z轴正方向平移0.5个单位距离然后绘制一个红色正方形 (4) 将立方体的顶点坐标分别沿x,y,z轴方向缩放0.5倍然后绘制一个绿色正方形 (5) 将立方体的顶点坐标沿z轴逆时针方向旋转45度然后绘制一个黄色正方形。 3. 输出 具体结果如下图所示 #include vector
#include cmath
#include algorithm
#include iostream
#include model.h
#include geometry.h
#include pngimage.husing namespace std;
const double PI acos(-1.0);void line(Vec3i p0, Vec3i p1, PNGImage image, PNGColor color)
{bool steep false;if (std::abs(p0.x - p1.x) std::abs(p0.y - p1.y)){std::swap(p0.x, p0.y);std::swap(p1.x, p1.y);steep true;}if (p0.x p1.x){std::swap(p0.x, p1.x);std::swap(p0.y, p1.y);}int dx p1.x - p0.x;int dy std::abs(p1.y - p0.y);int y p0.y;int d -dx;for (int x p0.x; x p1.x; x){if (steep)image.set(y, x, color);elseimage.set(x, y, color);d d 2 * dy;if (d 0){y (p1.y p0.y ? 1 : -1);d d - 2 * dx;}}
}Matrix viewport(int x, int y, int w, int h, int depth) {Matrix m Matrix::identity(4);m[0][3] x w / 2.f;m[1][3] y h / 2.f;m[2][3] depth / 2.f;m[0][0] w / 2.f;m[1][1] h / 2.f;m[2][2] depth / 2.f;return m;
}Matrix translation(Vec3f v) {Matrix Tr Matrix::identity(4);// Please add the code here/********** Begin ********/Tr[0][3] v.x;Tr[1][3] v.y;Tr[2][3] v.z;/********** End *********/return Tr;
}Matrix scale(float factorX, float factorY, float factorZ)
{Matrix Z Matrix::identity(4);/********** Begin ********/Z[0][0] factorX;Z[1][1] factorY;Z[2][2] factorZ;/********** End *********/return Z;
}Matrix rotation_x(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);/********** Begin ********/R[1][1] R[2][2] cosangle;R[1][2] -sinangle;R[2][1] sinangle;/********** End *********/return R;
}Matrix rotation_y(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);/********** Begin ********/R[0][0] R[2][2] cosangle;R[0][2] sinangle;R[2][0] -sinangle;/********** End *********/return R;
}Matrix rotation_z(float angle) {angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);/********** Begin ********/R[0][0] R[1][1] cosangle;R[0][1] -sinangle;R[1][0] sinangle;/********** End *********/return R;
}int main(int argc, char** argv)
{const PNGColor white PNGColor(255, 255, 255, 255);const PNGColor black PNGColor(0, 0, 0, 255);const PNGColor red PNGColor(255, 0, 0, 255);const PNGColor green PNGColor(0, 255, 0, 255);const PNGColor blue PNGColor(0, 0, 255, 255);const PNGColor yellow PNGColor(255, 255, 0, 255);Model *model NULL;const int width 500;const int height 500;const int depth 255;//generate some imagePNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) in.size() in encodeimage.init(black);model new Model(../step3/cube.obj);Matrix VP viewport(width / 4, width / 4, width / 2, height / 2, depth);{ // draw the axesVec3f x(1.f, 0.f, 0.f), y(0.f, 1.f, 0.f), o(0.f, 0.f, 0.f);o VP*o;x VP*x;y VP*y;line(o, x, image, red);line(o, y, image, green);}for (int i 0; i model-nfaces(); i) {std::vectorint face model-face(i);for (int j 0; j (int)face.size(); j) {Vec3f wp0 model-vert(face[j]);Vec3f wp1 model-vert(face[(j 1) % face.size()]);// draw the original modelVec3f op0 VP*wp0;Vec3f op1 VP*wp1;line(op0, op1, image, white);// draw the translated model// Please add the code here/********** Begin ********/Matrix T translation(Vec3f(0.5, 0.5, 0.5));/********** End *********/Vec3f tp0 VP*T*wp0;Vec3f tp1 VP*T*wp1;line(tp0, tp1, image, red);// draw the scaled model// Please add the code here/********** Begin ********/ Matrix S scale(0.5, 0.5, 0.5);/********** End *********/Vec3f sp0 VP*S*wp0;Vec3f sp1 VP*S*wp1;line(sp0, sp1, image, green);// draw the rotated model// Please add the code here/********** Begin ********/ Matrix R rotation_z(45);/********** End *********/Vec3f rp0 VP*R*wp0;Vec3f rp1 VP*R*wp1;line(rp0, rp1, image, yellow);}}image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file(../img_step3/test.png);delete model;return 0;
} 第2关图形的平移与缩放 一. 任务描述 1. 本关任务 (1) 理解几何变换基本原理, 掌握平移和缩放变换的方法; (2) 根据几何变换基本原理,将main函数中的空白部分补充完整。 2. 输入 (1) 代码将自动输入一个边长为2的obj正方体模型具体模型如下图 (2) 将立方体的顶点坐标分别沿x,y,z轴方向缩放0.5倍然后绘制一个白色正方形 (3) 将立方体的顶点坐标分别沿x,y,z轴方向缩放0.5倍再分别向x,y,z轴正方向平移0.5个单位距离然后绘制一个红色正方形 (4) 将立方体的顶点坐标分别向x,y,z轴正方向平移0.5个单位距离再分别沿x,y,z轴方向缩放0.5倍然后绘制一个绿色正方形。 3. 输出 具体结果如下图所示 #include vector
#include cmath
#include algorithm
#include iostream
#include model.h
#include geometry.h
#include pngimage.husing namespace std;
const double PI acos(-1.0);void line(Vec3i p0, Vec3i p1, PNGImage image, PNGColor color)
{bool steep false;if (std::abs(p0.x - p1.x) std::abs(p0.y - p1.y)){std::swap(p0.x, p0.y);std::swap(p1.x, p1.y);steep true;}if (p0.x p1.x){std::swap(p0.x, p1.x);std::swap(p0.y, p1.y);}int dx p1.x - p0.x;int dy std::abs(p1.y - p0.y);int y p0.y;int d -dx;for (int x p0.x; x p1.x; x){if (steep)image.set(y, x, color);elseimage.set(x, y, color);d d 2 * dy;if (d 0){y (p1.y p0.y ? 1 : -1);d d - 2 * dx;}}
}Matrix viewport(int x, int y, int w, int h, int depth) {Matrix m Matrix::identity(4);m[0][3] x w / 2.f;m[1][3] y h / 2.f;m[2][3] depth / 2.f;m[0][0] w / 2.f;m[1][1] h / 2.f;m[2][2] depth / 2.f;return m;
}Matrix translation(Vec3f v) {Matrix Tr Matrix::identity(4);Tr[0][3] v.x;Tr[1][3] v.y;Tr[2][3] v.z;return Tr;
}Matrix scale(float factorX, float factorY, float factorZ)
{Matrix Z Matrix::identity(4);Z[0][0] factorX;Z[1][1] factorY;Z[2][2] factorZ;return Z;
}Matrix rotation_x(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[1][1] R[2][2] cosangle;R[1][2] -sinangle;R[2][1] sinangle;return R;
}Matrix rotation_y(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[2][2] cosangle;R[0][2] sinangle;R[2][0] -sinangle;return R;
}Matrix rotation_z(float angle) {angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[1][1] cosangle;R[0][1] -sinangle;R[1][0] sinangle;return R;
}int main(int argc, char** argv)
{const PNGColor white PNGColor(255, 255, 255, 255);const PNGColor black PNGColor(0, 0, 0, 255);const PNGColor red PNGColor(255, 0, 0, 255);const PNGColor green PNGColor(0, 255, 0, 255);const PNGColor blue PNGColor(0, 0, 255, 255);const PNGColor yellow PNGColor(255, 255, 0, 255);Model *model NULL;const int width 500;const int height 500;const int depth 255;//generate some imagePNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) in.size() in encodeimage.init(black);model new Model(cube.obj);Matrix VP viewport(width / 4, width / 4, width / 2, height / 2, depth);for (int i 0; i model-nfaces(); i){std::vectorint face model-face(i);for (int j 0; j (int)face.size(); j){Vec3f wp0 model-vert(face[j]);Vec3f wp1 model-vert(face[(j 1) % face.size()]);// Please add the code here/********** Begin ********/Matrix S0 scale(0.5, 0.5, 0.5);Vec3f swp0 S0 * wp0;Vec3f swp1 S0 * wp1;// draw the model after scaledVec3f op0 VP * swp0;Vec3f op1 VP * swp1;line(op0, op1, image, white);Matrix T translation(Vec3f(0.5, 0.5, 0.5));Matrix S scale(0.5, 0.5, 0.5);// scaled then translatedVec3f tsp0 VP*T*S*swp0;Vec3f tsp1 VP*T*S*swp1;line(tsp0, tsp1, image, red);// translated then scaledVec3f stp0 VP*S*T*swp0;Vec3f stp1 VP*S*T*swp1;line(stp0, stp1, image, green);/********** End *********/}}image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file(../img_step2/test.png);delete model;return 0;
}
第3关图形的平移与旋转 一. 任务描述 1. 本关任务 (1) 理解几何变换基本原理, 掌握平移和旋转变换的方法; (2) 根据几何变换基本原理,将main函数中的空白部分补充完整。 2. 输入 (1) 代码将自动输入一个边长为2的obj正方体模型具体模型如下图 (2) 将立方体的顶点坐标分别沿x,y,z轴方向缩放0.5倍然后绘制一个白色正方形 (3) 将立方体的顶点坐标分别向x,y,z轴正方向平移0.5个单位距离再沿z轴逆时针方向旋转45度然后绘制一个绿色正方形 (4) 将立方体的顶点坐标分别沿z轴逆时针方向旋转45度再分别向x,y,z轴正方向平移0.5个单位距离然后绘制一个红色正方形 3. 输出 具体结果如下图所示 #include vector
#include cmath
#include algorithm
#include iostream
#include model.h
#include geometry.h
#include pngimage.husing namespace std;
const double PI acos(-1.0);void line(Vec3i p0, Vec3i p1, PNGImage image, PNGColor color)
{bool steep false;if (std::abs(p0.x - p1.x) std::abs(p0.y - p1.y)){std::swap(p0.x, p0.y);std::swap(p1.x, p1.y);steep true;}if (p0.x p1.x){std::swap(p0.x, p1.x);std::swap(p0.y, p1.y);}int dx p1.x - p0.x;int dy std::abs(p1.y - p0.y);int y p0.y;int d -dx;for (int x p0.x; x p1.x; x){if (steep)image.set(y, x, color);elseimage.set(x, y, color);d d 2 * dy;if (d 0){y (p1.y p0.y ? 1 : -1);d d - 2 * dx;}}
}Matrix viewport(int x, int y, int w, int h, int depth) {Matrix m Matrix::identity(4);m[0][3] x w / 2.f;m[1][3] y h / 2.f;m[2][3] depth / 2.f;m[0][0] w / 2.f;m[1][1] h / 2.f;m[2][2] depth / 2.f;return m;
}Matrix translation(Vec3f v) {Matrix Tr Matrix::identity(4);Tr[0][3] v.x;Tr[1][3] v.y;Tr[2][3] v.z;return Tr;
}Matrix scale(float factorX, float factorY, float factorZ)
{Matrix Z Matrix::identity(4);Z[0][0] factorX;Z[1][1] factorY;Z[2][2] factorZ;return Z;
}Matrix rotation_x(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[1][1] R[2][2] cosangle;R[1][2] -sinangle;R[2][1] sinangle;return R;
}Matrix rotation_y(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[2][2] cosangle;R[0][2] sinangle;R[2][0] -sinangle;return R;
}Matrix rotation_z(float angle) {angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[1][1] cosangle;R[0][1] -sinangle;R[1][0] sinangle;return R;
}int main(int argc, char** argv)
{const PNGColor white PNGColor(255, 255, 255, 255);const PNGColor black PNGColor(0, 0, 0, 255);const PNGColor red PNGColor(255, 0, 0, 255);const PNGColor green PNGColor(0, 255, 0, 255);const PNGColor blue PNGColor(0, 0, 255, 255);const PNGColor yellow PNGColor(255, 255, 0, 255);Model *model NULL;const int width 500;const int height 500;const int depth 255;//generate some imagePNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) in.size() in encodeimage.init(black);model new Model(cube.obj);Matrix VP viewport(width / 4, width / 4, width / 2, height / 2, depth);for (int i 0; i model-nfaces(); i){std::vectorint face model-face(i);for (int j 0; j (int)face.size(); j){Vec3f wp0 model-vert(face[j]);Vec3f wp1 model-vert(face[(j 1) % face.size()]);// Please add the code here/********** Begin ********/Matrix S scale(0.5,0.5,0.5);Vec3f sp0 VP*S*wp0;Vec3f sp1 VP*S*wp1;line(sp0,sp1,image,white);Matrix P rotation_z(45)*translation(Vec3f(0.5,0.5,0.5))*S;Vec3f pp0 VP*P*wp0;Vec3f pp1 VP*P*wp1;line(pp0,pp1,image,green);Matrix Q translation(Vec3f(0.5,0.5,0.5))*rotation_z(45)*S;Vec3f qp0 VP*Q*wp0;Vec3f qp1 VP*Q*wp1;line(qp0,qp1,image,red);/********** End *********/}}image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file(../img_step1/test.png);delete model;return 0;
} 第4关图形的旋转与缩放 一. 任务描述 1. 本关任务 (1) 理解几何变换基本原理, 掌握旋转和缩放变换的方法; (2) 根据几何变换基本原理,将main函数中的空白部分补充完整。 2. 输入 (1) 代码将自动输入一个边长为2的obj正方体模型具体模型如下图 (2) 将立方体的顶点坐标分别沿x,y,z轴方向缩放0.5倍然后绘制一个白色正方形 (3) 将立方体的顶点坐标分别向y,z轴缩放0.5倍x轴保持不变再沿z轴逆时针方向旋转45度然后绘制一个绿色矩形 (4) 将立方体的顶点坐标分别沿z轴逆时针方向旋转45度再分别向y,z轴缩放0.5倍x轴保持不变然后绘制一个红菱形。 3. 输出 具体结果如下图所示 #include vector
#include cmath
#include algorithm
#include iostream
#include model.h
#include geometry.h
#include pngimage.husing namespace std;
const double PI acos(-1.0);void line(Vec3i p0, Vec3i p1, PNGImage image, PNGColor color)
{bool steep false;if (std::abs(p0.x - p1.x) std::abs(p0.y - p1.y)){std::swap(p0.x, p0.y);std::swap(p1.x, p1.y);steep true;}if (p0.x p1.x){std::swap(p0.x, p1.x);std::swap(p0.y, p1.y);}int dx p1.x - p0.x;int dy std::abs(p1.y - p0.y);int y p0.y;int d -dx;for (int x p0.x; x p1.x; x){if (steep)image.set(y, x, color);elseimage.set(x, y, color);d d 2 * dy;if (d 0){y (p1.y p0.y ? 1 : -1);d d - 2 * dx;}}
}Matrix viewport(int x, int y, int w, int h, int depth) {Matrix m Matrix::identity(4);m[0][3] x w / 2.f;m[1][3] y h / 2.f;m[2][3] depth / 2.f;m[0][0] w / 2.f;m[1][1] h / 2.f;m[2][2] depth / 2.f;return m;
}Matrix translation(Vec3f v) {Matrix Tr Matrix::identity(4);Tr[0][3] v.x;Tr[1][3] v.y;Tr[2][3] v.z;return Tr;
}Matrix scale(float factorX, float factorY, float factorZ)
{Matrix Z Matrix::identity(4);Z[0][0] factorX;Z[1][1] factorY;Z[2][2] factorZ;return Z;
}Matrix rotation_x(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[1][1] R[2][2] cosangle;R[1][2] -sinangle;R[2][1] sinangle;return R;
}Matrix rotation_y(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[2][2] cosangle;R[0][2] sinangle;R[2][0] -sinangle;return R;
}Matrix rotation_z(float angle) {angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[1][1] cosangle;R[0][1] -sinangle;R[1][0] sinangle;return R;
}int main(int argc, char** argv)
{const PNGColor white PNGColor(255, 255, 255, 255);const PNGColor black PNGColor(0, 0, 0, 255);const PNGColor red PNGColor(255, 0, 0, 255);const PNGColor green PNGColor(0, 255, 0, 255);const PNGColor blue PNGColor(0, 0, 255, 255);const PNGColor yellow PNGColor(255, 255, 0, 255);Model *model NULL;const int width 500;const int height 500;const int depth 255;//generate some imagePNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) in.size() in encodeimage.init(black);model new Model(cube.obj);Matrix VP viewport(width / 4, width / 4, width / 2, height / 2, depth);for (int i 0; i model-nfaces(); i){std::vectorint face model-face(i);for (int j 0; j (int)face.size(); j){Vec3f wp0 model-vert(face[j]);Vec3f wp1 model-vert(face[(j 1) % face.size()]);// Please add the code here/********** Begin ********/Matrix S scale(0.5,0.5,0.5);Vec3f sp0 VP*S*wp0;Vec3f sp1 VP*S*wp1;line(sp0,sp1,image,white);Matrix P rotation_z(45)*scale(1,0.5,0.5)*S;Vec3f pp0 VP*P*wp0;Vec3f pp1 VP*P*wp1;line(pp0,pp1,image,green);Matrix Q scale(1,0.5,0.5)*rotation_z(45)*S;Vec3f qp0 VP*Q*wp0;Vec3f qp1 VP*Q*wp1;line(qp0,qp1,image,red);/********** End *********/}}image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file(../img_step4/test.png);delete model;return 0;
}第5关绘制三菱形状 一. 任务描述 1. 本关任务 (1) 理解几何变换基本原理, 掌握平移、旋转和缩放变换的方法; (2) 根据几何变换基本原理,将main函数中的空白部分补充完整来绘制三菱形状。 2. 输入 (1) 代码将自动输入一个边长为2的obj正方体模型具体模型如下图 (2) 将立方体的顶点坐标分别沿x,y,z轴方向缩放0.5倍 (3) 将立方体的顶点坐标分别沿z轴逆时针方向旋转45度再分别向y,z轴缩放0.5倍x轴保持不变然后绘制一个红菱形 (4) 将红色菱形沿着x轴正方向平移22 个单位距离然后将红菱形沿Z轴逆时针旋转90度 (5)绿色和黄色菱形与红色菱形的夹角均为120度。 3. 输出 具体结果如下图所示 #include vector
#include cmath
#include algorithm
#include iostream
#include model.h
#include geometry.h
#include pngimage.husing namespace std;
const double PI acos(-1.0);void line(Vec3i p0, Vec3i p1, PNGImage image, PNGColor color)
{bool steep false;if (std::abs(p0.x - p1.x) std::abs(p0.y - p1.y)){std::swap(p0.x, p0.y);std::swap(p1.x, p1.y);steep true;}if (p0.x p1.x){std::swap(p0.x, p1.x);std::swap(p0.y, p1.y);}int dx p1.x - p0.x;int dy std::abs(p1.y - p0.y);int y p0.y;int d -dx;for (int x p0.x; x p1.x; x){if (steep)image.set(y, x, color);elseimage.set(x, y, color);d d 2 * dy;if (d 0){y (p1.y p0.y ? 1 : -1);d d - 2 * dx;}}
}Matrix viewport(int x, int y, int w, int h, int depth) {Matrix m Matrix::identity(4);m[0][3] x w / 2.f;m[1][3] y h / 2.f;m[2][3] depth / 2.f;m[0][0] w / 2.f;m[1][1] h / 2.f;m[2][2] depth / 2.f;return m;
}Matrix translation(Vec3f v) {Matrix Tr Matrix::identity(4);Tr[0][3] v.x;Tr[1][3] v.y;Tr[2][3] v.z;return Tr;
}Matrix scale(float factorX, float factorY, float factorZ)
{Matrix Z Matrix::identity(4);Z[0][0] factorX;Z[1][1] factorY;Z[2][2] factorZ;return Z;
}Matrix rotation_x(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[1][1] R[2][2] cosangle;R[1][2] -sinangle;R[2][1] sinangle;return R;
}Matrix rotation_y(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[2][2] cosangle;R[0][2] sinangle;R[2][0] -sinangle;return R;
}Matrix rotation_z(float angle) {angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[1][1] cosangle;R[0][1] -sinangle;R[1][0] sinangle;return R;
}int main(int argc, char** argv)
{const PNGColor white PNGColor(255, 255, 255, 255);const PNGColor black PNGColor(0, 0, 0, 255);const PNGColor red PNGColor(255, 0, 0, 255);const PNGColor green PNGColor(0, 255, 0, 255);const PNGColor blue PNGColor(0, 0, 255, 255);const PNGColor yellow PNGColor(255, 255, 0, 255);Model *model NULL;const int width 800;const int height 800;const int depth 255;//generate some imagePNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) in.size() in encodeimage.init(black);model new Model(cube.obj);Matrix VP viewport(width / 4, width / 4, width / 2, height / 2, depth);for (int i 0; i model-nfaces(); i){std::vectorint face model-face(i);for (int j 0; j (int)face.size(); j){Vec3f wp0 model-vert(face[j]);Vec3f wp1 model-vert(face[(j 1) % face.size()]);Matrix T translation(Vec3f(sqrt(2)/2, 0, 0));// Please add the code here/********** Begin ********/Matrix S scale(0.5f,0.5f ,0.5f );Matrix S1 scale(1.f,0.5f ,0.5f );Matrix R rotation_z(45.f);Matrix R3 rotation_z(90.f);Matrix R2 rotation_z(120.f);Matrix R1 rotation_z(-120.f);Vec3f sp0 VP*R3*T*S1*R*S*wp0;Vec3f sp1 VP*R3*T*S1*R*S*wp1;line(sp0, sp1, image, red);Vec3f op0 VP*R2*R3*T*S1*R*S*wp0;Vec3f op1 VP*R2*R3*T*S1*R*S*wp1;line(op0, op1, image,green );Vec3f Sp0 VP*R1*R3*T*S1*R*S*wp0;Vec3f Sp1 VP*R1*R3*T*S1*R*S*wp1;line(Sp0, Sp1, image,yellow );/********** End *********/} }image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file(../img_step5/test.png);delete model;return 0;
}
模型、观察及视口变换v1.0
第1关立方体模型变换 一.任务描述 根据提示在右侧修改代码并自己绘制出图形。平台会对你编写的代码进行测试。 1.本关任务 学习了解三维图形几何变换原理。 理解掌握OpenGL三维图形几何变换的方法。 理解掌握OpenGL程序的模型视图变换。 掌握OpenGL三维图形显示与观察的原理与实现。 2.预期输出 3.具体要求 (1).背景色为黑色用 glclearcolor 来完成 (2).运用glPushMatrix()函数和glPopMatrix()函数进行矩阵操作以中心为绘制原点设置前景色为红色glColor3f(1.0, 0.0, 0.0)绘制单位立方体线框用glutWireCube(1.0)完成; (3).运用glPushMatrix()函数和glPopMatrix()函数进行矩阵操作设置前景色为黑色glColor3f(0.0, 1.0, 0.0)设置线宽为2.0用glLineWidth(2.0)完成将原单位立方体线框沿X轴正方向平移2.0 (4).运用glPushMatrix()函数和glPopMatrix()函数进行矩阵操作沿X轴负方向平移2.0设置前景色为蓝色glColor3f(0.0, 0.0, 1.0)绘制单位立方体实体用glutSolidCube(1.0)完成 // 提示在合适的地方修改或添加代码
#include GL/freeglut.h
#includestdio.h// 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束GLint winWidth 400, winHeight 400 ; //设置初始化窗口大小/*观察坐标系参数设置*/
GLfloat x0 0.0, yy 0.0, z0 5.0; //设置观察坐标系原点
GLfloat xref 0.0, yref 0.0, zref 0.0; //设置观察坐标系参考点视点
GLfloat Vx 0.0, Vy 1.0, Vz 0.0; //设置观察坐标系向上向量y轴 /*观察体参数设置 */
GLfloat xwMin -1.0, ywMin -1.0, xwMax 1.0, ywMax 1.0;//设置裁剪窗口坐标范围
GLfloat dnear 1.5, dfar 20.0; //设置远、近裁剪面深度范围void init(void)
{glClearColor(0.0, 0.0, 0.0, 0.0);
}
void display(void)
{glClear(GL_COLOR_BUFFER_BIT);glLoadIdentity();/*观察变换*/gluLookAt(x0, yy, z0, xref, yref, zref, Vx, Vy, Vz); //指定三维观察参数// 请在此添加你的代码/********** Begin ********///glColor3f(1.0, 0.0, 0.0);glPushMatrix();glutWireCube(1.0);glPopMatrix();
//glColor3f(0.0, 1.0, 0.0);glLineWidth(2.0);glPushMatrix();glTranslatef(2.0f,0.0f,0.0f);glutWireCube(1.0);glPopMatrix();
//glColor3f(0.0, 0.0, 1.0);glPushMatrix();glTranslatef(-2.0f,0.0f,0.0f);glutSolidCube(1.0);glPopMatrix();/********** End **********/glFlush();
}void reshape(GLint newWidth, GLint newHeight)
{/*视口变换*/glViewport(0, 0, newWidth, newHeight); //定义视口大小/*投影变换*/glMatrixMode(GL_PROJECTION);glLoadIdentity();/*透视投影设置透视观察体*/glFrustum(xwMin, xwMax, ywMin, ywMax, dnear, dfar);/*模型变换*/glMatrixMode(GL_MODELVIEW);winWidth newWidth;winHeight newHeight;
}
int main(int argc, char* argv[])
{glutInit(argc, argv);glutInitWindowPosition(100, 100);glutInitWindowSize( 400 , 400 ); //设置初始化窗口大小glutCreateWindow(三维观察);init();glutDisplayFunc(display);glutReshapeFunc(reshape);glutMainLoopEvent();/*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(800 * 400 * 3);//分配内存GLint viewport[4] { 0 };glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for (int i 0; i 400; i) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for (int j 0; j 400; j) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k 1];plane0Ptr[j] pPixelData[k 2];}}cv::merge(imgPlanes, img);cv::flip(img, img, 0);cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);//cv::waitKey();cv::imwrite(../img_step1/test.jpg, img);return 0;
} 第2关立方体观察变换 一.任务描述 根据提示在右侧修改代码并自己绘制出图形。平台会对你编写的代码进行测试。 1.本关任务 学习了解三维图形几何变换原理。 理解掌握OpenGL三维图形几何变换的方法。 理解掌握OpenGL程序的模型视图变换。 掌握OpenGL三维图形显示与观察的原理与实现。 2.预期输出 3.具体要求 (1).背景色为黑色用 glclearcolor 来完成 (2).运用glPushMatrix()函数和glPopMatrix()函数进行矩阵操作以中心为绘制原点设置前景色为红色glColor3f(1.0, 0.0, 0.0)绘制单位立方体线框用glutWireCube(1.0)完成; (3).运用glPushMatrix()函数和glPopMatrix()函数进行矩阵操作设置前景色为黑色glColor3f(0.0, 1.0, 0.0)设置线宽为2.0用glLineWidth(2.0)完成将原单位立方体线框沿X轴正方向平移2.0 (4).运用glPushMatrix()函数和glPopMatrix()函数进行矩阵操作沿X轴负方向平移2.0设置前景色为蓝色glColor3f(0.0, 0.0, 1.0)绘制单位立方体实体用glutSolidCube(1.0)完成 (5).视点改为1.0,1.5,8.0)观察中心改为在(0, 0 ,0)向上矢量改为(0, 1, 0) (6).将glFrustum(xwMin, xwMax, ywMin, ywMax, dnear, dfar);换为透视投影gluPerspective (fovy,aspect,zNear,zFar)函数参数分别为视角宽高比近处远处。要求参数为gluPerspective(45, 1, 1, 100)。 // 提示在合适的地方修改或添加代码
#include GL/freeglut.h
#includestdio.h// 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束GLint winWidth 400, winHeight 400 ; //设置初始化窗口大小/*观察坐标系参数设置*/
GLfloat x0 1.0, yy 1.5, z0 8.0; //设置观察坐标系原点
GLfloat xref 0.0, yref 0.0, zref 0.0; //设置观察坐标系参考点视点
GLfloat Vx 0.0, Vy 1.0, Vz 0.0; //设置观察坐标系向上向量y轴 /*观察体参数设置 */
GLfloat xwMin -1.0, ywMin -1.0, xwMax 1.0, ywMax 1.0;//设置裁剪窗口坐标范围
GLfloat dnear 1.5, dfar 20.0; //设置远、近裁剪面深度范围void init(void)
{glClearColor(0.0, 0.0, 0.0, 0.0);
}
void display(void)
{glClear(GL_COLOR_BUFFER_BIT);glLoadIdentity();/*观察变换*/gluLookAt(x0, yy, z0, xref, yref, zref, Vx, Vy, Vz); //指定三维观察参数// 请在此添加你的代码/********** Begin ********/glPushMatrix();glColor3f(1.0, 0.0, 0.0);glutWireCube(1.0);glPopMatrix();glPushMatrix();glColor3f(0.0, 1.0, 0.0);glLineWidth(2.0);glTranslatef(2.0f,0.0f,0.0f);glutWireCube(1.0);glPopMatrix();glPushMatrix();glColor3f(0.0, 0.0, 1.0);glLineWidth(2.0);glTranslatef(-2.0f,0.0f,0.0f);glutSolidCube(1.0);glPopMatrix();/********** End **********/glFlush();
}
void reshape(GLint newWidth, GLint newHeight)
{/*视口变换*/glViewport(0, 0, newWidth, newHeight); //定义视口大小/*投影变换*/glMatrixMode(GL_PROJECTION);glLoadIdentity();/*透视投影设置透视观察体*/gluPerspective( 45,1,1,100 );/*模型变换*/glMatrixMode(GL_MODELVIEW);winWidth newWidth;winHeight newHeight;
}
int main(int argc, char* argv[])
{glutInit(argc, argv);glutInitWindowPosition(100, 100);glutInitWindowSize( 400 , 400 ); //设置初始化窗口大小glutCreateWindow(三维观察);init();glutDisplayFunc(display);glutReshapeFunc(reshape);glutMainLoopEvent();/*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(800 * 400 * 3);//分配内存GLint viewport[4] { 0 }; glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for (int i 0; i 400; i) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for (int j 0; j 400; j) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k 1];plane0Ptr[j] pPixelData[k 2];}}cv::merge(imgPlanes, img);cv::flip(img, img, 0);cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);//cv::waitKey();cv::imwrite(../img_step2/test.jpg, img);return 0;
} 第3关立方体视口变换 一.任务描述 根据提示在右侧修改代码并自己绘制出图形。平台会对你编写的代码进行测试。 1.本关任务 学习了解三维图形几何变换原理。 理解掌握OpenGL三维图形几何变换的方法。 理解掌握OpenGL程序的模型视图变换。 掌握OpenGL三维图形显示与观察的原理与实现。 2.预期输出 3.具体要求 (1).背景色为黑色用 glclearcolor 来完成 (2).运用glPushMatrix()函数和glPopMatrix()函数进行矩阵操作以中心为绘制原点设置前景色为红色glColor3f(1.0, 0.0, 0.0)绘制单位立方体线框用glutWireCube(1.0)完成; (3).运用glPushMatrix()函数和glPopMatrix()函数进行矩阵操作设置前景色为黑色glColor3f(0.0, 1.0, 0.0)设置线宽为2.0用glLineWidth(2.0)完成将原单位立方体线框沿X轴正方向平移2.0 (4).运用glPushMatrix()函数和glPopMatrix()函数进行矩阵操作沿X轴负方向右平移2.0设置前景色为蓝色glColor3f(0.0, 0.0, 1.0)绘制单位立方体实体用glutSolidCube(1.0)完成 (5).进行视口变换视口宽为800高为400。实验内调整winWidth和winHeight 来设置初始化窗口大小 (6).调用透视投影gluperspective()函数参数为gluPerspective(45, 2, 1, 100)要求宽高比为2 (7).在main函数中用glutInitWindowSize()调整视口窗口大小。 // 提示在合适的地方修改或添加代码
#include GL/freeglut.h
#includestdio.h// 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束GLint winWidth 800 , winHeight 400 ; //设置初始化窗口大小/*观察坐标系参数设置*/
GLfloat x0 0.0, yy 0.0, z0 5.0; //设置观察坐标系原点
GLfloat xref 0.0, yref 0.0, zref 0.0; //设置观察坐标系参考点视点
GLfloat Vx 0.0, Vy 1.0, Vz 0.0; //设置观察坐标系向上向量y轴 /*观察体参数设置 */
GLfloat xwMin -1.0, ywMin -1.0, xwMax 1.0, ywMax 1.0;//设置裁剪窗口坐标范围
GLfloat dnear 1.5, dfar 20.0; //设置远、近裁剪面深度范围void init(void)
{glClearColor(0.0, 0.0, 0.0, 0.0);
}
void display(void)
{glClear(GL_COLOR_BUFFER_BIT);glLoadIdentity();/*观察变换*/gluLookAt(x0, yy, z0, xref, yref, zref, Vx, Vy, Vz); //指定三维观察参数// 请在此添加你的代码/********** Begin ********/glColor3f(1.0, 0.0, 0.0);glPushMatrix();glutWireCube(1.0);glPopMatrix();glColor3f(0.0, 1.0, 0.0);glLineWidth(2.0);glPushMatrix();glTranslatef(2.0f,0.0f,0.0f);glutWireCube(1.0);glPopMatrix();glColor3f(0.0, 0.0, 1.0);glPushMatrix();glTranslatef(-2.0f,0.0f,0.0f);glutSolidCube(1.0);glPopMatrix();/********** End **********/glFlush();
}void reshape(GLint newWidth, GLint newHeight)
{/*视口变换*/glViewport(0, 0, newWidth, newHeight); //定义视口大小/*投影变换*/glMatrixMode(GL_PROJECTION);glLoadIdentity();/*透视投影设置透视观察体*/gluPerspective( 45,2 ,1 ,100 );/*模型变换*/glMatrixMode(GL_MODELVIEW);winWidth newWidth;winHeight newHeight;
}
int main(int argc, char* argv[])
{glutInit(argc, argv);glutInitWindowPosition(100, 100);glutInitWindowSize( 800 ,400 ); //设置初始化窗口大小glutCreateWindow(三维观察);init();glutDisplayFunc(display);glutReshapeFunc(reshape);glutMainLoopEvent();/*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(800 * 400 * 3);//分配内存GLint viewport[4] { 0 }; glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 800, CV_8UC3);cv::split(img, imgPlanes);for (int i 0; i 400; i) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for (int j 0; j 800; j) {int k 3 * (i * 800 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k 1];plane0Ptr[j] pPixelData[k 2];}}cv::merge(imgPlanes, img);cv::flip(img, img, 0);cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);//cv::waitKey();cv::imwrite(../img_step5/test.jpg, img);return 0;
}
模型、观察及视口变换v2.0
第1关模型变换-左右两个立方体 一. 任务描述 1. 本关任务 (1) 理解模型变换基本原理,掌握平移和旋转变换的方法; (2) 根据模型变换基本原理,将main函数中的空白部分补充完整。 2. 输入 (1) 代码将自动输入一个边长为1的obj正方体模型具体模型如下图 (2) 代码自动将模型投影到二维平面上生成一个边长为1的白色立方体具体图片如下所示 (3) 将白色立方体的顶点坐标向x轴正方向平移1.2个单位距离然后绘制一个红色立方形 (4) 将白色立方体的顶点坐标沿y轴逆时针方向旋转30度再向x轴负方向平移1.3个单位距离然后绘制一个绿色正方形。 3. 输出 具体结果如下图所示 #include vector
#include cmath
#include algorithm
#include iostream
#include model.h
#include geometry.h
#include pngimage.husing namespace std;
const double PI acos(-1.0);void line(Vec3i p0, Vec3i p1, PNGImage image, PNGColor color)
{bool steep false;if (std::abs(p0.x - p1.x) std::abs(p0.y - p1.y)){std::swap(p0.x, p0.y);std::swap(p1.x, p1.y);steep true;}if (p0.x p1.x){std::swap(p0.x, p1.x);std::swap(p0.y, p1.y);}int dx p1.x - p0.x;int dy std::abs(p1.y - p0.y);int y p0.y;int d -dx;for (int x p0.x; x p1.x; x){if (steep)image.set(y, x, color);elseimage.set(x, y, color);d d 2 * dy;if (d 0){y (p1.y p0.y ? 1 : -1);d d - 2 * dx;}}
}Matrix translation(Vec3f v) {//平移Matrix Tr Matrix::identity(4);Tr[0][3] v.x;Tr[1][3] v.y;Tr[2][3] v.z;return Tr;
}Matrix scale(float factorX, float factorY, float factorZ)
{Matrix Z Matrix::identity(4);Z[0][0] factorX;Z[1][1] factorY;Z[2][2] factorZ;return Z;
}Matrix rotation_x(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[1][1] R[2][2] cosangle;R[1][2] -sinangle;R[2][1] sinangle;return R;
}Matrix rotation_y(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[2][2] cosangle;R[0][2] sinangle;R[2][0] -sinangle;return R;
}Matrix rotation_z(float angle) {angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[1][1] cosangle;R[0][1] -sinangle;R[1][0] sinangle;return R;
}int main(int argc, char** argv)
{const PNGColor white PNGColor(255, 255, 255, 255);const PNGColor black PNGColor(0, 0, 0, 255);const PNGColor red PNGColor(255, 0, 0, 255);const PNGColor green PNGColor(0, 255, 0, 255);const PNGColor blue PNGColor(0, 0, 255, 255);const PNGColor yellow PNGColor(255, 255, 0, 255);Model *model NULL;const int width 500;const int height 500;const int depth 255;Vec3f eye(0.5, 1.5, 4);Vec3f center(0, 0, 0);Matrix Projection Matrix::projection(eye, center);Matrix ViewPort Matrix::viewport(width / 4, width / 4, width / 2, height / 2, depth);//generate some imagePNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) in.size() in encodeimage.init(black);model new Model(cube.obj);for (int i 0; i model-nfaces(); i){std::vectorint face model-face(i);for (int j 0; j (int)face.size(); j){Vec3f wp0 model-vert(face[j]);Vec3f wp1 model-vert(face[(j 1) % face.size()]);Matrix S0 scale(0.5, 0.5, 0.5);Vec3f swp0 S0 * wp0;Vec3f swp1 S0 * wp1;// for comparing - draw the model after scaled Vec3f op0 ViewPort * Projection * swp0;Vec3f op1 ViewPort * Projection * swp1;line(op0, op1, image, white);// Please add the code here/********** Begin ********///3) 将白色立方体的顶点坐标向x轴正方向平移1.2个单位距离然后绘制一个红色立方形Matrix S1 translation(Vec3f(1.2,0.0,0.0));op0 ViewPort * Projection *S1 * swp0;op1 ViewPort * Projection *S1 * swp1;line(op0, op1, image, red);// (4) 将白色立方体的顶点坐标沿y轴逆时针方向旋转30度再向x轴负方向平移1.3个单位距离然后绘制一个绿色正方形// Matrix rotation_y(float angle)Matrix S3 rotation_y(30.0);Matrix S4 translation(Vec3f(-1.3,0.0,0.0));op0 ViewPort * Projection *S4 *S3 * swp0;op1 ViewPort * Projection *S4 *S3 * swp1;line(op0, op1, image,green );/********** End *********/}}image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file(../img_step1/test.png);delete model;return 0;
}
第2关观察变换 一. 任务描述 1. 本关任务 (1) 理解观察变换基本原理,将lookat函数中空白部分补充完整; (2) 将main函数中的参数补充完整。 2. 输入 (1) 代码将自动输入一个边长为1的obj正方体模型具体模型如下图 (2) 相机坐标为(0, 1.5, 4)中心点坐标为000向上的矢量为Vec3f(0, 1, 0) 3. 输出 具体结果如下图所示 #include vector
#include cmath
#include algorithm
#include iostream
#include model.h
#include geometry.h
#include pngimage.husing namespace std;
const double PI acos(-1.0);void line(Vec3i p0, Vec3i p1, PNGImage image, PNGColor color)
{bool steep false;if (std::abs(p0.x - p1.x) std::abs(p0.y - p1.y)){std::swap(p0.x, p0.y);std::swap(p1.x, p1.y);steep true;}if (p0.x p1.x){std::swap(p0.x, p1.x);std::swap(p0.y, p1.y);}int dx p1.x - p0.x;int dy std::abs(p1.y - p0.y);int y p0.y;int d -dx;for (int x p0.x; x p1.x; x){if (steep)image.set(y, x, color);elseimage.set(x, y, color);d d 2 * dy;if (d 0){y (p1.y p0.y ? 1 : -1);d d - 2 * dx;}}
}Matrix lookat(Vec3f eye, Vec3f center, Vec3f up) {Matrix res Matrix::identity(4);// Please add the code here/********** Begin ********/Vec3f z (eye - center).normalize();Vec3f x (up^z).normalize();Vec3f y (z^x).normalize();for (int i 0; i 3; i) {res[0][i] x[i];res[1][i] y[i];res[2][i] z[i];res[i][3] -center[i];}/********** End ********/return res;
}Matrix translation(Vec3f v) {Matrix Tr Matrix::identity(4);Tr[0][3] v.x;Tr[1][3] v.y;Tr[2][3] v.z;return Tr;
}Matrix scale(float factorX, float factorY, float factorZ)
{Matrix Z Matrix::identity(4);Z[0][0] factorX;Z[1][1] factorY;Z[2][2] factorZ;return Z;
}Matrix rotation_x(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[1][1] R[2][2] cosangle;R[1][2] -sinangle;R[2][1] sinangle;return R;
}Matrix rotation_y(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[2][2] cosangle;R[0][2] sinangle;R[2][0] -sinangle;return R;
}Matrix rotation_z(float angle) {angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[1][1] cosangle;R[0][1] -sinangle;R[1][0] sinangle;return R;
}int main(int argc, char** argv)
{const PNGColor white PNGColor(255, 255, 255, 255);const PNGColor black PNGColor(0, 0, 0, 255);const PNGColor red PNGColor(255, 0, 0, 255);const PNGColor green PNGColor(0, 255, 0, 255);const PNGColor blue PNGColor(0, 0, 255, 255);const PNGColor yellow PNGColor(255, 255, 0, 255);Model *model NULL;const int width 500;const int height 500;const int depth 255;// Please add the code here/********** Begin ********/Vec3f eye(0 ,1.5 ,4 );Vec3f center( 0, 0 ,0 );Matrix ModelView lookat(eye, center, Vec3f( 0, 1 ,0 ));// Please add the code here/********** Begin ********/Matrix Projection Matrix::projection(eye, center);Matrix ViewPort Matrix::viewport(width / 4, width / 4, width / 2, height / 2, depth);//generate some imagePNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) in.size() in encodeimage.init(black);model new Model(cube.obj);for (int i 0; i model-nfaces(); i){std::vectorint face model-face(i);for (int j 0; j (int)face.size(); j){Vec3f wp0 model-vert(face[j]);Vec3f wp1 model-vert(face[(j 1) % face.size()]);Matrix S0 scale(0.5, 0.5, 0.5);Vec3f swp0 S0 * wp0;Vec3f swp1 S0 * wp1;Vec3f sp0 ViewPort*Projection*ModelView*swp0;Vec3f sp1 ViewPort*Projection*ModelView*swp1;line(sp0, sp1, image, red);}}image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file(../img_step2/test.png);delete model;return 0;
} 第3关视口变换 一. 任务描述 1. 本关任务 (1) 理解视口变换的方法; (3) 根据视口变换的方法将viewport函数中的空白部分补充完整并将main函数中的参数补充完整。 2. 输入 (1) 代码将自动输入一个边长为1的obj正方体模型具体模型如下图 (2) 视口矩阵中参数x、y的大小为宽度(width)的四分之一参数w的大小为宽度的一半(width)参数h的大小为高度的一半(height)参数d255。 3. 输出 具体结果如下图所示 #include vector
#include cmath
#include algorithm
#include iostream
#include model.h
#include geometry.h
#include pngimage.husing namespace std;
const double PI acos(-1.0);void line(Vec3i p0, Vec3i p1, PNGImage image, PNGColor color)
{bool steep false;if (std::abs(p0.x - p1.x) std::abs(p0.y - p1.y)){std::swap(p0.x, p0.y);std::swap(p1.x, p1.y);steep true;}if (p0.x p1.x){std::swap(p0.x, p1.x);std::swap(p0.y, p1.y);}int dx p1.x - p0.x;int dy std::abs(p1.y - p0.y);int y p0.y;int d -dx;for (int x p0.x; x p1.x; x){if (steep)image.set(y, x, color);elseimage.set(x, y, color);d d 2 * dy;if (d 0){y (p1.y p0.y ? 1 : -1);d d - 2 * dx;}}
}Matrix viewport(int x, int y, int w, int h, int depth) {Matrix m Matrix::identity(4);// Please add the code here/********** Begin ********/m[0][0]w/2;m[0][3]x(w/2);m[1][1]h/2;m[1][3]yh/2;m[2][2]255/2;m[2][3]255/2;m[3][3]1;/********** End **********/return m;
}Matrix lookat(Vec3f eye, Vec3f center, Vec3f up) {Vec3f z (eye - center).normalize();Vec3f x (up^z).normalize();Vec3f y (z^x).normalize();Matrix res Matrix::identity(4);for (int i 0; i 3; i) {res[0][i] x[i];res[1][i] y[i];res[2][i] z[i];res[i][3] -center[i];}return res;
}Matrix translation(Vec3f v) {Matrix Tr Matrix::identity(4);Tr[0][3] v.x;Tr[1][3] v.y;Tr[2][3] v.z;return Tr;
}Matrix scale(float factorX, float factorY, float factorZ)
{Matrix Z Matrix::identity(4);Z[0][0] factorX;Z[1][1] factorY;Z[2][2] factorZ;return Z;
}Matrix rotation_x(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[1][1] R[2][2] cosangle;R[1][2] -sinangle;R[2][1] sinangle;return R;
}Matrix rotation_y(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[2][2] cosangle;R[0][2] sinangle;R[2][0] -sinangle;return R;
}Matrix rotation_z(float angle) {angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[1][1] cosangle;R[0][1] -sinangle;R[1][0] sinangle;return R;
}int main(int argc, char** argv)
{const PNGColor white PNGColor(255, 255, 255, 255);const PNGColor black PNGColor(0, 0, 0, 255);const PNGColor red PNGColor(255, 0, 0, 255);const PNGColor green PNGColor(0, 255, 0, 255);const PNGColor blue PNGColor(0, 0, 255, 255);const PNGColor yellow PNGColor(255, 255, 0, 255);Model *model NULL;Vec3f eye(0, 1.5, 4);Vec3f center(0, 0, 0);Matrix ModelView lookat(eye, center, Vec3f(0, 1, 0));Matrix Projection Matrix::projection(eye, center);const int width 500;const int height 500;const int depth 255;// Please add the code here/********** Begin ********/Matrix ViewPort viewport(width/4,width/4,width/2,height/2,depth);/********** End **********///generate some imagePNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) in.size() in encodeimage.init(black);model new Model(cube.obj);for (int i 0; i model-nfaces(); i){std::vectorint face model-face(i);for (int j 0; j (int)face.size(); j){Vec3f wp0 model-vert(face[j]);Vec3f wp1 model-vert(face[(j 1) % face.size()]);Matrix S0 scale(0.5, 0.5, 0.5);Vec3f swp0 S0 * wp0;Vec3f swp1 S0 * wp1;Vec3f sp0 ViewPort*Projection*ModelView*swp0;Vec3f sp1 ViewPort*Projection*ModelView*swp1;line(sp0, sp1, image, red);}}image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file(../img_step3/test.png);delete model;return 0;
}
投影变换v1.0 第1关立方体透视投影 一.任务描述 根据提示在右侧修改代码并自己绘制出图形。平台会对你编写的代码进行测试。 1.本关任务 学习了解三维图形几何变换原理。 理解掌握OpenGL三维图形几何变换的方法。 理解掌握OpenGL程序的模型视图变换。 掌握OpenGL三维图形显示与观察的原理与实现。 2.预期输出 3.具体要求 (1).背景色为黑色用 glclearcolor 来完成 (2).运用glPushMatrix()函数和glPopMatrix()函数进行矩阵操作以中心为绘制原点设置前景色为红色glColor3f(1.0, 0.0, 0.0)绘制单位立方体线框用glutWireCube(1.0)完成; (3).运用glPushMatrix()函数和glPopMatrix()函数进行矩阵操作设置前景色为黑色glColor3f(0.0, 1.0, 0.0)设置线宽为2.0用glLineWidth(2.0)完成将原单位立方体线框沿X轴正方向平移2.0 (4).运用glPushMatrix()函数和glPopMatrix()函数进行矩阵操作沿X轴负方向平移2.0设置前景色为蓝色glColor3f(0.0, 0.0, 1.0)绘制单位立方体实体用glutSolidCube(1.0)完成 (5).由图可知中间红色为一点透视。右边绿色和左边蓝色为两点透视。通过glRotatef()旋转绿色立方体来完成蓝色立方体的三点透视。将绿色立方体绕X轴旋转30度。 // 提示在合适的地方修改或添加代码
#include GL/freeglut.h
#includestdio.h// 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束GLint winWidth 400, winHeight 400 ; //设置初始化窗口大小/*观察坐标系参数设置*/
GLfloat x0 0.0, yy 0.0, z0 5.0; //设置观察坐标系原点
GLfloat xref 0.0, yref 0.0, zref 0.0; //设置观察坐标系参考点视点
GLfloat Vx 0.0, Vy 1.0, Vz 0.0; //设置观察坐标系向上向量y轴 /*观察体参数设置 */
GLfloat xwMin -1.0, ywMin -1.0, xwMax 1.0, ywMax 1.0;//设置裁剪窗口坐标范围
GLfloat dnear 1.5, dfar 20.0; //设置远、近裁剪面深度范围void init(void)
{glClearColor(0.0, 0.0, 0.0, 0.0);
}
void display(void)
{glClear(GL_COLOR_BUFFER_BIT);glLoadIdentity();/*观察变换*/gluLookAt(x0, yy, z0, xref, yref, zref, Vx, Vy, Vz); //指定三维观察参数// 请在此添加你的代码/********** Begin ********/glPushMatrix();glColor3f(1.0, 0.0, 0.0); //设置前景色为红色glutWireCube(1.0); //绘制单位立方体线框glPopMatrix();glPushMatrix();glColor3f(0.0, 1.0, 0.0); //设置前景色为黑色glLineWidth(2.0); //设置线宽glRotatef(30,1,0,0);glTranslatef(2.0f, 0.0f, 0.0f);glutWireCube(1.0); //绘制单位立方体线框glPopMatrix();glPushMatrix();glTranslatef(-2.0f, 0.0f, 0.0f);glColor3f(0.0, 0.0, 1.0);glutSolidCube(1.0); //绘制单位立方体实体glPopMatrix();/********** End **********/glFlush();
}void reshape(GLint newWidth, GLint newHeight)
{/*视口变换*/glViewport(0, 0, newWidth, newHeight); //定义视口大小/*投影变换*/glMatrixMode(GL_PROJECTION);glLoadIdentity();/*透视投影设置透视观察体*/glFrustum(xwMin, xwMax, ywMin, ywMax, dnear, dfar);/*模型变换*/glMatrixMode(GL_MODELVIEW);winWidth newWidth;winHeight newHeight;
}
int main(int argc, char* argv[])
{glutInit(argc, argv);glutInitWindowPosition(100, 100);glutInitWindowSize( 400 , 400 ); //设置初始化窗口大小glutCreateWindow(三维观察);init();glutDisplayFunc(display);glutReshapeFunc(reshape);glutMainLoopEvent();/*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(800 * 400 * 3);//分配内存GLint viewport[4] { 0 };glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for (int i 0; i 400; i) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for (int j 0; j 400; j) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k 1];plane0Ptr[j] pPixelData[k 2];}}cv::merge(imgPlanes, img);cv::flip(img, img, 0);cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);//cv::waitKey();cv::imwrite(../img_step4/test.jpg, img);return 0;
}第2关立方体平行投影 一.任务描述 根据提示在右侧修改代码并自己绘制出图形。平台会对你编写的代码进行测试。 1.本关任务 学习了解三维图形几何变换原理。 理解掌握OpenGL三维图形几何变换的方法。 理解掌握OpenGL程序的模型视图变换。 掌握OpenGL三维图形显示与观察的原理与实现。 2.预期输出 3.具体要求 (1).背景色为黑色用 glclearcolor 来完成 (2).运用glPushMatrix()函数和glPopMatrix()函数进行矩阵操作以中心为绘制原点设置前景色为红色glColor3f(1.0, 0.0, 0.0)绘制单位立方体线框用glutWireCube(1.0)完成; (3).运用glPushMatrix()函数和glPopMatrix()函数进行矩阵操作设置前景色为黑色glColor3f(0.0, 1.0, 0.0)设置线宽为2.0用glLineWidth(2.0)完成将原单位立方体线框沿X轴正方向平移2.0 (4).运用glPushMatrix()函数和glPopMatrix()函数进行矩阵操作沿X轴负方向平移2.0设置前景色为蓝色glColor3f(0.0, 0.0, 1.0)绘制单位立方体实体用glutSolidCube(1.0)完成 (5).进行平行投影调用glOrtho()函数坐标为(左右下上近远)坐标为glOrtho(-3.0, 3.0, -3.0, 3.0,-100.0, 100.0); // 提示在合适的地方修改或添加代码
#include GL/freeglut.h
#includestdio.h// 评测代码所用头文件-开始
#includeopencv2/core/core.hpp
#includeopencv2/highgui/highgui.hpp
#includeopencv2/imgproc/imgproc.hpp
// 评测代码所用头文件-结束GLint winWidth 400, winHeight 400 ; //设置初始化窗口大小/*观察坐标系参数设置*/
GLfloat x0 0.0, yy 0.0, z0 5.0; //设置观察坐标系原点
GLfloat xref 0.0, yref 0.0, zref 0.0; //设置观察坐标系参考点视点
GLfloat Vx 0.0, Vy 1.0, Vz 0.0; //设置观察坐标系向上向量y轴 /*观察体参数设置 */
GLfloat xwMin -1.0, ywMin -1.0, xwMax 1.0, ywMax 1.0;//设置裁剪窗口坐标范围
GLfloat dnear 1.5, dfar 20.0; //设置远、近裁剪面深度范围void init(void)
{glClearColor(0.0, 0.0, 0.0, 0.0);
}
void display(void)
{glClear(GL_COLOR_BUFFER_BIT);glLoadIdentity();/*观察变换*/gluLookAt(x0, yy, z0, xref, yref, zref, Vx, Vy, Vz); //指定三维观察参数// 请在此添加你的代码/********** Begin ********/glPushMatrix();glColor3f(1.0, 0.0, 0.0); //设置前景色为红色glutWireCube(1.0); //绘制单位立方体线框glPopMatrix();glPushMatrix();glColor3f(0.0, 1.0, 0.0); //设置前景色为黑色glLineWidth(2.0); //设置线宽glTranslatef(2.0f, 0.0f, 0.0f);glutWireCube(1.0); //绘制单位立方体线框glPopMatrix();glPushMatrix();glTranslatef(-2.0f, 0.0f, 0.0f);glColor3f(0.0, 0.0, 1.0);glutSolidCube(1.0); //绘制单位立方体实体glPopMatrix();/********** End **********/glFlush();
}void reshape(GLint newWidth, GLint newHeight)
{/*视口变换*/glViewport(0, 0, newWidth, newHeight); //定义视口大小/*投影变换*/glMatrixMode(GL_PROJECTION);glLoadIdentity();/*平行投影*/glOrtho( -3,3 ,-3 ,3 ,-100 ,100 );/*模型变换*/glMatrixMode(GL_MODELVIEW);winWidth newWidth;winHeight newHeight;
}
int main(int argc, char* argv[])
{glutInit(argc, argv);glutInitWindowPosition(100, 100);glutInitWindowSize( 400 , 400 ); //设置初始化窗口大小glutCreateWindow(三维观察);init();glutDisplayFunc(display);glutReshapeFunc(reshape);glutMainLoopEvent();/*************以下为评测代码与本次实验内容无关请勿修改**************/GLubyte* pPixelData (GLubyte*)malloc(800 * 400 * 3);//分配内存GLint viewport[4] { 0 };glReadBuffer(GL_FRONT);glPixelStorei(GL_UNPACK_ALIGNMENT, 4);glGetIntegerv(GL_VIEWPORT, viewport);glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3], GL_RGB, GL_UNSIGNED_BYTE, pPixelData);cv::Mat img;std::vectorcv::Mat imgPlanes;img.create(400, 400, CV_8UC3);cv::split(img, imgPlanes);for (int i 0; i 400; i) {unsigned char* plane0Ptr imgPlanes[0].ptrunsigned char(i);unsigned char* plane1Ptr imgPlanes[1].ptrunsigned char(i);unsigned char* plane2Ptr imgPlanes[2].ptrunsigned char(i);for (int j 0; j 400; j) {int k 3 * (i * 400 j);plane2Ptr[j] pPixelData[k];plane1Ptr[j] pPixelData[k 1];plane0Ptr[j] pPixelData[k 2];}}cv::merge(imgPlanes, img);cv::flip(img, img, 0);cv::namedWindow(openglGrab);cv::imshow(openglGrab, img);//cv::waitKey();cv::imwrite(../img_step3/test.jpg, img);return 0;
}
投影变换v2.0
第1关一点透视 一. 任务描述 1. 本关任务 (1) 理解透视投影变换的方法; (2) 将projection函数和main函数中的空白部分补充完整。 2. 输入 (1) 代码将自动输入一个边长为1的obj正方体模型具体模型如下图 (2) 代码自动将模型投影到二维平面中心生成一个边长为1的立方体经过模型变换和投影变换后生成三个绿色的方体三个立方体的投影变换eye的坐标均为(0,0,5)具体图片如下所示 (3) 参考已有代码将中心立绿色方体的顶点分别向y轴负方向平移1.2个单位绘制一个红色立方体。再将红色立方体顶点分别向x轴正负两个方向平移1.2个单位绘制两个红色立方体。三个立方体的投影变换eye的坐标均为(0,0,4) (4) 将中心绿色立方体的顶点分别向y轴正方向平移1.2个单位绘制一个黄色立方体。再将黄色立方体顶点分别向x轴正负两个方向平移1.2个单位绘制两个黄色立方体。三个立方体的投影变换eye的坐标均为(0,0,8) 3. 输出 具体结果如下图所示 #include vector
#include cmath
#include algorithm
#include iostream
#include model.h
#include geometry.h
#include pngimage.h
using namespace std;
const double PI acos(-1.0);
void line(Vec3i p0, Vec3i p1, PNGImage image, PNGColor color)
{bool steep false;if (std::abs(p0.x - p1.x) std::abs(p0.y - p1.y)){std::swap(p0.x, p0.y);std::swap(p1.x, p1.y);steep true;}if (p0.x p1.x){std::swap(p0.x, p1.x);std::swap(p0.y, p1.y);}int dx p1.x - p0.x;int dy std::abs(p1.y - p0.y);int y p0.y;int d -dx;for (int x p0.x; x p1.x; x){if (steep)image.set(y, x, color);elseimage.set(x, y, color);d d 2 * dy;if (d 0){y (p1.y p0.y ? 1 : -1);d d - 2 * dx;}}
}
Matrix projection(Vec3f eye, Vec3f center)
{Matrix m Matrix::identity(4);// Please add the code here/********** Begin ********/m[3][2] -1.f / (eye - center).norm();/********** End **********/return m;
}
Matrix viewport(int x, int y, int w, int h, int depth) {Matrix m Matrix::identity(4);m[0][3] x w / 2.f;m[1][3] y h / 2.f;m[2][3] depth / 2.f;m[0][0] w / 2.f;m[1][1] h / 2.f;m[2][2] depth / 2.f;return m;
}
Matrix lookat(Vec3f eye, Vec3f center, Vec3f up) {Vec3f z (eye - center).normalize();Vec3f x (up^z).normalize();Vec3f y (z^x).normalize();Matrix res Matrix::identity(4);for (int i 0; i 3; i) {res[0][i] x[i];res[1][i] y[i];res[2][i] z[i];res[i][3] -center[i];}return res;
}
Matrix translation(Vec3f v) {Matrix Tr Matrix::identity(4);Tr[0][3] v.x;Tr[1][3] v.y;Tr[2][3] v.z;return Tr;
}
Matrix scale(float factorX, float factorY, float factorZ)
{Matrix Z Matrix::identity(4);Z[0][0] factorX;Z[1][1] factorY;Z[2][2] factorZ;return Z;
}
Matrix rotation_x(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[1][1] R[2][2] cosangle;R[1][2] -sinangle;R[2][1] sinangle;return R;
}
Matrix rotation_y(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[2][2] cosangle;R[0][2] sinangle;R[2][0] -sinangle;return R;
}
Matrix rotation_z(float angle) {angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[1][1] cosangle;R[0][1] -sinangle;R[1][0] sinangle;return R;
}
int main(int argc, char** argv)
{const PNGColor white PNGColor(255, 255, 255, 255);const PNGColor black PNGColor(0, 0, 0, 255);const PNGColor red PNGColor(255, 0, 0, 255);const PNGColor green PNGColor(0, 255, 0, 255);const PNGColor blue PNGColor(0, 0, 255, 255);const PNGColor yellow PNGColor(255, 255, 0, 255);Model *model NULL;const int width 800;const int height 800;const int depth 255;Vec3f center(0, 0, 0);Matrix ViewPort viewport(width / 4, width / 4, width / 2, height / 2, depth);//generate some imagePNGImage image(width, height, PNGImage::RGBA); image.init(black);model new Model(cube.obj);for (int i 0; i model-nfaces(); i){std::vectorint face model-face(i);for (int j 0; j (int)face.size(); j){Vec3f wp0 model-vert(face[j]);Vec3f wp1 model-vert(face[(j 1) % face.size()]);Matrix S0 scale(0.5, 0.5, 0.5);Vec3f swp0 S0 * wp0;Vec3f swp1 S0 * wp1;// 一点透视 float t[3] { -1.2, 0, 1.2 };Matrix ModelView Matrix::identity(4);PNGColor clr[3] { red, green, yellow };Vec3f eye2(0, 0, 5);Matrix Projection2 projection(eye2, center);for (int j 0; j 3; j){ModelView translation(Vec3f(t[j], t[1], 0));Vec3f op0 ViewPort * Projection2 * ModelView * swp0;Vec3f op1 ViewPort * Projection2 * ModelView *swp1;line(op0, op1, image, green);}// Please add the code here/********** Begin ********/Vec3f eye1(0, 0, 4);Matrix Projection1 projection(eye1, center);for (int j 0; j 3; j){ModelView translation(Vec3f(t[j], t[0], 0));Vec3f op0 ViewPort * Projection1 * ModelView * swp0;Vec3f op1 ViewPort * Projection1 * ModelView *swp1;line(op0, op1, image, red);}Vec3f eye3(0, 0, 8);Matrix Projection3 projection(eye3, center);for (int j 0; j 3; j){ModelView translation(Vec3f(t[j], t[2], 0));Vec3f op0 ViewPort * Projection3 * ModelView * swp0;Vec3f op1 ViewPort * Projection3 * ModelView *swp1;line(op0, op1, image, yellow);}/********** End **********/}}image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file(../img_step1/test.png);delete model;return 0;
}
第2关两点透视 一. 任务描述 1. 本关任务 (1) 理解透视投影变换的方法; (2) 将main函数中的空白部分补充完整。 2. 输入 (1) 代码将自动输入一个边长为1的obj正方体模型具体模型如下图 (2) 代码自动将模型投影到二维平面中心生成一个边长为1的绿色立方体 (3) 改变模型位置产生两点透视: 将绿色立方体顶点分别沿z轴逆时针旋转45度向y轴正方向平移1.2个单位绘制一个红色立方体。再将红色立方体顶点分别向x轴正负两个方向平移1.2个单位绘制两个红色立方体。最后对三个红立方体进行投影变换变换矩阵Projection已给出 (4) 改变视点与模型位置产生两点透视(先模型变换再观察变换) 首先将立绿色方体的顶点分别向x轴正负两个方向平移1.2个单位绘制两个绿色立方体。然后对三个绿色立方体分别进行观察变换将参数eye沿y轴顺时针旋转45度作为相机坐标中心点坐标为center向上矢量为Vec3f(0, 1, 0)。最后对三个绿立方体进行投影变换变换矩阵Projection已给出 (5) 改变视点与模型位置产生两点透视(先观察变换再模型变换) 首先对绿色立方体分别进行观察变换将参数eye沿y轴顺时针旋转45度作为相机坐标中心点坐标为center向上矢量为Vec3f(0, 1, 0)。将绿色立方体向y轴负方向平移1.2个单位绘制一个黄色立方体。再将黄色立方体顶点分别向x轴正负两个方向平移1.2个单位绘制两个黄色立方体。最后对三个黄立方体进行投影变换变换矩阵Projection已给出。 3. 输出 具体结果如下图所示 #include vector
#include cmath
#include algorithm
#include iostream
#include model.h
#include geometry.h
#include pngimage.husing namespace std;
const double PI acos(-1.0);void line(Vec3i p0, Vec3i p1, PNGImage image, PNGColor color)
{bool steep false;if (std::abs(p0.x - p1.x) std::abs(p0.y - p1.y)){std::swap(p0.x, p0.y);std::swap(p1.x, p1.y);steep true;}if (p0.x p1.x){std::swap(p0.x, p1.x);std::swap(p0.y, p1.y);}int dx p1.x - p0.x;int dy std::abs(p1.y - p0.y);int y p0.y;int d -dx;for (int x p0.x; x p1.x; x){if (steep)image.set(y, x, color);elseimage.set(x, y, color);d d 2 * dy;if (d 0){y (p1.y p0.y ? 1 : -1);d d - 2 * dx;}}
}Matrix projection(Vec3f eye, Vec3f center)
{Matrix m Matrix::identity(4);m[3][2] -1.f / (eye - center).norm();return m;
}Matrix viewport(int x, int y, int w, int h, int depth) {Matrix m Matrix::identity(4);m[0][3] x w / 2.f;m[1][3] y h / 2.f;m[2][3] depth / 2.f;m[0][0] w / 2.f;m[1][1] h / 2.f;m[2][2] depth / 2.f;return m;
}Matrix lookat(Vec3f eye, Vec3f center, Vec3f up) {Vec3f z (eye - center).normalize();Vec3f x (up^z).normalize();Vec3f y (z^x).normalize();Matrix res Matrix::identity(4);for (int i 0; i 3; i) {res[0][i] x[i];res[1][i] y[i];res[2][i] z[i];res[i][3] -center[i];}return res;
}Matrix translation(Vec3f v) {Matrix Tr Matrix::identity(4);Tr[0][3] v.x;Tr[1][3] v.y;Tr[2][3] v.z;return Tr;
}Matrix scale(float factorX, float factorY, float factorZ)
{Matrix Z Matrix::identity(4);Z[0][0] factorX;Z[1][1] factorY;Z[2][2] factorZ;return Z;
}Matrix rotation_x(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[1][1] R[2][2] cosangle;R[1][2] -sinangle;R[2][1] sinangle;return R;
}Matrix rotation_y(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[2][2] cosangle;R[0][2] sinangle;R[2][0] -sinangle;return R;
}Matrix rotation_z(float angle) {angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[1][1] cosangle;R[0][1] -sinangle;R[1][0] sinangle;return R;
}int main(int argc, char** argv)
{const PNGColor white PNGColor(255, 255, 255, 255);const PNGColor black PNGColor(0, 0, 0, 255);const PNGColor red PNGColor(255, 0, 0, 255);const PNGColor green PNGColor(0, 255, 0, 255);const PNGColor blue PNGColor(0, 0, 255, 255);const PNGColor yellow PNGColor(255, 255, 0, 255);Model *model NULL;const int width 800;const int height 800;const int depth 255;//generate some imagePNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) in.size() in encodeimage.init(black);model new Model(cube.obj);Vec3f eye(0, 0, 4);Vec3f center(0, 0, 0);Matrix ModelView Matrix::identity(4);Matrix Projection projection(eye, center);Matrix ViewPort viewport(width / 4, width / 4, width / 2, height / 2, depth);for (int i 0; i model-nfaces(); i){std::vectorint face model-face(i);for (int j 0; j (int)face.size(); j){Vec3f wp0 model-vert(face[j]);Vec3f wp1 model-vert(face[(j 1) % face.size()]);Matrix S0 scale(0.4, 0.4, 0.4);Vec3f swp0 S0 * wp0;Vec3f swp1 S0 * wp1;// Please add the code here/********** Begin ********/float tx[3] { -1.2, 0, 1.2 };for (int i 0; i 3; i){ModelView translation(Vec3f(tx[i], 1.2, 0)) * rotation_y(45);Vec3f op0 ViewPort * Projection * ModelView * swp0;Vec3f op1 ViewPort * Projection * ModelView * swp1;line(op0, op1, image, red);}// 改变视点与模型位置产生两点透视 // 先模型变换再视点变换Vec3f eye1 rotation_y(-45) * eye;for (int j 0; j 3; j){Matrix ModelView1 lookat(eye1, center, Vec3f(0, 1, 0)) * translation(Vec3f(tx[j], 0, 0));Vec3f vp0 ViewPort * Projection * ModelView1 * swp0;Vec3f vp1 ViewPort * Projection * ModelView1 *swp1;line(vp0, vp1, image, green);}// 改变视点与模型位置产生两点透视 // 先视点变换再模型变换for (int k 0; k 3; k){ Matrix ModelView1 translation(Vec3f(tx[k], -1.2, 0)) * lookat(eye1, center, Vec3f(0, 1, 0));Vec3f vp0 ViewPort * Projection * ModelView1 * swp0;Vec3f vp1 ViewPort * Projection * ModelView1 *swp1;line(vp0, vp1, image, yellow);} /********** End ********/}}image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file(../img_step2/test.png);delete model;return 0;
} 第3关三视图与正等测投影 一. 任务描述 1. 本关任务 (1) 理解投影变换的方法; (2) 将main函数中的空白部分补充完整。 2. 输入 (1) 代码将自动输入一个边长为1的obj正方体模型具体模型如下图 (2) 代码自动将模型投影到二维平面经过模型变换生成一个长宽高不等的立方体 (3) 将立方体沿Z轴向XOY平面正投影并绘制出一个白色矩形 (4) 将立方体沿Y轴向XOZ平面正投影然后沿X轴逆时针旋转90度最后沿着Y轴负方向平移1.2个单位长度绘制一个红色矩形 (5) 将立方体沿X轴向YOZ平面正投影然后沿Y轴顺时针旋转90度最后沿着X轴负方向平移1.2个单位长度绘制一个绿色矩形 (6) 绘制正等测投影图将立方体沿Z轴逆时针旋转45度再沿X轴逆时针旋转35.25度然后沿Z轴向XOY平面正投影。最后沿着Y轴正方向平移1.2个单位长度绘制一个黄色立方体 3. 输出 具体结果如下图所示 #include vector
#include cmath
#include algorithm
#include iostream
#include model.h
#include geometry.h
#include pngimage.husing namespace std;
const double PI acos(-1.0);void line(Vec3i p0, Vec3i p1, PNGImage image, PNGColor color)
{bool steep false;if (std::abs(p0.x - p1.x) std::abs(p0.y - p1.y)){std::swap(p0.x, p0.y);std::swap(p1.x, p1.y);steep true;}if (p0.x p1.x){std::swap(p0.x, p1.x);std::swap(p0.y, p1.y);}int dx p1.x - p0.x;int dy std::abs(p1.y - p0.y);int y p0.y;int d -dx;for (int x p0.x; x p1.x; x){if (steep)image.set(y, x, color);elseimage.set(x, y, color);d d 2 * dy;if (d 0){y (p1.y p0.y ? 1 : -1);d d - 2 * dx;}}
}Matrix projection(Vec3f eye, Vec3f center)
{Matrix m Matrix::identity(4);m[3][2] -1.f / (eye - center).norm();return m;
}Matrix viewport(int x, int y, int w, int h, int depth) {Matrix m Matrix::identity(4);m[0][3] x w / 2.f;m[1][3] y h / 2.f;m[2][3] depth / 2.f;m[0][0] w / 2.f;m[1][1] h / 2.f;m[2][2] depth / 2.f;return m;
}Matrix lookat(Vec3f eye, Vec3f center, Vec3f up) {Vec3f z (eye - center).normalize();Vec3f x (up^z).normalize();Vec3f y (z^x).normalize();Matrix res Matrix::identity(4);for (int i 0; i 3; i) {res[0][i] x[i];res[1][i] y[i];res[2][i] z[i];res[i][3] -center[i];}return res;
}Matrix translation(Vec3f v) {Matrix Tr Matrix::identity(4);Tr[0][3] v.x;Tr[1][3] v.y;Tr[2][3] v.z;return Tr;
}Matrix scale(float factorX, float factorY, float factorZ)
{Matrix Z Matrix::identity(4);Z[0][0] factorX;Z[1][1] factorY;Z[2][2] factorZ;return Z;
}Matrix rotation_x(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[1][1] R[2][2] cosangle;R[1][2] -sinangle;R[2][1] sinangle;return R;
}Matrix rotation_y(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[2][2] cosangle;R[0][2] sinangle;R[2][0] -sinangle;return R;
}Matrix rotation_z(float angle) {angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[1][1] cosangle;R[0][1] -sinangle;R[1][0] sinangle;return R;
}int main(int argc, char** argv)
{const PNGColor white PNGColor(255, 255, 255, 255);const PNGColor black PNGColor(0, 0, 0, 255);const PNGColor red PNGColor(255, 0, 0, 255);const PNGColor green PNGColor(0, 255, 0, 255);const PNGColor blue PNGColor(0, 0, 255, 255);const PNGColor yellow PNGColor(255, 255, 0, 255);Model *model NULL;const int width 800;const int height 800;const int depth 255;//generate some imagePNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) in.size() in encodeimage.init(black);model new Model(cube.obj);Matrix ViewPort viewport(width / 4, width / 4, width / 2, height / 2, depth);for (int i 0; i model-nfaces(); i){std::vectorint face model-face(i);for (int j 0; j (int)face.size(); j){Vec3f wp0 model-vert(face[j]);Vec3f wp1 model-vert(face[(j 1) % face.size()]);Matrix S0 scale(0.5, 0.4, 0.3);Vec3f swp0 S0 * wp0;Vec3f swp1 S0 * wp1;/********** Begin ********/Matrix ProjectionX Matrix::identity(4);ProjectionX[0][0] 0.0f;Matrix ProjectionY Matrix::identity(4);ProjectionY[1][1] 0.0f;Matrix ProjectionZ Matrix::identity(4);ProjectionZ[2][2] 0.0f;//沿Z轴向XOY平面投影 Vec3f zp0 ViewPort * ProjectionZ * swp0;Vec3f zp1 ViewPort * ProjectionZ * swp1;line(zp0, zp1, image, white);//沿Y轴向XOZ平面投影再旋转与平移Matrix rx rotation_x(90);Matrix ty translation(Vec3f(0, -1.2f, 0));Vec3f yp0 ViewPort * ty * rx * ProjectionY * swp0;Vec3f yp1 ViewPort * ty * rx * ProjectionY * swp1;line(yp0, yp1, image, red);//沿X轴向YOZ平面投影再旋转与平移Matrix ry rotation_y(-90);Matrix tx translation(Vec3f(-1.2f, 0, 0));Vec3f xp0 ViewPort * tx * ry * ProjectionX * swp0;Vec3f xp1 ViewPort * tx * ry * ProjectionX * swp1;line(xp0, xp1, image, green);//正等测投影图Matrix rz rotation_z(45);Matrix rx1 rotation_x(35.25);Matrix ty1 translation(Vec3f(0, 1.2f, 0));Vec3f rp0 ViewPort * ty1 * ProjectionZ * rx1 * rz *swp0;Vec3f rp1 ViewPort * ty1 * ProjectionZ * rx1 * rz *swp1;line(rp0, rp1, image, yellow);/********** end ********/}}image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file(../img_step3/test.png);delete model;return 0;
} 第4关视口变换与三视图 一. 任务描述 1. 本关任务 (1) 理解投影变换的方法; (2) 将main函数中的空白部分补充完整。 2. 输入 (1) 代码将自动输入一个边长为1的obj正方体模型具体模型如下图 (2) 代码自动将模型投影到二维平面经过模型变换生成一个长宽高不等的立方体并将显示窗口一分为四分为四个视口每个视口大小均为原窗口大小的一半。红绿两线为四个视口的分隔线 (3) 在第一视口ViewPort中首先将立方体沿Z轴向XOY平面投影。然后进行视口变换ViewPort并绘制出一个白色矩形 (4) 在第二视口ViewPort1中首先将立方体沿X轴向YOZ平面投影。然后沿Y轴顺时针旋转90度最后进行视口变换ViewPort1绘制一个绿色矩形 (5) 在第三视口ViewPort2中首先将立方体沿Y轴向XOZ平面投影。然后沿X轴逆时针旋转90度最后进行视口变换ViewPort2绘制一个红矩形 (6) 在第四视口ViewPort3中首先将立方体沿Y轴顺时针旋转45度然后进行投影变换投影变换参数eye和center已给出。最后进行视口变换ViewPort3绘制一个黄色立方体。 3. 输出 具体结果如下图所示 #include vector
#include cmath
#include algorithm
#include iostream
#include model.h
#include geometry.h
#include pngimage.h
using namespace std;
const double PI acos(-1.0);
void line(Vec3i p0, Vec3i p1, PNGImage image, PNGColor color)
{bool steep false;if (std::abs(p0.x - p1.x) std::abs(p0.y - p1.y)){std::swap(p0.x, p0.y);std::swap(p1.x, p1.y);steep true;}if (p0.x p1.x){std::swap(p0.x, p1.x);std::swap(p0.y, p1.y);}int dx p1.x - p0.x;int dy std::abs(p1.y - p0.y);int y p0.y;int d -dx;for (int x p0.x; x p1.x; x){if (steep)image.set(y, x, color);elseimage.set(x, y, color);d d 2 * dy;if (d 0){y (p1.y p0.y ? 1 : -1);d d - 2 * dx;}}
}
Matrix projection(Vec3f eye, Vec3f center)
{Matrix m Matrix::identity(4);m[3][2] -1.f / (eye - center).norm();return m;
}
Matrix viewport(int x, int y, int w, int h, int depth) {Matrix m Matrix::identity(4);m[0][3] x w / 2.f;m[1][3] y h / 2.f;m[2][3] depth / 2.f;m[0][0] w / 2.f;m[1][1] h / 2.f;m[2][2] depth / 2.f;return m;
}
Matrix lookat(Vec3f eye, Vec3f center, Vec3f up) {Vec3f z (eye - center).normalize();Vec3f x (up^z).normalize();Vec3f y (z^x).normalize();Matrix res Matrix::identity(4);for (int i 0; i 3; i) {res[0][i] x[i];res[1][i] y[i];res[2][i] z[i];res[i][3] -center[i];}return res;
}
Matrix translation(Vec3f v) {Matrix Tr Matrix::identity(4);Tr[0][3] v.x;Tr[1][3] v.y;Tr[2][3] v.z;return Tr;
}
Matrix scale(float factorX, float factorY, float factorZ)
{Matrix Z Matrix::identity(4);Z[0][0] factorX;Z[1][1] factorY;Z[2][2] factorZ;return Z;
}
Matrix rotation_x(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[1][1] R[2][2] cosangle;R[1][2] -sinangle;R[2][1] sinangle;return R;
}
Matrix rotation_y(float angle)
{angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[2][2] cosangle;R[0][2] sinangle;R[2][0] -sinangle;return R;
}
Matrix rotation_z(float angle) {angle angle * PI / 180;float sinangle sin(angle);float cosangle cos(angle);Matrix R Matrix::identity(4);R[0][0] R[1][1] cosangle;R[0][1] -sinangle;R[1][0] sinangle;return R;
}
int main(int argc, char** argv)
{const PNGColor white PNGColor(255, 255, 255, 255);const PNGColor black PNGColor(0, 0, 0, 255);const PNGColor red PNGColor(255, 0, 0, 255);const PNGColor green PNGColor(0, 255, 0, 255);const PNGColor blue PNGColor(0, 0, 255, 255);const PNGColor yellow PNGColor(255, 255, 0, 255);Model *model NULL;const int width 800;const int height 800;const int depth 255;//generate some imagePNGImage image(width, height, PNGImage::RGBA); //Error when RGB because lodepng_get_raw_size_lct(w, h, colortype, bitdepth) in.size() in encodeimage.init(black);model new Model(cube.obj);Vec3f eye(0, 0, 4);Vec3f center(0, 0, 0);Matrix ProjectionX Matrix::identity(4);ProjectionX[0][0] 0.0f;Matrix ProjectionY Matrix::identity(4);ProjectionY[1][1] 0.0f;Matrix ProjectionZ Matrix::identity(4);ProjectionZ[2][2] 0.0f;Matrix ViewPort viewport(0, height / 2, width / 2, height / 2, depth);Matrix ViewPort1 viewport(width / 2, height / 2, width / 2, height / 2, depth);Matrix ViewPort2 viewport(0, 0, width / 2, height / 2, depth);Matrix ViewPort3 viewport(width / 2, 0, width / 2, height / 2, depth);// 绘制视口分隔线Vec3f x1(0.f, height / 2, 0.f), x2(width, height / 2, 0.f);Vec3f y1(width / 2, 0.f, 0.f), y2(width / 2, height, 0.f);line(x1, x2, image, red);line(y1, y2, image, green);for (int i 0; i model-nfaces(); i){std::vectorint face model-face(i);for (int j 0; j (int)face.size(); j){Vec3f wp0 model-vert(face[j]);Vec3f wp1 model-vert(face[(j 1) % face.size()]);Matrix S0 scale(0.5, 0.4, 0.3);Vec3f swp0 S0 * wp0;Vec3f swp1 S0 * wp1;// Please add the code here/********** Begin ********///沿Z轴向XOY平面投影 Vec3f zp0 ViewPort * ProjectionZ * swp0;Vec3f zp1 ViewPort * ProjectionZ * swp1;line(zp0, zp1, image, white);//沿X轴向YOZ平面投影再旋转与平移Matrix ry rotation_y(-90);Vec3f xp0 ViewPort1 * ry * ProjectionX * swp0;Vec3f xp1 ViewPort1 * ry * ProjectionX * swp1;line(xp0, xp1, image, green);//沿Y轴向XOZ平面投影再旋转与平移Matrix rx rotation_x(90);Vec3f yp0 ViewPort2 * rx * ProjectionY * swp0;Vec3f yp1 ViewPort2 * rx * ProjectionY * swp1;line(yp0, yp1, image, red);//两点透视图Matrix ModelView rotation_y(-45);Matrix Projection projection(eye, center); Vec3f vp0 ViewPort3 * Projection * ModelView * swp0;Vec3f vp1 ViewPort3 * Projection * ModelView * swp1;line(vp0, vp1, image, yellow);/************End**********/}}image.flip_vertically(); // i want to have the origin at the left bottom corner of the imageimage.write_png_file(../img_step4/test.png);delete model;return 0;
}