二维图形变换
1.了解不同的二维坐标变换公式。
2.掌握二维坐标变换公式的使用方法。
3.掌握二维图形的基本几何变换:平移、旋转和缩放。
1.在屏幕上绘制出较简单的几何图形。
2.对1的图形进行平移变换(每次平移一个单位),绘制出变换后的几何图形。
3.对1的图形进行旋转变换(每次旋转角度为3.14/36),绘制出变换后的几何图形。
4.对1的图形进行比例变换(横纵坐标变换比例为0.5或2),绘制出变换后的几何图形。
1. 编辑一个资源,并为其映射一个类cgTransControl。
2. 在Doc下,定义空间变换矩阵
float m_LineTransMatria【3】【2】;
float m_PolyTransMatria【3】【2】.
3. 定义一条空间线段和一个空间多边形,本例为三角形。
4. 二维图形变换主要是基于齐次坐标方程,通过一些简单的矩阵运算来实现:
矩阵的每个元素都有特殊含义。其中可以对图形进行缩放,旋转等变换;是对图形进行平移变换;
则是对图形整体进行缩放变换.
5. 平移变换:
将一个图形在X方向中平移tx个单位,在Y方向平移ty个单位.其实现过程如下:
其中:x1,y1是变换后的坐标,x,y是变换前的坐标,通过上述变换,(x,y)被平移了P(tx,ty). 在二维平面上任何复杂的变换都可以通过上述基本变换的组合来实现.在计算机上主要体现在矩阵的乘法运算,即将各个简单变换的矩阵逆序相乘,就可以得到一个总的变换矩阵.利用这个总的变换矩阵就可以对图形进行复合变换.
6. 旋转变化:
7. 放缩变换:
void CCg_WuPing2DtransView::pDrawScene(CDC* pDC) { CCg_WuPing2DtransDoc* pDoc = GetDocument(); // Draw coordinate pDC->MoveTo(m_wndWidth/2, 0); pDC->LineTo(m_wndWidth/2, m_wndHeight); pDC->MoveTo( 0, m_wndHeight/2); pDC->LineTo(m_wndWidth, m_wndHeight/2); if (pDoc->m_objSelect < 2) pCalTransMatrix(); // Line Object trans and clip float tx1,ty1,tx2,ty2; int itx1,ity1,itx2,ity2; tx1 = pDoc->x1; ty1 = pDoc->y1; tx2 = pDoc->x2; ty2 = pDoc->y2; pTrans2Dpoint(&tx1, &ty1); pTrans2Dpoint(&tx2, &ty2); pDC->MoveTo(m_wndWidth/2+tx1, m_wndHeight/2-ty1); pDC->LineTo(m_wndWidth/2+tx2, m_wndHeight/2-ty2); pDoc->m_lineVisible = false; itx1 = tx1; itx2 = tx2; ity1 = ty1; ity2 = ty2; if (ClipLine(&itx1, &ity1, &itx2, &ity2)) { CPen newPen; CPen *oldPen; // Create new color pen to Draw Clipping Line newPen.CreatePen(PS_SOLID, 2, RGB(255, 250, 0)); oldPen = (CPen *)pDC->SelectObject(&newPen); pDC->MoveTo(itx1+m_wndWidth/2, m_wndHeight/2-ity1); pDC->LineTo(itx2+m_wndWidth/2, m_wndHeight/2-ity2); pDC->SelectObject(oldPen); newPen.DeleteObject(); pDoc->cx1 = itx1; pDoc->cx2 = itx2; pDoc->cy1 = ity1; pDoc->cy2 = ity2; pDoc->m_lineVisible = true; } // polygon Object trans and clip float tx[16],ty[16]; for (int i = 0; i < pDoc->m_polyPoints; i++) { tx[i] = pDoc->m_polyPointsX[i]; ty[i] = pDoc->m_polyPointsY[i]; } pTrans2Dpoints(pDoc->m_polyPoints, tx, ty); pDC->MoveTo(m_wndWidth/2+tx[0], m_wndHeight/2-ty[0]); for (i = 1; i < pDoc->m_polyPoints; i++) pDC->LineTo(m_wndWidth/2+tx[i], m_wndHeight/2-ty[i]); pDoc->m_polyVisible = false; int points = pDoc->m_polyPoints,xx[16],yy[16],cn,cx[16],cy[16]; for (i = 0; i < pDoc->m_polyPoints; i++) { xx[i] = tx[i]; yy[i] = ty[i]; } if (ClipPolygon(pDoc->m_polyPoints, xx, yy, &cn, cx, cy)) { CPen newPen; CPen *oldPen; // Create new color pen to Draw Clipping Line newPen.CreatePen(PS_SOLID, 2, RGB(255, 0, 0)); oldPen = (CPen *)pDC->SelectObject(&newPen); pDC->MoveTo(cx[0]+m_wndWidth/2, m_wndHeight/2-cy[0]); for (i = 0; i < cn; i++) pDC->LineTo(cx[i]+m_wndWidth/2, m_wndHeight/2-cy[i]); pDC->LineTo(cx[0]+m_wndWidth/2, m_wndHeight/2-cy[0]); pDC->SelectObject(oldPen); newPen.DeleteObject(); pDoc->m_clipPolyPoints = cn; for (i = 0; i < cn; i++ ) { pDoc->m_polyClipPointsX[i] = cx[i]; pDoc->m_polyClipPointsY[i] = cy[i]; } pDoc->m_polyVisible = true; } pDC->MoveTo(m_wndWidth/2+pDoc->m_wndRectangle[0], m_wndHeight/2-pDoc->m_wndRectangle[3]); pDC->LineTo(m_wndWidth/2+pDoc->m_wndRectangle[1], m_wndHeight/2-pDoc->m_wndRectangle[3]); pDC->LineTo(m_wndWidth/2+pDoc->m_wndRectangle[1], m_wndHeight/2-pDoc->m_wndRectangle[2]); pDC->LineTo(m_wndWidth/2+pDoc->m_wndRectangle[0], m_wndHeight/2-pDoc->m_wndRectangle[2]); pDC->LineTo(m_wndWidth/2+pDoc->m_wndRectangle[0], m_wndHeight/2-pDoc->m_wndRectangle[3]); // Tell CgTransControl the process finish now. pDoc->UpdateAllViews(this); }
void CCg_WuPing2DtransView::pCalTransMatrix() { CCg_WuPing2DtransDoc* pDoc = GetDocument(); switch (pDoc->m_transDir) { case 0: // -X if (pDoc->m_transMode == 0) pCal2DTranslateMatrix(-10.0, 0.0); else if (pDoc->m_transMode == 1) pCal2DRotateMatrix(sin(3.14/36), cos(3.14/36)); else pCal2DScaleMatrix(0.5, 1.0); break; case 1: // +X if (pDoc->m_transMode == 0) pCal2DTranslateMatrix(10.0, 0.0); else if (pDoc->m_transMode == 1) pCal2DRotateMatrix(-sin(3.14/36), cos(3.14/36)); else pCal2DScaleMatrix(2.0, 1.0); break; case 2: // +Y if (pDoc->m_transMode == 0) pCal2DTranslateMatrix(0.0, +10.0); else if (pDoc->m_transMode == 1) pCal2DRotateMatrix(-sin(3.14/36), cos(3.14/36)); else pCal2DScaleMatrix(2.0, 1.0); break; case 3: // -Y if (pDoc->m_transMode == 0) pCal2DTranslateMatrix(0.0, -10.0); else if (pDoc->m_transMode == 1) pCal2DRotateMatrix(sin(3.14/36), cos(3.14/36)); else pCal2DScaleMatrix(0.5, 1.0); break; } }
void CCg_WuPing2DtransView::pCal2DTranslateMatrix(float Tx, float Ty)//平移变换 { CCg_WuPing2DtransDoc * pDoc = (CCg_WuPing2DtransDoc*)GetDocument(); if(pDoc ->m_objSelect == 0) { pDoc->m_lineTransMatrix[2][0] = pDoc ->m_lineTransMatrix[2][0] + Tx; pDoc ->m_lineTransMatrix[2][1] = pDoc ->m_lineTransMatrix[2][1] + Ty; } if(pDoc ->m_objSelect == 1) { pDoc->m_polyTransMatrix[2][0] = pDoc->m_polyTransMatrix[2][0] + Tx; pDoc->m_polyTransMatrix[2][1] = pDoc->m_polyTransMatrix[2][1] + Ty; } }
void CCg_WuPing2DtransView::pCal2DRotateMatrix(float S, float C)//旋转变换 { CCg_WuPing2DtransDoc* pDoc = (CCg_WuPing2DtransDoc*)GetDocument(); if(pDoc ->m_objSelect == 0) { float temp1,temp2; temp1 = pDoc ->m_lineTransMatrix[0][0]; temp2 = pDoc ->m_lineTransMatrix[1][0]; pDoc ->m_lineTransMatrix[0][0] = pDoc ->m_lineTransMatrix[0][0]*C-pDoc ->m_lineTransMatrix[0][1]*S; pDoc ->m_lineTransMatrix[0][1] = temp1*S + pDoc ->m_lineTransMatrix[0][1]*C; pDoc ->m_lineTransMatrix[1][0] = pDoc ->m_lineTransMatrix[1][0]*C-pDoc ->m_lineTransMatrix[1][1]*S; pDoc ->m_lineTransMatrix[1][1] = temp2*S+pDoc ->m_lineTransMatrix[1][1]*C; } if(pDoc ->m_objSelect == 1) { float temp1,temp2; temp1 = pDoc ->m_polyTransMatrix[0][0]; temp2 = pDoc ->m_polyTransMatrix[1][0]; pDoc ->m_polyTransMatrix[0][0] = pDoc ->m_polyTransMatrix[0][0]*C-pDoc ->m_polyTransMatrix[0][1]*S; pDoc ->m_polyTransMatrix[0][1] = temp1*S + pDoc ->m_polyTransMatrix[0][1]*C; pDoc ->m_polyTransMatrix[1][0] = pDoc ->m_polyTransMatrix[1][0]*C-pDoc ->m_polyTransMatrix[1][1]*S; pDoc ->m_polyTransMatrix[1][1] = temp2*S+pDoc ->m_polyTransMatrix[1][1]*C; } }
void CCg_WuPing2DtransView::pCal2DScaleMatrix(float Sx, float Sy)// 比例变换 { CCg_WuPing2DtransDoc* pDoc = (CCg_WuPing2DtransDoc*)GetDocument(); if(pDoc ->m_objSelect == 0) { pDoc ->m_lineTransMatrix[0][0] = pDoc ->m_lineTransMatrix[0][0] * Sx; pDoc ->m_lineTransMatrix[1][1] = pDoc ->m_lineTransMatrix[1][1] * Sy; } if(pDoc ->m_objSelect == 1) { pDoc ->m_polyTransMatrix[0][0] *= Sx; pDoc ->m_polyTransMatrix[1][1] *= Sy; } }
调用以下函数:
void CCg_WuPing2DtransView::OnTimer(UINT nIDEvent) void CCg_WuPing2DtransView::OnOutoplay() void CCg_WuPing2DtransView::OnUpdateOutoplay(CCmdUI* pCmdUI)