圖形學的第一個實驗,
因為老師課上的講解原因,是以這裡将一個邊長為1的正方形塊作為一個像素,放大後可以看出來。
先上代碼,畫線的:
void drawLine(node * mnode)
{
glClearColor(0.0f, 0.0f, 0.0f,0.0f);//繪圖顔色為黑色
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
//glViewport(0, 0, 400, 400);
for (int i = 0; i < 400; i++)
{
glVertex2i(i, 0);
glVertex2i(i, 400);
}
for (int i = 0; i < 400; i++)
{
glVertex2i(0, i);
glVertex2i(400,i);
}
glEnd();
//glClear(GL_COLOR_BUFFER_BIT); //清空顔色緩沖池
glColor3f(1.0, 0.0, 0.0);
//glBegin(GL_POINTS);
//glViewport(0, 0, 400, 400);
int x, y, dx, dy, e;
int x1 = mnode[0].x, y1 = mnode[0].y, x2 = mnode[1].x, y2 =mnode[1].y;
dx = x2 - x1;
dy = y2 - y1;
e = -dx;
x = x1;
y = y1;
for (int i = 0; i <= dx; i++)
{
//glVertex2i(x, y);
glRectf(x,y, x+1, y+1); //繪制矩形
x++;
e = e + 2 * dy;
if (e >= 0)
{
y++;
e = e - 2 * dx;
}
}
//glEnd();
glFlush();
}
放大後的圖像
然後是畫圓的代碼:
void drawCircle()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//繪圖顔色為黑色
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
//glBegin(GL_POINTS);
glBegin(GL_LINES);
glViewport(0, 0, 400, 400);
for (int i = 0; i < 400; i++)
{
glVertex2i(i, 0);
glVertex2i(i, 400);
}
for (int i = 0; i < 400; i++)
{
glVertex2i(0, i);
glVertex2i(400, i);
}
glEnd();
//glViewport(0, 0, 400, 400);
glColor3f(1.0, 0.0, 0.0);
int x, y;
float d;
int r = 100;
x = 0, y = r;
d = 1.25 - r;
//glVertex2i(x+r,y+r);
//glVertex2i(y+r, x+r);
//glVertex2i(-x+r, y+r);
//glVertex2i(y+r, -x+r);
//glVertex2i(x+r, -y+r);
//glVertex2i(-y+r, x+r);
//glVertex2i(-x+r, -y+r);
//glVertex2i(-y+r, -x+r);
glRectf(x+r, y+r, x +r+1, y+r+1); //繪制矩形
glRectf(y+r, x+r, y+r+ 1, x+r+1); //繪制矩形
glRectf(-x+r, y+r, -x+r+1, y +r+ 1); //繪制矩形
glRectf(y+r, -x+r, y+r+ 1, -x+r+ 1); //繪制矩形
glRectf(x+r, -y+r, x+r+ 1, -y+r+ 1); //繪制矩形
glRectf(-y+r, x+r, -y+r + 1, x+r+ 1); //繪制矩形
glRectf(-x+r, -y+r, -x+r + 1, -y+r + 1); //繪制矩形
glRectf(-y+r, -x+r, -y+r + 1, -x+r + 1); //繪制矩形
while (x <= y)
{
if (d <= 0)
{
d += 2 * x + 3;
}
else
{
d += 2 * (x - y) + 5;
y--;
}
x++;
//cout<< x <<" "<<y<< endl;
/*glVertex2i(x + r, y + r);
glVertex2i(y + r, x + r);
glVertex2i(-x + r, y + r);
glVertex2i(y + r, -x + r);
glVertex2i(x + r, -y + r);
glVertex2i(-y + r, x + r);
glVertex2i(-x + r, -y + r);
glVertex2i(-y + r, -x + r);*/
glRectf(x + r, y + r, x + r + 1, y + r + 1); //繪制矩形
glRectf(y + r, x + r, y + r + 1, x + r + 1); //繪制矩形
glRectf(-x + r, y + r, -x + r + 1, y + r + 1); //繪制矩形
glRectf(y + r, -x + r, y + r + 1, -x + r + 1); //繪制矩形
glRectf(x + r, -y + r, x + r + 1, -y + r + 1); //繪制矩形
glRectf(-y + r, x + r, -y + r + 1, x + r + 1); //繪制矩形
glRectf(-x + r, -y + r, -x + r + 1, -y + r + 1); //繪制矩形
glRectf(-y + r, -x + r, -y + r + 1, -x + r + 1); //繪制矩形
}
//glEnd();
glFlush();
}
放大後的代碼:
實作原理:
過各行各列像素中心構造一組網格線,按直線從起點到終點的順序計算直線與各垂直網格線的交點,然後确定該列像素中與此交點最近的像素。該算法的巧妙之處在于采用增量計算,使得對于每一列,隻要檢查一個誤差項的符号,就可以确定該列的所求的像素。
簡單來說就是如果在中點及以下則取y,中點以上則取y+1。
中點畫圓法:
完整的代碼:
// ConsoleApplication2.cpp: 定義控制台應用程式的入口點。
//
#include "stdafx.h"
#include<gl/GLUT.H>
#include<cmath>
#include<iostream>
#include "node.h"
using namespace std;
node Line[2] = { node(0.0,0.0),node(0.0,0.0) };
int nodeNumber = 0;
bool finish = false;//已經畫完
void Initial(void)//初始化函數
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);//白色背景,前3個是RGB,最後是Alpha值,用來控制透明,1.0表示完全不透明
glMatrixMode(GL_MODELVIEW);//OpenGL按照三維方式來處理圖像,是以需要一個投影變換将三維圖形投影到顯示器的二維空間中
glLoadIdentity();
gluOrtho2D(0.0, 400, 0.0, 400.0);//指定使用正投影将一個x坐标在0~200,y坐标0~150範圍内的矩形坐标區域投影到顯示器視窗
}
void drawLine(node * mnode)
{
glClearColor(0.0f, 0.0f, 0.0f,0.0f);//繪圖顔色為黑色
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
//glViewport(0, 0, 400, 400);
for (int i = 0; i < 400; i++)
{
glVertex2i(i, 0);
glVertex2i(i, 400);
}
for (int i = 0; i < 400; i++)
{
glVertex2i(0, i);
glVertex2i(400,i);
}
glEnd();
//glClear(GL_COLOR_BUFFER_BIT); //清空顔色緩沖池
glColor3f(1.0, 0.0, 0.0);
//glBegin(GL_POINTS);
//glViewport(0, 0, 400, 400);
int x, y, dx, dy, e;
int x1 = mnode[0].x, y1 = mnode[0].y, x2 = mnode[1].x, y2 =mnode[1].y;
dx = x2 - x1;
dy = y2 - y1;
e = -dx;
x = x1;
y = y1;
for (int i = 0; i <= dx; i++)
{
//glVertex2i(x, y);
glRectf(x,y, x+1, y+1); //繪制矩形
x++;
e = e + 2 * dy;
if (e >= 0)
{
y++;
e = e - 2 * dx;
}
}
//glEnd();
glFlush();
}
void drawLine1()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//繪圖顔色為黑色
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
//glViewport(0, 0, 400, 400);
for (int i = 0; i < 400; i++)
{
glVertex2i(i, 0);
glVertex2i(i, 400);
}
for (int i = 0; i < 400; i++)
{
glVertex2i(0, i);
glVertex2i(400, i);
}
glEnd();
//glClear(GL_COLOR_BUFFER_BIT); //清空顔色緩沖池
glColor3f(1.0, 0.0, 0.0);
//glBegin(GL_POINTS);
//glViewport(0, 0, 400, 400);
int x, y, dx, dy, e;
int x1 = 0, y1 = 8, x2 = 50, y2 = 100;
dx = x2 - x1;
dy = y2 - y1;
e = -dx;
x = x1;
y = y1;
for (int i = 0; i <= dx; i++)
{
//glVertex2i(x, y);
glRectf(x, y, x + 1, y + 1); //繪制矩形
x++;
e = e + 2 * dy;
if (e >= 0)
{
y++;
e = e - 2 * dx;
}
}
//glEnd();
glFlush();
}
void drawLine()
{
if (finish)
{
drawLine(&Line[0]);
finish = false;
}
}
void drawCircle()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//繪圖顔色為黑色
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
//glBegin(GL_POINTS);
glBegin(GL_LINES);
glViewport(0, 0, 400, 400);
for (int i = 0; i < 400; i++)
{
glVertex2i(i, 0);
glVertex2i(i, 400);
}
for (int i = 0; i < 400; i++)
{
glVertex2i(0, i);
glVertex2i(400, i);
}
glEnd();
//glViewport(0, 0, 400, 400);
glColor3f(1.0, 0.0, 0.0);
int x, y;
float d;
int r = 100;
x = 0, y = r;
d = 1.25 - r;
//glVertex2i(x+r,y+r);
//glVertex2i(y+r, x+r);
//glVertex2i(-x+r, y+r);
//glVertex2i(y+r, -x+r);
//glVertex2i(x+r, -y+r);
//glVertex2i(-y+r, x+r);
//glVertex2i(-x+r, -y+r);
//glVertex2i(-y+r, -x+r);
glRectf(x+r, y+r, x +r+1, y+r+1); //繪制矩形
glRectf(y+r, x+r, y+r+ 1, x+r+1); //繪制矩形
glRectf(-x+r, y+r, -x+r+1, y +r+ 1); //繪制矩形
glRectf(y+r, -x+r, y+r+ 1, -x+r+ 1); //繪制矩形
glRectf(x+r, -y+r, x+r+ 1, -y+r+ 1); //繪制矩形
glRectf(-y+r, x+r, -y+r + 1, x+r+ 1); //繪制矩形
glRectf(-x+r, -y+r, -x+r + 1, -y+r + 1); //繪制矩形
glRectf(-y+r, -x+r, -y+r + 1, -x+r + 1); //繪制矩形
while (x <= y)
{
if (d <= 0)
{
d += 2 * x + 3;
}
else
{
d += 2 * (x - y) + 5;
y--;
}
x++;
//cout<< x <<" "<<y<< endl;
/*glVertex2i(x + r, y + r);
glVertex2i(y + r, x + r);
glVertex2i(-x + r, y + r);
glVertex2i(y + r, -x + r);
glVertex2i(x + r, -y + r);
glVertex2i(-y + r, x + r);
glVertex2i(-x + r, -y + r);
glVertex2i(-y + r, -x + r);*/
glRectf(x + r, y + r, x + r + 1, y + r + 1); //繪制矩形
glRectf(y + r, x + r, y + r + 1, x + r + 1); //繪制矩形
glRectf(-x + r, y + r, -x + r + 1, y + r + 1); //繪制矩形
glRectf(y + r, -x + r, y + r + 1, -x + r + 1); //繪制矩形
glRectf(x + r, -y + r, x + r + 1, -y + r + 1); //繪制矩形
glRectf(-y + r, x + r, -y + r + 1, x + r + 1); //繪制矩形
glRectf(-x + r, -y + r, -x + r + 1, -y + r + 1); //繪制矩形
glRectf(-y + r, -x + r, -y + r + 1, -x + r + 1); //繪制矩形
}
//glEnd();
glFlush();
}
void mouseClick(int btn, int state, int x, int y)
{
if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)//點選左鍵
{
y = 400 - y;
node temp(x, y);
if (nodeNumber<2)
{
Line[nodeNumber] = temp;
nodeNumber++;
glColor3f(1.0, 0.0, 0.0);
// glViewport(0, 0, 400, 400);
glBegin(GL_POINTS);
glVertex2d(x, y);
glEnd();
glFlush();
}
}
if (btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)//點選右鍵
{
//drawLine(&Line[0]);
finish = true;
nodeNumber = 0;
}
}
int main(int argc, char * argv[])//這是使用glut庫函數進行視窗管理
{
glutInit(&argc, argv);//使用glut庫需要進行初始化
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);//設定視窗顯示模式,顔色模型和緩存,這裡是RGB顔色模型和單緩存
glutInitWindowPosition(100, 100);//設定視窗的初始位置,螢幕左上角為原點,機關為像素
glutInitWindowSize(400, 400);//設定視窗的大小
glutCreateWindow("直線");//建立一個視窗,參數是視窗标題名
Initial();
glutDisplayFunc(&drawLine1);//将myDisplay指定為目前視窗的顯示内容函數*/
//glutMouseFunc(mouseClick);
glutCreateWindow("圓");//建立一個視窗,參數是視窗标題名
Initial();
glutDisplayFunc(&drawCircle);//将myDisplay指定為目前視窗的顯示内容函數
glutMainLoop();//使視窗架構運作起來,使顯示回調函數開始工作
return 0;
}
還有一個頭檔案:
#pragma once
#pragma once
struct node//點結構
{
double x;
double y;
node()
{
x = 0.0;
y = 0.0;
}
~node() {}
node(double xx, double yy)
{
x = xx;
y = yy;
}
/*node & operator=(const node& a)
{
node m;
m.x = a.x;
m.y = a.y;
return m;
}*/
};
struct side//邊結構
{
node a;
node b;
side(node aa, node bb)
{
a.x = aa.x;
a.y = aa.y;
b.y = bb.y;
b.x = bb.x;
}
side(int n)
{
a.x = 0;
a.y = 0;
b.x = 0;
b.y = 0;
}
side()
{
a.x = 0;
a.y = 0;
b.x = 0;
b.y = 0;
}
};