雪山飞狐_lzh 发表于 2009-5-14 21:47:00

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

本帖最后由 作者 于 2009-6-20 16:04:26 编辑

先发几个简单的例子,抛砖引玉,希望大家也贴上自己的得意之作:)
直线打断,模拟Break命令      
      public static void MyBreakLine()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            //选择直线
            PromptEntityOptions opt1 = new PromptEntityOptions("\nselect a line:");
            opt1.SetRejectMessage("\nerror!");
            opt1.AddAllowedClass(typeof(Line), true);
            PromptEntityResult res1 = ed.GetEntity(opt1);
            if (res1.Status == PromptStatus.OK)
            {
                //选择第二打断点
                PromptPointOptions opt2 = new PromptPointOptions("\nselect second point:");
                opt2.AllowNone = true;
                PromptPointResult res2 = ed.GetPoint(opt2);
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                  Line oldline = (Line)tr.GetObject(res1.ObjectId, OpenMode.ForRead);
                  List<double> pars = new List<double>();
                  Point3d pt1 = oldline.GetClosestPointTo(res1.PickedPoint, false);
                  Point3d pt2 = new Point3d();
                  pars.Add(oldline.GetParameterAtPoint(pt1));
                  BlockTableRecord btr =
                        (BlockTableRecord)tr.GetObject(
                            db.CurrentSpaceId,
                            OpenMode.ForWrite,
                            false);
                  DBObjectCollection objs;
                  //两种情况
                  if (res2.Status == PromptStatus.OK)
                  {
                        //如果选择了第二点,获取直线上两点的param值,并排序
                        pt2 = oldline.GetClosestPointTo(res2.Value, false);
                        pars.Add(oldline.GetParameterAtPoint(pt2));
                        pars.Sort();
                        //按param值打断曲线
                        objs = oldline.GetSplitCurves(new DoubleCollection(pars.ToArray()));
                        foreach (Line newline in objs)
                        {
                            //如果生成的直线起点或终点不是选择的打断点,把它加入数据库
                            if ((newline.StartPoint != pt1 && newline.StartPoint != pt2) ^ (newline.EndPoint != pt1 && newline.EndPoint != pt2))
                            {
                              btr.AppendEntity(newline);
                              tr.AddNewlyCreatedDBObject(newline, true);
                            }
                        }
                  }
                  else
                  {
                        //如果没有选择第二点,就按第一点打断
                        objs = oldline.GetSplitCurves(new DoubleCollection(pars.ToArray()));
                        foreach (Line newline in objs)
                        {
                            btr.AppendEntity(newline);
                            tr.AddNewlyCreatedDBObject(newline, true);
                        }
                  }
                  oldline.UpgradeOpen();
                  oldline.Erase();
                  tr.Commit();
                }
            }
      }
所有曲线打断于点
      
      public static void BreakAllCurve()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            //选择曲线
            PromptSelectionResult res = ed.GetSelection(new PromptSelectionOptions(), new SelectionFilter(new TypedValue[] { new TypedValue(0, "*Line,Arc,Circle,Ellipse") }));
            ObjectId[] ids = res.Value.GetObjectIds();
            ObjectIdCollection oldids = new ObjectIdCollection();
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr =
                  (BlockTableRecord)tr.GetObject(
                        db.CurrentSpaceId,
                        OpenMode.ForWrite,
                        false);
                //遍历选择集
                foreach (ObjectId i in ids)
                {
                  List<double> pars = new List<double>();
                  Curve iCurve = (Curve)tr.GetObject(i, OpenMode.ForRead);
                  //获取曲线与其他曲线的交点处的param值集合,按该集合打断曲线
                  foreach (ObjectId j in ids)
                  {
                        if (i != j)
                        {
                            Curve jCurve = (Curve)tr.GetObject(j, OpenMode.ForRead);
                            Point3dCollection iwpnts = new Point3dCollection();
                            iCurve.IntersectWith(jCurve, Intersect.OnBothOperands, iwpnts, 0, 0);
                            foreach (Point3d p in iwpnts)
                            {
                              pars.Add(iCurve.GetParameterAtPoint(p));
                            }
                        }
                  }
                  //如果有交点,按param值排序并打断
                  if (pars.Count > 0)
                  {
                        pars.Sort();
                        try
                        {
                            //将子曲线加入数据库,原曲线加入oldids集合
                            foreach (Curve c in iCurve.GetSplitCurves(new DoubleCollection(pars.ToArray())))
                            {
                              btr.AppendEntity(c);
                              tr.AddNewlyCreatedDBObject(c, true);
                            }
                            oldids.Add(i);
                        }
                        catch
                        { }
                  }
                }
                foreach (ObjectId id in oldids)
                {
                  tr.GetObject(id, OpenMode.ForWrite).Erase();
                }
                tr.Commit();
            }
      }简单的直线倒角

      
      public void daojiao()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptDoubleResult resgetdist = ed.GetDistance("\n请输入倒角距离");
            if (resgetdist.Status == PromptStatus.OK)
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                  double dist = resgetdist.Value;
                  PromptEntityOptions optgetent = new PromptEntityOptions("\n请选择第一条直线:");
                  optgetent.SetRejectMessage("\n错误的选择");
                  optgetent.AddAllowedClass(typeof(Line), true);
                  PromptEntityResult resgetent = ed.GetEntity(optgetent);
                  if (resgetent.Status == PromptStatus.OK)
                  {
                        ObjectId id1 = resgetent.ObjectId;
                        Line line1 = (Line)tr.GetObject(id1, OpenMode.ForWrite);
                        line1.Highlight();
                        Point3d pt1 = resgetent.PickedPoint;
                        optgetent.Message = "\n请选择第二条直线:";
                        resgetent = ed.GetEntity(optgetent);
                        if (resgetent.Status == PromptStatus.OK)
                        {
                            ObjectId id2 = resgetent.ObjectId;
                            Point3d pt2 = resgetent.PickedPoint;
                            Line line2 = (Line)tr.GetObject(id2, OpenMode.ForWrite);
                            pt1 = line1.GetClosestPointTo(pt1, false);
                            pt2 = line2.GetClosestPointTo(pt2, false);
                            //获取两直线交点
                            Point3dCollection pts = new Point3dCollection();
                            line1.IntersectWith(line2, Intersect.ExtendBoth, pts, 0, 0);
                            //如果有交点
                            if (pts.Count == 1)
                            {
                              Point3d pt = pts;
                              Plane plane = new Plane();
                              //判断点选在直线的哪一侧(是否靠近起点)
                              Vector3d v1,v2;
                              v1 = line1.StartPoint - pt;
                              v2 = line1.EndPoint - pt;
                              bool atstart1 = false;
                              if (v1.Length != 0)
                              {
                                    atstart1 = Tolerance.Equals(v1.AngleOnPlane(plane), (pt1 - pt).AngleOnPlane(plane));
                                    if (Tolerance.Equals(v1.AngleOnPlane(plane), v2.AngleOnPlane(plane)))
                                    {
                                        atstart1 = v1.Length > v2.Length;
                                    }
                              }
                              v1 = line2.StartPoint - pt;
                              v2 = line2.EndPoint - pt;
                              bool atstart2 = false;
                              if (v1.Length != 0)
                              {
                                    atstart2 = Tolerance.Equals(v1.AngleOnPlane(plane), (pt2 - pt).AngleOnPlane(plane));
                                    if (Tolerance.Equals(v1.AngleOnPlane(plane), v2.AngleOnPlane(plane)))
                                    {
                                        atstart2 = v1.Length > v2.Length;
                                    }
                              }
                              // 判断被选择段是否可以倒角
                              Point3d pt3 = atstart1 ? line1.StartPoint : line1.EndPoint;
                              Point3d pt4 = atstart2 ? line2.StartPoint : line2.EndPoint;
                              Vector3d vec1 = pt3 - pt;
                              Vector3d vec2 = pt4 - pt;
                              if (vec1.Length >= dist && vec2.Length >= dist)
                              {
                                    //计算倒角点
                                    vec1 = vec1.GetNormal() * dist;
                                    vec2 = vec2.GetNormal() * dist;
                                    pt3 = pt + vec1;
                                    pt4 = pt + vec2;
                                    //按点选的位置改变原直线
                                    if (atstart1)
                                    {
                                        line1.EndPoint = pt3;
                                    }
                                    else
                                    {
                                        line1.StartPoint = pt3;
                                    }
                                    if (line1.Length == 0)
                                    {
                                        line1.Erase();
                                    }
                                    if (atstart2)
                                    {
                                        line2.EndPoint = pt4;
                                    }
                                    else
                                    {
                                        line2.StartPoint = pt4;
                                    }
                                    if (line2.Length == 0)
                                    {
                                        line2.Erase();
                                    }
                                    //生成倒角线
                                    Line line = new Line(pt3, pt4);
                                    BlockTableRecord btr =
                                        (BlockTableRecord)tr.GetObject(
                                          db.CurrentSpaceId,
                                          OpenMode.ForWrite,
                                          false);
                                    btr.AppendEntity(line);
                                    tr.AddNewlyCreatedDBObject(line, true);
                              }
                              else
                              {
                                    ed.WriteMessage("\n距离太大\n*无效");
                              }
                            }
                            else
                            {
                              ed.WriteMessage("\n直线平行\n*无效");
                            }
                        }
                  }
                  tr.Commit();
                }
            }
      }

找回hatch的边界,
填充边界是一组Ge曲线,所以需要转换为Db曲线
圆弧和椭圆的处理不太好,Ge库实体的方法有点晕哈,期待高人操刀
      
      public static void HatchLoop()
      {
            PromptSelectionResult res = CadHelper.Editor.GetSelection(
                new PromptSelectionOptions(),
                new SelectionFilter(new TypedValue[] { new TypedValue(0, "Hatch") }));
            if (res.Status != PromptStatus.OK)
                return;
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr =
                  (BlockTableRecord)tr.GetObject(
                        db.CurrentSpaceId,
                        OpenMode.ForWrite,
                        false);
                foreach (ObjectId id in res.Value.GetObjectIds())
                {
                  //获取Hatch对象的Ocs
                  Hatch h = (Hatch)tr.GetObject(id, OpenMode.ForRead);
                  Matrix3d mat = Matrix3d.PlaneToWorld(h.GetPlane());
                  //遍历边界集合,通常边界有两种形式:多义线 或 曲线集合
                  for (int i = 0; i < h.NumberOfLoops; i++)
                  {
                        HatchLoop loop = h.GetLoopAt(i);
                        //如果是多义线,转换为Db库的多义线
                        if (loop.IsPolyline)
                        {
                            BulgeVertexCollection bvs = loop.Polyline;
                            Polyline pl = new Polyline();
                            for (int j = 0; j < bvs.Count; j++)
                            {
                              BulgeVertex bv = bvs;
                              pl.AddVertexAt(j, bv.Vertex, bv.Bulge, 0, 0);
                            }
                            pl.TransformBy(mat);
                            btr.AppendEntity(pl);
                            tr.AddNewlyCreatedDBObject(pl, true);
                        }
                        //否则,遍历曲线集合,依次转化为Db库的曲线
                        else
                        {
                            foreach (Curve2d curve in loop.Curves)
                            {
                              Curve c = CadHelper.ConvertCurve2d(curve, mat);
                              btr.AppendEntity(c);
                              tr.AddNewlyCreatedDBObject(c, true);
                            }
                        }
                  }
                }
                tr.Commit();
            }
      }

CadHelper类
using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
namespace TlsCad
{

    public static class CadHelper
    {
      #region Curve
      //Ge2d曲线按Ocs转化为Db曲线
      public static Curve ConvertCurve2d(Curve2d curve, Matrix3d mat)
      {
            //直线
            if (curve is LineSegment2d)
            {
                return ConvertLineSegment2d((LineSegment2d)curve, mat);
            }
            //样条曲线
            else if (curve is NurbCurve2d)
            {
                return ConvertNurbCurve2d((NurbCurve2d)curve, mat);
            }
            //椭圆
            else if (curve is EllipticalArc2d)
            {
                return ConvertEllipticalArc2d((EllipticalArc2d)curve, mat);
            }
            //圆弧
            else if (curve is CircularArc2d)
            {
                return ConvertCircularArc2d((CircularArc2d)curve, mat);
            }
            else
            {
                //待续
                return null;
            }
      }

      #region ConvertCurve2d
      //圆弧
      public static Curve ConvertCircularArc2d(CircularArc2d ca2d, Matrix3d mat)
      {
            Curve c = ConvertCircularArc2d(ca2d);
            c.TransformBy(mat);
            return c;
      }
      public static Curve ConvertCircularArc2d(CircularArc2d ca2d)
      {
            if (ca2d.IsClosed())
            {
                return ConvertCircular2d(ca2d);
            }
            else
            {
                return ConvertArc2d(ca2d);
            }
      }
      public static Circle ConvertCircular2d(CircularArc2d c2d)
      {
            return
                new Circle(
                  new Point3d(new Plane(), c2d.Center),
                  new Vector3d(0, 0, 1),
                  c2d.Radius);
      }
      public static Arc ConvertArc2d(CircularArc2d a2d)
      {
            double startangle, endangle;
            if (a2d.IsClockWise)
            {
                startangle = (a2d.EndPoint - a2d.Center).Angle;
                endangle = (a2d.StartPoint - a2d.Center).Angle;
            }
            else
            {
                startangle = (a2d.StartPoint - a2d.Center).Angle;
                endangle = (a2d.EndPoint - a2d.Center).Angle;
            }
            return
                new Arc(
                  new Point3d(new Plane(), a2d.Center),
                  new Vector3d(0, 0, 1),
                  a2d.Radius,
                  startangle,
                  endangle);
      }
      //椭圆弧
      public static Ellipse ConvertEllipticalArc2d(EllipticalArc2d ea2d, Matrix3d mat)
      {
            Ellipse e = ConvertEllipticalArc2d(ea2d);
            e.TransformBy(mat);
            return e;
      }
      public static Ellipse ConvertEllipticalArc2d(EllipticalArc2d ea2d)
      {
            double startangle, endangle;
            if (ea2d.IsCircular())
            {
                startangle = 0;
                endangle = Math.PI * 2;
            }
            else
            {
                double majorangle = ea2d.MajorAxis.Angle;
                if (ea2d.IsClockWise)
                {
                  startangle = (ea2d.EndPoint - ea2d.Center).Angle - majorangle;
                  endangle = (ea2d.StartPoint - ea2d.Center).Angle - majorangle;
                }
                else
                {
                  startangle = (ea2d.StartPoint - ea2d.Center).Angle - majorangle;
                  endangle = (ea2d.EndPoint - ea2d.Center).Angle - majorangle;
                }
            }
            return
                new Ellipse(
                  new Point3d(new Plane(), ea2d.Center),
                  new Vector3d(0, 0, 1),
                  new Vector3d(new Plane(), ea2d.MajorAxis) * ea2d.MajorRadius,
                  ea2d.MinorRadius / ea2d.MajorRadius,
                  startangle,
                  endangle);
      }
      //直线
      public static Line ConvertLineSegment2d(LineSegment2d ls2d, Matrix3d mat)
      {
            Line l = ConvertLineSegment2d(ls2d);
            l.TransformBy(mat);
            return l;
      }
      public static Line ConvertLineSegment2d(LineSegment2d ls2d)
      {
            Plane plane = new Plane();
            return
                new Line(
                  new Point3d(plane, ls2d.StartPoint),
                  new Point3d(plane, ls2d.EndPoint));
      }
      //样条曲线
      public static Spline ConvertNurbCurve2d(NurbCurve2d nc2d, Matrix3d mat)
      {
            Spline spl = ConvertNurbCurve2d(nc2d);
            spl.TransformBy(mat);
            return spl;
      }
      public static Spline ConvertNurbCurve2d(NurbCurve2d nc2d)
      {
            int i;
            Plane plane = new Plane();
            Point3dCollection ctlpnts = new Point3dCollection();
            for (i = 0; i < nc2d.NumControlPoints; i++)
            {
                ctlpnts.Add(new Point3d(plane, nc2d.GetControlPointAt(i)));
            }
            DoubleCollection knots = new DoubleCollection();
            foreach (double knot in nc2d.Knots)
            {
                knots.Add(knot);
            }
            DoubleCollection weights = new DoubleCollection();
            for (i = 0; i < nc2d.NumWeights; i++)
            {
                weights.Add(nc2d.GetWeightAt(i));
            }
            return
                new Spline(
                  nc2d.Degree,
                  false,
                  false,
                  false,
                  ctlpnts,
                  knots,
                  weights,
                  0,
                  nc2d.Knots.Tolerance);
      }
      #endregion
      #endregion
    }
}

xiongdi6k 发表于 2020-4-3 09:43:30

都是知识点线画上以后要学习

tender138 发表于 2024-11-6 02:23:25

非常感谢飞狐大神,又从你的帖子里学到了好多知识!

xuyinli6283420 发表于 2018-8-9 15:36:27

非常感谢飞狐大神,又从你的帖子里学到了好多知识!

雪山飞狐_lzh 发表于 2009-5-14 22:18:00

本帖最后由 作者 于 2009-5-23 14:02:47 编辑

所有曲线打断于点
      
      public static void BreakAllCurve()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            //选择曲线
            PromptSelectionResult res = ed.GetSelection(new PromptSelectionOptions(), new SelectionFilter(new TypedValue[] { new TypedValue(0, "*Line,Arc,Circle,Ellipse") }));
            ObjectId[] ids = res.Value.GetObjectIds();

            ObjectIdCollection oldids = new ObjectIdCollection();
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr =
                  (BlockTableRecord)tr.GetObject(
                        db.CurrentSpaceId,
                        OpenMode.ForWrite,
                        false);
                //遍历选择集
                foreach (ObjectId i in ids)
                {
                  List<double> pars = new List<double>();
                  Curve iCurve = (Curve)tr.GetObject(i, OpenMode.ForRead);
                  //获取曲线与其他曲线的交点处的param值集合,按该集合打断曲线
                  foreach (ObjectId j in ids)
                  {
                        if (i != j)
                        {
                            Curve jCurve = (Curve)tr.GetObject(j, OpenMode.ForRead);
                            Point3dCollection iwpnts = new Point3dCollection();
                            iCurve.IntersectWith(jCurve, Intersect.OnBothOperands, iwpnts, 0, 0);
                            foreach (Point3d p in iwpnts)
                            {
                              pars.Add(iCurve.GetParameterAtPoint(p));
                            }
                        }
                  }
                  //如果有交点,按param值排序并打断
                  if (pars.Count > 0)
                  {
                        pars.Sort();
                        try
                        {
                            //将子曲线加入数据库,原曲线加入oldids集合
                            foreach (Line newline in iCurve.GetSplitCurves(new DoubleCollection(pars.ToArray())))
                            {
                              btr.AppendEntity(newline);
                              tr.AddNewlyCreatedDBObject(newline, true);
                            }
                            oldids.Add(i);
                        }
                        catch
                        { }
                  }
                }
                foreach (ObjectId id in oldids)
                {
                  tr.GetObject(id, OpenMode.ForWrite).Erase();
                }
                tr.Commit();
            }
      }

雪山飞狐_lzh 发表于 2009-5-15 13:13:00

本帖最后由 作者 于 2009-5-23 14:13:00 编辑

找回hatch的边界,
填充边界是一组Ge曲线,所以需要转换为Db曲线
圆弧和椭圆的处理不太好,Ge库实体的方法有点晕哈,期待高人操刀
      
      public static void HatchLoop()
      {
            PromptSelectionResult res = CadHelper.Editor.GetSelection(
                new PromptSelectionOptions(),
                new SelectionFilter(new TypedValue[] { new TypedValue(0, "Hatch") }));
            if (res.Status != PromptStatus.OK)
                return;
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTableRecord btr =
                  (BlockTableRecord)tr.GetObject(
                        db.CurrentSpaceId,
                        OpenMode.ForWrite,
                        false);
                foreach (ObjectId id in res.Value.GetObjectIds())
                {
                  //获取Hatch对象的Ocs
                  Hatch h = (Hatch)tr.GetObject(id, OpenMode.ForRead);
                  Matrix3d mat = Matrix3d.PlaneToWorld(h.GetPlane());
                  //遍历边界集合,通常边界有两种形式:多义线 或 曲线集合
                  for (int i = 0; i < h.NumberOfLoops; i++)
                  {
                        HatchLoop loop = h.GetLoopAt(i);
                        //如果是多义线,转换为Db库的多义线
                        if (loop.IsPolyline)
                        {
                            BulgeVertexCollection bvs = loop.Polyline;
                            Polyline pl = new Polyline();
                            for (int j = 0; j < bvs.Count; j++)
                            {
                              BulgeVertex bv = bvs;
                              pl.AddVertexAt(j, bv.Vertex, bv.Bulge, 0, 0);
                            }
                            pl.TransformBy(mat);
                            btr.AppendEntity(pl);
                            tr.AddNewlyCreatedDBObject(pl, true);
                        }
                        //否则,遍历曲线集合,依次转化为Db库的曲线
                        else
                        {
                            foreach (Curve2d curve in loop.Curves)
                            {
                              Curve c = CadHelper.ConvertCurve2d(curve, mat);
                              btr.AppendEntity(c);
                              tr.AddNewlyCreatedDBObject(c, true);
                            }
                        }
                  }
                }
                tr.Commit();
            }
      }

CadHelper类
using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
namespace TlsCad
{

    public static class CadHelper
    {
      #region Curve
      //Ge2d曲线按Ocs转化为Db曲线
      public static Curve ConvertCurve2d(Curve2d curve, Matrix3d mat)
      {
            //直线
            if (curve is LineSegment2d)
            {
                return ConvertLineSegment2d((LineSegment2d)curve, mat);
            }
            //样条曲线
            else if (curve is NurbCurve2d)
            {
                return ConvertNurbCurve2d((NurbCurve2d)curve, mat);
            }
            //椭圆
            else if (curve is EllipticalArc2d)
            {
                return ConvertEllipticalArc2d((EllipticalArc2d)curve, mat);
            }
            //圆弧
            else if (curve is CircularArc2d)
            {
                return ConvertCircularArc2d((CircularArc2d)curve, mat);
            }
            else
            {
                //待续
                return null;
            }
      }

      #region ConvertCurve2d
      //圆弧
      public static Curve ConvertCircularArc2d(CircularArc2d ca2d, Matrix3d mat)
      {
            Curve c = ConvertCircularArc2d(ca2d);
            c.TransformBy(mat);
            return c;
      }
      public static Curve ConvertCircularArc2d(CircularArc2d ca2d)
      {
            if (ca2d.IsClosed())
            {
                return ConvertCircular2d(ca2d);
            }
            else
            {
                return ConvertArc2d(ca2d);
            }
      }
      public static Circle ConvertCircular2d(CircularArc2d c2d)
      {
            return
                new Circle(
                  new Point3d(new Plane(), c2d.Center),
                  new Vector3d(0, 0, 1),
                  c2d.Radius);
      }
      public static Arc ConvertArc2d(CircularArc2d a2d)
      {
            double startangle, endangle;
            if (a2d.IsClockWise)
            {
                startangle = (a2d.EndPoint - a2d.Center).Angle;
                endangle = (a2d.StartPoint - a2d.Center).Angle;
            }
            else
            {
                startangle = (a2d.StartPoint - a2d.Center).Angle;
                endangle = (a2d.EndPoint - a2d.Center).Angle;
            }
            return
                new Arc(
                  new Point3d(new Plane(), a2d.Center),
                  new Vector3d(0, 0, 1),
                  a2d.Radius,
                  startangle,
                  endangle);
      }
      //椭圆弧
      public static Ellipse ConvertEllipticalArc2d(EllipticalArc2d ea2d, Matrix3d mat)
      {
            Ellipse e = ConvertEllipticalArc2d(ea2d);
            e.TransformBy(mat);
            return e;
      }
      public static Ellipse ConvertEllipticalArc2d(EllipticalArc2d ea2d)
      {
            double startangle, endangle;
            if (ea2d.IsCircular())
            {
                startangle = 0;
                endangle = Math.PI * 2;
            }
            else
            {
                double majorangle = ea2d.MajorAxis.Angle;
                if (ea2d.IsClockWise)
                {
                  startangle = (ea2d.EndPoint - ea2d.Center).Angle - majorangle;
                  endangle = (ea2d.StartPoint - ea2d.Center).Angle - majorangle;
                }
                else
                {
                  startangle = (ea2d.StartPoint - ea2d.Center).Angle - majorangle;
                  endangle = (ea2d.EndPoint - ea2d.Center).Angle - majorangle;
                }
            }
            return
                new Ellipse(
                  new Point3d(new Plane(), ea2d.Center),
                  new Vector3d(0, 0, 1),
                  new Vector3d(new Plane(), ea2d.MajorAxis) * ea2d.MajorRadius,
                  ea2d.MinorRadius / ea2d.MajorRadius,
                  startangle,
                  endangle);
      }
      //直线
      public static Line ConvertLineSegment2d(LineSegment2d ls2d, Matrix3d mat)
      {
            Line l = ConvertLineSegment2d(ls2d);
            l.TransformBy(mat);
            return l;
      }
      public static Line ConvertLineSegment2d(LineSegment2d ls2d)
      {
            Plane plane = new Plane();
            return
                new Line(
                  new Point3d(plane, ls2d.StartPoint),
                  new Point3d(plane, ls2d.EndPoint));
      }
      //样条曲线
      public static Spline ConvertNurbCurve2d(NurbCurve2d nc2d, Matrix3d mat)
      {
            Spline spl = ConvertNurbCurve2d(nc2d);
            spl.TransformBy(mat);
            return spl;
      }
      public static Spline ConvertNurbCurve2d(NurbCurve2d nc2d)
      {
            int i;
            Plane plane = new Plane();
            Point3dCollection ctlpnts = new Point3dCollection();
            for (i = 0; i < nc2d.NumControlPoints; i++)
            {
                ctlpnts.Add(new Point3d(plane, nc2d.GetControlPointAt(i)));
            }
            DoubleCollection knots = new DoubleCollection();
            foreach (double knot in nc2d.Knots)
            {
                knots.Add(knot);
            }
            DoubleCollection weights = new DoubleCollection();
            for (i = 0; i < nc2d.NumWeights; i++)
            {
                weights.Add(nc2d.GetWeightAt(i));
            }
            return
                new Spline(
                  nc2d.Degree,
                  false,
                  false,
                  false,
                  ctlpnts,
                  knots,
                  weights,
                  0,
                  nc2d.Knots.Tolerance);
      }
      #endregion
      #endregion
    }
}

雪山飞狐_lzh 发表于 2009-5-16 16:37:00

本帖最后由 作者 于 2009-5-16 17:57:20 编辑

简单的直线倒角

      
      public void daojiao()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptDoubleResult resgetdist = ed.GetDistance("\n请输入倒角距离");
            if (resgetdist.Status == PromptStatus.OK)
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                  double dist = resgetdist.Value;
                  PromptEntityOptions optgetent = new PromptEntityOptions("\n请选择第一条直线:");
                  optgetent.SetRejectMessage("\n错误的选择");
                  optgetent.AddAllowedClass(typeof(Line), true);
                  PromptEntityResult resgetent = ed.GetEntity(optgetent);
                  if (resgetent.Status == PromptStatus.OK)
                  {
                        ObjectId id1 = resgetent.ObjectId;
                        Line line1 = (Line)tr.GetObject(id1, OpenMode.ForWrite);
                        line1.Highlight();
                        Point3d pt1 = resgetent.PickedPoint;
                        optgetent.Message = "\n请选择第二条直线:";
                        resgetent = ed.GetEntity(optgetent);
                        if (resgetent.Status == PromptStatus.OK)
                        {
                            ObjectId id2 = resgetent.ObjectId;
                            Point3d pt2 = resgetent.PickedPoint;
                            Line line2 = (Line)tr.GetObject(id2, OpenMode.ForWrite);
                            pt1 = line1.GetClosestPointTo(pt1, false);
                            pt2 = line2.GetClosestPointTo(pt2, false);
                            //获取两直线交点
                            Point3dCollection pts = new Point3dCollection();
                            line1.IntersectWith(line2, Intersect.ExtendBoth, pts, 0, 0);
                            //如果有交点
                            if (pts.Count == 1)
                            {
                              Point3d pt = pts;
                              Plane plane = new Plane();
                              //判断点选在直线的哪一侧(是否靠近起点)
                              Vector3d v1,v2;
                              v1 = line1.StartPoint - pt;
                              v2 = line1.EndPoint - pt;
                              bool atstart1 = false;
                              if (v1.Length != 0)
                              {
                                    atstart1 = Tolerance.Equals(v1.AngleOnPlane(plane), (pt1 - pt).AngleOnPlane(plane));
                                    if (Tolerance.Equals(v1.AngleOnPlane(plane), v2.AngleOnPlane(plane)))
                                    {
                                        atstart1 = v1.Length > v2.Length;
                                    }
                              }
                              v1 = line2.StartPoint - pt;
                              v2 = line2.EndPoint - pt;
                              bool atstart2 = false;
                              if (v1.Length != 0)
                              {
                                    atstart2 = Tolerance.Equals(v1.AngleOnPlane(plane), (pt2 - pt).AngleOnPlane(plane));
                                    if (Tolerance.Equals(v1.AngleOnPlane(plane), v2.AngleOnPlane(plane)))
                                    {
                                        atstart2 = v1.Length > v2.Length;
                                    }
                              }
                              // 判断被选择段是否可以倒角
                              Point3d pt3 = atstart1 ? line1.StartPoint : line1.EndPoint;
                              Point3d pt4 = atstart2 ? line2.StartPoint : line2.EndPoint;
                              Vector3d vec1 = pt3 - pt;
                              Vector3d vec2 = pt4 - pt;
                              if (vec1.Length >= dist && vec2.Length >= dist)
                              {
                                    //计算倒角点
                                    vec1 = vec1.GetNormal() * dist;
                                    vec2 = vec2.GetNormal() * dist;
                                    pt3 = pt + vec1;
                                    pt4 = pt + vec2;
                                    //按点选的位置改变原直线
                                    if (atstart1)
                                    {
                                        line1.EndPoint = pt3;
                                    }
                                    else
                                    {
                                        line1.StartPoint = pt3;
                                    }
                                    if (line1.Length == 0)
                                    {
                                        line1.Erase();
                                    }
                                    if (atstart2)
                                    {
                                        line2.EndPoint = pt4;
                                    }
                                    else
                                    {
                                        line2.StartPoint = pt4;
                                    }
                                    if (line2.Length == 0)
                                    {
                                        line2.Erase();
                                    }
                                    //生成倒角线
                                    Line line = new Line(pt3, pt4);
                                    BlockTableRecord btr =
                                        (BlockTableRecord)tr.GetObject(
                                          db.CurrentSpaceId,
                                          OpenMode.ForWrite,
                                          false);
                                    btr.AppendEntity(line);
                                    tr.AddNewlyCreatedDBObject(line, true);
                              }
                              else
                              {
                                    ed.WriteMessage("\n距离太大\n*无效");
                              }
                            }
                            else
                            {
                              ed.WriteMessage("\n直线平行\n*无效");
                            }
                        }
                  }
                  tr.Commit();
                }
            }
      }

sieben 发表于 2009-5-18 08:54:00

仅以此表示对新任版主的支持!    /// <summary>
    /// 将Line Arc LWPolyline 编辑成LWPolyline,能连接在一起的连接起来
    /// 要求端点相接
    /// Version : 2007.09.19
    /// </summary>
    /// <param name="cur1">第一曲线,若两条曲线连接成一条,则新曲线使用第一曲线一般属性(有例外),不应该为null</param>
    /// <param name="cur2">第二曲线,可以为null,这时是编辑单个实体</param>
    /// <param name="dTol">一个距离数值,用于作为判断两点重合的标准</param>
    /// <returns>成功返回Polyline,否则返回null</returns>
    public static Polyline JoinPolyline(Curve cur1, Curve cur2, double dTol)
    {
      try
      {      
      Polyline pline = null;
      if (cur1 == null || cur1.Closed) return null;
      if (!cur1.GetType().Equals(typeof(Polyline)))
      {
          #region !Polyline:Line Arc Polyline
          if (cur2 != null && cur2.GetType().Equals(typeof(Polyline)))
          {//第一曲线为非Polyline,而第二曲线为Polyline,这时以第二曲线作为第一曲线重新调用函数,此举只为减少代码
            return JoinPolyline(cur2, cur1, dTol);
          }
          pline = new Polyline();
          if (cur1.GetType().Equals(typeof(Line)))//Line:?
          {//曲线为Line,使用其数据生成一个Polyline
            Line line = (Line)cur1;
            pline.AddVertexAt(0, new Point2d(line.StartPoint.X, line.StartPoint.Y), 0, 0, 0);
            pline.AddVertexAt(1, new Point2d(line.EndPoint.X, line.EndPoint.Y), 0, 0, 0);
            pline.SetPropertiesFrom(line);//使用原来实体属性
            if (cur2 != null)//若第二曲线不为空,则试图连接两者
            pline = JoinPolyline(pline, cur2, dTol);
            return pline;//将新生成的多义线提交到数据库
          }
          else if (cur1.GetType().Equals(typeof(Arc)))//Arc:?
          {//曲线为Line,使用其数据生成一个Polyline   
            Arc arc = (Arc)cur1;
            Point3d p1 = arc.GetPointAtParameter(arc.EndParam * 0.5 + arc.StartParam * 0.5);
            double dltAng = arc.EndAngle - arc.StartAngle;
            if (dltAng < 0.0) dltAng += pi * 2;//圆弧的结束角比开始角大时
            double bulge = Math.Tan(dltAng / 4.0);
            if (Clockwise(arc.StartPoint, p1, arc.EndPoint) == -1)//根据圆弧的时钟走向确定凸度正负
            bulge = -bulge;
            pline.AddVertexAt(0, new Point2d(arc.StartPoint.X, arc.StartPoint.Y), bulge, 0, 0);
            pline.AddVertexAt(1, new Point2d(arc.EndPoint.X, arc.EndPoint.Y), 0, 0, 0);
            pline.SetPropertiesFrom(arc);//使用原来实体属性
            if (cur2 != null)//若第二曲线不为空,则试图连接两者
            pline = JoinPolyline(pline, cur2, dTol);
            return pline;//将新生成的多义线提交到数据库
          }
          else
          {//本函数只处理Line Arc Polyline 三种类型曲线         
            return null;
          }
          #endregion !Polyline:Line Arc Polyline
      }
      else if (cur1.GetType().Equals(typeof(Polyline)))
      {
          #region Polyline:Line Arc Polyline
          pline = (Polyline)cur1;
          if (pline.StartPoint.DistanceTo(pline.EndPoint) < dTol)
          {//曲线的起点和终点重合,将其封闭属性设置为true
            if (!pline.Closed)
            pline.Closed = true;
            return pline;
          }
          if (cur2 != null && cur2.GetType().Equals(typeof(Line)))
          {//第二曲线为Line,将其加入到多义线里,需注意是加入直线的远点
            #region Polyline:Line
            Line line = (Line)cur2;
            if (pline.EndPoint.DistanceTo(line.StartPoint) < dTol)
            {
            pline.AddVertexAt(pline.NumberOfVertices, new Point2d(line.EndPoint.X, line.EndPoint.Y), 0, 0, 0);
            }
            else if (pline.EndPoint.DistanceTo(line.EndPoint) < dTol)
            {
            pline.AddVertexAt(pline.NumberOfVertices, new Point2d(line.StartPoint.X, line.StartPoint.Y), 0, 0, 0);
            }
            else if (pline.StartPoint.DistanceTo(line.StartPoint) < dTol)
            {
            pline.AddVertexAt(0, new Point2d(line.EndPoint.X, line.EndPoint.Y), 0, 0, 0);
            }
            else if (pline.StartPoint.DistanceTo(line.EndPoint) < dTol)
            {
            pline.AddVertexAt(0, new Point2d(line.StartPoint.X, line.StartPoint.Y), 0, 0, 0);
            }
            #endregion Polyline:Line
          }
          else if (cur2 != null && cur2.GetType().Equals(typeof(Arc)))
          {
            #region Polyline:Arc
            //第二曲线为Arc,将其加入到多义线里,需注意凸度的计算及正负
            //凸度的大小由圆弧的圆周角计算可得,
            //凸度的正负先根据圆弧的时钟走向得到一个值,然后在根据圆弧的近点,中点,远点三点的时钟走向
            //还有在Polyline里是后加入还是前插入来最终确定正负
            Arc arc = (Arc)cur2;
            Point3d p1 = arc.GetPointAtParameter(arc.EndParam * 0.5 + arc.StartParam * 0.5);
            double dltAng = arc.EndAngle - arc.StartAngle;
            if (dltAng < 0.0) dltAng += pi * 2;
            double bulge = Math.Tan(dltAng / 4.0);
            if (pline.EndPoint.DistanceTo(arc.StartPoint) < dTol)
            {//末端接入,根据圆弧近点,中点,远点确定凸度正负
            if (Clockwise(arc.StartPoint, p1, arc.EndPoint) == -1)
                bulge = -bulge;
            pline.AddVertexAt(pline.NumberOfVertices, new Point2d(arc.EndPoint.X, arc.EndPoint.Y), 0, 0, 0);
            pline.SetBulgeAt(pline.NumberOfVertices - 2, bulge);//注意凸度段序号
            }
            else if (pline.EndPoint.DistanceTo(arc.EndPoint) < dTol)
            {//末端接入,根据圆弧近点,中点,远点确定凸度正负
            if (Clockwise(arc.EndPoint, p1, arc.StartPoint) == -1)
                bulge = -bulge;
            pline.AddVertexAt(pline.NumberOfVertices, new Point2d(arc.StartPoint.X, arc.StartPoint.Y), 0, 0, 0);
            pline.SetBulgeAt(pline.NumberOfVertices - 2, bulge);
            }
            else if (pline.StartPoint.DistanceTo(arc.StartPoint) < dTol)
            {//开始端接入,根据圆弧远点,中点,近点确定凸度正负
            if (Clockwise(arc.EndPoint, p1, arc.StartPoint) == -1)
                bulge = -bulge;
            pline.AddVertexAt(0, new Point2d(arc.EndPoint.X, arc.EndPoint.Y), bulge, 0, 0);
            }
            else if (pline.StartPoint.DistanceTo(arc.EndPoint) < dTol)
            {//开始端接入,根据圆弧远点,中点,近点确定凸度正负
            if (Clockwise(arc.StartPoint, p1, arc.EndPoint) == -1)
                bulge = -bulge;
            pline.AddVertexAt(0, new Point2d(arc.StartPoint.X, arc.StartPoint.Y), bulge, 0, 0);
            }
            #endregion Polyline:Arc
          }
          else if (cur2 != null && cur2.GetType().Equals(typeof(Polyline)))
          {
            #region Polyline:Polyline
            Polyline pline2 = (Polyline)cur2;
            if (pline.EndPoint.DistanceTo(pline2.StartPoint) < dTol)
            { //第一曲线末端接入,第二曲线正向加入
            for (int i = 1; i < pline2.NumberOfVertices; i++)//一段段的读出,加入另外曲线
            {
                pline.AddVertexAt(pline.NumberOfVertices, pline2.GetPoint2dAt(i), 0, 0, 0);
                pline.SetBulgeAt(pline.NumberOfVertices - 2, pline2.GetBulgeAt(i - 1));//注意凸度段序号
            }
            }
            else if (pline.EndPoint.DistanceTo(pline2.EndPoint) < dTol)
            {//末端接入,第二曲线逆向加入,第二曲线原有凸度需反向
            for (int i = pline2.NumberOfVertices - 2; i >= 0; i--)
            {
                pline.AddVertexAt(pline.NumberOfVertices, pline2.GetPoint2dAt(i), 0, 0, 0);
                pline.SetBulgeAt(pline.NumberOfVertices - 2, -pline2.GetBulgeAt(i));
            }
            }
            else if (pline.StartPoint.DistanceTo(pline2.StartPoint) < dTol)
            {
            //第一曲线开始端入,第二曲线逆向加入,第二曲线原有凸度需反向
            for (int i = 1; i < pline2.NumberOfVertices; i++)
            {
                pline.AddVertexAt(0, pline2.GetPoint2dAt(i), 0, 0, 0);
                pline.SetBulgeAt(0, -pline2.GetBulgeAt(i - 1));
            }
            }
            else if (pline.StartPoint.DistanceTo(pline2.EndPoint) < dTol)
            {
            //第一曲线开始端入,第二曲线正向加入
            for (int i = pline2.NumberOfVertices - 2; i >= 0; i--)
            {
                pline.AddVertexAt(0, pline2.GetPoint2dAt(i), 0, 0, 0);
                pline.SetBulgeAt(0, pline2.GetBulgeAt(i));
            }
            }
            #endregion Polyline:Polyline
          }
          else
          {
            return null;
          }
          if (pline.StartPoint.DistanceTo(pline.EndPoint) < dTol) //如果曲线起点和终点重合,将Closed = true
          {
            pline.Closed = true;
            //即使起点和终点已重合,pline.Closed = true还是会增加一个节点,导致多义线出现零节点
            pline.RemoveVertexAt(pline.NumberOfVertices - 1);
          }
          return pline;
          #endregion Polyline:Line Arc Polyline
      }
      return pline;
      }
      catch (System.Exception ex)
      {
         return null;
      }
    }
    /// <summary>
    /// 判断1,2,3三个点的依次走向为顺时针还是逆时针走向
    /// </summary>
    /// <param name="P1">第一个点</param>
    /// <param name="P2">第二个点</param>
    /// <param name="P3">第三个点</param>
    /// <returns>顺时针返回-1,逆时针返回1,点重合或在一条直线上返回0</returns>
    static public int Clockwise(Point3d P1, Point3d P2, Point3d P3)
    {
      double A = P3.Y - P1.Y;
      double B = P1.X - P3.X;
      double C = -1.0 * A * P1.X - B * P1.Y;
      double d1 = -A * P2.X - B * P2.Y;
      if (d1 == C)
      return 0;
      else if (d1 > C)
      return -1;
      else
      return 1;
    }
public const double pi = 3.141592653589793;
提示:pi可以直接调用System.Math.PI获取,:)

雪山飞狐_lzh 发表于 2009-6-8 22:12:00

本帖最后由 作者 于 2009-6-20 16:07:16 编辑

连接两条相连的Spline,Ge曲线还是强大些:)
简单的示例
      public static Spline ConvertNurbCurve3d(NurbCurve3d nc3d)
      {
            DoubleCollection knots = new DoubleCollection();
            foreach (double knot in nc3d.Knots)
            {
                knots.Add(knot);
            }
            NurbCurve3dData ncdata = nc3d.DefinitionData;
            return
                new Spline(
                  ncdata.Degree,
                  ncdata.Rational,
                  nc3d.IsClosed(),
                  ncdata.Periodic,
                  ncdata.ControlPoints,
                  knots,
                  ncdata.Weights,
                  0,
                  nc3d.Knots.Tolerance);
      }
      public static NurbCurve3d ConvertNurbCurve3d(Spline spl)
      {
            KnotCollection knots = new KnotCollection();
            foreach (double knot in spl.NurbsData.GetKnots())
            {
                knots.Add(knot);
            }
            NurbsData ndata = spl.NurbsData;
            return
                new NurbCurve3d(
                  ndata.Degree,
                  knots,
                  ndata.GetControlPoints(),
                  ndata.Periodic);
      }
      
      public static void Test4()
      {
            PromptSelectionResult res = CadHelper.Editor.GetSelection();
            using (DBTransaction tr = new DBTransaction())
            {
                Spline c1 = (Spline)tr.GetObject(res.Value.ObjectId, OpenMode.ForRead);
                Spline c2 = (Spline)tr.GetObject(res.Value.ObjectId, OpenMode.ForRead);
                NurbCurve3d nc3d = ConvertNurbCurve3d(c1);
                nc3d.JoinWith(ConvertNurbCurve3d(c2));
                Spline spl = ConvertNurbCurve3d(nc3d);
                tr.OpenCurrentSpace();
                tr.AddEntity(spl);
            }
      }打断自相交曲线,以前写过一个巨复杂的:),一百多行代码
使用Ge CurveCurveIntersector3d对象要简单有效的多:)
暂时只有Spline的
      
      public static void Test7()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptEntityResult res1 = ed.GetEntity("选择图元1");
            using (DBTransaction tr = new DBTransaction())
            {
                Spline spl1 = (Spline)tr.GetObject(res1.ObjectId, OpenMode.ForRead);
                NurbCurve3d nc1 = ConvertDbCurve.ToNurbCurve3d(spl1);
                CurveCurveIntersector3d cci = new CurveCurveIntersector3d(nc1, nc1, Vector3d.ZAxis);
                List<double> pars = new List<double>();
               
                for (int i = 0; i < cci.NumberOfIntersectionPoints; i++)
                {
                  pars.AddRange(cci.GetIntersectionParameters(i));
                }
                if (pars.Count > 0)
                {
                  pars.Sort();
                  tr.OpenCurrentSpace();
                  tr.AddEntity(spl1.GetSplitCurves(new DoubleCollection(pars.ToArray())));
                  spl1.UpgradeOpen();
                  spl1.Erase(true);
                }
            }
      }
曲线的不等比缩放
注意,不是所有的曲线都支持,可以直接转换的只有椭圆,样条曲线
圆可以先转换为椭圆
其余的曲线可能需要先转换为Ge样条曲线,再变换矩阵,或取Spline属性
      public static Matrix3d ScaleMatrix(Point3d point, double x, double y, double z)
      {
            double[] matdata = new double;
            matdata = x;
            matdata = point.X * (1 - x);
            matdata = y;
            matdata = point.Y * (1 - y);
            matdata = z;
            matdata = point.Z * (1 - z);
            matdata = 1;
            return new Matrix3d(matdata);
      }
      
      public static void Test9()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptEntityResult res1 = ed.GetEntity("选择图元1");
            using (DBTransaction tr = new DBTransaction())
            {
                Curve curve = (Curve)tr.GetObject(res1.ObjectId, OpenMode.ForWrite);
                curve.TransformBy(ScaleMatrix(new Point3d(10, 10, 0), 2, 1, 1));
            }
      }

雪山飞狐_lzh 发表于 2009-6-12 00:05:00

打断自相交曲线,以前写过一个巨复杂的:),一百多行代码
使用Ge CurveCurveIntersector3d对象要简单有效的多:)
      
      public static void Test7()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptEntityResult res1 = ed.GetEntity("选择图元1");
            using (DBTransaction tr = new DBTransaction())
            {
                Spline spl1 = (Spline)tr.GetObject(res1.ObjectId, OpenMode.ForRead);
                NurbCurve3d nc1 = ConvertDbCurve.ToNurbCurve3d(spl1);
                CurveCurveIntersector3d cci = new CurveCurveIntersector3d(nc1, nc1, Vector3d.ZAxis);
                List<double> pars = new List<double>();
               
                for (int i = 0; i < cci.NumberOfIntersectionPoints; i++)
                {
                  pars.AddRange(cci.GetIntersectionParameters(i));
                }
                if (pars.Count > 0)
                {
                  pars.Sort();
                  tr.OpenCurrentSpace();
                  tr.AddEntity(spl1.GetSplitCurves(new DoubleCollection(pars.ToArray())));
                  spl1.UpgradeOpen();
                  spl1.Erase(true);
                }
            }
      }

雪山飞狐_lzh 发表于 2009-6-12 19:54:00

本帖最后由 作者 于 2009-6-20 16:05:34 编辑

曲线的不等比缩放
注意,不是所有的曲线都支持,可以直接转换的只有椭圆,样条曲线
圆可以先转换为椭圆
其余的曲线可能需要先转换为Ge样条曲线,再变换矩阵,或取Spline属性
      public static Matrix3d ScaleMatrix(Point3d point, double x, double y, double z)
      {
            double[] matdata = new double;
            matdata = x;
            matdata = point.X * (1 - x);
            matdata = y;
            matdata = point.Y * (1 - y);
            matdata = z;
            matdata = point.Z * (1 - z);
            matdata = 1;
            return new Matrix3d(matdata);
      }
      
      public static void Test9()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptEntityResult res1 = ed.GetEntity("选择图元1");
            using (DBTransaction tr = new DBTransaction())
            {
                Curve curve = (Curve)tr.GetObject(res1.ObjectId, OpenMode.ForWrite);
                curve.TransformBy(ScaleMatrix(new Point3d(10, 10, 0), 2, 1, 1));
            }
      }相关资料
由于用齐次坐标表示,三维几何变换的矩阵是一个4阶方阵,其形式如下:



   1)平移变换

   参照二维的平移变换,我们很容易得到三维平移变换矩阵:

   
   2)缩放变换
    直接考虑相对于参考点(xf,yf,zf)的缩放变换,其步骤为:               A. 将平移到坐标原点处;
   B. 进行缩放变换;
   C. 将参考点(xf,yf,zf)移回原来位置
       则变换矩阵为:
      
    3)绕坐标轴的旋转变换
    三维空间的旋转相对要复杂些,考虑右手坐标系下相对坐标原点绕坐标轴旋转q 角的变换:

   A. 将平移到坐标原点处;
   B. 进行缩放变换;
   C. 将参考点(xf,yf,zf)移回原来位置
       则变换矩阵为:
      
    3)绕坐标轴的旋转变换
    三维空间的旋转相对要复杂些,考虑右手坐标系下相对坐标原点绕坐标轴旋转q 角的变换:

   A. 将平移到坐标原点处;
   B. 进行缩放变换;
   C. 将参考点(xf,yf,zf)移回原来位置
       则变换矩阵为:
      
    3)绕坐标轴的旋转变换
    三维空间的旋转相对要复杂些,考虑右手坐标系下相对坐标原点绕坐标轴旋转q 角的变换:

(xf,yf,zf)的缩放变换,其步骤为:         A. 将平移到坐标原点处;
   B. 进行缩放变换;
   C. 将参考点(xf,yf,zf)移回原来位置
       则变换矩阵为:
      
    3)绕坐标轴的旋转变换
    三维空间的旋转相对要复杂些,考虑右手坐标系下相对坐标原点绕坐标轴旋转q 角的变换:
(xf,yf,zf)移回原来位置
       则变换矩阵为:
      
    3)绕坐标轴的旋转变换
    三维空间的旋转相对要复杂些,考虑右手坐标系下相对坐标原点绕坐标轴旋转q 角的变换:         A.绕x轴旋转

   

   B.绕y轴旋转

   

   C.绕z轴旋转

   

   
   
三维空间的平移、旋转及缩放示意图
   4)绕任意轴的旋转变换
   设旋转轴AB由任意一点A(xa,ya,za)及其方向数(a,b,c)定义,

      
   可以通过下列步骤来实现P点的旋转:
   A. 将A点移到坐标原点。
   B. 使AB分别绕X轴、Y轴旋转适当角度与Z轴重合。
AB分别绕X轴、Y轴旋转适当角度与Z轴重合。         
   D.作上述变换的逆操作,使AB回到原来位置。


是AB在YOZ平面与XOZ平面的投影与Z轴的夹角。

wjm3 发表于 2009-6-17 16:52:00

“所有曲线打断于点”的程序只是针对line对象有用?我试了cad2008、2010多段线都没打断。

雪山飞狐_lzh 发表于 2009-6-17 17:20:00

<p>如果有自交点,这个简化版本不支持:)</p><p>在自交点打断曲线可以看下三楼的代码</p>
页: [1] 2 3 4 5 6
查看完整版本: 曲线处理专贴----我们的[原创]