CAD工具之家's Archivers

From boitboy on 2013-07-11 17:05:08

样条曲线转换为多段线

样条曲线拟合 //定义PI #ifndef PI #define PI 4*atan(1.0)//提高pi的精度 #endif bool getSplineSamplePoints(AcDbSpline *&spline, AcGePoint3dArray &pnts) { assert(spline != NULL); AcGePoint3d orgPt; spline->getStartPoint(orgPt); pnts.append(orgPt); double dStartParam=0.0; spline->getStartParam(dStartParam); double dEntParam=0.0; spline->getEndParam(dEntParam); double dDist=0.0; spline->getDistAtParam(dEntParam,dDist); int nNum=(int)dDist/0.005; if(nNum<25) { nNum=25; } if(nNum>10000) { nNum=10000; } for(int i=0;i<nNum;i++) { double dTmpParam=0.0; spline->getParamAtDist(dDist*(i+1)/nNum,dTmpParam); spline->getPointAtParam(dTmpParam,orgPt); pnts.append(orgPt); } return pnts.logicalLength()>2; } AcGePoint2d convert3dPointTo2d(AcGePoint3d pt) { AcGePoint2d pm; pm.set(pt.x,pt.y); return pm; } //获取三个点构成的夹角 double GetIntersectionDngle(AcGePoint2d pt1,AcGePoint2d pt2,AcGePoint2d pt3) { AcGeVector2d vt1=pt1-pt2; AcGeVector2d vt2=pt3-pt2; return vt1.angleTo(vt2); } //获取三个点构成的夹角 double GetIntersectionDngle(AcGePoint3d pt1,AcGePoint3d pt2,AcGePoint3d pt3) { return GetIntersectionDngle(convert3dPointTo2d(pt1),convert3dPointTo2d(pt2),convert3dPointTo2d(pt3)); } //删除构成直线的三个点中间的点 //dMinAngle,构成的夹角最小值,默认为0.5度 void RemovePointBetweenLine(AcGePoint3dArray &pnts,double dMinAngle=PI-0.5*PI/180.0) { AcGePoint3dArray rcPts; if(pnts.logicalLength()<=2) { return; } rcPts.append(pnts.at(0)); rcPts.append(pnts.at(1)); for(int i=2;i<pnts.logicalLength();i++) { AcGePoint3d pt1=rcPts.at(rcPts.logicalLength()-2); AcGePoint3d pt2=rcPts.at(rcPts.logicalLength()-1); AcGePoint3d pt3=pnts.at(i); double dAngle=GetIntersectionDngle(pt1,pt2,pt3); if(dAngle>=dMinAngle&&dAngle<=PI) { rcPts.setAt(rcPts.logicalLength()-1,pt3); } else { rcPts.append(pt3); } } pnts.setLogicalLength(0); pnts.append(rcPts); } // 功能:将选择集转换为实体ID数组 // 参数: ssName,选择集 // ObjIds,实体ID数组 // 返回: void SSToIds(AcDbObjectIdArray& ObjIds,ads_name ssName) { AcDbObjectId ObjId; ads_name EntName; long nLength=0; acedSSLength(ssName,&nLength); for(int nLen=0; nLen<nLength; nLen++) { acedSSName(ssName,nLen,EntName); acdbGetObjectId(ObjId,EntName); ObjIds.append(ObjId); } } // 功能:添加实体到块表记录中 // 参数: pEnt:待添加的实体指针 // btrID,AcDbBlockTableRecord的ID // 返回: 实体的ObjectID,如果插入失败返回一个空的ObjectId AcDbObjectId AppendEntity(AcDbEntity* pEnt,const AcDbObjectId btrID) { AcDbObjectId resultId; resultId.setNull(); AcDbBlockTableRecord* pBlkRec = NULL;//打开表 Acad::ErrorStatus es = acdbOpenObject(pBlkRec, btrID, AcDb::kForWrite); if (es != Acad::eOk) { acutPrintf(_T("\n 打开模型空间失败!%s"),acadErrorStatusText(es)); return resultId; } es = pBlkRec->appendAcDbEntity(resultId,pEnt);//添加实体 if (es != Acad::eOk) { acutPrintf(_T("\n 添加对象到模型空间失败!%s"),acadErrorStatusText(es)); pBlkRec->close(); return resultId; } es=pBlkRec->close(); return resultId; } Acad::ErrorStatus ToPLine(AcDbSpline *spline) { AcGePoint3dArray pnts; bool rc=getSplineSamplePoints(spline,pnts); if(!rc) return Acad::eInvalidInput; RemovePointBetweenLine(pnts); AcDbPolyline* pLine=new AcDbPolyline(pnts.logicalLength()); for(int i=0;i<pnts.logicalLength();i++) { pLine->addVertexAt(i,convert3dPointTo2d(pnts.at(i))); } AppendEntity(pLine,spline->blockId()); pLine->close(); return Acad::eOk; } Acad::ErrorStatus ToPLine(AcDbObjectId id) { AcDbObjectPointer<AcDbSpline> spLine(id,AcDb::kForRead); if(spLine.openStatus()!=Acad::eOk) return spLine.openStatus(); return ToPLine(spLine.object()); } void ToPLine() { Acad::ErrorStatus es=eOk; resbuf* rb = acutBuildList(RTDXF0, _T("SPLINE"), 0); ads_name ssName; acutPrintf(_T("\n请选择样条曲线:\n")); int rc=acedSSGet(NULL, NULL,NULL,rb,ssName); if(rc!=RTNORM) { acutRelRb(rb); return; } AcDbObjectIdArray ids; SSToIds(ids,ssName); acedSSFree(ssName); AcDbObjectId id; for(int i=0;i<ids.logicalLength();i++) { id=ids.at(i); ToPLine(id); } }

查看完整版本: 样条曲线转换为多段线

Tags: ObjectArx, 多段线, 拟合, 样条曲线


©CAD工具之家
创办于:2013年5月24日