www.pudn.com > CurveEditor.rar > CurveEditorView.cpp
// CurveEditorView.cpp : implementation of the CCurveEditorView class // #include "stdafx.h" #include "CurveEditor.h" #include "CurveEditorDoc.h" #include "CurveEditorView.h" #include#include "UIStructure.h" #include "MainFrm.h" #include "Helper.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CCurveEditorView IMPLEMENT_DYNCREATE(CCurveEditorView, CView) BEGIN_MESSAGE_MAP(CCurveEditorView, CView) //{{AFX_MSG_MAP(CCurveEditorView) ON_WM_SIZE() ON_WM_LBUTTONUP() ON_WM_LBUTTONDOWN() ON_WM_SETCURSOR() ON_WM_MOUSEMOVE() ON_WM_KEYDOWN() ON_WM_KEYUP() ON_COMMAND(ID_ALWAYS_SHOW_SPLIT_POINT, OnAlwaysShowSplitPoint) ON_UPDATE_COMMAND_UI(ID_ALWAYS_SHOW_SPLIT_POINT, OnUpdateAlwaysShowSplitPoint) ON_COMMAND(ID_SHOW_TANGENT, OnShowTangent) ON_UPDATE_COMMAND_UI(ID_SHOW_TANGENT, OnUpdateShowTangent) ON_COMMAND(ID_NEW_CURVES, OnNewCurves) ON_COMMAND(ID_MOVE_INTERSECTION, OnMoveIntersection) ON_UPDATE_COMMAND_UI(ID_MOVE_INTERSECTION, OnUpdateMoveIntersection) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) ON_MESSAGE(MFR_COMMAND, OnMainFrameCommand) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CCurveEditorView construction/destruction CCurveEditorView::CCurveEditorView() { // TODO: add construction code here m_cxWnd = 0; m_nCurrentPane = 0; m_posPointCatched = NULL; m_nCurrentCurve = -1; m_rgb[0] = RGB(0,0,0); m_rgb[1] = RGB(0,0,255); alpha = 3.14/6; theta = 3.14/2.5; k=1.1; kNormal=1.3; m_bScale = false; m_bRotate = false; m_bDown = false; m_bAlwaysShowInts = false; m_bAlwaysSplitPoint =false; m_bShowTangent = false; m_bMoveIntersection = false; } CCurveEditorView::~CCurveEditorView() { } BOOL CCurveEditorView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CCurveEditorView drawing void CCurveEditorView::OnDraw(CDC* pDC) { CCurveEditorDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here pDC->BitBlt(0, 0, m_cxWnd, m_cyWnd, &m_dcMem, 0, 0, SRCCOPY); } ///////////////////////////////////////////////////////////////////////////// // CCurveEditorView printing BOOL CCurveEditorView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CCurveEditorView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CCurveEditorView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CCurveEditorView diagnostics #ifdef _DEBUG void CCurveEditorView::AssertValid() const { CView::AssertValid(); } void CCurveEditorView::Dump(CDumpContext& dc) const { CView::Dump(dc); } CCurveEditorDoc* CCurveEditorView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCurveEditorDoc))); return (CCurveEditorDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CCurveEditorView message handlers void CCurveEditorView::OnInitialUpdate() { int i; CRect rect; CMainFrame *pFrame = (CMainFrame *)AfxGetMainWnd(); CView::OnInitialUpdate(); ((CMainFrame*)::AfxGetMainWnd())->SetEditorViewHwnd(GetSafeHwnd()); CCurveEditorDoc* pDoc = GetDocument(); // CCurveEditorDoc* pDoc = (CCurveEditorDoc*)GetDocument(); pDoc->m_pObjectsTreeView = (CObjectsTree*)pFrame->GetTreeView(); pDoc->AddView(pDoc->m_pObjectsTreeView); pDoc->m_hWndObjects = pDoc->m_pObjectsTreeView->GetSafeHwnd(); ASSERT_VALID(pDoc); // get control pad hwnd m_hWndObjects = pDoc->m_hWndObjects; // Initialize the control points VECTOR vCtrl1[4], vOffset={10, 10, 10}; vCtrl1[0].x=0; vCtrl1[0].y=0; vCtrl1[0].z=0; vCtrl1[1].x=-44; vCtrl1[1].y=2; vCtrl1[1].z=36; vCtrl1[2].x=-120; vCtrl1[2].y=0; vCtrl1[2].z=67; vCtrl1[3].x=34; vCtrl1[3].y=-53; vCtrl1[3].z=99; for(i=0; i<4; i++) { pDoc->m_alstCtrlPoint[0].AddTail(vCtrl1[i]); pDoc->m_alstCtrlPoint[1].AddTail(vCtrl1[i]+vOffset); } // create off-screen buffer pDoc->SetMainViewHwnd(GetSafeHwnd()); CClientDC dc(this); m_cxScr = GetSystemMetrics(SM_CXSCREEN); m_cyScr = GetSystemMetrics(SM_CYSCREEN); m_bmp.CreateCompatibleBitmap(&dc, m_cxScr, m_cyScr); m_dcMem.CreateCompatibleDC(&dc); m_pBmpOld = m_dcMem.SelectObject(&m_bmp); DrawSplit(); DrawCurve(); DrawCube(); } void CCurveEditorView::DrawSplit() { m_dcMem.FillSolidRect(0, 0, m_cxScr, m_cxScr, RGB(230,230,255)); CPen pen(PS_SOLID, 0, RGB(255,255,255)), *pPenOld; pPenOld = m_dcMem.SelectObject(&pen); m_dcMem.MoveTo(0, m_cyWnd/2-2); m_dcMem.LineTo(m_cxWnd, m_cyWnd/2-2); m_dcMem.MoveTo(m_cxWnd/2-2, 0); m_dcMem.LineTo(m_cxWnd/2-2, m_cyWnd); m_dcMem.SelectObject(pPenOld); pen.DeleteObject(); pen.CreatePen(PS_SOLID, 0, RGB(90,90,90)); pPenOld = m_dcMem.SelectObject(&pen); m_dcMem.MoveTo(m_cxWnd/2+2, 0); m_dcMem.LineTo(m_cxWnd/2+2, m_cyWnd); m_dcMem.MoveTo(0, m_cyWnd/2+2); m_dcMem.LineTo(m_cxWnd, m_cyWnd/2+2); m_dcMem.SelectObject(pPenOld); pen.DeleteObject(); pen.CreatePen(PS_SOLID, 3, RGB(192,192,192)); pPenOld = m_dcMem.SelectObject(&pen); m_dcMem.MoveTo(0, m_cyWnd/2); m_dcMem.LineTo(m_cxWnd, m_cyWnd/2); m_dcMem.MoveTo(m_cxWnd/2, 0); m_dcMem.LineTo(m_cxWnd/2, m_cyWnd); m_dcMem.SelectObject(pPenOld); pen.DeleteObject(); pen.CreatePen(PS_SOLID, 0, RGB(0,0,255)); pPenOld = m_dcMem.SelectObject(&pen); int x, y; x=(m_nCurrentPane%2)*m_cxWnd/2; y=(m_nCurrentPane/2)*m_cyWnd/2; m_dcMem.MoveTo(x, y); m_dcMem.LineTo(x+m_cxWnd/2, y); m_dcMem.LineTo(x+m_cxWnd/2, y+m_cyWnd/2); m_dcMem.LineTo(x, y+m_cyWnd/2); m_dcMem.LineTo(x, y); m_dcMem.SelectObject(pPenOld); pen.DeleteObject(); } void CCurveEditorView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); // TODO: Add your message handler code here m_cxWnd = cx; m_cyWnd = cy; m_rectFront.left = 0; m_rectFront.top = 0; m_rectFront.right = m_cxWnd/2-2; m_rectFront.bottom = m_cyWnd/2-2; m_rectLeft.left = m_cxWnd/2+3; m_rectLeft.bottom = m_cyWnd/2-2; m_rectLeft.right = m_cxWnd; m_rectLeft.top = 0; m_rectTop.left = 0; m_rectTop.bottom = m_cyWnd; m_rectTop.top = m_cyWnd/2+3; m_rectTop.right = m_cxWnd/2-2; m_rectUser.right = m_cxWnd; m_rectUser.bottom = m_cyWnd; m_rectUser.top = m_cyWnd/2+3; m_rectUser.left = m_cxWnd/2+3; if(m_dcMem.GetSafeHdc()) { DrawSplit(); DrawCurve(); DrawCube(); } } void CCurveEditorView::DrawCurve() { VECTOR vPoint[100]; VECTOR* pvCtrlPoint; int x0, y0, x1, y1; int i, nCurveNum, count; CCurveEditorDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); POSITION position; CPen pen, *pPenOld; for(nCurveNum=0; nCurveNum<2; nCurveNum++) { // prepare pen pen.CreatePen(PS_SOLID, 0, m_rgb[nCurveNum]); pPenOld = m_dcMem.SelectObject(&pen); count = pDoc->m_alstCtrlPoint[nCurveNum].GetCount(); pvCtrlPoint = new VECTOR[count]; position = pDoc->m_alstCtrlPoint[nCurveNum].GetHeadPosition(); for(i=0; i m_alstCtrlPoint[nCurveNum].GetNext(position); // calculate curve for(i=0; i<100; i++) //Bezier(pvCtrlPoint1, &vPoint[i], 1.0/99*i); DeCasteljau(pvCtrlPoint, count, 1.0/99*i, &vPoint[i]); // Draw user view VECTOR a; VECTOR2D Pe; a.x=0; a.y=0; a.z=10; Pn.x = -sin(theta)*cos(alpha); Pn.y = -sin(theta)*sin(alpha); Pn.z = -cos(theta); Px = a%((-1)*Pn); x0 = (m_rectUser.left + m_rectUser.right)/2; y0 = (m_rectUser.top + m_rectUser.bottom)/2; Pe = k*ProjectParallel(vPoint[0], Pn, Px); m_dcMem.MoveTo(x0 + (int)Pe.x, y0 - (int)Pe.y); for(i=1; i<100; i++) { Pe = k*ProjectParallel(vPoint[i], Pn, Px); m_dcMem.LineTo(x0 + (int)Pe.x, y0 - (int)Pe.y); } for(i=0; i<100; i++) vPoint[i] = kNormal*vPoint[i]; // Draw other view x0 = (m_rectFront.left + m_rectFront.right)/2; y0 = (m_rectFront.top + m_rectFront.bottom)/2; m_dcMem.MoveTo((int)(x0+vPoint[0].y), (int)(y0-vPoint[0].z)); for(i=1; i<100; i++) m_dcMem.LineTo((int)(x0+vPoint[i].y), (int)(y0-vPoint[i].z)); if(m_nCurrentPane == 0) for(i=0; i *plstCtrlPoint; VECTOR *pvPoint, *pvCtrl; POSITION position; CCurveEditorDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); plstCtrlPoint = pDoc->m_alstCtrlPoint; for(nCurve=0; nCurve<2; nCurve++) { n = plstCtrlPoint[nCurve].GetCount(); pT = new double[3*n]; pvCtrl = new VECTOR[3*n]; pvPoint = new VECTOR[3*n]; // fill control point array position = plstCtrlPoint[nCurve].GetHeadPosition(); for(i=0; i m_alstCtrlPoint[nCurveNum].GetHeadPosition(); m_posPointCatched = NULL; if(m_nCurrentPane == 0) { x0 = (m_rectFront.left + m_rectFront.right)/2; y0 = (m_rectFront.top + m_rectFront.bottom)/2; do{ posOld = position; vector = pDoc->m_alstCtrlPoint[nCurveNum].GetNext(position); x1 = x0 + (int)(kNormal*vector.y); y1 = y0 - (int)(kNormal*vector.z); if(abs(x1 - point.x)<4 && abs(y1 - point.y)<4) { m_posPointCatched = posOld; m_vCtrlPointOld = vector; bFind = true; break; } }while(position); } else if(m_nCurrentPane == 1) { x0 = (m_rectLeft.left + m_rectLeft.right)/2; y0 = (m_rectLeft.top + m_rectLeft.bottom)/2; do{ posOld = position; vector = pDoc->m_alstCtrlPoint[nCurveNum].GetNext(position); x1 = x0 + (int)(kNormal*vector.x); y1 = y0 - (int)(kNormal*vector.z); if(abs(x1 - point.x)<4 && abs(y1 - point.y)<4) { m_posPointCatched = posOld; m_vCtrlPointOld = vector; bFind = true; break; } }while(position); } else if(m_nCurrentPane == 2) { x0 = (m_rectTop.left + m_rectTop.right)/2; y0 = (m_rectTop.top + m_rectTop.bottom)/2; do{ posOld = position; vector = pDoc->m_alstCtrlPoint[nCurveNum].GetNext(position); x1 = x0 + (int)(kNormal*vector.y); y1 = y0 + (int)(kNormal*vector.x); if(abs(x1 - point.x)<4 && abs(y1 - point.y)<4) { m_posPointCatched = posOld; m_vCtrlPointOld = vector; bFind = true; break; } }while(position); } } if(bFind) { m_nCurrentCurve = nCurveNum; break; } } } void CCurveEditorView::OnMouseMove(UINT nFlags, CPoint point) { VECTOR vector; if(m_nCurrentPane==WhichPane(m_pointDown) && m_bDown) { // user pane if(m_nCurrentPane==3) { if(m_bScale) { k = kOld*(1+ (point.y - m_pointDown.y)/100.0); if(k<0.001)k=0.001; DrawAll(); } else if(m_bRotate) { alpha = alphaOld+ (m_pointDown.x - point.x )/100.0; theta = thetaOld+ (m_pointDown.y - point.y)/100.0; if(theta<3.14/5)theta=3.14/5; else if(theta>3.14*0.8)theta=3.14*0.8; DrawAll(); } } // other pane else { // scale function if(m_bScale) { kNormal = kNormalOld*(1+ (+ point.y - m_pointDown.y)/100.0); DrawAll(); } // other function else if(m_posPointCatched) { CCurveEditorDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // move the current curve's control point switch(m_nCurrentPane) { case 0: vector.x = m_vCtrlPointOld.x; vector.y = m_vCtrlPointOld.y + (point.x - m_pointDown.x)/kNormal; vector.z = m_vCtrlPointOld.z + (m_pointDown.y - point.y)/kNormal; break; case 1: vector.x = m_vCtrlPointOld.x + (point.x - m_pointDown.x)/kNormal; vector.y = m_vCtrlPointOld.y; vector.z = m_vCtrlPointOld.z + (m_pointDown.y - point.y)/kNormal; break; case 2: vector.x = m_vCtrlPointOld.x + (point.y - m_pointDown.y)/kNormal; vector.y = m_vCtrlPointOld.y + (point.x - m_pointDown.x)/kNormal; vector.z = m_vCtrlPointOld.z; default: break; } pDoc->m_alstCtrlPoint[m_nCurrentCurve].SetAt(m_posPointCatched, vector); // the message format: wParam=function No., lParam=curve No. POINTCHANGED pc; pc.nCurveNum = m_nCurrentCurve; pc.position = m_posPointCatched; ::SendMessage(m_hWndObjects, CEV_NOTIFY_MESSAGE, CEVN_UPDATE_CURVE, (LPARAM)&pc); DrawAll(); } } RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } else if(m_bShowTangent) { CCurveEditorDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); POSITION position; int nCount, i; int x0, y0; double t; VECTOR *pvCtrl, vPoint, vTangent; nCount = pDoc->m_alstCtrlPoint[0].GetCount(); pvCtrl = new VECTOR[nCount]; position = pDoc->m_alstCtrlPoint[0].GetHeadPosition(); for(i=0; i m_alstCtrlPoint[0].GetNext(position); t = (point.x - 50)/300.0; if(t<0)t=0; if(t>1.0) t=1.0; DeCasteljau(pvCtrl, nCount, t, &vPoint); BezierTangent(pvCtrl, nCount, t, &vTangent); DrawAll(); // Front view x0 = (m_rectFront.left + m_rectFront.right)/2; y0 = (m_rectFront.top + m_rectFront.bottom)/2; vPoint = kNormal*vPoint; vTangent = kNormal*vTangent; m_dcMem.MoveTo((int)(x0+vPoint.y), (int)(y0-vPoint.z)); vTangent = (500.0/Module(vTangent))*vTangent; vTangent = vTangent + vPoint; m_dcMem.LineTo((int)(x0+vTangent.y), (int)(y0-vTangent.z)); RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); delete[] pvCtrl; } if(m_bMoveIntersection) ChangeCurve(point); m_pointMouse = point; CView::OnMouseMove(nFlags, point); } void CCurveEditorView::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if(WhichPane(point) == WhichPane(m_pointDown)) m_nCurrentPane = WhichPane(point); DrawAll(); //m_dcMem.FillSolidRect(m_nCurrentPane==0?&m_rectFront: //(m_nCurrentPane==1?&m_rectLeft:(m_nCurrentPane==2?&m_rectTop:&m_rectUser)), // RGB(0,255,255)); RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); m_bDown = false; CView::OnLButtonUp(nFlags, point); } BOOL CCurveEditorView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { // TODO: Add your message handler code here and/or call default if(m_nCurrentPane==WhichPane(m_pointMouse)) { if(m_bScale) { SetCursor(AfxGetApp()->LoadCursor(IDC_VIEW_SCALE)); return 1; } else if(m_bRotate) { SetCursor(AfxGetApp()->LoadCursor(IDC_VIEW_ROTATE)); return 1; } } return CView::OnSetCursor(pWnd, nHitTest, message); } void CCurveEditorView::DrawAll() { // CString str; // str.Format("k=%f, kNormal=%f, alpha=%f, theta=%f", // k, kNormal, alpha*18./3.14, theta*180/3.14); DrawSplit(); // m_dcMem.TextOut(10, 10, str); DrawCurve(); DrawCube(); if(m_bAlwaysSplitPoint)DrawSplitPoint(); } int CCurveEditorView::WhichPane(CPoint point) { int nCurrentPane=-1; if(m_rectFront.PtInRect(point)) nCurrentPane = 0; if(m_rectLeft.PtInRect(point)) nCurrentPane = 1; if(m_rectTop.PtInRect(point)) nCurrentPane = 2; if(m_rectUser.PtInRect(point)) nCurrentPane =3; return nCurrentPane; } LONG CCurveEditorView::OnMainFrameCommand(WPARAM wParam, LPARAM lParam) { switch(wParam) { case ID_ROTATE_VIEW: OnRotateView(); break; case ID_SCALE_VIEW: OnScaleView(); break; case ID_INCREASE_CURVE_ORDER: OnIncreaseCurveOrder(); break; case ID_DECREASE_CURVE_ORDER: OnDecreaseCurveOrder(); break; case ID_ALWAYS_SHOW_INTERSECTION: OnAlwaysShowIntersection(); break; default: return -1; break; } return 0; } void CCurveEditorView::OnRotateView() { if(m_bRotate) { m_bRotate = false; } else m_bRotate = true; m_bScale = false; } void CCurveEditorView::OnScaleView() { if(m_bScale) { m_bScale = false; } else m_bScale = true; m_bRotate = false; } void CCurveEditorView::OnIncreaseCurveOrder() { int i=0, nCurrentCurve; POSITION position; CCurveEditorDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); nCurrentCurve = pDoc->m_nCurrentCurve; int count = pDoc->m_alstCtrlPoint[nCurrentCurve].GetCount(); VECTOR *pvOld, *pvNew; pvOld = new VECTOR[count]; pvNew = new VECTOR[count+1]; position = pDoc->m_alstCtrlPoint[nCurrentCurve].GetHeadPosition(); while(position) pvOld[i++] = pDoc->m_alstCtrlPoint[nCurrentCurve].GetNext(position); BezierIncreaseOrder(pvOld, pvNew, count); position = pDoc->m_alstCtrlPoint[nCurrentCurve].GetHeadPosition(); i=0; while(position) { pDoc->m_alstCtrlPoint[nCurrentCurve].SetAt(position, pvNew[i++]); pDoc->m_alstCtrlPoint[nCurrentCurve].GetNext(position); } pDoc->m_alstCtrlPoint[nCurrentCurve].AddTail(pvNew[count]); delete[] pvOld; delete[] pvNew; ::SendMessage(m_hWndObjects, CEV_NOTIFY_MESSAGE, CEVN_CTRL_POINT_INCREASED, nCurrentCurve); DrawAll(); RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } void CCurveEditorView::OnDecreaseCurveOrder() { } void CCurveEditorView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default if(nChar==VK_ESCAPE) m_bMoveIntersection = false; if(nChar==VK_ESCAPE && !m_bDown) { m_bScale = m_bRotate = false; ((CMainFrame*)AfxGetMainWnd())->EscapeFunction(); } if(nChar==VK_CONTROL && !m_bDown) { m_bScale = false; m_bRotate = true; } CView::OnKeyDown(nChar, nRepCnt, nFlags); } void CCurveEditorView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { if(nChar==VK_CONTROL) { m_bRotate = false; } CView::OnKeyUp(nChar, nRepCnt, nFlags); } void CCurveEditorView::OnAlwaysShowIntersection() { // m_bAlwaysShowInts = !m_bAlwaysShowInts; } void CCurveEditorView::OnAlwaysShowSplitPoint() { m_bAlwaysSplitPoint = !m_bAlwaysSplitPoint; } void CCurveEditorView::OnUpdateAlwaysShowSplitPoint(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_bAlwaysSplitPoint); } void CCurveEditorView::OnShowTangent() { m_bMoveIntersection = false; m_bShowTangent = !m_bShowTangent; } void CCurveEditorView::OnUpdateShowTangent(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_bShowTangent); } void CCurveEditorView::OnNewCurves() { // make two curves that have one intersection point VECTOR avCtrlPoint[4], avPoint[2][4]; avPoint[0][0].x = 0; avPoint[0][0].y = -500.92; avPoint[0][0].z = -40; avPoint[0][1].x = -85.54; avPoint[0][1].y = -118; avPoint[0][1].z = -74; avPoint[0][2].x = -110; avPoint[0][2].y = 13.85; avPoint[0][2].z = 77.77; avPoint[0][3].x = 34; avPoint[0][3].y = -53; avPoint[0][3].z = 99; avPoint[1][0].x = -100.0; avPoint[1][0].y = 10.0; avPoint[1][0].z = 10.0; // avPoint[1][1].x = -144.77; // avPoint[1][1].y = 72.77; // avPoint[1][1].z = -15.54; avPoint[1][1] = avPoint[0][1]; avPoint[1][2] = avPoint[0][2]; avPoint[1][3].x = 44.0; avPoint[1][3].y = -43.00; avPoint[1][3].z = -109.0; int i, j; CCurveEditorDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); for(i=0; i<2; i++) { BezierFit(avPoint[i], 4, avCtrlPoint); pDoc->m_alstCtrlPoint[i].RemoveAll(); for(j=0; j<4; j++) pDoc->m_alstCtrlPoint[i].AddTail(avCtrlPoint[j]); } ::SendMessage(m_hWndObjects, CEV_NOTIFY_MESSAGE, CEVN_NEW_CURVE, 0); DrawAll(); RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } void CCurveEditorView::OnMoveIntersection() { m_bShowTangent = false; m_bMoveIntersection = ! m_bMoveIntersection; } void CCurveEditorView::OnUpdateMoveIntersection(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_bMoveIntersection); } void CCurveEditorView::ChangeCurve(CPoint point) { int count, i, j; double *paT[2]; VECTOR vIntPoint; CCurveEditorDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // make two curves that have two intersection point VECTOR avCtrlPoint[2][4], avPoint[2][4]; avPoint[0][0].x = 110; avPoint[0][0].y = -500.92; avPoint[0][0].z = -40; avPoint[0][1].x = 30; avPoint[0][1].y = point.x-400; avPoint[0][1].z = point.y-310; avPoint[0][2].x = 40; avPoint[0][2].y = 13.85; avPoint[0][2].z = 77.77; avPoint[0][3].x = 30; avPoint[0][3].y = -53; avPoint[0][3].z = 99; avPoint[1][0].x = 80; avPoint[1][0].y = 10.0; avPoint[1][0].z = 10.0; // avPoint[1][1].x = -144.77; // avPoint[1][1].y = 72.77; // avPoint[1][1].z = -15.54; avPoint[1][1] = avPoint[0][1]; avPoint[1][2] = avPoint[0][2]; avPoint[1][3].x = 0; avPoint[1][3].y = -43.00; avPoint[1][3].z = -109.0; for(i=0; i<2; i++) { BezierFit(avPoint[i], 4, avCtrlPoint[i]); pDoc->m_alstCtrlPoint[i].RemoveAll(); for(j=0; j<4; j++) pDoc->m_alstCtrlPoint[i].AddTail(avCtrlPoint[i][j]); } ::SendMessage(m_hWndObjects, CEV_NOTIFY_MESSAGE, CEVN_NEW_CURVE, 0); DrawAll(); paT[0] = new double[16]; paT[1] = new double[16]; ASSERT(paT[0] && paT[1]); count = Intersection(avCtrlPoint[0], 4, avCtrlPoint[1], 4, paT[0], paT[1], 16); CString str; str.Format("count = %d, x = %d, y = %d", count, point.x, point.y); m_dcMem.TextOut(10, 10, str); int x0, y0, x1, y1; x0 = (m_rectFront.left + m_rectFront.right)/2; y0 = (m_rectFront.top + m_rectFront.bottom)/2; for(i=0; i<2; i++) for(j=0; j