C#打断曲线方法(程序代码)
一直就不喜欢在程序里用AutoCAD命令,在.Net里还有AutoCAD命令与Editor及事务提交之间纠缠不清的关系,特别是三者的次序我实在搞不清楚,托管类里没有打断曲线的方法,AutoCAD的Break命令用起来不顺手,而且还担心不可靠.只好自己写一个打断曲线的方法,各位或许会用得上.花了一个很晚的晚上和一个很早的早上.可以打断直线,圆弧,圆,椭圆,椭圆弧,轻型多义线(封闭和开口的),Xline及射线.<BR> /// <summary><BR> /// curveid Object must have existed in Database<BR> /// Can break Line | Arc | Circle | Ellipse | Polyline | Xline | Ray<BR> /// </summary><BR> /// <param name="p1">第一个打断点 </param><BR> /// <param name="p2">第二个打断点</param><BR> /// <param name="curveid">要打断曲线的ObjectId</param><BR> /// <returns></returns><BR> public static bool BreakCurve(Point3d p1, Point3d p2, ObjectId curveid)<BR> {<BR> //pcm.WriteLine("BreakCurve start", 0);<BR> try<BR> {<BR> Database cdb = curveid.Database;<BR> using (Transaction ctrans = cdb.TransactionManager.StartTransaction())<BR> {<BR> Curve cur = (Curve)ctrans.GetObject(curveid, OpenMode.ForWrite);<BR> Point3d p11 = cur.GetClosestPointTo(p1, false);<BR> Point3d p21 = cur.GetClosestPointTo(p2, false);<BR> #region Break Line<BR> if (cur is Line)<BR> {<BR> //pcm.WriteLine("Break Line start ", 1);<BR> Line l1 = (Line)cur;<BR> Line l2 = (Line)l1.Clone();<BR> if (l1.GetDistAtPoint(p11) < l1.GetDistAtPoint(p21))<BR> {<BR> l2.StartPoint = p21;<BR> l1.EndPoint = p11;<BR> }<BR> else<BR> {<BR> l2.StartPoint = p11;<BR> l1.EndPoint = p21;<BR> }<BR> DrawEntity(l2);<BR> }<BR> #endregion Break Line<BR> #region Break Arc<BR> if (cur is Arc)<BR> {//pcm.WriteLine("Break Arc start ", 1);<BR> Arc arc1 = (Arc)cur;<BR> Arc arc2 = (Arc)arc1.Clone();<BR> Vector3d v11 = arc1.StartPoint.GetVectorTo(arc1.Center);<BR> Vector3d v12 = arc1.EndPoint.GetVectorTo(arc1.Center);<BR> Vector3d v21 = p11.GetVectorTo(arc1.Center);<BR> Vector3d v22 = p21.GetVectorTo(arc1.Center);<BR> if (v11.GetAngleTo(v21, Vector3d.ZAxis) < v11.GetAngleTo(v22, Vector3d.ZAxis))<BR> {<BR> arc2.EndAngle = arc1.StartAngle + v11.GetAngleTo(v21, Vector3d.ZAxis);<BR> arc1.StartAngle += v11.GetAngleTo(v22, Vector3d.ZAxis);<BR> }<BR> else<BR> {<BR> arc2.EndAngle = arc1.StartAngle + v11.GetAngleTo(v22, Vector3d.ZAxis);<BR> arc1.StartAngle += v11.GetAngleTo(v21, Vector3d.ZAxis);<BR> }<BR> DrawEntity(arc2);<BR> }<BR> #endregion Break Arc<BR> #region Break Circle<BR> if (cur is Circle)<BR> {//pcm.WriteLine("Break Circle start ", 1);<BR> Circle c1 = (Circle)cur;<BR> Vector3d v1 = p11.GetVectorTo(c1.Center);<BR> Vector3d v2 = p21.GetVectorTo(c1.Center);<BR> Arc arc1 = new Arc();<BR> arc1.Center = c1.Center;<BR> arc1.SetPropertiesFrom(c1);<BR> arc1.Radius = c1.Radius;<BR> arc1.StartAngle = Vector3d.XAxis.GetAngleTo(v2, Vector3d.ZAxis);<BR> arc1.EndAngle = arc1.StartAngle + v2.GetAngleTo(v1, Vector3d.ZAxis);<BR> c1.Erase();<BR> DrawEntity(arc1);<BR> }<BR> #endregion Break Circle<BR> #region Break Ellipse<BR> if (cur is Ellipse)<BR> {<BR> //pcm.WriteLine("Break Ellipse start ", 1);<BR> Ellipse ell1 = (Ellipse)cur;<BR> if (ell1.Closed)<BR> {<BR> // pcm.WriteLine("Ellipse closed ", 1);<BR> Vector3d v1 = p11.GetVectorTo(ell1.Center);<BR> Vector3d v2 = p21.GetVectorTo(ell1.Center);<BR> ell1.StartAngle = ell1.MajorAxis.GetAngleTo(v2, Vector3d.ZAxis);<BR> ell1.EndAngle = ell1.StartAngle + v2.GetAngleTo(v1, Vector3d.ZAxis);<BR> }<BR> else<BR> {<BR> //pcm.WriteLine("Ellipse opened ", 1);<BR> Ellipse ell2 = (Ellipse)ell1.Clone();<BR> Vector3d v11 = ell1.StartPoint.GetVectorTo(ell1.Center);<BR> Vector3d v12 = ell1.EndPoint.GetVectorTo(ell1.Center);<BR> Vector3d v21 = p11.GetVectorTo(ell1.Center);<BR> Vector3d v22 = p21.GetVectorTo(ell1.Center);<BR> if (v11.GetAngleTo(v21, Vector3d.ZAxis) < v11.GetAngleTo(v22, Vector3d.ZAxis))<BR> {<BR> ell2.EndAngle = ell1.StartAngle + v11.GetAngleTo(v21, Vector3d.ZAxis);<BR> ell1.StartAngle += v11.GetAngleTo(v22, Vector3d.ZAxis);<BR> }<BR> else<BR> {<BR> ell2.EndAngle = ell1.StartAngle + v11.GetAngleTo(v22, Vector3d.ZAxis);<BR> ell1.StartAngle += v11.GetAngleTo(v21, Vector3d.ZAxis);<BR> }<BR> DrawEntity(ell2);<BR> }<BR> }<BR> #endregion Break Ellipse<BR> #region Break Polyline<BR> if (cur is Polyline)<BR> {<BR> //pcm.WriteLine("Break PolyLine start ", 1);<BR> Polyline pl1 = (Polyline)cur;<BR> double param11 = pl1.GetParameterAtPoint(p11);<BR> double param12 = pl1.GetParameterAtPoint(p21);<BR> double param21 = Math.Min(param11, param12);<BR> double param22 = Math.Max(param11, param12);<BR> if (pl1.Closed)<BR> {<BR> #region Polyline closed<BR> pcm.WriteLine("PolyLine closed ", 1);<BR> Polyline pl2 = new Polyline();<BR> pl2.SetPropertiesFrom(pl1);<BR> double len11 = pl1.GetDistanceAtParameter(param21) + pl1.GetDistanceAtParameter(pl1.EndParam) - pl1.GetDistanceAtParameter(param22);<BR> double len12 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param21);<BR> int param31 = (int)Math.Floor(param21);<BR> int param32 = (int)Math.Floor(param22) + 1;<BR> Point3d p31;<BR> if (len11 > len12)<BR> {<BR> if ((double)param32 != param22)<BR> {<BR> double bul12 = pl1.GetBulgeAt(param32 - 1);<BR> double bul22 = 0;<BR> if (bul12 != 0.0)<BR> {<BR> double len22 = pl1.GetDistanceAtParameter(param32) - pl1.GetDistanceAtParameter(param32 - 1);<BR> double len32 = pl1.GetDistanceAtParameter(param32) - pl1.GetDistanceAtParameter(param22);<BR> bul22 = Math.Tan(len32 * Math.Atan(bul12) / len22);<BR> }<BR> p31 = pl1.GetPointAtParameter(param22);<BR> pl2.AddVertexAt(0, new Point2d(p31.X, p31.Y), bul22, 0, 0);<BR> }<BR> for (int i = param32; i < pl1.EndParam; i++)<BR> {<BR> p31 = pl1.GetPointAtParameter(i);<BR> pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), pl1.GetBulgeAt(i), 0, 0);<BR> }<BR> for (int i = 0; i <= param31; i++)<BR> {<BR> p31 = pl1.GetPointAtParameter(i);<BR> pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), pl1.GetBulgeAt(i), 0, 0);<BR> }<BR> if ((double)param31 != param21)<BR> {<BR> p31 = pl1.GetPointAtParameter(param21);<BR> pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), 0, 0, 0);<BR> double bul11 = pl1.GetBulgeAt(param31);<BR> if (bul11 != 0.0)<BR> {<BR> double len21 = pl1.GetDistanceAtParameter(param31 + 1) - pl1.GetDistanceAtParameter(param31);<BR> double len31 = pl1.GetDistanceAtParameter(param21) - pl1.GetDistanceAtParameter(param31);<BR> if (pl2.NumberOfVertices == 2)<BR> len31 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param21);<BR> double bul21 = Math.Tan(len31 * Math.Atan(bul11) / len21);<BR> pl2.SetBulgeAt(pl2.NumberOfVertices - 2, bul21);<BR> }<BR> }<BR> }<BR> else<BR> {<BR> if ((double)param31 != param21)<BR> {<BR> double bul11 = pl1.GetBulgeAt(param31);<BR> double bul21 = 0;<BR> if (bul11 != 0.0)<BR> {<BR> double len21 = pl1.GetDistanceAtParameter(param31 + 1) - pl1.GetDistanceAtParameter(param31);<BR> double len31 = pl1.GetDistanceAtParameter(param31 + 1) - pl1.GetDistanceAtParameter(param21);<BR> bul21 = Math.Tan(len31 * Math.Atan(bul11) / len21);<BR> }<BR> p31 = pl1.GetPointAtParameter(param21);<BR> pl2.AddVertexAt(0, new Point2d(p31.X, p31.Y), bul21, 0, 0);<BR> }<BR> for (int i = param31 + 1; i <= param32 - 1; i++)<BR> {<BR> p31 = pl1.GetPointAtParameter(i);<BR> pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), pl1.GetBulgeAt(i), 0, 0);<BR> }<BR> if ((double)param32 != param22)<BR> {<BR> p31 = pl1.GetPointAtParameter(param22);<BR> pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), 0, 0, 0);<BR> double bul12 = pl1.GetBulgeAt(param32 - 1);<BR> if (bul12 != 0.0)<BR> {<BR> double len22 = pl1.GetDistanceAtParameter(param32) - pl1.GetDistanceAtParameter(param32 - 1);<BR> double len32 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param32 - 1);<BR> if (pl2.NumberOfVertices == 2)<BR> len32 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param21);<BR> double bul22 = Math.Tan(len32 * Math.Atan(bul12) / len22);<BR> pl2.SetBulgeAt(pl2.NumberOfVertices - 2, bul22);<BR> }<BR> }<BR> }<BR> #endregion Polyline closed<BR> DrawEntity(pl2);<BR> }<BR> else<BR> {<BR> #region Polyline opened<BR> //pcm.WriteLine("PolyLine opend ", 1);<BR> Polyline pl2 = new Polyline();<BR> pl2.SetPropertiesFrom(pl1);<BR> double len11 = pl1.GetDistanceAtParameter(param21) + pl1.GetDistanceAtParameter(pl1.EndParam) - pl1.GetDistanceAtParameter(param22);<BR> double len12 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param21);<BR> int param31 = (int)Math.Floor(param21);<BR> int param32 = (int)Math.Floor(param22) + 1;<BR> Point3d p31;<BR> for (int i = 0; i < param21; i++)<BR> {<BR> p31 = pl1.GetPointAtParameter(i);<BR> pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), pl1.GetBulgeAt(i), 0, 0);<BR> }<BR> if ((double)param31 != param21)<BR> {<BR> p31 = pl1.GetPointAtParameter(param21);<BR> pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), 0, 0, 0);<BR> double bul11 = pl1.GetBulgeAt(param31);<BR> if (bul11 != 0.0)<BR> {<BR> double len21 = pl1.GetDistanceAtParameter(param31 + 1) - pl1.GetDistanceAtParameter(param31);<BR> double len31 = pl1.GetDistanceAtParameter(param21) - pl1.GetDistanceAtParameter(param31);<BR> if (pl2.NumberOfVertices == 2)<BR> len31 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param21);<BR> double bul21 = Math.Tan(len31 * Math.Atan(bul11) / len21);<BR> pl2.SetBulgeAt(pl2.NumberOfVertices - 2, bul21);<BR> }<BR> }<BR> Polyline pl3 = new Polyline();<BR> pl3.SetPropertiesFrom(pl1);<BR> if ((double)param32 != param22)<BR> {<BR> double bul12 = pl1.GetBulgeAt(param32 - 1);<BR> double bul22 = 0;<BR> if (bul12 != 0.0)<BR> {<BR> double len22 = pl1.GetDistanceAtParameter(param32) - pl1.GetDistanceAtParameter(param32 - 1);<BR> double len32 = pl1.GetDistanceAtParameter(param32) - pl1.GetDistanceAtParameter(param22);<BR> bul22 = Math.Tan(len32 * Math.Atan(bul12) / len22);<BR> }<BR> p31 = pl1.GetPointAtParameter(param22);<BR> pl3.AddVertexAt(0, new Point2d(p31.X, p31.Y), bul22, 0, 0);<BR> }<BR> for (int i = param32; i <= pl1.EndParam; i++)<BR> {<BR> p31 = pl1.GetPointAtParameter(i);<BR> pl3.AddVertexAt(pl3.NumberOfVertices, new Point2d(p31.X, p31.Y), pl1.GetBulgeAt(i), 0, 0);<BR> }<BR> DrawEntity(pl2);<BR> DrawEntity(pl3);<BR> //pcm.WriteLine("Break Polyline end ", 1);<BR> #endregion Polyline opened<BR> }<BR> pl1.Erase();<BR> }<BR> #endregion Break Polyline<BR> #region Break XLine<BR> if (cur is Xline)<BR> {<BR> //pcm.WriteLine("Break Xline start ", 1);<BR> Xline xl1 = (Xline)cur;<BR> Vector3d v1 = p11.GetVectorTo(p21);<BR> Vector3d v2 = p21.GetVectorTo(p11);<BR> Ray ray1 = new Ray();<BR> ray1.SetPropertiesFrom(xl1);<BR> ray1.BasePoint = p11;<BR> ray1.UnitDir = v1;<BR> Ray ray2 = new Ray();<BR> ray2.SetPropertiesFrom(xl1);<BR> ray2.BasePoint = p21;<BR> ray2.UnitDir = v2;<BR> DrawEntity(ray1);<BR> DrawEntity(ray2);<BR> xl1.Erase();<BR> }<BR> #endregion Break XLine<BR> #region Break Ray<BR> if (cur is Ray)<BR> {<BR> //pcm.WriteLine("Break Ray start ", 1);<BR> Ray ray1 = (Ray)cur;<BR> Line l1;<BR> if (ray1.BasePoint.DistanceTo(p11) > ray1.BasePoint.DistanceTo(p21))<BR> {<BR> l1 = new Line(ray1.BasePoint, p21);<BR> l1.SetPropertiesFrom(ray1);<BR> ray1.BasePoint = p11;<BR> }<BR> else<BR> {<BR> l1 = new Line(ray1.BasePoint, p11);<BR> l1.SetPropertiesFrom(ray1);<BR> ray1.BasePoint = p21;<BR> }<BR> DrawEntity(l1);<BR> }<BR> #endregion Break Ray<BR> ctrans.Commit();<BR> return true;<BR> }<BR> }<BR> catch (System.Exception ex)<BR> { pcm.WriteLine(ex); return false; }<BR> } <P>问:</P><P>编译时为何提示无DrawEntity方法?或引用何命名空间?</P> <P> public static ObjectId DrawEntity(Entity ent)<BR> { //Debug.WriteLine("Draw Entity");<BR> try<BR> {<BR> Database db=HostApplicationServices.WorkingDatabase;<BR> Transaction trans = db.TransactionManager.StartTransaction(); <BR> BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForWrite);<BR> BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt, OpenMode.ForWrite);<BR> btr.AppendEntity(ent);<BR> trans.AddNewlyCreatedDBObject(ent, true);<BR> trans.Commit(); <BR> trans.Dispose(); <BR> return ent.ObjectId;<BR> }<BR> catch (System.Exception ex)<BR> {<BR> // smc.WriteLine(ex);<BR> return ObjectId.Null;<BR> }<BR> }</P>
<P>不好意思,DrawEntity是我定义的一个方法,作用是生成实体.</P>
<P>其实不使用我的方法也行,只要在DrawEntity这个地方把实体提交给数据库就行</P> <p>你好,请教一下如何取得多段线中圆弧的中点?回油箱:<a href="mailto:muli_zxm@163.com">muli_zxm@163.com</a></p><p>谢谢哦</p> <p>不好意思!好久没有来到这里!前不久才发现有个getSplitCurves函数,打断曲线用这个函数才是正途,</p><p>下面是C++的代码,C#里的curve 同样有GetSplitCurves方法,代码应该也差不多</p><p>回楼上:可以通过GetBulgeAt(param)的返回值判断是否为圆弧(不等于0就是),然后用GetPointAtParameter(param+0.5)即可得到圆弧中点</p><p> bool nsp::breakCurve(AcDbCurve* curve, AcGePoint3d p1, AcGePoint3d p2)<br/> {<br/> AcGePoint3d p11;<br/> curve->getClosestPointTo(p1,p11);<br/> double param1;<br/> curve->getParamAtPoint(p11,param1);<br/> AcGePoint3d p21;<br/> curve->getClosestPointTo(p2,p21);<br/> double param2;<br/> curve->getParamAtPoint(p21,param2);<br/> AcGeDoubleArray params;<br/> if (param1<param2)<br/> {<br/> params.append(param1);<br/> params.append(param2);<br/> }<br/> else<br/> {<br/> params.append(param2);<br/> params.append(param1);<br/> }<br/> AcDbVoidPtrArray curveSegments;<br/> curve->getSplitCurves(params, curveSegments);<br/> AcDbEntity* ent =NULL;<br/> if (curveSegments.length()==2)<br/> {<br/> ent=(AcDbEntity*)curveSegments;<br/> nsp::drawEntity(ent);<br/> ent->close();<br/> }<br/> else if (curveSegments.length()==3)<br/> {<br/> ent=(AcDbEntity*)curveSegments;<br/> nsp::drawEntity(ent);<br/> ent->close();<br/> ent=(AcDbEntity*)curveSegments;<br/> nsp::drawEntity(ent);<br/> ent->close();<br/> }<br/> curve->erase();<br/>return true ;<br/> }</p> 这是用什么方式开发的,ActiveX? <p>用C#怎样调用Addhatch()函数</p><p></p> using app = Autodesk.AutoCAD.ApplicationServices.Application;<br/>AcadApplication CurApp = (AcadApplication)app.AcadApplication;<br/>AcadDocument CurDoc = CurApp.ActiveDocument;<br/>AcadModelSpace CurSpace = CurDoc.ModelSpace;<br/>CurSpace.AddHatch(int PatternType, string PatternName, bool Associativity, object HatchObjectType)<br/>AcadBlocks Blocks = CurDoc.Blocks;<br/>AcadBlock Block = Blocks.Item(0);<br/>Block .AddHatch(int PatternType, string PatternName, bool Associativity, object HatchObjectType)
页:
[1]