You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

849 lines
20 KiB
C++

1 month ago
//////////////////////////////////////////////////////////////////////////////
//<2F>ļ<EFBFBD>: CItem<65><6D><EFBFBD><EFBFBD>չ
//<2F><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>:
// <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD>
//
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д: 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<dfPoint, dfPoint> 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)
{
//ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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;
//ֱ<><D6B1><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>γ<EFBFBD><CEB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>ж<EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD>Ķ<EFBFBD>
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 <dfPoint, dfPoint> pointList;
CURVE_SEGMENT segment1;
segment1.pCurve = p1;
//ѡ<><D1A1><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ˵<C4B6>
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;
//ѡ<><D1A1><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ˵<C4B6>
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) //û<><C3BB>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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) //<2F><>Ϊһ<CEAA><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ,ֱ<>ӽ<EFBFBD><D3BD>г<EFBFBD><D0B3><EFBFBD>
{
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;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ߵĽ<DFB5><C4BD><EFBFBD>
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)
{
////<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޽<EFBFBD><DEBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD>ѡ<EFBFBD>񡰷񡱽<F1A1B0B7>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߽<EFBFBD><DFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//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)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ
{
if (crossList.GetCount() == 1)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
//crossList.RemoveAll();
//et = CrossWithMustExtend(p1, p2, crossList);
/*if (crossList.GetCount() < 2)
{*/
//ֱ<>Ӵ<EFBFBD><D3B4><EFBFBD><EFBFBD>պ<EFBFBD><D5BA><EFBFBD><EFBFBD>򣬰<EFBFBD><F2A3ACB0>ͽ<EFBFBD>ԭ<EFBFBD><D4AD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD>߶˵<DFB6><CBB5>ͽ<EFBFBD><CDBD>㹲ͬ<E3B9B2><CDAC><EFBFBD>ɱպ<C9B1><D5BA><EFBFBD><EFBFBD><EFBFBD>
CreateTwoCurveSolid(SelectList.GetHead(), SelectList.GetTail());
bEnd = TRUE;
return TRUE;
/*}*/
}
if (!bEnd)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD><DFB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
CurPoint = crossList.GetHead();
PrevPoint = crossList.GetTail();
::AfxGetPublicFunction()->Swap(PrevPoint.x[0], PrevPoint.x[1]); //Ϊ<><CEAA><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>,<2C><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
}
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<CURVE_SEGMENT, CURVE_SEGMENT>& cg)
{
CList <dfPoint, dfPoint> 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;
//<2F><><EFBFBD><EFBFBD><EFBFBD>γɵ<CEB3><C9B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߱<EFBFBD><DFB1><EFBFBD><EFBFBD>
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<POSITION,POSITION> 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);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޽<EFBFBD><DEBD><EFBFBD><E3A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//AfxMessageBox(IDS_STRING_SOLID_NOCROSS);
int result = MessageBox(GetDrawView()->GetHWND(), "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߡ<EFBFBD>", "", 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<44><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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 <dfPoint, dfPoint> PointList;
GetCurve(segment, PointList);
if (PointList.GetCount() == 0)
{
pDoc->SetStatusOfCrossPoint(false);
/*::AfxMessageBox("Error: Null Curve");*/
return FALSE;
}
CurveGroup.AddTail(segment);
PrevPoint = CurPoint;
//<2F><>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>
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); //<2F><><EFBFBD><EFBFBD>ͷ
pc->Extend(m_iMaxExtendLength, 1); //<2F><><EFBFBD><EFBFBD>β
p1->Cross(*(CCurve*)pc, cross);
if (cross.GetCount() > count)
{
delete pc;
_SolidSetCurve(cross, p2, count);
return 2;
}
*pc = *p1;
pc->Extend(m_iMaxExtendLength, 0); //<2F><><EFBFBD><EFBFBD>ͷ
pc->Extend(m_iMaxExtendLength, 1); //<2F><><EFBFBD><EFBFBD>β
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); //<2F><><EFBFBD><EFBFBD>ͷ
pb->Extend(m_iMaxExtendLength, 1); //<2F><><EFBFBD><EFBFBD>β
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); //<2F><><EFBFBD><EFBFBD>ͷ
pc->Extend(m_iMaxExtendLength, 1); //<2F><><EFBFBD><EFBFBD>β
CCurveEx* pb = new CCurveEx;
*pb = *p2;
pb->Extend(m_iMaxExtendLength, 0); //<2F><><EFBFBD><EFBFBD>ͷ
pb->Extend(m_iMaxExtendLength, 1); //<2F><><EFBFBD><EFBFBD>β
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 <dfPoint, dfPoint>& list)
{
CCurveEx* pc = segment.pCurve;
if (segment.m_bExtend)
{
pc = new CCurveEx;
*pc = *segment.pCurve;
pc->Extend(m_iMaxExtendLength, 0); //<2F><><EFBFBD><EFBFBD>ͷ
pc->Extend(m_iMaxExtendLength, 1); //<2F><><EFBFBD><EFBFBD>β
}
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();
}
//<2F>õ<EFBFBD><C3B5><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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;
//<2F><>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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();
// һ<><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE>
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;
//<2F><>ȡ<EFBFBD>ӿ<EFBFBD><D3BF>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GetCurves();
if (CurveList.IsEmpty())//<2F><><EFBFBD><EFBFBD>curvelist<73><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><DFA3><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>˳<EFBFBD><CBB3><EFBFBD>״̬
{
SetStatusCode(STATUS_CODE_SOLID_NO_CURVE);
SetStatusText(STATUS_TEXT_SOLID_NO_CURVE);
return;
}
//<2F><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>а<EFBFBD><D0B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E0BDBB><EFBFBD>պϵ<D5BA><CFB5><EFBFBD><EFBFBD>߰<EFBFBD><DFB0><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD>
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);
//<2F><><EFBFBD><EFBFBD><EFBFBD>պ<EFBFBD><D5BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѱ<EFBFBD><D1B0><EFBFBD><EFBFBD>պ<EFBFBD><D5BA><EFBFBD><EFBFBD>߽<EFBFBD><DFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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;
//ѡȡ<D1A1><C8A1>ְ<EFBFBD><D6B0>С<EFBFBD>ıպ<C4B1><D5BA><EFBFBD><EFBFBD><EFBFBD>
pos = InsideCurveList.GetHeadPosition();
while (pos)
{
pCurve = (CCurveEx*)InsideCurveList.GetNext(pos);
if (pCurve)
{
if (pCurve->Area() < minArea)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD>
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;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD>
double CItemSolidAuto::CrossProduct(dfPoint p, dfPoint q) {
return p.x0 * q.y0 - p.y0 * q.x0;
}
// <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD>߶<EFBFBD><DFB6>Ƿ<EFBFBD><C7B7>ཻ,<2C><><EFBFBD><EFBFBD><EFBFBD>ý<EFBFBD><C3BD><EFBFBD>
bool CItemSolidAuto::Cross(dfPoint p1, dfPoint q1, dfPoint p2, dfPoint q2, dfPoint& cr) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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)) {
// <20><><EFBFBD><EFBFBD><E3BDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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;
}