liang-barsky
#include<opencv2/core/core.hpp> #include<opencv2/imgproc/imgproc.hpp> #include<opencv2/highgui/highgui.hpp> #include<opencv2/opencv.hpp> #include<stdio.h> #include <string> #define For(i,a,b) for(int i=a;i<=b;++i) using namespace cv; Mat src; Mat dst; Point old_pt; Point new_pt; double xmin,xmax,ymin,ymax; int flag; void liang(Point pre_pt, Point cur_pt){ flag=0; double l,r,L,R; double x1=pre_pt.x,x2=cur_pt.x; double y1=pre_pt.y,y2=cur_pt.y; double p[6],q[6]; p[1] = -(x2 - x1); p[2] = -p[1]; p[3] = -(y2 - y1); p[4] = -p[3]; q[1] = x1 - xmin; q[2] = xmax - x1; q[3] = y1 - ymin; q[4] = ymax - y1; if(p[1]<0){ l=q[1]/p[1]; r=q[2]/p[2]; } if(p[1]>0){ r=q[1]/p[1]; l=q[2]/p[2]; } if(p[1]==0){ l=0; r=1; } if(p[3]<0){ L=q[3]/p[3]; R=q[4]/p[4]; } if(p[3]>0){ R=q[3]/p[3]; L=q[4]/p[4]; } if(p[3]==0){ L=0; R=1; } l=max((double)0,l); r=min((double)1,r); L=max((double)0,L); R=min((double)1,R); l=max(l,L); r=min(r,R); if(l<r){ old_pt.x=x1+l*p[2]; old_pt.y=y1+l*p[4]; new_pt.x=x1+r*p[2]; new_pt.y=y1+r*p[4]; flag=1; } } void on_mouse(int event, int x, int y, int flags, void* ustc){ static Point pre_pt ; static Point cur_pt ; char temp_1[20]; char temp_2[20]; if (event == EVENT_LBUTTONDOWN){ dst.copyTo(src); pre_pt = Point(x, y); circle(src, pre_pt, 0.5, Scalar(255, 0, 0), FILLED, 0); imshow("liang-barsky", src); } else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON)){ dst.copyTo(src); cur_pt = Point(x, y); sprintf(temp_2,"x:%d,y:%d",pre_pt.x,pre_pt.y); sprintf(temp_1,"x:%d,y:%d",x,y); putText(src,temp_2,Point(pre_pt.x,pre_pt.y),FONT_HERSHEY_SIMPLEX,0.8,Scalar(0,255,255)); putText(src,temp_1,Point(x,y),FONT_HERSHEY_SIMPLEX,0.8,Scalar(0,255,255)); circle(src, pre_pt, 3, Scalar(255,0, 0), FILLED, 0); circle(src, cur_pt, 3, Scalar(255,0, 0), FILLED, 0); line(src, pre_pt, cur_pt, Scalar(0, 255,0), 2, 8 ,0); imshow("liang-barsky", src); } else if (event == EVENT_LBUTTONUP){ dst.copyTo(src); cur_pt = Point(x, y); sprintf(temp_2,"x:%d,y:%d",pre_pt.x,pre_pt.y); sprintf(temp_1,"x:%d,y:%d",x,y); putText(src,temp_2,Point(pre_pt.x,pre_pt.y),FONT_HERSHEY_SIMPLEX,0.8,Scalar(0,255,255)); putText(src,temp_1,Point(x,y),FONT_HERSHEY_SIMPLEX,0.8,Scalar(0,255,255)); circle(src, pre_pt, 3, Scalar(255,0, 0), FILLED, 0); circle(src, cur_pt, 3, Scalar(255,0, 0), FILLED, 0); liang(pre_pt,cur_pt); if(flag){ line(src, pre_pt, old_pt, Scalar(0, 255,0), 2, 8, 0); line(src, old_pt, new_pt, Scalar(255, 0, 0), 4, 8, 0); line(src, new_pt, cur_pt, Scalar(0, 255,0), 2, 8, 0); } else{ line(src, pre_pt, cur_pt, Scalar(0, 255,0), 2, 8, 0); } imshow("liang-barsky", src); } } int main(){ namedWindow("liang-barsky", 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("liang-barsky", on_mouse, 0); imshow("liang-barsky", src); waitKey(0); return 0; }