明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 7393|回复: 7

[几何] C#打断曲线方法(程序代码)

[复制链接]
发表于 2006-8-31 22:26:00 | 显示全部楼层 |阅读模式
一直就不喜欢在程序里用AutoCAD命令,在.Net里还有AutoCAD命令与Editor及事务提交之间纠缠不清的关系,特别是三者的次序我实在搞不清楚,托管类里没有打断曲线的方法,AutoCAD的Break命令用起来不顺手,而且还担心不可靠.只好自己写一个打断曲线的方法,各位或许会用得上.花了一个很晚的晚上和一个很早的早上.可以打断直线,圆弧,圆,椭圆,椭圆弧,轻型多义线(封闭和开口的),Xline及射线.
        /// <summary>
        /// curveid Object must have existed in Database
        /// Can break Line | Arc | Circle | Ellipse | Polyline | Xline | Ray
        /// </summary>
        /// <param name="p1">第一个打断点 </param>
        /// <param name="p2">第二个打断点</param>
        /// <param name="curveid">要打断曲线的ObjectId</param>
        /// <returns></returns>
        public static bool BreakCurve(Point3d p1, Point3d p2, ObjectId curveid)
        {
            //pcm.WriteLine("BreakCurve start", 0);
            try
            {
                Database cdb = curveid.Database;
                using (Transaction ctrans = cdb.TransactionManager.StartTransaction())
                {
                    Curve cur = (Curve)ctrans.GetObject(curveid, OpenMode.ForWrite);
                    Point3d p11 = cur.GetClosestPointTo(p1, false);
                    Point3d p21 = cur.GetClosestPointTo(p2, false);
                    #region Break Line
                    if (cur is Line)
                    {
                        //pcm.WriteLine("Break Line start ", 1);
                        Line l1 = (Line)cur;
                        Line l2 = (Line)l1.Clone();
                        if (l1.GetDistAtPoint(p11) < l1.GetDistAtPoint(p21))
                        {
                            l2.StartPoint = p21;
                            l1.EndPoint = p11;
                        }
                        else
                        {
                            l2.StartPoint = p11;
                            l1.EndPoint = p21;
                        }
                        DrawEntity(l2);
                    }
                    #endregion Break Line
                    #region Break Arc
                    if (cur is Arc)
                    {//pcm.WriteLine("Break Arc start ", 1);
                        Arc arc1 = (Arc)cur;
                        Arc arc2 = (Arc)arc1.Clone();
                        Vector3d v11 = arc1.StartPoint.GetVectorTo(arc1.Center);
                        Vector3d v12 = arc1.EndPoint.GetVectorTo(arc1.Center);
                        Vector3d v21 = p11.GetVectorTo(arc1.Center);
                        Vector3d v22 = p21.GetVectorTo(arc1.Center);
                        if (v11.GetAngleTo(v21, Vector3d.ZAxis) < v11.GetAngleTo(v22, Vector3d.ZAxis))
                        {
                            arc2.EndAngle = arc1.StartAngle + v11.GetAngleTo(v21, Vector3d.ZAxis);
                            arc1.StartAngle += v11.GetAngleTo(v22, Vector3d.ZAxis);
                        }
                        else
                        {
                            arc2.EndAngle = arc1.StartAngle + v11.GetAngleTo(v22, Vector3d.ZAxis);
                            arc1.StartAngle += v11.GetAngleTo(v21, Vector3d.ZAxis);
                        }
                        DrawEntity(arc2);
                    }
                    #endregion Break Arc
                    #region Break Circle
                    if (cur is Circle)
                    {//pcm.WriteLine("Break Circle start ", 1);
                        Circle c1 = (Circle)cur;
                        Vector3d v1 = p11.GetVectorTo(c1.Center);
                        Vector3d v2 = p21.GetVectorTo(c1.Center);
                        Arc arc1 = new Arc();
                        arc1.Center = c1.Center;
                        arc1.SetPropertiesFrom(c1);
                        arc1.Radius = c1.Radius;
                        arc1.StartAngle = Vector3d.XAxis.GetAngleTo(v2, Vector3d.ZAxis);
                        arc1.EndAngle = arc1.StartAngle + v2.GetAngleTo(v1, Vector3d.ZAxis);
                        c1.Erase();
                        DrawEntity(arc1);
                    }
                    #endregion Break Circle
                    #region Break Ellipse
                    if (cur is Ellipse)
                    {
                        //pcm.WriteLine("Break Ellipse start ", 1);
                        Ellipse ell1 = (Ellipse)cur;
                        if (ell1.Closed)
                        {
                            // pcm.WriteLine("Ellipse closed ", 1);
                            Vector3d v1 = p11.GetVectorTo(ell1.Center);
                            Vector3d v2 = p21.GetVectorTo(ell1.Center);
                            ell1.StartAngle = ell1.MajorAxis.GetAngleTo(v2, Vector3d.ZAxis);
                            ell1.EndAngle = ell1.StartAngle + v2.GetAngleTo(v1, Vector3d.ZAxis);
                        }
                        else
                        {
                            //pcm.WriteLine("Ellipse opened ", 1);
                            Ellipse ell2 = (Ellipse)ell1.Clone();
                            Vector3d v11 = ell1.StartPoint.GetVectorTo(ell1.Center);
                            Vector3d v12 = ell1.EndPoint.GetVectorTo(ell1.Center);
                            Vector3d v21 = p11.GetVectorTo(ell1.Center);
                            Vector3d v22 = p21.GetVectorTo(ell1.Center);
                            if (v11.GetAngleTo(v21, Vector3d.ZAxis) < v11.GetAngleTo(v22, Vector3d.ZAxis))
                            {
                                ell2.EndAngle = ell1.StartAngle + v11.GetAngleTo(v21, Vector3d.ZAxis);
                                ell1.StartAngle += v11.GetAngleTo(v22, Vector3d.ZAxis);
                            }
                            else
                            {
                                ell2.EndAngle = ell1.StartAngle + v11.GetAngleTo(v22, Vector3d.ZAxis);
                                ell1.StartAngle += v11.GetAngleTo(v21, Vector3d.ZAxis);
                            }
                            DrawEntity(ell2);
                        }
                    }
                    #endregion Break Ellipse
                    #region Break Polyline
                    if (cur is Polyline)
                    {
                        //pcm.WriteLine("Break PolyLine start ", 1);
                        Polyline pl1 = (Polyline)cur;
                        double param11 = pl1.GetParameterAtPoint(p11);
                        double param12 = pl1.GetParameterAtPoint(p21);
                        double param21 = Math.Min(param11, param12);
                        double param22 = Math.Max(param11, param12);
                        if (pl1.Closed)
                        {
                            #region Polyline closed
                           pcm.WriteLine("PolyLine closed ", 1);
                            Polyline pl2 = new Polyline();
                            pl2.SetPropertiesFrom(pl1);
                            double len11 = pl1.GetDistanceAtParameter(param21) + pl1.GetDistanceAtParameter(pl1.EndParam) - pl1.GetDistanceAtParameter(param22);
                            double len12 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param21);
                            int param31 = (int)Math.Floor(param21);
                            int param32 = (int)Math.Floor(param22) + 1;
                            Point3d p31;
                            if (len11 > len12)
                            {
                                if ((double)param32 != param22)
                                {
                                    double bul12 = pl1.GetBulgeAt(param32 - 1);
                                    double bul22 = 0;
                                    if (bul12 != 0.0)
                                    {
                                        double len22 = pl1.GetDistanceAtParameter(param32) - pl1.GetDistanceAtParameter(param32 - 1);
                                        double len32 = pl1.GetDistanceAtParameter(param32) - pl1.GetDistanceAtParameter(param22);
                                        bul22 = Math.Tan(len32 * Math.Atan(bul12) / len22);
                                    }
                                    p31 = pl1.GetPointAtParameter(param22);
                                    pl2.AddVertexAt(0, new Point2d(p31.X, p31.Y), bul22, 0, 0);
                                }
                                for (int i = param32; i < pl1.EndParam; i++)
                                {
                                    p31 = pl1.GetPointAtParameter(i);
                                    pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), pl1.GetBulgeAt(i), 0, 0);
                                }
                                for (int i = 0; i <= param31; i++)
                                {
                                    p31 = pl1.GetPointAtParameter(i);
                                    pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), pl1.GetBulgeAt(i), 0, 0);
                                }
                                if ((double)param31 != param21)
                                {
                                    p31 = pl1.GetPointAtParameter(param21);
                                    pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), 0, 0, 0);
                                    double bul11 = pl1.GetBulgeAt(param31);
                                    if (bul11 != 0.0)
                                    {
                                        double len21 = pl1.GetDistanceAtParameter(param31 + 1) - pl1.GetDistanceAtParameter(param31);
                                        double len31 = pl1.GetDistanceAtParameter(param21) - pl1.GetDistanceAtParameter(param31);
                                        if (pl2.NumberOfVertices == 2)
                                            len31 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param21);
                                        double bul21 = Math.Tan(len31 * Math.Atan(bul11) / len21);
                                        pl2.SetBulgeAt(pl2.NumberOfVertices - 2, bul21);
                                    }
                                }
                            }
                            else
                            {
                                if ((double)param31 != param21)
                                {
                                    double bul11 = pl1.GetBulgeAt(param31);
                                    double bul21 = 0;
                                    if (bul11 != 0.0)
                                    {
                                        double len21 = pl1.GetDistanceAtParameter(param31 + 1) - pl1.GetDistanceAtParameter(param31);
                                        double len31 = pl1.GetDistanceAtParameter(param31 + 1) - pl1.GetDistanceAtParameter(param21);
                                        bul21 = Math.Tan(len31 * Math.Atan(bul11) / len21);
                                    }
                                    p31 = pl1.GetPointAtParameter(param21);
                                    pl2.AddVertexAt(0, new Point2d(p31.X, p31.Y), bul21, 0, 0);
                                }
                                for (int i = param31 + 1; i <= param32 - 1; i++)
                                {
                                    p31 = pl1.GetPointAtParameter(i);
                                    pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), pl1.GetBulgeAt(i), 0, 0);
                                }
                                if ((double)param32 != param22)
                                {
                                    p31 = pl1.GetPointAtParameter(param22);
                                    pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), 0, 0, 0);
                                    double bul12 = pl1.GetBulgeAt(param32 - 1);
                                    if (bul12 != 0.0)
                                    {
                                        double len22 = pl1.GetDistanceAtParameter(param32) - pl1.GetDistanceAtParameter(param32 - 1);
                                        double len32 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param32 - 1);
                                        if (pl2.NumberOfVertices == 2)
                                            len32 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param21);
                                        double bul22 = Math.Tan(len32 * Math.Atan(bul12) / len22);
                                        pl2.SetBulgeAt(pl2.NumberOfVertices - 2, bul22);
                                    }
                                }
                            }
                            #endregion Polyline closed
                            DrawEntity(pl2);
                        }
                        else
                        {
                            #region Polyline opened
                            //pcm.WriteLine("PolyLine opend ", 1);
                            Polyline pl2 = new Polyline();
                            pl2.SetPropertiesFrom(pl1);
                            double len11 = pl1.GetDistanceAtParameter(param21) + pl1.GetDistanceAtParameter(pl1.EndParam) - pl1.GetDistanceAtParameter(param22);
                            double len12 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param21);
                            int param31 = (int)Math.Floor(param21);
                            int param32 = (int)Math.Floor(param22) + 1;
                            Point3d p31;
                            for (int i = 0; i < param21; i++)
                            {
                                p31 = pl1.GetPointAtParameter(i);
                                pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), pl1.GetBulgeAt(i), 0, 0);
                            }
                            if ((double)param31 != param21)
                            {
                                p31 = pl1.GetPointAtParameter(param21);
                                pl2.AddVertexAt(pl2.NumberOfVertices, new Point2d(p31.X, p31.Y), 0, 0, 0);
                                double bul11 = pl1.GetBulgeAt(param31);
                                if (bul11 != 0.0)
                                {
                                    double len21 = pl1.GetDistanceAtParameter(param31 + 1) - pl1.GetDistanceAtParameter(param31);
                                    double len31 = pl1.GetDistanceAtParameter(param21) - pl1.GetDistanceAtParameter(param31);
                                    if (pl2.NumberOfVertices == 2)
                                        len31 = pl1.GetDistanceAtParameter(param22) - pl1.GetDistanceAtParameter(param21);
                                    double bul21 = Math.Tan(len31 * Math.Atan(bul11) / len21);
                                    pl2.SetBulgeAt(pl2.NumberOfVertices - 2, bul21);
                                }
                            }
                            Polyline pl3 = new Polyline();
                            pl3.SetPropertiesFrom(pl1);
                            if ((double)param32 != param22)
                            {
                                double bul12 = pl1.GetBulgeAt(param32 - 1);
                                double bul22 = 0;
                                if (bul12 != 0.0)
                                {
                                    double len22 = pl1.GetDistanceAtParameter(param32) - pl1.GetDistanceAtParameter(param32 - 1);
                                    double len32 = pl1.GetDistanceAtParameter(param32) - pl1.GetDistanceAtParameter(param22);
                                    bul22 = Math.Tan(len32 * Math.Atan(bul12) / len22);
                                }
                                p31 = pl1.GetPointAtParameter(param22);
                                pl3.AddVertexAt(0, new Point2d(p31.X, p31.Y), bul22, 0, 0);
                            }
                            for (int i = param32; i <= pl1.EndParam; i++)
                            {
                                p31 = pl1.GetPointAtParameter(i);
                                pl3.AddVertexAt(pl3.NumberOfVertices, new Point2d(p31.X, p31.Y), pl1.GetBulgeAt(i), 0, 0);
                            }
                            DrawEntity(pl2);
                            DrawEntity(pl3);
                            //pcm.WriteLine("Break Polyline end ", 1);
                            #endregion Polyline opened
                        }
                        pl1.Erase();
                    }
                    #endregion Break Polyline
                    #region Break XLine
                    if (cur is Xline)
                    {
                        //pcm.WriteLine("Break Xline start ", 1);
                        Xline xl1 = (Xline)cur;
                        Vector3d v1 = p11.GetVectorTo(p21);
                        Vector3d v2 = p21.GetVectorTo(p11);
                        Ray ray1 = new Ray();
                        ray1.SetPropertiesFrom(xl1);
                        ray1.BasePoint = p11;
                        ray1.UnitDir = v1;
                        Ray ray2 = new Ray();
                        ray2.SetPropertiesFrom(xl1);
                        ray2.BasePoint = p21;
                        ray2.UnitDir = v2;
                        DrawEntity(ray1);
                        DrawEntity(ray2);
                        xl1.Erase();
                    }
                    #endregion Break XLine
                    #region Break Ray
                    if (cur is Ray)
                    {
                        //pcm.WriteLine("Break Ray start ", 1);
                        Ray ray1 = (Ray)cur;
                        Line l1;
                        if (ray1.BasePoint.DistanceTo(p11) > ray1.BasePoint.DistanceTo(p21))
                        {
                            l1 = new Line(ray1.BasePoint, p21);
                            l1.SetPropertiesFrom(ray1);
                            ray1.BasePoint = p11;
                        }
                        else
                        {
                            l1 = new Line(ray1.BasePoint, p11);
                            l1.SetPropertiesFrom(ray1);
                            ray1.BasePoint = p21;
                        }
                        DrawEntity(l1);
                    }
                    #endregion Break Ray
                    ctrans.Commit();
                    return true;
                }
            }
            catch (System.Exception ex)
            { pcm.WriteLine(ex); return false; }
        }
发表于 2006-9-9 10:02:00 | 显示全部楼层

问:

编译时为何提示无DrawEntity方法?或引用何命名空间?

 楼主| 发表于 2006-9-12 14:31:00 | 显示全部楼层

        public static ObjectId DrawEntity(Entity ent)
        { //Debug.WriteLine("Draw Entity");
            try
            {
        Database db=HostApplicationServices.WorkingDatabase;
        Transaction trans = db.TransactionManager.StartTransaction();       
        BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForWrite);
        BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                btr.AppendEntity(ent);
                trans.AddNewlyCreatedDBObject(ent, true);
                trans.Commit();
  trans.Dispose();
                return ent.ObjectId;
            }
            catch (System.Exception ex)
            {
                // smc.WriteLine(ex);
                return ObjectId.Null;
            }
        }

不好意思,DrawEntity是我定义的一个方法,作用是生成实体.

其实不使用我的方法也行,只要在DrawEntity这个地方把实体提交给数据库就行

发表于 2007-4-29 16:56:00 | 显示全部楼层

你好,请教一下如何取得多段线中圆弧的中点?回油箱:muli_zxm@163.com

谢谢哦

 楼主| 发表于 2007-5-8 13:54:00 | 显示全部楼层

不好意思!好久没有来到这里!前不久才发现有个getSplitCurves函数,打断曲线用这个函数才是正途,

下面是C++的代码,C#里的curve 同样有GetSplitCurves方法,代码应该也差不多

回楼上:可以通过GetBulgeAt(param)的返回值判断是否为圆弧(不等于0就是),然后用GetPointAtParameter(param+0.5)即可得到圆弧中点

 bool nsp::breakCurve(AcDbCurve* curve, AcGePoint3d p1, AcGePoint3d p2)
 {
  AcGePoint3d p11;
  curve->getClosestPointTo(p1,p11);
  double param1;
  curve->getParamAtPoint(p11,param1);
 AcGePoint3d p21;
 curve->getClosestPointTo(p2,p21);
  double param2;
  curve->getParamAtPoint(p21,param2);
 AcGeDoubleArray params;
 if (param1<param2)
 {
 params.append(param1);
 params.append(param2);
 }
 else
 {
 params.append(param2);
 params.append(param1);
 }
 AcDbVoidPtrArray curveSegments;
  curve->getSplitCurves(params, curveSegments);
  AcDbEntity* ent =NULL;
  if (curveSegments.length()==2)
  {
  ent=(AcDbEntity*)curveSegments[1];
  nsp::drawEntity(ent);
  ent->close();
  }
  else if (curveSegments.length()==3)
  {
  ent=(AcDbEntity*)curveSegments[0];
  nsp::drawEntity(ent);
  ent->close();
  ent=(AcDbEntity*)curveSegments[2];
  nsp::drawEntity(ent);
  ent->close();
  }
 curve->erase();
return true ;
 }

发表于 2007-5-11 20:36:00 | 显示全部楼层
这是用什么方式开发的,ActiveX?
发表于 2008-2-27 13:45:00 | 显示全部楼层

用C#怎样调用Addhatch()函数

 楼主| 发表于 2008-3-4 10:23:00 | 显示全部楼层
using app = Autodesk.AutoCAD.ApplicationServices.Application;
AcadApplication CurApp = (AcadApplication)app.AcadApplication;
AcadDocument     CurDoc = CurApp.ActiveDocument;
AcadModelSpace   CurSpace = CurDoc.ModelSpace;
CurSpace.AddHatch(int PatternType, string PatternName, bool Associativity, object HatchObjectType)
AcadBlocks        Blocks = CurDoc.Blocks;
AcadBlock        Block = Blocks.Item(0);
Block .AddHatch(int PatternType, string PatternName, bool Associativity, object HatchObjectType)
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-25 12:25 , Processed in 0.235332 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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