//------------------------------------------------------------------------+ // Copyright (C), 1998-2011, Beijing Tangent Software Co. Ltd. // = FileName : TGGeVisibilityPoly2D类 // = Version : ver1.0 // = Author : cet // = CreateDate : 2011-04-13 // = Description: 具有可见性属性的poly2d类实现 // = Maintainers: // //------------------------------------------------------------------------+ #include "stdafx.h" #include "TGGeVisibilityPoly2D.h" #include "TchGlobalDef.h" namespace { bool IsOnSameLine(const AcGePoint3d &pt1, const AcGePoint3d &pt2, const AcGePoint3d &pt3) { AcGeVector3d vt1 = pt2 - pt1, vt2 = pt3 - pt2; return (vt1.isParallelTo(vt2) == Adesk::kTrue ? true : false); } // 求三点构成的弧的角度(pt2为弧中一点, pt1, pt3 为端点) double GetAngleBy3Pt(const TADSGePoint3d &pt1, const TADSGePoint3d &pt2, const TADSGePoint3d &pt3) { AcGeVector3d vt1 = pt1 - pt2; AcGeVector3d vt2 = pt3 - pt2; double dAngle = vt1.angleTo(vt2); // 夹角 dAngle = (PI - dAngle) * 2; // 根据圆内接四边形对角互补,并且四边形任意一角是其对应圆心角的一半 return dAngle; } } TGGeVisibilityPoly2D::TGGeVisibilityPoly2D() { m_arnVisibility.Reset(); } TGGeVisibilityPoly2D::TGGeVisibilityPoly2D( const TGGeVisibilityPoly2D & src ) { TADSGePointList::copyFrom(src); m_ardbulges.Reset(); m_ardbulges.copyFrom( src.m_ardbulges ); m_arnVisibility.Reset(); m_arnVisibility.copyFrom(src.m_arnVisibility); m_nFlag = src.GetFlag(); } TGGeVisibilityPoly2D::~TGGeVisibilityPoly2D() { } void TGGeVisibilityPoly2D::Reset() { TGGePoly2D::Reset(); m_arnVisibility.Reset(); } bool TGGeVisibilityPoly2D::SetAcDbCurve( AcDbCurve* pCurve ) { AcDbPolyline* pLwPoly = AcDbPolyline::cast(pCurve); if (pLwPoly == NULL ) { return false; } Reset(); // 清空数据 double dElev = pLwPoly->elevation(); // 标高 AcDb::Visibility visible = pLwPoly->visibility(); // 可见性 AcGePoint2d pt; double dBulge = 0.0; for (long i = 0; i < (long)pLwPoly->numVerts(); i++) { pLwPoly->getPointAt(i, pt); pLwPoly->getBulgeAt(i, dBulge); dBulge = atan(dBulge) * 4; // 角度,直线时为0,弧线时为弧的角度 AppendNode(TADSGePoint3d(pt.x, pt.y, dElev), dBulge, visible); } if (pLwPoly->isClosed()) { m_nFlag = 1; } else { m_nFlag = 0; } return true; } int TGGeVisibilityPoly2D::Nth( int nIndex, TGGeLine &xline, TGGeArc &xarc, AcDb::Visibility *pVal /*= NULL*/ ) const { if (!IsValid(nIndex)) // 判断索引是否有效 { return RTERROR; } int nLen = Length(); TADSGePoint3d p1 = (*this)[nIndex]; // 索引nIndex所对应线段的第一个点 TADSGePoint3d p2; if (nIndex == nLen - 1) // 第二个点 { p2 = (*this)[0]; } else { p2 = (*this)[nIndex + 1]; } // 线段的可见性 if (pVal != NULL) { AcDb::Visibility val = m_arnVisibility[nIndex]; *pVal = val; } double dAng = m_ardbulges[nIndex]; if (fabs(dAng) > 1.0E-6) // 线段为弧线 { xarc.Set(p1,p2,dAng); return ARC_SEGMENT; } else // 线段为直线 { xline.m_startPoint = p1; xline.m_endPoint = p2; return LINE_SEGMENT; } } int TGGeVisibilityPoly2D::Nth( int nIndex, TGGeCurveSegment & cvCurve, AcDb::Visibility *pVal /*= NULL*/ ) const { if (!IsValid(nIndex)) { return RTERROR; } static TGGeLine ln; static TGGeArc arc; int nflg = Nth(nIndex, ln, arc,pVal); int nFlag = cvCurve.m_nFlag; int nRet = RTNORM; switch(nflg) { case LINE_SEGMENT: cvCurve.m_startPoint = ln.m_startPoint; cvCurve.m_endPoint = ln.m_endPoint; cvCurve.m_dBulge = 0.0; break; case ARC_SEGMENT: cvCurve = arc; break; default: nRet = RTERROR; } cvCurve.m_nFlag = nFlag; return nRet; } int TGGeVisibilityPoly2D::Nth( int nIndex, TGGeDirectionCurve &curve, AcDb::Visibility *pVal /*= NULL*/ ) const { if (!IsValid(nIndex)) { return RTERROR; } int nLen = Length(); TADSGePoint3d p1 = (*this)[nIndex], p2; if (nIndex == nLen - 1) { p2 = (*this)[0]; } else { p2 = (*this)[nIndex + 1]; } if (pVal != NULL) { *pVal = m_arnVisibility[nIndex]; } double dAng = m_ardbulges[nIndex]; curve.m_startPoint = p1; curve.m_endPoint = p2; curve.m_dBulge = dAng; return RTNORM; } int TGGeVisibilityPoly2D::Reverse() { if (Length() < 2) { return RTERROR; } TGGeVisibilityPoly2D destPoly; int nTotalSeg = TotalSegments(); TGGeDirectionCurve cv; AcDb::Visibility visible = AcDb::kVisible; for (int i = nTotalSeg - 1; i >= 0; i--) { Nth(i, cv, &visible); destPoly.AppendNode(cv.EndPoint(), -cv.GetBulge(), visible); } if (!(m_nFlag & 0x01)) // 不闭合,添加原pline的第一个点 { destPoly.AppendNode(*((*this)[0]), -(*m_ardbulges[nTotalSeg]), *m_arnVisibility[nTotalSeg]); } destPoly.SetFlag(m_nFlag); *this = destPoly; return RTNORM; } int TGGeVisibilityPoly2D::Compress( bool bUnionCurve ) { int nLen = Length(); if (nLen < 1) { return RTERROR; } // 删除重复点 int nIndex = -1; // 重复点索引 for (int i = 0; i < nLen; i++) { if (nIndex == -1) { nIndex = i; continue; } TADSGePoint3d &pt1 = *((*this)[nIndex]); TADSGePoint3d &pt2 = *((*this)[i]); if (pt1.Distance(pt2) < _DIST_SNAP) // 两点重合 { RemoveNode(nIndex); // 删除前一个重合点 --i; // 调整i值使其仍指向pt2点的索引 --nLen; } nIndex = i; } // 检查最后一点和第一点是否重合(闭合时) if (m_nFlag == 1 && (*((*this)[0])).Distance(*((*this)[nLen - 1])) < _DIST_SNAP) // 两点重合 { RemoveNode(nLen - 1); // 删除最后一点 } if (!bUnionCurve) { return RTNORM; } // 合并可见性相同的共线或共圆的线段 nIndex = -1; // nIndex代表需要和当前索引i对应的线段对比的线段索引(前一点索引) int bMerged = 0; // 是否可合并 TGGeArc arc1, arc2; TGGeLine line1, line2; int nType1 = 0, nType2 = 0; // 线型 int nNextIndex = -1; // 下一点索引 for (i = 0; i < Length(); i++) { if (nIndex == -1) { nIndex = i; continue; } nNextIndex = i + 1; if (i == Length() - 1 && m_nFlag == 1) // 曲线闭合在最后一点时,修改索引值 { nNextIndex = 0; } else if (i == Length() - 1 && m_nFlag == 0) // 曲线不闭合在最后一点时,退出 { break; } if (*(m_arnVisibility[nIndex]) == *(m_arnVisibility[i])) // 可见性相同 { nType1 = Nth(nIndex, line1, arc1, NULL); nType2 = Nth(i, line2, arc2,NULL); if (nType1 == nType2 && nType1 == LINE_SEGMENT) // 同为直线 { if (IsOnSameLine(*((*this)[nIndex]), *((*this)[i]), *((*this)[nNextIndex]))) // 共线 { RemoveNode(i); // 删除共线直线相交的点 --i; // 调整i值使其指向合并后的直线对应索引 } } else if (nType1 == nType2 && nType1 == ARC_SEGMENT) // 同为弧线 { if (fabs(arc1.GetRadius() - arc2.GetRadius()) < _DIST_SNAP && arc1.GetCenterPt() == arc2.GetCenterPt()) // 共圆 { double dAngle = GetAngleBy3Pt(*((*this)[nIndex]), *((*this)[i]), *((*this)[nNextIndex])); // 合并后的新弧的角度 double dBugle = tan(dAngle/4); // 新弧凸度值 dBugle = tan(*(m_ardbulges[nIndex]) / 4) < g_angleZero ? fabs(dBugle) * (-1) : fabs(dBugle); // 根据TGGeVisibilityPoly2D在nIndex的凸度值确定合并后的弧段的凸度值 *(m_ardbulges[nIndex]) = atan(dBugle) * 4; // 修改nIndex的凸度值 RemoveNode(i); // 删除共线直线相交的点 --i; // 调整i值使其指向合并后的直线对应索引 } } } nIndex = i; } // 曲线闭合时处理最后一段和第一段 nLen = Length(); if (m_nFlag == 1 && nLen > 1 && *(m_arnVisibility[0]) == *(m_arnVisibility[nLen - 1])) { nType1 = Nth(0, line1, arc1, NULL); nType2 = Nth(nLen - 1, line2, arc2,NULL); if (nType1 == nType2 && nType1 == LINE_SEGMENT) // 同为直线 { // 检查是否共线 if (IsOnSameLine(*((*this)[nLen - 1]), *((*this)[0]), *((*this)[1]))) // 共线 { RemoveNode(0); // 删除共线直线相交的点 } } else if (nType1 == nType2 && nType1 == ARC_SEGMENT) // 同为弧线 { if (fabs(arc1.GetRadius() - arc2.GetRadius()) < _DIST_SNAP && arc1.GetCenterPt() == arc2.GetCenterPt()) // 共圆 { double dAngle = GetAngleBy3Pt(*((*this)[nLen - 1]), *((*this)[0]), *((*this)[1])); // 合并后的新弧的角度 double dBugle = tan(dAngle/4); // 新弧凸度值 dBugle = *(m_ardbulges[nLen - 1]) < g_angleZero ? fabs(dBugle) * (-1) : fabs(dBugle); // 根据TGGeVisibilityPoly2D在nIndex的凸度值确定合并后的弧段的凸度值 *(m_ardbulges[nLen - 1]) = atan(dBugle) * 4; // 修改nIndex的凸度值 RemoveNode(0); // 删除共线直线相交的点 } } } return RTNORM; } int TGGeVisibilityPoly2D::Make( LPCTSTR szLay /*= NULL*/ ) const { int nLen = Length(); if (nLen <= 1) { return RTERROR; } std::vector > vecIndex; // 保存需绘制的所有pline的索引 std::vector vec; bool bExist = false; // 是否在已有的vec中添加索引 for (int i = 0; i < nLen; i++) { if (!bExist) { vec.clear(); bExist = true; } if (m_arnVisibility[i] == AcDb::kVisible) { vec.push_back(i); } else { bExist = false; if (!vec.empty()) { vec.push_back(i); vecIndex.push_back(vec); } } } if (!vec.empty()) { vecIndex.push_back(vec); } // 当TGGeVisibilityPoly2D的第一个点和最后一个点均可见并且是闭合线时, 合并第一条和最后一条pline int nSize = vecIndex.size(); std::vector::iterator it; if (m_nFlag == 1 // 闭合 && m_arnVisibility[0] == AcDb::kVisible && m_arnVisibility[nLen - 1] == AcDb::kVisible // 第一点和最后一点均可见 && nSize > 1) // 存在多条pline { std::vector &vec1 = vecIndex[0], &vec2 = vecIndex[nSize - 1]; for (it = vec1.begin(); it != vec1.end(); it++) { vec2.push_back(*it); } vecIndex.erase(vecIndex.begin()); } // 绘制pline int nIndex = 0; std::vector >::iterator it2; for (it2 = vecIndex.begin(); it2 != vecIndex.end(); it2++) { AcDbPolyline *pLine = new AcDbPolyline; for (it = (*it2).begin(), nIndex = 0; it != (*it2).end(); it++, nIndex++) { double dBuge = tan(m_ardbulges[*it] / 4.0); pLine->addVertexAt(nIndex, (*this)[*it].AsAcGePoint2d(), dBuge); } if (nSize == 1 && m_nFlag == 1 && (*it2).size() == nLen) // 所有点可见并且是闭合线 { pLine->setClosed(Adesk::kTrue); } if (szLay) { AssureLayer(szLay, LAYSTAT_UNLOCK); pLine->setLayer(szLay); } double dThickness = 0.0; TGGetVar(_T("THICKNESS"), &dThickness); pLine->setThickness(dThickness); pLine->setElevation((*this)[0].z); AddToModelSpace(pLine, Adesk::kTrue); } return RTNORM; } int TGGeVisibilityPoly2D::MakeSegments( LPCTSTR szLay /*= NULL*/ ) const { int nLen = Length(); for (int i = 0; i < nLen; i++) { MakeSegment(i, szLay); } return RTNORM; } int TGGeVisibilityPoly2D::MakeSegment( int nIndex, LPCTSTR szLay /*= NULL*/ ) const { TGGeLine line; TGGeArc arc; AcDb::Visibility eVal; int nrc = Nth(nIndex, line, arc, &eVal); if (nrc == LINE_SEGMENT && eVal == AcDb::kVisible) { line.Make(szLay); } else if (nrc == ARC_SEGMENT && eVal == AcDb::kVisible) { arc.Make(szLay); } return RTNORM; } void TGGeVisibilityPoly2D::TransformBy( const AcGeMatrix3d &mat ) { TGGePoly2D::TransformBy(mat); } void TGGeVisibilityPoly2D::RemoveNode( long nIndex ) { TGGePoly2D::RemoveNode(nIndex); m_arnVisibility.Remove(nIndex); } void TGGeVisibilityPoly2D::InsertNodeAt( int nIndex, const TADSGePoint3d &pt, double dBulge, AcDb::Visibility eVal ) { if (nIndex >= Length() - 1) { AppendNode(pt, dBulge, eVal); } else { (*this)[nIndex + 1]; Insert(new TADSGePoint3d(pt)); m_ardbulges[nIndex + 1]; m_ardbulges.Insert(new double(dBulge)); AcDb::Visibility *pVal = new AcDb::Visibility(); *pVal = eVal; m_arnVisibility[nIndex + 1]; m_arnVisibility.Insert(pVal); } } void TGGeVisibilityPoly2D::InsertNodeAt( const TADSGePoint3d &ptOn, AcDb::Visibility eVal ) { // 检查ptOn是否在线上 int nLen = Length(); if (nLen == 2) // 只有一段线时 { TGGeLine line; TGGeArc arc; int nType = Nth(0, line, arc, NULL); // 获得线段 if (nType == LINE_SEGMENT) { TADSGePoint3d ptS = line.StartPoint(), ptE = line.EndPoint(); double dDist1 = ptS.Distance(ptOn); double dDist2 = ptE.Distance(ptOn); double dDist = ptS.Distance(ptE); if (fabs(dDist - dDist1 - dDist2) > _DIST_SNAP) // 检查点ptOn是否在直线上 { return; } } else if (nType == ARC_SEGMENT) { if (!(arc.PtOnArc(ptOn))) // 检查点ptOn是否在弧线上 { return; } } else { return; } } else if ((ptOn & (*this)) != PR_EDGE) // 存在多段线段,并且ptOn不在线上 { return; } // ptOn在顶点上 for (int i = 0; i < nLen; i++) { TADSGePoint3d pt = *((*this)[i]); if (pt.Distance(ptOn) < _DIST_SNAP) { *(m_arnVisibility[i]) = eVal; // ptOn在顶点上时直接修改其可见性即可 return; } } // ptOn在线上并且不为顶点 TGGeLine line; TGGeArc arc; TADSGePoint3d pt1, pt2; for (i = 0; i < nLen; i++) { int nType = Nth(i, line, arc); // 获取索引i对应的线段 if (nType == LINE_SEGMENT) { line.GetStartPoint(pt1); line.GetEndPoint(pt2); double dDist = pt1.Distance(pt2); // 直线长度 double dDist2 = pt1.Distance(ptOn) + pt2.Distance(ptOn); // ptOn到直线段两点距离之和 if (fabs(dDist2 - dDist) < _DIST_SNAP) // 判断点是否在直线上 { if (i == nLen - 1) { (*this).Append(new TADSGePoint3d(ptOn)); m_ardbulges.Append(new double(0.0)); AcDb::Visibility *pVal = new AcDb::Visibility(); *pVal = eVal; m_arnVisibility.Append(pVal); } else { (*this)[i+1]; (*this).Insert(new TADSGePoint3d(ptOn)); m_ardbulges[i+1]; m_ardbulges.Insert(new double(0.0)); AcDb::Visibility *pVal = new AcDb::Visibility(); *pVal = eVal; m_arnVisibility[i+1]; m_arnVisibility.Insert(pVal); } break; } } else if (nType == ARC_SEGMENT) { if(arc.PtOnArc(ptOn)) // 判断点是否在弧上 { pt1 = *((*this)[i]); if (i == nLen - 1) { pt2 = *((*this)[0]); } else { pt2 = *((*this)[i + 1]); } // 求被ptOn分为两段的弧的凸度值 TADSGePoint3d pt; arc.GetStartPoint(pt); double dAngle1 = 0.0; // pt1与ptOn弧段的角度 double dAngle2 = 0.0; // pt2与ptOn弧段的角度 if (pt1.Distance(pt) < _DIST_SNAP) //pt1为弧起点 { pt = arc.GetCenterPt(); AcGeVector3d vt1 = pt1 - pt; AcGeVector3d vt2 = ptOn - pt; AcGeVector3d vt3 = pt2 - pt; dAngle1 = vt1.angleTo(vt2, AcGeVector3d::kZAxis); dAngle2 = vt2.angleTo(vt3, AcGeVector3d::kZAxis); } else // pt2为弧起点 { pt = arc.GetCenterPt(); AcGeVector3d vt1 = pt1 - pt; AcGeVector3d vt2 = ptOn - pt; AcGeVector3d vt3 = pt2 - pt; dAngle1 = vt2.angleTo(vt1, AcGeVector3d::kZAxis); dAngle2 = vt3.angleTo(vt2, AcGeVector3d::kZAxis); } double dBugle1 = tan(dAngle1 / 4); // 凸度值 double dBugle2 = tan(dAngle2 / 4); // 根据原弧的凸度正负值确定新弧凸度值 double dBugle = tan(*(m_ardbulges[i]) / 4); dBugle1 = dBugle > g_angleZero ? fabs(dBugle1) : fabs(dBugle1) * (-1); dBugle2 = dBugle > g_angleZero ? fabs(dBugle2) : fabs(dBugle2) * (-1); dAngle1 = atan(dBugle1) * 4; dAngle2 = atan(dBugle2) * 4; // 插入ptOn点 *(m_ardbulges[i]) = dAngle1; // 修改原弧凸度值 AcDb::Visibility *pVal = new AcDb::Visibility(); *pVal = eVal; if (i == nLen - 1) { m_ardbulges.Append(new double(dAngle2)); m_arnVisibility.Append(pVal); (*this).Append(new TADSGePoint3d(ptOn)); } else { m_ardbulges[i+1]; m_ardbulges.Insert(new double(dAngle2)); m_arnVisibility[i+1]; m_arnVisibility.Insert(pVal); (*this)[i+1]; (*this).Insert(new TADSGePoint3d(ptOn)); } break; } } } } void TGGeVisibilityPoly2D::InsertNodeAt(const TADSGePoint3d &ptOn1, const TADSGePoint3d &ptOn2,AcDb::Visibility eVal) { int nIndex1 = HitTestOnCurve(ptOn1); int nIndex2 = HitTestOnCurve(ptOn2); if (nIndex1 == 0 || nIndex2 == 0) // 有点不在线上 { return; } AcDb::Visibility eValTemp1 = AcDb::kVisible; AcDb::Visibility eValTemp2 = AcDb::kVisible; if (nIndex1 < 0) // 非顶点 { eValTemp1 = GetVisibleAt(-nIndex1 - 1); } if (nIndex2 < 0) // 非顶点 { eValTemp2 = GetVisibleAt(-nIndex2 - 1); } if (nIndex1 < 0) // 非顶点 { InsertNodeAt(ptOn1,eValTemp1); } if (nIndex2 < 0) // 非顶点 { InsertNodeAt(ptOn2,eValTemp2); } nIndex1 = HitTestOnCurve(ptOn1); nIndex2 = HitTestOnCurve(ptOn2); if (nIndex1 <= 0) { return; } if (nIndex2 <= 0) { return; } --nIndex1; --nIndex2; int nMin = nIndex1 < nIndex2 ? nIndex1 : nIndex2; int nMax = nIndex2 < nIndex1 ? nIndex1 : nIndex2; for(int i = nMin; i < nMax; i++) { SetVisibleAt(i, eVal); } } void TGGeVisibilityPoly2D::AppendNode( const TADSGePoint3d &pt, ads_real dBulge, AcDb::Visibility eVal ) { TGGePoly2D::AppendNode(pt, dBulge); AcDb::Visibility *pVal = new AcDb::Visibility(); *pVal = eVal; m_arnVisibility.Append(pVal); } TGGeVisibilityPoly2D& TGGeVisibilityPoly2D::operator=( const TGGeVisibilityPoly2D &src ) { if (this != &src) { Reset(); m_nFlag = src.m_nFlag; for(int i = 0; i < src.Length(); i++) { const TADSGePoint3d &pt = src[i]; double val = src.m_ardbulges[i]; AcDb::Visibility *pVal = new AcDb::Visibility(); *pVal = src.GetVisibleAt(i); Append(new TADSGePoint3d(pt)); m_ardbulges.Append(new ads_real(val)); m_arnVisibility.Append(pVal); } } return *this; } void TGGeVisibilityPoly2D::SetVisible( AcDb::Visibility dNewVal ) { int nLen = Length(); for (int i = 0; i < nLen; i++) { *m_arnVisibility[i] = dNewVal; } } void TGGeVisibilityPoly2D::SetVisibleAt( int nIndex, AcDb::Visibility dNewVal ) { if (!IsValid(nIndex)) { return; } *m_arnVisibility[nIndex] = dNewVal; } void TGGeVisibilityPoly2D::SetVisibleAt( const TADSGePoint3d& ptOn, AcDb::Visibility dNewVal ) { int nLen = Length(); for (int i = 0; i < nLen; i++) { if (ptOn.Distance(*((*this)[i])) < _DIST_SNAP) { *m_arnVisibility[i] = dNewVal; break; } } } void TGGeVisibilityPoly2D::SetVisibleAt( int nFrom, int nTo, AcDb::Visibility dNewVal ) { int nLen = Length(); if (IsValid(nFrom) && IsValid(nTo) && nFrom <= nTo) { for (int i = nFrom; i <= nTo; i++) { *m_arnVisibility[i] = dNewVal; } } } AcDb::Visibility TGGeVisibilityPoly2D::GetVisibleAt( int nIndex ) const { AcDb::Visibility eVal = AcDb::kVisible; if (IsValid(nIndex)) { eVal = m_arnVisibility[nIndex]; } return eVal; } AcDb::Visibility TGGeVisibilityPoly2D::GetVisibleAt( const TADSGePoint3d& ptOn ) const { AcDb::Visibility eVal = AcDb::kVisible; int nLen = Length(); for (int i = 0; i < nLen; i++) { if ((*this)[i] == ptOn) { eVal = m_arnVisibility[i]; break; } } return eVal; } int TGGeVisibilityPoly2D::SetVisibilities( TDPtrList &arnVisibility ) { if (arnVisibility.Length() > 0) { m_arnVisibility.copyFrom(arnVisibility); return m_arnVisibility.Length(); } return -1; } int TGGeVisibilityPoly2D::GetVisibilities( TDPtrList &arnVisibility ) { if (m_arnVisibility.Length() > 0) { arnVisibility.copyFrom(m_arnVisibility); return arnVisibility.Length(); } return -1; } TDPtrList& TGGeVisibilityPoly2D::GetVisibilities() { return m_arnVisibility; } // add by xlc on 110427 获得poly离pt点近的一端指向poly内的方向 // 返回值:true:成功;false:失败 bool TGGeVisibilityPoly2D::GetIDirection(AcGePoint3d pt, double& dDir) { if (TotalSegments() < 1) { return false; } TGGeCurveSegment cvSeg; if (pt.distanceTo(*(*this)[0]) < pt.distanceTo(*(*this)[Length()-1])) { Nth(0, cvSeg); if (cvSeg.GetBulge() < _angSnap) //直线段 { dDir = cvSeg.IDirection(0); } else { if (pt.distanceTo(cvSeg.StartPoint()) < pt.distanceTo(cvSeg.EndPoint())) { dDir = cvSeg.IDirection(0); } else { dDir = cvSeg.IDirection(1); } } } else { Nth(TotalSegments()-1, cvSeg); if (cvSeg.GetBulge() < _angSnap) //直线段 { dDir = cvSeg.IDirection(1); } else { if (pt.distanceTo(cvSeg.StartPoint()) < pt.distanceTo(cvSeg.EndPoint())) { dDir = cvSeg.IDirection(0); } else { dDir = cvSeg.IDirection(1); } } } return true; }