天气与日历 切换到窄版

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

‎使用 ObjectARX 获取 AcDbSpline 的边界框‎

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-6-22 09:46:18 | 显示全部楼层 |阅读模式
‎使用 ObjectARX 获取 AcDbSpline 的边界框‎


‎我想得到样条曲线的边界框,但是getGeomExtents()函数没有返回预期的结果。如何为样条曲线获得更紧密的边界框?‎

  
‎AcDbSpline 在使用 getGeomExtents() 时不会返回"紧密"边界框。‎

‎要获得更紧密的边界框,您需要自己计算边界框。您可以使用函数 getPointAtParam() 沿样条线遍历并检查最大/最小 x 和 y 坐标。边界框的精度取决于曲线的划分和采样程度。除法值 1e6 具有良好的精度,并且需要可接受的时间来计算。下面粘贴的函数显示了如何执行此操作。附加的 VC++ 项目具有完整的代码(具有最少的错误检查)。键入命令"SplineBB"并选择一个样条对象。它将绘制两个边界框。红色矩形是 getGeomExtents() 返回的范围,而黄色矩形是计算范围。‎


[code]///////////////////////////////////////////////////////////////////////////////////////////////
//Description: fKeepExtremes
//1) Function to check for the minimum/maximum X and Y.
//2) mPtMin and mPtMax will have minimum/maximum X and Y
///////////////////////////////////////////////////////////////////////////////////////////////


void fKeepExtremes(AcGePoint3d& mPtSample,AcGePoint3d& mPtMin,AcGePoint3d& mPtMax)
{
//test for max
if(mPtSample.x > mPtMax.x) mPtMax.x = mPtSample.x;
if(mPtSample.y > mPtMax.y) mPtMax.y = mPtSample.y;
if(mPtSample.z > mPtMax.z) mPtMax.z = mPtSample.z;

//test for min
if(mPtSample.x < mPtMin.x) mPtMin.x = mPtSample.x;
if(mPtSample.y < mPtMin.y) mPtMin.y = mPtSample.y;
if(mPtSample.z > mPtMax.z) mPtMax.z = mPtSample.z;
}


///////////////////////////////////////////////////////////////////////////////////////////////
//Description: fGetBoundingBoxBySampling
//1) Function to divide the AcDbSpline 1e6 times and check for points at each division
///////////////////////////////////////////////////////////////////////////////////////////////
void fGetBoundingBoxBySampling(AcDbSpline *pSpline,AcGePoint3d& mPtMin, AcGePoint3d& mPtMax)
{
double mParam;
double mIncr;


double mStartParam;
double mEndParam;


AcGePoint3d mPtTemp;
pSpline->getStartPoint(mPtTemp);
pSpline->getParamAtPoint(mPtTemp,mStartParam);


pSpline->getEndPoint(mPtTemp);
pSpline->getParamAtPoint(mPtTemp,mEndParam);

//calculate the division
mIncr = (mEndParam - mStartParam)/1e6; //1e6 is the sampling tolerance

//set the seed point for max and min. It is set to the start point
mPtMax = mPtTemp;
mPtMin = mPtTemp;


for(mParam = mStartParam;mParam <= mEndParam;mParam +=mIncr)
{
  if(Acad::eOk == pSpline->getPointAtParam(mParam,mPtTemp))
  {
   fKeepExtremes(mPtTemp,mPtMin,mPtMax);
  }


}
}


///////////////////////////////////////////////////////////////////////////////////////////////
//Description: fDrawRect
//1) Draws a LwPolyline rectangle given lower left and upper right corners
///////////////////////////////////////////////////////////////////////////////////////////////
void fDrawRect(AcGePoint3d& mPtMin,AcGePoint3d& mPtMax,int mColor)
{
AcDbPolyline *pPline = new AcDbPolyline(4);
pPline->addVertexAt(0, AcGePoint2d(mPtMin.x,mPtMin.y));
pPline->addVertexAt(1,AcGePoint2d(mPtMax.x,mPtMin.y));
pPline->addVertexAt(2,AcGePoint2d(mPtMax.x,mPtMax.y));
pPline->addVertexAt(3,AcGePoint2d(mPtMin.x,mPtMax.y));
pPline->setClosed(Adesk::kTrue);

fAddEntToDwg(acdbHostApplicationServices()->workingDatabase(),pPline);
pPline->setColorIndex(mColor);
pPline->close();
}


///////////////////////////////////////////////////////////////////////////////////////////////
//Description: SplineBB
//1) command 'SplineBB'
///////////////////////////////////////////////////////////////////////////////////////////////
void SplineBB()
{
AcDbEntity *pEnt = NULL;
AcDbObjectId mId;
ads_point mPt;
ads_name mEname;

//select the entity
if ( RTNORM == acedEntSel(L"Select a Spline", mEname, mPt))
{
  if ( Acad::eOk == acdbGetObjectId(mId, mEname ))
  {
   acdbOpenAcDbEntity(pEnt, mId, AcDb::kForRead);
  }
}
else
{
  return;
}


//see if it is a spline
AcDbSpline *pSpline = NULL;


if (NULL != pEnt)
{
  pSpline = AcDbSpline::cast(pEnt);


  if(NULL != pSpline)
  {
   AcGePoint3d mPtMin,mPtMax;


   //draw the bounding box returned by spline's getGeomExtents
   AcDbExtents mExts;
   pSpline->getGeomExtents(mExts);


   //draw bounding box returned by the spline in red
   fDrawRect(mExts.minPoint(),mExts.maxPoint(),1);
   
   //calculate the time taken
   struct _timeb t1,t2;
   _ftime(&t1);


   //calculate the bounding box
   fGetBoundingBoxBySampling(pSpline,mPtMin,mPtMax);
   
   _ftime(&t2);
   acutPrintf(L"\nMethod Time %6.2f seconds.\n", (t2.time + (double)(t2.millitm)/1000) - (t1.time + (double)(t1.millitm)/1000) );
   
   //draw calculated bounding box in yellow
   fDrawRect(mPtMin,mPtMax,2);


   pSpline->close();
  }
  else
  {
   acutPrintf(L"\nEntity is not an Spline");
   pEnt->close();
  }
}
return;
}[/code]

 

 

 

 

‎使用 ObjectARX 获取 AcDbSpline 的边界框‎
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-1 13:31 , Processed in 0.139306 second(s), 24 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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