Computer Graphics - code_1

/*------------------------------------
author:XD_G
location:SWUN
time:09/2015~01/2016
course:Computer Graphics
teacher:Tianyun Huang
------------------------------------*/

#include <iostream>
#include <vector>
#include <GL/glut.h>

#pragma comment( lib , "opengl32.lib")
#pragma comment( lib , "glu32.lib" )
#pragma comment( lib , "glut32.lib" )

#define x_min View_leftbottom.x
#define x_max View_righttop.x
#define y_min View_leftbottom.y
#define y_max View_righttop.y

using namespace std;

//point struct
class Point {
public:
	int x;
	int y;
	unsigned char loc;
	Point() :x(0), y(0), loc(0) {}
	Point(int  a, int  b) :x(a), y(b), loc(0) {}
	Point(int  a, int  b, unsigned char c) :x(a), y(b), loc(c) {}
	Point(const Point& src): x(src.x),y(src.y),loc(src.loc) {}
	Point& operator=(const Point &src) {
		if (this != &src) {
			this->x = src.x;
			this->y = src.y;
			this->loc = src.loc;
		}
		return *this;
	}
};

enum Wnd{LEFT, RIGHT, BOTTOM, TOP};

//windows_size
int L_w = 1366 / 2;
int L_h = 768 / 2;

//view_windows
Point View_leftbottom(-L_w, -L_h);
Point View_righttop(L_w, L_h);

//lines_set
vector<Point >  line_points_set;
vector<Point >  new_line_points_set;

//polygon_polygon_points_set
vector<Point >  polygon_points_set;

//color table
GLfloat black_color[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat red_color[] = { 1.0,0.0,0.0,1.0 };
GLfloat green_color[] = { 0.0, 1.0, 0.0, 1.0 };
GLfloat blue_color[] = { 0.0, 0.0, 1.0, 1.0 };
GLfloat white_color[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat grey_color[] = { 0.5, 0.5, 0.5, 1.0 };

//clip area_code
const unsigned char winLeftBitCode = 0x1;// 0001
const unsigned char winRightBitCode = 0x2;// 0010
const unsigned char winBottomBitCode = 0x4;// 0100
const unsigned char winTopBitCode = 0x8;// 1000

  

//Functions

//Init & Set func
inline void setPixel(int x, int y, GLfloat* c){
	glColor4fv(c);
	glBegin(GL_POINTS);
	glVertex2i(x, y);
	glEnd();
}

//将所求直线变换到斜率0~1之间
inline void translate(int &x0, int &y0, int &x1, int &y1, float k) {
	if (k > 1) {
		int temp = x0;
		x0 = y0;
		y0 = temp;
		temp = x1;
		x1 = y1;
		y1 = temp;
		if (x0 > x1) {
			temp = x0;
			x0 = x1;
			x1 = temp;
			temp = y0;
			y0 = y1;
			y1 = temp;
		}
	}
	else if (k >= -1 && k < 0) {
		y0 = -y0;
		y1 = -y1;
		if (x0 > x1) {
			int temp = x0;
			x0 = x1;
			x1 = temp;
			temp = y0;
			y0 = y1;
			y1 = temp;
		}
	}
	else if (k < -1) {
		int temp = x0;
		x0 = y0;
		y0 = -temp;
		temp = x1;
		x1 = y1;
		y1 = -temp;
		if (x0 > x1) {
			temp = x0;
			x0 = x1;
			x1 = temp;
			temp = y0;
			y0 = y1;
			y1 = temp;
		}
	}
	else {
		if (x0 > x1) {
			int temp = x0;
			x0 = x1;
			x1 = temp;
			temp = y0;
			y0 = y1;
			y1 = temp;
		}
	}
}

//对称作直线时将生成直线逆向还原到所求
inline void set_line_pixel(int x, int y, float k, GLfloat* color) {
	if (k > 0 && k <= 1)
		setPixel(x, y, color);
	if (k > 1)
		setPixel(y, x, color);
	if (k >= -1 && k < 0)
		setPixel(x, -y, color);
	if (k < -1)
		setPixel(-y, x, color);
}

//从八分圆对称做出完整圆
inline void circlePoint(int x, int y, GLfloat* color){
	setPixel(x, y, color);
	setPixel(y, x, color);
	setPixel(-x, y, color);
	setPixel(y, -x, color);
	setPixel(x, -y, color);
	setPixel(-y, x, color);
	setPixel(-x, -y, color);
	setPixel(-y, -x, color);
}

//设置多边形顶点集合
void polygon_points() {
	Point A(-290, 150);
	Point B(-30, 80);
	Point C(210, 260);
	Point D(250, -55);
	Point E(30, -245);
	Point F(10, -230);
	polygon_points_set.push_back(A);
	polygon_points_set.push_back(B);
	polygon_points_set.push_back(C);
	polygon_points_set.push_back(D);
	polygon_points_set.push_back(E);
	polygon_points_set.push_back(F);
}

//设置线段端点集合
void line_points() {
	Point A(-290, 50);	Point B(10, -130);
	Point C(70, 15);	Point D(-45, -255);
	Point E(30, 210);	Point F(26, -280);
	Point G(30, 15);	Point H(180, 80);
	Point I(50, -250);	Point J(50, 250);
	Point K(-250, 50);	Point L(250, 50);
	line_points_set.push_back(A);
	line_points_set.push_back(B);
	line_points_set.push_back(C);
	line_points_set.push_back(D);
	line_points_set.push_back(E);
	line_points_set.push_back(F);
	line_points_set.push_back(G);
	line_points_set.push_back(H);
	line_points_set.push_back(I);
	line_points_set.push_back(J);
	line_points_set.push_back(K);
	line_points_set.push_back(L);
}

//作直线
inline void GL_Line(int x0, int y0, int x1, int y1, GLfloat* color, int width = 1) {
	glColor4fv(color);
	glLineWidth(width);
	glBegin(GL_LINES);
	glVertex3f(x0, y0, 0.0f);
	glVertex3f(x1, y1, 0.0f);
	glEnd();
}

//作直线
inline void GL_Line(Point p1, Point p2, GLfloat* color, int width = 1) {
	glColor4fv(color);
	glLineWidth(width);
	glBegin(GL_LINES);
	glVertex3f(p1.x, p1.y, 0.0f);
	glVertex3f(p2.x, p2.y, 0.0f);
	glEnd();
}

//设置观察窗口大小
inline void set_ViewWindows(int xmin, int xmax, int ymin, int ymax) {
	x_min = xmin; x_max = xmax; y_min = ymin; y_max = ymax;
	GL_Line(x_min, y_min, x_min, y_max, grey_color);
	GL_Line(x_min, y_min, x_max, y_min, grey_color);
	GL_Line(x_max, y_min, x_max, y_max, grey_color);
	GL_Line(x_min, y_max, x_max, y_max, grey_color);
}

  

//Algorithms func

//DDA直线算法
void DDALine(int x0, int y0, int x1, int y1, GLfloat* color){
	int i;
	float dx, dy, length, x, y;
	if (fabs(x1*1.0 - x0) >= fabs(y1*1.0 - y0))
		length = fabs(x1*1.0 - x0);
	else
		length = fabs(y1*1.0 - y0);
	dx = (x1 - x0) / length;
	dy = (y1 - y0) / length;
	i = 1;
	x = x0;
	y = y0;
	while (i < length){
		setPixel(int(x + 0.5), int(y + 0.5), color);
		x = x + dx;
		y = y + dy;
		i++;
	}

}

//Bresenham直线算法(全斜率_对称)
void Bresenham_Line(int x0, int y0, int x1, int y1, GLfloat* color){
	float k = (y1 - y0) * 1.00 / (x1 - x0) * 1.00;
	translate(x0, y0, x1, y1, k);
	int dx, dy, e, i, x, y;
	dx = x1 - x0, dy = y1 - y0, e = 2 * dy - dx;
	x = x0, y = y0;
	for (i = 0; i <= dx; i++){
		set_line_pixel(x, y, k, color);
		x++;
		if (e >= 0){
			y++;
			e = e + 2 * dy - 2 * dx;
		}
		else{
			e = e + 2 * dy;
		}
	}
}

//中点画椭圆
void MidpointEllipse(int xc, int yc, int a, int b, GLfloat* color){
	long aa = a*a, bb = b*b;
	long twoaa = 2 * aa, twobb = 2 * bb;
	long x = 0, y = b;
	long long d;
	long dx = 0;
	long dy = twoaa * y;
	d = long(bb + aa*(-b + 0.25) + 0.5);
	setPixel(xc + x, yc + y, color);
	setPixel(xc + x, yc - y, color);
	setPixel(xc - x, yc + y, color);
	setPixel(xc - x, yc - y, color);
	while (dx < dy){
		x++;
		dx += twobb;
		if (d < 0)
			d += bb + dx;
		else{
			dy -= twoaa;
			d += bb + dx - dy;
			y--;
		}
		setPixel(xc + x, yc + y, color);
		setPixel(xc + x, yc - y, color);
		setPixel(xc - x, yc + y, color);
		setPixel(xc - x, yc - y, color);
	}
	d =long long( bb*(x + 0.5)*(x + 0.5) + aa*(y - 1)*(y - 1) - aa*bb + 0.5);
	cout << "X:" << x << endl;
	cout << "1:" << long long (bb*(x + 0.5)*(x + 0.5)) << endl;
	cout << "2:" << aa*(y - 1)*(y - 1) << endl;
	cout << "3:" << aa*bb << endl;
	cout << "D:" << d << endl;
	while (y > 0){
		y--;
		dy -= twoaa;
		if (d > 0)
			d += aa - dy;
		else{
			x++;
			dx += twobb;
			d += aa - dy + dx;
		}
		setPixel(xc + x, yc + y, color);
		setPixel(xc + x, yc - y, color);
		setPixel(xc - x, yc + y, color);
		setPixel(xc - x, yc - y, color);
	}
}

//中点画圆
void MidPointCircle(int r, GLfloat* color){
	int x, y;
	int e;
	x = 0;
	y = r;
	e = 1 - r;
	circlePoint(x, y, color);
	while (x <= y){
		x++;
		if (e < 0){
			e += 2 * x + 1;
		}
		else{
			y--;
			e += 2 * (x - y) + 1;
		}
		circlePoint(x, y, color);
	}
}

//中点画抛物线
//mode1:y=a*x^2+bx+c
//mode2:x=a*y^2+by+c
void MidPointParabola(float a, float b, float c, int mode, GLfloat* color) {
	int flag = 1;
	if (a < 0) {
		a = -a;
		b = -b;
		c = -c;
		flag = -1;
	}
	cout << a << endl;
	float px = -b / (2 * a);
	float py = (4 * a*c - b*b) / (4 * a);
	if (a == 0) {
		setPixel(0.0 + px, 0.0 + py, color);
		return;
	}
	float x = 0, y = 0;
	float e = 0;
	if (mode == 1) {
		setPixel(x + px, y + py, color);
		setPixel(-x + px, y + py, color);
	}
	else {
		setPixel(y + py, x + px, color);
		setPixel(y + py, -x + px, color);
	}

	while (x <= 1 / (2 * a)) {	//area_1

		if (e <= 0) {
			e += -(2 * x + 3) * a + 1;
			++y;
		}
		else {
			e += -(2 * x + 3) * a;
		}
		if (mode == 1) {
			if (flag == 1) {
				setPixel(x + px, y + py, color);
				setPixel(-x + px, y + py, color);
			}
			else {
				setPixel(x + px, -y - py, color);
				setPixel(-x + px, -y - py, color);
			}
		}
		else {
			if (flag == 1) {
				setPixel(y + py, x + px, color);
				setPixel(y + py, -x + px, color);
			}
			else {
				setPixel(-y - py, x + px, color);
				setPixel(-y - py, -x + px, color);
			}
		}
		++x;
	}
	x -= 1;//上句多加1

	e = (x + 0.5)*(x + 0.5)  * a - y - 1;
	while (x < 100) {//area_2
		if (e <= 0) {
			e += (2 * x + 2) * a - 1;
			x++;
		}
		else {
			e -= 1;

		}
		if (mode == 1) {
			if (flag == 1) {
				setPixel(x + px, y + py, color);
				setPixel(-x + px, y + py, color);
			}
			else {
				setPixel(x + px, -y - py, color);
				setPixel(-x + px, -y - py, color);
			}
		}
		else {
			if (flag == 1) {
				setPixel(y + py, x + px, color);
				setPixel(y + py, -x + px, color);
			}
			else {
				setPixel(-y - py, x + px, color);
				setPixel(-y - py, -x + px, color);
			}
		}
		y++;
	}
}

//中点画线
void MidPointLine(int x0, int y0, int x1, int y1, GLfloat* color) {
	float k = (y1 - y0)*1.00 / (x1 - x0)*1.00;
	translate(x0, y0, x1, y1, k);
	int dx = x1 - x0, dy = y1 - y0;
	float b = (dx*y1 - dy*x1) / dx;
	float d0 = dx*(y0 + 0.5) - dy*(x0 + 1) - dx*b;
	int x = x0, y = y0;
	double d = d0;
	while (x <= x1) {
		set_line_pixel(x, y, k, color);
		x++;
		if (d >= 0) {

			d = d - dy;
		}
		else {
			y++;
			d = d - dy + dx;
		}
	}
}

  

//通过顶点集合绘制多边形
void polygon(vector<Point>* set, GLfloat* color, int width = 1) {
	for (auto pr = set->begin() + 1; pr != set->end(); ++pr) {
		auto pl = pr - 1;
		GL_Line(pl->x, pl->y, pr->x, pr->y, color, width);
	}
	GL_Line((set->end() - 1)->x, (set->end() - 1)->y, set->begin()->x, set->begin()->y, color, width);
}

//将线段端点集合绘制成为线段
void lines(vector<Point>* set, GLfloat* color, int width = 1) {
	for (auto pr = set->begin() + 1; pr <= set->end() - 1; pr += 2) {
		auto pl = pr - 1;
		GL_Line(pl->x, pl->y, pr->x, pr->y, color, width);
		if (pr == set->end() - 1)
			break;
	}
}

//设置点的区域编码
void set_PointLoc(Point* pr) {
	pr->loc = 0;
	if (pr->x < x_min)
		pr->loc |= winLeftBitCode;
	if (pr->x > x_max)
		pr->loc |= winRightBitCode;
	if (pr->y < y_min)
		pr->loc |= winBottomBitCode;
	if (pr->y > y_max)
		pr->loc |= winTopBitCode;
}

//设置点集合的区域编码
void set_Loc(vector<Point>* set) {
	for (auto pr = set->begin(); pr < set->end(); ++pr)
		set_PointLoc(&*pr);
}

//交换两点坐标
void swapPoints(Point &p1, Point &p2) {
	Point _temp;
	_temp = p1;
	p1 = p2;
	p2 = _temp;
}

//判断点是否在窗口内
inline bool insideornot(Point p) {
	return !(p.loc);
}

//判断是否两点都在窗口外
inline unsigned char both_out(Point p1, Point p2) {
	return p1.loc & p2.loc;
}

//判断是否两点都在窗口内
inline unsigned char both_in(Point p1, Point p2) {
	return !(p1.loc | p2.loc);
}

//单条线段裁剪_CouhenSutherland
void LineClip_CouhenSutherland(Point p1, Point p2, GLfloat* color, int width = 1) {
	bool done = false, plot = false;
	double m = 0;
	if (p1.x != p2.x)
		m = (float)(p2.y - p1.y) / (float)(p2.x - p1.x);
	while (!done) {
		set_PointLoc(&p1);
		set_PointLoc(&p2);
		if (both_in(p1, p2)) {
			done = true;
			plot = true;
		}
		else if (both_out(p1, p2)) {
			done = true;
		}
		else {
			if (insideornot(p1)) {
				swapPoints(p1, p2);
			}
			if (p1.loc & winLeftBitCode) {
				p1.y += (x_min - p1.x)*m;
				p1.x = x_min;
			}
			else if (p1.loc & winRightBitCode) {
				p1.y += (x_max - p1.x)*m;
				p1.x = x_max;
			}
			else if (p1.loc & winBottomBitCode) {
				if (p2.x != p1.x)
					p1.x += (y_min - p1.y) / m;
				p1.y = y_min;
			}
			else if (p1.loc & winTopBitCode) {
				if (p2.x != p1.x)
					p1.x += (y_max - p1.y) / m;
				p1.y = y_max;
			}
		}
	}
	if (plot)
		GL_Line(p1.x, p1.y, p2.x, p2.y, color, width);
}

//线段集合裁剪_CouhenSutherland
void LineSetClip_CouhenSutherland(vector<Point>* set, GLfloat* color, int width = 1) {
	set_Loc(set);//设置线段端点区域码
	for (auto pr = set->begin() + 1; pr <= set->end() - 1; pr += 2) {
		auto pl = pr - 1;
		LineClip_CouhenSutherland(*pl, *pr, color, width);
		if (pr == set->end() - 1)
			break;
	}
}

//计算Liang算法中的p值
double calculate_pk(const Point p1, const Point p2, int type) {
	switch (type) {
	case 0:
		return -(p2.x - p1.x);
		break;
	case 1:
		return p2.x - p1.x;
		break;
	case 2:
		return -(p2.y - p1.y);
		break;
	case 3:
		return p2.y - p1.y;
		break;
	}
}

//计算Liang算法中的q值
double calculate_qk(const Point p1, const Point p2, int type) {
	switch (type) {
	case 0:
		return p1.x - x_min;
		break;
	case 1:
		return x_max - p1.x;
		break;
	case 2:
		return p1.y - y_min;
		break;
	case 3:
		return y_max - p1.y;
		break;
	}
}

bool LineClip_test(const double p, const double q, double &u1, double &u2) {
	double u = q / p;
	if (p < 0) {
		if (u > u2)
			return false;
		else if (u > u1) {
			u1 = u;
			return true;
		}
	}
	else if (p > 0) {
		if (u < u1)
			return false;
		else if (u < u2) {
			u2 = u;
			return true;
		}
	}

	else if (q < 0)
		return false;
}

//单条线段裁剪_LiangBarsky
void LineClip_LiangBarsky(Point p1, Point p2, GLfloat* color, int width = 1) {
	double u1 = 0, u2 = 1, u = 0;;
	int dx = p2.x - p1.x;
	int dy = p2.y - p1.y;

	vector<double > pk;
	vector<double > qk;
 	for (int i = 0; i < 4; ++i) {
		double temp;
		temp = calculate_pk(p1, p2, i);
		pk.push_back(temp);
		temp = calculate_qk(p1, p2, i);
		qk.push_back(temp);
	}

	if (LineClip_test(pk[LEFT], qk[LEFT], u1, u2)) {
		if (LineClip_test(pk[RIGHT], qk[RIGHT], u1, u2)) {
			if (LineClip_test(pk[BOTTOM], qk[BOTTOM], u1, u2)) {
				if (LineClip_test(pk[TOP], qk[TOP], u1, u2)) {
					if (u2 < 1) {
						p2.x = p1.x + u2 * dx;
						p2.y = p1.y + u2 * dy;
					}
					if (u1 > 0)	{
						p1.x = p1.x + u1 * dx;
						p1.y = p1.y + u1 * dy;
					}
					GL_Line(p1.x, p1.y, p2.x, p2.y, color, width);
				}
			}
		}
	}
}

//线段集合裁剪_LiangBarsky
void LineSetClip_LiangBarsky(vector<Point>* set, GLfloat* color, int width = 1) {
	for (auto pr = set->begin() + 1; pr <= set->end() - 1; pr += 2) {
		auto pl = pr - 1;
		LineClip_LiangBarsky(*pl, *pr, color, width);
		if (pr == set->end() - 1)
			break;
	}
}

//判断点是否在边界内
bool isPointinsideEdge(Point p, const int mode) {
	set_PointLoc(&p);
	switch (mode) {
	case LEFT:
		if ((p.loc & winLeftBitCode) == winLeftBitCode)
			return false;
		else return true;
	case RIGHT:
		if ((p.loc & winRightBitCode) == winRightBitCode)
			return false;
		else return true;
	case BOTTOM:
		if ((p.loc & winBottomBitCode) == winBottomBitCode)
			return false;
		else return true;
	case TOP:
		if ((p.loc & winTopBitCode) == winTopBitCode)
			return false;
		else return true;
	}
}

//判断线段是否与边界相交
bool isLinecrossEdge(Point p1, Point p2, const int mode) {
	if (isPointinsideEdge(p1, mode) == isPointinsideEdge(p2, mode))
		return false;
	return true;
}

//计算线段与边界直线的交点
Point intersect(Point p1, Point p2, const int mode) {
	/*if (p1.x == p2.x)
		exit(0);*/
	Point result;

	switch (mode) {
	case LEFT:
		result.x = x_min;
		result.y = p1.y + (x_min - p1.x) * (p2.y - p1.y) / (p2.x - p1.x);
		return result;
		break;
	case RIGHT:
		result.x = x_max;
		result.y = p1.y + (x_max - p1.x) * (p2.y - p1.y) / (p2.x - p1.x);
		return result;
		break;
	case BOTTOM:
		result.y = y_min;
		result.x = p1.x + (y_min - p1.y) / ((double)(p2.y - p1.y) / (double)(p2.x - p1.x));
		return result;
		break;
	case TOP:
		result.y = y_max;
		result.x = p1.x + (y_max - p1.y) / ((double)(p2.y - p1.y) / (double)(p2.x - p1.x));
		return result;
		break;
	}
}

//水平垂直情况下的线段顶点的添加
void parallelClip(Point p1, Point p2, vector<Point >* set, const int mode) {
	if (p1.x == p2.x) {//垂直
		switch (mode) {
		case LEFT:
			if (p1.x >= x_min)//II2
				set->push_back(p2);
			break;
		case RIGHT:
			if (p1.x <= x_max)//II2
				set->push_back(p2);
			break;
		case BOTTOM:
			if ((p1.y >= y_min) && (p2.y >= y_min))//II2
				set->push_back(p2);
			else if ((p1.y >= y_min) && (p2.y < y_min)) {//IOX
				Point temp(p1.x, y_min);
				set->push_back(temp);
			}
			else if ((p1.y < y_min) && (p2.y >= y_min)) {//OIX2
				Point temp(p1.x, y_min);
				set->push_back(temp);
				set->push_back(p2);
			}
			break;
		case TOP:
			if ((p1.y <= y_max) && (p2.y <= y_max))//II2
				set->push_back(p2);
			else if ((p1.y > y_max) && (p2.y <= y_max)) {//OIX2
				Point temp(p1.x, y_max);
				set->push_back(temp);
				set->push_back(p2);
			}
			else if ((p1.y <= y_max) && (p2.y > y_max)) {//IOX
				Point temp(p1.x, y_max);
				set->push_back(temp);
			}
			break;
		}
		return;
	}

	else if (p1.y == p2.y) {//水平
		switch (mode) {
		case LEFT:
			if ((p1.x >= x_min) && (p2.x >= x_min))//II2
				set->push_back(p2);
			else if ((p1.x < x_min) && (p2.x >= x_min)) {//OIX2
				Point temp(x_min, p1.y);
				set->push_back(temp);
				set->push_back(p2);
			}
			else if ((p1.x >= x_min) && (p2.x < x_min)) {//IOX
				set->push_back(p1);
				Point temp(x_min, p1.y);
				set->push_back(temp);
			}
			break;
		case RIGHT:
			if ((p1.x <= x_max) && (p2.x <= x_max))//II2
				set->push_back(p2);
			else if ((p1.x <= x_max) && (p2.x > x_max)) {//IOX
				set->push_back(p1);
				Point temp(x_max, p1.y);
				set->push_back(temp);
			}
			else if ((p1.x > x_max) && (p2.x <= x_max)) {//OIx2
				Point temp(x_max, p1.y);
				set->push_back(temp);
				set->push_back(p2);
			}
			break;
		case BOTTOM:
			if (p1.y >= y_min)//II2
				set->push_back(p2);
			break;
		case TOP:
			if (p1.y <= y_max)//II2
				set->push_back(p2);
			break;
		}
		return;
	}
}

//各种方向下多边形裁剪
void PolygonEdgeClip(vector<Point>* set, vector<Point>* newset, const int mode) {
	for (auto pl = set->begin(); pl != set->end(); ++pl) {
		if (pl == (set->end() - 1)) break;
		auto pr = pl + 1;
			if (isPointinsideEdge(*pl, mode)) {
			if (isPointinsideEdge(*pr, mode)) {//II2
				newset->push_back(*pr);
			}
			else {//IOX
				newset->push_back(intersect(*pl, *pr, mode));//

			}
		}
		else if (!isPointinsideEdge(*pl, mode)) {
			if (isPointinsideEdge(*pr, mode)) {//OIX2
				newset->push_back(intersect(*pl, *pr, mode));
				newset->push_back(*pr);
			}
		}
	}

	if (((set->end() - 1)->x == (set->begin())->x) || ((set->end() - 1)->y == (set->begin())->y))
		parallelClip(*(set->end() - 1), *(set->begin()), newset, mode);
	else if (isPointinsideEdge(*(set->end() - 1), mode)) {
		if (isPointinsideEdge(*(set->begin()), mode)) {//II2
			newset->push_back(*(set->begin()));
		}
		else if (!isPointinsideEdge(*(set->begin()), mode)) {//IOX
			newset->push_back(intersect(*(set->end() - 1), *(set->begin()), mode));//
		}
	}
	else if (!isPointinsideEdge(*(set->end() - 1), mode)) {
		if (isPointinsideEdge(*(set->begin()), mode)) {//OIX2
			newset->push_back(intersect(*(set->end() - 1), *(set->begin()), mode));
			newset->push_back(*(set->begin()));
		}
	}

}

//多边形裁剪
void PolygonClip(vector<Point>* set, GLfloat* color, int width = 1) {
	vector<Point > set_L, set_R, set_B, set_result;
	PolygonEdgeClip(set, &set_L, LEFT);//四个方向上各裁剪一次
	PolygonEdgeClip(&set_L, &set_R, RIGHT);
	PolygonEdgeClip(&set_R, &set_B, BOTTOM);
	PolygonEdgeClip(&set_B, &set_result, TOP);
	polygon(&set_result, color, 3);
}

  

//Frame func
void display(){
	glClear(GL_COLOR_BUFFER_BIT);
	DDALine(0,-L_h,0,L_h,black_color);//坐标轴
	DDALine(-L_w, 0, L_w, 0, black_color);

	/*----各种图形生成算法.start:----*/
	MidPointParabola(1.0000 / 50,1,2,1,blue_color); //中点画抛物线

	Bresenham_Line(180, -150, -350, 470, red_color);//全斜率直线

	MidPointCircle(175, green_color);//中点画圆

	MidpointEllipse(0, 0, 250, 140, black_color);//中点画椭圆

	MidPointLine(-110, 150, 350, 270, red_color);//中点画线
	/*----各种图形生成算法.end!----*/

	/*----线段裁剪.start:----*/
	line_points();//设置线段点集合
	lines(&line_points_set, green_color, 3);//画线
	set_ViewWindows(-200, 200, -200, 200);//设置窗口

	LineSetClip_CouhenSutherland(&line_points_set, red_color, 3);//Couhen_Sutherland线段裁剪

	LineSetClip_LiangBarsky(&line_points_set, red_color, 3);//LiangBarsky线段裁剪
	/*----线段裁剪.end!----*/

	/*----多边形裁剪.start:----*/
	polygon_points();//设置多边形顶点
	polygon(&polygon_points_set, green_color, 3);//绘制原始多边形
	set_ViewWindows(-200, 200, -200, 200);//设置窗口
	PolygonClip(&polygon_points_set, red_color, 3);//多边形裁剪
	/*----多边形裁剪.end!----*/

	glFlush();
}

//Display Init
void init(void){
	glClearColor(1.0, 1.0, 1.0, 0.0);//设置清屏颜色
	glMatrixMode(GL_PROJECTION);//设置投影矩阵
	glLoadIdentity();//单位化上述投影矩阵
	gluOrtho2D(-L_w*1.0, L_w*1.0, -L_h*1.0, L_h*1.0);//设置具体投影矩阵为平面正交投影4/3
}

void main(int argc, char** argv){
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitWindowPosition(50, 50);
	glutInitWindowSize(L_w*2, L_h*2);
	glutCreateWindow("Graphic Display");
	init();
	glutDisplayFunc(&display);
	glutMainLoop();
}

  

时间: 2024-10-19 21:21:44

Computer Graphics - code_1的相关文章

以图学习linux graphics -Mesa (computer graphics) 软件架构图

查看: 212|回复: 1    以图学习linux graphics -Mesa (computer graphics) 软件架构图 [复制链接]     titer1 轻车都尉(从四品) 注册时间 2014-8-22 积分 1095 串个门 加好友 打招呼 发消息 电梯直达 1#  发表于 2014-10-3 23:29:43 |只看该作者 |倒序浏览 本帖最后由 titer1 于 2014-10-3 23:29 编辑 Linux_kernel_and_OpenGL_video_game 更

HDU 4716 A Computer Graphics Problem(模拟啊 )

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4716 Problem Description In this problem we talk about the study of Computer Graphics. Of course, this is very, very hard. We have designed a new mobile phone, your task is to write a interface to displa

水题 HDOJ 4716 A Computer Graphics Problem

题目传送门 1 /* 2 水题:看见x是十的倍数就简单了 3 */ 4 #include <cstdio> 5 #include <iostream> 6 #include <algorithm> 7 #include <cstring> 8 #include <string> 9 #include <cmath> 10 using namespace std; 11 12 const int MAXN = 1e4 + 10; 13

A Computer Graphics Problem 4176 2013上海邀请赛

A Computer Graphics Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 968    Accepted Submission(s): 688 Problem Description In this problem we talk about the study of Computer Graphics.

Computer Graphics Research Software

Helping you avoid re-inventing the wheel since 2009! Last updated December 5, 2012.Try searching this page for keywords like 'segmentation' or 'PLY'.If you would like to contribute links, please e-mail them to [email protected]. Papers & Archives Gra

《Computer Graphics》 Peter.Shirley读书笔记

1.3图形学API使用图形函数库的关键在于处理应用程序接口(API),多数API都具有使用回调(callback)的用户界面工具包.当前主要有两种API模式.第一种是Java的集成方式,图形与用户界面工具包被集成在一起,都是可移植的包,并且完全标准化,作为语言的一部分得到支持:第二种的代表是D3D和OpenGL,画图命令是软件库的一部分,软件库与某种语言绑定(如C++),而用户界面软件是独立的实体,一般随系统不同而不同. 1.4最常用的模型由三维三角形组成 1.5三维图形流水线(graphic

Computer Graphics - code_2

#include <windows.h> #include <stdlib.h> #include <string.h> #include <tchar.h> #include <vector> #include <string> #include <time.h> using namespace std; typedef struct Point { //点结构 public: int x; int y; struct

Computer Graphics - code_3

#include <iostream> #include <GL/glut.h> #include <cmath> #define PI 3.141592653 #pragma comment( lib , "opengl32.lib") #pragma comment( lib , "glu32.lib" ) #pragma comment( lib , "glut32.lib" ) using namesp

计算机图形学 - 线段裁剪 - Liang Barsky算法(梁友栋算法)

算法描述: Liang_Barsky算法的基本出发点是直线的参数方程.给出任意一条直线段,两端点分别为和,令, 则直线的参数方程为: 如果直线上任意一点位于窗口内,则必须满足下列关系式: 上述不等式可以表示为: 其中p和q定义为: 任何一条直线如果平行于某一条裁剪边界,则有,下标k 对应于直线段平行的窗口边界(,并且分别表示裁剪窗口的左.右.下.上边界).如果对于某一个k值,满足,那么直线完全在窗口的外面,可以抛弃.如果,则该直线在它所平行的窗口边界的内部,还需要进一步计算才能确定直线是否在窗口