使用梦想绘图控件ARX编程,搜索闭合区域,计算面积和周长的代码
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px;"><p><font color="#000000" size="3" face="宋体-方正超大字符集">程序运效果可以参考控件安装目录的sample\edit.sln工程。</font></p><p><font color="#000000" size="2" face="宋体-方正超大字符集"></font></p><p><font color="#000000" size="2" face="宋体-方正超大字符集">.h 文件<br/>// 计算直线与PL线组成的闭合区域的面积,和周长。<br/><br/>class CAreaCalculation<br/>{<br/>public:<br/>CAreaCalculation(void);<br/>virtual ~CAreaCalculation(void);<br/><br/>// 执行该功能。<br/>void Do();<br/><br/>private:<br/>// 跟用户交互,让用户在图上选择一个闭合区域的直线或PL线。<br/>AcDbObjectId SelEntity();<br/><br/><br/>// 搜索闭合区域的递归调用函数。<br/>bool SearchClosePathCall(IN AcGePoint3d startPt, // 搜索的开始点。<br/>IN AcGePoint3d curPt, // 当前搜索位置。<br/>IN std::set<AcDbObjectId>& adyFindId, // 搜索过程中,已经发现的曲线ID.<br/>IN OUT std::vector<AcDbObjectId>& aryPathId, // 搜索成功,返回的闭合区域ID。<br/>IN double dSearchTol, // 搜索精度范围,在这个范围内的曲线是认为连接的。<br/>IN struct resbuf* pRbFilter // 搜索实体的过滤条件。<br/>);<br/><br/>};<br/><br/><br/>.cpp文件:<br/><br/>#include "StdAfx.h"<br/>#include "AreaCalculation.h"<br/>#include "MxTools.h"<br/><br/>CAreaCalculation::CAreaCalculation(void)<br/>{<br/>}<br/><br/>CAreaCalculation::~CAreaCalculation(void)<br/>{<br/>}<br/><br/><br/>void CAreaCalculation::Do()<br/>{<br/>MxDraw::StopAllTwinkeEnt(MxDraw::GetCurOcxHandle() );<br/>// 让用户选择闭合区域中的某条线,然后由该条线搜索到整个闭合区域。<br/>AcDbObjectId entId = CAreaCalculation::SelEntity();<br/>if(entId.isNull() )<br/>return;<br/><br/>// 由entId实体开始,搜索整个闭合区域。<br/>AcDbObjectPointer<AcDbCurve> spCurve(entId,AcDb::kForRead);<br/>if(spCurve.openStatus() != Acad::eOk)<br/>{<br/>ASSERT(0);<br/>return ;<br/>}<br/><br/>AcGePoint3d sPt;<br/>spCurve->getStartPoint(sPt);<br/><br/>AcGePoint3d ePt;<br/>spCurve->getEndPoint(ePt);<br/><br/>double dSeachTol = 3.0;<br/><br/><br/>AcDbPolyline *pPl = AcDbPolyline::cast(spCurve.object() );<br/>if(pPl != NULL)<br/>{<br/>bool isClose = pPl->isClosed();<br/>if(!isClose)<br/>{<br/>// 看该曲线是不是首尾相连的.<br/>if(sPt.distanceTo(ePt) < dSeachTol)<br/>isClose = true;<br/>}<br/>if(isClose)<br/>{<br/>double dArea = 0.0;<br/>pPl->getArea(dArea);<br/><br/>double dEndParam = 0.0;<br/>pPl->getEndParam(dEndParam);<br/><br/>double dLen = 0.0;<br/>pPl->getDistAtParam(dEndParam,dLen);<br/><br/>acutPrintf(_T("\n 面积为:%lf,周长为:%lf"),dArea,dLen);<br/><br/>spCurve->close();<br/>MxDraw::TwinkeEnt(entId);<br/>return ;<br/>}<br/>}<br/><br/><br/>CString sLayerName = spCurve->layerEx();<br/><br/>spCurve->close();<br/><br/><br/>if(sPt.distanceTo(ePt) < dSeachTol)<br/>{<br/>// 小短线。<br/>acutPrintf(_T("\n 选择的曲线开始点与结束点相同"));<br/>return ;<br/>}<br/><br/>std::set<AcDbObjectId> adyFindId;<br/>adyFindId.insert(entId);<br/><br/>// 把层名做为过滤条件。<br/>struct resbuf* pRbFilter = acutBuildList(RTDXF0,_T("LINE,LWPOLYLINE,ARC"),8,sLayerName,0);<br/><br/>std::vector<AcDbObjectId> aryPathId;<br/>if(!SearchClosePathCall(sPt,<br/>ePt,adyFindId,aryPathId,dSeachTol,pRbFilter) )<br/>{<br/>acutPrintf(_T("\n 没有发现闭合区域"));<br/>acutRelRb(pRbFilter);<br/>return ;<br/>}<br/>acutRelRb(pRbFilter);<br/>aryPathId.push_back(entId);<br/><br/><br/>// 由闭合区域,构造一个临时的PL线,用于计算面积。<br/><br/>std::vector<AcDbObjectId>::reverse_iterator iter = aryPathId.rbegin();<br/>bool isFirst = false;<br/><br/>AcGePoint3d curPt = sPt;<br/>std::vector<AcGePoint2d> vecVertex;<br/>std::vector<double> vecBulge;<br/><br/>vecVertex.push_back(sPt.convert2d(AcGePlane::kXYPlane));<br/>vecBulge.push_back(0.0);<br/>for(;iter != aryPathId.rend();++iter)<br/>{<br/>AcDbObjectPointer<AcDbCurve> spCurve(*iter,AcDb::kForRead);<br/>if(spCurve.openStatus() != Acad::eOk)<br/>{<br/>ASSERT(0);<br/>return ;<br/>}<br/>if(AcDbLine::cast(spCurve.object() ) != NULL)<br/>{<br/>AcDbLine* pLine = AcDbLine::cast(spCurve.object());<br/>AcGePoint3d sPt;<br/>pLine->getStartPoint(sPt);<br/><br/>AcGePoint3d ePt;<br/>pLine->getEndPoint(ePt);<br/><br/>AcGePoint3d nextPt = sPt;<br/>if(curPt.distanceTo(sPt) < curPt.distanceTo(ePt) )<br/>nextPt = ePt;<br/><br/>vecVertex.push_back(nextPt.convert2d(AcGePlane::kXYPlane));<br/>vecBulge.push_back(0.0);<br/><br/>curPt = nextPt;<br/>}<br/>else if(AcDbArc::cast(spCurve.object()) != NULL)<br/>{<br/>AcDbArc* pArc = AcDbArc::cast(spCurve.object());<br/>AcGePoint3d sPt;<br/>pArc->getStartPoint(sPt);<br/><br/>AcGePoint3d ePt;<br/>pArc->getEndPoint(ePt);<br/><br/>if(curPt.distanceTo(sPt) > curPt.distanceTo(ePt) )<br/>{<br/>AcGePoint3d tmpPt = sPt;<br/>sPt = ePt;<br/>ePt = tmpPt;<br/>}<br/>curPt = ePt;<br/><br/>double dSParam = 0.0;<br/>double dEParam = 1.0;<br/>pArc->getStartParam(dSParam);<br/>pArc->getEndParam(dEParam);<br/><br/>AcGePoint3d cenPt;<br/>if(pArc->getPointAtParam(dSParam + (dEParam - dSParam) / 2.0,cenPt)<br/>!= Acad::eOk)<br/>{<br/>ASSERT(0);<br/>return;<br/>}<br/><br/>// 计算圆弧的凸度。<br/>double dBulge = 0.0;<br/>if(MxTools::GetArcBulge(sPt,<br/>cenPt,<br/>ePt,<br/>dBulge<br/>) )<br/>{<br/>vecBulge = dBulge;<br/>vecVertex.push_back(ePt.convert2d(AcGePlane::kXYPlane));<br/>vecBulge.push_back(0.0);<br/>}<br/>else<br/>{<br/>vecVertex.push_back(ePt.convert2d(AcGePlane::kXYPlane));<br/>vecBulge.push_back(0.0);<br/>}<br/>}<br/>else if(AcDbPolyline::cast(spCurve.object()) != NULL)<br/>{<br/>AcDbPolyline* pPolyline = AcDbPolyline::cast(spCurve.object());<br/><br/><br/>std::vector<McGePoint2d> vecTmpPt;<br/>std::vector<double> vecTmpBulge;<br/><br/>int iNum = pPolyline->numVerts();<br/>for(int k = 0; k < iNum;k++)<br/>{<br/>AcGePoint2d pt;<br/>pPolyline->getPointAt(k,pt);<br/>double dBulge = 0.0;<br/>pPolyline->getBulgeAt(k,dBulge);<br/><br/>vecTmpPt.push_back(pt);<br/>vecTmpBulge.push_back(dBulge);<br/>}<br/><br/>if(curPt.convert2d(AcGePlane::kXYPlane).distanceTo(vecTmpPt) <br/>> curPt.convert2d(AcGePlane::kXYPlane).distanceTo(vecTmpPt) <br/>)<br/>{<br/>// 反向。<br/>for(int j = iNum - 2; j >= 0 ;j--)<br/>{<br/>vecBulge = -vecTmpBulge;<br/>vecVertex.push_back(vecTmpPt);<br/>vecBulge.push_back(0.0);<br/>}<br/>curPt = vecTmpPt.Point3d();<br/>}<br/>else<br/>{<br/>// <br/>for(int j = 1; j < iNum;j++)<br/>{<br/>vecBulge = vecTmpBulge;<br/>vecVertex.push_back(vecTmpPt);<br/>vecBulge.push_back(0.0);<br/>}<br/>curPt = vecTmpPt.Point3d();;<br/>}<br/>}<br/>else<br/>{<br/>ASSERT(0);<br/>}<br/>}<br/><br/>// 构建PL线.<br/><br/>ASSERT(vecVertex.size() == vecBulge.size());<br/><br/>AcDbPolyline tmpPl;<br/>for(unsigned int n = 0; n < vecVertex.size();n++)<br/>{<br/>tmpPl.addVertexAt(vecVertex,vecBulge);<br/>}<br/><br/>// 调用tmpPL计算面积,周长,函数。<br/><br/>double dArea = 0.0;<br/>tmpPl.getArea(dArea);<br/><br/>double dEndParam = 0.0;<br/>tmpPl.getEndParam(dEndParam);<br/><br/>double dLen = 0.0;<br/>tmpPl.getDistAtParam(dEndParam,dLen);<br/><br/>acutPrintf(_T("\n 面积为:%lf,周长为:%lf"),dArea,dLen);<br/><br/>for(unsigned int nn = 0; nn < aryPathId.size();nn++)<br/>{<br/>MxDraw::TwinkeEnt(aryPathId);<br/>}<br/><br/>}<br/><br/>bool CAreaCalculation::SearchClosePathCall(IN AcGePoint3d startPt,<br/>IN AcGePoint3d curPt,<br/>IN std::set<AcDbObjectId>& adyFindId,<br/>IN OUT std::vector<AcDbObjectId>& aryPathId,<br/>IN double dSearchTol,<br/>IN struct resbuf* pRbFilter<br/>)<br/>{<br/><br/>AcDbObjectIdArray aryId;<br/>if(!MxTools::FindEntAtPoint(curPt,pRbFilter,<br/>dSearchTol * 10.0,aryId) )<br/>{<br/>return false;<br/>}<br/><br/>// vecNextPos 需要搜索的下一个位置。<br/>std::map<AcDbObjectId,AcGePoint3d> mapNextPos;<br/>for(int i = 0; i < aryId.length();i++)<br/>{<br/>if(adyFindId.find(aryId) != adyFindId.end() )<br/>continue;<br/><br/>AcDbObjectPointer<AcDbCurve> spCurve(aryId,AcDb::kForRead);<br/>if(spCurve.openStatus() != Acad::eOk)<br/>continue;<br/><br/>AcGePoint3d sPt;<br/>spCurve->getStartPoint(sPt);<br/><br/>AcGePoint3d ePt;<br/>spCurve->getEndPoint(ePt);<br/><br/>// 小短线。<br/>if(sPt.distanceTo(ePt) < dSearchTol)<br/>{<br/>continue;<br/>}<br/>double dSDis = sPt.distanceTo(curPt);<br/>double dEDis = ePt.distanceTo(curPt);<br/>double dMinDis = dSDis;<br/>if(dMinDis > dEDis)<br/>dMinDis = dEDis;<br/>if(dMinDis > dSearchTol)<br/>{<br/>// 认为两条线不连接.<br/>continue; <br/>}<br/>adyFindId.insert(aryId);<br/><br/><br/>AcGePoint3d nexPt = sPt;<br/>if(dSDis < dEDis )<br/>nexPt = ePt;<br/><br/>if(nexPt.distanceTo(startPt) < dSearchTol)<br/>{<br/>// 找到了闭合区域。<br/>aryPathId.push_back(aryId);<br/>return true;<br/>}<br/>mapNextPos.insert(std::make_pair(aryId,nexPt) );<br/>}<br/><br/>std::map<AcDbObjectId,AcGePoint3d>::iterator iter = mapNextPos.begin();<br/>for(;iter != mapNextPos.end();++iter)<br/>{<br/>if(SearchClosePathCall(startPt,<br/>iter->second,<br/>adyFindId,<br/>aryPathId,<br/>dSearchTol,pRbFilter<br/>) )<br/>{<br/>aryPathId.push_back(iter->first);<br/>return true;<br/>}<br/>}<br/>return false;<br/>}<br/><br/>AcDbObjectId CAreaCalculation::SelEntity()<br/>{<br/>struct resbuf* pRbFilter = acutBuildList(RTDXF0,_T("LINE,LWPOLYLINE,ARC"),0);<br/><br/>AcDbObjectId id;<br/>AcGePoint3d ptPick;<br/><br/>if(MxTools::SelectEnt(_T("\n 选择闭合区域中的某条线:"),pRbFilter,id,ptPick) != RTNORM)<br/>{<br/>return id;<br/>}<br/>acutRelRb(pRbFilter);<br/><br/>return id;<br/>}</font></p></blockquote> <p>我只想问下,你是如何把CAD嵌入到自己的窗体中的~~~~~</p><p> </p>
<p>谢谢了</p>
页:
[1]