rongyifei 发表于 2010-6-24 23:01:00

从多段线上直接偏移一条线段或是圆弧

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

gbhsu 发表于 2011-8-13 18:45:48

希望得到简便的方法!
页: [1]
查看完整版本: 从多段线上直接偏移一条线段或是圆弧