244 lines
5.4 KiB
C++
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);
|
|
}
|
|
|
|
}
|