乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 18|回复: 1

使用梦想绘图控件ARX编程,搜索闭合区域,计算面积和周长的代码

[复制链接]

13

主题

31

帖子

4

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
83
发表于 2009-9-23 08:31:00 | 显示全部楼层 |阅读模式
程序运效果可以参考控件安装目录的sample\edit.sln工程。
.h 文件
// 计算直线与PL线组成的闭合区域的面积,和周长。
class CAreaCalculation
{
public:
CAreaCalculation(void);
virtual ~CAreaCalculation(void);
// 执行该功能。
void Do();
private:
// 跟用户交互,让用户在图上选择一个闭合区域的直线或PL线。
AcDbObjectId SelEntity();

// 搜索闭合区域的递归调用函数。
bool SearchClosePathCall(IN AcGePoint3d startPt, // 搜索的开始点。
IN AcGePoint3d curPt, // 当前搜索位置。
IN std::set& adyFindId, // 搜索过程中,已经发现的曲线ID.
IN OUT std::vector& aryPathId, // 搜索成功,返回的闭合区域ID。
IN double dSearchTol, // 搜索精度范围,在这个范围内的曲线是认为连接的。
IN struct resbuf* pRbFilter // 搜索实体的过滤条件。
);
};

.cpp文件:
#include "StdAfx.h"
#include "AreaCalculation.h"
#include "MxTools.h"
CAreaCalculation::CAreaCalculation(void)
{
}
CAreaCalculation::~CAreaCalculation(void)
{
}

void CAreaCalculation:o()
{
MxDraw::StopAllTwinkeEnt(MxDraw::GetCurOcxHandle() );
// 让用户选择闭合区域中的某条线,然后由该条线搜索到整个闭合区域。
AcDbObjectId entId = CAreaCalculation::SelEntity();
if(entId.isNull() )
return;
// 由entId实体开始,搜索整个闭合区域。
AcDbObjectPointer spCurve(entId,AcDb::kForRead);
if(spCurve.openStatus() != Acad::eOk)
{
ASSERT(0);
return ;
}
AcGePoint3d sPt;
spCurve->getStartPoint(sPt);
AcGePoint3d ePt;
spCurve->getEndPoint(ePt);
double dSeachTol = 3.0;

AcDbPolyline *pPl = AcDbPolyline::cast(spCurve.object() );
if(pPl != NULL)
{
bool isClose = pPl->isClosed();
if(!isClose)
{
// 看该曲线是不是首尾相连的.
if(sPt.distanceTo(ePt) getArea(dArea);
double dEndParam = 0.0;
pPl->getEndParam(dEndParam);
double dLen = 0.0;
pPl->getDistAtParam(dEndParam,dLen);
acutPrintf(_T("\n 面积为:%lf,周长为:%lf"),dArea,dLen);
spCurve->close();
MxDraw::TwinkeEnt(entId);
return ;
}
}

CString sLayerName = spCurve->layerEx();
spCurve->close();

if(sPt.distanceTo(ePt)  adyFindId;
adyFindId.insert(entId);
// 把层名做为过滤条件。
struct resbuf* pRbFilter = acutBuildList(RTDXF0,_T("LINE,LWPOLYLINE,ARC"),8,sLayerName,0);
std::vector aryPathId;
if(!SearchClosePathCall(sPt,
ePt,adyFindId,aryPathId,dSeachTol,pRbFilter) )
{
acutPrintf(_T("\n 没有发现闭合区域"));
acutRelRb(pRbFilter);
return ;
}
acutRelRb(pRbFilter);
aryPathId.push_back(entId);

// 由闭合区域,构造一个临时的PL线,用于计算面积。
std::vector::reverse_iterator iter = aryPathId.rbegin();
bool isFirst = false;
AcGePoint3d curPt = sPt;
std::vector vecVertex;
std::vector vecBulge;
vecVertex.push_back(sPt.convert2d(AcGePlane::kXYPlane));
vecBulge.push_back(0.0);
for(;iter != aryPathId.rend();++iter)
{
AcDbObjectPointer spCurve(*iter,AcDb::kForRead);
if(spCurve.openStatus() != Acad::eOk)
{
ASSERT(0);
return ;
}
if(AcDbLine::cast(spCurve.object() ) != NULL)
{
AcDbLine* pLine = AcDbLine::cast(spCurve.object());
AcGePoint3d sPt;
pLine->getStartPoint(sPt);
AcGePoint3d ePt;
pLine->getEndPoint(ePt);
AcGePoint3d nextPt = sPt;
if(curPt.distanceTo(sPt) getStartPoint(sPt);
AcGePoint3d ePt;
pArc->getEndPoint(ePt);
if(curPt.distanceTo(sPt) > curPt.distanceTo(ePt) )
{
AcGePoint3d tmpPt = sPt;
sPt = ePt;
ePt = tmpPt;
}
curPt = ePt;
double dSParam = 0.0;
double dEParam = 1.0;
pArc->getStartParam(dSParam);
pArc->getEndParam(dEParam);
AcGePoint3d cenPt;
if(pArc->getPointAtParam(dSParam + (dEParam - dSParam) / 2.0,cenPt)
!= Acad::eOk)
{
ASSERT(0);
return;
}
// 计算圆弧的凸度。
double dBulge = 0.0;
if(MxTools::GetArcBulge(sPt,
cenPt,
ePt,
dBulge
) )
{
vecBulge[vecBulge.size() - 1] = dBulge;
vecVertex.push_back(ePt.convert2d(AcGePlane::kXYPlane));
vecBulge.push_back(0.0);
}
else
{
vecVertex.push_back(ePt.convert2d(AcGePlane::kXYPlane));
vecBulge.push_back(0.0);
}
}
else if(AcDbPolyline::cast(spCurve.object()) != NULL)
{
AcDbPolyline* pPolyline = AcDbPolyline::cast(spCurve.object());

std::vector vecTmpPt;
std::vector vecTmpBulge;
int iNum = pPolyline->numVerts();
for(int k = 0; k getPointAt(k,pt);
double dBulge = 0.0;
pPolyline->getBulgeAt(k,dBulge);
vecTmpPt.push_back(pt);
vecTmpBulge.push_back(dBulge);
}
if(curPt.convert2d(AcGePlane::kXYPlane).distanceTo(vecTmpPt[0])
> curPt.convert2d(AcGePlane::kXYPlane).distanceTo(vecTmpPt[iNum - 1])
)
{
// 反向。
for(int j = iNum - 2; j >= 0 ;j--)
{
vecBulge[vecBulge.size() - 1] = -vecTmpBulge[j];
vecVertex.push_back(vecTmpPt[j]);
vecBulge.push_back(0.0);
}
curPt = vecTmpPt[0].Point3d();
}
else
{
//
for(int j = 1; j & adyFindId,
IN OUT std::vector& aryPathId,
IN double dSearchTol,
IN struct resbuf* pRbFilter
)
{
AcDbObjectIdArray aryId;
if(!MxTools::FindEntAtPoint(curPt,pRbFilter,
dSearchTol * 10.0,aryId) )
{
return false;
}
// vecNextPos 需要搜索的下一个位置。
std::map mapNextPos;
for(int i = 0; i  spCurve(aryId,AcDb::kForRead);
if(spCurve.openStatus() != Acad::eOk)
continue;
AcGePoint3d sPt;
spCurve->getStartPoint(sPt);
AcGePoint3d ePt;
spCurve->getEndPoint(ePt);
// 小短线。
if(sPt.distanceTo(ePt)  dEDis)
dMinDis = dEDis;
if(dMinDis > dSearchTol)
{
// 认为两条线不连接.
continue;
}
adyFindId.insert(aryId);

AcGePoint3d nexPt = sPt;
if(dSDis ::iterator iter = mapNextPos.begin();
for(;iter != mapNextPos.end();++iter)
{
if(SearchClosePathCall(startPt,
iter->second,
adyFindId,
aryPathId,
dSearchTol,pRbFilter
) )
{
aryPathId.push_back(iter->first);
return true;
}
}
return false;
}
AcDbObjectId CAreaCalculation::SelEntity()
{
struct resbuf* pRbFilter = acutBuildList(RTDXF0,_T("LINE,LWPOLYLINE,ARC"),0);
AcDbObjectId id;
AcGePoint3d ptPick;
if(MxTools::SelectEnt(_T("\n 选择闭合区域中的某条线:"),pRbFilter,id,ptPick) != RTNORM)
{
return id;
}
acutRelRb(pRbFilter);
return id;
}

ax2dnjxzulp.JPG

ax2dnjxzulp.JPG

回复

使用道具 举报

0

主题

2

帖子

1

银币

初来乍到

Rank: 1

铜币
2
发表于 2010-8-13 17:47:00 | 显示全部楼层
我只想问下,你是如何把CAD嵌入到自己的窗体中的~~~~~

谢谢了
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-2-5 19:58 , Processed in 0.170954 second(s), 59 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表