新建一个文档命名为1124,文档类型为单文档。
创建CP2类
右键1124 classes,点击new class新建一个类CP2:
在CP2类中声明三个域:(double x;double y;UINT rc;)
找到cpp文件,在里面引用CP2这个类:(#include “P2.h”)
在CView类中新建两个CP2类型的变量p0、p1和四个成员变量(定义矩形的四个方向的边界):
(这四个边界变量用double、int都可以)
在构造函数中给这四个变量赋值。
CMy11122View::CMy11122View() { // TODO: add construction code here wxl=-300,wyb=-100,wxr=300,wyt=100; }
新建函数DrawClipWindow(CDC*pDC),用来画矩形。
void CMy11122View::DrawClipWindow(CDC*pDC) { CRect rect(wxl,wyb,wxr,wyt); pDC->Rectangle(rect); }
在OnDraw函数中调用画矩形函数
void CMy11122View::OnDraw(CDC* pDC) { CMy11122Doc* pDoc = Getdocument(); ASSERT_VALID(pDoc); DrawClipWindow(pDC);//绘制裁剪窗口 // TODO: add draw code for native data here }
增加鼠标点击函数:
-
新建成员变量flag(用来判断赋值给p0还是p1,以及画线)
-
在构造函数中将flag初始化为0
CMy11122View::CMy11122View() { // TODO: add construction code here wxl=300,wyb=100,wxr=700,wyt=400; flag=0; }
3. 双击WM_LBUTTONDOWN添加该函数,点击Add and Edit编辑函数。
4. 在函数中编写如下代码:
void CMy11122View::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CDC*pDC=GetDC(); if(flag==0) { p0.x=point.x; p0.y=point.y; flag=1; } else { p1.x=point.x; p1.y=point.y; pDC->MoveTo(p0.x,p0.y); pDC->LineTo(p1.x,p1.y); flag=0; } CView::OnLButtonDown(nFlags, point); }
创建编码函数:
#define LEFT 0x1 //代表:0001 #define RIGHT 0x2 //代表:0010 #define BOTTOM 0x4 //代表:0100 #define TOP 0x8 //代表:1000 void CMy1112View::EnCode(CP2 &pt) { pt.rc=0; if(pt.xwxr) pt.rc=pt.rc | RIGHT; if(pt.y wyt) pt.rc=pt.rc | TOP; }
创建Cohen函数:
添加代码:(我用的方法是在函数开始时用白色画笔覆盖所画的线,再重画裁剪后得到的线)
void CMy11122View::OnCohen() { CDC*pDC=GetDC(); CPen NewPen,*pOldPen; NewPen.CreatePen(PS_SOLID,1,RGB(255,255,255)); pOldPen=pDC->SelectObject(&NewPen); pDC->MoveTo(p0.x,p0.y); pDC->LineTo(p1.x,p1.y); pDC->SelectObject(pOldPen); // TODO: Add your command handler code here CP2 p;//交点坐标 EnCode(p0);//起点编码 EnCode(p1);//终点编码 while(p0.rc!=0 || p1.rc!=0)//处理至少一个顶点在窗口外 { if((p0.rc & p1.rc)!=0)//简弃之 { return; } if(0==p0.rc)//确保p0位于窗口之外 { CP2 Temp; Temp=p0; p0=p1; p1=Temp; } UINT RC=p0.rc; double k=(p1.y-p0.y)/(p1.x-p0.x);//斜率 if(RC & LEFT)//p0点位于窗口的左侧 { p.x=wxl;//计算交点y坐标 p.y=k*(p.x-p0.x)+p0.y; } else if(RC & RIGHT)//p0点位于窗口的右侧 { p.x=wxr;//计算交点y坐标 p.y=k*(p.x-p0.x)+p0.y; } else if(RC & BOTTOM)//p0点位于窗口的下侧 { p.y=wyb;//计算交点x坐标 p.x=(p.y-p0.y)/k+p0.x; } else if(RC & TOP)//p0点位于窗口的上侧 { p.y=wyt;//计算交点x坐标 p.x=(p.y-p0.y)/k+p0.x; } EnCode(p); p0=p; } pDC->MoveTo(p0.x,p0.y); pDC->LineTo(p1.x,p1.y); }
为Cohen添加菜单函数:
-
在此处双击:
-
双击“帮助”后的空白处
-
编辑菜单属性
-
在空白处右键建立类向导:
点击Edit Code,将Cohen函数复制到OnCohen中来:
运行,用鼠标任意点两点,画线
点击裁剪:
裁剪多条直线效果(此方法只能画一条线裁剪一次):
梁友栋裁剪算法:
把EnCode和Cohen函数中的裁剪部分算法换成LBLineClip函数即可。
void CMy11122View::OnCohen() { CDC*pDC=GetDC(); CPen NewPen,*pOldPen; NewPen.CreatePen(PS_SOLID,1,RGB(255,255,255)); pOldPen=pDC->SelectObject(&NewPen); pDC->MoveTo(p0.x,p0.y); pDC->LineTo(p1.x,p1.y); pDC->SelectObject(pOldPen); double tmax,tmin,dx,dy; dx=p1.x-p0.x;dy=p1.y-p0.y;tmax=0.0,tmin=1.0; if(ClipTest(-dx,p0.x-wxl,tmax,tmin)) //窗口边界的左、右、下、上顺序裁剪直线 { if(ClipTest(dx,wxr-p0.x,tmax,tmin)) { if(ClipTest(-dy,p0.y-wyb,tmax,tmin)) { if(ClipTest(dy,wyt-p0.y,tmax,tmin)) { if(tmin<1.0)//判断直线终点 { p1.x=p0.x+tmin*dx; p1.y=p0.y+tmin*dy; } if(tmax>0.0)//判断直线的起点 { p0.x=p0.x+tmax*dx; p0.y=p0.y+tmax*dy; } } } } } pDC->MoveTo(p0.x,p0.y); pDC->LineTo(p1.x,p1.y); }
BOOL CMy11122View::ClipTest(double u,double v,double &tmax,double &tmin)//裁剪测试函数 { double t; BOOL ReturnValue=TRUE; if(u<0.0)//从裁剪窗口的外部到内部,计算起点处的tmax { t=v/u; if(t>tmin) ReturnValue=FALSE; else if(t>tmax) tmax=t; } else { if(u>0.0)//从裁剪窗口的内部到外部,计算终点处的tmin { t=v/u; if(t欢迎分享,转载请注明来源:内存溢出
评论列表(0条)