計算機圖形學課程設計報告---多邊形剪裁和填充圖形軟件設計_第1頁
已閱讀1頁,還剩19頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、<p><b>  圖形學課程設計</b></p><p>  --多邊形剪裁和填充圖形軟件設計</p><p><b>  一、題目內(nèi)容說明:</b></p><p>  1、交互式地實現(xiàn)多邊形的裁剪和填充。</p><p><b>  2、功能要求:</b><

2、;/p><p><b>  窗口功能設計。</b></p><p>  2)實現(xiàn)鼠標畫多邊形與數(shù)據(jù)存儲功能。</p><p>  4)實現(xiàn)鼠標剪裁窗口選擇功能。</p><p>  實現(xiàn)多邊形裁剪和填充功能。</p><p><b>  二、總體設計:</b></p>

3、<p>  本程序使用MFC實現(xiàn)多邊形的裁剪和填充繪圖程序。</p><p>  多邊形裁剪算法分析:</p><p>  基本思想是一次用窗口的一條邊裁剪多邊形,窗口的一條邊以及延長線構(gòu)成裁剪線,改線把平面分成兩個部分:可見一側(cè),不可見一側(cè)。用一條裁剪邊多多邊形進行裁剪,得到一個頂點序列,作為嚇一條裁剪邊處理過程的輸入點。</p><p>  對于每

4、一條裁剪邊,只是判斷點在窗口的哪一測以及求線段與裁剪邊的交點算法應隨之改變。</p><p>  僅用一條裁剪邊時,逐次多邊形裁剪框圖:</p><p>  在CGraphics類的CutRectangular(CRect)函數(shù)中實現(xiàn)對多邊形的裁剪</p><p>  多邊形填充算法分析:</p><p>  確定多邊形所占有的最大掃描線數(shù),

5、得到多邊形頂點的最小和最大y值(ymin和ymax),從y=ymin 到 y=ymax, 每次用一條掃描進行填充。對一條掃描線填充的過程可分為四個步驟: a.求交b.排序c.交點配對d.區(qū)間填色。在CGraphics類中的FillPlogon函數(shù)中實現(xiàn)多邊形的填充算法。</p><p><b>  三、模塊設計:</b></p><p>  各個程序函數(shù)的功能,參數(shù),

6、變量的說明:</p><p>  MFC應用程序框架中類的詳細解析:</p><p>  1.MainFrm:創(chuàng)建窗口及窗口里的菜單、工具欄、狀態(tài)欄等實現(xiàn)交互的按鈕。</p><p>  1)函數(shù)int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct){}創(chuàng)建菜單、工具欄、狀欄。</p><p

7、>  2)BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)設置窗口的大小和初始位置。</p><p>  2.圖像裁剪View:視圖,負責內(nèi)存數(shù)據(jù)與用戶的交互,包括數(shù)據(jù)的顯示、菜單的選取,鼠標的響應。</p><p>  void CMyView::OnLButtonDown(UINT nFlags, CPoint poin

8、t){}對鼠標按下左鍵的響應,如果是自定義裁剪的區(qū)域操作就捕獲鼠標按下的點,畫裁剪區(qū)域,如果是自定義點坐標的操作就捕獲鼠標的點畫多邊形。</p><p>  void CMyView::OnMouseMove(UINT nFlags, CPoint point){}對 鼠標 移動的響應。用捕獲的點畫出相應的矩形裁剪邊框。畫邊框的時候,先用白色擦出原先的矩形邊框,再用虛線畫出新

9、的舉行邊框</p><p>  void CMyView::OnRButtonUp(UINT nFlags, CPoint point){}對鼠標放開左鍵的相應。如果是自定義點的坐標,就獲取新的初始裁減矩形范圍。</p><p>  void CMyView::OnLButtonUp(UINT nFlags, CPoint point){}對鼠標放開左鍵的響應</p><

10、;p>  void CMyView::OnInitialUpdate(){}初始化裁剪區(qū)域和在窗口中畫一個矩形和一個五角星。</p><p>  void CMyView::OnDraw(CDC* pDC){}重畫窗口,用voidCMyView::OnInitialUpdate{}來啟動它,通過消息映射表處理菜單、工具條、快捷鍵和其他用戶消息。定義裁剪矩形區(qū)域,并賦值。當自定義多邊形坐標時,在各個點坐標處畫

11、一個小圓,以顯示點的位置。畫出多邊形。</p><p>  3.圖像裁剪DOC:文檔,負責內(nèi)存數(shù)據(jù)與磁盤的交互。</p><p>  void CMyDoc::OnFillployon(){}</p><p>  void CMyDoc::OnUpdateFillployon(CCmdUI* pCmdUI){}</p><p>  void

12、CMyDoc::OnCutRect(){}</p><p>  void CMyDoc::OnUpdateCutRect(CCmdUI* pCmdUI){}</p><p>  4.CGraphics:實現(xiàn)多邊形的填充和裁剪。</p><p>  構(gòu)造函數(shù)CGraphics():PointCount(10),Point(NULL){}初始化五角星的頂點坐標。<

13、/p><p>  析構(gòu)函數(shù)~CGraphics(){}刪除動態(tài)生成的Point指針。</p><p>  bool DrawPloyon(CDC*);在指定設備中畫多邊形。</p><p>  bool FillPloyon(CDC*);填充多邊形。</p><p>  bool InterCross(CPoint,CPoint,CPoint,C

14、Point,CPoint&);判斷兩條線段是否相交。</p><p>  bool CutRect(CRect);對多邊形進行裁剪。</p><p>  bool IsInSquareRgn(CRect,CPoint,int);對多邊形裁剪時,判斷線段斷點是否在可視一側(cè)。</p><p>  bool SortArray(int*,int);冒泡排序。<

15、;/p><p><b>  四、詳細設計:</b></p><p>  1、創(chuàng)建窗口、菜單、工具欄、狀欄的函數(shù)。</p><p>  int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)</p><p><b>  {</b></p>

16、<p>  if (CFrameWnd::OnCreate(lpCreateStruct) == -1)</p><p>  return -1;</p><p>  if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP</p><p>  | C

17、BRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||</p><p>  !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))</p><p><b>  {</b></p><p>  TRACE0("Failed to cre

18、ate toolbar\n");</p><p>  return -1; // fail to create</p><p><b>  }</b></p><p>  if (!m_wndStatusBar.Create(this) ||</p><p>  !m_wndStatusBar.Set

19、Indicators(indicators,</p><p>  sizeof(indicators)/sizeof(UINT)))</p><p><b>  {</b></p><p>  TRACE0("Failed to create status bar\n");</p><p>  ret

20、urn -1; // fail to create</p><p><b>  }</b></p><p>  // TODO: Delete these three lines if you don't want the toolbar to</p><p>  // be dockable</p><

21、p>  m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);</p><p>  EnableDocking(CBRS_ALIGN_ANY);</p><p>  DockControlBar(&m_wndToolBar);</p><p>  return 0; </p><p><b&

22、gt;  }</b></p><p>  2、鼠標按下左鍵的響應函數(shù)</p><p>  void CMyView::OnLButtonDown(UINT nFlags, CPoint point) </p><p><b>  {</b></p><p>  //對鼠標按下左鍵的相應</p>

23、<p>  CScrollView::OnLButtonDown(nFlags, point);</p><p>  if(m_bDefineRect)</p><p><b>  {</b></p><p>  //如果是自定義裁減的區(qū)域的操作</p><p>  SetCapture();//捕獲鼠標&l

24、t;/p><p>  m_bCaptured = TRUE;</p><p>  CDC *dc=GetDC();</p><p>  CRect rect(TopLeft,BottomRight);</p><p>  dc->SelectStockObject(WHITE_PEN);</p><p>  dc-&

25、gt;Rectangle(rect);</p><p>  InvalidateRect(rect,false);</p><p>  TopLeft = point;</p><p>  ::SetCursor(::LoadCursor(NULL, IDC_CROSS));//設置鼠標樣子為十字形的</p><p><b>  }

26、</b></p><p>  if(m_bDefinePointV)</p><p><b>  {</b></p><p>  //如果是自定義點坐標的操作</p><p>  PointArray.Add(point);</p><p>  CRect ellipseRect;&l

27、t;/p><p>  ellipseRect.top = point.y - 5;</p><p>  ellipseRect.bottom = point.y + 5;</p><p>  ellipseRect.left = point.x - 5;</p><p>  ellipseRect.right = point.x + 5;<

28、/p><p>  InvalidateRect(ellipseRect,true);</p><p><b>  }</b></p><p><b>  }</b></p><p>  3、鼠標移動時的響應函數(shù)</p><p>  void CMyView::OnMouseMo

29、ve(UINT nFlags, CPoint point) </p><p><b>  {</b></p><p>  CScrollView::OnMouseMove(nFlags, point);</p><p>  //對鼠標移動時的相應</p><p>  if (m_bCaptured) </p>

30、<p><b>  {</b></p><p>  //畫出相應的矩形裁減邊框</p><p>  CDC *dc=GetDC();</p><p>  CRect rect(TopLeft,BottomRight);</p><p>  dc->SelectStockObject(WHITE_PEN

31、);</p><p>  dc->Rectangle(rect);//用白色擦除原先的矩形邊框</p><p>  InvalidateRect(rect,false);</p><p>  BottomRight=point;</p><p>  CRect newrect(TopLeft,BottomRight);</p>

32、;<p><b>  CPen pen;</b></p><p>  pen.CreatePen(PS_DOT,1,RGB(0,0,0));</p><p>  dc->SelectObject(pen);</p><p>  dc->Rectangle(newrect);//用虛線畫出新的矩形邊框</p>

33、<p><b>  }</b></p><p><b>  }</b></p><p>  void CMyView::OnLButtonUp(UINT nFlags, CPoint point) </p><p><b>  {</b></p><p>  CS

34、crollView::OnLButtonUp(nFlags, point);</p><p>  //對鼠標放開左鍵的響應</p><p>  if (m_bCaptured) </p><p><b>  {</b></p><p>  ::ReleaseCapture();</p><p> 

35、 m_bCaptured = false;</p><p>  m_bDefineRect = false;</p><p><b>  }</b></p><p><b>  }</b></p><p>  void CMyView::OnViewDefineRect() </p>

36、<p><b>  {</b></p><p>  //設置是否自定義裁減區(qū)域</p><p>  m_bDefineRect = true;</p><p><b>  }</b></p><p>  void CMyView::OnEditDefinePoint() </p>

37、;<p><b>  {</b></p><p>  //設置是否自定義點的坐標</p><p>  m_bDefinePointV = true;</p><p><b>  }</b></p><p>  4、放開鼠標右鍵的響應</p><p>  voi

38、d CMyView::OnRButtonUp(UINT nFlags, CPoint point) </p><p><b>  {</b></p><p>  ////對鼠標放開右鍵的相應</p><p>  CScrollView::OnRButtonUp(nFlags, point);</p><p>  if(m

39、_bDefinePointV)</p><p><b>  {</b></p><p>  CMyDoc* pDoc = GetDocument();</p><p>  ASSERT_VALID(pDoc);</p><p>  pDoc->m_grahics.PointCount=PointArray.GetS

40、ize();</p><p>  if(pDoc->m_grahics.Point)</p><p>  delete pDoc->m_grahics.Point;</p><p>  pDoc->m_grahics.Point = new CPoint[pDoc->m_grahics.PointCount];</p><

41、p>  for(int i=0;i<pDoc->m_grahics.PointCount;i++)</p><p>  pDoc->m_grahics.Point[i]=PointArray.GetAt(i);//對Point點坐標重新賦值</p><p>  PointArray.RemoveAll();</p><p>  m_bDefi

42、nePointV=false;</p><p>  CRect rect;</p><p>  this->GetClientRect(rect);</p><p>  InvalidateRect(rect);</p><p>  //獲取新的初始裁減矩形范圍</p><p>  int minX = pDoc

43、->m_grahics.Point[0].x , minY = pDoc->m_grahics.Point[0].y;</p><p>  int maxX = pDoc->m_grahics.Point[0].x , maxY = pDoc->m_grahics.Point[0].y;</p><p>  for(i=1;i<pDoc->m_grahi

44、cs.PointCount;i++)</p><p><b>  {</b></p><p>  if(minX > pDoc->m_grahics.Point[i].x)</p><p>  minX = pDoc->m_grahics.Point[i].x;</p><p>  if(minY &g

45、t; pDoc->m_grahics.Point[i].y)</p><p>  minY = pDoc->m_grahics.Point[i].y;</p><p>  if(maxX < pDoc->m_grahics.Point[i].x)</p><p>  maxX = pDoc->m_grahics.Point[i].x;&

46、lt;/p><p>  if(maxY < pDoc->m_grahics.Point[i].y)</p><p>  maxY = pDoc->m_grahics.Point[i].y;</p><p><b>  }</b></p><p>  TopLeft = CPoint(minX,minY);&

47、lt;/p><p>  BottomRight = CPoint(maxX,maxY);</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  5、初始化函數(shù)</b></p><p>  void CMy

48、View::OnInitialUpdate()</p><p><b>  {</b></p><p>  CScrollView::OnInitialUpdate();</p><p>  CSize sizeTotal;</p><p>  sizeTotal.cx = sizeTotal.cy = 100;<

49、/p><p>  SetScrollSizes(MM_TEXT, sizeTotal);</p><p>  CMyDoc* pDoc = GetDocument();</p><p>  ASSERT_VALID(pDoc);</p><p>  //設置初始的裁減區(qū)域</p><p>  int minX = pDoc

50、->m_grahics.Point[0].x , minY = pDoc->m_grahics.Point[0].y;</p><p>  int maxX = pDoc->m_grahics.Point[0].x , maxY = pDoc->m_grahics.Point[0].y;</p><p>  for(int i=1;i<pDoc->m_g

51、rahics.PointCount;i++)</p><p><b>  {</b></p><p>  if(minX > pDoc->m_grahics.Point[i].x)</p><p>  minX = pDoc->m_grahics.Point[i].x;</p><p>  if(min

52、Y > pDoc->m_grahics.Point[i].y)</p><p>  minY = pDoc->m_grahics.Point[i].y;</p><p>  if(maxX < pDoc->m_grahics.Point[i].x)</p><p>  maxX = pDoc->m_grahics.Point[i]

53、.x;</p><p>  if(maxY < pDoc->m_grahics.Point[i].y)</p><p>  maxY = pDoc->m_grahics.Point[i].y;</p><p><b>  }</b></p><p>  TopLeft = CPoint(minX,min

54、Y);</p><p>  BottomRight = CPoint(maxX,maxY);</p><p><b>  }</b></p><p>  6、重畫窗口的函數(shù),是MFC自動生成的,我們可以在里面添加自己的代碼,用來實現(xiàn)消息映射表處理菜單、工具條、快捷鍵和其他用戶消息。</p><p>  void CMyV

55、iew::OnDraw(CDC* pDC)</p><p><b>  {</b></p><p>  CMyDoc* pDoc = GetDocument();</p><p>  ASSERT_VALID(pDoc);</p><p>  // TODO: add draw code for native data

56、here</p><p>  int left,top,right,buttom;</p><p>  left=min(TopLeft.x,BottomRight.x);</p><p>  right=max(TopLeft.x,BottomRight.x);</p><p>  top=min(TopLeft.y,BottomRight

57、.y);</p><p>  buttom=max(TopLeft.y,BottomRight.y);</p><p>  CRect rect(left,top,right,buttom);</p><p>  //定義裁減矩形區(qū)域,并賦值</p><p>  CPen penDot,penSolid;</p><p&g

58、t;  penDot.CreatePen(PS_DOT,1,RGB(0,0,0));</p><p>  pDC->SelectObject(penDot);</p><p>  pDC->Rectangle(rect);</p><p>  //用虛線畫出裁減矩形區(qū)域</p><p>  penSolid.CreatePen(P

59、S_SOLID,1,RGB(0,0,0));</p><p>  pDC->SelectObject(penSolid);</p><p>  if(PointArray.GetSize())</p><p><b>  {</b></p><p>  //當自定義多邊形點坐標時,在各個點坐標處畫一個小圓,以顯示點

60、的位置</p><p><b>  int i;</b></p><p>  for(i=0;i<PointArray.GetSize();i++)</p><p><b>  {</b></p><p>  pDC->MoveTo(PointArray.GetAt(i));</p

61、><p>  CRect ellipseRect;</p><p>  ellipseRect.top = PointArray.GetAt(i).y - 5;</p><p>  ellipseRect.bottom = PointArray.GetAt(i).y + 5;</p><p>  ellipseRect.left = PointA

62、rray.GetAt(i).x - 5;</p><p>  ellipseRect.right = PointArray.GetAt(i).x + 5;</p><p>  pDC->Ellipse(ellipseRect);</p><p><b>  }</b></p><p><b>  }<

63、;/b></p><p>  if(pDoc->bCutRect) </p><p><b>  {</b></p><p>  //判斷是否裁減,若是,則根據(jù)裁減區(qū)域進行裁減</p><p>  pDoc->m_grahics.CutRect(rect);</p><p>  

64、pDoc->bCutRect=false;</p><p><b>  }</b></p><p>  pDoc->m_grahics.DrawPloyon(pDC);</p><p><b>  //畫出多邊形</b></p><p>  if(pDoc->bFillPloyon

65、)</p><p><b>  {</b></p><p>  //判斷是否填充,根據(jù)需要進行相應的操作</p><p>  pDoc->m_grahics.FillPloyon(pDC);</p><p>  pDoc->bFillPloyon=false;</p><p><

66、b>  }</b></p><p><b>  }</b></p><p>  7、在指定的pDC設備中,畫多邊形</p><p>  bool CGraphics::DrawPloyon(CDC* pDC)</p><p><b>  {</b></p><p

67、>  if(PointCount < 3)</p><p>  return false;</p><p>  //若多邊形小于三個點則返回</p><p>  pDC->MoveTo(Point[0]);</p><p>  for(int i=1;i<PointCount;i++)</p><p

68、><b>  {</b></p><p>  pDC->LineTo(Point[i]);</p><p><b>  }</b></p><p>  pDC->LineTo(Point[0]);</p><p>  //在pDC中畫出多邊形</p><p&g

69、t;  return true;</p><p><b>  }</b></p><p>  8、填充多邊形函數(shù),重量級的函數(shù)</p><p>  //在指定的pDC設備中,填充多邊形</p><p>  bool CGraphics::FillPloyon(CDC* pDC)</p><p>&

70、lt;b>  {</b></p><p>  if(PointCount < 3)</p><p>  return false;</p><p>  //若多邊形小于三個點則返回</p><p>  int minX = Point[0].x , minY = Point[0].y;</p><p

71、>  int maxX = Point[0].x , maxY = Point[0].y;</p><p>  for(int i=1;i<PointCount;i++)</p><p><b>  {</b></p><p>  if(minX > Point[i].x)</p><p>  minX

72、 = Point[i].x;</p><p>  if(minY > Point[i].y)</p><p>  minY = Point[i].y;</p><p>  if(maxX < Point[i].x)</p><p>  maxX = Point[i].x;</p><p>  if(maxY

73、 < Point[i].y)</p><p>  maxY = Point[i].y;</p><p><b>  }</b></p><p>  //獲取多邊形中所有坐標點的最大值和最小值,作為掃描線循環(huán)的范圍</p><p>  CUIntArray myArray;</p><p>&

74、lt;b>  int x,y;</b></p><p>  for(y=minY;y<maxY;y++)</p><p><b>  {</b></p><p>  //掃描線從minY開始到maxY</p><p>  for(i=0;i<PointCount;i++)</p>

75、<p><b>  {</b></p><p>  //對每條邊進行循環(huán)</p><p>  CPoint PointCross;</p><p>  int beforeI=BeforeIndex(i),afterI=AfterIndex(i);</p><p>  //判斷是否跟線段相交</p&g

76、t;<p>  if(InterCross(Point[beforeI],Point[i],CPoint(minX,y),CPoint(maxX,y),PointCross))</p><p><b>  {</b></p><p>  //若是存在交點,則進行相應的判斷,即判斷x的坐標取兩次、一次還是不取</p><p>  i

77、f(PointCross==Point[i])</p><p><b>  {</b></p><p>  if((Point[beforeI].y > PointCross.y) && (Point[afterI].y > PointCross.y))</p><p><b>  {</b>&

78、lt;/p><p>  myArray.Add(PointCross.x);</p><p>  myArray.Add(PointCross.x);</p><p>  //邊頂點的y值大于交點的y值,x坐標取兩次</p><p><b>  }</b></p><p><b>  els

79、e</b></p><p>  if((Point[beforeI].y - PointCross.y) * (Point[afterI].y - PointCross.y) < 0)</p><p>  myArray.Add(PointCross.x);//邊頂點的y值在交點的y值之間,即一個頂點的y值大于交點的y值,而另一個小于,相應的x坐標取一次</

80、p><p><b>  else</b></p><p>  if(PointCross.y==Point[afterI].y)</p><p>  myArray.Add(PointCross.x); </p><p><b>  }</b></p><p><b&

81、gt;  else </b></p><p>  if(PointCross==Point[beforeI])</p><p><b>  {</b></p><p><b>  continue;</b></p><p><b>  }</b></p>

82、<p><b>  else</b></p><p>  myArray.Add(PointCross.x);//當交點不在線段的頂點時,x坐標只取一次</p><p><b>  }</b></p><p><b>  }</b></p><p>  int

83、*scanLineX,num=myArray.GetSize();</p><p>  scanLineX = new int[num];</p><p>  for(i=0;i<num;i++)</p><p>  scanLineX[i]=myArray.GetAt(i);//獲取掃描線x值,以構(gòu)成填充區(qū)間</p><p>  my

84、Array.RemoveAll();</p><p>  SortArray(scanLineX,num);//對scanLine(掃描線x坐標進行排序)</p><p>  for(i=0;i<num;i=i+2)</p><p><b>  {</b></p><p>  if(i+1>=num)<

85、/p><p><b>  break;</b></p><p>  for(x=scanLineX[i];x<scanLineX[i+1];x++)//x值配對填充</p><p>  pDC->SetPixelV(CPoint(x,y),RGB(255,0,0));//將填充區(qū)間相應點的顏色設置成紅色</p><p

86、><b>  }</b></p><p>  Sleep(1);//CPU暫停1ms,以體現(xiàn)出多邊形是以掃描線的方式,一條一條的填充的</p><p>  delete scanLineX;</p><p><b>  }</b></p><p>  return true;</p>

87、;<p><b>  }</b></p><p>  9、裁剪多邊形的函數(shù),重量級的函數(shù)</p><p>  bool CGraphics::CutRect(CRect rect)</p><p><b>  {</b></p><p>  CPoint rectPoint[4];&l

88、t;/p><p>  rectPoint[0].x = rect.left;</p><p>  rectPoint[0].y = rect.top;</p><p>  rectPoint[1].x = rect.right;</p><p>  rectPoint[1].y = rect.top;</p><p>  

89、rectPoint[3].x = rect.left;</p><p>  rectPoint[3].y = rect.bottom;</p><p>  rectPoint[2].x = rect.right;</p><p>  rectPoint[2].y = rect.bottom;</p><p>  //獲取裁減矩形的四個點的坐標

90、,第一個點為左上,第二個點為右上,第三個點為右下,第四個點為左下</p><p><b>  int i;</b></p><p>  CArray<CPoint,CPoint&> myArray;//裁減后,保存的多邊形的依次各點的坐標</p><p>  for(int rectNum=0;rectNum<4;re

91、ctNum++)</p><p><b>  {</b></p><p>  //對裁減矩形的四條邊進行循環(huán)</p><p>  for(i=0;i<PointCount;i++)</p><p><b>  {</b></p><p>  //對每條邊進行循環(huán)<

92、/p><p>  CPoint PointCross;</p><p>  int beforeI=BeforeIndex(i),afterI=AfterIndex(i);</p><p>  int afterrectNum = ((rectNum == 3)?0:rectNum+1);</p><p>  //判斷是否跟線段相交</p&

93、gt;<p>  if(InterCross(Point[beforeI],Point[i],rectPoint[rectNum],rectPoint[afterrectNum],PointCross))</p><p><b>  {</b></p><p>  if(PointCross==Point[i])</p><p>

94、<b>  {</b></p><p>  myArray.Add(Point[i]);//交點在線段上,直接添加點坐標在保存多邊形的數(shù)組中</p><p><b>  }</b></p><p><b>  else </b></p><p>  if(PointCross=

95、=Point[beforeI])</p><p><b>  {</b></p><p>  if(IsInSquareRgn(rect,Point[i],rectNum))</p><p>  myArray.Add(Point[i]);//判斷是否可視,若是,則添加點坐標</p><p><b>  }&l

96、t;/b></p><p><b>  else</b></p><p><b>  {</b></p><p>  myArray.Add(PointCross);//跟線段相交,但交點不在頂點上,添加交點坐標</p><p>  if(IsInSquareRgn(rect,Point[i]

97、,rectNum))</p><p>  myArray.Add(Point[i]);//判斷是否可視,若是,則添加點坐標</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  else</b></p><

98、;p>  if(IsInSquareRgn(rect,Point[i],rectNum))</p><p>  myArray.Add(Point[i]);//線段不相交,但需判斷是否可視,若是,則添加點坐標</p><p><b>  }</b></p><p>  PointCount=myArray.GetSize();</p

99、><p><b>  if(Point)</b></p><p>  delete Point;</p><p>  Point = new CPoint[PointCount];</p><p>  for(i=0;i<PointCount;i++)</p><p>  Point[i]=my

100、Array.GetAt(i);//重新賦予點坐標的值</p><p>  myArray.RemoveAll();</p><p><b>  }</b></p><p>  return true;</p><p><b>  }</b></p><p>  10、判斷判斷

101、兩條線段是否相交的函數(shù)</p><p>  bool CGraphics::InterCross(CPoint objectP1,CPoint objectP2,CPoint scanP1,CPoint scanP2,CPoint& coordinate)</p><p><b>  {</b></p><p>  //objectP1

102、、objectP2是一條線段的頂點坐標,而scanP1、scanP2是另一條線段的頂點坐標</p><p>  if(objectP1 == objectP2)</p><p>  return false;//若objectP1、objectP2相等,則構(gòu)不成線段,退出</p><p>  if(scanP1 == scanP2)</p><p

103、>  return false;//若scanP1、scanP2等,則構(gòu)不成線段,退出</p><p>  if( ( objectP1.y - objectP2.y ) * ( scanP1.x - scanP2.x )</p><p>  == ( scanP1.y - scanP2.y ) * ( objectP1.x - objectP2.x))</p><

104、;p><b>  {</b></p><p>  //對斜率相等的情況下的處理</p><p>  if((objectP1.y-objectP2.y)*(scanP1.x-objectP1.x)==(objectP1.x-objectP2.x)*(scanP1.y-objectP1.y))</p><p><b>  {<

105、;/b></p><p>  //判斷兩條線段是不是同一條線段</p><p>  coordinate=objectP2;</p><p>  return true;</p><p><b>  }</b></p><p><b>  else</b></p&

106、gt;<p>  return false;</p><p><b>  }</b></p><p>  if(objectP1.x == objectP2.x)</p><p><b>  {</b></p><p>  //當?shù)谝粭l線段斜率不存在是的,處理辦法</p>

107、<p>  double x,y;</p><p>  x = objectP1.x;</p><p>  y = (scanP1.y-scanP2.y)*1.0/(scanP1.x-scanP2.x)*(objectP1.x-scanP1.x)+scanP1.y;</p><p>  y = (float)((int)(y+0.5));</p&g

108、t;<p>  if(((objectP1.y-y)*(y-objectP2.y)>=0) && ((objectP1.x-x)*(x-objectP2.x)>=0))</p><p><b>  {</b></p><p>  //判斷交點是不是在該兩條線段上</p><p>  coordinate

109、.x = objectP1.x;</p><p>  coordinate.y = (int)(y+0.5);</p><p>  return true;</p><p><b>  }</b></p><p>  return false;</p><p><b>  }</b

110、></p><p><b>  else</b></p><p><b>  {</b></p><p>  if(scanP1.x == scanP2.x)</p><p><b>  {</b></p><p>  //當?shù)诙l線段斜率不存在是

111、的,處理辦法</p><p>  double x,y;</p><p>  x = scanP1.x;</p><p>  y = (objectP1.y-objectP2.y)*1.0/(objectP1.x-objectP2.x)*(scanP1.x-objectP1.x)+objectP1.y;</p><p>  y = (floa

112、t)((int)(y+0.5));</p><p>  if(((objectP1.y-y)*(y-objectP2.y)>=0) && ((objectP1.x-x)*(x-objectP2.x)>=0))</p><p><b>  {</b></p><p>  //判斷交點是不是在該兩條線段上</p&g

113、t;<p>  coordinate.x = scanP1.x;</p><p>  coordinate.y = (int)(y+0.5);</p><p>  return true;</p><p><b>  }</b></p><p>  return false;</p><

114、p><b>  }</b></p><p><b>  else</b></p><p><b>  {</b></p><p>  //兩條線段斜率都存在時的處理辦法</p><p>  double k1,k2;</p><p>  k1 =

115、( objectP1.y - objectP2.y ) * 1.0 / ( objectP1.x - objectP2.x);</p><p>  k2 = ( scanP1.y - scanP2.y ) * 1.0 / ( scanP1.x - scanP2.x );</p><p>  //k1,k2為計算的兩線段的斜率</p><p>  double x,y

116、;</p><p>  x = (scanP1.y-objectP1.y-k2*scanP1.x+k1*objectP1.x)/(k1-k2);</p><p>  y = (k1*k2*scanP1.x-k1*k2*objectP1.x+k2*objectP1.y-k1*scanP1.y)/(k2-k1);</p><p>  x=(float)((int)(x+

117、0.5));</p><p>  y = (float)((int)(y+0.5));</p><p>  if(((objectP1.y-y)*(y-objectP2.y)>=0) && ((objectP1.x-x)*(x-objectP2.x)>=0))</p><p><b>  {</b></p>

118、;<p>  //判斷交點是不是在該兩條線段上</p><p>  coordinate.x = (int)(x+0.5);</p><p>  coordinate.y = (int)(y+0.5);</p><p>  return true;</p><p><b>  }</b></p>

119、<p>  return false;</p><p><b>  }</b></p><p><b>  }</b></p><p>  return true;</p><p><b>  }</b></p><p><b>

120、  11、冒泡排序函數(shù)</b></p><p>  bool CGraphics::SortArray(int* iArray,int iLength)</p><p><b>  {</b></p><p><b>  //冒泡排序</b></p><p>  int i,j,iTem

121、p;</p><p>  bool bFlag;</p><p>  for(i=0;i<iLength;i++)</p><p><b>  {</b></p><p>  bFlag=true;</p><p>  for(j=0;j<iLength-i-1;j++)</p&

122、gt;<p><b>  {</b></p><p>  if(iArray[j] > iArray[j+1])</p><p><b>  {</b></p><p>  iTemp=iArray[j];</p><p>  iArray[j]=iArray[j+1];<

123、/p><p>  iArray[j+1]=iTemp;</p><p>  bFlag=false;</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  if(bFlag)</b></p>

124、<p><b>  break;</b></p><p><b>  }</b></p><p>  return true;</p><p><b>  }</b></p><p>  12、對多邊形裁減時,判斷線段端點是否在可視一側(cè),判斷就是直接判斷點坐標的關(guān)系

125、</p><p>  bool CGraphics::IsInSquareRgn(CRect rect,CPoint Point,int flag)</p><p><b>  {</b></p><p>  switch(flag) {</p><p><b>  case 0:</b></

126、p><p>  if(Point.y > rect.top)</p><p>  return true;</p><p><b>  else </b></p><p>  return false;</p><p><b>  break;</b></p>

127、<p><b>  case 1:</b></p><p>  if(Point.x < rect.right)</p><p>  return true;</p><p><b>  else </b></p><p>  return false;</p>&l

128、t;p><b>  break;</b></p><p><b>  case 2:</b></p><p>  if(Point.y < rect.bottom)</p><p>  return true;</p><p><b>  else </b><

129、/p><p>  return false;</p><p><b>  break;</b></p><p><b>  case 3:</b></p><p>  if(Point.x > rect.left)</p><p>  return true;</p&

130、gt;<p><b>  else </b></p><p>  return false;</p><p><b>  break;</b></p><p><b>  default:</b></p><p><b>  break;</b&g

131、t;</p><p><b>  }</b></p><p>  return true;</p><p><b>  }</b></p><p>  四、完成的成果截圖:</p><p><b>  初始化過后:</b></p><

132、p>  自定義多邊形點坐標和自定義裁剪區(qū)域:</p><p><b>  填充:</b></p><p><b>  五、體會</b></p><p>  上學期上計算機圖形學的課時就只有多邊形裁剪和填充算法聽得最認真,理解的還算可以。老師給出的這幾個題目中我最感興趣的是三維真實感圖形設計與繪制,起初我選的是這個題目

133、。我想啊,OpengGL的編程我還沒有很深地接觸過,借助做課程設計可以多學學,而且三維的做出來了多帶勁兒啊。然而,在具體做的過程中,我遇到的困難比我想象的難。我到處借書查資料學習,但是關(guān)于OpenGL的書講得都沒多詳細。做到鼠標跟蹤球?qū)崿F(xiàn)三維模型的空間旋轉(zhuǎn)時,糾結(jié)了好久,未果。于是,我轉(zhuǎn)戰(zhàn)與寢室的一個同學一起做多邊形的裁剪和填充。用MFC框架做菜單,工具欄這些做得挺順利的。在此過程中更深地了解了MFC框架。很認真地復習了上學期學的圖形學

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論