#include "StdAfx.h" #include "itemcurvearc.h" #include "SigmaDoc.h" namespace NItem { static CRect CalculateHandleRect(LPPOINT pPoint); CItemCurveArc::CItemCurveArc(CSigmaDoc * ppDoc) : CItemCurve(ppDoc) , loop(0) { m_AddLineState = ppDoc->GetEditLineStatus(); m_pArc = new CItemArc(ppDoc); m_pArc->m_bDoSelectEnd = FALSE; } CItemCurveArc::~CItemCurveArc(void) { if (m_pArc)delete m_pArc; m_pArc = NULL; } BOOL CItemCurveArc::IsArcState(void) { if (m_AddLineState != CURVE_STATE_ARC) return FALSE; return TRUE; } void CItemCurveArc::OnLButtonDown(CDC *pDC, UINT nFlags, CPoint point, int vk) { if (!IsArcState()) CItemCurve::OnLButtonDown(pDC, nFlags, point, vk); else { ClearRedoList(); m_pArc->OnLButtonDown(pDC, nFlags, point, vk); if (loop == 2) { CArc* pArc = m_pArc->CreateArc(); if (pArc == NULL) return; CCurveEx* pCurve = pArc->GetCurve(); dfPoint pt; m_dpLastMousePos.x0 = m_pArc->PointStart.x0; m_dpLastMousePos.y0 = m_pArc->PointStart.y0; for (int i = 0; i < pCurve->num; i++) { pt.x0 = pCurve->x[i]; pt.y0 = pCurve->y[i]; DrawLineScreen(m_dpLastMousePos.x0, m_dpLastMousePos.y0, pt.x0, pt.y0); AddPoint(pt); m_dpLastMousePos = pt; } delete pArc; m_pArc->PointStart = m_pArc->PointEnd; m_pArc->PointMiddle = m_pArc->PointStart; m_pArc->loop = 1; loop = 0; } loop++; } } int CItemCurveArc::OnMouseMove(CDC* pDC, UINT nFlags, CPoint point)//, BYTE*& destBuffer, int& destLen) { if (!IsArcState()) { return CItemCurve::OnMouseMove(pDC, nFlags, point);//, destBuffer, destLen); } else if (m_pArc) { if (m_pArc->loop == 1) { if (!PointList.IsEmpty()) m_pArc->PointStart = PointList.GetTail(); } m_dpLastMousePos = GetRealPoint(PointList, nFlags, point); return m_pArc->OnMouseMove(pDC, nFlags, point); } return 0; } void CItemCurveArc::OnLButtonUp(CDC *pDC, UINT nFlags, CPoint point, int vk) { } void CItemCurveArc::SetCurveState(int state, CDC * pDC) { if (m_AddLineState == state) return; CItemCurve::SetCurveState(state, pDC); if (m_AddLineState == CURVE_STATE_ARC && PointList.GetCount() > 0) { m_pArc->PointStart = PointList.GetTail(); m_pArc->PointMiddle = m_pArc->PointStart; loop = 1; m_pArc->loop = loop; } } /////////////////////////////////////////////////////////////////////////////////////////////////// CItemCurveSpline::CItemCurveSpline(CSigmaDoc * ppDoc) : CItemCurveArc(ppDoc) { m_bAuxiliarySplineRedraw = FALSE; m_nSplineNodes = 5; m_mSmoothStepFactor = 3; //SetCurveState(CURVE_STATE_SPLINE); } CItemCurveSpline::~CItemCurveSpline(void) { } void CItemCurveSpline::OnDraw(CXyDC* pDC) { if (PointList.GetCount() > 0) { int od = pDC->GetDC()->SetROP2(R2_NOTXORPEN); Draw(pDC, PointList, PEN_COLOR); pDC->GetDC()->SetROP2(od); } if (IsSplineState()) { if (m_spPointList.GetCount() < 1) return; m_spPointList.AddTail(m_dpLastMousePos); DrawSpline(pDC); m_spPointList.RemoveTail(); } } void CItemCurveSpline::DrawSpline(CXyDC* pDC) { if (m_spPointList.GetCount() <= 1) return; CDC* pdc = pDC->GetDC(); HDC hdc = pdc->m_hDC; int od = pdc->SetROP2(R2_NOTXORPEN); //画样条曲线 CPen* pOld = pdc->SelectObject(&m_pen); CPointList pl; CCurveEx ce; ce.SetPoints(m_spPointList, 2); ce.CurveToSpline(pl, pDC->GetMiniSmoothStep() * m_mSmoothStepFactor, 0); dfPoint dp; POSITION p = pl.GetHeadPosition(); dp = pl.GetNext(p); CPoint pt1 = pDC->GetScreen(dp.x0, dp.y0); CPoint pt2; POINT prePt; while (p) { dp = pl.GetNext(p); pt2 = pDC->GetScreen(dp.x0, dp.y0); ::MoveToEx(hdc, pt1.x, pt1.y, &prePt); ::LineTo(hdc, pt2.x, pt2.y); pt1 = pt2; } /* ce.SetPoints(pl, 2); pDC->Draw(ce); */ pDC->GetDC()->SelectObject(pOld); int count = 0; CPen pen; pen.CreatePen(PS_SOLID, 2, RGB(0, 0, 255)); //pOld = (CPen*)pDC->GetDC()->SelectStockObject(BLACK_PEN); pOld = (CPen*)pdc->SelectObject(&pen); CRect rt; POINT sp; dfPoint dt; POSITION pos = m_spPointList.GetHeadPosition(); while (pos) { dp = m_spPointList.GetNext(pos); if (count > 0) { if (fabs(dt.x0 - dp.x0) < 1e-3 && //是否是重复点 fabs(dt.y0 - dp.y0) < 1e-3) continue; } sp = pDC->GetScreen(dp.x0, dp.y0); rt = CalculateHandleRect(&sp); rt.InflateRect(1, 1); pDC->GetDC()->Ellipse(&rt); dt = dp; count++; } pDC->GetDC()->SelectObject(pOld); pDC->GetDC()->SetROP2(od); } void CItemCurveSpline::DrawSplineTail(CXyDC * pDC) { if (m_spCalcPointList.GetCount() <= 1) return; CDC* pdc = pDC->GetDC(); HDC hdc = pdc->m_hDC; int od = pdc->SetROP2(R2_NOTXORPEN); //画样条曲线 CPen* pOld = pdc->SelectObject(&m_pen); CPointList pl; CCurveEx ce; ce.SetPoints(m_spCalcPointList, 2); ce.CurveToSpline(pl, pDC->GetMiniSmoothStep() * m_mSmoothStepFactor, 0); dfPoint dp; POSITION p = pl.GetHeadPosition(); if (p == NULL) { return; } dp = pl.GetNext(p); CPoint pt1 = pDC->GetScreen(dp.x0, dp.y0); CPoint pt2; POINT prePt; while (p) { dp = pl.GetNext(p); pt2 = pDC->GetScreen(dp.x0, dp.y0); ::MoveToEx(hdc, pt1.x, pt1.y, &prePt); ::LineTo(hdc, pt2.x, pt2.y); pt1 = pt2; } pdc->SelectObject(pOld); int count = 0; CPen pen; pen.CreatePen(PS_SOLID, 2, RGB(0, 0, 255));//画节点圆圈 //pOld = (CPen*)pDC->GetDC()->SelectStockObject(BLACK_PEN); pOld = (CPen*)pdc->SelectObject(&pen); CRect rt; POINT sp; dfPoint dt; POSITION pos = m_spCalcPointList.GetHeadPosition(); while (pos) { dp = m_spCalcPointList.GetNext(pos); if (count > 0) { if (fabs(dt.x0 - dp.x0) < 1e-3 && //是否是重复点 fabs(dt.y0 - dp.y0) < 1e-3) continue; } sp = pDC->GetScreen(dp.x0, dp.y0); rt = CalculateHandleRect(&sp); rt.InflateRect(1, 1); ::Ellipse(hdc, rt.left, rt.top, rt.right, rt.bottom); //pDC->GetDC()->Ellipse(&rt); dt = dp; count++; } pdc->SelectObject(pOld); pdc->SetROP2(od); } void CItemCurveSpline::GetSplineRealPoints(CDC *pDC) { m_spPointList.AddTail(m_dpLastMousePos);//当前点加入样条节点列表中 if (m_spPointList.GetCount() > m_nSplineNodes) { CopyPreRealPoints();//保存当前样条曲线点列表 { m_spRealPointList.RemoveAll(); dfPoint dp, dps; CPointList pl; CCurveEx ce; ce.SetPoints(m_spPointList, 2); GetDC()->Create(pDC); ce.CurveToSpline(pl, GetDC()->GetMiniSmoothStep() * m_mSmoothStepFactor, 0); POSITION pos = pl.GetHeadPosition(); int end = m_spPointList.GetCount() - m_nSplineNodes; int idx = 0; while (pos) { dp = pl.GetNext(pos); dps = m_spPointList.GetAt(m_spPointList.FindIndex(idx)); if (fabs(dp.x0 - dps.x0) <= DBL_MIN || //当最后两点相等时 fabs(dp.y0 - dps.y0) <= DBL_MIN) { idx++; } if (idx <= end) { m_spRealPointList.AddTail(dp); } else { m_spRealPointList.AddTail(dp); break; } } } } } void CItemCurveSpline::RedrawSplineHead(CXyDC * pDC) { CDC* pdc = pDC->GetDC(); HDC hdc = pdc->m_hDC; int od = pdc->SetROP2(R2_NOTXORPEN); CPen* pOld = pdc->SelectObject(&m_pen); //清除前一条样条曲线的前段 if (m_spPreRealPointList.GetCount() >= 2) { dfPoint dp; POSITION p = m_spPreRealPointList.GetHeadPosition(); dp = m_spPreRealPointList.GetNext(p); CPoint pt1 = pDC->GetScreen(dp.x0, dp.y0); CPoint pt2; POINT prePt; while (p) { dp = m_spPreRealPointList.GetNext(p); pt2 = pDC->GetScreen(dp.x0, dp.y0); ::MoveToEx(hdc, pt1.x, pt1.y, &prePt); ::LineTo(hdc, pt2.x, pt2.y); pt1 = pt2; } } //画新的样条曲线的前段 if (m_spRealPointList.GetCount() >= 2) { dfPoint dp; POSITION p = m_spRealPointList.GetHeadPosition(); dp = m_spRealPointList.GetNext(p); CPoint pt1 = pDC->GetScreen(dp.x0, dp.y0); CPoint pt2; POINT prePt; while (p) { dp = m_spRealPointList.GetNext(p); pt2 = pDC->GetScreen(dp.x0, dp.y0); ::MoveToEx(hdc, pt1.x, pt1.y, &prePt); ::LineTo(hdc, pt2.x, pt2.y); pt1 = pt2; } } //不画节点圆圈 /* pdc->SelectObject(pOld); int count = 0; CPen pen; pen.CreatePen(PS_SOLID, 2, RGB(0, 0, 255)); //pOld = (CPen*)pDC->GetDC()->SelectStockObject(BLACK_PEN); pOld = (CPen*)pdc->SelectObject(&pen); CRect rt; POINT sp; dfPoint dt; POSITION pos = m_spPointList.GetHeadPosition(); dfPoint dp; while (pos) { dp = m_spPointList.GetNext(pos); if (count > 0) { if (fabs(dt.x0 - dp.x0) < 1e-3 && //是否是重复点 fabs(dt.y0 - dp.y0) < 1e-3) continue; } sp = pDC->GetScreen(dp.x0, dp.y0); rt = CalculateHandleRect(&sp); rt.InflateRect(1, 1); pdc->Ellipse(&rt); dt = dp; count++; } */ pdc->SelectObject(pOld); pdc->SetROP2(od); } void CItemCurveSpline::DrawSplineBody(CXyDC * pDC) { CDC* pdc = pDC->GetDC(); HDC hdc = pdc->m_hDC; int od = pdc->SetROP2(R2_NOTXORPEN); CPen* pOld = pdc->SelectObject(&m_pen); //画新的样条曲线的前段 if (m_spRealPointList.GetCount() >= 2) { dfPoint dp; POSITION p = m_spRealPointList.GetHeadPosition(); dp = m_spRealPointList.GetNext(p); CPoint pt1 = pDC->GetScreen(dp.x0, dp.y0); CPoint pt2; POINT prePt; while (p) { dp = m_spRealPointList.GetNext(p); pt2 = pDC->GetScreen(dp.x0, dp.y0); ::MoveToEx(hdc, pt1.x, pt1.y, &prePt); ::LineTo(hdc, pt2.x, pt2.y); pt1 = pt2; } } pdc->SelectObject(pOld); pdc->SetROP2(od); } void CItemCurveSpline::GetHeadRealPoints(CXyDC* pDC) { if (m_spCalcPointList.GetCount() <= 1) return; m_spHeadRealPointList.RemoveAll();//绘制样条曲线时,获取样条曲线首段实际点序列 //画样条曲线 CPointList pl; CCurveEx ce; ce.SetPoints(m_spCalcPointList, 2); ce.CurveToSpline(pl, pDC->GetMiniSmoothStep() * m_mSmoothStepFactor, 0); dfPoint dp; dfPoint dpEnd; bool bGetHeadRealPoints = false; if (m_spCalcPointList.GetCount() == m_nSplineNodes + 1) { dpEnd = m_spCalcPointList.GetAt(m_spCalcPointList.FindIndex(1));//获取节点中的第二个点 } POSITION p = pl.GetHeadPosition(); while (p) { dp = pl.GetNext(p); if (fabs(dp.x0 - dpEnd.x0) <= DBL_MIN && (dp.y0 - dpEnd.y0) <= DBL_MIN) { m_spHeadRealPointList.AddTail(dp); break; } else { m_spHeadRealPointList.AddTail(dp); } } } void CItemCurveSpline::DrawHeadRealPoints(CXyDC * pDC) { if (m_spHeadRealPointList.GetCount() <= 1) return; CDC* pdc = pDC->GetDC(); HDC hdc = pdc->m_hDC; int od = pdc->SetROP2(R2_NOTXORPEN); //画样条曲线 CPen* pOld = pdc->SelectObject(&m_pen); dfPoint dp; POSITION p = m_spHeadRealPointList.GetHeadPosition(); if (p == NULL) { return; } dp = m_spHeadRealPointList.GetNext(p); CPoint pt1 = pDC->GetScreen(dp.x0, dp.y0); CPoint pt2; POINT prePt; while (p) { dp = m_spHeadRealPointList.GetNext(p); pt2 = pDC->GetScreen(dp.x0, dp.y0); ::MoveToEx(hdc, pt1.x, pt1.y, &prePt); ::LineTo(hdc, pt2.x, pt2.y); pt1 = pt2; } pDC->GetDC()->SelectObject(pOld); pDC->GetDC()->SetROP2(od); } void CItemCurveSpline::OnLButtonDown(CDC *pDC, UINT nFlags, CPoint point, int vk) { if (!IsSplineState()) CItemCurveArc::OnLButtonDown(pDC, nFlags, point, vk); else { ClearRedoList(); dfPoint dp = GetRealPoint(m_spPointList, nFlags, point); if (m_spPointList.GetCount() == 0)//样条曲线节点列表为空,只有首段曲线就是样条曲线的情况下 { m_spHeadRealPointList.RemoveAll(); m_spCalcPointList.RemoveAll(); m_spRealPointList.RemoveAll(); m_spPointList.AddTail(dp);//当前点加入样条桩点列表中 } else if (m_spPointList.GetCount() > 0)//样条曲线节点不为空,首段曲线不是样条曲线、自动把曲线尾点当样条曲线首节点 { dfPoint dt = m_spPointList.GetTail(); if (fabs(dt.x0 - m_dpLastMousePos.x0) > DBL_MIN || //当最后两点不相等时 fabs(dt.y0 - m_dpLastMousePos.y0) > DBL_MIN) { GetSplineRealPoints(pDC); } } m_bStretchStart = TRUE; m_bAuxiliarySplineRedraw = FALSE; //鼠标移动的最后位置和点击的位置可能不是一个位置,样条曲线绘制的时候只取鼠标移动的最后位置 //m_dpLastMousePos = dp;//鼠标最后位置 } } void CItemCurveSpline::CopyPreRealPoints() { m_spPreRealPointList.RemoveAll(); dfPoint dp; POSITION pos = m_spRealPointList.GetHeadPosition(); while (pos) { dp = m_spRealPointList.GetNext(pos); m_spPreRealPointList.AddTail(dp); } } void CItemCurveSpline::CopySplineHeads(int n) { m_spCalcPointList.RemoveAll(); dfPoint dp; for (int i = 0; i < n; i++) { dp = m_spPointList.GetAt(m_spPointList.FindIndex(i)); m_spCalcPointList.AddTail(dp); } } void CItemCurveSpline::CopySplineTails(int n) { m_spCalcPointList.RemoveAll(); int num = m_spPointList.GetCount(); if (0 == num) { return; } dfPoint dp; if (num <= n) { for (int i = 0; i < num; i++) { dp = m_spPointList.GetAt(m_spPointList.FindIndex(i)); m_spCalcPointList.AddTail(dp); } } else { for (int i = num - n; i < num; i++) { dp = m_spPointList.GetAt(m_spPointList.FindIndex(i)); m_spCalcPointList.AddTail(dp); } } } int CItemCurveSpline::OnMouseMove(CDC* pDC, UINT nFlags, CPoint point) { m_pScreenDC = pDC; /*if(!IsSplineState()) CItemCurveArc::OnMouseMove(pDC, nFlags, point, destBuffer, destLen); else {*/ if (m_spPointList.GetCount() == 0) { return 1; } if (m_spPointList.GetCount() == 1)//样条曲线节点只有一个 { dfPoint dp = GetRealPoint(m_spPointList, nFlags, point);//当为正交90状态时,需要计算新点位置 GetDC()->Create(pDC); if (m_bAuxiliarySplineRedraw) { EraseAuxiliarySpline(pDC); m_dpLastMousePos = dp; TRACE("M:m_dpLastMousePos:%f,%f\n", m_dpLastMousePos.x0, m_dpLastMousePos.y0); CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); DrawSplineTail(GetDC()); m_bStretchStart = FALSE; m_bAuxiliarySplineRedraw = FALSE; return 1; } if (!m_bStretchStart) { CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); DrawSplineTail(GetDC());//记录的实际点坐标,用xyDC绘制 } m_dpLastMousePos = dp; TRACE("M:m_dpLastMousePos:%f,%f\n", m_dpLastMousePos.x0, m_dpLastMousePos.y0); CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); DrawSplineTail(GetDC()); m_bStretchStart = FALSE; m_bAuxiliarySplineRedraw = FALSE; } if (m_spPointList.GetCount() >= 2 && m_spPointList.GetCount() <= m_nSplineNodes) //样条曲线节点数量在2到3 { dfPoint dp = GetRealPoint(m_spPointList, nFlags, point);//当为正交90状态时,需要计算新点位置 GetDC()->Create(pDC); if (m_bAuxiliarySplineRedraw) { EraseAuxiliarySpline(pDC); m_dpLastMousePos = dp; TRACE("M:m_dpLastMousePos:%f,%f\n", m_dpLastMousePos.x0, m_dpLastMousePos.y0); CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); DrawSplineTail(GetDC()); m_bStretchStart = FALSE; m_bAuxiliarySplineRedraw = FALSE; return 1; } if (!m_bStretchStart) { CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); DrawSplineTail(GetDC());//记录的实际点坐标,因此要做xyDC绘制 } else {//第一条橡皮筋线 CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); DrawSplineTail(GetDC());//擦除原来的最一后一段样条曲线 } m_dpLastMousePos = dp; TRACE("M:m_dpLastMousePos:%f,%f\n", m_dpLastMousePos.x0, m_dpLastMousePos.y0); CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); DrawSplineTail(GetDC()); m_bStretchStart = FALSE; m_bAuxiliarySplineRedraw = FALSE; } if (m_spPointList.GetCount() > m_nSplineNodes)//样条曲线节点大于 { dfPoint dp = GetRealPoint(m_spPointList, nFlags, point);//当为正交90状态时,需要计算新点位置 GetDC()->Create(pDC); if (m_bAuxiliarySplineRedraw) { EraseAuxiliarySpline(pDC); m_dpLastMousePos = dp; TRACE("M:m_dpLastMousePos:%f,%f\n", m_dpLastMousePos.x0, m_dpLastMousePos.y0); CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); DrawSplineTail(GetDC()); m_bStretchStart = FALSE; m_bAuxiliarySplineRedraw = FALSE; return 1; } if (!m_bStretchStart) { CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); DrawSplineTail(GetDC());//记录的实际点坐标,因此要做xyDC绘制 } else {//第一条橡皮筋线 CopySplineTails(m_nSplineNodes + 1); DrawSplineTail(GetDC());//擦除原来的最一后一段样条曲线 RedrawSplineHead(GetDC()); //GetHeadRealPoints(GetDC()); //DrawHeadRealPoints(GetDC());//画原来样条线的前一段 } m_dpLastMousePos = dp; TRACE("M:m_dpLastMousePos:%f,%f\n", m_dpLastMousePos.x0, m_dpLastMousePos.y0); CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); DrawSplineTail(GetDC()); m_bStretchStart = FALSE; m_bAuxiliarySplineRedraw = FALSE; } //} return 1; } void CItemCurveSpline::OnLButtonUp(CDC *pDC, UINT nFlags, CPoint point, int vk) { if (!IsSplineState()) CItemCurveArc::OnLButtonUp(pDC, nFlags, point, vk); else { } } void CItemCurveSpline::SetCurveState(int state, CDC * pDC) { if (state == m_AddLineState) return;//设置状态与当前状态相同不动作 if (m_AddLineState == CURVE_STATE_SPLINE)//原来为样式绘制状态,切换到其它状态 { AppendPoint();//把样条曲线添加到曲线列表 } if (state == CURVE_STATE_SPLINE)//原来不为样式绘制状态,切换到样条状态 { m_spPointList.RemoveAll(); if (PointList.GetCount() > 0) { dfPoint dp = PointList.GetTail(); m_spPointList.AddTail(dp);//把曲线最后一个点作为样条的第一个点 if (!m_bStretchStart) { EraseRubberLine();//擦除屏幕上的橡皮筋线 CopySplineTails(m_nSplineNodes);//绘样条橡皮筋线 m_spCalcPointList.AddTail(m_dpLastMousePos); DrawSplineTail(GetDC()); m_bStretchStart = true; } } } CItemCurveArc::SetCurveState(state, pDC); } void CItemCurveSpline::AutoClose(void) { AppendPoint(); CItemCurveArc::AutoClose(); if (PointList.IsEmpty()) return; dfPoint dp = PointList.GetHead(); m_spPointList.AddTail(dp); } POSITION CItemCurveSpline::NextCurve(void) { AppendPoint(); return CItemCurve::NextCurve(); } void CItemCurveSpline::AppendPoint(void) { if (!IsSplineState()) return; int num = m_spPointList.GetCount(); if (num <= 1) return; if (num >= 2 && num <= m_nSplineNodes) { CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); CCurveEx ce; ce.SetPoints(m_spCalcPointList, 2); CPointList pl; ce.CurveToSpline(pl, GetDC()->GetMiniSmoothStep() * 3, 0); dfPoint dp; POSITION pos = pl.GetHeadPosition(); while (pos) { dp = pl.GetNext(pos); AddPoint(dp); } } else if (num > m_nSplineNodes) { dfPoint dp; POSITION pos = m_spRealPointList.GetHeadPosition(); while (pos) { dp = m_spRealPointList.GetNext(pos); AddPoint(dp); } CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); CCurveEx ce; ce.SetPoints(m_spCalcPointList, 2); CPointList pl; ce.CurveToSpline(pl, GetDC()->GetMiniSmoothStep() * 3, 0); pos = pl.GetHeadPosition(); while (pos) { dp = pl.GetNext(pos); AddPoint(dp); } } clearSplineData(); } void CItemCurveSpline::clearSplineData() { m_spPointList.RemoveAll(); m_spRealPointList.RemoveAll(); m_spHeadRealPointList.RemoveAll(); m_spCalcPointList.RemoveAll(); } BOOL CItemCurveSpline::IsSplineState(void) { if (m_AddLineState == CURVE_STATE_SPLINE) return TRUE; return FALSE; } BOOL CItemCurveSpline::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { switch (nChar) { case VK_BACK: if (IsSplineState() && m_spPointList.GetCount() > 0)//从点列表后向前删除 { RemoveTail(); //m_spPointList.RemoveTail();//移除最后一个点 if (m_spPointList.GetCount() > m_nSplineNodes)//重新计算样条曲线主体 { CopyPreRealPoints();//保存当前样条曲线点列表 { m_spRealPointList.RemoveAll(); dfPoint dp, dps; CPointList pl; CCurveEx ce; ce.SetPoints(m_spPointList, 2); GetDC()->Create(m_pScreenDC); ce.CurveToSpline(pl, GetDC()->GetMiniSmoothStep() * m_mSmoothStepFactor, 0); POSITION pos = pl.GetHeadPosition(); int end = m_spPointList.GetCount() - m_nSplineNodes; int idx = 0; while (pos) { dp = pl.GetNext(pos); dps = m_spPointList.GetAt(m_spPointList.FindIndex(idx)); if (fabs(dp.x0 - dps.x0) <= DBL_MIN || //当最后两点相等时 fabs(dp.y0 - dps.y0) <= DBL_MIN) { idx++; } if (idx <= end) { m_spRealPointList.AddTail(dp); } else { m_spRealPointList.AddTail(dp); break; } } } } return FALSE; } break; case '1': //直线 //GetView()->OnCurveStateLine(); break; case '2': //圆弧 //GetView()->OnCurveStateArc(); break; case '3': //三次样条曲线 //GetView()->OnCurveStateSpline(); break; case '9': //90度线 //GetView()->OnCurveStateAngleLine(); break; } return CItemCurve::OnKeyDown(nChar, nRepCnt, nFlags); } BOOL CItemCurveSpline::IsOnlyPointListTail(void) { if (m_spPointList.GetCount() == 1 && !PointList.IsEmpty()) { dfPoint ds = m_spPointList.GetTail(); dfPoint dp = PointList.GetTail(); if (AfxGetPublicFunction()->Distance2(ds.x0, ds.y0, dp.x0, dp.y0) <= DBL_MIN) return TRUE; } return FALSE; } void CItemCurveSpline::OnCancel(void) { clearSplineData(); m_bAuxiliarySplineRedraw = FALSE; CItemCurve::OnCancel(); } void CItemCurveSpline::RemoveTail(void) { int num = m_spPointList.GetCount(); if (0 == num) return; dfPoint dp; dfPoint tt; if (1 == num) { if (PointList.GetCount() == 0) { if (!m_bStretchStart)//已绘橡皮筋线,擦除橡皮筋线 { CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); GetDC()->Create(m_pScreenDC); DrawSplineTail(GetDC());//擦除最后的橡皮筋线 m_spPointList.RemoveAll(); } clearSplineData(); } if (PointList.GetCount() > 1) { //如果样条线前面有直线,在这里要处理 if (!m_bStretchStart)//已绘橡皮筋线,擦除橡皮筋线 { CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); GetDC()->Create(m_pScreenDC); DrawSplineTail(GetDC());//擦除最后的橡皮筋线 int count = PointList.GetCount(); if (count >= 2) { CPen* pOld = m_pScreenDC->SelectObject(&m_pen); dfPoint dp1, dp2; dp1 = PointList.GetTail(); dp2 = PointList.GetAt(PointList.FindIndex(PointList.GetCount() - 2)); CPoint pt1 = GetDC()->GetScreen(dp1.x0, dp1.y0); CPoint pt2 = GetDC()->GetScreen(dp2.x0, dp2.y0); DrawLineScreen(pt1.x, pt1.y, pt2.x, pt2.y); m_pScreenDC->SelectObject(pOld); } m_spPointList.RemoveAll(); PointList.RemoveTail(); m_spPointList.AddTail(PointList.GetTail()); CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); GetDC()->Create(m_pScreenDC); DrawSplineTail(GetDC()); } return; } else if (PointList.GetCount() == 1) { if (!m_bStretchStart)//已绘橡皮筋线,擦除橡皮筋线 { CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); GetDC()->Create(m_pScreenDC); DrawSplineTail(GetDC());//擦除最后的橡皮筋线 m_spPointList.RemoveAll(); PointList.RemoveAll(); } clearSplineData(); } return; } if (num > 1 && num <= m_nSplineNodes) { m_spRealPointList.RemoveAll(); if (!m_bStretchStart)//已绘橡皮筋线,擦除橡皮筋线 { CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); GetDC()->Create(m_pScreenDC); DrawSplineTail(GetDC()); m_spPointList.RemoveTail(); CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); GetDC()->Create(m_pScreenDC); DrawSplineTail(GetDC()); } else { CopySplineTails(m_nSplineNodes); GetDC()->Create(m_pScreenDC); DrawSplineTail(GetDC()); dp = m_spPointList.GetTail(); m_spPointList.RemoveTail(); CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(dp); GetDC()->Create(m_pScreenDC); DrawSplineTail(GetDC()); } return; } if (num > m_nSplineNodes) { if (!m_bStretchStart) { CopySplineTails(m_nSplineNodes);//清除活动SPLINE m_spCalcPointList.AddTail(m_dpLastMousePos); GetDC()->Create(m_pScreenDC); DrawSplineTail(GetDC()); m_spPointList.RemoveTail();//移除最后一个点 CopySplineTails(m_nSplineNodes);//清除活动SPLINE m_spCalcPointList.AddTail(m_dpLastMousePos); GetDC()->Create(m_pScreenDC); DrawRealLine(GetDC());//清除SPLINE的主体线 dp = m_spCalcPointList.GetHead(); for (int i = m_spRealPointList.GetCount() - 1; i >= 0; i--) { tt = m_spRealPointList.GetAt(m_spRealPointList.FindIndex(i)); if (fabs(tt.x0 - dp.x0) <= DBL_MIN && fabs(tt.y0 - dp.y0) <= DBL_MIN) { break; } else { m_spRealPointList.RemoveTail(); } } GetDC()->Create(m_pScreenDC); DrawRealLine(GetDC());//重绘主体线 GetDC()->Create(m_pScreenDC);//重绘活动SPLINE DrawSplineTail(GetDC()); } else { CopySplineTails(m_nSplineNodes + 1); GetDC()->Create(m_pScreenDC); DrawSplineTail(GetDC()); m_spPointList.RemoveTail(); CopySplineTails(m_nSplineNodes + 1); m_spCalcPointList.AddTail(m_dpLastMousePos); GetDC()->Create(m_pScreenDC); DrawSplineTail(GetDC()); dp = m_spPointList.GetHead(); for (int i = m_spRealPointList.GetCount() - 1; i >= 0; i--) { tt = m_spRealPointList.GetAt(m_spRealPointList.FindIndex(i)); if (fabs(tt.x0 - dp.x0) <= DBL_MIN && fabs(tt.y0 - dp.y0) <= DBL_MIN) { break; } else { m_spRealPointList.RemoveTail(); } } } return; } } void CItemCurveSpline::DrawRealLine(CXyDC * pDC) { if (m_spRealPointList.GetCount() <= 1) return; CDC* pdc = pDC->GetDC(); HDC hdc = pdc->m_hDC; int od = pdc->SetROP2(R2_NOTXORPEN); //画样条曲线 CPen* pOld = pdc->SelectObject(&m_pen); dfPoint dp; POSITION p = m_spRealPointList.GetHeadPosition(); dp = m_spRealPointList.GetNext(p); CPoint pt1 = pDC->GetScreen(dp.x0, dp.y0); CPoint pt2; POINT prePt; while (p) { dp = m_spRealPointList.GetNext(p); pt2 = pDC->GetScreen(dp.x0, dp.y0); ::MoveToEx(hdc, pt1.x, pt1.y, &prePt); ::LineTo(hdc, pt2.x, pt2.y); pt1 = pt2; } pDC->GetDC()->SelectObject(pOld); pDC->GetDC()->SetROP2(od); } void CItemCurveSpline::Undo(void) { if (m_spPointList.IsEmpty()) CItemCurveArc::Undo(); else { RemoveTail(); } } void CItemCurveSpline::Redo(void) { if (IsOnlyPointListTail()) { CItemCurveArc::Redo(); m_spPointList.RemoveAll(); if (!PointList.IsEmpty()) { dfPoint dp = PointList.GetTail(); m_spPointList.AddTail(dp); } } } BOOL CItemCurveSpline::IsCanUndo(void) { if (IsOnlyPointListTail()) return CItemCurveArc::IsCanUndo(); return !m_spPointList.IsEmpty(); } BOOL CItemCurveSpline::IsCanRedo(void) { if (IsOnlyPointListTail()) return CItemCurveArc::IsCanRedo(); return FALSE; } void CItemCurveSpline::EraseAuxiliarySpline(CDC * pScreenDC) { CXyDC * pDC = GetDC(); if (pDC == 0) return; pDC->Create(pScreenDC); CPen * pOld = pScreenDC->SelectObject(&m_pen); int od = pScreenDC->SetROP2(R2_NOTXORPEN); CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); GetDC()->Create(m_pScreenDC);//重绘活动SPLINE DrawSplineTail(GetDC()); pScreenDC->SelectObject(pOld); pScreenDC->SetROP2(od); m_bAuxiliarySplineRedraw = FALSE; } void CItemCurveSpline::DrawAssistant(CDC * pScreenDC, int mouseX, int mouseY) { GetDC()->Create(pScreenDC); CXyDC * pDC = GetDC(); if (pDC == 0) return; DrawSplineBody(pDC);//画样条线主体 DrawSplineTail(pDC); //m_bStretchStart = TRUE; m_bAuxiliarySplineRedraw = TRUE; m_bStretchStart = FALSE; /* CXyDC * pDC = GetDC(); if (pDC == 0) return; pDC->Create(pScreenDC); CPen * pOld = pScreenDC->SelectObject(&m_pen); //spline if (m_spPointList.GetCount() == 0) { pScreenDC->SelectObject(pOld); return; } CopySplineTails(m_nSplineNodes); m_spCalcPointList.AddTail(m_dpLastMousePos); CDC* pdc = pDC->GetDC(); HDC hdc = pdc->m_hDC; //画样条曲线 CPointList pl; CCurveEx ce; ce.SetPoints(m_spCalcPointList, 2); ce.CurveToSpline(pl, pDC->GetMiniSmoothStep() * m_mSmoothStepFactor, 0); if (pl.GetCount() <= 1) { pScreenDC->SelectObject(pOld); return; } dfPoint dp1, dp2; POSITION p = pl.GetHeadPosition(); dp1 = pl.GetNext(p); POINT prePt; while (p) { dp2 = pl.GetNext(p); pDC->MoveTo(dp1.x0, dp1.y0); pDC->LineTo(dp2.x0, dp2.y0); dp1 = dp2; } pScreenDC->SelectObject(pOld); int count = 0; CPen pen; pen.CreatePen(PS_SOLID, 2, RGB(0, 0, 255)); //pOld = (CPen*)pDC->GetDC()->SelectStockObject(BLACK_PEN); pOld = (CPen*)pScreenDC->SelectObject(&pen); CRect rt; POINT sp; dfPoint dp, dt; POSITION pos = m_spCalcPointList.GetHeadPosition(); while (pos) { dp = m_spCalcPointList.GetNext(pos); if (count > 0) { if (fabs(dt.x0 - dp.x0) < DBL_MIN && //是否是重复点 fabs(dt.y0 - dp.y0) < DBL_MIN) continue; } sp = pDC->GetScreen(dp.x0, dp.y0); rt = CalculateHandleRect(&sp); rt.InflateRect(1, 1); pDC->GetDC()->Ellipse(&rt); dt = dp; count++; } m_spCalcPointList.RemoveTail(); DrawSplineTail(GetDC()); DrawRealLine(GetDC()); pScreenDC->SelectObject(pOld); m_bStretchStart = TRUE; m_bAuxiliarySplineRedraw = FALSE; */ } //////////////////////////////////////////////////////////////////////////////////////////////////////// //CItemCurveMerge CItemCurveMerge::CItemCurveMerge(CSigmaDoc * ppDoc) : CItemCurveSpline(ppDoc) { m_pItemSelect = new CItemSelectElement(ppDoc); m_pItemSelect->EnableDraw(FALSE); m_pItemSelect->SetCompareIdea(1); m_pItemSelect->SetNumber(-1); //CMainFrame* pmf = (CMainFrame*)GetDoc()->GetMainFrame(); //if(pmf)pmf->ShowToolBar(IDR_TOOLBAR_PLINE_INSERT, TRUE); } CItemCurveMerge::~CItemCurveMerge(void) { if (m_pItemSelect)delete m_pItemSelect; m_pItemSelect = NULL; //CMainFrame* pmf = (CMainFrame*)GetDoc()->GetMainFrame(); //if(pmf)pmf->ShowToolBar(IDR_TOOLBAR_PLINE_INSERT, FALSE); } BOOL CItemCurveMerge::IsMergeState(void) { if (m_AddLineState == CURVE_STATE_MERGE) return TRUE; return FALSE; } void CItemCurveMerge::OnLButtonDown(CDC *pDC, UINT nFlags, CPoint point, int vk) { GetDC()->Create(pDC); if (IsMergeState()) { m_pItemSelect->OnLButtonDown(pDC, nFlags, point, vk); if (m_pItemSelect->GetSelectCount() == 1) { EraseScreenLines(); CPoint2D dp = GetDC()->GetReal(point); POSITION pos = m_pItemSelect->GetSelectItem(0); MergeElement(pos, dp); m_pItemSelect->RemoveAllSelect(); //选中一个曲线就清空 RedrawScreenLines(); } } else CItemCurveSpline::OnLButtonDown(pDC, nFlags, point, vk); } int CItemCurveMerge::OnMouseMove(CDC *pDC, UINT nFlags, CPoint point)// , BYTE*& destBuffer, int& destLen) { if (IsMergeState() || m_AddLineState == CURVE_STATE_LINE || m_AddLineState == CURVE_STATE_ANGLE) { CItemCurve::OnMouseMove(pDC, nFlags, point); return 1; } SetScreenDC(pDC); GetDC()->Create(pDC); int count = m_ptDisposableList.GetSize() / 2; for (int i = 0; i < count; i++) { dfPoint pt1 = m_ptDisposableList.GetHead(); m_ptDisposableList.RemoveHead(); dfPoint pt2 = m_ptDisposableList.GetHead(); m_ptDisposableList.RemoveHead(); DrawLine(pt1, pt2); } m_ptDisposableList.RemoveAll(); CItemCurveSpline::OnMouseMove(pDC, nFlags, point);// , destBuffer, destLen); return 1; } void CItemCurveMerge::OnLButtonUp(CDC *pDC, UINT nFlags, CPoint point, int vk) { if (IsMergeState()) { m_pItemSelect->OnLButtonUp(pDC, nFlags, point, vk); } else CItemCurveSpline::OnLButtonUp(pDC, nFlags, point, vk); } void CItemCurveMerge::DrawAssistant(CDC * pScreenDC, int mouseX, int mouseY) { if (m_AddLineState == CURVE_STATE_SPLINE) { CItemCurveSpline::DrawAssistant(pScreenDC, mouseX, mouseY); } CItemCurve::DrawAssistant(pScreenDC, mouseX, mouseY); } BOOL CItemCurveMerge::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { if (IsMergeState()) return m_pItemSelect->OnSetCursor(pWnd, nHitTest, message); return CItemCurveSpline::OnSetCursor(pWnd, nHitTest, message); } void CItemCurveMerge::EndCurve() { if (IsSplineState()) { CItemCurveSpline::NextCurve(); return; } else { CItemCurve::NextCurve(); } } void CItemCurveMerge::AddCurve() { NextCurve(); } void CItemCurveMerge::AutoClose(void) { AppendPoint(); if (PointList.IsEmpty()) return; dfPoint dp = PointList.GetHead(); m_ptDisposableList.AddTail(dp); //画上连接首尾的线 m_ptDisposableList.AddTail(PointList.GetTail()); m_ptDisposableList.AddTail(m_dpLastMousePos); //擦除橡皮线 m_ptDisposableList.AddTail(PointList.GetTail()); AddPoint(dp); m_dpLastMousePos = dp; } void CItemCurveMerge::ChangeMergeState() { if (m_AddLineState == CURVE_STATE_MERGE) { CItemCurve::RestoreCurveState(); if (PointList.IsEmpty()) return; dfPoint dp = PointList.GetTail(); m_spPointList.AddTail(dp); } else { if (IsSplineState()) { AppendPoint(); } CItemCurve::SetCurveState(CURVE_STATE_MERGE, NULL); } } void CItemCurveMerge::OnCancel(void) { switch (m_AddLineState) { case CURVE_STATE_MERGE: case CURVE_STATE_LINE: case CURVE_STATE_ARC: case CURVE_STATE_ANGLE: CItemCurve::OnCancel(); break; case CURVE_STATE_SPLINE: CItemCurveSpline::OnCancel(); default: break; } } void CItemCurveMerge::SetCurveState(int state, CDC * pDC) { if (state == m_AddLineState)//设置合并曲线状态 { return; } if (state == CURVE_STATE_MERGE) { m_AddLineState = CURVE_STATE_MERGE; CItemCurve::SetCurveState(CURVE_STATE_MERGE, NULL); return; } if (state == CURVE_STATE_DRAWING) { /*CItemCurve::RestoreCurveState(); if (PointList.IsEmpty()) return; dfPoint dp = PointList.GetTail(); m_spPointList.AddTail(dp); return;*/ } else { CItemCurveSpline::SetCurveState(state, pDC); } } void CItemCurveMerge::EreaseOldLine() { dfPoint ptTail = PointList.GetTail(); CPoint ptT = GetDC()->GetScreen(ptTail); CPoint ptPrev = GetDC()->GetScreen(m_dpLastMousePos); DrawLineScreen(ptPrev.x, ptPrev.y, ptT.x, ptT.y); } void CItemCurveMerge::DrawLine(dfPoint pt1, dfPoint pt2) { CPoint pt1S = GetDC()->GetScreen(pt1); CPoint pt2S = GetDC()->GetScreen(pt2); DrawLineScreen(pt1S.x, pt1S.y, pt2S.x, pt2S.y); } void CItemCurveMerge::MergeElement(POSITION pos, CPoint2D& dp) { if (pos == NULL) return; if (m_pDoc == NULL) return; COne* pOne = m_pDoc->GetDraw()->GetAt(pos); if (pOne == NULL) return; switch (pOne->GetType()) { case DOUBLEFOX_CURVE: { CCurveEx* pc = (CCurveEx*)pOne->GetValue(); double dis = AfxGetPublicFunction()->Distance2(dp.x0, dp.y0, pc->x[0], pc->y[0]); if (dis < AfxGetPublicFunction()->Distance2(dp.x0, dp.y0, pc->x[pc->num - 1], pc->y[pc->num - 1]))//与头连接 { for (int i = 0; i < pc->num; i++) this->AddPointFromCoordinate(pc->x[i], pc->y[i]); } else//与尾连接 { int lastIndex = pc->num - 1; for (int i = lastIndex; i >= 0; i--) this->AddPointFromCoordinate(pc->x[i], pc->y[i]); } m_dpLastMousePos = PointList.GetTail(); } break; case DOUBLEFOX_MXN: case DOUBLEFOX_XYZ: case DOUBLEFOX_POINT: case DOUBLEFOX_TEXT: case DOUBLEFOX_ELLIPSE: case DOUBLEFOX_CIRCLE: case DOUBLEFOX_INSERT: case DOUBLEFOX_DRAW: case DOUBLEFOX_DRAW_RECT: case DOUBLEFOX_PROPORTION: case DOUBLEFOX_FRAME: case DOUBLEFOX_IMAGE: case DOUBLEFOX_OLE: case DOUBLEFOX_TREE: case DOUBLEFOX_WMF: case DOUBLEFOX_STATION: case DOUBLEFOX_MTEXT: { CPointNameBase* pPoint = (CPointNameBase*)pOne->GetValue(); dfPoint dp; dp.x0 = pPoint->x0; dp.y0 = pPoint->y0; AddPoint(dp); } break; } } static CRect CalculateHandleRect(LPPOINT pPoint) { CRect rc(*pPoint, *pPoint); //int d = m_HandleSize / 2; //m_HandleSize = 8 int d = 4; rc.InflateRect(d, d); return rc; } }//namespace