////////////////////////////////////////////////////////////////////////////// //文件: CItem类扩展 //主要功能: // 操作各类元素或完成一定的功能 // //程序编写: 2006-12-07 // // ///////////////////////////////////////////////////////////////////////////// #include "StdAfx.h" #include ".\itemsolid.h" #include "SigmaDoc.h" #include "SigmaView.h" #include "DrawOperator/CurveClosure.h" #include "StatusDefine.h" ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// //CItemSolidLink CItemSolidLink::CItemSolidLink(CSigmaDoc * ppDoc) : CItemLinkCurve(ppDoc) { this->SetType(ITEM_SOLID_LINK); num = -1; } CItemSolidLink::~CItemSolidLink(void) { RemoveAllSelect(); } BOOL CItemSolidLink::DoSelectEnd(void) { if (SelectList.GetCount() == 0) return FALSE; CSigmaDoc * pDoc = GetDoc(); SELECT_ITEM st1, st2; COne *pOne1, *pOne2; CCurveEx *p1, *p2; CList PointList; dfPoint dp; int n; double dish, dist, dis11, dis12, dis21, dis22; POSITION pos = SelectList.GetHeadPosition(); st1 = SelectList.GetNext(pos); pOne1 = pDoc->GetDraw()->GetAt(st1.pos); p1 = (CCurveEx*)pOne1->GetValue(); p1->GetPoint(PointList, FALSE); while (pos) { st2 = SelectList.GetNext(pos); pOne2 = pDoc->GetDraw()->GetAt(st2.pos); p2 = (CCurveEx*)pOne2->GetValue(); n = p2->num - 1; dp = PointList.GetHead(); dis11 = ::AfxGetPublicFunction()->Distance2(dp.x0, dp.y0, p2->x[0], p2->y[0]); dis12 = ::AfxGetPublicFunction()->Distance2(dp.x0, dp.y0, p2->x[n], p2->y[n]); dish = min(dis11, dis12); dp = PointList.GetTail(); dis21 = ::AfxGetPublicFunction()->Distance2(dp.x0, dp.y0, p2->x[0], p2->y[0]); dis22 = ::AfxGetPublicFunction()->Distance2(dp.x0, dp.y0, p2->x[n], p2->y[n]); dist = min(dis21, dis22); if (dish < dist) { if (dis11 < dis12) p2->GetPoint(PointList, FALSE, TRUE); else p2->GetPoint(PointList, TRUE, TRUE); } else { if (dis21 < dis22) p2->GetPoint(PointList, FALSE, FALSE); else p2->GetPoint(PointList, TRUE, FALSE); } } dp = PointList.GetHead(); PointList.AddTail(dp); CCurveEx *pCurve = new CCurveEx; pCurve->SetPoints(PointList, 2); pCurve->m_type = PLINE_SOLID; pos = AddElement(pCurve, DOUBLEFOX_CURVE, true, true); PointList.RemoveAll(); COne* pOne = GetDoc()->GetDraw()->GetAt(pos); GetView()->ActionAdd(pOne, ID_EDIT_SOLID_LINK_RANGE); return TRUE; } int CItemSolidLink::GetSubMenu() { return 5; } void CItemSolidLink::ClearAssistantCurve(void) { //删除辅助曲线 if (AssistantCurveList.IsEmpty()) return; /*if(::AfxMessageBox(IDS_STRING_DELETE_ASSISTANT,MB_YESNO|MB_ICONQUESTION)!=IDYES) return;*/ SELECT_ITEM item; POSITION p, pt; POSITION pos = SelectList.GetHeadPosition(); while (pos) { pt = pos; item = SelectList.GetNext(pos); p = AssistantCurveList.Find(item.pos); if (p) SelectList.RemoveAt(pt); } GetDoc()->InvalidateDelete(AssistantCurveList); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //CItemSolid CItemSolid::CItemSolid(CSigmaDoc * ppDoc) : CItemSolidLink(ppDoc) { this->SetType(ITEM_SOLID); m_nCompareIdea = 0; num = -1; m_iMaxExtendLength = 5000; } CItemSolid::~CItemSolid(void) { } int CItemSolid::GetSubMenu() { return 5; } int CItemSolid::OnMouseMove(CDC* pDC, UINT nFlags, CPoint point) { return CItemLinkCurve::OnMouseMove(pDC, nFlags, point); //CSigmaDoc * pDoc = GetDoc(); //CString info; //info.Format(IDS_STRING_CONFIRM_NEXT_CURVE,(int)SelectList.GetCount()+1); //pDoc->SetStatusBarInfo(0,info); } CCrossPoint CItemSolid::GetPoint(SELECT_ITEM& item, CCurveEx* p1, CCurveEx* p2, CCrossPoint& otherPoint) { CCrossPoint CurPoint; //直接连接第一条线与最后一条线形成填充区域,需要判断选择哪端 if (::AfxGetPublicFunction()->Distance2(item.point.x0, item.point.y0, p1->x[0], p1->y[0]) > ::AfxGetPublicFunction()->Distance2(item.point.x0, item.point.y0, p1->x[p1->num - 1], p1->y[p1->num - 1])) { CurPoint.x[0] = p1->l[p1->num - 1]; //tail point otherPoint.x[0] = p1->l[0]; //head point } else { CurPoint.x[0] = p1->l[0]; //head point otherPoint.x[0] = p1->l[p1->num - 1]; //tail point } if (::AfxGetPublicFunction()->Distance2(item.point.x0, item.point.y0, p2->x[0], p2->y[0]) > ::AfxGetPublicFunction()->Distance2(item.point.x0, item.point.y0, p2->x[p2->num - 1], p1->y[p2->num - 1])) { CurPoint.x[1] = p2->l[p2->num - 1]; //tail point otherPoint.x[1] = p2->l[0]; //head point } else { CurPoint.x[1] = p2->l[0]; //head point otherPoint.x[1] = p2->l[p2->num - 1]; //tail point } CurPoint.curve = p1; otherPoint.curve = p1; return CurPoint; } BOOL CItemSolid::CreateTwoCurveSolid(SELECT_ITEM& item1, SELECT_ITEM& item2) { BOOL ret = true; CSigmaDoc * pDoc = GetDoc(); CCurveEx* p1 = (CCurveEx*)pDoc->GetDraw()->GetAtValue(item1.pos); CCurveEx* p2 = (CCurveEx*)pDoc->GetDraw()->GetAtValue(item2.pos); CCrossPoint cp; CCrossList cl; p1->Cross(*p2, cl); if (cl.GetCount() >= 1) { cp = cl.GetHead(); } CList pointList; CURVE_SEGMENT segment1; segment1.pCurve = p1; //选择第一条曲线离选择点近的端点 double ds = ::AfxGetPublicFunction()->Distance2(item1.point.x0, item1.point.y0, p1->x[0], p1->y[0]); double de = ::AfxGetPublicFunction()->Distance2(item1.point.x0, item1.point.y0, p1->x[p1->num - 1], p1->y[p1->num - 1]); if (ds < de) { segment1.head = p1->l[0]; } else { segment1.head = p1->l[p1->num - 1]; } segment1.tail = cp.x[0]; GetCurve(segment1, pointList); CURVE_SEGMENT segment2; segment2.pCurve = p2; //选择第二条曲线离选择点近的端点 ds = ::AfxGetPublicFunction()->Distance2(item2.point.x0, item2.point.y0, p2->x[0], p2->y[0]); de = ::AfxGetPublicFunction()->Distance2(item2.point.x0, item2.point.y0, p2->x[p2->num - 1], p2->y[p2->num - 1]); segment2.head = cp.x[1]; if (ds < de) { segment2.tail = p2->l[0]; } else { segment2.tail = p2->l[p2->num - 1]; } GetCurve(segment2, pointList); if (pointList.GetCount() < 2) return NULL; CCurveEx* pCurve = new CCurveEx; pCurve->SetPoints(pointList, 2); pCurve->m_type = PLINE_SOLID; POSITION pos = this->AddElement(pCurve, DOUBLEFOX_CURVE, true, true); pDoc->Invalidate(pos); SelectList.RemoveAll(); COne* pOne = pDoc->GetDraw()->GetAt(pos); GetView()->ActionAdd(pOne, ID_EDIT_GETSOLIDRANGE); return ret; } BOOL CItemSolid::DoSelectEnd(void) { if (SelectList.GetCount() == 0) //没有选择曲线 return TRUE; CSigmaDoc * pDoc = GetDoc(); POSITION pos; SELECT_ITEM item; item = SelectList.GetTail(); CCurveEx* p1 = (CCurveEx*)pDoc->GetDraw()->GetAtValue(item.pos); if (SelectList.GetCount() == 1) //当为一条曲线时,直接进行充填 { CCurveEx* pCurve = new CCurveEx; *pCurve = *p1; pCurve->m_type = PLINE_SOLID; pos = this->AddElement(pCurve, DOUBLEFOX_CURVE, true, false); pDoc->Invalidate(pos); SelectList.RemoveAll(); //for undo/redo COne* pOne = pDoc->GetDraw()->GetAt(pos); GetView()->ActionAdd(pOne, ID_EDIT_GETSOLIDRANGE); return TRUE; } BOOL bEnd = FALSE; //计算第一条线与最后一条线的交点 item = SelectList.GetHead(); CCurveEx* p2 = (CCurveEx*)pDoc->GetDraw()->GetAtValue(item.pos); CCrossPoint CurPoint; CCrossPoint otherPoint; CCrossList crossList; int et = CrossWithExtend(p1, p2, crossList); if (crossList.GetCount() == 0) { ////该曲线与第一条曲线无交点,是否重新选择曲线,或立即绘制一条辅助曲线?选择“否”将直接连接曲线结束充填。 //AfxMessageBox(IDS_STRING_SOLID_NOCROSS1); //return FALSE; /*if(::AfxMessageBox(IDS_STRING_SOLID_NOCROSS1, MB_YESNO|MB_ICONQUESTION) == IDYES) return FALSE;*/ CurPoint = GetPoint(item, p1, p2, otherPoint); bEnd = TRUE; } if (SelectList.GetCount() == 2)//仅有两条曲线时 { if (crossList.GetCount() == 1)//两条曲线一个交点 { //crossList.RemoveAll(); //et = CrossWithMustExtend(p1, p2, crossList); /*if (crossList.GetCount() < 2) {*/ //直接创建闭合区域,按就近原则选择曲线端点和交点共同构成闭合区域 CreateTwoCurveSolid(SelectList.GetHead(), SelectList.GetTail()); bEnd = TRUE; return TRUE; /*}*/ } if (!bEnd)//两条曲线多个交点 { CurPoint = crossList.GetHead(); PrevPoint = crossList.GetTail(); ::AfxGetPublicFunction()->Swap(PrevPoint.x[0], PrevPoint.x[1]); //为了适应下面的代码,需要交换位置 } FirstPoint = PrevPoint; } else if (!bEnd) CurPoint = GetNearestCrossPoint(crossList, item.point); CURVE_SEGMENT segment; segment.head = PrevPoint.x[1]; segment.tail = CurPoint.x[0]; segment.pCurve = p1; if (et == 1 || et == 3 || m_bExtendLastCurve) segment.m_bExtend = TRUE; else segment.m_bExtend = FALSE; CurveGroup.AddTail(segment); segment.head = CurPoint.x[1]; segment.tail = FirstPoint.x[0]; segment.pCurve = p2; if (et == 2 || et == 3 || m_bExtendFirstCurve) segment.m_bExtend = TRUE; else segment.m_bExtend = FALSE; CurveGroup.AddHead(segment); if (CreateCurve(CurveGroup) == NULL) { CurveGroup.RemoveTail(); segment.head = PrevPoint.x[1]; segment.tail = otherPoint.x[0]; segment.pCurve = p1; if (et == 1 || et == 3 || m_bExtendLastCurve) segment.m_bExtend = TRUE; else segment.m_bExtend = FALSE; CurveGroup.AddTail(segment); CreateCurve(CurveGroup); } return TRUE; } POSITION CItemSolid::CreateCurve(CList& cg) { CList PointList; CURVE_SEGMENT segment; POSITION pos = cg.GetHeadPosition(); while (pos) { segment = cg.GetNext(pos); GetCurve(segment, PointList); } if (PointList.GetCount() < 2) return NULL; CCurveEx* pCurve = new CCurveEx; pCurve->SetPoints(PointList, 2); pCurve->m_type = PLINE_SOLID; //计算形成的区域是否是首尾曲线与曲线本身相交 PointList.RemoveHead(); PointList.RemoveHead(); PointList.RemoveTail(); PointList.RemoveTail(); CCurveEx* pe = new CCurveEx; pe->SetPoints(PointList, 2); CCurveEx *pc = new CCurveEx; pc->Create(2); pc->x[0] = pCurve->x[0]; pc->y[0] = pCurve->y[0]; pc->x[1] = pCurve->x[pCurve->num - 1]; pc->y[1] = pCurve->y[pCurve->num - 1]; pc->GetLocation(); CCrossList cross; pe->Cross(*(CCurve*)pc, cross); if (cross.GetCount() > 0) { delete pCurve; delete pc; delete pe; return NULL; } delete pc; delete pe; CSigmaDoc * pDoc = GetDoc(); pos = this->AddElement(pCurve, DOUBLEFOX_CURVE, true, true); pDoc->Invalidate(pos); SelectList.RemoveAll(); COne* pOne = pDoc->GetDraw()->GetAt(pos); GetView()->ActionAdd(pOne, ID_EDIT_GETSOLIDRANGE); /*CList select; pos=SelectList.GetHeadPosition(); while(pos) select.AddTail(SelectList.GetNext(pos).pos); pDoc->InvalidateSelection(select);*/ return pos; } BOOL CItemSolid::SelectItem(POSITION pos, CPoint2D point) { if (pos == NULL) return FALSE; int cnt = (int)SelectList.GetCount(); CSigmaDoc * pDoc = GetDoc(); //CString info; //info.Format(IDS_STRING_CONFIRM_NEXT_CURVE,cnt+1); //pDoc->SetStatusBarInfo(0,info); if (cnt == 0) return TRUE; SELECT_ITEM item = SelectList.GetTail(); CCurveEx* p1 = (CCurveEx*)pDoc->GetDraw()->GetAtValue(item.pos); CCurveEx* p2 = (CCurveEx*)pDoc->GetDraw()->GetAtValue(pos); CCrossList cross; pDoc->SetStatusOfCrossPoint(1); int et = CrossWithExtend(p1, p2, cross); if (cross.GetCount() == 0) { pDoc->SetStatusOfCrossPoint(0); //该曲线与上条曲线无交点,请从新选择曲线,或立即绘制一条辅助曲线 //AfxMessageBox(IDS_STRING_SOLID_NOCROSS); int result = MessageBox(GetDrawView()->GetHWND(), "该曲线与上条曲线无交点,请重新选择曲线。", "", MB_OK); return FALSE; } if (cnt == 1) { PrevPoint = GetNearestCrossPoint(cross, point); FirstPoint = PrevPoint; if (et == 1 || et == 3) m_bExtendFirstCurve = TRUE; else m_bExtendFirstCurve = FALSE; if (et == 2 || et == 3) m_bExtendLastCurve = TRUE; else m_bExtendLastCurve = FALSE; return TRUE; } CCrossPoint CurPoint = GetNearestCrossPoint(cross, point); CURVE_SEGMENT segment; segment.PrevPoint = PrevPoint; //为UNDO,REDO做备份 segment.m_bExtendLastCurve = m_bExtendLastCurve; segment.head = PrevPoint.x[1]; segment.tail = CurPoint.x[0]; segment.pCurve = p1; if (et == 1 || et == 3 || m_bExtendLastCurve) segment.m_bExtend = TRUE; else segment.m_bExtend = FALSE; if (et == 2 || et == 3) m_bExtendLastCurve = TRUE; else m_bExtendLastCurve = FALSE; CList PointList; GetCurve(segment, PointList); if (PointList.GetCount() == 0) { pDoc->SetStatusOfCrossPoint(false); /*::AfxMessageBox("Error: Null Curve");*/ return FALSE; } CurveGroup.AddTail(segment); PrevPoint = CurPoint; //仅为了显示曲线 CCurveEx* pCurve = new CCurveEx; pCurve->SetPoints(PointList, 2); this->Draw(GetDC(), pCurve, RGB(0, 255, 0)); delete pCurve; return TRUE; } void _SolidSetCurve(CCrossList& crossList, CCurveEx* pCurve, int countJump) { POSITION pos = crossList.GetHeadPosition(); if (countJump > 0) pos = crossList.FindIndex(countJump); CCrossPoint cp; while (pos) { cp = crossList.GetAt(pos); cp.curve = pCurve; crossList.SetAt(pos, cp); crossList.GetNext(pos); } } int NItem::CItemSolid::CrossWithExtend(CCurveEx* p1, CCurveEx* p2, CCrossList& cross) { int count = (int)cross.GetCount(); p1->Cross(*(CCurve*)p2, cross); if (cross.GetCount() > count) return 0; CCurveEx* pc = new CCurveEx; *pc = *p2; pc->Extend(m_iMaxExtendLength, 0); //延伸头 pc->Extend(m_iMaxExtendLength, 1); //延伸尾 p1->Cross(*(CCurve*)pc, cross); if (cross.GetCount() > count) { delete pc; _SolidSetCurve(cross, p2, count); return 2; } *pc = *p1; pc->Extend(m_iMaxExtendLength, 0); //延伸头 pc->Extend(m_iMaxExtendLength, 1); //延伸尾 pc->Cross(*(CCurve*)p2, cross); if (cross.GetCount() > count) { delete pc; _SolidSetCurve(cross, p2, count); return 1; } CCurveEx* pb = new CCurveEx; *pb = *p2; pb->Extend(m_iMaxExtendLength, 0); //延伸头 pb->Extend(m_iMaxExtendLength, 1); //延伸尾 pc->Cross(*(CCurve*)pb, cross); delete pb; delete pc; if (cross.GetCount() > count) { _SolidSetCurve(cross, p2, count); return 3; } return -1; } int CItemSolid::CrossWithMustExtend(CCurveEx* p1, CCurveEx* p2, CCrossList& cross) { int count = (int)cross.GetCount(); CCurveEx* pc = new CCurveEx; *pc = *p1; pc->Extend(m_iMaxExtendLength, 0); //延伸头 pc->Extend(m_iMaxExtendLength, 1); //延伸尾 CCurveEx* pb = new CCurveEx; *pb = *p2; pb->Extend(m_iMaxExtendLength, 0); //延伸头 pb->Extend(m_iMaxExtendLength, 1); //延伸尾 pc->Cross(*(CCurve*)pb, cross); delete pb; delete pc; if (cross.GetCount() > count) { _SolidSetCurve(cross, p2, count); return 3; } return -1; } void CItemSolid::GetCurve(NItem::CItemSolid::CURVE_SEGMENT& segment, CList & list) { CCurveEx* pc = segment.pCurve; if (segment.m_bExtend) { pc = new CCurveEx; *pc = *segment.pCurve; pc->Extend(m_iMaxExtendLength, 0); //延伸头 pc->Extend(m_iMaxExtendLength, 1); //延伸尾 } pc->GetCurve(segment.head, segment.tail, list); if (segment.m_bExtend) delete pc; } CCrossPoint CItemSolid::GetNearestCrossPoint(CCrossList& cross, CPoint2D point) { ASSERT(cross.GetCount() > 0); if (cross.GetCount() == 1) return cross.GetHead(); double dmin = 1e300, dis; CCrossPoint pt, rpt; dfPoint dp; CCurveEx* pCurve; POSITION pos = cross.GetHeadPosition(); while (pos) { pt = cross.GetNext(pos); pCurve = (CCurveEx*)pt.curve; dp.l = pt.x[1]; pCurve->GetCoordinate(dp.l, dp.x0, dp.y0, dp.z0); dis = ::AfxGetPublicFunction()->Distance(point.x0, point.y0, dp.x0, dp.y0); if (dmin > dis) { dmin = dis; rpt = pt; } } return rpt; } void CItemSolid::Undo(void) { CItemLinkCurve::Undo(); if (!CurveGroup.IsEmpty()) { CURVE_SEGMENT cs = CurveGroup.RemoveTail(); PrevPoint = cs.PrevPoint; m_bExtendLastCurve = cs.m_bExtendLastCurve; } if (SelectList.GetCount() == 0) return; SELECT_ITEM item = SelectList.GetTail(); CSigmaDoc * pDoc = GetDoc(); pDoc->Invalidate(item.pos); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// CItemPathFill::CItemPathFill(CSigmaDoc * ppDoc) : CItem(ppDoc) { this->SetType(ITEM_PATH_FILL); m_fillMode = 0; } CItemPathFill::~CItemPathFill(void) { } ////////////////////////////////////////////////////////////////////////////////////// //CItemSolidAuto CItemSolidAuto::CItemSolidAuto(CSigmaDoc * ppDoc) : CItem(ppDoc) { SetType(ITEM_SOLID_AUTO); m_iMaxExtendLength = 0; } CItemSolidAuto::~CItemSolidAuto() { ClearCurveList(); } void CItemSolidAuto::ClearCurveList() { CCurveEx* cx; POSITION p = CurveList.GetHeadPosition(); while (p) { cx = (CCurveEx *)(CurveList.GetNext(p)); delete cx; } InsideCurveList.RemoveAll(); CurveList.RemoveAll(); } //得到当前层所有曲线 void NItem::CItemSolidAuto::GetCurves() { CurveList.RemoveAll(); InsideCurveList.RemoveAll(); CPositionList plist; CXy *xy; xy = GetDoc()->GetDraw(); CRect rect = GetDrawView()->GetClientRect(); CRect8 range; dfPoint dfpTopleft = GetReal(rect.TopLeft()); dfPoint dfpBottomRight = GetReal(rect.BottomRight()); range.top = dfpTopleft.y0; range.bottom = dfpBottomRight.y0; range.left = dfpTopleft.x0; range.right = dfpBottomRight.x0; //仅选择当前视图所见的曲线 xy->IsInRange(range, plist, DOUBLEFOX_CURVE, true); //xy->GetElement(DOUBLEFOX_CURVE, plist, FALSE); COne *pOne; CCurveEx* cx; CCurveEx* pNewCurve; POSITION pt; POSITION pos = plist.GetHeadPosition(); while (pos) { pt = plist.GetNext(pos); pOne = (COne *)xy->GetAt(pt); cx = (CCurveEx*)pOne->value; pNewCurve = new CCurveEx; *pNewCurve = *cx; pNewCurve->GetLocation(); // 一个点的曲线删除 if (pNewCurve->num <= 1) { delete pNewCurve; continue; } if (pNewCurve->IsInside(dfp.x0, dfp.y0)) { InsideCurveList.AddTail(pNewCurve); } CurveList.AddTail(pNewCurve); } } void CItemSolidAuto::OnLButtonDown(CDC *pDC, UINT nFlags, CPoint point, int vk) { ClearStatus(); ClearCurveList(); CPoint2D rp = GetDC()->GetReal(point); dfp.x0 = rp.x0; dfp.y0 = rp.y0; //获取视口上的所有曲线 GetCurves(); if (CurveList.IsEmpty())//如果curvelist中无曲线,则提示并退出该状态 { SetStatusCode(STATUS_CODE_SOLID_NO_CURVE); SetStatusText(STATUS_TEXT_SOLID_NO_CURVE); return; } //计算图件中包含的曲线相交或闭合的曲线包含的点的最小面积 CCurveEx* pc = CreateSolid(); if (pc) { POSITION pos = CurveList.Find(pc); if (pos) { CurveList.RemoveAt(pos); } pc->m_type = PLINE_SOLID; pos = AddElement(pc, DOUBLEFOX_CURVE, true, true); GetDoc()->Invalidate(pos); COne* pOne = GetDoc()->GetDraw()->GetAt(pos); GetView()->ActionAdd(pOne, ID_EDIT_AUTOSOLID); } else { SetStatusCode(STATUS_CODE_SOLID_CURVE_NOTCLOSED); SetStatusText(STATUS_TEXT_SOLID_CURVE_NOTCLOSED); } } CCurveEx* NItem::CItemSolidAuto::CreateSolid() { if (CurveList.IsEmpty()) return 0; CCurveClosure closure(&CurveList); //创建闭合曲线已包含闭合曲线进行运算 CCurveEx *pCur = closure.CreateClosedCurve(dfp); CCurveEx *pMinAreaCur = NULL; if (pCur == NULL || !pCur->IsClosed()) { if (pCur) delete pCur; pMinAreaCur = GetMinInsideCurve(); } else { pMinAreaCur = GetMinInsideCurve(); if (pMinAreaCur) { if (pCur->Area() < pMinAreaCur->Area()) { pMinAreaCur = pCur; } } else { return pCur; } } return pMinAreaCur; } CCurveEx* NItem::CItemSolidAuto::GetMinInsideCurve() { CCurveEx *pCurve = NULL; CCurveEx *pMinAreaCurve = NULL; POSITION pos; double minArea = DBL_MAX; //选取面职最小的闭合区域 pos = InsideCurveList.GetHeadPosition(); while (pos) { pCurve = (CCurveEx*)InsideCurveList.GetNext(pos); if (pCurve) { if (pCurve->Area() < minArea) { //创建新的曲线 pMinAreaCurve = pCurve; minArea = pCurve->Area(); } } } return pMinAreaCurve; } BOOL CItemSolidAuto::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { //GetDoc()->GetCursor().SetCursor(CursorCrosshair); //return GetDoc()->GetCursor().SetCursor(); return TRUE; } int CItemSolidAuto::GetSubMenu() { return 5; } // 计算两个向量的叉积 double CItemSolidAuto::CrossProduct(dfPoint p, dfPoint q) { return p.x0 * q.y0 - p.y0 * q.x0; } // 判断两线段是否相交,并求得交点 bool CItemSolidAuto::Cross(dfPoint p1, dfPoint q1, dfPoint p2, dfPoint q2, dfPoint& cr) { // 计算向量 dfPoint v1; v1.x0 = q1.x0 - p1.x0; v1.y0 = q1.y0 - p1.y0; dfPoint v2; v2.x0 = q2.x0 - p2.x0; v2.y0 = q2.y0 - p2.y0; // 计算叉积 dfPoint p; p.x0 = p1.x0 - p2.x0; p.y0 = p1.y0 - p2.y0; double cp1 = CrossProduct(v2, p); p.x0 = q1.x0 - p2.x0; p.y0 = q1.y0 - p2.y0; double cp2 = CrossProduct(v2, p); p.x0 = p2.x0 - p1.x0; p.y0 = p2.y0 - p1.y0; double cp3 = CrossProduct(v1, p); p.x0 = q2.x0 - p1.x0; p.y0 = q2.y0 - p1.y0; double cp4 = CrossProduct(v1, p); if ((cp1 * cp2 < 0) && (cp3 * cp4 < 0)) { // 计算交点的坐标 cr.x0 = p1.x0 + (q1.x0 - p1.x0) * cp1 / (cp1 - cp2); cr.y0 = p1.y0 + (q1.y0 - p1.y0) * cp1 / (cp1 - cp2); return true; } return false; }