363 lines
6.8 KiB
C++
363 lines
6.8 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
|
|
// = FileName : TPtGraph.cpp
|
|
// = Version : ver2.0
|
|
// = Author : xlc
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: 类的定义
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "TPtGraph.h"
|
|
|
|
|
|
TPtGraph::TPtGraph()
|
|
{
|
|
|
|
}
|
|
|
|
TPtGraph::~TPtGraph()
|
|
{
|
|
ClearRef();
|
|
}
|
|
|
|
void TPtGraph::AppendA(TPtNode*p)
|
|
{
|
|
AddTail(p);
|
|
p->SetRefA(&GetCurData());
|
|
}
|
|
|
|
void TPtGraph::AppendB(TPtNode*p)
|
|
{
|
|
AddTail(p);
|
|
p->SetRefB(&GetCurData());
|
|
}
|
|
|
|
void TPtGraph::AppendC(TPtNode*p)
|
|
{
|
|
AddTail(p);
|
|
p->SetRefC(&GetCurData());
|
|
}
|
|
|
|
void TPtGraph::AppendRef(long i)
|
|
{
|
|
refList.FindOrAddTail(i);
|
|
}
|
|
|
|
void TPtGraph::ClearRef()
|
|
{
|
|
if (refList.IsEmpty())
|
|
{
|
|
return;
|
|
}
|
|
for (refList.MoveToFirst();!refList.IsOut();refList.MoveToNext())
|
|
{
|
|
MoveTo(refList.GetCurData());
|
|
SetCurData(NULL);
|
|
}
|
|
for (MoveToFirst();!IsOut();MoveToNext())
|
|
{
|
|
if (IsCurEmpty())
|
|
{
|
|
DelCur();
|
|
}
|
|
}
|
|
refList.Clear();
|
|
}
|
|
|
|
void TPtGraph::InsertA(TPtNode*p)
|
|
{
|
|
TPtNode*p0 = GetCurData();
|
|
while(true)
|
|
{
|
|
double dpa = p->PaA()-p0->PaA();
|
|
if (UP_ZERO(dpa))
|
|
{
|
|
if (EQUAL_ZERO(p0->NextA()->PaA()))
|
|
{
|
|
p->CNNextA(p0->NextA());
|
|
p0->CNNextA(p);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
p0 = p0->NextA();
|
|
}
|
|
}
|
|
else if (DOWN_ZERO(dpa))
|
|
{
|
|
p0->PreA()->CNNextA(p);
|
|
p->CNNextA(p0);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
p->Replace(p0);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TPtGraph::InsertB(TPtNode*p)
|
|
{
|
|
TPtNode*p0 = GetCurData();
|
|
while(true)
|
|
{
|
|
double dpa = p->PaB()-p0->PaB();
|
|
if (UP_ZERO(dpa))
|
|
{
|
|
if (EQUAL_ZERO(p0->NextB()->PaB()))
|
|
{
|
|
p->CNNextB(p0->NextB());
|
|
p0->CNNextB(p);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
p0 = p0->NextB();
|
|
}
|
|
}
|
|
else if (DOWN_ZERO(dpa))
|
|
{
|
|
p0->PreB()->CNNextB(p);
|
|
p->CNNextB(p0);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
p->Replace(p0);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TPtGraph::CreatePtGraphA(const TGMLine2D&mLine)
|
|
{
|
|
TPtNode*p0 = new TPtNode(mLine.GetVertex(0));
|
|
AppendA(p0);
|
|
for (long i = 1;i<mLine.GetVertexNum();i++)
|
|
{
|
|
TPtNode*p = new TPtNode(mLine.GetVertex(i));
|
|
p0->CNNextA(p);
|
|
p0 = p;
|
|
AppendA(p0);
|
|
}
|
|
if (mLine.IsClosed())
|
|
{
|
|
p0 = GetCurData();
|
|
MoveToFirst();
|
|
p0->CNNextA(GetCurData());
|
|
}
|
|
}
|
|
|
|
void TPtGraph::CreatePtGraphB(const TGMLine2D&mLine)
|
|
{
|
|
TPtNode*p0 = new TPtNode(mLine.GetVertex(0));
|
|
AppendB(p0);
|
|
for (long i = 1;i<mLine.GetVertexNum();i++)
|
|
{
|
|
TPtNode*p = new TPtNode(mLine.GetVertex(i));
|
|
p0->CNNextB(p);
|
|
p0 = p;
|
|
AppendB(p0);
|
|
}
|
|
if (mLine.IsClosed())
|
|
{
|
|
p0 = GetCurData();
|
|
MoveToFirst();
|
|
p0->CNNextB(GetCurData());
|
|
}
|
|
}
|
|
|
|
bool TPtGraph::CreatePtGraphC(const TGMLine2D&mLineA,const TGMLine2D&mLineB)
|
|
{
|
|
bool ret = false;
|
|
TPtGraph gA,gB;
|
|
gA.CreatePtGraphA(mLineA);
|
|
gB.CreatePtGraphB(mLineB);
|
|
TPGeLine2D lineA,lineB;
|
|
double paA,paB;
|
|
TPtNode *pNew;
|
|
TGPoint pt;
|
|
for (long i = 0;i<mLineA.GetVertexNum();i++)
|
|
{
|
|
mLineA.GetSegment(i,lineA);
|
|
for (long j = 0;j<mLineB.GetVertexNum();j++)
|
|
{
|
|
mLineB.GetSegment(j,lineB);
|
|
if (lineA.Intersect(lineB,paA,paB) == INT_1PT)
|
|
{
|
|
double dpA = paA-1,dpB = paB-1;
|
|
if (UPEQUAL_ZERO(paA) && DOWNEQUAL_ZERO(dpA) && UPEQUAL_ZERO(paB) && DOWNEQUAL_ZERO(dpB))
|
|
{
|
|
ret = true;
|
|
lineA.Pa2Pt(paA,pt);
|
|
pNew = new TPtNode(pt);
|
|
|
|
bool bBLeftA = lineA.IsVectorLeft(lineB);
|
|
bool bALeftB = !bBLeftA;
|
|
if (!EQUAL_ZERO(dpB))
|
|
{
|
|
if (UP_ZERO(paA) && DOWN_ZERO(dpA))
|
|
{
|
|
pNew->AddFlag(bBLeftA ? B_IN : B_OUT);
|
|
}
|
|
else if (EQUAL_ZERO(paA))
|
|
{
|
|
TPGeLine2D lineA0;
|
|
mLineA.GetSegment(i == 0 ? mLineA.GetVertexNum() - 1 : i - 1, lineA0);
|
|
if (!(lineA0.IsParallel(lineB) && lineA0.IsReverseDirection(lineB)))
|
|
{
|
|
bool bARightA0 = lineA0.IsVectorRight(lineA);
|
|
bool bBLeftA0 = lineA0.IsVectorLeft(lineB);
|
|
if (bARightA0)
|
|
{
|
|
pNew->AddFlag(bBLeftA0 || bBLeftA?B_IN:B_OUT);
|
|
}
|
|
else
|
|
{
|
|
pNew->AddFlag(bBLeftA0 && bBLeftA?B_IN:B_OUT);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TPGeLine2D lineA1;
|
|
mLineA.GetSegment(i == mLineA.GetVertexNum() - 1 ? 0 : i + 1, lineA1);
|
|
if (!(lineA1.IsParallel(lineB) && lineA1.IsSameDirection(lineB)))
|
|
{
|
|
bool bA1RightA = lineA.IsVectorRight(lineA1);
|
|
bool bBLeftA1 = lineA1.IsVectorLeft(lineB);
|
|
if (bA1RightA)
|
|
{
|
|
pNew->AddFlag(bBLeftA1 || bBLeftA?B_IN:B_OUT);
|
|
}
|
|
else
|
|
{
|
|
pNew->AddFlag(bBLeftA1 && bBLeftA?B_IN:B_OUT);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!EQUAL_ZERO(dpA))
|
|
{
|
|
if (UP_ZERO(paB) && DOWN_ZERO(dpB))
|
|
{
|
|
pNew->AddFlag(bALeftB?A_IN:A_OUT);
|
|
}
|
|
else if (EQUAL_ZERO(paB))
|
|
{
|
|
TPGeLine2D lineB0;
|
|
mLineB.GetSegment(j == 0 ? mLineB.GetVertexNum() - 1 : j - 1, lineB0);
|
|
if (!(lineB0.IsParallel(lineA) && lineB0.IsReverseDirection(lineA)))
|
|
{
|
|
bool bBRightB0 = lineB0.IsVectorRight(lineB);
|
|
bool bALeftB0 = lineB0.IsVectorLeft(lineA);
|
|
if (bBRightB0)
|
|
{
|
|
pNew->AddFlag(bALeftB0 || bALeftB?A_IN:A_OUT);
|
|
}
|
|
else
|
|
{
|
|
pNew->AddFlag(bALeftB0 && bALeftB?A_IN:A_OUT);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TPGeLine2D lineB1;
|
|
mLineB.GetSegment(j == mLineB.GetVertexNum()-1?0:j+1,lineB1);
|
|
if (!(lineB1.IsParallel(lineA) && lineB1.IsSameDirection(lineA)))
|
|
{
|
|
bool bB1RightB = lineB.IsVectorRight(lineB1);
|
|
bool bALeftB1 = lineB1.IsVectorLeft(lineA);
|
|
if (bB1RightB)
|
|
{
|
|
pNew->AddFlag(bALeftB1 || bALeftB?A_IN:A_OUT);
|
|
}
|
|
else
|
|
{
|
|
pNew->AddFlag(bALeftB1 && bALeftB?A_IN:A_OUT);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (EQUAL_ZERO(dpA))
|
|
{
|
|
gA.MoveTo(i+1);
|
|
if (gA.IsOut())
|
|
{
|
|
gA.MoveToFirst();
|
|
}
|
|
paA = 0;
|
|
}
|
|
else
|
|
{
|
|
gA.MoveTo(i);
|
|
}
|
|
|
|
if (EQUAL_ZERO(dpB))
|
|
{
|
|
gB.MoveTo(j+1);
|
|
if (gB.IsOut())
|
|
{
|
|
gB.MoveToFirst();
|
|
}
|
|
paB = 0;
|
|
}
|
|
else
|
|
{
|
|
gB.MoveTo(j);
|
|
}
|
|
|
|
pNew->SetPaA(paA);
|
|
pNew->SetPaB(paB);
|
|
|
|
gA.InsertA(pNew);
|
|
gB.InsertB(pNew);
|
|
if (UP_ZERO(paA) && UP_ZERO(paB))
|
|
{
|
|
AppendC(pNew);
|
|
}
|
|
else if (EQUAL_ZERO(paA) && EQUAL_ZERO(paB))
|
|
{
|
|
gB.AppendRef(gB.GetCur());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
gA.ClearRef();
|
|
gB.ClearRef();
|
|
Conbine(gA);
|
|
Conbine(gB);
|
|
return ret;
|
|
}
|
|
|
|
void TPtGraph::MakeListIn(TPDList<TPtList> &res)
|
|
{
|
|
for (MoveToFirst();!IsOut();MoveToNext())
|
|
{
|
|
TPtNode*p = GetCurData();
|
|
if (p->IsABNode())
|
|
{
|
|
p->MakeListIn(res);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TPtGraph::MakeListOut(TPDList<TPtList> &res)
|
|
{
|
|
for (MoveToFirst();!IsOut();MoveToNext())
|
|
{
|
|
TPtNode*p = GetCurData();
|
|
if (p->IsABNode())
|
|
{
|
|
p->MakeListOut(res);
|
|
}
|
|
}
|
|
}
|