第1关:画圆
1 任务描述
根据以下要求修改右侧的代码,绘制预期的输出图像。系统将测试您编写的代码。
1.1 任务要求
- 熟悉编程环境;
- 了解光栅图形显示的特点;
- 以OpenGL为开发平台设计程序,理解并掌握圆的对称性和“中点法”,以便能够画出一个圆。
1.2 预期输出
1.3 具体要求
- 背景颜色为黑色(0.0,0.0,0.0,0.0),并以“glclearColor”完成;
- 编写一个算法来生成圆周上八个对称点的坐标;
- 使用“中点法”生成一个圆,点的大小设置为2,颜色设置为(0.0f,1.0f,1.0f);
- 圆心两个端点的坐标为(200,200),半径为150。
2 相关知识
要完成此任务,您需要了解圆的对称性和“中点法”,以便能够绘制圆。
2.1 生成圆周上八个对称点的坐标
根据圆的对称性。如果我们生成一个点(x,y)的坐标,我们将得到八个点的坐标。
开始你的编程之旅。
3 实验代码:
#include <GL/freeglut.h>
#include<stdio.h>
// The header file used to evaluate the code - begin
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
// The header file used to evaluate the code - end
//Eight points of symmetry are formed on the circumference of the circle
void CirclePoints(int x0, int y0, int x, int y)
{
// 添加代码区域
/********** Begin ********/
glBegin(GL_POINTS);//绘制点
glVertex2i(x0+x,y0+y);//八个对称点坐标
glVertex2i(x0+x,y0-y);
glVertex2i(x0-x,y0+y);
glVertex2i(x0-x,y0-y);
glVertex2i(x0+y,y0+x);
glVertex2i(x0+y,y0-x);
glVertex2i(x0-y,y0+x);
glVertex2i(x0-y,y0-x);
glEnd();//结束
/********** End **********/
}
void MidPoint_Circle(int x0, int y0, int r)
{
// 添加代码区域
/********** Begin ********/
int x=0,y=r,d=1-r;
glBegin(GL_POINTS);//绘制点
while(x<=y)
{
glVertex2i(x0+x,y0+y);//八个对称点坐标
glVertex2i(x0+x,y0-y);
glVertex2i(x0-x,y0+y);
glVertex2i(x0-x,y0-y);
glVertex2i(x0+y,y0+x);
glVertex2i(x0+y,y0-x);
glVertex2i(x0-y,y0+x);
glVertex2i(x0-y,y0-x);
if(d<0)
{
d=d+2*x+3;
x=x+1;
}
else
{
d=d+2*(x-y)+5;
x++;
y--;
}
}
glEnd();//结束
/********** End **********/
}
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
// Please add your code here
/********** Begin ********/
//修改参数区域
glPointSize(2.0);//点的大小
glColor3f(0.0, 1.0, 1.0);//颜色设置,青色
MidPoint_Circle(200 ,200 ,150 );//圆心两个端点的坐标,半径
/********** 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 circle!");
Init();
glutDisplayFunc(myDisplay);
glutReshapeFunc(myReshape);
glutMainLoopEvent();
//The following is the evaluation code, which has nothing to do with the content of this experiment. Please do not modify it//
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::vector<cv::Mat> imgPlanes;
img.create(400, 400, CV_8UC3);
cv::split(img, imgPlanes);
for (int i = 0; i < 400; i++) {
unsigned char* plane0Ptr = imgPlanes[0].ptr<unsigned char>(i);
unsigned char* plane1Ptr = imgPlanes[1].ptr<unsigned char>(i);
unsigned char* plane2Ptr = imgPlanes[2].ptr<unsigned 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;
}