Files
envi-code/SourceCode/Code2026/tg_shs/shs_siteplan/TDbPlaceTree.cpp
T
2026-09-28 15:28:50 +08:00

244 lines
5.4 KiB
C++

#include "stdafx.h"
#include "TDbPlaceTree.h"
TDbPlaceTree::TDbPlaceTree()
{
}
void TDbPlaceTree::SetPolyPath(XPoly2D poly2D)
{
PolyConvert(poly2D, m_polyLine);
}
void TDbPlaceTree::UpdatePlaceTreeData(double dRad, double dDis, bool bIsSetDis, bool bIsRotation, AcDbObjectId idBlk)
{
m_dRad = dRad;
m_dDis = dDis;
m_bIsSetDis = bIsSetDis;
m_bIsRotation = bIsRotation;
m_idBlk = idBlk;
}
Adesk::Boolean TDbPlaceTree::subWorldDraw(AcGiWorldDraw *pWd)
{
AcGePoint3dArray arPts;// 保存插入点
PolyLineStyle(&m_polyLine,m_dDis, arPts,m_bIsSetDis);
int nLen = arPts.length();
for (int n = 0; n<nLen; n++)
{
if (!SimulateMakeBlockReference(arPts[n],pWd)) // 造块
//if (!MakeBlockReference(arPts[n],pWd)) // 造块
{
return false;
}
}
return Adesk::kTrue;
}
TDbPlaceTree::~TDbPlaceTree(void)
{
}
// add by xly on 110324 引入随机函数
extern double GetRandNumber(double dMin, double dMax);
bool TDbPlaceTree::MakeBlockReference(AcGePoint3d ptInsert,AcGiWorldDraw *pWd)
{
AcDbBlockReference pRef(ptInsert, m_idBlk);
AcDbExtents extents;
AcGePoint3d ptLow,ptUp;
// 获得块的包围盒
pRef.getGeomExtents(extents);
// 计算块的大小
ptLow = extents.minPoint();
ptUp = extents.maxPoint();
double dSize = (ptUp.x-ptLow.x)/2;
// 比例变化矩阵
AcGeMatrix3d xform;
// 设置块比例
xform.setToScaling(m_dRad / dSize, ptInsert);
pRef.transformBy(xform);
// add by xly on 110324 设置随机旋转
if (m_bIsRotation)
{
xform.setToRotation((double)GetRandNumber(0, PI * 2), AcGeVector3d::kZAxis, ptInsert);
pRef.transformBy(xform);
}
// add by xly on 110327 设置任意布树的图层
AcDbObjectId idLayer = InitLayer(LAY_TREE);
pRef.setLayer(idLayer);
pRef.worldDraw(pWd);
//AcDbObjectId idRef = AddToModelSpace(pRef, Adesk::kTrue); // 添加到数据库中
return true;
}
bool TDbPlaceTree::SimulateMakeBlockReference(AcGePoint3d ptInsert,AcGiWorldDraw *pWd)
{
AcGeVector3d nrm(0,0,1);
AcDbCircle Arc(ptInsert,nrm, m_dRad);
Arc.worldDraw(pWd);
return true;
}
// 多段线样式生成树
void TDbPlaceTree::PolyLineStyle(AcDbPolyline *pPolyLine, double dTreeDis, AcGePoint3dArray &ptAryInsert, BOOL bIsSetDis)
{
// 获得多段线的起点
AcGePoint3d ptSt;
pPolyLine->getStartPoint(ptSt);
// 获得多段线的所有顶点
int iNumVerts = pPolyLine->numVerts();
double dBulge = 0.0;
AcGeCircArc3d arc;
AcGeLineSeg3d line;
AcGePoint3dArray aryTemp;
// 遍历多段线的顶点,除了最后一点
for (int i = 0; i<iNumVerts-1; i++)
{
// 获得顶点处的弧度值
pPolyLine->getBulgeAt(i,dBulge);
if (dBulge != 0)// 圆弧
{
pPolyLine->getArcSegAt(i,arc);
// 获得几何图形的参数
AcGePoint3d ptCenter = arc.center();
AcGeVector3d normal = arc.normal();
AcGeVector3d refVec = arc.refVec();
AcGePlane plane = AcGePlane(ptCenter,normal);
double dAng = refVec.angleOnPlane(plane);
// 构造数据库的实体
AcDbArc *pArc = new AcDbArc(ptCenter,normal,arc.radius(),arc.startAng()+dAng, arc.endAng()+dAng);
ArcStyle(pArc,dTreeDis,aryTemp,bIsSetDis,dBulge);
}
else// 直线
{
pPolyLine->getLineSegAt(i,line);
AcDbLine *pLine = new AcDbLine(line.startPoint(),line.endPoint());
LineStyle(pLine,dTreeDis,aryTemp,bIsSetDis);
}
ptAryInsert.append(aryTemp);
}
}
// 直线样式生成树
void TDbPlaceTree::LineStyle(AcDbLine *pLine, double dTreeDis, AcGePoint3dArray &ptAryInsert, BOOL bIsSetDis)
{
// 获得直线的起点和终点
AcGePoint3d ptSt,ptEnd;
ptSt = pLine->startPoint();
ptEnd = pLine->endPoint();
// add by xly on 110324 清空数组
ptAryInsert.setLogicalLength(0);
ptAryInsert.append(ptSt);
// 计算直线的长度
double dLenth = ptSt.distanceTo(ptEnd);
AcGeVector3d ver = ptEnd - ptSt;
// 当前的坐标系
double dUcsAngle = 0.0;
AcGeVector3d vtCur(cos(dUcsAngle), sin(dUcsAngle), 0);
dUcsAngle = ver.angleTo(vtCur, AcGeVector3d::kZAxis);
// 生成树的数量
int iNumTrees = 0;
if(bIsSetDis)// 间距自调
{
iNumTrees = (int)(dLenth / dTreeDis);
dTreeDis = dLenth / iNumTrees;
}
else// 间距不自调
{
iNumTrees = (int)(dLenth / dTreeDis);
}
AcGePoint3d ptInsertNew;
for(int i = 0; i < iNumTrees; i++)
{
// 计算新的插入点
acutPolar(asDblArray(ptSt), -dUcsAngle, dTreeDis+dTreeDis * i, asDblArray(ptInsertNew));
ptAryInsert.append(ptInsertNew);
}
}
// 圆弧样式生成树
void TDbPlaceTree::ArcStyle(AcDbArc *pArc, double dTreeDis, AcGePoint3dArray &ptAryInsert, BOOL bIsSetDis, double dBugle)
{
AcGePoint3d ptSt,ptCentre;
// 获得圆弧的参数
pArc->getStartPoint(ptSt);
ptCentre = pArc->center();
// add by xly on 110324 清空数组
ptAryInsert.setLogicalLength(0);
ptAryInsert.append(ptSt);
// 获得圆弧的半径
double dArcRad = pArc->radius();
// 计算弧长
double dLenth = (pArc->endAngle() - pArc->startAngle()) * dArcRad;
if (dLenth<0+_DIST_SNAP)// 优弧
{
dLenth = 2 * PI * dArcRad + dLenth;
}
// 当前的坐标系
double dUcsAngle;
// 生成树的数量
int iNumTrees = 0;
if (bIsSetDis)// 间距自调
{
iNumTrees = (int)(dLenth / dTreeDis);
dTreeDis = dLenth / iNumTrees;
// 根据弧长计算角度
dUcsAngle = dTreeDis / dArcRad;
}
else
{
// 根据弧长计算角度
dUcsAngle = dTreeDis / dArcRad;
// 计算插入树的数量
iNumTrees = (int)(dLenth / (dUcsAngle*dArcRad));
}
AcGeVector3d verSt, verEnd;
verSt = ptSt- ptCentre;
// 绘制树
AcGePoint3d ptInsertNew;
for(int i = 0; i<iNumTrees; i++ )
{
if (dBugle>-1E-6)
{
verEnd = verSt.rotateBy(dUcsAngle, AcGeVector3d::kZAxis);
}
else
{
verEnd = verSt.rotateBy(-dUcsAngle, AcGeVector3d::kZAxis);
}
ptInsertNew = verEnd + ptCentre;
ptAryInsert.append(ptInsertNew);
}
}