明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 39060|回复: 56

[几何] 曲线处理专贴----我们的[原创]

    [复制链接]
发表于 2009-5-14 21:47:00 | 显示全部楼层 |阅读模式
本帖最后由 作者 于 2009-6-20 16:04:26 编辑

先发几个简单的例子,抛砖引玉,希望大家也贴上自己的得意之作:)
直线打断,模拟Break命令
  1.         [CommandMethod("myb")]
  2.         public static void MyBreakLine()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Database db = doc.Database;
  6.             Editor ed = doc.Editor;
  7.             //选择直线
  8.             PromptEntityOptions opt1 = new PromptEntityOptions("\nselect a line:");
  9.             opt1.SetRejectMessage("\nerror!");
  10.             opt1.AddAllowedClass(typeof(Line), true);
  11.             PromptEntityResult res1 = ed.GetEntity(opt1);
  12.             if (res1.Status == PromptStatus.OK)
  13.             {
  14.                 //选择第二打断点
  15.                 PromptPointOptions opt2 = new PromptPointOptions("\nselect second point:");
  16.                 opt2.AllowNone = true;
  17.                 PromptPointResult res2 = ed.GetPoint(opt2);
  18.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  19.                 {
  20.                     Line oldline = (Line)tr.GetObject(res1.ObjectId, OpenMode.ForRead);
  21.                     List<double> pars = new List<double>();
  22.                     Point3d pt1 = oldline.GetClosestPointTo(res1.PickedPoint, false);
  23.                     Point3d pt2 = new Point3d();
  24.                     pars.Add(oldline.GetParameterAtPoint(pt1));
  25.                     BlockTableRecord btr =
  26.                         (BlockTableRecord)tr.GetObject(
  27.                             db.CurrentSpaceId,
  28.                             OpenMode.ForWrite,
  29.                             false);
  30.                     DBObjectCollection objs;
  31.                     //两种情况
  32.                     if (res2.Status == PromptStatus.OK)
  33.                     {
  34.                         //如果选择了第二点,获取直线上两点的param值,并排序
  35.                         pt2 = oldline.GetClosestPointTo(res2.Value, false);
  36.                         pars.Add(oldline.GetParameterAtPoint(pt2));
  37.                         pars.Sort();
  38.                         //按param值打断曲线
  39.                         objs = oldline.GetSplitCurves(new DoubleCollection(pars.ToArray()));
  40.                         foreach (Line newline in objs)
  41.                         {
  42.                             //如果生成的直线起点或终点不是选择的打断点,把它加入数据库
  43.                             if ((newline.StartPoint != pt1 && newline.StartPoint != pt2) ^ (newline.EndPoint != pt1 && newline.EndPoint != pt2))
  44.                             {
  45.                                 btr.AppendEntity(newline);
  46.                                 tr.AddNewlyCreatedDBObject(newline, true);
  47.                             }
  48.                         }
  49.                     }
  50.                     else
  51.                     {
  52.                         //如果没有选择第二点,就按第一点打断
  53.                         objs = oldline.GetSplitCurves(new DoubleCollection(pars.ToArray()));
  54.                         foreach (Line newline in objs)
  55.                         {
  56.                             btr.AppendEntity(newline);
  57.                             tr.AddNewlyCreatedDBObject(newline, true);
  58.                         }
  59.                     }
  60.                     oldline.UpgradeOpen();
  61.                     oldline.Erase();
  62.                     tr.Commit();
  63.                 }
  64.             }
  65.         }
所有曲线打断于点
  1.         [CommandMethod("BAC")]
  2.         public static void BreakAllCurve()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Database db = doc.Database;
  6.             Editor ed = doc.Editor;
  7.             //选择曲线
  8.             PromptSelectionResult res = ed.GetSelection(new PromptSelectionOptions(), new SelectionFilter(new TypedValue[] { new TypedValue(0, "*Line,Arc,Circle,Ellipse") }));
  9.             ObjectId[] ids = res.Value.GetObjectIds();
  10.             ObjectIdCollection oldids = new ObjectIdCollection();
  11.             using (Transaction tr = db.TransactionManager.StartTransaction())
  12.             {
  13.                 BlockTableRecord btr =
  14.                     (BlockTableRecord)tr.GetObject(
  15.                         db.CurrentSpaceId,
  16.                         OpenMode.ForWrite,
  17.                         false);
  18.                 //遍历选择集
  19.                 foreach (ObjectId i in ids)
  20.                 {
  21.                     List<double> pars = new List<double>();
  22.                     Curve iCurve = (Curve)tr.GetObject(i, OpenMode.ForRead);
  23.                     //获取曲线与其他曲线的交点处的param值集合,按该集合打断曲线
  24.                     foreach (ObjectId j in ids)
  25.                     {
  26.                         if (i != j)
  27.                         {
  28.                             Curve jCurve = (Curve)tr.GetObject(j, OpenMode.ForRead);
  29.                             Point3dCollection iwpnts = new Point3dCollection();
  30.                             iCurve.IntersectWith(jCurve, Intersect.OnBothOperands, iwpnts, 0, 0);
  31.                             foreach (Point3d p in iwpnts)
  32.                             {
  33.                                 pars.Add(iCurve.GetParameterAtPoint(p));
  34.                             }
  35.                         }
  36.                     }
  37.                     //如果有交点,按param值排序并打断
  38.                     if (pars.Count > 0)
  39.                     {
  40.                         pars.Sort();
  41.                         try
  42.                         {
  43.                             //将子曲线加入数据库,原曲线加入oldids集合
  44.                             foreach (Curve c in iCurve.GetSplitCurves(new DoubleCollection(pars.ToArray())))
  45.                             {
  46.                                 btr.AppendEntity(c);
  47.                                 tr.AddNewlyCreatedDBObject(c, true);
  48.                             }
  49.                             oldids.Add(i);
  50.                         }
  51.                         catch
  52.                         { }
  53.                     }
  54.                 }
  55.                 foreach (ObjectId id in oldids)
  56.                 {
  57.                     tr.GetObject(id, OpenMode.ForWrite).Erase();
  58.                 }
  59.                 tr.Commit();
  60.             }
  61.         }
简单的直线倒角
  1.         [CommandMethod("dj")]
  2.         public void daojiao()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Database db = doc.Database;
  6.             Editor ed = doc.Editor;
  7.             PromptDoubleResult resgetdist = ed.GetDistance("\n请输入倒角距离");
  8.             if (resgetdist.Status == PromptStatus.OK)
  9.             {
  10.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  11.                 {
  12.                     double dist = resgetdist.Value;
  13.                     PromptEntityOptions optgetent = new PromptEntityOptions("\n请选择第一条直线:");
  14.                     optgetent.SetRejectMessage("\n错误的选择");
  15.                     optgetent.AddAllowedClass(typeof(Line), true);
  16.                     PromptEntityResult resgetent = ed.GetEntity(optgetent);
  17.                     if (resgetent.Status == PromptStatus.OK)
  18.                     {
  19.                         ObjectId id1 = resgetent.ObjectId;
  20.                         Line line1 = (Line)tr.GetObject(id1, OpenMode.ForWrite);
  21.                         line1.Highlight();
  22.                         Point3d pt1 = resgetent.PickedPoint;
  23.                         optgetent.Message = "\n请选择第二条直线:";
  24.                         resgetent = ed.GetEntity(optgetent);
  25.                         if (resgetent.Status == PromptStatus.OK)
  26.                         {
  27.                             ObjectId id2 = resgetent.ObjectId;
  28.                             Point3d pt2 = resgetent.PickedPoint;
  29.                             Line line2 = (Line)tr.GetObject(id2, OpenMode.ForWrite);
  30.                             pt1 = line1.GetClosestPointTo(pt1, false);
  31.                             pt2 = line2.GetClosestPointTo(pt2, false);
  32.                             //获取两直线交点
  33.                             Point3dCollection pts = new Point3dCollection();
  34.                             line1.IntersectWith(line2, Intersect.ExtendBoth, pts, 0, 0);
  35.                             //如果有交点
  36.                             if (pts.Count == 1)
  37.                             {
  38.                                 Point3d pt = pts[0];
  39.                                 Plane plane = new Plane();
  40.                                 //判断点选在直线的哪一侧(是否靠近起点)
  41.                                 Vector3d v1,v2;
  42.                                 v1 = line1.StartPoint - pt;
  43.                                 v2 = line1.EndPoint - pt;
  44.                                 bool atstart1 = false;
  45.                                 if (v1.Length != 0)
  46.                                 {
  47.                                     atstart1 = Tolerance.Equals(v1.AngleOnPlane(plane), (pt1 - pt).AngleOnPlane(plane));
  48.                                     if (Tolerance.Equals(v1.AngleOnPlane(plane), v2.AngleOnPlane(plane)))
  49.                                     {
  50.                                         atstart1 = v1.Length > v2.Length;
  51.                                     }
  52.                                 }
  53.                                 v1 = line2.StartPoint - pt;
  54.                                 v2 = line2.EndPoint - pt;
  55.                                 bool atstart2 = false;
  56.                                 if (v1.Length != 0)
  57.                                 {
  58.                                     atstart2 = Tolerance.Equals(v1.AngleOnPlane(plane), (pt2 - pt).AngleOnPlane(plane));
  59.                                     if (Tolerance.Equals(v1.AngleOnPlane(plane), v2.AngleOnPlane(plane)))
  60.                                     {
  61.                                         atstart2 = v1.Length > v2.Length;
  62.                                     }
  63.                                 }
  64.                                 // 判断被选择段是否可以倒角
  65.                                 Point3d pt3 = atstart1 ? line1.StartPoint : line1.EndPoint;
  66.                                 Point3d pt4 = atstart2 ? line2.StartPoint : line2.EndPoint;
  67.                                 Vector3d vec1 = pt3 - pt;
  68.                                 Vector3d vec2 = pt4 - pt;
  69.                                 if (vec1.Length >= dist && vec2.Length >= dist)
  70.                                 {
  71.                                     //计算倒角点
  72.                                     vec1 = vec1.GetNormal() * dist;
  73.                                     vec2 = vec2.GetNormal() * dist;
  74.                                     pt3 = pt + vec1;
  75.                                     pt4 = pt + vec2;
  76.                                     //按点选的位置改变原直线
  77.                                     if (atstart1)
  78.                                     {
  79.                                         line1.EndPoint = pt3;
  80.                                     }
  81.                                     else
  82.                                     {
  83.                                         line1.StartPoint = pt3;
  84.                                     }
  85.                                     if (line1.Length == 0)
  86.                                     {
  87.                                         line1.Erase();
  88.                                     }
  89.                                     if (atstart2)
  90.                                     {
  91.                                         line2.EndPoint = pt4;
  92.                                     }
  93.                                     else
  94.                                     {
  95.                                         line2.StartPoint = pt4;
  96.                                     }
  97.                                     if (line2.Length == 0)
  98.                                     {
  99.                                         line2.Erase();
  100.                                     }
  101.                                     //生成倒角线
  102.                                     Line line = new Line(pt3, pt4);
  103.                                     BlockTableRecord btr =
  104.                                         (BlockTableRecord)tr.GetObject(
  105.                                             db.CurrentSpaceId,
  106.                                             OpenMode.ForWrite,
  107.                                             false);
  108.                                     btr.AppendEntity(line);
  109.                                     tr.AddNewlyCreatedDBObject(line, true);
  110.                                 }
  111.                                 else
  112.                                 {
  113.                                     ed.WriteMessage("\n距离太大\n*无效");
  114.                                 }
  115.                             }
  116.                             else
  117.                             {
  118.                                 ed.WriteMessage("\n直线平行\n*无效");
  119.                             }
  120.                         }
  121.                     }
  122.                     tr.Commit();
  123.                 }
  124.             }
  125.         }
找回hatch的边界,
填充边界是一组Ge曲线,所以需要转换为Db曲线
圆弧和椭圆的处理不太好,Ge库实体的方法有点晕哈,期待高人操刀
  1.         [CommandMethod("ht")]
  2.         public static void HatchLoop()
  3.         {
  4.             PromptSelectionResult res = CadHelper.Editor.GetSelection(
  5.                 new PromptSelectionOptions(),
  6.                 new SelectionFilter(new TypedValue[] { new TypedValue(0, "Hatch") }));
  7.             if (res.Status != PromptStatus.OK)
  8.                 return;
  9.             Document doc = Application.DocumentManager.MdiActiveDocument;
  10.             Database db = doc.Database;
  11.             using (Transaction tr = db.TransactionManager.StartTransaction())
  12.             {
  13.                 BlockTableRecord btr =
  14.                     (BlockTableRecord)tr.GetObject(
  15.                         db.CurrentSpaceId,
  16.                         OpenMode.ForWrite,
  17.                         false);
  18.                 foreach (ObjectId id in res.Value.GetObjectIds())
  19.                 {
  20.                     //获取Hatch对象的Ocs
  21.                     Hatch h = (Hatch)tr.GetObject(id, OpenMode.ForRead);
  22.                     Matrix3d mat = Matrix3d.PlaneToWorld(h.GetPlane());
  23.                     //遍历边界集合,通常边界有两种形式:多义线 或 曲线集合
  24.                     for (int i = 0; i < h.NumberOfLoops; i++)
  25.                     {
  26.                         HatchLoop loop = h.GetLoopAt(i);
  27.                         //如果是多义线,转换为Db库的多义线
  28.                         if (loop.IsPolyline)
  29.                         {
  30.                             BulgeVertexCollection bvs = loop.Polyline;
  31.                             Polyline pl = new Polyline();
  32.                             for (int j = 0; j < bvs.Count; j++)
  33.                             {
  34.                                 BulgeVertex bv = bvs[j];
  35.                                 pl.AddVertexAt(j, bv.Vertex, bv.Bulge, 0, 0);
  36.                             }
  37.                             pl.TransformBy(mat);
  38.                             btr.AppendEntity(pl);
  39.                             tr.AddNewlyCreatedDBObject(pl, true);
  40.                         }
  41.                         //否则,遍历曲线集合,依次转化为Db库的曲线
  42.                         else
  43.                         {
  44.                             foreach (Curve2d curve in loop.Curves)
  45.                             {
  46.                                 Curve c = CadHelper.ConvertCurve2d(curve, mat);
  47.                                 btr.AppendEntity(c);
  48.                                 tr.AddNewlyCreatedDBObject(c, true);
  49.                             }
  50.                         }
  51.                     }
  52.                 }
  53.                 tr.Commit();
  54.             }
  55.         }
CadHelper类
  1. using System;
  2. using System.Collections.Generic;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.EditorInput;
  6. using Autodesk.AutoCAD.Geometry;
  7. namespace TlsCad
  8. {
  9.     public static class CadHelper
  10.     {
  11.         #region Curve
  12.         //Ge2d曲线按Ocs转化为Db曲线
  13.         public static Curve ConvertCurve2d(Curve2d curve, Matrix3d mat)
  14.         {
  15.             //直线
  16.             if (curve is LineSegment2d)
  17.             {
  18.                 return ConvertLineSegment2d((LineSegment2d)curve, mat);
  19.             }
  20.             //样条曲线
  21.             else if (curve is NurbCurve2d)
  22.             {
  23.                 return ConvertNurbCurve2d((NurbCurve2d)curve, mat);
  24.             }
  25.             //椭圆
  26.             else if (curve is EllipticalArc2d)
  27.             {
  28.                 return ConvertEllipticalArc2d((EllipticalArc2d)curve, mat);
  29.             }
  30.             //圆弧
  31.             else if (curve is CircularArc2d)
  32.             {
  33.                 return ConvertCircularArc2d((CircularArc2d)curve, mat);
  34.             }
  35.             else
  36.             {
  37.                 //待续
  38.                 return null;
  39.             }
  40.         }
  41.         #region ConvertCurve2d
  42.         //圆弧
  43.         public static Curve ConvertCircularArc2d(CircularArc2d ca2d, Matrix3d mat)
  44.         {
  45.             Curve c = ConvertCircularArc2d(ca2d);
  46.             c.TransformBy(mat);
  47.             return c;
  48.         }
  49.         public static Curve ConvertCircularArc2d(CircularArc2d ca2d)
  50.         {
  51.             if (ca2d.IsClosed())
  52.             {
  53.                 return ConvertCircular2d(ca2d);
  54.             }
  55.             else
  56.             {
  57.                 return ConvertArc2d(ca2d);
  58.             }
  59.         }
  60.         public static Circle ConvertCircular2d(CircularArc2d c2d)
  61.         {
  62.             return
  63.                 new Circle(
  64.                     new Point3d(new Plane(), c2d.Center),
  65.                     new Vector3d(0, 0, 1),
  66.                     c2d.Radius);
  67.         }
  68.         public static Arc ConvertArc2d(CircularArc2d a2d)
  69.         {
  70.             double startangle, endangle;
  71.             if (a2d.IsClockWise)
  72.             {
  73.                 startangle = (a2d.EndPoint - a2d.Center).Angle;
  74.                 endangle = (a2d.StartPoint - a2d.Center).Angle;
  75.             }
  76.             else
  77.             {
  78.                 startangle = (a2d.StartPoint - a2d.Center).Angle;
  79.                 endangle = (a2d.EndPoint - a2d.Center).Angle;
  80.             }
  81.             return
  82.                 new Arc(
  83.                     new Point3d(new Plane(), a2d.Center),
  84.                     new Vector3d(0, 0, 1),
  85.                     a2d.Radius,
  86.                     startangle,
  87.                     endangle);
  88.         }
  89.         //椭圆弧
  90.         public static Ellipse ConvertEllipticalArc2d(EllipticalArc2d ea2d, Matrix3d mat)
  91.         {
  92.             Ellipse e = ConvertEllipticalArc2d(ea2d);
  93.             e.TransformBy(mat);
  94.             return e;
  95.         }
  96.         public static Ellipse ConvertEllipticalArc2d(EllipticalArc2d ea2d)
  97.         {
  98.             double startangle, endangle;
  99.             if (ea2d.IsCircular())
  100.             {
  101.                 startangle = 0;
  102.                 endangle = Math.PI * 2;
  103.             }
  104.             else
  105.             {
  106.                 double majorangle = ea2d.MajorAxis.Angle;
  107.                 if (ea2d.IsClockWise)
  108.                 {
  109.                     startangle = (ea2d.EndPoint - ea2d.Center).Angle - majorangle;
  110.                     endangle = (ea2d.StartPoint - ea2d.Center).Angle - majorangle;
  111.                 }
  112.                 else
  113.                 {
  114.                     startangle = (ea2d.StartPoint - ea2d.Center).Angle - majorangle;
  115.                     endangle = (ea2d.EndPoint - ea2d.Center).Angle - majorangle;
  116.                 }
  117.             }
  118.             return
  119.                 new Ellipse(
  120.                     new Point3d(new Plane(), ea2d.Center),
  121.                     new Vector3d(0, 0, 1),
  122.                     new Vector3d(new Plane(), ea2d.MajorAxis) * ea2d.MajorRadius,
  123.                     ea2d.MinorRadius / ea2d.MajorRadius,
  124.                     startangle,
  125.                     endangle);
  126.         }
  127.         //直线
  128.         public static Line ConvertLineSegment2d(LineSegment2d ls2d, Matrix3d mat)
  129.         {
  130.             Line l = ConvertLineSegment2d(ls2d);
  131.             l.TransformBy(mat);
  132.             return l;
  133.         }
  134.         public static Line ConvertLineSegment2d(LineSegment2d ls2d)
  135.         {
  136.             Plane plane = new Plane();
  137.             return
  138.                 new Line(
  139.                     new Point3d(plane, ls2d.StartPoint),
  140.                     new Point3d(plane, ls2d.EndPoint));
  141.         }
  142.         //样条曲线
  143.         public static Spline ConvertNurbCurve2d(NurbCurve2d nc2d, Matrix3d mat)
  144.         {
  145.             Spline spl = ConvertNurbCurve2d(nc2d);
  146.             spl.TransformBy(mat);
  147.             return spl;
  148.         }
  149.         public static Spline ConvertNurbCurve2d(NurbCurve2d nc2d)
  150.         {
  151.             int i;
  152.             Plane plane = new Plane();
  153.             Point3dCollection ctlpnts = new Point3dCollection();
  154.             for (i = 0; i < nc2d.NumControlPoints; i++)
  155.             {
  156.                 ctlpnts.Add(new Point3d(plane, nc2d.GetControlPointAt(i)));
  157.             }
  158.             DoubleCollection knots = new DoubleCollection();
  159.             foreach (double knot in nc2d.Knots)
  160.             {
  161.                 knots.Add(knot);
  162.             }
  163.             DoubleCollection weights = new DoubleCollection();
  164.             for (i = 0; i < nc2d.NumWeights; i++)
  165.             {
  166.                 weights.Add(nc2d.GetWeightAt(i));
  167.             }
  168.             return  
  169.                 new Spline(
  170.                     nc2d.Degree,
  171.                     false,
  172.                     false,
  173.                     false,
  174.                     ctlpnts,
  175.                     knots,
  176.                     weights,
  177.                     0,
  178.                     nc2d.Knots.Tolerance);
  179.         }
  180.         #endregion
  181.         #endregion
  182.     }
  183. }
发表于 2020-4-3 09:43:30 | 显示全部楼层
都是知识点  线画上  以后要学习
发表于 2024-11-6 02:23:25 | 显示全部楼层
非常感谢飞狐大神,又从你的帖子里学到了好多知识!
发表于 2018-8-9 15:36:27 | 显示全部楼层
非常感谢飞狐大神,又从你的帖子里学到了好多知识!
 楼主| 发表于 2009-5-14 22:18:00 | 显示全部楼层
本帖最后由 作者 于 2009-5-23 14:02:47 编辑

所有曲线打断于点
  1.         [CommandMethod("BAC")]
  2.         public static void BreakAllCurve()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Database db = doc.Database;
  6.             Editor ed = doc.Editor;
  7.             //选择曲线
  8.             PromptSelectionResult res = ed.GetSelection(new PromptSelectionOptions(), new SelectionFilter(new TypedValue[] { new TypedValue(0, "*Line,Arc,Circle,Ellipse") }));
  9.             ObjectId[] ids = res.Value.GetObjectIds();
  10.             ObjectIdCollection oldids = new ObjectIdCollection();
  11.             using (Transaction tr = db.TransactionManager.StartTransaction())
  12.             {
  13.                 BlockTableRecord btr =
  14.                     (BlockTableRecord)tr.GetObject(
  15.                         db.CurrentSpaceId,
  16.                         OpenMode.ForWrite,
  17.                         false);
  18.                 //遍历选择集
  19.                 foreach (ObjectId i in ids)
  20.                 {
  21.                     List<double> pars = new List<double>();
  22.                     Curve iCurve = (Curve)tr.GetObject(i, OpenMode.ForRead);
  23.                     //获取曲线与其他曲线的交点处的param值集合,按该集合打断曲线
  24.                     foreach (ObjectId j in ids)
  25.                     {
  26.                         if (i != j)
  27.                         {
  28.                             Curve jCurve = (Curve)tr.GetObject(j, OpenMode.ForRead);
  29.                             Point3dCollection iwpnts = new Point3dCollection();
  30.                             iCurve.IntersectWith(jCurve, Intersect.OnBothOperands, iwpnts, 0, 0);
  31.                             foreach (Point3d p in iwpnts)
  32.                             {
  33.                                 pars.Add(iCurve.GetParameterAtPoint(p));
  34.                             }
  35.                         }
  36.                     }
  37.                     //如果有交点,按param值排序并打断
  38.                     if (pars.Count > 0)
  39.                     {
  40.                         pars.Sort();
  41.                         try
  42.                         {
  43.                             //将子曲线加入数据库,原曲线加入oldids集合
  44.                             foreach (Line newline in iCurve.GetSplitCurves(new DoubleCollection(pars.ToArray())))
  45.                             {
  46.                                 btr.AppendEntity(newline);
  47.                                 tr.AddNewlyCreatedDBObject(newline, true);
  48.                             }
  49.                             oldids.Add(i);
  50.                         }
  51.                         catch
  52.                         { }
  53.                     }
  54.                 }
  55.                 foreach (ObjectId id in oldids)
  56.                 {
  57.                     tr.GetObject(id, OpenMode.ForWrite).Erase();
  58.                 }
  59.                 tr.Commit();
  60.             }
  61.         }
 楼主| 发表于 2009-5-15 13:13:00 | 显示全部楼层
本帖最后由 作者 于 2009-5-23 14:13:00 编辑

找回hatch的边界,
填充边界是一组Ge曲线,所以需要转换为Db曲线
圆弧和椭圆的处理不太好,Ge库实体的方法有点晕哈,期待高人操刀
  1.         [CommandMethod("ht")]
  2.         public static void HatchLoop()
  3.         {
  4.             PromptSelectionResult res = CadHelper.Editor.GetSelection(
  5.                 new PromptSelectionOptions(),
  6.                 new SelectionFilter(new TypedValue[] { new TypedValue(0, "Hatch") }));
  7.             if (res.Status != PromptStatus.OK)
  8.                 return;
  9.             Document doc = Application.DocumentManager.MdiActiveDocument;
  10.             Database db = doc.Database;
  11.             using (Transaction tr = db.TransactionManager.StartTransaction())
  12.             {
  13.                 BlockTableRecord btr =
  14.                     (BlockTableRecord)tr.GetObject(
  15.                         db.CurrentSpaceId,
  16.                         OpenMode.ForWrite,
  17.                         false);
  18.                 foreach (ObjectId id in res.Value.GetObjectIds())
  19.                 {
  20.                     //获取Hatch对象的Ocs
  21.                     Hatch h = (Hatch)tr.GetObject(id, OpenMode.ForRead);
  22.                     Matrix3d mat = Matrix3d.PlaneToWorld(h.GetPlane());
  23.                     //遍历边界集合,通常边界有两种形式:多义线 或 曲线集合
  24.                     for (int i = 0; i < h.NumberOfLoops; i++)
  25.                     {
  26.                         HatchLoop loop = h.GetLoopAt(i);
  27.                         //如果是多义线,转换为Db库的多义线
  28.                         if (loop.IsPolyline)
  29.                         {
  30.                             BulgeVertexCollection bvs = loop.Polyline;
  31.                             Polyline pl = new Polyline();
  32.                             for (int j = 0; j < bvs.Count; j++)
  33.                             {
  34.                                 BulgeVertex bv = bvs[j];
  35.                                 pl.AddVertexAt(j, bv.Vertex, bv.Bulge, 0, 0);
  36.                             }
  37.                             pl.TransformBy(mat);
  38.                             btr.AppendEntity(pl);
  39.                             tr.AddNewlyCreatedDBObject(pl, true);
  40.                         }
  41.                         //否则,遍历曲线集合,依次转化为Db库的曲线
  42.                         else
  43.                         {
  44.                             foreach (Curve2d curve in loop.Curves)
  45.                             {
  46.                                 Curve c = CadHelper.ConvertCurve2d(curve, mat);
  47.                                 btr.AppendEntity(c);
  48.                                 tr.AddNewlyCreatedDBObject(c, true);
  49.                             }
  50.                         }
  51.                     }
  52.                 }
  53.                 tr.Commit();
  54.             }
  55.         }
CadHelper类
  1. using System;
  2. using System.Collections.Generic;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.EditorInput;
  6. using Autodesk.AutoCAD.Geometry;
  7. namespace TlsCad
  8. {
  9.     public static class CadHelper
  10.     {
  11.         #region Curve
  12.         //Ge2d曲线按Ocs转化为Db曲线
  13.         public static Curve ConvertCurve2d(Curve2d curve, Matrix3d mat)
  14.         {
  15.             //直线
  16.             if (curve is LineSegment2d)
  17.             {
  18.                 return ConvertLineSegment2d((LineSegment2d)curve, mat);
  19.             }
  20.             //样条曲线
  21.             else if (curve is NurbCurve2d)
  22.             {
  23.                 return ConvertNurbCurve2d((NurbCurve2d)curve, mat);
  24.             }
  25.             //椭圆
  26.             else if (curve is EllipticalArc2d)
  27.             {
  28.                 return ConvertEllipticalArc2d((EllipticalArc2d)curve, mat);
  29.             }
  30.             //圆弧
  31.             else if (curve is CircularArc2d)
  32.             {
  33.                 return ConvertCircularArc2d((CircularArc2d)curve, mat);
  34.             }
  35.             else
  36.             {
  37.                 //待续
  38.                 return null;
  39.             }
  40.         }
  41.         #region ConvertCurve2d
  42.         //圆弧
  43.         public static Curve ConvertCircularArc2d(CircularArc2d ca2d, Matrix3d mat)
  44.         {
  45.             Curve c = ConvertCircularArc2d(ca2d);
  46.             c.TransformBy(mat);
  47.             return c;
  48.         }
  49.         public static Curve ConvertCircularArc2d(CircularArc2d ca2d)
  50.         {
  51.             if (ca2d.IsClosed())
  52.             {
  53.                 return ConvertCircular2d(ca2d);
  54.             }
  55.             else
  56.             {
  57.                 return ConvertArc2d(ca2d);
  58.             }
  59.         }
  60.         public static Circle ConvertCircular2d(CircularArc2d c2d)
  61.         {
  62.             return
  63.                 new Circle(
  64.                     new Point3d(new Plane(), c2d.Center),
  65.                     new Vector3d(0, 0, 1),
  66.                     c2d.Radius);
  67.         }
  68.         public static Arc ConvertArc2d(CircularArc2d a2d)
  69.         {
  70.             double startangle, endangle;
  71.             if (a2d.IsClockWise)
  72.             {
  73.                 startangle = (a2d.EndPoint - a2d.Center).Angle;
  74.                 endangle = (a2d.StartPoint - a2d.Center).Angle;
  75.             }
  76.             else
  77.             {
  78.                 startangle = (a2d.StartPoint - a2d.Center).Angle;
  79.                 endangle = (a2d.EndPoint - a2d.Center).Angle;
  80.             }
  81.             return
  82.                 new Arc(
  83.                     new Point3d(new Plane(), a2d.Center),
  84.                     new Vector3d(0, 0, 1),
  85.                     a2d.Radius,
  86.                     startangle,
  87.                     endangle);
  88.         }
  89.         //椭圆弧
  90.         public static Ellipse ConvertEllipticalArc2d(EllipticalArc2d ea2d, Matrix3d mat)
  91.         {
  92.             Ellipse e = ConvertEllipticalArc2d(ea2d);
  93.             e.TransformBy(mat);
  94.             return e;
  95.         }
  96.         public static Ellipse ConvertEllipticalArc2d(EllipticalArc2d ea2d)
  97.         {
  98.             double startangle, endangle;
  99.             if (ea2d.IsCircular())
  100.             {
  101.                 startangle = 0;
  102.                 endangle = Math.PI * 2;
  103.             }
  104.             else
  105.             {
  106.                 double majorangle = ea2d.MajorAxis.Angle;
  107.                 if (ea2d.IsClockWise)
  108.                 {
  109.                     startangle = (ea2d.EndPoint - ea2d.Center).Angle - majorangle;
  110.                     endangle = (ea2d.StartPoint - ea2d.Center).Angle - majorangle;
  111.                 }
  112.                 else
  113.                 {
  114.                     startangle = (ea2d.StartPoint - ea2d.Center).Angle - majorangle;
  115.                     endangle = (ea2d.EndPoint - ea2d.Center).Angle - majorangle;
  116.                 }
  117.             }
  118.             return
  119.                 new Ellipse(
  120.                     new Point3d(new Plane(), ea2d.Center),
  121.                     new Vector3d(0, 0, 1),
  122.                     new Vector3d(new Plane(), ea2d.MajorAxis) * ea2d.MajorRadius,
  123.                     ea2d.MinorRadius / ea2d.MajorRadius,
  124.                     startangle,
  125.                     endangle);
  126.         }
  127.         //直线
  128.         public static Line ConvertLineSegment2d(LineSegment2d ls2d, Matrix3d mat)
  129.         {
  130.             Line l = ConvertLineSegment2d(ls2d);
  131.             l.TransformBy(mat);
  132.             return l;
  133.         }
  134.         public static Line ConvertLineSegment2d(LineSegment2d ls2d)
  135.         {
  136.             Plane plane = new Plane();
  137.             return
  138.                 new Line(
  139.                     new Point3d(plane, ls2d.StartPoint),
  140.                     new Point3d(plane, ls2d.EndPoint));
  141.         }
  142.         //样条曲线
  143.         public static Spline ConvertNurbCurve2d(NurbCurve2d nc2d, Matrix3d mat)
  144.         {
  145.             Spline spl = ConvertNurbCurve2d(nc2d);
  146.             spl.TransformBy(mat);
  147.             return spl;
  148.         }
  149.         public static Spline ConvertNurbCurve2d(NurbCurve2d nc2d)
  150.         {
  151.             int i;
  152.             Plane plane = new Plane();
  153.             Point3dCollection ctlpnts = new Point3dCollection();
  154.             for (i = 0; i < nc2d.NumControlPoints; i++)
  155.             {
  156.                 ctlpnts.Add(new Point3d(plane, nc2d.GetControlPointAt(i)));
  157.             }
  158.             DoubleCollection knots = new DoubleCollection();
  159.             foreach (double knot in nc2d.Knots)
  160.             {
  161.                 knots.Add(knot);
  162.             }
  163.             DoubleCollection weights = new DoubleCollection();
  164.             for (i = 0; i < nc2d.NumWeights; i++)
  165.             {
  166.                 weights.Add(nc2d.GetWeightAt(i));
  167.             }
  168.             return  
  169.                 new Spline(
  170.                     nc2d.Degree,
  171.                     false,
  172.                     false,
  173.                     false,
  174.                     ctlpnts,
  175.                     knots,
  176.                     weights,
  177.                     0,
  178.                     nc2d.Knots.Tolerance);
  179.         }
  180.         #endregion
  181.         #endregion
  182.     }
  183. }
 楼主| 发表于 2009-5-16 16:37:00 | 显示全部楼层
本帖最后由 作者 于 2009-5-16 17:57:20 编辑

简单的直线倒角
  1.         [CommandMethod("dj")]
  2.         public void daojiao()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Database db = doc.Database;
  6.             Editor ed = doc.Editor;
  7.             PromptDoubleResult resgetdist = ed.GetDistance("\n请输入倒角距离");
  8.             if (resgetdist.Status == PromptStatus.OK)
  9.             {
  10.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  11.                 {
  12.                     double dist = resgetdist.Value;
  13.                     PromptEntityOptions optgetent = new PromptEntityOptions("\n请选择第一条直线:");
  14.                     optgetent.SetRejectMessage("\n错误的选择");
  15.                     optgetent.AddAllowedClass(typeof(Line), true);
  16.                     PromptEntityResult resgetent = ed.GetEntity(optgetent);
  17.                     if (resgetent.Status == PromptStatus.OK)
  18.                     {
  19.                         ObjectId id1 = resgetent.ObjectId;
  20.                         Line line1 = (Line)tr.GetObject(id1, OpenMode.ForWrite);
  21.                         line1.Highlight();
  22.                         Point3d pt1 = resgetent.PickedPoint;
  23.                         optgetent.Message = "\n请选择第二条直线:";
  24.                         resgetent = ed.GetEntity(optgetent);
  25.                         if (resgetent.Status == PromptStatus.OK)
  26.                         {
  27.                             ObjectId id2 = resgetent.ObjectId;
  28.                             Point3d pt2 = resgetent.PickedPoint;
  29.                             Line line2 = (Line)tr.GetObject(id2, OpenMode.ForWrite);
  30.                             pt1 = line1.GetClosestPointTo(pt1, false);
  31.                             pt2 = line2.GetClosestPointTo(pt2, false);
  32.                             //获取两直线交点
  33.                             Point3dCollection pts = new Point3dCollection();
  34.                             line1.IntersectWith(line2, Intersect.ExtendBoth, pts, 0, 0);
  35.                             //如果有交点
  36.                             if (pts.Count == 1)
  37.                             {
  38.                                 Point3d pt = pts[0];
  39.                                 Plane plane = new Plane();
  40.                                 //判断点选在直线的哪一侧(是否靠近起点)
  41.                                 Vector3d v1,v2;
  42.                                 v1 = line1.StartPoint - pt;
  43.                                 v2 = line1.EndPoint - pt;
  44.                                 bool atstart1 = false;
  45.                                 if (v1.Length != 0)
  46.                                 {
  47.                                     atstart1 = Tolerance.Equals(v1.AngleOnPlane(plane), (pt1 - pt).AngleOnPlane(plane));
  48.                                     if (Tolerance.Equals(v1.AngleOnPlane(plane), v2.AngleOnPlane(plane)))
  49.                                     {
  50.                                         atstart1 = v1.Length > v2.Length;
  51.                                     }
  52.                                 }
  53.                                 v1 = line2.StartPoint - pt;
  54.                                 v2 = line2.EndPoint - pt;
  55.                                 bool atstart2 = false;
  56.                                 if (v1.Length != 0)
  57.                                 {
  58.                                     atstart2 = Tolerance.Equals(v1.AngleOnPlane(plane), (pt2 - pt).AngleOnPlane(plane));
  59.                                     if (Tolerance.Equals(v1.AngleOnPlane(plane), v2.AngleOnPlane(plane)))
  60.                                     {
  61.                                         atstart2 = v1.Length > v2.Length;
  62.                                     }
  63.                                 }
  64.                                 // 判断被选择段是否可以倒角
  65.                                 Point3d pt3 = atstart1 ? line1.StartPoint : line1.EndPoint;
  66.                                 Point3d pt4 = atstart2 ? line2.StartPoint : line2.EndPoint;
  67.                                 Vector3d vec1 = pt3 - pt;
  68.                                 Vector3d vec2 = pt4 - pt;
  69.                                 if (vec1.Length >= dist && vec2.Length >= dist)
  70.                                 {
  71.                                     //计算倒角点
  72.                                     vec1 = vec1.GetNormal() * dist;
  73.                                     vec2 = vec2.GetNormal() * dist;
  74.                                     pt3 = pt + vec1;
  75.                                     pt4 = pt + vec2;
  76.                                     //按点选的位置改变原直线
  77.                                     if (atstart1)
  78.                                     {
  79.                                         line1.EndPoint = pt3;
  80.                                     }
  81.                                     else
  82.                                     {
  83.                                         line1.StartPoint = pt3;
  84.                                     }
  85.                                     if (line1.Length == 0)
  86.                                     {
  87.                                         line1.Erase();
  88.                                     }
  89.                                     if (atstart2)
  90.                                     {
  91.                                         line2.EndPoint = pt4;
  92.                                     }
  93.                                     else
  94.                                     {
  95.                                         line2.StartPoint = pt4;
  96.                                     }
  97.                                     if (line2.Length == 0)
  98.                                     {
  99.                                         line2.Erase();
  100.                                     }
  101.                                     //生成倒角线
  102.                                     Line line = new Line(pt3, pt4);
  103.                                     BlockTableRecord btr =
  104.                                         (BlockTableRecord)tr.GetObject(
  105.                                             db.CurrentSpaceId,
  106.                                             OpenMode.ForWrite,
  107.                                             false);
  108.                                     btr.AppendEntity(line);
  109.                                     tr.AddNewlyCreatedDBObject(line, true);
  110.                                 }
  111.                                 else
  112.                                 {
  113.                                     ed.WriteMessage("\n距离太大\n*无效");
  114.                                 }
  115.                             }
  116.                             else
  117.                             {
  118.                                 ed.WriteMessage("\n直线平行\n*无效");
  119.                             }
  120.                         }
  121.                     }
  122.                     tr.Commit();
  123.                 }
  124.             }
  125.         }
发表于 2009-5-18 08:54:00 | 显示全部楼层
仅以此表示对新任版主的支持!
  1.     /// <summary>
  2.     /// 将Line Arc LWPolyline 编辑成LWPolyline,能连接在一起的连接起来
  3.     /// 要求端点相接
  4.     /// Version : 2007.09.19
  5.     /// </summary>
  6.     /// <param name="cur1">第一曲线,若两条曲线连接成一条,则新曲线使用第一曲线一般属性(有例外),不应该为null</param>
  7.     /// <param name="cur2">第二曲线,可以为null,这时是编辑单个实体</param>
  8.     /// <param name="dTol">一个距离数值,用于作为判断两点重合的标准</param>
  9.     /// <returns>成功返回Polyline,否则返回null</returns>
  10.     public static Polyline JoinPolyline(Curve cur1, Curve cur2, double dTol)
  11.     {
  12.       try
  13.       {      
  14.         Polyline pline = null;
  15.         if (cur1 == null || cur1.Closed) return null;
  16.         if (!cur1.GetType().Equals(typeof(Polyline)))
  17.         {
  18.           #region !Polyline:Line Arc Polyline
  19.           if (cur2 != null && cur2.GetType().Equals(typeof(Polyline)))
  20.           {//第一曲线为非Polyline,而第二曲线为Polyline,这时以第二曲线作为第一曲线重新调用函数,此举只为减少代码
  21.             return JoinPolyline(cur2, cur1, dTol);
  22.           }
  23.           pline = new Polyline();
  24.           if (cur1.GetType().Equals(typeof(Line)))//Line:?
  25.           {//曲线为  Line,使用其数据生成一个Polyline
  26.             Line line = (Line)cur1;
  27.             pline.AddVertexAt(0, new Point2d(line.StartPoint.X, line.StartPoint.Y), 0, 0, 0);
  28.             pline.AddVertexAt(1, new Point2d(line.EndPoint.X, line.EndPoint.Y), 0, 0, 0);
  29.             pline.SetPropertiesFrom(line);//使用原来实体属性
  30.             if (cur2 != null)//若第二曲线不为空,则试图连接两者
  31.               pline = JoinPolyline(pline, cur2, dTol);
  32.             return pline;//将新生成的多义线提交到数据库
  33.           }
  34.           else if (cur1.GetType().Equals(typeof(Arc)))//Arc:?
  35.           {//曲线为  Line,使用其数据生成一个Polyline   
  36.             Arc arc = (Arc)cur1;
  37.             Point3d p1 = arc.GetPointAtParameter(arc.EndParam * 0.5 + arc.StartParam * 0.5);
  38.             double dltAng = arc.EndAngle - arc.StartAngle;
  39.             if (dltAng < 0.0) dltAng += pi * 2;//圆弧的结束角比开始角大时
  40.             double bulge = Math.Tan(dltAng / 4.0);
  41.             if (Clockwise(arc.StartPoint, p1, arc.EndPoint) == -1)//根据圆弧的时钟走向确定凸度正负
  42.               bulge = -bulge;
  43.             pline.AddVertexAt(0, new Point2d(arc.StartPoint.X, arc.StartPoint.Y), bulge, 0, 0);
  44.             pline.AddVertexAt(1, new Point2d(arc.EndPoint.X, arc.EndPoint.Y), 0, 0, 0);
  45.             pline.SetPropertiesFrom(arc);//使用原来实体属性
  46.             if (cur2 != null)//若第二曲线不为空,则试图连接两者
  47.               pline = JoinPolyline(pline, cur2, dTol);
  48.             return pline;//将新生成的多义线提交到数据库
  49.           }
  50.           else
  51.           {//本函数只处理Line Arc Polyline 三种类型曲线         
  52.             return null;
  53.           }
  54.           #endregion !Polyline:Line Arc Polyline
  55.         }
  56.         else if (cur1.GetType().Equals(typeof(Polyline)))
  57.         {
  58.           #region Polyline:Line Arc Polyline
  59.           pline = (Polyline)cur1;
  60.           if (pline.StartPoint.DistanceTo(pline.EndPoint) < dTol)
  61.           {//曲线的起点和终点重合,将其封闭属性设置为true
  62.             if (!pline.Closed)
  63.               pline.Closed = true;
  64.             return pline;
  65.           }
  66.           if (cur2 != null && cur2.GetType().Equals(typeof(Line)))
  67.           {//第二曲线为Line,将其加入到多义线里,需注意是加入直线的远点
  68.             #region Polyline:Line
  69.             Line line = (Line)cur2;
  70.             if (pline.EndPoint.DistanceTo(line.StartPoint) < dTol)
  71.             {
  72.               pline.AddVertexAt(pline.NumberOfVertices, new Point2d(line.EndPoint.X, line.EndPoint.Y), 0, 0, 0);
  73.             }
  74.             else if (pline.EndPoint.DistanceTo(line.EndPoint) < dTol)
  75.             {
  76.               pline.AddVertexAt(pline.NumberOfVertices, new Point2d(line.StartPoint.X, line.StartPoint.Y), 0, 0, 0);
  77.             }
  78.             else if (pline.StartPoint.DistanceTo(line.StartPoint) < dTol)
  79.             {
  80.               pline.AddVertexAt(0, new Point2d(line.EndPoint.X, line.EndPoint.Y), 0, 0, 0);
  81.             }
  82.             else if (pline.StartPoint.DistanceTo(line.EndPoint) < dTol)
  83.             {
  84.               pline.AddVertexAt(0, new Point2d(line.StartPoint.X, line.StartPoint.Y), 0, 0, 0);
  85.             }
  86.             #endregion Polyline:Line
  87.           }
  88.           else if (cur2 != null && cur2.GetType().Equals(typeof(Arc)))
  89.           {
  90.             #region Polyline:Arc
  91.             //第二曲线为Arc,将其加入到多义线里,需注意凸度的计算及正负
  92.             //凸度的大小由圆弧的圆周角计算可得,
  93.             //凸度的正负先根据圆弧的时钟走向得到一个值,然后在根据圆弧的近点,中点,远点三点的时钟走向
  94.             //还有在Polyline里是后加入还是前插入来最终确定正负
  95.             Arc arc = (Arc)cur2;
  96.             Point3d p1 = arc.GetPointAtParameter(arc.EndParam * 0.5 + arc.StartParam * 0.5);
  97.             double dltAng = arc.EndAngle - arc.StartAngle;
  98.             if (dltAng < 0.0) dltAng += pi * 2;
  99.             double bulge = Math.Tan(dltAng / 4.0);
  100.             if (pline.EndPoint.DistanceTo(arc.StartPoint) < dTol)
  101.             {//末端接入,根据圆弧近点,中点,远点确定凸度正负
  102.               if (Clockwise(arc.StartPoint, p1, arc.EndPoint) == -1)
  103.                 bulge = -bulge;
  104.               pline.AddVertexAt(pline.NumberOfVertices, new Point2d(arc.EndPoint.X, arc.EndPoint.Y), 0, 0, 0);
  105.               pline.SetBulgeAt(pline.NumberOfVertices - 2, bulge);//注意凸度段序号
  106.             }
  107.             else if (pline.EndPoint.DistanceTo(arc.EndPoint) < dTol)
  108.             {//末端接入,根据圆弧近点,中点,远点确定凸度正负
  109.               if (Clockwise(arc.EndPoint, p1, arc.StartPoint) == -1)
  110.                 bulge = -bulge;
  111.               pline.AddVertexAt(pline.NumberOfVertices, new Point2d(arc.StartPoint.X, arc.StartPoint.Y), 0, 0, 0);
  112.               pline.SetBulgeAt(pline.NumberOfVertices - 2, bulge);
  113.             }
  114.             else if (pline.StartPoint.DistanceTo(arc.StartPoint) < dTol)
  115.             {//开始端接入,根据圆弧远点,中点,近点确定凸度正负
  116.               if (Clockwise(arc.EndPoint, p1, arc.StartPoint) == -1)
  117.                 bulge = -bulge;
  118.               pline.AddVertexAt(0, new Point2d(arc.EndPoint.X, arc.EndPoint.Y), bulge, 0, 0);
  119.             }
  120.             else if (pline.StartPoint.DistanceTo(arc.EndPoint) < dTol)
  121.             {//开始端接入,根据圆弧远点,中点,近点确定凸度正负
  122.               if (Clockwise(arc.StartPoint, p1, arc.EndPoint) == -1)
  123.                 bulge = -bulge;
  124.               pline.AddVertexAt(0, new Point2d(arc.StartPoint.X, arc.StartPoint.Y), bulge, 0, 0);
  125.             }
  126.             #endregion Polyline:Arc
  127.           }
  128.           else if (cur2 != null && cur2.GetType().Equals(typeof(Polyline)))
  129.           {
  130.             #region Polyline:Polyline
  131.             Polyline pline2 = (Polyline)cur2;
  132.             if (pline.EndPoint.DistanceTo(pline2.StartPoint) < dTol)
  133.             { //第一曲线末端接入,第二曲线正向加入
  134.               for (int i = 1; i < pline2.NumberOfVertices; i++)//一段段的读出,加入另外曲线
  135.               {
  136.                 pline.AddVertexAt(pline.NumberOfVertices, pline2.GetPoint2dAt(i), 0, 0, 0);
  137.                 pline.SetBulgeAt(pline.NumberOfVertices - 2, pline2.GetBulgeAt(i - 1));//注意凸度段序号
  138.               }
  139.             }
  140.             else if (pline.EndPoint.DistanceTo(pline2.EndPoint) < dTol)
  141.             {//末端接入,第二曲线逆向加入,第二曲线原有凸度需反向
  142.               for (int i = pline2.NumberOfVertices - 2; i >= 0; i--)
  143.               {
  144.                 pline.AddVertexAt(pline.NumberOfVertices, pline2.GetPoint2dAt(i), 0, 0, 0);
  145.                 pline.SetBulgeAt(pline.NumberOfVertices - 2, -pline2.GetBulgeAt(i));
  146.               }
  147.             }
  148.             else if (pline.StartPoint.DistanceTo(pline2.StartPoint) < dTol)
  149.             {
  150.               //第一曲线开始端入,第二曲线逆向加入,第二曲线原有凸度需反向
  151.               for (int i = 1; i < pline2.NumberOfVertices; i++)
  152.               {
  153.                 pline.AddVertexAt(0, pline2.GetPoint2dAt(i), 0, 0, 0);
  154.                 pline.SetBulgeAt(0, -pline2.GetBulgeAt(i - 1));
  155.               }
  156.             }
  157.             else if (pline.StartPoint.DistanceTo(pline2.EndPoint) < dTol)
  158.             {
  159.               //第一曲线开始端入,第二曲线正向加入
  160.               for (int i = pline2.NumberOfVertices - 2; i >= 0; i--)
  161.               {
  162.                 pline.AddVertexAt(0, pline2.GetPoint2dAt(i), 0, 0, 0);
  163.                 pline.SetBulgeAt(0, pline2.GetBulgeAt(i));
  164.               }
  165.             }
  166.             #endregion Polyline:Polyline
  167.           }
  168.           else
  169.           {
  170.             return null;
  171.           }
  172.           if (pline.StartPoint.DistanceTo(pline.EndPoint) < dTol) //如果曲线起点和终点重合,将Closed = true
  173.           {
  174.             pline.Closed = true;
  175.             //即使起点和终点已重合,pline.Closed = true还是会增加一个节点,导致多义线出现零节点
  176.             pline.RemoveVertexAt(pline.NumberOfVertices - 1);
  177.           }
  178.           return pline;
  179.           #endregion Polyline:Line Arc Polyline
  180.         }
  181.         return pline;
  182.       }
  183.       catch (System.Exception ex)
  184.       {
  185.          return null;
  186.       }
  187.     }
  188.     /// <summary>
  189.     /// 判断1,2,3三个点的依次走向为顺时针还是逆时针走向
  190.     /// </summary>
  191.     /// <param name="P1">第一个点</param>
  192.     /// <param name="P2">第二个点</param>
  193.     /// <param name="P3">第三个点</param>
  194.     /// <returns>顺时针返回-1,逆时针返回1,点重合或在一条直线上返回0</returns>
  195.     static public int Clockwise(Point3d P1, Point3d P2, Point3d P3)
  196.     {
  197.       double A = P3.Y - P1.Y;
  198.       double B = P1.X - P3.X;
  199.       double C = -1.0 * A * P1.X - B * P1.Y;
  200.       double d1 = -A * P2.X - B * P2.Y;
  201.       if (d1 == C)
  202.         return 0;
  203.       else if (d1 > C)
  204.         return -1;
  205.       else
  206.         return 1;
  207.     }
  208. public const double pi = 3.141592653589793;
复制代码
提示:pi可以直接调用System.Math.PI获取,:)

评分

参与人数 2威望 +1 明经币 +10 金钱 +20 贡献 +20 激情 +20 收起 理由
ahlzl + 1 【好评】 好程序!
雪山飞狐_lzh + 10 + 20 + 20 + 20 【好评】表扬一下 希望有更精彩的:)

查看全部评分

 楼主| 发表于 2009-6-8 22:12:00 | 显示全部楼层
本帖最后由 作者 于 2009-6-20 16:07:16 编辑

连接两条相连的Spline,Ge曲线还是强大些:)
简单的示例
  1.         public static Spline ConvertNurbCurve3d(NurbCurve3d nc3d)
  2.         {
  3.             DoubleCollection knots = new DoubleCollection();
  4.             foreach (double knot in nc3d.Knots)
  5.             {
  6.                 knots.Add(knot);
  7.             }
  8.             NurbCurve3dData ncdata = nc3d.DefinitionData;
  9.             return
  10.                 new Spline(
  11.                     ncdata.Degree,
  12.                     ncdata.Rational,
  13.                     nc3d.IsClosed(),
  14.                     ncdata.Periodic,
  15.                     ncdata.ControlPoints,
  16.                     knots,
  17.                     ncdata.Weights,
  18.                     0,
  19.                     nc3d.Knots.Tolerance);
  20.         }
  21.         public static NurbCurve3d ConvertNurbCurve3d(Spline spl)
  22.         {
  23.             KnotCollection knots = new KnotCollection();
  24.             foreach (double knot in spl.NurbsData.GetKnots())
  25.             {
  26.                 knots.Add(knot);
  27.             }
  28.             NurbsData ndata = spl.NurbsData;
  29.             return
  30.                 new NurbCurve3d(
  31.                     ndata.Degree,
  32.                     knots,
  33.                     ndata.GetControlPoints(),
  34.                     ndata.Periodic);
  35.         }
  36.         [CommandMethod("t4")]
  37.         public static void Test4()
  38.         {
  39.             PromptSelectionResult res = CadHelper.Editor.GetSelection();
  40.             using (DBTransaction tr = new DBTransaction())
  41.             {
  42.                 Spline c1 = (Spline)tr.GetObject(res.Value[0].ObjectId, OpenMode.ForRead);
  43.                 Spline c2 = (Spline)tr.GetObject(res.Value[1].ObjectId, OpenMode.ForRead);
  44.                 NurbCurve3d nc3d = ConvertNurbCurve3d(c1);
  45.                 nc3d.JoinWith(ConvertNurbCurve3d(c2));
  46.                 Spline spl = ConvertNurbCurve3d(nc3d);
  47.                 tr.OpenCurrentSpace();
  48.                 tr.AddEntity(spl);
  49.             }
  50.         }
打断自相交曲线,以前写过一个巨复杂的:),一百多行代码
使用Ge CurveCurveIntersector3d对象要简单有效的多:)
暂时只有Spline的
  1.         [CommandMethod("t7")]
  2.         public static void Test7()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Database db = doc.Database;
  6.             Editor ed = doc.Editor;
  7.             PromptEntityResult res1 = ed.GetEntity("选择图元1");
  8.             using (DBTransaction tr = new DBTransaction())
  9.             {
  10.                 Spline spl1 = (Spline)tr.GetObject(res1.ObjectId, OpenMode.ForRead);
  11.                 NurbCurve3d nc1 = ConvertDbCurve.ToNurbCurve3d(spl1);
  12.                 CurveCurveIntersector3d cci = new CurveCurveIntersector3d(nc1, nc1, Vector3d.ZAxis);
  13.                 List<double> pars = new List<double>();
  14.                
  15.                 for (int i = 0; i < cci.NumberOfIntersectionPoints; i++)
  16.                 {
  17.                     pars.AddRange(cci.GetIntersectionParameters(i));
  18.                 }
  19.                 if (pars.Count > 0)
  20.                 {
  21.                     pars.Sort();
  22.                     tr.OpenCurrentSpace();
  23.                     tr.AddEntity(spl1.GetSplitCurves(new DoubleCollection(pars.ToArray())));
  24.                     spl1.UpgradeOpen();
  25.                     spl1.Erase(true);
  26.                 }
  27.             }
  28.         }
曲线的不等比缩放
注意,不是所有的曲线都支持,可以直接转换的只有椭圆,样条曲线
圆可以先转换为椭圆
其余的曲线可能需要先转换为Ge样条曲线,再变换矩阵,或取Spline属性
  1.         public static Matrix3d ScaleMatrix(Point3d point, double x, double y, double z)
  2.         {
  3.             double[] matdata = new double[16];
  4.             matdata[0] = x;
  5.             matdata[3] = point.X * (1 - x);
  6.             matdata[5] = y;
  7.             matdata[7] = point.Y * (1 - y);
  8.             matdata[10] = z;
  9.             matdata[11] = point.Z * (1 - z);
  10.             matdata[15] = 1;
  11.             return new Matrix3d(matdata);
  12.         }
  13.         [CommandMethod("t9")]
  14.         public static void Test9()
  15.         {
  16.             Document doc = Application.DocumentManager.MdiActiveDocument;
  17.             Database db = doc.Database;
  18.             Editor ed = doc.Editor;
  19.             PromptEntityResult res1 = ed.GetEntity("选择图元1");
  20.             using (DBTransaction tr = new DBTransaction())
  21.             {
  22.                 Curve curve = (Curve)tr.GetObject(res1.ObjectId, OpenMode.ForWrite);
  23.                 curve.TransformBy(ScaleMatrix(new Point3d(10, 10, 0), 2, 1, 1));
  24.             }
  25.         }
 楼主| 发表于 2009-6-12 00:05:00 | 显示全部楼层
打断自相交曲线,以前写过一个巨复杂的:),一百多行代码
使用Ge CurveCurveIntersector3d对象要简单有效的多:)
  1.         [CommandMethod("t7")]
  2.         public static void Test7()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Database db = doc.Database;
  6.             Editor ed = doc.Editor;
  7.             PromptEntityResult res1 = ed.GetEntity("选择图元1");
  8.             using (DBTransaction tr = new DBTransaction())
  9.             {
  10.                 Spline spl1 = (Spline)tr.GetObject(res1.ObjectId, OpenMode.ForRead);
  11.                 NurbCurve3d nc1 = ConvertDbCurve.ToNurbCurve3d(spl1);
  12.                 CurveCurveIntersector3d cci = new CurveCurveIntersector3d(nc1, nc1, Vector3d.ZAxis);
  13.                 List<double> pars = new List<double>();
  14.                
  15.                 for (int i = 0; i < cci.NumberOfIntersectionPoints; i++)
  16.                 {
  17.                     pars.AddRange(cci.GetIntersectionParameters(i));
  18.                 }
  19.                 if (pars.Count > 0)
  20.                 {
  21.                     pars.Sort();
  22.                     tr.OpenCurrentSpace();
  23.                     tr.AddEntity(spl1.GetSplitCurves(new DoubleCollection(pars.ToArray())));
  24.                     spl1.UpgradeOpen();
  25.                     spl1.Erase(true);
  26.                 }
  27.             }
  28.         }
 楼主| 发表于 2009-6-12 19:54:00 | 显示全部楼层
本帖最后由 作者 于 2009-6-20 16:05:34 编辑

曲线的不等比缩放
注意,不是所有的曲线都支持,可以直接转换的只有椭圆,样条曲线
圆可以先转换为椭圆
其余的曲线可能需要先转换为Ge样条曲线,再变换矩阵,或取Spline属性
  1.         public static Matrix3d ScaleMatrix(Point3d point, double x, double y, double z)
  2.         {
  3.             double[] matdata = new double[16];
  4.             matdata[0] = x;
  5.             matdata[3] = point.X * (1 - x);
  6.             matdata[5] = y;
  7.             matdata[7] = point.Y * (1 - y);
  8.             matdata[10] = z;
  9.             matdata[11] = point.Z * (1 - z);
  10.             matdata[15] = 1;
  11.             return new Matrix3d(matdata);
  12.         }
  13.         [CommandMethod("t9")]
  14.         public static void Test9()
  15.         {
  16.             Document doc = Application.DocumentManager.MdiActiveDocument;
  17.             Database db = doc.Database;
  18.             Editor ed = doc.Editor;
  19.             PromptEntityResult res1 = ed.GetEntity("选择图元1");
  20.             using (DBTransaction tr = new DBTransaction())
  21.             {
  22.                 Curve curve = (Curve)tr.GetObject(res1.ObjectId, OpenMode.ForWrite);
  23.                 curve.TransformBy(ScaleMatrix(new Point3d(10, 10, 0), 2, 1, 1));
  24.             }
  25.         }
  1. 相关资料
  2. 由于用齐次坐标表示,三维几何变换的矩阵是一个4阶方阵,其形式如下:
  3.      1)平移变换
  4.      参照二维的平移变换,我们很容易得到三维平移变换矩阵:
  5.      
  6.      2)缩放变换
  7.     直接考虑相对于参考点(xf,yf,zf)的缩放变换,其步骤为:               A. 将平移到坐标原点处;
  8.      B. 进行缩放变换;
  9.      C. 将参考点(xf,yf,zf)移回原来位置
  10.        则变换矩阵为:
  11.       
  12.     3)绕坐标轴的旋转变换
  13.     三维空间的旋转相对要复杂些,考虑右手坐标系下相对坐标原点绕坐标轴旋转q 角的变换:
  14.      A. 将平移到坐标原点处;
  15.      B. 进行缩放变换;
  16.      C. 将参考点(xf,yf,zf)移回原来位置
  17.        则变换矩阵为:
  18.       
  19.     3)绕坐标轴的旋转变换
  20.     三维空间的旋转相对要复杂些,考虑右手坐标系下相对坐标原点绕坐标轴旋转q 角的变换:
  21.      A. 将平移到坐标原点处;
  22.      B. 进行缩放变换;
  23.      C. 将参考点(xf,yf,zf)移回原来位置
  24.        则变换矩阵为:
  25.       
  26.     3)绕坐标轴的旋转变换
  27.     三维空间的旋转相对要复杂些,考虑右手坐标系下相对坐标原点绕坐标轴旋转q 角的变换:
  28. (xf,yf,zf)的缩放变换,其步骤为:           A. 将平移到坐标原点处;
  29.      B. 进行缩放变换;
  30.      C. 将参考点(xf,yf,zf)移回原来位置
  31.        则变换矩阵为:
  32.       
  33.     3)绕坐标轴的旋转变换
  34.     三维空间的旋转相对要复杂些,考虑右手坐标系下相对坐标原点绕坐标轴旋转q 角的变换:
  35. (xf,yf,zf)移回原来位置
  36.        则变换矩阵为:
  37.       
  38.     3)绕坐标轴的旋转变换
  39.     三维空间的旋转相对要复杂些,考虑右手坐标系下相对坐标原点绕坐标轴旋转q 角的变换:         A.绕x轴旋转
  40.    
  41.   
  42.      B.绕y轴旋转
  43.    
  44.   
  45.      C.绕z轴旋转
  46.    
  47.      
  48.      
  49. 三维空间的平移、旋转及缩放示意图
  50.    4)绕任意轴的旋转变换
  51.    设旋转轴AB由任意一点A(xa,ya,za)及其方向数(a,b,c)定义,
  52.       
  53.    可以通过下列步骤来实现P点的旋转:
  54.      A. 将A点移到坐标原点。
  55.      B. 使AB分别绕X轴、Y轴旋转适当角度与Z轴重合。
  56. AB分别绕X轴、Y轴旋转适当角度与Z轴重合。         
  57.      D.作上述变换的逆操作,使AB回到原来位置。
  58. 是AB在YOZ平面与XOZ平面的投影与Z轴的夹角。
复制代码
发表于 2009-6-17 16:52:00 | 显示全部楼层
“所有曲线打断于点”的程序只是针对line对象有用?我试了cad2008、2010多段线都没打断。
 楼主| 发表于 2009-6-17 17:20:00 | 显示全部楼层

如果有自交点,这个简化版本不支持:)

在自交点打断曲线可以看下三楼的代码

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-23 02:22 , Processed in 0.245739 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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