//-----------------------------------------------------------------------------+ // 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 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 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 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 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&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