1381 lines
28 KiB
C++
1381 lines
28 KiB
C++
#include "stdafx.h"
|
|
#include "globalFunc.h"
|
|
#include "AcDbObjectPtr.h"
|
|
#include "CollectElevation.h"
|
|
#include "aecdbtext.h"
|
|
#include "dbxline.h"
|
|
#include <algorithm>
|
|
#include "AecDbSymbElevation.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[]=__FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
CCollectElevation::CCollectElevation()
|
|
{
|
|
m_nMinObjectCount = 5;
|
|
m_dAngel = PI/4;
|
|
m_bExternalBlk = false; // cet 2011.12.2 add
|
|
}
|
|
|
|
|
|
CCollectElevation::~CCollectElevation()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
bool CCollectElevation::GetSelectPointElevation(XPoint ptSel,Entity ent,int nType, double &dEle)
|
|
{
|
|
bool bRet = true;
|
|
PickSet ssAll(SS_FREE);
|
|
ssAll += m_ssAll;
|
|
// 获取实体的id和插入点
|
|
GetAllPickSetPt(ssAll, ptSel, nType);
|
|
if (m_nLandForm == 0) // 平地采集
|
|
{
|
|
bRet = GetNearestPtEle(ptSel, nType, dEle);
|
|
}
|
|
else if (m_nLandForm == 1) // 坡地采集
|
|
{
|
|
bRet = GetEleByThreePt(ssAll, ptSel, nType, dEle);
|
|
|
|
// 坡地采集失败时,使用平地采集
|
|
if (!bRet)
|
|
{
|
|
bRet = GetNearestPtEle(ptSel, nType, dEle);
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
//通过实体得到文字数值 并得到选择点与文字的距离
|
|
double CCollectElevation::GetTextValue(XPoint pt,Entity ent,double &dDis,XPoint &ptVal)
|
|
{
|
|
double dValue = 0.0;
|
|
|
|
if (ent.Is(_T("ATS_TEXT")))
|
|
{
|
|
CString csText;
|
|
//上华文字
|
|
OPENOBJ_BEGIN(ent, AcDb::kForRead, AecXDbText, pEnt);
|
|
if(pEnt)
|
|
{
|
|
csText = pEnt->GetText();
|
|
|
|
ptVal = pEnt->GetLocation();
|
|
// cet 2011.12.2 add
|
|
if(m_bExternalBlk)
|
|
{
|
|
ptVal.TransformBy(m_mat);
|
|
}
|
|
dDis = pt.Distance2d(ptVal);
|
|
dValue = _tstof(csText);
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
else if (ent.Is(_T("ATS_ELEVATION")))
|
|
{
|
|
CString csText;
|
|
OPENOBJ_BEGIN(ent, AcDb::kForRead, AecXDbSymbElevation, pEnt);
|
|
if(pEnt)
|
|
{
|
|
csText = pEnt->GetText();
|
|
|
|
ptVal = pEnt->GetLocation();
|
|
// cet 2011.12.2 add
|
|
if(m_bExternalBlk)
|
|
{
|
|
ptVal.TransformBy(m_mat);
|
|
}
|
|
dDis = pt.Distance2d(ptVal);
|
|
dValue = _tstof(csText);
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
else
|
|
{
|
|
AcDbText *pText = NULL;
|
|
AcDbObjectId id;
|
|
acdbGetObjectId(id, ent);
|
|
AcDbEntity *pEnt = NULL;
|
|
|
|
acdbOpenAcDbEntity(pEnt, id, AcDb::kForWrite);
|
|
if (pEnt != NULL)
|
|
{
|
|
pText = AcDbText::cast(pEnt);
|
|
if (pText != NULL)
|
|
{
|
|
ptVal = pText->position();
|
|
|
|
// cet 2011.12.2 add
|
|
if(m_bExternalBlk)
|
|
{
|
|
ptVal.TransformBy(m_mat);
|
|
}
|
|
|
|
dDis = pt.Distance2d(ptVal);
|
|
|
|
CString sText = pText->textString();
|
|
dValue = _tstof(sText);
|
|
}
|
|
pEnt->close();
|
|
}
|
|
}
|
|
|
|
return dValue;
|
|
}
|
|
|
|
/*
|
|
//通过实体得到点Z坐标 并得到选择点与该实体的距离
|
|
double CCollectElevation::GetPointZValue(XPoint pt,Entity ent,double &dDis)
|
|
{
|
|
double dValue = 0.0;
|
|
AcDbPoint *pPoint = NULL;
|
|
AcDbObjectId id;
|
|
acdbGetObjectId(id, ent);
|
|
AcDbEntity *pEnt = NULL;
|
|
|
|
acdbOpenAcDbEntity(pEnt, id, AcDb::kForWrite);
|
|
if (pEnt != NULL)
|
|
{
|
|
pPoint = AcDbPoint::cast(pEnt);
|
|
if (pPoint != NULL)
|
|
{
|
|
XPoint ptValue = pPoint->position();
|
|
dValue = ptValue.z;
|
|
dDis = pt.Distance2d(ptValue);
|
|
}
|
|
pEnt->close();
|
|
}
|
|
|
|
return dValue;
|
|
}
|
|
|
|
//得到实体圆Z坐标 并得到选择点与该实体的距离
|
|
double CCollectElevation::GetCirCleZValue(XPoint pt,Entity ent,double &dDis)
|
|
{
|
|
double dValue = 0.0;
|
|
AcDbCircle *pCirCle = NULL;
|
|
AcDbObjectId id;
|
|
acdbGetObjectId(id, ent);
|
|
AcDbEntity *pEnt = NULL;
|
|
|
|
acdbOpenAcDbEntity(pEnt, id, AcDb::kForWrite);
|
|
if (pEnt != NULL)
|
|
{
|
|
pCirCle = AcDbCircle::cast(pEnt);
|
|
if (pCirCle != NULL)
|
|
{
|
|
XPoint ptValue = pCirCle->center();
|
|
dValue = ptValue.z;
|
|
dDis = pt.Distance2d(ptValue);
|
|
}
|
|
pEnt->close();
|
|
}
|
|
return dValue;
|
|
}
|
|
|
|
void CCollectElevation::SetCollectObjectCount(int nCount)
|
|
{
|
|
m_nMinObjectCount = nCount;
|
|
}
|
|
|
|
void CCollectElevation::GetAllPickSet(PickSet &ssAll,int nType,RBList &rbMask,Entity ent)
|
|
{
|
|
resbuf *rb = NULL;
|
|
|
|
TCHAR szLayerName[256];
|
|
ent.GetData(8,szLayerName);
|
|
if (nType == 0)
|
|
{
|
|
rb = ads_buildlist(RTDXF0, _T("TEXT,ATS_TEXT"),8,szLayerName, NULL);
|
|
ssAll.Get(_T("X"), NULL, NULL, rb);
|
|
}
|
|
else if (nType == 1)
|
|
{
|
|
rb = ads_buildlist(RTDXF0, _T("POINT"), 8,szLayerName,NULL);
|
|
ssAll.Get(_T("X"), NULL, NULL, rb);
|
|
}
|
|
else if (nType == 2)
|
|
{
|
|
rb = ads_buildlist(RTDXF0, _T("CIRCLE"),8,szLayerName, NULL);
|
|
ssAll.Get(_T("X"), NULL, NULL, rb);
|
|
}
|
|
else if (nType == 5)
|
|
{
|
|
rb = ads_buildlist(RTDXF0, _T("ATS_ELEVATION"),8,szLayerName, NULL);
|
|
ssAll.Get(_T("X"), NULL, NULL, rb);
|
|
}
|
|
else
|
|
{
|
|
TCHAR szBlkName[256];
|
|
ent.GetData(2,szBlkName);
|
|
|
|
rb = ads_buildlist(RTDXF0, _T("INSERT"),8,szLayerName,2,szBlkName, NULL);
|
|
ssAll.Get(_T("X"), NULL, NULL, rb);
|
|
}
|
|
FiletratePickSet(ssAll, ent); // 过滤非数值文字 cet 2010.4.12 add
|
|
rbMask.Append(rb);
|
|
}
|
|
|
|
void CCollectElevation::GetNeedPicSet(PickSet &ss,double &dRidus,int nType,XPoint ptSel,PickSet &ssAll,RBList &rbMask)
|
|
{
|
|
long len = 0;
|
|
int nCount = 1;//圆半径扩大的倍数
|
|
|
|
XPoint ptLow,ptUp;
|
|
ssAll.GetExtend(ptLow,ptUp);
|
|
double nMaxRidius = ptUp.Distance2d(ptLow);
|
|
while (len < m_nMinObjectCount)
|
|
{
|
|
AcDbPolyline *pPLine = new AcDbPolyline;
|
|
dRidus *= nCount;
|
|
GetCirClePolyLine(pPLine,ptSel,dRidus);
|
|
|
|
//得到POLYLINE范围内实体
|
|
XPoly2D poly;
|
|
PolyConvert(*pPLine, poly);
|
|
delete pPLine;
|
|
XPoint ptLow,ptUp;
|
|
|
|
poly.GetExtend(ptLow,ptUp);
|
|
poly.TransUCS(Groups(0), Groups(1));//Groups(0) wcs, Groups(1) ucs
|
|
RBList rbFence = poly.Fence();
|
|
|
|
AssureInCurrentView_New(ptLow, ptUp);
|
|
ss.Get(_T("CP"), rbFence, NULL, rbMask);
|
|
len = ss.Length();
|
|
if (len == 0)
|
|
break;
|
|
|
|
if (dRidus > 2*nMaxRidius)
|
|
break;
|
|
|
|
nCount++;
|
|
}
|
|
}
|
|
|
|
void CCollectElevation::GetAroundElevation(PickSet &ss,std::vector<SourcePoint> &vecPt,int nType,XPoint ptSel,LPCTSTR lpTag)
|
|
{
|
|
Entity ent;
|
|
double dHeightTemp = 0.0;
|
|
double dDis = 0.0;
|
|
CString sValueTemp;
|
|
XPoint ptVal;
|
|
SourcePoint sp;
|
|
|
|
int nSize = ss.Length();
|
|
for(long i=0;i<nSize;i++)
|
|
{
|
|
ent = ss[i];
|
|
switch(nType)
|
|
{
|
|
case 0:
|
|
case 5:
|
|
{
|
|
//文字 标高
|
|
dHeightTemp = GetTextValue(ptSel,ent,dDis,ptVal);
|
|
if (fabs(dHeightTemp) > 0.0001) //SB修改 20090929 支持负数
|
|
{
|
|
sp.dHeight = dHeightTemp;
|
|
sp.dDist = dDis;
|
|
vecPt.push_back(sp);
|
|
}
|
|
}
|
|
break;
|
|
case 1:
|
|
{
|
|
//点
|
|
dHeightTemp = GetPointZValue(ptSel,ent,dDis);
|
|
if (fabs(dHeightTemp) > 0.0001)//SB修改 20090929 支持负数
|
|
{
|
|
sp.dHeight = dHeightTemp;
|
|
sp.dDist = dDis;
|
|
vecPt.push_back(sp);
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
{
|
|
//圆
|
|
dHeightTemp = GetCirCleZValue(ptSel,ent,dDis);
|
|
if (fabs(dHeightTemp) > 0.0001)//SB修改 20090929 支持负数
|
|
{
|
|
sp.dHeight = dHeightTemp;
|
|
sp.dDist = dDis;
|
|
vecPt.push_back(sp);
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
{
|
|
//图块
|
|
dHeightTemp = GetBlockZValue(ptSel,ent,dDis);
|
|
if (fabs(dHeightTemp) > 0.0001)//SB修改 20090929 支持负数
|
|
{
|
|
sp.dHeight = dHeightTemp;
|
|
sp.dDist = dDis;
|
|
vecPt.push_back(sp);
|
|
}
|
|
}
|
|
break;
|
|
case 4:
|
|
{
|
|
if (GetTextValueByTag(ptSel,lpTag,sValueTemp,ent,dDis))
|
|
{
|
|
//属性字
|
|
dHeightTemp = _ttoi(sValueTemp);
|
|
sp.dHeight = dHeightTemp;
|
|
sp.dDist = dDis;
|
|
vecPt.push_back(sp);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//过滤掉部分无用点
|
|
//过滤掉无用实体
|
|
//ss :需要过滤的实体集 作为返回参数时表示过滤后的实体集
|
|
//pt 需要计算标高的点的坐标
|
|
//rbMask 选择数据源的 MASK
|
|
//dRidus 包含实体范围的圆的半径
|
|
//算法:从圆心向最近的点射出射线,将射线经过的实体删除
|
|
void CCollectElevation::FiletratePickSet(PickSet &ss,XPoint pt,RBList &rbMask,double dRidus)
|
|
{
|
|
PickSet ssTemp(SS_FREE);
|
|
ssTemp += ss;
|
|
|
|
PickSet ssDel(SS_FREE);
|
|
|
|
double nMin = 0.0;
|
|
int nIndexDel = -1;
|
|
|
|
XPoint ptVal;
|
|
Entity ent;
|
|
AcDbObjectId id,tempID;
|
|
|
|
while (ssTemp.Length() > 0)
|
|
{
|
|
//找距离pt的实体的最小值
|
|
for (long i = 0; i < ssTemp.Length(); ++i)
|
|
{
|
|
ent = ssTemp[i];
|
|
acdbGetObjectId(id,ent);
|
|
if (m_mapIDToPt.find(id) != m_mapIDToPt.end())
|
|
ptVal = m_mapIDToPt[id];
|
|
|
|
if (i == 0)
|
|
{
|
|
nMin = pt.Distance2d(ptVal);
|
|
tempID = id;
|
|
}
|
|
else
|
|
{
|
|
if (nMin > pt.Distance2d(ptVal))
|
|
{
|
|
nMin = pt.Distance2d(ptVal);
|
|
tempID = id;
|
|
}
|
|
}
|
|
}
|
|
|
|
ssTemp -= tempID;
|
|
PickSet ssTemp2(SS_FREE);
|
|
ptVal = m_mapIDToPt[tempID];
|
|
|
|
//得到通过最小点的射线与圆的交点
|
|
AcGeVector2d vec2d = ptVal - pt;
|
|
vec2d.normalize();
|
|
vec2d *= dRidus;
|
|
ptVal = pt + vec2d;
|
|
|
|
int n = ssDel.Length();
|
|
CString sTemp;
|
|
sTemp.Format(_T("%d"),n);
|
|
XCircle circle(pt,dRidus);
|
|
circle.Make();
|
|
XLine l(pt,ptVal);
|
|
l.Make();
|
|
TCHAR sTemp2[100];
|
|
ads_getstring(NULL, sTemp, sTemp2);
|
|
|
|
struct resbuf *pointlist;
|
|
pointlist = ads_buildlist(RTPOINT, &pt, RTPOINT, &ptVal, NULL);
|
|
ssTemp2.Get(_T("F"), pointlist, NULL, rbMask);
|
|
ads_relrb(pointlist);
|
|
|
|
//得到需要删除的实体
|
|
Entity entDel;
|
|
for (long j = 0; j < ssTemp2.Length(); ++j)
|
|
{
|
|
entDel = ssTemp2[j];
|
|
acdbGetObjectId(id,entDel);
|
|
|
|
if (ssTemp.IsInclude(entDel))
|
|
{
|
|
ssDel += id;
|
|
ssTemp -= id;
|
|
}
|
|
}
|
|
}
|
|
|
|
ss -= ssDel;
|
|
}
|
|
|
|
//过滤掉无用实体
|
|
//ss :需要过滤的实体集 作为返回参数时表示过滤后的实体集
|
|
//pt 需要计算标高的点的坐标
|
|
//算法:将一个圆分成多个扇形,将同一个扇形中离圆心最近的点保留,其他点删除
|
|
void CCollectElevation::FiletratePickSet(PickSet &ss,XPoint pt,double dAngle)
|
|
{
|
|
AcGeVector3d vec3dFirst,vec3dNext;
|
|
XPoint ptTemp,ptVal;
|
|
|
|
//求得形成扇形区域的两向量
|
|
pt.z = 0;
|
|
ptTemp = pt;
|
|
ptTemp.y = pt.y -1;
|
|
vec3dFirst = ptTemp - pt;
|
|
vec3dFirst.normalize();
|
|
vec3dFirst.rotateBy(dAngle,AcGeVector3d::kZAxis);
|
|
vec3dNext = vec3dFirst;
|
|
|
|
PickSet ssTemp(SS_FREE);
|
|
ssTemp += ss;
|
|
|
|
PickSet ssRel(SS_FREE);
|
|
Entity ent,entTemp;
|
|
AcDbObjectId id,tempID;
|
|
double dMin = 0.0;
|
|
XPoint ptProject;
|
|
for (int k = 0; k < (2*PI)/m_dAngel; ++k)
|
|
{
|
|
vec3dNext.rotateBy(m_dAngel,AcGeVector3d::kZAxis);
|
|
XLine xLineFirst(pt,pt+vec3dFirst);
|
|
XLine xLineNext(pt,pt+vec3dNext);
|
|
|
|
//求得扇形区域内距离圆心最近的点
|
|
BOOL bFirst = TRUE;
|
|
BOOL bHasPointsIn = FALSE;
|
|
for (long i = 0; i < ssTemp.Length(); ++i)
|
|
{
|
|
ent = ssTemp[i];
|
|
|
|
acdbGetObjectId(id,ent);
|
|
if (m_mapIDToPt.find(id) != m_mapIDToPt.end())
|
|
ptVal = m_mapIDToPt[id];
|
|
|
|
//ptVal点不在扇形区域则继续循环
|
|
if (!IsPointInArc(vec3dFirst,vec3dNext,ptVal,pt))
|
|
continue;
|
|
else
|
|
bHasPointsIn = TRUE;
|
|
|
|
if (ptVal.Distance(&xLineFirst) < ptVal.Distance(&xLineNext))
|
|
ptVal.Project(&xLineFirst,ptProject);
|
|
else
|
|
ptVal.Project(&xLineNext,ptProject);
|
|
|
|
if (bFirst)
|
|
{
|
|
dMin = pt.Distance2d(ptProject);
|
|
tempID = id;
|
|
entTemp = ent;
|
|
bFirst = FALSE;
|
|
}
|
|
else
|
|
{
|
|
if (dMin > pt.Distance2d(ptProject))
|
|
{
|
|
dMin = pt.Distance2d(ptProject);
|
|
tempID = id;
|
|
entTemp = ent;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (bHasPointsIn)
|
|
{
|
|
//至少有 一点在 扇形区域
|
|
if (!ssRel.IsInclude(entTemp))
|
|
{
|
|
if (!!entTemp)
|
|
ssRel += entTemp;
|
|
}
|
|
|
|
if (m_mapIDToPt.find(tempID) != m_mapIDToPt.end())
|
|
ptVal = m_mapIDToPt[tempID];
|
|
|
|
if (dAngle > 0.01)
|
|
{
|
|
XPoint pt1 = ptVal,pt2 = ptVal,pt3 = ptVal,pt4 = ptVal;
|
|
pt1.y += 10*GlobalFunc::DocGetPScale();
|
|
pt2.y -= 10*GlobalFunc::DocGetPScale();
|
|
pt3.x += 10*GlobalFunc::DocGetPScale();
|
|
pt4.x -= 10*GlobalFunc::DocGetPScale();
|
|
ads_grdraw(GlobalFunc::Wcs2Ucs(pt1),GlobalFunc::Wcs2Ucs(pt2),1,0);
|
|
ads_grdraw(GlobalFunc::Wcs2Ucs(pt3),GlobalFunc::Wcs2Ucs(pt4),1,0);
|
|
}
|
|
|
|
}
|
|
vec3dFirst = vec3dNext;
|
|
}
|
|
|
|
for (long j = 0; j < ssTemp.Length(); ++j)
|
|
{
|
|
if (!ssRel.IsInclude(ssTemp[j]))
|
|
ss -= ssTemp[j];
|
|
}
|
|
|
|
}
|
|
|
|
//判断点是否在两个向量组成扇形区域
|
|
BOOL CCollectElevation::IsPointInArc(AcGeVector3d vec1,AcGeVector3d vec2,AcGePoint3d pt,AcGePoint3d ptCenter)
|
|
{
|
|
pt.z = 0;
|
|
AcGeVector3d vec = pt - ptCenter;
|
|
vec.normalize();
|
|
|
|
AcDbLine xLine(pt,ptCenter);
|
|
|
|
XPoint pt1,pt2;
|
|
pt1 = ptCenter + vec1;
|
|
pt2 = ptCenter + vec2;
|
|
|
|
AcGePoint3dArray ptArray;
|
|
AcDbLine line(pt1,pt2);
|
|
|
|
line.intersectWith(&xLine,AcDb::kOnBothOperands,ptArray);
|
|
|
|
if (ptArray.length() > 0)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
*/
|
|
|
|
//设置地形
|
|
void CCollectElevation::SetLandForm(int nType)
|
|
{
|
|
m_nLandForm = nType;
|
|
}
|
|
|
|
// 过滤含非数值型数据的实体
|
|
void CCollectElevation::FiletratePickSet(PickSet &ss, Entity &ent)
|
|
{
|
|
PickSet ssDel(SS_FREE);
|
|
if (ent.Is(_T("ATS_TEXT")))
|
|
{
|
|
AcDbObjectId id;
|
|
AecXDbText *pEnt = NULL;
|
|
CString strText;
|
|
for(long i = 0; i < ss.Length(); i++)
|
|
{
|
|
acdbGetObjectId(id, ss[i]);
|
|
acdbOpenObject(pEnt, id, AcDb::kForRead);
|
|
if (pEnt != NULL)
|
|
{
|
|
strText = pEnt->GetText();
|
|
pEnt->close();
|
|
// 是否为数值
|
|
if (!IsNumValue(strText))
|
|
{
|
|
ssDel += ss[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (ent.Is(_T("TEXT")))
|
|
{
|
|
AcDbObjectId id;
|
|
AcDbText *pEnt = NULL;
|
|
CString strText;
|
|
for(long i = 0; i < ss.Length(); i++)
|
|
{
|
|
acdbGetObjectId(id, ss[i]);
|
|
acdbOpenObject(pEnt, id, AcDb::kForRead);
|
|
if (pEnt != NULL)
|
|
{
|
|
strText = pEnt->textString();
|
|
pEnt->close();
|
|
// 是否为数值
|
|
if (!IsNumValue(strText))
|
|
{
|
|
ssDel += ss[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (ent.Is(_T("ATS_ELEVATION")))
|
|
{
|
|
CString strText;
|
|
AcDbObjectId id;
|
|
AecXDbSymbElevation *pEnt = NULL;
|
|
for(long i = 0; i < ss.Length(); i++)
|
|
{
|
|
acdbGetObjectId(id, ss[i]);
|
|
acdbOpenObject(pEnt, id, AcDb::kForRead);
|
|
if (pEnt != NULL)
|
|
{
|
|
strText = pEnt->GetText();
|
|
pEnt->close();
|
|
// 是否为数值
|
|
if (!IsNumValue(strText))
|
|
{
|
|
ssDel += ss[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ss -= ssDel;
|
|
}
|
|
|
|
bool CCollectElevation::IsNumValue(const CString &strText)
|
|
{
|
|
bool bRet = true;
|
|
TCHAR ch;
|
|
for (int j = 0; j < strText.GetLength(); j++)
|
|
{
|
|
ch = strText.GetAt(j);
|
|
if ((ch < _T('0') || ch > _T('9')) &&
|
|
ch != _T('.') && ch != _T('-') && ch != _T('+'))
|
|
{
|
|
bRet = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
bool CCollectElevation::GetNearestPtEle(const AcGePoint3d &pt, int nType, double &dEle)
|
|
{
|
|
bool bRet = false;
|
|
//获取最近点
|
|
Entity ent;
|
|
AcDbObjectId id;
|
|
id = GetNearestPt(pt);
|
|
|
|
if (id.isValid())
|
|
{
|
|
std::vector<AcGePoint3d> vecPt;
|
|
std::map<AcDbObjectId,XPoint>::iterator it;
|
|
it = m_mapIDToPt.find(id);
|
|
vecPt.push_back((*it).second);
|
|
DrawAcrossLine(vecPt);
|
|
|
|
//获取最近点标高
|
|
dEle = GetEntEle(id, nType);
|
|
bRet = true;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
bool CCollectElevation::GetEleByThreePt(PickSet &ssAll, const AcGePoint3d &pt, int nType, double &dEle)
|
|
{
|
|
bool bRet = false;
|
|
// 获取三个最近点
|
|
std::vector<AcDbObjectId> vecId;
|
|
GetNearestThreePt(vecId, pt);
|
|
|
|
// 由三点求pt点的标高
|
|
if (vecId.size() >= 3)
|
|
{
|
|
// 保存m_mapIDToPt中的数据
|
|
std::map<AcDbObjectId,XPoint> temp;
|
|
std::map<AcDbObjectId,XPoint>::iterator it;
|
|
for (it = m_mapIDToPt.begin(); it != m_mapIDToPt.end(); it++)
|
|
{
|
|
temp[(*it).first] = (*it).second;
|
|
}
|
|
|
|
std::vector<AcGePoint3d> vecPt;
|
|
AcGePoint3d pt1, pt2, pt3;
|
|
AcDbObjectId id;
|
|
double dEle2 = 0.0;
|
|
|
|
// 确定三点的Z值
|
|
id = vecId[0];
|
|
it = m_mapIDToPt.find(id);
|
|
if (it != m_mapIDToPt.end())
|
|
{
|
|
pt1 = (*it).second;
|
|
dEle2 = GetEntEle(id, nType);
|
|
pt1.z = dEle2;
|
|
m_mapIDToPt.erase(it);
|
|
}
|
|
|
|
id = vecId[1];
|
|
it = m_mapIDToPt.find(id);
|
|
if (it != m_mapIDToPt.end())
|
|
{
|
|
pt2 = (*it).second;
|
|
dEle2 = GetEntEle(id, nType);
|
|
pt2.z = dEle2;
|
|
m_mapIDToPt.erase(it);
|
|
}
|
|
|
|
id = vecId[2];
|
|
it = m_mapIDToPt.find(id);
|
|
if (it != m_mapIDToPt.end())
|
|
{
|
|
pt3 = (*it).second;
|
|
dEle2 = GetEntEle(id, nType);
|
|
pt3.z = dEle2;
|
|
m_mapIDToPt.erase(it);
|
|
}
|
|
|
|
vecPt.push_back(pt1);
|
|
vecPt.push_back(pt2);
|
|
vecPt.push_back(pt3);
|
|
|
|
if(IsPtInTriangle(pt1, pt2, pt3, pt)) // pt 点在三角形内
|
|
{
|
|
// 构造经过三点的平面
|
|
AcGePlane plan(pt1, pt2, pt3);
|
|
// 求点到面的投影点
|
|
AcGePoint3d ptPrj;
|
|
ptPrj = pt.project(plan, AcGeVector3d::kZAxis);
|
|
double d = tan(GetAnglePlaneToXYPlane(plan));
|
|
|
|
dEle = ptPrj.z;
|
|
bRet = true;
|
|
DrawAcrossLine(vecPt);
|
|
}
|
|
else // pt点不在三角形内
|
|
{
|
|
AcGePoint3d ptPrj, ptT1, ptT2, ptT3;
|
|
std::map<AcDbObjectId, XPoint>::iterator it;
|
|
AcGePoint3d pt4;
|
|
while (m_mapIDToPt.size() != 0)
|
|
{
|
|
id = GetNearestPt(pt);
|
|
it = m_mapIDToPt.find(id);
|
|
if (it == m_mapIDToPt.end())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
pt4 = (*it).second;
|
|
m_mapIDToPt.erase(it);
|
|
// cet 2011.12.7 add 判断第四个点距pt点是否在合理范围
|
|
if (!IsValidPt(pt1, pt2, pt3, pt4, pt, 1.5))
|
|
{
|
|
continue;
|
|
}
|
|
dEle2 = GetEntEle(id, nType);
|
|
pt4.z = dEle2;
|
|
|
|
bool bRes1 = IsPtInTriangle(pt4, pt2, pt3, pt);
|
|
bool bRes2 = IsPtInTriangle(pt1, pt4, pt3, pt);
|
|
bool bRes3 = IsPtInTriangle(pt1, pt2, pt4, pt);
|
|
|
|
if (bRes1 && !bRes2 && !bRes3)
|
|
{
|
|
ptPrj = GetProjectPt(pt4, pt2, pt3, pt);
|
|
vecPt[0] = pt4;
|
|
}
|
|
else if (!bRes1 && bRes2 && !bRes3)
|
|
{
|
|
ptPrj = GetProjectPt(pt1, pt4, pt3, pt);
|
|
vecPt[1] = pt4;
|
|
}
|
|
if (!bRes1 && !bRes2 && bRes3)
|
|
{
|
|
ptPrj = GetProjectPt(pt1, pt2, pt4, pt);
|
|
vecPt[2] = pt4;
|
|
}
|
|
else if (bRes1 && bRes2 && !bRes3)
|
|
{
|
|
ptT1 = pt1;
|
|
ptT2 = pt2;
|
|
ptT3 = pt;
|
|
ptT1.z = 0;
|
|
ptT2.z = 0;
|
|
ptT3.z = 0;
|
|
|
|
if (ptT3.distanceTo(ptT1) < ptT3.distanceTo(ptT2))
|
|
{
|
|
ptPrj = GetProjectPt(pt1, pt4, pt3, pt);
|
|
vecPt[1] = pt4;
|
|
}
|
|
else
|
|
{
|
|
ptPrj = GetProjectPt(pt4, pt2, pt3, pt);
|
|
vecPt[0] = pt4;
|
|
}
|
|
}
|
|
if (bRes1 && !bRes2 && bRes3)
|
|
{
|
|
ptT1 = pt1;
|
|
ptT2 = pt3;
|
|
ptT3 = pt;
|
|
ptT1.z = 0;
|
|
ptT2.z = 0;
|
|
ptT3.z = 0;
|
|
|
|
if (ptT3.distanceTo(ptT1) < ptT3.distanceTo(ptT2))
|
|
{
|
|
ptPrj = GetProjectPt(pt1, pt2, pt4, pt);
|
|
vecPt[2] = pt4;
|
|
}
|
|
else
|
|
{
|
|
ptPrj = GetProjectPt(pt4, pt2, pt3, pt);
|
|
vecPt[0] = pt4;
|
|
}
|
|
}
|
|
else if (!bRes1 && bRes2 && bRes3)
|
|
{
|
|
ptT1 = pt3;
|
|
ptT2 = pt2;
|
|
ptT3 = pt;
|
|
ptT1.z = 0;
|
|
ptT2.z = 0;
|
|
ptT3.z = 0;
|
|
|
|
if (ptT3.distanceTo(ptT1) < ptT3.distanceTo(ptT2))
|
|
{
|
|
ptPrj = GetProjectPt(pt1, pt4, pt3, pt);
|
|
vecPt[1] = pt4;
|
|
}
|
|
else
|
|
{
|
|
ptPrj = GetProjectPt(pt1, pt2, pt4, pt);
|
|
vecPt[2] = pt4;
|
|
}
|
|
}
|
|
if (!bRes1 && !bRes2 && !bRes3)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
dEle = ptPrj.z;
|
|
bRet = true;
|
|
DrawAcrossLine(vecPt);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 恢复m_mapIDToPt
|
|
m_mapIDToPt.clear();
|
|
for (it = temp.begin(); it != temp.end(); it++)
|
|
{
|
|
m_mapIDToPt[(*it).first] = (*it).second;
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
void CCollectElevation::GetNearestThreePt(std::vector<AcDbObjectId> &vecId, const AcGePoint3d &pt)
|
|
{
|
|
if (m_mapIDToPt.size() < 3)
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcDbObjectId id;
|
|
std::map<AcDbObjectId,XPoint> temp;
|
|
std::map<AcDbObjectId,XPoint>::iterator it;
|
|
for (it = m_mapIDToPt.begin(); it != m_mapIDToPt.end(); it++)
|
|
{
|
|
temp[(*it).first] = (*it).second;
|
|
}
|
|
|
|
id = GetNearestPt(pt);
|
|
vecId.push_back(id);
|
|
m_mapIDToPt.erase(id);
|
|
|
|
id = GetNearestPt(pt);
|
|
vecId.push_back(id);
|
|
m_mapIDToPt.erase(id);
|
|
|
|
id = GetNearestPt(pt);
|
|
vecId.push_back(id);
|
|
m_mapIDToPt.erase(id);
|
|
|
|
m_mapIDToPt.clear();
|
|
for (it = temp.begin(); it != temp.end(); it++)
|
|
{
|
|
m_mapIDToPt[(*it).first] = (*it).second;
|
|
}
|
|
}
|
|
|
|
AcDbObjectId CCollectElevation::GetNearestPt(const AcGePoint3d &pt)
|
|
{
|
|
Entity ent;
|
|
AcDbObjectId id = AcDbObjectId::kNull;
|
|
double nMin = 0.0;
|
|
XPoint ptTemp;
|
|
std::map<AcDbObjectId,XPoint>::iterator it;
|
|
id = AcDbObjectId::kNull;
|
|
for (it = m_mapIDToPt.begin(); it != m_mapIDToPt.end(); it++)
|
|
{
|
|
ptTemp = (*it).second;
|
|
if (it == m_mapIDToPt.begin())
|
|
{
|
|
nMin = ptTemp.Distance2d(pt);
|
|
id = (*it).first;
|
|
}
|
|
else
|
|
{
|
|
if (nMin > ptTemp.Distance2d(pt))
|
|
{
|
|
nMin = ptTemp.Distance2d(pt);
|
|
id = (*it).first;
|
|
}
|
|
}
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
void CCollectElevation::GetAllPickSetPt(PickSet &ssAll, const AcGePoint3d &pt, int nType)
|
|
{
|
|
Entity ent;
|
|
AcDbObjectId id;
|
|
XPoint ptVal;
|
|
AcDbPoint *pPt = NULL;
|
|
AcDbCircle *pCir = NULL;
|
|
AcDbBlockReference *pRef = NULL;
|
|
for (long j = 0; j < ssAll.Length(); ++j)
|
|
{
|
|
ent = ssAll[j];
|
|
acdbGetObjectId(id,ent);
|
|
if (nType == 0 || nType == 5) // 文字
|
|
{
|
|
double dDis = 0.0;
|
|
GetTextValue(pt,ent,dDis,ptVal);
|
|
}
|
|
else if (nType == 1) // 点
|
|
{
|
|
acdbOpenObject(pPt, id, AcDb::kForRead);
|
|
if(pPt != NULL)
|
|
{
|
|
ptVal = pPt->position();
|
|
pPt->close();
|
|
// cet 2011.12.2 add
|
|
if(m_bExternalBlk)
|
|
{
|
|
ptVal.TransformBy(m_mat);
|
|
}
|
|
}
|
|
}
|
|
else if (nType == 2) // 圆
|
|
{
|
|
acdbOpenObject(pCir, id, AcDb::kForRead);
|
|
if(pCir != NULL)
|
|
{
|
|
ptVal = pCir->center();
|
|
pCir->close();
|
|
// cet 2011.12.2 add
|
|
if(m_bExternalBlk)
|
|
{
|
|
ptVal.TransformBy(m_mat);
|
|
}
|
|
}
|
|
}
|
|
else // 块
|
|
{
|
|
acdbOpenObject(pRef, id, AcDb::kForRead);
|
|
if(pRef != NULL)
|
|
{
|
|
ptVal = pRef->position();
|
|
pRef->close();
|
|
// cet 2011.12.2 add
|
|
if(m_bExternalBlk)
|
|
{
|
|
ptVal.TransformBy(m_mat);
|
|
}
|
|
}
|
|
}
|
|
m_mapIDToPt[id] = ptVal;
|
|
}
|
|
}
|
|
|
|
double CCollectElevation::GetEntEle(const AcDbObjectId &id, int nType)
|
|
{
|
|
double dEle = 0.0;
|
|
XPoint ptVal;
|
|
AcDbPoint *pPt = NULL;
|
|
AcDbCircle *pCir = NULL;
|
|
AcDbBlockReference *pRef = NULL;
|
|
if (nType == 0) // 文字
|
|
{
|
|
ads_name sName;
|
|
acdbGetAdsName(sName, id);
|
|
Entity ent(sName);
|
|
if (ent.Is(_T("ATS_TEXT")))
|
|
{
|
|
AecXDbText *pText = NULL;
|
|
acdbOpenObject(pText, id, AcDb::kForRead);
|
|
if (pText != NULL)
|
|
{
|
|
CString strText = pText->GetText();
|
|
dEle = _tstof(strText);
|
|
pText->close();
|
|
}
|
|
}
|
|
else if (ent.Is(_T("TEXT")))
|
|
{
|
|
AcDbText *pText = NULL;
|
|
acdbOpenObject(pText, id, AcDb::kForRead);
|
|
if (pText != NULL)
|
|
{
|
|
CString strText = pText->textString();
|
|
dEle = _tstof(strText);
|
|
pText->close();
|
|
}
|
|
}
|
|
}
|
|
else if ( nType == 5) // 文字
|
|
{
|
|
AecXDbSymbElevation *pEle = NULL;
|
|
acdbOpenObject(pEle, id, AcDb::kForRead);
|
|
if (pEle != NULL)
|
|
{
|
|
CString strText = pEle->GetText();
|
|
pEle->close();
|
|
dEle = _tstof(strText);
|
|
}
|
|
}
|
|
else if (nType == 1) // 点
|
|
{
|
|
acdbOpenObject(pPt, id, AcDb::kForRead);
|
|
if(pPt != NULL)
|
|
{
|
|
ptVal = pPt->position();
|
|
pPt->close();
|
|
// cet 2011.12.2 add
|
|
if (m_bExternalBlk)
|
|
{
|
|
ptVal.TransformBy(m_mat);
|
|
}
|
|
dEle = ptVal.z;
|
|
}
|
|
}
|
|
else if (nType == 2) // 圆
|
|
{
|
|
acdbOpenObject(pCir, id, AcDb::kForRead);
|
|
if(pCir != NULL)
|
|
{
|
|
ptVal = pCir->center();
|
|
pCir->close();
|
|
// cet 2011.12.2 add
|
|
if (m_bExternalBlk)
|
|
{
|
|
ptVal.TransformBy(m_mat);
|
|
}
|
|
dEle = ptVal.z;
|
|
}
|
|
}
|
|
else // 块
|
|
{
|
|
acdbOpenObject(pRef, id, AcDb::kForRead);
|
|
if(pRef != NULL)
|
|
{
|
|
if (nType == 3) //图块Z坐标
|
|
{
|
|
ptVal = pRef->position();
|
|
pRef->close();
|
|
// cet 2011.12.2 add
|
|
if (m_bExternalBlk)
|
|
{
|
|
ptVal.TransformBy(m_mat);
|
|
}
|
|
dEle = ptVal.z;
|
|
}
|
|
else if (nType == 4) // 图块属性值
|
|
{
|
|
AcDbObjectIterator *pIterator = NULL;
|
|
pIterator = pRef->attributeIterator();
|
|
for (pIterator->start(); !pIterator->done(); pIterator->step())
|
|
{
|
|
//遍历块中实体
|
|
AcDbEntity *pEnt = NULL;
|
|
AcDbAttribute *pAtt = NULL;
|
|
AcDbObjectId att_id;
|
|
att_id = pIterator -> objectId();
|
|
acdbOpenAcDbEntity(pEnt, att_id, AcDb::kForRead);
|
|
pAtt = AcDbAttribute::cast(pEnt);
|
|
if(pAtt != NULL)
|
|
{
|
|
CString strText = pAtt->textString();
|
|
dEle = _tstof(strText);
|
|
}
|
|
pEnt->close();
|
|
}
|
|
delete pIterator;
|
|
pRef->close();
|
|
}
|
|
}
|
|
}
|
|
|
|
return dEle;
|
|
}
|
|
|
|
void CCollectElevation::GetNeedPicSet(Entity ent, AcGePoint3d pt, int nType)
|
|
{
|
|
// 设置过滤器
|
|
resbuf *rb = NULL;
|
|
TCHAR szLayerName[256];
|
|
ent.GetData(8,szLayerName);
|
|
if (nType == 0)
|
|
{
|
|
rb = ads_buildlist(RTDXF0, _T("TEXT,ATS_TEXT"), 8, szLayerName, NULL);
|
|
}
|
|
else if (nType == 1)
|
|
{
|
|
rb = ads_buildlist(RTDXF0, _T("POINT"), 8, szLayerName,NULL);
|
|
}
|
|
else if (nType == 2)
|
|
{
|
|
rb = ads_buildlist(RTDXF0, _T("CIRCLE"),8, szLayerName, NULL);
|
|
}
|
|
else if (nType == 5)
|
|
{
|
|
rb = ads_buildlist(RTDXF0, _T("ATS_ELEVATION"), 8, szLayerName, NULL);
|
|
}
|
|
else
|
|
{
|
|
TCHAR szBlkName[256];
|
|
ent.GetData(2,szBlkName);
|
|
rb = ads_buildlist(RTDXF0, _T("INSERT"), 8, szLayerName, 2, szBlkName, NULL);
|
|
}
|
|
|
|
// 选取数据源
|
|
int nSize = 0;
|
|
if (m_nLandForm == 0)
|
|
{
|
|
nSize = 1;
|
|
}
|
|
else
|
|
{
|
|
nSize = 3;
|
|
}
|
|
double dLen = 2 * GlobalFunc::DocGetPScale();
|
|
int nCount = 1;
|
|
XPoint pt1, pt2, pt3, pt4;
|
|
PickSet ssSel(SS_FREE);
|
|
pt = GlobalFunc::Wcs2Ucs(pt);
|
|
while (ssSel.Length() < nSize)
|
|
{
|
|
dLen *= nCount;
|
|
ssSel.Free();
|
|
pt1 = pt - AcGeVector3d::kXAxis * dLen + AcGeVector3d::kYAxis * dLen;
|
|
pt2 = pt - AcGeVector3d::kXAxis * dLen - AcGeVector3d::kYAxis * dLen;
|
|
pt3 = pt2 + AcGeVector3d::kXAxis * 2 * dLen;
|
|
pt4 = pt1 + AcGeVector3d::kXAxis * 2 * dLen;
|
|
pt = GlobalFunc::Ucs2Wcs(pt);
|
|
RBList rbPt = acutBuildList(RTPOINT,&pt1,RTPOINT,&pt2,RTPOINT,&pt3,RTPOINT,&pt4,NULL);
|
|
acedSSGet(_T("CP"),rbPt,NULL,rb,ssSel);
|
|
FiletrateInvalidEnt(ssSel, ent); // 删除选择集中的无效数据
|
|
nCount *= 10;
|
|
}
|
|
|
|
// 保存选择集中的实体id
|
|
m_vecId.clear();
|
|
for (long i = 0; i < ssSel.Length(); i++)
|
|
{
|
|
AcDbObjectId id = AcDbObjectId::kNull;
|
|
acdbGetObjectId(id, ssSel[i]);
|
|
m_vecId.push_back(id);
|
|
}
|
|
}
|
|
|
|
void CCollectElevation::FiletrateInvalidEnt(PickSet &ss, Entity &ent)
|
|
{
|
|
PickSet ssDel(SS_FREE);
|
|
std::map<AcDbObjectId, XPoint>::iterator it;
|
|
for (long i = 0; i < ss.Length(); i++)
|
|
{
|
|
AcDbObjectId id = AcDbObjectId::kNull;
|
|
acdbGetObjectId(id, ss[i]);
|
|
it = m_mapIDToPt.find(id);
|
|
if (it == m_mapIDToPt.end())
|
|
{
|
|
ssDel += ss[i];
|
|
}
|
|
}
|
|
|
|
ss -= ssDel;
|
|
}
|
|
|
|
void CCollectElevation::DrawAcrossLine(std::vector<AcGePoint3d> &vecPt)
|
|
{
|
|
std::vector<AcGePoint3d>::iterator it;
|
|
double dLen = 10*GlobalFunc::DocGetPScale();
|
|
for (it = vecPt.begin(); it != vecPt.end(); it++)
|
|
{
|
|
XPoint pt;
|
|
pt = *it;
|
|
pt = GlobalFunc::Wcs2Ucs(pt);
|
|
XPoint pt1 = pt,pt2 = pt,pt3 = pt,pt4 = pt;
|
|
pt1.y += dLen;
|
|
pt2.y -= dLen;
|
|
pt3.x += dLen;
|
|
pt4.x -= dLen;
|
|
ads_grdraw(pt1,pt2,1,0);
|
|
ads_grdraw(pt3,pt4,1,0);
|
|
}
|
|
}
|
|
|
|
void CCollectElevation::SetPickSet(PickSet &ssAll)
|
|
{
|
|
m_ssAll.Free();
|
|
m_ssAll += ssAll;
|
|
}
|
|
|
|
double CCollectElevation::GetAnglePlaneToXYPlane(const AcGePlane &plane)
|
|
{
|
|
AcGeVector3d normal1, normal2;
|
|
normal1 = plane.normal();
|
|
normal2 = (AcGePlane::kXYPlane).normal();
|
|
double dAngle = normal2.angleTo(normal1);
|
|
|
|
if (dAngle > PI / 2)
|
|
{
|
|
dAngle = PI - dAngle;
|
|
}
|
|
|
|
return dAngle;
|
|
}
|
|
|
|
void CCollectElevation::SetGradient(bool bGradient)
|
|
{
|
|
m_bGradient = bGradient;
|
|
}
|
|
|
|
double CCollectElevation::GetGradient()
|
|
{
|
|
return m_dGradient;
|
|
}
|
|
|
|
void CCollectElevation::SetGradient(double dGradient)
|
|
{
|
|
m_dGradient = dGradient;
|
|
}
|
|
|
|
bool CCollectElevation::IsPtInTriangle(AcGePoint3d pt1, AcGePoint3d pt2, AcGePoint3d pt3, AcGePoint3d pt)
|
|
{
|
|
bool bRet = false;
|
|
pt1.z = 0;
|
|
pt2.z = 0;
|
|
pt3.z = 0;
|
|
pt.z =0;
|
|
AcDbLine l1(pt1, pt2), l2(pt1, pt3), l3(pt3, pt2);
|
|
|
|
if (IsPtOnLine(l1, pt) || IsPtOnLine(l2, pt) || IsPtOnLine(l2, pt)) // 点在边上
|
|
{
|
|
bRet = true;
|
|
}
|
|
else
|
|
{
|
|
AcGePoint3d ptMin1, ptMin2;
|
|
ptMin1.x = (pt1.x + pt2.x) / 2;
|
|
ptMin1.y = (pt1.y + pt2.y) / 2;
|
|
ptMin1.z = (pt1.z + pt2.z) / 2;
|
|
ptMin2.x = (pt1.x + pt3.x) / 2;
|
|
ptMin2.y = (pt1.y + pt3.y) / 2;
|
|
ptMin2.z = (pt1.z + pt3.z) / 2;
|
|
|
|
AcDbLine l4(ptMin1, pt3), l5(ptMin2, pt2);
|
|
AcGePoint3dArray arPt;
|
|
l4.intersectWith(&l5, AcDb::kOnBothOperands, arPt);
|
|
if (arPt.length() == 1)
|
|
{
|
|
AcGePoint3d ptIns = arPt[0];
|
|
AcDbLine l6(ptIns, pt);
|
|
if (!IsIntersectionLineByLine(l6, l1) &&
|
|
!IsIntersectionLineByLine(l6, l2) &&
|
|
!IsIntersectionLineByLine(l6, l3))
|
|
{
|
|
bRet = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
bool CCollectElevation::IsPtOnLine(const AcDbLine &line, const AcGePoint3d &pt)
|
|
{
|
|
bool bRet = false;
|
|
AcGePoint3d ptTemp;
|
|
line.getClosestPointTo(pt, ptTemp);
|
|
if (pt.distanceTo(ptTemp) < 1e-3)
|
|
{
|
|
bRet = true;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
bool CCollectElevation::IsIntersectionLineByLine(const AcDbLine &l1, const AcDbLine &l2)
|
|
{
|
|
AcGePoint3dArray arPt;
|
|
l1.intersectWith(&l2, AcDb::kOnBothOperands, arPt);
|
|
if (arPt.length() == 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
AcGePoint3d CCollectElevation::GetProjectPt(const AcGePoint3d pt1, const AcGePoint3d pt2, const AcGePoint3d pt3, const AcGePoint3d pt)
|
|
{
|
|
// 构造经过三点的平面
|
|
AcGePlane plan(pt1, pt2, pt3);
|
|
// 求点到面的投影点
|
|
AcGePoint3d ptPrj;
|
|
ptPrj = pt.project(plan, AcGeVector3d::kZAxis);
|
|
|
|
return ptPrj;
|
|
}
|
|
|
|
void CCollectElevation::SetExternalBlk(bool bExternalBlk)
|
|
{
|
|
m_bExternalBlk = bExternalBlk;
|
|
}
|
|
|
|
void CCollectElevation::SetExnternalBlkMat(const AcGeMatrix3d &mat)
|
|
{
|
|
m_mat = mat;
|
|
}
|
|
|
|
bool CCollectElevation::IsValidPt(const AcGePoint3d &pt1, const AcGePoint3d &pt2, const AcGePoint3d &pt3, const AcGePoint3d &pt4, const AcGePoint3d &pt, double dScale)
|
|
{
|
|
AcGePoint3d ptTemp1 = pt1, ptTemp2 = pt2;
|
|
AcGePoint3d ptTemp3 = pt3, ptTemp4 = pt4;
|
|
AcGePoint3d ptTemp = pt;
|
|
ptTemp1.z = 0.0;
|
|
ptTemp2.z = 0.0;
|
|
ptTemp3.z = 0.0;
|
|
ptTemp4.z = 0.0;
|
|
ptTemp.z = 0.0;
|
|
double dDist1 = ptTemp1.distanceTo(ptTemp);
|
|
double dDist2 = ptTemp2.distanceTo(ptTemp);
|
|
double dDist3 = ptTemp3.distanceTo(ptTemp);
|
|
double dDist4 = ptTemp4.distanceTo(ptTemp);
|
|
|
|
double dMaxDist = dDist1 > dDist2 ? (dDist1 > dDist3 ? dDist1 : dDist3) : (dDist2 > dDist3 ? dDist2 : dDist3);
|
|
if (dMaxDist * dScale < dDist4)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
} |