天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 56|回复: 0

objectARX将直线,圆弧,多段线转化为(合并)多段线

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-6-22 09:46:18 | 显示全部楼层 |阅读模式
[code]将头文件和实现文分别复制后,可直接使用:


头文件xxxx.h:


#pragma once
#include <vector>
using namespace std;


//给所有的点编号,多次出现的点只编一个号,后面用编号来代替点,简化过程
struct PointNum
{
AcGePoint3d pt; //点
int nNum;  //编号
};


//相连的点,用编号与编号连表示
struct NumMap
{
int nNum1;  //编号
int nNum2;  //编号
double dBulge; //凸度
};


//绘制点
struct DrawPoint
{
int nNum;  //编号
double dBulge; //到下一点的凸度
};


class UserHelp
{
public:
UserHelp(void);
public:
~UserHelp(void);
private:
//-----------------------------------------------------------------------------
//Summary:找出与这一点相连的下一点,以及与之相连的凸度
//Par:
// nm   相连信息数组
// nThisNum 点编号
// dThisBulge 凸度
// nNextNum 点编号(查找不成功时,为-1)
//Return:
// 查找成功为true,查找不成功为false
//-----------------------------------------------------------------------------
static bool FindNextPointNum(vector<NumMap>& nm, int nThisNum, double& dThisBulge, int& nNextNum);


//-----------------------------------------------------------------------------
//Summary:通过编号查找相应的点
//Par:
// vecPt2Num 点编号数组
// dThisBulge 凸度
// ptThis  对应的点
//Return:
// 查找成功为true,查找不成功为false
//-----------------------------------------------------------------------------
static bool NumToPoint(vector<PointNum>& vecPt2Num, int nThisNum, AcGePoint3d& ptThis);


//-----------------------------------------------------------------------------
//Summary:将实体添加到数据库中
//Par:
// pEnt 实体指针  
//Return:
// 返回添加实体ID号
//-----------------------------------------------------------------------------
static AcDbObjectId Append(AcDbEntity* pEnt);


//-----------------------------------------------------------------------------
//Summary:计算圆弧的凸度
//Par:
// pArc 圆弧指针  
//Return:
// 返回计算的结果
//-----------------------------------------------------------------------------
static double GetBulge(AcDbArc*& pArc);


//-----------------------------------------------------------------------------
//Summary:得到某两点间的绘制信息,包括点编号,连接信息
//Par:
// vecPt2Num 点编号数组
// vecNumMap 连接信息数组
// nCodeNum 需要编号的第几个点
// ptStart  起点
// ptEnd  终点
// dBulge  ptStart到ptEnd的凸度
//Return:
// 无。
//-----------------------------------------------------------------------------
static void GetDrawInfo(vector<PointNum>& vecPt2Num, vector<NumMap>& vecNumMap, int& nCodeNum,
const AcGePoint3d& ptStart, const AcGePoint3d ptEnd, double dBulge);


//-----------------------------------------------------------------------------
//Summary:将直线,圆弧,多段线转化为(合并)多段线
//Par:
// idObjArr 直线,圆弧,多段线的id
// idPolyline 转化后多段线的ID
//Return:
// 转换成功为true,不成功为false。
//-----------------------------------------------------------------------------
public:
static  bool ChangeToPolyLine(AcDbObjectIdArray& idObjArr, AcDbObjectId& idPolyline);
};








实现文件xxxx.cpp:





#include "StdAfx.h"
#include "UserHelp.h"
#include <algorithm>


UserHelp::UserHelp(void)
{
}


UserHelp::~UserHelp(void)
{
}


AcDbObjectId UserHelp::Append(AcDbEntity* pEnt)
{
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()
  ->getSymbolTable(pBlockTable, AcDb::kForRead);


AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,
  AcDb::kForWrite);
pBlockTable->close();


AcDbObjectId EntId;
pBlockTableRecord->appendAcDbEntity(EntId, pEnt);


pBlockTableRecord->close();
return EntId;
}


double UserHelp::GetBulge(AcDbArc*& pArc)
{
double dStartAngle = pArc->startAngle();
double dEndAngle = pArc->endAngle();


double dAlfa = dEndAngle - dStartAngle;
if (dAlfa < 0.0)//如果终点角度小于起点角度,取补角
{
  dAlfa = 2 * PI + dAlfa;
}


double dBulge = 0.0;


dBulge = tan((dAlfa) / 4.0);
return dBulge;
}




bool UserHelp::FindNextPointNum(vector<NumMap>& nm, int nThisNum, double& dThisBulge, int& nNextNum)
{
bool bFind = false;


//以第一个编号给为起点查找
vector<NumMap>::iterator itr;
for (itr = nm.begin(); itr != nm.end(); itr++)
{
  if ((*itr).nNum1 == nThisNum)
  {
   nNextNum = (*itr).nNum2;
   dThisBulge = (*itr).dBulge;
   bFind = true;
   nm.erase(itr);
   break;
  }
}


if (!bFind)//如果以第一个编号给为起点未找到,就以第二个编号给为起点查找
{
  for (itr = nm.begin(); itr != nm.end(); itr++)
  {
   if ((*itr).nNum2 == nThisNum)
   {
    nNextNum = (*itr).nNum1;
    dThisBulge = -(*itr).dBulge;//凸度取反
    bFind = true;
    nm.erase(itr);
    break;
   }
  }
}


if (bFind)
{
  return true;
}
else
{
  nNextNum = -1;
  dThisBulge = 0.0;
}

return false;
}


bool UserHelp::NumToPoint(vector<PointNum>& vecPt2Num, int nThisNum, AcGePoint3d& ptThis)
{
bool bFind = false;
vector<PointNum>::iterator itr;
for (itr = vecPt2Num.begin(); itr != vecPt2Num.end(); itr++)
{
  if ((*itr).nNum == nThisNum)
  {
   ptThis = (*itr).pt;
   bFind = true;
   break;
  }
}


return bFind;
}


void UserHelp::GetDrawInfo(vector<PointNum>& vecPt2Num, vector<NumMap>& vecNumMap, int& nCodeNum,
     const AcGePoint3d& ptStart, const AcGePoint3d ptEnd, double dBulge)
{
bool bStartNew = true; //起点是否编号
bool bEndNew = true; //终点是否编号


NumMap nummap;//两点之间的联系信息
nummap.dBulge = dBulge;


//处理起点
vector<PointNum>::iterator itr;
for (itr = vecPt2Num.begin(); itr != vecPt2Num.end(); itr++)
{
  if ((*itr).pt == ptStart)
  {
   bStartNew = false;
   nummap.nNum1 = (*itr).nNum;
   break;
  }
}


if (bStartNew)
{
  PointNum pn;
  pn.nNum = nCodeNum++;
  pn.pt = ptStart;
  vecPt2Num.push_back(pn);


  nummap.nNum1 = pn.nNum;
}


//处理终点
for (itr = vecPt2Num.begin(); itr != vecPt2Num.end(); itr++)
{
  if ((*itr).pt == ptEnd)
  {
   bEndNew = false;
   nummap.nNum2 = (*itr).nNum;
   break;
  }
}


if (bEndNew)
{
  PointNum pn;
  pn.nNum = nCodeNum++;
  pn.pt = ptEnd;
  vecPt2Num.push_back(pn);
  nummap.nNum2 = pn.nNum;
}


//添加联系信息
vecNumMap.push_back(nummap);
}


bool UserHelp::ChangeToPolyLine(AcDbObjectIdArray& idObjArr, AcDbObjectId& idPolyline)
{
vector<PointNum> vecPt2Num;//所有点编号
vector<NumMap> vecNumMap;//所有连接信息
int nCodeNum = 0;


int length = idObjArr.length();
for (int i = 0; i < length; i++)
{
  // 获得指向当前元素的指针
  AcDbEntity *pEnt;
  Acad::ErrorStatus es = acdbOpenAcDbEntity(pEnt, idObjArr.at(i),
   AcDb::kForRead);


  // 选择到作为边界的多段线了,直接跳过该次循环
  if (es != Acad::eOk)   
  {
   continue;
  }   


  if(pEnt->isKindOf(AcDbArc::desc()))//圆弧
  {
   AcDbArc* pArc = AcDbArc::cast(pEnt);
   if (pArc == NULL)
   {
    continue;
   }


   AcGePoint3d ptStart, ptEnd;
   pArc->getStartPoint(ptStart);
   pArc->getEndPoint(ptEnd);


   double dBulge = 0.0;
   dBulge = UserHelp::GetBulge(pArc);


   UserHelp::GetDrawInfo(vecPt2Num, vecNumMap, nCodeNum, ptStart, ptEnd, dBulge);
   pArc->close();   
  }
  else if (pEnt->isKindOf(AcDbLine::desc()))//直线
  {
   AcDbLine* pLine = AcDbLine::cast(pEnt);
   if (pLine == NULL)
   {
    continue;
   }   


   AcGePoint3d ptStart, ptEnd;
   pLine->getStartPoint(ptStart);
   pLine->getEndPoint(ptEnd);


   double dBulge = 0.0;


   UserHelp::GetDrawInfo(vecPt2Num, vecNumMap, nCodeNum, ptStart, ptEnd, dBulge);


   pLine->close();
  }


  else if (pEnt->isKindOf(AcDbPolyline::desc()))
  {
   AcDbPolyline* pPolyLine = AcDbPolyline::cast(pEnt);
   if (pPolyLine == NULL)
   {
    continue;
   }


   int nVerCount = 0;
   nVerCount = pPolyLine->numVerts();
   if (nVerCount <= 1)
   {
    continue;
   }
   AcGePoint3d ptFirst;
   double dBugle = -1000.0;
   pPolyLine->getPointAt(0, ptFirst);
   pPolyLine->getBulgeAt(0,dBugle);


   for (int i = 1; i < nVerCount; i++)
   {
    AcGePoint3d ptVer;
    pPolyLine->getPointAt(i, ptVer);
    UserHelp::GetDrawInfo(vecPt2Num, vecNumMap, nCodeNum, ptFirst, ptVer, dBugle);


    ptFirst = ptVer;
    pPolyLine->getBulgeAt(i, dBugle);
   }
   pPolyLine->close();   
  }


  pEnt->close();
}   


AcGePoint3d pt1, pt2;
double dBulge = 0.0;


vector<NumMap>::iterator itr1;// vecNumMap;
vector<NumMap>::iterator itr2;// vecNumMap;
vector< vector<DrawPoint> > vecLines;


if (vecNumMap.size() > 0)
{
  itr1 = vecNumMap.begin();
}


while(itr1 != vecNumMap.end())
{
  //从某点出发向一个方向搜索
  vector<DrawPoint> vecOneLine;


  int nBegin = (*itr1).nNum1;
  int nThisNum = nBegin;   
  int nLastNum = nThisNum;


  DrawPoint drawpoint;   


  while(vecNumMap.size() > 0)  
  {
   bool bSuc = false;
   double dThisBulge = 0.0;
   int nNextNum = 0;


   bSuc = UserHelp::FindNextPointNum(vecNumMap, nThisNum, dThisBulge, nNextNum);
   if (bSuc)
   {
    drawpoint.nNum = nThisNum;
    drawpoint.dBulge =dThisBulge;
    vecOneLine.push_back(drawpoint);
    nThisNum = nNextNum;
    nLastNum = nThisNum;
   }   
   else
   {
    break;
   }
  }


  //处理最近一个点
  drawpoint.nNum = nLastNum;
  drawpoint.dBulge = 0.0;
  vecOneLine.push_back(drawpoint);




  //从某点出发向另一个方向搜索
  vector<DrawPoint> vecOtherLine;
  nThisNum = nBegin;
  nLastNum = nThisNum;
  while(vecNumMap.size() > 0)  
  {
   bool bSuc = false;
   double dThisBulge = 0.0;
   int nNextNum = 0;


   bSuc = UserHelp::FindNextPointNum(vecNumMap, nThisNum, dThisBulge, nNextNum);
   if (bSuc)
   {
    drawpoint.nNum = nNextNum;
    drawpoint.dBulge =dThisBulge;
    vecOtherLine.push_back(drawpoint);
    nThisNum = nNextNum;
   }   
   else
   {
    break;
   }
  }


  //两个方向拼接
  reverse(vecOtherLine.begin(), vecOtherLine.end());
  vector<DrawPoint>::iterator itrTmp;
  for (itrTmp = vecOtherLine.begin(); itrTmp != vecOtherLine.end(); itrTmp++)
  {
   (*itrTmp).dBulge *= -1.0;
  }


  vecOtherLine.insert(vecOtherLine.end(), vecOneLine.begin(), vecOneLine.end());


  vecLines.push_back(vecOtherLine);
  itr1 = vecNumMap.begin();
}


//绘制多段线
vector< vector<DrawPoint> >::iterator itr_1;
vector<DrawPoint>::iterator itr_2;
for (itr_1 = vecLines.begin(); itr_1 != vecLines.end(); itr_1++)
{
  AcDbPolyline* pPolyLine = new AcDbPolyline;
  int i = 0;
  vector<DrawPoint>& vecPoints = (*itr_1);
  for (itr_2 = vecPoints.begin(); itr_2 != vecPoints.end(); itr_2++)
  {
   int nNum = (*itr_2).nNum;
   AcGePoint3d ptVer;
   if (UserHelp::NumToPoint(vecPt2Num, nNum, ptVer))
   {
    pPolyLine->addVertexAt(i++, ptVer.convert2d(AcGePlane::kXYPlane),(*itr_2).dBulge);
   }
  }


  idPolyline = UserHelp::Append(pPolyLine);
  pPolyLine->close();
}
return true;
}[/code]

 

 

 

 

objectARX将直线,圆弧,多段线转化为(合并)多段线
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

GMT+8, 2024-11-1 09:25 , Processed in 0.139213 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表