基于MFC的线段裁剪算法的实现
一、新建MFC项目
此处就不再赘述,没有 基础的可以先看第一个 程序。
项目名为
二、宏定义设置
在适当位置设置宏。
#define LEFT 1
#define RIGHT 2
#define BOTTOM 4
#define TOP 8
#define XL 100
#define XR 300
#define YT 100
#define YB 250
三、全局变量初始化
const UINT N = 8;
CPoint ptset[N];
int flag = 0;
四、窗口初始化
void CLineclippingView::OnDraw(CDC* pDC)
{
CLineclippingDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码
CPen newpen(PS_SOLID, 1, RGB(0, 0, 0));
CPen *old = pDC->SelectObject(&newpen);
pDC->Rectangle(CRect(XL, YT, XR, YB));
ptset[0] = CPoint(120, 150);
ptset[1] = CPoint(170, 110);
ptset[2] = CPoint(0, 190);
ptset[3] = CPoint(350, 150);
ptset[4] = CPoint(0, 250);
ptset[5] = CPoint(150, 230);
ptset[6] = CPoint(200, 50);
ptset[7] = CPoint(120, 150);
pDC->TextOutW(0, 20, L"双击鼠标左键,出现要剪切的线段");
pDC->SelectObject(old);
}
五、线段初始化
类向导添加消息中的 处理程序。
void CLineclippingView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CDC *pDC = GetDC();
CPen newpen(PS_SOLID, 1, RGB(255, 0, 0));
CPen *old = pDC->SelectObject(&newpen);
flag = 1;
for (int i = 0; i < N; i++) {
pDC->MoveTo(ptset[i]);
pDC->LineTo(ptset[i + 1]);
i++;
}
CView::OnLButtonDblClk(nFlags, point);
}
六、线段裁剪算法实现
设置 为 ,添加事件处理函数 。
void CLineclippingView::OnClipline()
{
// TODO: 在此添加命令处理程序代码
CDC * pDC = GetDC();
CPen newpen(PS_SOLID, 1, RGB(255, 0, 0));
CPen *old = pDC->SelectObject(&newpen);
if (flag != 1) {
MessageBox(L"请先双击鼠标左击", L"警告!");
}
else {
float x, y;
int i;
int code1, code2;
RedrawWindow();
for (int i = 0; i < N; i++, i++) {
int c = 0;
if (ptset[i].x < XL)
c = c | LEFT;
else if (ptset[i].x > XR)
c = c | RIGHT;
if (ptset[i].y > YB)
c = c | BOTTOM;
else if (ptset[i].y < YT)
c = c | TOP;
code1 = c;
c = 0;
if (ptset[i + 1].x < XL)
c = c | LEFT;
else if (ptset[i + 1].x > XR)
c = c | RIGHT;
if (ptset[i + 1].y > YB)
c = c | BOTTOM;
else if (ptset[i + 1].y < YT)
c = c | TOP;
code2 = c;
if (code1 != 0 && code2 != 0 && (code1&code2) == 0) {
if ((LEFT&code1) != 0) {
x = XL;
y = (float)ptset[i].y + (ptset[i + 1].y - ptset[i].y)*(XL - ptset[i].x) / (ptset[i + 1].x - ptset[i].x);
}
else if ((RIGHT&code1) != 0) {
x = XR;
y = (float)ptset[i].y + (ptset[i + 1].y - ptset[i].y)*(XR - ptset[i].x) / (ptset[i + 1].x - ptset[i].x);
}
else if ((BOTTOM&code1) != 0) {
y = YB;
x = (float)ptset[i].x + (ptset[i + 1].x - ptset[i].x)*(YB - ptset[i].y) / (ptset[i + 1].y - ptset[i + 1].y);
}
else if ((TOP&code1) != 0) {
y = YT;
x = (float)ptset[i].x + (ptset[i + 1].x - ptset[i].x)*(YT - ptset[i].y) / (ptset[i + 1].y - ptset[i].y);
}
ptset[i].x = (long)x;
ptset[i].y = (long)y;
if ((LEFT&code2) != 0) {
x = XL;
y = (float)ptset[i].y + (ptset[i + 1].y - ptset[i].y)*(XL - ptset[i].x) / (ptset[i + 1].x - ptset[i].x);
}
else if ((RIGHT&code2) != 0) {
x = XR;
y = (float)ptset[i].y + (ptset[i + 1].y - ptset[i].y)*(XR - ptset[i].x) / (ptset[i + 1].x - ptset[i].x);
}
else if ((BOTTOM&code2) != 0) {
y = YB;
x = (float)ptset[i].x + (ptset[i + 1].x - ptset[i].x)*(YB - ptset[i].y) / (ptset[i + 1].y - ptset[i + 1].y);
}
else if ((TOP&code2) != 0) {
y = YT;
x = (float)ptset[i].x + (ptset[i + 1].x - ptset[i].x)*(YT - ptset[i].y) / (ptset[i + 1].y - ptset[i].y);
}
ptset[i + 1].x = (long)x;
ptset[i + 1].y = (long)y;
pDC->MoveTo(ptset[i].x, ptset[i].y);
pDC->LineTo(ptset[i + 1].x, ptset[i + 1].y);
}
if (code1 == 0 && code2 == 0) {
pDC->MoveTo(ptset[i].x, ptset[i].y);
pDC->LineTo(ptset[i + 1].x, ptset[i + 1].y);
}
if (code1 == 0 && code2 != 0) {
pDC->MoveTo(ptset[0].x, ptset[0].y);
if ((LEFT&code2) != 0) {
x = XL;
y = (float)ptset[i].y + (ptset[i + 1].y - ptset[i].y)*(XL - ptset[i].x) / (ptset[i + 1].x - ptset[i].x);
}
else if ((RIGHT&code2) != 0) {
x = XR;
y = (float)ptset[i].y + (ptset[i + 1].y - ptset[i].y)*(XR - ptset[i].x) / (ptset[i + 1].x - ptset[i].x);
}
else if ((BOTTOM&code2) != 0) {
y = YB;
x = (float)ptset[i].x + (ptset[i + 1].x - ptset[i].x)*(YB - ptset[i].y) / (ptset[i + 1].y - ptset[i + 1].y);
}
else if ((TOP&code2) != 0) {
y = YT;
x = (float)ptset[i].x + (ptset[i + 1].x - ptset[i].x)*(YT - ptset[i].y) / (ptset[i + 1].y - ptset[i].y);
}
ptset[i + 1].x = (long)x;
ptset[i + 1].y = (long)y;
pDC->LineTo(ptset[i + 1].x, ptset[i + 1].y);
}
if (code1 != 0 && code2 == 0) {
pDC->MoveTo(ptset[i + 1].x, ptset[i + 1].y);
if ((LEFT&code1) != 0) {
x = XL;
y = (float)ptset[i].y + (ptset[i + 1].y - ptset[i].y)*(XL - ptset[i].x) / (ptset[i + 1].x - ptset[i].x);
}
else if ((RIGHT&code1) != 0) {
x = XR;
y = (float)ptset[i].y + (ptset[i + 1].y - ptset[i].y)*(XR - ptset[i].x) / (ptset[i + 1].x - ptset[i].x);
}
else if ((BOTTOM&code1) != 0) {
y = YB;
x = (float)ptset[i].x + (ptset[i + 1].x - ptset[i].x)*(YB - ptset[i].y) / (ptset[i + 1].y - ptset[i + 1].y);
}
else if ((TOP&code1) != 0) {
y = YT;
x = (float)ptset[i].x + (ptset[i + 1].x - ptset[i].x)*(YT - ptset[i].y) / (ptset[i + 1].y - ptset[i].y);
}
ptset[i].x = (long)x;
ptset[i].y = (long)y;
pDC->LineTo(ptset[i].x, ptset[i].y);
}
}
}
}