547 lines
9.6 KiB
C++
547 lines
9.6 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
|
|
// = FileName : TPGeCurve2D.cpp
|
|
// = Version : ver2.0
|
|
// = Author : xlc
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: 类的定义
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "TPGeCurve2D.h"
|
|
#include "TGPoint2D.h"
|
|
#include "TGPCurve3D.h"
|
|
#include "TGRegion2D.h"
|
|
#include "TPushMemVar.h"
|
|
#include "TProductid.h"
|
|
|
|
extern int g_nProductId;
|
|
|
|
IMPLEMENT_RUN_TIME_CLASS1(TPGeCurve2D,"TPGeCurve2D",TGObject2D)
|
|
|
|
|
|
TPGeCurve2D::~TPGeCurve2D()
|
|
{
|
|
|
|
}
|
|
|
|
bool TPGeCurve2D::IsInclude(const TGObject&obj) const
|
|
{
|
|
if(IS_CLASS(&obj,TGRegion2D))
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return TGObject2D::IsInclude(obj);
|
|
}
|
|
}
|
|
|
|
double TPGeCurve2D::Length() const
|
|
{
|
|
TGObjectList oList;
|
|
double dLength = 0;
|
|
if(Explode(oList))
|
|
{
|
|
for(oList.MoveToFirst(); !oList.IsOut(); oList.MoveToNext())
|
|
{
|
|
dLength += oList.GetCurCurve2D().Length();
|
|
}
|
|
}
|
|
|
|
return dLength;
|
|
}
|
|
|
|
double TPGeCurve2D::AllIntegration() const
|
|
{
|
|
TGObjectList oList;
|
|
if(Explode(oList))
|
|
{
|
|
double dr = 0;
|
|
for(oList.MoveToFirst(); !oList.IsOut(); oList.MoveToNext())
|
|
{
|
|
dr += oList.GetCurCurveSeg2D().AllIntegration();
|
|
}
|
|
return dr;
|
|
}
|
|
else
|
|
{
|
|
return Integration(0,1);
|
|
}
|
|
}
|
|
|
|
GRelation TPGeCurve2D::HitTest(const TGPoint&pt) const
|
|
{
|
|
GRelation r = TGObject::HitTest(pt);
|
|
if(!IsClosed())
|
|
{
|
|
return r;
|
|
}
|
|
|
|
if(r.Is(GR_IN))
|
|
{
|
|
return GR_IN;
|
|
}
|
|
|
|
TPGeGLine2D line(pt,TGPoint(pt.x,pt.y+1));
|
|
TGObjectList interList;
|
|
if(!Intersect(line,interList))
|
|
{
|
|
return GR_OUTSIDE;
|
|
}
|
|
|
|
TSqTable<double> paList(interList.GetLength());
|
|
for(interList.MoveToFirst();!interList.IsOut();interList.MoveToNext())
|
|
{
|
|
if(interList.GetCurData()->HitTest(pt).Is(GR_IN))
|
|
{
|
|
return GR_IN;
|
|
}
|
|
else
|
|
{
|
|
double pa;
|
|
line.Pt2Pa(interList.GetCurData()->GetSamplePoint(),pa);
|
|
paList.AddTail(pa);
|
|
}
|
|
}
|
|
paList.Arrange();
|
|
|
|
if(paList[0]>0)
|
|
{
|
|
return GR_OUTSIDE;
|
|
}
|
|
|
|
for(long i = 1;i < paList.GetLength(); i++)
|
|
{
|
|
if(paList[i] > 0)
|
|
{
|
|
TGPoint pt0,pt1;
|
|
line.Pa2Pt(paList[i - 1],pt0);
|
|
line.Pa2Pt(paList[i],pt1);
|
|
double pa0,pa1;
|
|
Pt2Pa(pt0,pa0);
|
|
Pt2Pa(pt1,pa1);
|
|
double area = AllIntegration();
|
|
TPGeCurve2D *pSeg = GetSubCurve(pa0,pa1);
|
|
double area1 = pSeg->AllIntegration();
|
|
double area2 = area - area1;
|
|
delete pSeg;
|
|
if((area1 > 0 && area2 > 0) || (area1 < 0 && area2 < 0))
|
|
{
|
|
return GR_INSIDE;
|
|
}
|
|
else
|
|
{
|
|
return GR_OUTSIDE;
|
|
}
|
|
}
|
|
}
|
|
return GR_OUTSIDE;
|
|
}
|
|
|
|
void TPGeCurve2D::Cut(const TGObject&obj,TGObjectList&left,TGObjectList &right,TGObjectList&mid) const
|
|
{
|
|
if(IS_CLASS(&obj,TPGeCurve2D))
|
|
{
|
|
//modify by xlc on 110610 区分日照,影响速度
|
|
if (g_nProductId != kTSUN)
|
|
{
|
|
const TPGeCurve2D& curve = (const TPGeCurve2D&)obj;
|
|
TGObjectList interList;
|
|
if(!Intersect(curve,interList))
|
|
{
|
|
GRelation r = HitTest(curve.GetSamplePoint());
|
|
if(r.Is(GR_RIGHT))
|
|
{
|
|
right << curve.Clone();
|
|
}
|
|
else
|
|
{
|
|
left << curve.Clone();
|
|
}
|
|
return;
|
|
}
|
|
TSqTable<double> paList(interList.GetLength());
|
|
for(interList.MoveToFirst(); !interList.IsOut(); interList.MoveToNext())
|
|
{
|
|
if(IS_TYPE(interList.GetCurData(),TGPoint2D))
|
|
{
|
|
double pa;
|
|
curve.Pt2Pa((TGPoint2D&)interList.GetCurPData(),pa);
|
|
paList.AddTail(pa);
|
|
}
|
|
else
|
|
{
|
|
TGPoint pt;
|
|
double pa;
|
|
TPGeCurve2D& subCurve = interList.GetCurCurve2D();
|
|
if(subCurve.IsFinite(true))
|
|
{
|
|
subCurve.GetStartPoint(pt);
|
|
curve.Pt2Pa(pt,pa);
|
|
paList.AddTail(pa);
|
|
}
|
|
if(subCurve.IsFinite(false))
|
|
{
|
|
subCurve.GetEndPoint(pt);
|
|
curve.Pt2Pa(pt,pa);
|
|
paList.AddTail(pa);
|
|
}
|
|
}
|
|
}
|
|
TGObjectList subCurve;
|
|
if(paList.IsEmpty())
|
|
{
|
|
mid << curve.Clone();
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
paList.Arrange();
|
|
curve.Split(paList,subCurve);
|
|
}
|
|
for(subCurve.MoveToFirst();!subCurve.IsOut();subCurve.MoveToNext())
|
|
{
|
|
GRelation r = HitTest(subCurve.GetCurPData().GetSamplePoint());
|
|
|
|
if(r.Is(GR_IN))
|
|
{
|
|
mid << subCurve.FetchCur();
|
|
}
|
|
else if(r.Is(GR_RIGHT))
|
|
{
|
|
right << subCurve.FetchCur();
|
|
}
|
|
else
|
|
{
|
|
left << subCurve.FetchCur();
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
//add by xlc on 100906 解决部分加粗不显示的问题
|
|
TPushMemVar<double> vPrec(g_distZero,1.0e-6);
|
|
|
|
const TPGeCurve2D& curve = (const TPGeCurve2D&)obj;
|
|
TGObjectList interList;
|
|
if(!Intersect(curve,interList))
|
|
{
|
|
GRelation r = HitTest(curve.GetSamplePoint());
|
|
if(r.Is(GR_RIGHT))
|
|
{
|
|
right << curve.Clone();
|
|
}
|
|
else
|
|
{
|
|
left << curve.Clone();
|
|
}
|
|
return;
|
|
}
|
|
TSqTable<double> paList(interList.GetLength());
|
|
for(interList.MoveToFirst(); !interList.IsOut(); interList.MoveToNext())
|
|
{
|
|
if(IS_TYPE(interList.GetCurData(),TGPoint2D))
|
|
{
|
|
double pa;
|
|
curve.Pt2Pa((TGPoint2D&)interList.GetCurPData(),pa);
|
|
paList.AddTail(pa);
|
|
}
|
|
else
|
|
{
|
|
TGPoint pt;
|
|
double pa;
|
|
TPGeCurve2D& subCurve = interList.GetCurCurve2D();
|
|
if(subCurve.IsFinite(true))
|
|
{
|
|
subCurve.GetStartPoint(pt);
|
|
curve.Pt2Pa(pt,pa);
|
|
paList.AddTail(pa);
|
|
}
|
|
if(subCurve.IsFinite(false))
|
|
{
|
|
subCurve.GetEndPoint(pt);
|
|
curve.Pt2Pa(pt,pa);
|
|
paList.AddTail(pa);
|
|
}
|
|
}
|
|
}
|
|
TGObjectList subCurve;
|
|
if(paList.IsEmpty())
|
|
{
|
|
mid << curve.Clone();
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
paList.Arrange();
|
|
curve.Split(paList,subCurve);
|
|
}
|
|
for(subCurve.MoveToFirst();!subCurve.IsOut();subCurve.MoveToNext())
|
|
{
|
|
GRelation r = HitTest(subCurve.GetCurPData().GetSamplePoint());
|
|
|
|
if(r.Is(GR_IN))
|
|
{
|
|
mid << subCurve.FetchCur();
|
|
}
|
|
else if(r.Is(GR_RIGHT))
|
|
{
|
|
right << subCurve.FetchCur();
|
|
}
|
|
else
|
|
{
|
|
left << subCurve.FetchCur();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
else if(IS_CLASS(&obj,TGRegion2D))
|
|
{
|
|
((const TGRegion2D&)obj).CutBy(*this,left,right);
|
|
}
|
|
else
|
|
{
|
|
const TGPoint2D&pt = (const TGPoint2D&)obj;
|
|
GRelation r = HitTest(pt);
|
|
if(r.Is(GR_IN))
|
|
{
|
|
mid << new TGPoint2D(pt);
|
|
}
|
|
else if(r.Is(GR_RIGHT))
|
|
{
|
|
right << new TGPoint2D(pt);
|
|
}
|
|
else
|
|
{
|
|
left << new TGPoint2D(pt);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool TPGeCurve2D::IsConnect(const TPGeCurve2D&seg) const
|
|
{
|
|
if(!IsFinite(false) || !seg.IsFinite(true))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
TGPoint2D pt0,pt1;
|
|
GetEndPoint(pt0);
|
|
seg.GetStartPoint(pt1);
|
|
return pt0 == pt1;
|
|
}
|
|
|
|
bool TPGeCurve2D::IsClosed() const
|
|
{
|
|
TGPoint2D pt0,pt1;
|
|
GetStartPoint(pt0);
|
|
GetEndPoint(pt1);
|
|
return pt0 == pt1;
|
|
}
|
|
|
|
TGMLine2D* TPGeCurve2D::MLinearize(double paDist) const
|
|
{
|
|
if(!IsCurveSeg())
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if(paDist < 1E-9)
|
|
{
|
|
paDist = GetMLinePrec();
|
|
}
|
|
|
|
long num = (long)(1 / paDist + 0.999999);
|
|
if(num < 1)
|
|
{
|
|
num = 1;
|
|
}
|
|
if(num < 2 && IsClosed())
|
|
{
|
|
num = 2;
|
|
}
|
|
TGMLine2D *pMLine = new TGMLine2D(IsClosed() ? num : num + 1,IsClosed());
|
|
paDist = 1.0 / num;
|
|
double pa = 0;
|
|
for(long i = 0; i < num; i++, pa += paDist)
|
|
{
|
|
Pa2Pt(pa,(*pMLine)[i]);
|
|
}
|
|
if(!IsClosed())
|
|
{
|
|
GetEndPoint((*pMLine)[i]);
|
|
}
|
|
return pMLine;
|
|
}
|
|
|
|
bool TPGeCurve2D::IsClockwise() const
|
|
{
|
|
return AllIntegration() > 0;
|
|
}
|
|
|
|
double TPGeCurve2D::Area() const
|
|
{
|
|
if(IsClosed())
|
|
{
|
|
return fabs(AllIntegration());
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void TPGeCurve2D::Split(const TTable<double>&paTable,TGObjectList&res) const
|
|
{
|
|
if(paTable.IsEmpty())
|
|
{
|
|
return;
|
|
}
|
|
if(IsClosed())
|
|
{
|
|
if(paTable.GetLength() == 1)
|
|
{
|
|
res << GetSubCurve(paTable.GetAt(0),paTable.GetAt(0));
|
|
}
|
|
else
|
|
{
|
|
for(long i = 1;i < paTable.GetLength(); i++)
|
|
{
|
|
if(DOWN_ZERO(paTable.GetAt(i - 1) - paTable.GetAt(i)))
|
|
{
|
|
res << GetSubCurve(paTable.GetAt(i - 1),paTable.GetAt(i));
|
|
}
|
|
}
|
|
double last = paTable.GetAt(i-1);
|
|
if(DOWN_ZERO(last - 1) || UP_ZERO(paTable.GetAt(0)))
|
|
{
|
|
res << GetSubCurve(last,paTable.GetAt(0));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(UP_ZERO(paTable.GetAt(0)))
|
|
{
|
|
res << GetSubCurve(0,paTable.GetAt(0));
|
|
}
|
|
for(long i = 1;i<paTable.GetLength();i++)
|
|
{
|
|
if(DOWN_ZERO(paTable.GetAt(i - 1) - paTable.GetAt(i)))
|
|
{
|
|
res << GetSubCurve(paTable.GetAt(i - 1),paTable.GetAt(i));
|
|
}
|
|
}
|
|
if(DOWN_ZERO(paTable.GetAt(i - 1) - 1))
|
|
{
|
|
res << GetSubCurve(paTable.GetAt(i - 1),1);
|
|
}
|
|
}
|
|
}
|
|
|
|
TGObject3D* TPGeCurve2D::Convert3D() const
|
|
{
|
|
return new TGPCurve3D((TPGeCurve2D*)Clone());
|
|
}
|
|
|
|
void TPGeCurve2D::GetStartPoint(TGPoint&pt) const
|
|
{
|
|
Pa2Pt(0,pt);
|
|
}
|
|
|
|
void TPGeCurve2D::GetEndPoint(TGPoint&pt) const
|
|
{
|
|
Pa2Pt(1,pt);
|
|
}
|
|
|
|
void TPGeCurve2D::GetMidPoint(TGPoint&pt) const
|
|
{
|
|
Pa2Pt(0.5,pt);
|
|
}
|
|
|
|
bool TPGeCurve2D::IsCurveSeg() const
|
|
{
|
|
return IsFinite(true) && IsFinite(false);
|
|
}
|
|
|
|
bool TPGeCurve2D::IsFinite() const
|
|
{
|
|
return IsCurveSeg() || IsClosed();
|
|
}
|
|
|
|
bool TPGeCurve2D::IsInfinite() const
|
|
{
|
|
return !IsClosed() && !IsFinite(true) && !IsFinite(false);
|
|
}
|
|
|
|
bool TPGeCurve2D::IsFinite(bool bStart) const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool TPGeCurve2D::IsSelfCross() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
void TPGeCurve2D::Pa2Pt(double pa,TGPoint&pt) const
|
|
{
|
|
|
|
}
|
|
|
|
void TPGeCurve2D::Pt2Pa(const TGPoint&pt,double&pa) const
|
|
{
|
|
|
|
}
|
|
|
|
void TPGeCurve2D::GetTangent(double pa,TPGeLine2D&line) const
|
|
{
|
|
|
|
}
|
|
|
|
double TPGeCurve2D::Integration(double pa0,double pa1) const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void TPGeCurve2D::Reverse()
|
|
{
|
|
|
|
}
|
|
|
|
TGPoint TPGeCurve2D::GetSamplePoint() const
|
|
{
|
|
TGPoint pt;
|
|
GetMidPoint(pt);
|
|
return pt;
|
|
}
|
|
|
|
TGMLine2D* TPGeCurve2D::PLinearize(double paDist/* = 0*/) const
|
|
{
|
|
return MLinearize(paDist);
|
|
}
|
|
|
|
double TPGeCurve2D::GetMLinePrec() const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
TPGeCurve2D* TPGeCurve2D::GetExtendCurve() const
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
TPGeCurve2D* TPGeCurve2D::GetSubCurve(double pa0,double pa1) const
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
bool TPGeCurve2D::Offset(double offset)
|
|
{
|
|
return false;
|
|
}
|