不含凹多边形裁剪算法
#include <iostream>
#include<GL/glut.h>
#include<vector>
using namespace std;
int window_size = 600;
int wmin = 200, wmax = 400;
int hmin = 200, hmax = 400;
int last_x = -1, last_y = -1;
struct Vertex {
int x, y;
};
struct Edge {
Vertex point[2];
};
Edge LEFT, RIGHT, TOP, BOTTOM;
vector<Vertex> inputVertex, outputVertex;
void Output(Vertex& p, int outlength, vector<Vertex>& OutVertexarray) {
}
bool Inside(Vertex& TestPt, Edge& ClipBoundary) {
if (ClipBoundary.point[1].x > ClipBoundary.point[0].x) {
if (TestPt.y >= ClipBoundary.point[0].y) {
return true;
}
}
else if (ClipBoundary.point[1].x < ClipBoundary.point[0].x) {
if (TestPt.y <= ClipBoundary.point[0].y) {
return true;
}
}
else if (ClipBoundary.point[1].y > ClipBoundary.point[0].y) {
if (TestPt.x <= ClipBoundary.point[0].x) {
return true;
}
}
else if (ClipBoundary.point[1].y < ClipBoundary.point[0].y) {
if (TestPt.x >= ClipBoundary.point[0].x) {
return true;
}
}
return false;
}
void Intersect(Vertex& S, Vertex& P, Edge& ClipBoundary, Vertex& IntersectPt) {
if (ClipBoundary.point[0].y == ClipBoundary.point[1].y) {
IntersectPt.y = ClipBoundary.point[1].y;
IntersectPt.x = S.x + (ClipBoundary.point[0].y - S.y) * (P.x - S.x) / (P.y - S.y);
}
else {
IntersectPt.x = ClipBoundary.point[0].x;
IntersectPt.y = S.y + (ClipBoundary.point[0].x - S.x) * (P.y - S.y) / (P.x - S.x);
}
}
void SutherlandHogmanClip(vector<Vertex>& InVertexArray, vector<Vertex>& OutVertexArray, Edge ClipBoundary, int Inlength);
void showResult(vector<Vertex>& VertexArray);
void polygonClip() {
LEFT.point[0].x = wmin;
LEFT.point[0].y = hmax;
LEFT.point[1].x = wmin;
LEFT.point[1].y = hmin;
SutherlandHogmanClip(inputVertex, outputVertex, LEFT, inputVertex.size());
BOTTOM.point[0].x = wmin;
BOTTOM.point[0].y = hmin;
BOTTOM.point[1].x = wmax;
BOTTOM.point[1].y = hmin;
inputVertex.clear();
SutherlandHogmanClip(outputVertex, inputVertex, BOTTOM, outputVertex.size());
RIGHT.point[0].x = wmax;
RIGHT.point[0].y = hmin;
RIGHT.point[1].x = wmax;
RIGHT.point[1].y = hmax;
outputVertex.clear();
SutherlandHogmanClip(inputVertex, outputVertex, RIGHT, inputVertex.size());
TOP.point[0].x = wmax;
TOP.point[0].y = hmax;
TOP.point[1].x = wmin;
TOP.point[1].y = hmax;
inputVertex.clear();
SutherlandHogmanClip(outputVertex, inputVertex, TOP, outputVertex.size());
showResult(inputVertex);
}
void showResult(vector<Vertex>& VertexArray) {
glColor3f(0, 255, 0);
int len = VertexArray.size();
for (int i = 0; i < VertexArray.size(); i++) {
cout << "裁剪后点的坐标为(" << VertexArray[i].x << "," << VertexArray[i].y << ")" << endl;
glLineWidth(5);
glBegin(GL_LINES);
glVertex2i(VertexArray[i].x, VertexArray[i].y);
glVertex2i(VertexArray[(i + 1) % len].x, VertexArray[(i + 1) % len].y);
glEnd();
glBegin(GL_POINTS);
glVertex2i(VertexArray[i].x, VertexArray[i].y);
glVertex2i(VertexArray[(i + 1) % len].x, VertexArray[(i + 1) % len].y);
glEnd();
glLineWidth(1);
}
glFlush();
}
void SutherlandHogmanClip(vector<Vertex>& InVertexArray, vector<Vertex>& OutVertexArray, Edge ClipBoundary, int Inlength) {
Vertex S, P, ip;
S = InVertexArray[Inlength - 1];
for (int j = 0; j < Inlength; j++) {
P = InVertexArray[j];
if (Inside(P, ClipBoundary)) {
if (Inside(S, ClipBoundary)) {
cout << "情况1" << endl;
OutVertexArray.push_back(P);
}
else {
cout << "情况4" << endl;
Intersect(S, P, ClipBoundary, ip);
OutVertexArray.push_back(ip);
OutVertexArray.push_back(P);
}
}
else if (Inside(S, ClipBoundary)) {
cout << "情况3" << endl;
Intersect(S, P, ClipBoundary, ip);
OutVertexArray.push_back(ip);
cout << "ip的坐标为" << ip.x << " , " << ip.y << endl;
cout << "刚才入数组的点的坐标为" << OutVertexArray.back().x << " , " << outputVertex.back().y << endl;
}
else {
cout << "情况2" << endl;
}
S = P;
}
}
void drawpoint(int x, int y) {
glColor3f(1, 0, 0);
glBegin(GL_POINTS);
glVertex2f(x, y);
glEnd();
glFlush();
}
void mykeyboard(unsigned char key, int x, int y) {
if (key == 'f' && inputVertex.size()) {
glColor3f(0, 0, 255);
glBegin(GL_LINES);
glVertex2d(last_x, last_y);
glVertex2d(inputVertex[0].x, inputVertex[0].y);
glEnd();
glFlush();
}
if (key == 'c') {
polygonClip();
}
}
void myDisplay();
void mymouse(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
inputVertex.push_back({ x,y });
drawpoint(x, y);
if (last_x >= 0 && last_y >= 0) {
cout << "可以画线" << endl;
glColor3f(0, 0, 255);
glBegin(GL_LINES);
glVertex2i(last_x, last_y);
glVertex2i(x, y);
glEnd();
glFlush();
}
cout << "刚才加入的坐标是" << x << "," << y << endl;
last_x = x; last_y = y;
}
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
cout << "点击了鼠标右键" << endl;
myDisplay();
inputVertex.clear(); outputVertex.clear();
last_x = -1; last_y = -1;
}
}
void myDisplay() {
cout << "调用了一次回调函数" << endl;
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0, 1, 1);
glBegin(GL_LINES);
glVertex2i(wmin, hmin);
glVertex2i(wmin, hmax);
glVertex2i(wmin, hmin);
glVertex2i(wmax, hmin);
glVertex2i(wmax, hmin);
glVertex2i(wmax, hmax);
glVertex2i(wmin, hmax);
glVertex2i(wmax, hmax);
glEnd();
glFlush();
}
void init() {
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(7);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluOrtho2D(0, window_size, window_size, 0);
myDisplay();
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(300, 100);
glutInitWindowSize(window_size, window_size);
glutCreateWindow("多边形裁剪算法");
init();
glutMouseFunc(mymouse);
glutKeyboardFunc(mykeyboard);
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}
含有凹多边形裁剪算法
#include <iostream>
#include<GL/glut.h>
#include<vector>
#include<cstring>
using namespace std;
const int window_size = 600;
int wmin = 200, wmax = 400;
int hmin = 200, hmax = 400;
int last_x = -1, last_y = -1;
struct Vertex {
int x, y;
};
struct Edge {
Vertex point[2];
};
int vis[window_size][window_size];
Edge LEFT, RIGHT, TOP, BOTTOM;
vector<Vertex> inputVertex, outputVertex;
bool Inside(Vertex& TestPt, Edge& ClipBoundary) {
if (ClipBoundary.point[1].x > ClipBoundary.point[0].x) {
if (TestPt.y >= ClipBoundary.point[0].y) {
return true;
}
}
else if (ClipBoundary.point[1].x < ClipBoundary.point[0].x) {
if (TestPt.y <= ClipBoundary.point[0].y) {
return true;
}
}
else if (ClipBoundary.point[1].y > ClipBoundary.point[0].y) {
if (TestPt.x <= ClipBoundary.point[0].x) {
return true;
}
}
else if (ClipBoundary.point[1].y < ClipBoundary.point[0].y) {
if (TestPt.x >= ClipBoundary.point[0].x) {
return true;
}
}
return false;
}
void Intersect(Vertex& S, Vertex& P, Edge& ClipBoundary, Vertex& IntersectPt) {
if (ClipBoundary.point[0].y == ClipBoundary.point[1].y) {
IntersectPt.y = ClipBoundary.point[1].y;
IntersectPt.x = S.x + (ClipBoundary.point[0].y - S.y) * (P.x - S.x) / (P.y - S.y);
}
else {
IntersectPt.x = ClipBoundary.point[0].x;
IntersectPt.y = S.y + (ClipBoundary.point[0].x - S.x) * (P.y - S.y) / (P.x - S.x);
}
}
void SutherlandHogmanClip(vector<Vertex>& InVertexArray, vector<Vertex>& OutVertexArray, Edge ClipBoundary, int Inlength);
void showResult(vector<Vertex>& VertexArray);
void polygonClip() {
LEFT.point[0].x = wmin;
LEFT.point[0].y = hmax;
LEFT.point[1].x = wmin;
LEFT.point[1].y = hmin;
SutherlandHogmanClip(inputVertex, outputVertex, LEFT, inputVertex.size());
BOTTOM.point[0].x = wmin;
BOTTOM.point[0].y = hmin;
BOTTOM.point[1].x = wmax;
BOTTOM.point[1].y = hmin;
inputVertex.clear();
SutherlandHogmanClip(outputVertex, inputVertex, BOTTOM, outputVertex.size());
RIGHT.point[0].x = wmax;
RIGHT.point[0].y = hmin;
RIGHT.point[1].x = wmax;
RIGHT.point[1].y = hmax;
outputVertex.clear();
SutherlandHogmanClip(inputVertex, outputVertex, RIGHT, inputVertex.size());
TOP.point[0].x = wmax;
TOP.point[0].y = hmax;
TOP.point[1].x = wmin;
TOP.point[1].y = hmax;
inputVertex.clear();
SutherlandHogmanClip(outputVertex, inputVertex, TOP, outputVertex.size());
showResult(inputVertex);
}
void drawpixel(int x, int y) {
glPointSize(2);
vis[x][y]++;
if (vis[x][y] % 2 == 1) {
glColor3ub(20, 160, 93);
glBegin(GL_POINTS);
glVertex2i(x, y);
glEnd();
glFlush();
}
else {
glColor3ub(255, 205, 68);
glBegin(GL_POINTS);
glVertex2i(x, y);
glEnd();
glFlush();
}
}
void Bresenham(int x0, int y0, int x1, int y1) {
cout << "B" << endl;
if (x0 > x1)swap(x0, x1), swap(y0, y1);
bool negk = y1 < y0;
if (negk) y0 = -y0, y1 = -y1;
bool steepk = y1 - y0 > x1 - x0;
if (steepk) swap(x0, y0), swap(x1, y1);
int x = x0, y = y0, dx = x1 - x0, dy = y1 - y0;
int e = -dx;
for (int i = 0; i <= dx; i ++) {
drawpixel(steepk ? y : x, negk ? (steepk ? -x : -y) : (steepk ? x : y));
x += 1; e += 2 * dy ;
if (e >= 0) y += 1, e -= 2 * dx;
}
}
void showResult(vector<Vertex>& VertexArray) {
glColor3ub(20, 160, 93);
int len = VertexArray.size();
for (int i = 0; i < VertexArray.size(); i++) {
cout << "裁剪后点的坐标为(" << VertexArray[i].x << "," << VertexArray[i].y << ")" << endl;
Bresenham(VertexArray[i].x, VertexArray[i].y,VertexArray[(i + 1) % len].x, VertexArray[(i + 1) % len].y);
glColor3ub(20, 160, 93);
glPointSize(7);
glBegin(GL_POINTS);
glVertex2i(VertexArray[i].x, VertexArray[i].y);
glVertex2i(VertexArray[(i + 1) % len].x, VertexArray[(i + 1) % len].y);
glEnd();
glLineWidth(1);
}
glFlush();
}
void SutherlandHogmanClip(vector<Vertex>& InVertexArray, vector<Vertex>& OutVertexArray, Edge ClipBoundary, int Inlength) {
Vertex S, P, ip;
S = InVertexArray[Inlength - 1];
for (int j = 0; j < Inlength; j++) {
P = InVertexArray[j];
if (Inside(P, ClipBoundary)) {
if (Inside(S, ClipBoundary)) {
cout << "情况1" << endl;
OutVertexArray.push_back(P);
}
else {
cout << "情况4" << endl;
Intersect(S, P, ClipBoundary, ip);
OutVertexArray.push_back(ip);
OutVertexArray.push_back(P);
}
}
else if (Inside(S, ClipBoundary)) {
cout << "情况3" << endl;
Intersect(S, P, ClipBoundary, ip);
OutVertexArray.push_back(ip);
cout << "ip的坐标为" << ip.x << " , " << ip.y << endl;
cout << "刚才入数组的点的坐标为" << OutVertexArray.back().x << " , " << outputVertex.back().y << endl;
}
else {
cout << "情况2" << endl;
}
S = P;
}
}
void drawpoint(int x, int y) {
glColor3ub(211, 82, 70);
glBegin(GL_POINTS);
glVertex2f(x, y);
glEnd();
glFlush();
}
void mykeyboard(unsigned char key, int x, int y) {
if (key == 'f' && inputVertex.size()) {
glColor3ub(75, 140, 255);
glBegin(GL_LINES);
glVertex2d(last_x, last_y);
glVertex2d(inputVertex[0].x, inputVertex[0].y);
glEnd();
glFlush();
}
if (key == 'c') {
polygonClip();
}
}
void myDisplay();
void mymouse(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
inputVertex.push_back({ x,y });
drawpoint(x, y);
if (last_x >= 0 && last_y >= 0) {
cout << "可以画线" << endl;
glColor3ub(75, 140, 255);
glBegin(GL_LINES);
glVertex2i(last_x, last_y);
glVertex2i(x, y);
glEnd();
glFlush();
}
cout << "刚才加入的坐标是" << x << "," << y << endl;
last_x = x; last_y = y;
}
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
cout << "点击了鼠标右键" << endl;
myDisplay();
inputVertex.clear(); outputVertex.clear();
memset(vis, 0, sizeof vis);
last_x = -1; last_y = -1;
}
}
void myDisplay() {
cout << "调用了一次回调函数" << endl;
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3ub(255, 205, 68);
glLineWidth(2);
glBegin(GL_LINES);
glVertex2i(wmin, hmin);
glVertex2i(wmin, hmax);
glVertex2i(wmin, hmin);
glVertex2i(wmax, hmin);
glVertex2i(wmax, hmin);
glVertex2i(wmax, hmax);
glVertex2i(wmin, hmax);
glVertex2i(wmax, hmax);
glEnd();
glFlush();
}
void init() {
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(7);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluOrtho2D(0, window_size, window_size, 0);
myDisplay();
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(300, 100);
glutInitWindowSize(window_size, window_size);
glutCreateWindow("多边形裁剪算法");
init();
glutMouseFunc(mymouse);
glutKeyboardFunc(mykeyboard);
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}