多边形裁剪
#include<opencv2/core/core.hpp> #include<opencv2/imgproc/imgproc.hpp> #include<opencv2/highgui/highgui.hpp> #include<opencv2/opencv.hpp> #include<bits/stdc++.h> #define For(i,a,b) for(int i=a;i<=b;++i) using namespace cv; using namespace std; int n,cnt; vector<Point>a,b; Mat src; Mat dst; Point pre_pt ,fir_pt; Point cur_pt ; double xmin,xmax,ymin,ymax,k; int flag; void check(int num){ pre_pt=Point(-1,-1); if(num==4){//上侧 for(auto i:a){ if(pre_pt.x==-1){ pre_pt=i; } else{ cur_pt=i; if(pre_pt.y>=ymin&&cur_pt.y<ymin){ k=(double)(cur_pt.y-ymin)*(double)(cur_pt.x-pre_pt.x)/(double)(cur_pt.y-pre_pt.y); b.push_back(Point(cur_pt.x-k,ymin)); } if(pre_pt.y>=ymin&&cur_pt.y>=ymin){ b.push_back(cur_pt); } if(pre_pt.y<ymin&&cur_pt.y>=ymin){ k=(double)(cur_pt.y-ymin)*(double)(cur_pt.x-pre_pt.x)/(double)(cur_pt.y-pre_pt.y); b.push_back(Point(cur_pt.x-k,ymin)); b.push_back(cur_pt); } pre_pt=i; } } } if(num==3){//右侧 for(auto i:a){ if(pre_pt.x==-1){ pre_pt=i; } else{ cur_pt=i; if(pre_pt.x<xmax&&cur_pt.x>=xmax){ k=(double)(cur_pt.x-xmax)*(double)(cur_pt.y-pre_pt.y)/(double)(cur_pt.x-pre_pt.x); b.push_back(Point(xmax,cur_pt.y-k)); } if(pre_pt.x<=xmax&&cur_pt.x<=xmax){ b.push_back(cur_pt); } if(pre_pt.x>=xmax&&cur_pt.x<xmax){ k=(double)(cur_pt.x-xmax)*(double)(cur_pt.y-pre_pt.y)/(double)(cur_pt.x-pre_pt.x); b.push_back(Point(xmax,cur_pt.y-k)); b.push_back(cur_pt); } pre_pt=i; } } } if(num==2){//下侧 for(auto i:a){ if(pre_pt.x==-1){ pre_pt=i; } else{ cur_pt=i; if(pre_pt.y<ymax&&cur_pt.y>=ymax){ k=(double)(cur_pt.y-ymax)*(double)(cur_pt.x-pre_pt.x)/(double)(cur_pt.y-pre_pt.y); b.push_back(Point(cur_pt.x-k,ymax)); } if(pre_pt.y<=ymax&&cur_pt.y<=ymax){ b.push_back(cur_pt); } if(pre_pt.y>=ymax&&cur_pt.y<ymax){ k=(double)(cur_pt.y-ymax)*(double)(cur_pt.x-pre_pt.x)/(double)(cur_pt.y-pre_pt.y); b.push_back(Point(cur_pt.x-k,ymax)); b.push_back(cur_pt); } pre_pt=i; } } } if(num==1){//左侧 for(auto i:a){ if(pre_pt.x==-1){ pre_pt=i; } else{ cur_pt=i; if(pre_pt.x<xmin&&cur_pt.x>=xmin){ k=(double)(cur_pt.x-xmin)*(double)(cur_pt.y-pre_pt.y)/(double)(cur_pt.x-pre_pt.x); b.push_back(Point(xmin,cur_pt.y-k)); b.push_back(cur_pt); } if(pre_pt.x>=xmin&&cur_pt.x>=xmin){ b.push_back(cur_pt); } if(pre_pt.x>=xmin&&cur_pt.x<xmin){ k=(double)(cur_pt.x-xmin)*(double)(cur_pt.y-pre_pt.y)/(double)(cur_pt.x-pre_pt.x); b.push_back(Point(xmin,cur_pt.y-k)); } pre_pt=i; } } } } void Sutherland_Hodgman(){ For(i,1,4){ check(i); a.clear(); for(auto j:b) a.push_back(j); a.push_back(b[0]); b.clear(); } pre_pt=Point(-1,-1); //dst.copyTo(src); for(auto i:a){ if(pre_pt.x==-1){ pre_pt=i; } else{ cur_pt=i; line(src, pre_pt, cur_pt, Scalar(255, 0, 0), 4, 8, 0); imshow("Sutherland-Hodgman", src); pre_pt=i; } } } void on_mouse(int event, int x, int y, int flags, void* ustc){ if (event == EVENT_LBUTTONDOWN){ cnt++; a.push_back(Point(x,y)); if(cnt==1){ pre_pt=Point(x,y); fir_pt=pre_pt; imshow("Sutherland-Hodgman", src); } if(cnt>1&&cnt<=n){ cur_pt=Point(x,y); line(src, pre_pt, cur_pt, Scalar(0, 255,0), 2, 4, 0); pre_pt=cur_pt; imshow("Sutherland-Hodgman", src); } if(cnt==n){ a.push_back(fir_pt); line(src, cur_pt, fir_pt, Scalar(0, 255,0), 2, 4, 0); imshow("Sutherland-Hodgman", src); Sutherland_Hodgman(); return; } } } int main(){ cout<<"请输入多边形的顶点数"<<endl; cin>>n; if(n<3){ cout<<"至少需要三个顶点哦😊"<<endl; return 0; } namedWindow("Sutherland-Hodgman", WINDOW_AUTOSIZE); src=Mat(1000, 1000, CV_8UC3, Scalar(0)); xmax=ymax=600; xmin=ymin=200; rectangle(src,Rect(200,200,400,400),Scalar(255,255,255),2,1,0); src.copyTo(dst); setMouseCallback("Sutherland-Hodgman", on_mouse, 0); imshow("Sutherland-Hodgman", src); waitKey(0); return 0; }