直线绘制:
首先现在MFC文件中的xxxView.h头文件中添加一个直线的结构体(xxx表示你MFC文件的名字)
typedef struct //线段结构 { CPoint startpoint; CPoint endpoint; } LINE;
还是在头文件里,加入下面那部分的代码(从CArry开始),encode函数是Cohen-Southerland算法实现编码的函数的定义,具体的代码在cpp文件里写
在菜单(Menu)文件中添加两个事件处理程序(注意:添加时要写到View类里去),一个线段绘制,一个线段裁剪
因为画线是通过鼠标左键来实现的,所以在View类里要添加一个消息(WM_LBUTTONDOWN),并加上代码
之前不是添加了两个事件处理程序吗,所以在第一个,也就是线段绘制函数添加代码(这里我把函数名改成了DrawLine)
最后在cpp文件中的OnDraw函数中添加划线的代码
现在启动应用,点击绘制线段应该是可以画出直线的
Cohen-Southerland算法
在cpp文件里最上面定义下
#define LEFT 1 //0001
#define RIGHT 2 //0010
#define BOTTOM 4//0100
#define TOP 8 //1000
接着编写编码函数
为了能够裁剪成功,并重新画出裁剪后的直线,所以要绘制一个矩形框
int XL = 100, XR = 300, YB = 100, YT = 200; //(x1,y1)、(x2,y2)为直线段的端点,XL为左边界,XR为右边界,YB为下边界,YT为上边
同时在OnDraw函数中绘制出矩形框(写在OnDraw函数里)
CPen newpen(PS_SOLID, 3, RGB(0, 255, 0)); CPen *old = pDC->SelectObject(&newpen); pDC->MoveTo(100, 100); pDC->LineTo(100, 200); pDC->MoveTo(100, 200); pDC->LineTo(300, 200); pDC->MoveTo(300, 200); pDC->LineTo(300, 100); pDC->MoveTo(300, 100); pDC->LineTo(100, 100); pDC->SelectObject(old);
接下来到了最关键的Cohen-Southerland算法
在第二个事件处理程序,也就是线段裁剪的函数里添加代码(函数名称没改,就是默认的ID号)
void CCGTestView::On32786() //线段裁剪 { // TODO: 在此添加命令处理程序代码 int code1, code2, code; int x, y; int i; int x1, y1, x2, y2; for (int i = 0; i < LineSet.GetSize(); i++) //绘制多条直线时,一条一条得实现 { x1 = LineSet.GetAt(i).startpoint.x; y1 = LineSet.GetAt(i).startpoint.y; x2 = LineSet.GetAt(i).endpoint.x; y2 = LineSet.GetAt(i).endpoint.y; encode(x1, y1, code1); //分别求出端点所在的区号 encode(x2, y2, code2); while (code1 != 0 || code2 != 0)//只有两个端点全在中心区内(直接保留完整线端,否则进入循环) { if (code1 &code2) //说明两个端点全在非中心区的区域,直接不画) return; if (code1 != 0) //如果端点1不在中心区 code = code1; //使端点1与边界交换 else //说明端点1在中心区,端点2不在中心区 code = code2; //使端点2与边界交点交换 if (code & LEFT) //线端与左边界相交,条件成立,点必定在左边界左侧 { x = XL; //求为与左边界相交的点的x值 y = y1 + (y2 - y1)*(XL - x1) / (x2 - x1); //斜率((y2 - y1)/(x2 - x1)) } else if (code & RIGHT)//线段与右边界相交,条件成立,点必定在右边界右侧 { x = XR; //求出右边界的交点x值 y = y1 + (y2 - y1)*(XR - x1) / (x2 - x1); } else if (code & BOTTOM) //线段与下边界相交 { y = YB; x = x1 + (x2 - x1)*(YB - y1) / (y2 - y1); } else if (code & TOP) //线段与上边界相交 { y = YT; x = x1 + (x2 - x1)*(YT - y1) / (y2 - y1); } //将端点与边界交点转换 if (code == code1) { x1 = x; y1 = y; encode(x1, y1, code1);//如果交换成功,新编码为0000 } else { x2 = x; y2 = y; encode(x2, y2, code2); //交换成功,新编码为0000 } } //绘制线段 CDC *pDC = this->GetDC(); CPen newpen(PS_SOLID, 3, RGB(255, 255, 0)); CPen *old = pDC->SelectObject(&newpen); pDC->MoveTo(x1, y1); pDC->LineTo(x2, y2); pDC->SelectObject(old); ReleaseDC(pDC); } }
运行结果:
------------------------------------------------------------------------
(在下写博客,是记下平时学习程中常遇到的问题,代码中若有不合理之处,还望各位大佬指正)