从多段线上直接偏移一条线段或是圆弧
<p><font face="Verdana"><font face="Verdana">AcDbObjectId PostToMS(AcDbEntity *pEnt)<br/>{<br/> AcDbBlockTable *pBlkTbl;<br/> acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl,<br/> AcDb::kForRead);<br/> AcDbBlockTableRecord *pMS;<br/> pBlkTbl->getAt(ACDB_MODEL_SPACE,pMS,AcDb::kForWrite);<br/> pBlkTbl->close();<br/> AcDbObjectId EntID;<br/> pMS->appendAcDbEntity(EntID,pEnt);<br/> pMS->close();<br/> return EntID;<br/>}</font></font></p><p><font face="Verdana"></font> </p>
<p><font face="Verdana">static void ROYMyTest_Test3(void)<br/> {<br/> // Add your code for command ROYMyTest._Test3 here<br/> ads_point pt,SidePt;<br/> ads_name eName;<br/> if (acedEntSel(_T("\nSelect a polyline:"),eName,pt)!=RTNORM)<br/> return;<br/> ads_real dDistance;<br/> acedInitGet(RSG_NONEG | RSG_NOZERO,_T(""));<br/> CString strPrompt;<br/> struct resbuf rb;<br/> acedGetVar(_T("OFFSETDIST"),&rb);<br/> strPrompt.Format(_T("\nInput offset distance<%.2f>:"),rb.resval.rreal);<br/> int state;<br/> state=acedGetReal(strPrompt,&dDistance);<br/> switch (state)<br/> {<br/> case RTNONE:<br/> dDistance=rb.resval.rreal;<br/> break;<br/> case RTCAN:<br/> return;<br/> case RTNORM:<br/> default:<br/> break;<br/> }<br/> rb.resval.rreal=dDistance;<br/> acedSetVar(_T("OFFSETDIST"),&rb);</font></p>
<p><font face="Verdana"> AcDbObjectId EntID;<br/> AcDbEntity *pEnt;<br/> if (acdbGetObjectId(EntID,eName)!=Acad::eOk<br/> || acedGetPoint(NULL,_T("\nPick up a point on side to offset:"),SidePt)!=RTNORM)<br/> return;<br/> if (acdbOpenAcDbEntity(pEnt,EntID,AcDb::kForRead)!=Acad::eOk)<br/> return;</font></p>
<p><font face="Verdana"> AcDbPolyline *pPLine=NULL;<br/> if (!pEnt->isKindOf(AcDbPolyline::desc()))<br/> {<br/> pEnt->close();<br/> return;<br/> }<br/> else<br/> pPLine=AcDbPolyline::cast(pEnt);<br/> if (pPLine==NULL)<br/> return;</font></p>
<p><font face="Verdana"> AcGePoint3d ptOnPolyLine;<br/> if (pPLine->getClosestPointTo(asPnt3d(pt),ptOnPolyLine)!=Acad::eOk)<br/> {<br/> pPLine->close();<br/> return;<br/> }</font></p>
<p><font face="Verdana"> double dParam;<br/> AcGeLineSeg3d line3d;<br/> AcGeCircArc3d CirArc3d;<br/> AcGeLine3d *pOffsetRetLine3d=NULL;<br/> AcGeCircArc3d *pOffsetRetCirArc3d=NULL;<br/> AcGePoint3d SidePtClosestPtOnCurve;<br/> pPLine->getParamAtPoint(ptOnPolyLine,dParam);<br/> AcGeVoidPointerArray CurvePointers;<br/> AcGePoint3d PreStartPt,PreEndPt,OffsetedStartPt,OffsetedEndPt;<br/> AcGePoint3d arcCenterPt;<br/> AcGeVector3d OffsetPositiveDirection,CurveDirectionAtPt,ProjectVec,SidePtDirection;<br/> if (pPLine->segType((int)dParam)==AcDbPolyline::kLine)<br/> {<br/> pPLine->getLineSegAt((int)dParam,line3d);<br/> SidePtClosestPtOnCurve=line3d.closestPointTo(asPnt3d(SidePt));<br/> CurveDirectionAtPt=line3d.direction();<br/> SidePtDirection=SidePtClosestPtOnCurve-asPnt3d(SidePt);<br/> OffsetPositiveDirection=CurveDirectionAtPt.crossProduct(AcGeVector3d::kZAxis);<br/> ProjectVec=SidePtDirection.orthoProject(OffsetPositiveDirection.perpVector());<br/> if (ProjectVec.isCodirectionalTo(OffsetPositiveDirection))<br/> line3d.getTrimmedOffset(dDistance,AcGeVector3d::kZAxis,CurvePointers);<br/> else<br/> line3d.getTrimmedOffset(-1*dDistance,AcGeVector3d::kZAxis,CurvePointers);<br/> for (int i=0;i<CurvePointers.length();i++)<br/> {<br/> pOffsetRetLine3d=(AcGeLine3d*)CurvePointers.at(i);<br/> if (pOffsetRetLine3d!=NULL)<br/> {<br/> pOffsetRetLine3d->hasStartPoint(OffsetedStartPt);<br/> pOffsetRetLine3d->hasEndPoint(OffsetedEndPt);<br/> delete pOffsetRetLine3d;<br/> AcDbLine *pLine;<br/> pLine=new AcDbLine();<br/> pLine->setStartPoint(OffsetedStartPt);<br/> pLine->setEndPoint(OffsetedEndPt);<br/> PostToMS((AcDbEntity*)pLine);<br/> pLine->close();<br/> }<br/> }<br/> }<br/> else if (pPLine->segType((int)dParam)==AcDbPolyline::kArc)<br/> {<br/> pPLine->getArcSegAt((int)dParam,CirArc3d);<br/> SidePtClosestPtOnCurve=CirArc3d.closestPointTo(asPnt3d(SidePt));<br/> CurveDirectionAtPt=(CirArc3d.center()-SidePtClosestPtOnCurve).crossProduct(<br/> CirArc3d.normal());<br/> SidePtDirection=SidePtClosestPtOnCurve-asPnt3d(SidePt);<br/> OffsetPositiveDirection=CurveDirectionAtPt.crossProduct(AcGeVector3d::kZAxis);<br/> ProjectVec=SidePtDirection.orthoProject(OffsetPositiveDirection.perpVector());<br/> if (ProjectVec.isCodirectionalTo(OffsetPositiveDirection))<br/> CirArc3d.getTrimmedOffset(dDistance,AcGeVector3d::kZAxis,CurvePointers);<br/> else<br/> CirArc3d.getTrimmedOffset(-1*dDistance,AcGeVector3d::kZAxis,CurvePointers);</font></p>
<p><font face="Verdana"> if (CurvePointers.length()==0)<br/> {<br/> acutPrintf(_T("\n输入的偏移距离太大!"));<br/> return;<br/> }<br/> <br/> for (int i=0;i<CurvePointers.length();i++)<br/> {<br/> pOffsetRetCirArc3d=(AcGeCircArc3d*)CurvePointers.at(i);<br/> if (pOffsetRetCirArc3d!=NULL)<br/> {<br/> double dRadius;<br/> dRadius=pOffsetRetCirArc3d->radius();<br/> pOffsetRetCirArc3d->hasStartPoint(OffsetedStartPt);<br/> pOffsetRetCirArc3d->hasEndPoint(OffsetedEndPt);<br/> arcCenterPt=pOffsetRetCirArc3d->center();<br/> AcGeVector3d normalVec=pOffsetRetCirArc3d->normal();<br/> delete pOffsetRetCirArc3d;<br/> AcDbArc *pArc;<br/> pArc=new AcDbArc();<br/> pArc->setCenter(arcCenterPt);<br/> double dStartAngle=(OffsetedStartPt-arcCenterPt).angleOnPlane(<br/> AcGePlane::kXYPlane);<br/> double dEndAngle=(OffsetedEndPt-arcCenterPt).angleOnPlane(<br/> AcGePlane::kXYPlane);<br/> if (normalVec.isCodirectionalTo(AcGeVector3d::kZAxis))<br/> {<br/> pArc->setStartAngle(dStartAngle);<br/> pArc->setEndAngle(dEndAngle);<br/> }<br/> else<br/> {<br/> pArc->setStartAngle(dEndAngle);<br/> pArc->setEndAngle(dStartAngle);<br/> }<br/> <br/> pArc->setRadius(dRadius);<br/> PostToMS((AcDbEntity*)pArc);<br/> pArc->close();<br/> }<br/> }<br/> }<br/> pPLine->close();<br/> }</font></p>
<p> </p>
<p><font face="Verdana">从多段线上直接偏移一条线段或是圆弧,就是偏移串接好多段线上的某个图元.</font></p>
<p><font face="Verdana">程序比较复杂,不知道有没有更好的方法!</font></p>
<p>难点是根据点选位置确定偏移方向!</p>
<p> </p> 希望得到简便的方法!
页:
[1]