实验四4梁友栋Word文件下载.docx
- 文档编号:20738256
- 上传时间:2023-01-25
- 格式:DOCX
- 页数:11
- 大小:46.39KB
实验四4梁友栋Word文件下载.docx
《实验四4梁友栋Word文件下载.docx》由会员分享,可在线阅读,更多相关《实验四4梁友栋Word文件下载.docx(11页珍藏版)》请在冰豆网上搜索。
P=P0+t(P1-P0)
展开形式为:
X=x0+t(x1-x0)
Y=y0+t(y1-y0)
式中,0≤t≤1。
对于对角点(Wxl,Wyt)、(Wxr,Wyb)的矩形裁剪窗口,直线段裁剪条件如下:
Wxl≤x0+t(x1-x0)≤Wxr
Wyt≤y0+t(y1-y0)≤Wyb
分解后有:
t(x0-x1)≤x0-Wxl
t(x1-x0)≤Wxr-x0
t(y0-y1)≤y0-Wyb
t(y1-y0)≤Wyt-y0
将△x=x1-x0,△y=y1-y0代入上式得到:
t*(-△x)≤x0-Wxl
t*△x≤Wxr-x0
t*(-△y)≤y0-Wyb
t*△y≤Wyt-y0
令:
u1=-△x,v1=x0-Wxl
u2=△x,v2=Wxr-x0
u3=-△y,v3=y0-Wyb
u4=△y,v4=Wyt-y0
则统一表示为:
t*Un≤Vn,n=1,2,3,4
N代表直线段裁剪时,窗口的边界顺序,n=1表示左边界;
n=2表示右边界;
n=3表示下边界;
n=4表示上边界。
上式给出了直线段的参数方程裁剪条件。
4.实验内容
绘制一个裁剪框,在裁剪框内绘制直线,点击裁剪,实现对直线的裁剪。
5.源程序清单
//TestView.cpp:
implementationoftheCTestViewclass
//
#include"
stdafx.h"
Test.h"
TestDoc.h"
TestView.h"
#defineROUND(a)int(a+0.5)//四舍五入
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//CTestView
IMPLEMENT_DYNCREATE(CTestView,CView)
BEGIN_MESSAGE_MAP(CTestView,CView)
//{{AFX_MSG_MAP(CTestView)
ON_COMMAND(ID_MENUDrawLine,OnMENUDrawLine)
ON_COMMAND(ID_MENUClip,OnMENUClip)
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
//Standardprintingcommands
ON_COMMAND(ID_FILE_PRINT,CView:
:
OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT,CView:
ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView:
OnFilePrintPreview)
END_MESSAGE_MAP()
//CTestViewconstruction/destruction
CTestView:
CTestView()
{
//TODO:
addconstructioncodehere
//窗口位置坐标
wxl=250;
wxr=850;
wyb=250;
wyt=450;
m_Attatch=FALSE;
m_i=0;
m_Draw=FALSE;
}
~CTestView()
BOOLCTestView:
PreCreateWindow(CREATESTRUCT&
cs)
ModifytheWindowclassorstylesherebymodifying
//theCREATESTRUCTcs
returnCView:
PreCreateWindow(cs);
//CTestViewdrawing
voidCTestView:
OnDraw(CDC*pDC)
CTestDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
adddrawcodefornativedatahere
CRectRect;
GetClientRect(&
Rect);
//获得客户区的大小
CBitmapBitmap,*pBitmap;
Bitmap.LoadBitmap(IDB_BITMAP);
CDCMemDC;
MemDC.CreateCompatibleDC(GetDC());
pBitmap=MemDC.SelectObject(&
Bitmap);
MemDC.BitBlt(0,0,Rect.Width(),Rect.Height(),&
Picture,0,0,SRCCOPY);
MemDC.TextOut(ROUND((wxl+wxr)/2),ROUND(wyb-20),"
窗口"
);
//窗口标题
//绘制窗口和直线
CPenPen3,*pOldPen3;
//定义3个像素的画笔
Pen3.CreatePen(PS_SOLID,3,RGB(0,0,0));
pOldPen3=MemDC.SelectObject(&
Pen3);
MemDC.MoveTo(ROUND(wxl),ROUND(wyt));
MemDC.LineTo(ROUND(wxr),ROUND(wyt));
MemDC.LineTo(ROUND(wxr),ROUND(wyb));
MemDC.LineTo(ROUND(wxl),ROUND(wyb));
MemDC.LineTo(ROUND(wxl),ROUND(wyt));
MemDC.SelectObject(pOldPen3);
Pen3.DeleteObject();
CPenPen1,*pOldPen1;
//定义1个像素的画笔
Pen1.CreatePen(PS_SOLID,1,RGB(0,0,255));
pOldPen1=MemDC.SelectObject(&
Pen1);
if(m_i>
=1)
{
MemDC.MoveTo(ROUND(Pointx[0]),ROUND(Pointy[0]));
MemDC.LineTo(ROUND(Pointx[1]),ROUND(Pointy[1]));
}
MemDC.SelectObject(pOldPen1);
Pen1.DeleteObject();
CDC*dc=GetDC();
dc->
BitBlt(0,0,Rect.Width(),Rect.Height(),&
MemDC,0,0,SRCCOPY);
MemDC.SelectObject(pBitmap);
//Rectprinting
OnPreparePrinting(CPrintInfo*pInfo)
//defaultpreparation
returnDoPreparePrinting(pInfo);
OnBeginPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)
addextrainitializationbeforeprinting
OnEndPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)
addcleanupafterprinting
//CTestViewdiagnostics
AssertValid()const
CView:
AssertValid();
Dump(CDumpContext&
dc)const
Dump(dc);
CTestDoc*CTestView:
GetDocument()//non-debugversionisinline
ASSERT(m_pDocument->
IsKindOf(RUNTIME_CLASS(CTestDoc)));
return(CTestDoc*)m_pDocument;
#endif//_DEBUG
//CTestViewmessagehandlers
OnMENUDrawLine()//绘制直线菜单函数
Addyourcommandhandlercodehere
if(FALSE==m_Attatch)
Picture.CreateCompatibleDC(GetDC());
CBitmap*Bitmap,*pBitmap;
Bitmap=newCBitmap;
Bitmap->
LoadBitmap(IDB_BITMAP);
pBitmap=Picture.SelectObject(Bitmap);
m_Attatch=TRUE;
m_Draw=TRUE;
Invalidate(FALSE);
AfxGetMainWnd()->
SetWindowText("
案例12:
梁友栋-Barsky直线裁剪算法"
//显示标题
MessageBox("
请使用鼠标在屏幕上绘制直线,然后点击裁剪按钮进行裁剪"
"
提示"
MB_OKCANCEL);
OnMENUClip()//裁剪菜单函数
Clip(&
Pointx[0],&
Pointy[0],&
Pointx[1],&
Pointy[1]);
OnLButtonDown(UINTnFlags,CPointpoint)//单击鼠标左键函数
Addyourmessagehandlercodehereand/orcalldefault
if(TRUE==m_Draw)
if(m_i<
2)
{
Pointx[m_i]=point.x;
Pointy[m_i]=point.y;
m_i++;
}
OnLButtonDown(nFlags,point);
OnMouseMove(UINTnFlags,CPointpoint)//鼠标移动函数
Invalidate(FALSE);
OnMouseMove(nFlags,point);
Clip(double*x1,double*y1,double*x2,double*y2)//裁剪函数
doubletmax,tmin,dx,dy;
dx=*x2-*x1;
dy=*y2-*y1;
tmax=0.0,tmin=1.0;
//窗口边界的左、右、下、上顺序裁剪直线
if(ClipTest(-dx,*x1-wxl,&
tmax,&
tmin))//n=1,左边界u1=-△x,v1=x1-wxl
if(ClipTest(dx,wxr-*x1,&
tmin))//n=2,右边界u2=△x,v2=wxr-x1
{
if(ClipTest(-dy,*y1-wyb,&
tmin))//n=3,下边界u3=-△y,v3=y1-wyb
{
if(ClipTest(dy,wyt-*y1,&
tmin))//n=4,上边界u4=△y,v4=wyt-y1
{
if(tmin<
1.0)//判断直线的终点
{
*x2=*x1+tmin*dx;
//重新计算直线端点
*y2=*y1+tmin*dy;
//x=x1+t(x2-x1)格式
}
if(tmax>
0.0)//判断直线的起点
*x1+=tmax*dx;
*y1+=tmax*dy;
}
}
intCTestView:
ClipTest(doubleu,doublev,double*tmax,double*tmin)//裁剪测试函数
{//顺序左右下上
doublet;
intReturnValue=TRUE;
if(u<
0.0)//外部到内部,计算起点处的tmax
t=v/u;
if(t>
*tmin)
ReturnValue=FALSE;
elseif(t>
*tmax)
*tmax=t;
else
if(u>
0.0)//内部到外部,计算终点处的tmin
t=v/u;
if(t<
ReturnValue=FALSE;
elseif(t<
*tmin=t;
else//平行于窗口边界的直线
if(v<
0.0)//直线在窗口外可直接删除
return(ReturnValue);
6.实验结果
裁剪后
7实验总结
梁友栋-Barsky直线裁剪算法,的主要原理是采用了编码的方式来进行判断,那个区域应该保留,那个区域应该去掉,通过条件判断来进行筛选,通过这次的实验对于算法有了一个新的认识,了解了其基本算法原理。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 梁友栋