明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3250|回复: 9

[几何] 截取两点间的部分

[复制链接]
发表于 2010-11-1 22:05:00 | 显示全部楼层 |阅读模式
  1. 现在我想在多义线上 截取两点间的部分,我在网上看到相关的东西,还是不怎么懂。
  2. /// <summary>
  3. ///在多义线上两点截取多义线
  4. /// </summary>
  5. /// <param name="cav">多义线</param>
  6. /// <param name="startPoint">剪切起点</param>
  7. /// <param name="endPoint">剪切终点</param>
  8. /// <param name="StoE">表示所需的部分是两点之间还是两点之外的部分</param>
  9. /// <param name="newCav" >保留的部分</param>
  10. /// <returns></returns>
  11. public static bool GetPolyLineBetweenTwoPoint(Curve cav, Point3d startPoint, Point3d endPoint,bool StoE ,ref Curve newCav)
  12. 。。。。
  13. Point3dCollection insertPoint = new Point3dCollection();
  14. insertPoint.Add(startPoint);
  15. insertPoint.Add(endPoint);
  16. DBObjectCollection m_Objs = new DBObjectCollection();
  17. m_Objs = cav.GetSplitCurves(insertPoint)
  18. foreach (Curve cur in m_Objs)
  19. {
  20. ObjectId m_CurId = CreateEntity(cur);
  21. Curve m_CurNew = OpenEntity(m_CurId) as Curve;
  22. //这里对m_Objs里进行取舍,那怎样取得我想要的部分呢(比如两点间的部分)?
  23. if (...)
  24. m_ObjColl.Add((DBObject)m_CurNew.Clone());//保存被剪之后的新实体
  25. EraseEntity(m_CurId);
  26. }
  27. newCav = m_ObjColl[0] as Curve ;
  28. ...
  29. }
复制代码
另外如
Point3d m_Pt1 = m_CurNew.GetPointAtParameter(m_Param);
Point3d m_Pt2 = m_TrimEdge.GetClosestPointTo(m_Pt1, false);
Vector3d m_Vect = m_TrimEdge.GetFirstDerivative(m_Pt2);
这三句分别表示什么意思?GetPointAtParameter,GetClosestPointTo,GetFirstDerivative是什么意思?
哪位帮帮忙解释下,我相信还有许多和我一样不清楚的人。

发表于 2010-11-1 22:11:00 | 显示全部楼层

GetPointAtParameter

This function determines the point on the curve that corresponds to value, and returns the point.

GetClosestPointTo

This function projects the curve onto the plane defined by givenPoint. Returns the point (in WCS coordinates) on the curve that is nearest to givenPoint.

GetFirstDerivative

Returns the first derivative of the vector.

发表于 2010-11-3 21:10:00 | 显示全部楼层
本帖最后由 作者 于 2010-11-3 22:41:10 编辑

下面的代码可以适应任何曲线
  1.         [CommandMethod("CTest")]
  2.         public void test()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Editor ed = doc.Editor;
  6.             Database db = doc.Database;
  7.             using (doc.LockDocument())
  8.             {
  9.                 PromptEntityOptions optEnt = new PromptEntityOptions("\n请选择曲线上的点:");
  10.                 optEnt.SetRejectMessage("你选择的不是曲线!");
  11.                 optEnt.AddAllowedClass(typeof(Curve), false);
  12.                 PromptEntityResult resEnt = ed.GetEntity(optEnt);
  13.                 if (resEnt.Status != PromptStatus.OK)
  14.                     return;
  15.                 ObjectId id = resEnt.ObjectId;
  16.                 Point3d pt1 = resEnt.PickedPoint;
  17.                 SystemManager.OSModeType oldos = SystemManager.OSMode;
  18.                 SystemManager.OSMode = SystemManager.OSModeType.Nearest;
  19.                 PromptPointOptions optPt2 = new PromptPointOptions("\n请选取第二个点:");
  20.                 PromptPointResult resPt2 = ed.GetPoint(optPt2);
  21.                 SystemManager.OSMode = oldos;
  22.                 if (resPt2.Status != PromptStatus.OK)
  23.                     return;
  24.                 Point3d pt2 = resPt2.Value;
  25.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  26.                 {
  27.                     BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite, false);
  28.                     Curve oldCurve = tr.GetObject(id, OpenMode.ForWrite) as Curve;
  29.                     if (pt2.DistanceTo(oldCurve.GetClosestPointTo(pt2, false)) > 5)
  30.                     {
  31.                         ed.WriteMessage("\n点不在曲线上!");
  32.                         return;
  33.                     }
  34.                     pt1 = oldCurve.GetClosestPointTo(pt1, false);
  35.                     pt2 = oldCurve.GetClosestPointTo(pt2, false);
  36.                     double par1 = oldCurve.GetParameterAtPoint(pt1);
  37.                     double par2 = oldCurve.GetParameterAtPoint(pt2);
  38.                     if (par1 > par2)
  39.                     {
  40.                         double temp = par1;
  41.                         par1 = par2;
  42.                         par2 = temp;
  43.                     }
  44.                     DoubleCollection pars = new DoubleCollection { par1, par2 };
  45.                     
  46.                     var curves = oldCurve.GetSplitCurves(pars);
  47.                     Curve newCurve = null;
  48.                     foreach (Curve curve in curves)
  49.                     {
  50.                         if (curve.GetClosestPointTo(pt1, false) == pt1 && curve.GetClosestPointTo(pt2, false) == pt2)
  51.                         {
  52.                             newCurve = curve;
  53.                             break;
  54.                         }
  55.                     }
  56.                     if (newCurve != null)
  57.                     {
  58.                         oldCurve.Erase();
  59.                         btr.AppendEntity(newCurve);
  60.                         tr.AddNewlyCreatedDBObject(newCurve, true);
  61.                     }
  62.                     tr.Commit();
  63.                 }
  64.             }
  65.         }
发表于 2010-11-3 21:13:00 | 显示全部楼层
SystemManager类
  1. using System;
  2. using Autodesk.AutoCAD.ApplicationServices;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.GraphicsSystem;
  6. namespace TlsCad.Runtime
  7. {
  8.     public static class SystemManager
  9.     {
  10.         #region Goal
  11.         public static Database CurrentDatabase
  12.         {
  13.             get
  14.             {
  15.                 return HostApplicationServices.WorkingDatabase;
  16.             }
  17.         }
  18.         public static Document ActiveDocument
  19.         {
  20.             get
  21.             {
  22.                 return Application.DocumentManager.MdiActiveDocument;
  23.             }
  24.         }
  25.         public static Editor Editor
  26.         {
  27.             get
  28.             {
  29.                 return ActiveDocument.Editor;
  30.             }
  31.         }
  32.         public static Manager GsManager
  33.         {
  34.             get
  35.             {
  36.                 return ActiveDocument.GraphicsManager;
  37.             }
  38.         }
  39.         #endregion
  40.         #region Preferences
  41.         public static object GetCurrentProfileProperty(string subSectionName, string propertyName)
  42.         {
  43.             UserConfigurationManager ucm = Application.UserConfigurationManager;
  44.             IConfigurationSection cpf = ucm.OpenCurrentProfile();
  45.             IConfigurationSection ss = cpf.OpenSubsection(subSectionName);
  46.             return ss.ReadProperty(propertyName, "");
  47.         }
  48.         public static IConfigurationSection GetDialogSection(object dialog, string propertyName)
  49.         {
  50.             UserConfigurationManager ucm = Application.UserConfigurationManager;
  51.             IConfigurationSection ds = ucm.OpenDialogSection(dialog);
  52.             return ds;
  53.         }
  54.         public static IConfigurationSection GetGlobalSection(string propertyName)
  55.         {
  56.             UserConfigurationManager ucm = Application.UserConfigurationManager;
  57.             IConfigurationSection gs = ucm.OpenGlobalSection();
  58.             IConfigurationSection ss = gs.OpenSubsection(propertyName);
  59.             return ss;
  60.         }
  61.         #endregion
  62.         #region Enum
  63.         private static T ToEnum<T>(this string value)
  64.         {
  65.             return (T)Enum.Parse(typeof(T), value, true);
  66.         }
  67.         private static string GetName<T>(this T value)
  68.         {
  69.             return Enum.GetName(typeof(T), value);
  70.         }
  71.         
  72.         #region Dimblk
  73.         public enum DimblkType
  74.         {
  75.             Defult,
  76.             Dot,
  77.             DotSmall,
  78.             DotBlank,
  79.             Origin,
  80.             Origin2,
  81.             Open,
  82.             Open90,
  83.             Open30,
  84.             Closed,
  85.             Small,
  86.             None,
  87.             Oblique,
  88.             BoxFilled,
  89.             BoxBlank,
  90.             ClosedBlank,
  91.             DatumFilled,
  92.             DatumBlank,
  93.             Integral,
  94.             ArchTick,
  95.         }
  96.         public static DimblkType Dimblk
  97.         {
  98.             get
  99.             {
  100.                 string s = (string)Application.GetSystemVariable("dimblk");
  101.                 if (s == "" || s == null)
  102.                 {
  103.                     return DimblkType.Defult;
  104.                 }
  105.                 else
  106.                 {
  107.                     return s.ToEnum<DimblkType>();
  108.                 }
  109.             }
  110.             set
  111.             {
  112.                 string s =
  113.                     value == DimblkType.Defult ?
  114.                     "." : "_" + value.GetName();
  115.                 Application.SetSystemVariable("dimblk", s);
  116.             }
  117.         }
  118.         public static ObjectId GetDimblkId(DimblkType dimblkname)
  119.         {
  120.             DimblkType oldDimblk = Dimblk;
  121.             Dimblk = dimblkname;
  122.             ObjectId id = HostApplicationServices.WorkingDatabase.Dimblk;
  123.             Dimblk = oldDimblk;
  124.             return id;
  125.         }
  126.         #endregion
  127.         #region OsMode
  128.         public enum OSModeType
  129.         {
  130.             None = 0,
  131.             End = 1,
  132.             Middle = 2,
  133.             Center = 4,
  134.             Node = 8,
  135.             Quadrant = 16,
  136.             Intersection = 32,
  137.             Insert = 64,
  138.             Pedal = 128,
  139.             Tangent = 256,
  140.             Nearest = 512,
  141.             Quick = 1024,
  142.             Appearance = 2048,
  143.             Extension = 4096,
  144.             Parallel = 8192
  145.         }
  146.         public static OSModeType OSMode
  147.         {
  148.             get
  149.             {
  150.                 return (OSModeType)Convert.ToInt16(Application.GetSystemVariable("osmode"));
  151.             }
  152.             set
  153.             {
  154.                 Application.SetSystemVariable("osmode", (int)value);
  155.             }
  156.         }
  157.         public static void AppendOSMode(OSModeType osm)
  158.         {
  159.             OSMode |= osm;
  160.         }
  161.         public static bool CheckOSMode(OSModeType osm)
  162.         {
  163.             return (OSMode & osm) == osm;
  164.         }
  165.         public static void RemoveOSMode(OSModeType osm)
  166.         {
  167.             OSMode ^= osm;
  168.         }
  169.         #endregion
  170.         #endregion
  171.     }
  172. }
 楼主| 发表于 2010-11-3 22:45:00 | 显示全部楼层
谢谢,我研究下
 楼主| 发表于 2010-11-5 21:09:00 | 显示全部楼层

谢谢你抽出时间给我回复。

主要是我的问题没有被我描述清楚、

我的意思是定义一个函数

public static Curve GetPolyLineBetweenTwoPoint(Curve cav, Point3d P1, Point3d P2,bool StoE )

1,首先我知道截取的两点在一个封闭的多义线cav上。(封闭的多义线cav---我也是事先就知道的)

2,假如起始点设为P1,终点设为P2,p1到p2是顺时针方向还是逆时针方向是由StoE决定。假如事先规定StoE为true时表示顺时针方向。

3,返回沿P1到P2顺时针或逆时针方向的一段多义线。

 

发表于 2010-11-5 23:26:00 | 显示全部楼层

这个有点麻烦

提供算法先考虑下吧

 

1、首先判断多段线的顺逆

2、按stoe和p1,p2的参数数值判断取舍

3、如果取起点所在的两段,还要把两段连接为一条

发表于 2010-11-9 12:23:00 | 显示全部楼层
谢谢,现在还不懂,先收藏,以后我也研究下
 楼主| 发表于 2010-11-9 19:16:00 | 显示全部楼层
谢谢飞狐,在你的指导下以及查阅了相关资料,我实现了此功能
  1.   
  2. /// <summary>
  3. /// 求点集组成的多边形面积
  4. /// </summary>
  5. /// <param name="nPts"></param>
  6. /// <returns></returns>
  7. public static double getPtArrayArea(Point3dCollection nPts)
  8. {
  9. int len = nPts.Count; Polyline3d s = new Polyline3d();
  10. double area = 0;
  11. if (len < 3)
  12. return 0;
  13. Point3d spt; Point3d p1; Point3d p2;
  14. spt = nPts[0];
  15. for (int i = 0; i < len - 1; i++)
  16. {
  17. p2 = nPts[i + 1];
  18. area += p1.X * p2.Y - p2.X * p1.Y;
  19. }
  20. area = (area + (p2.X * spt.Y - spt.X * p2.Y)) / 2;
  21. return area;
  22. }
  23. /// <summary>
  24. /// 如果逆时针,面积为正,顺时针,面积为负;如果逆时针,返回true,顺时针,返回false
  25. /// </summary>
  26. /// <param name="cur"></param>
  27. /// <returns>如果逆时针,返回true,顺时针,返回false</returns>
  28. public static bool isAntiClockWise(Polyline cur)
  29. {
  30. Point3dCollection points=new Point3dCollection();
  31. double m = cur.EndParam;
  32. int n = int.Parse(m.ToString());
  33. for (int i = 0; i < n; i++)
  34. {
  35. points.Add(cur.GetPoint3dAt(i));
  36. }
  37. return (getPtArrayArea(points) > 0);
  38. }
  39. /// <summary>
  40. ///在多义线上两点截取多义线,规定startpoint至endpoint总是逆时针方向
  41. /// </summary>
  42. /// <param name="cav">封闭的多义线</param>
  43. /// <param name="startPoint">剪切起点</param>
  44. /// <param name="endPoint">剪切终点</param>
  45. /// <param name="newCav" >保留的部分</param>
  46. public static Polyline GetPolyLineBetweenTwoPoint(BlockTableRecord btr, Transaction tr, Polyline cav, Point3d startPoint, Point3d endPoint)
  47. {
  48. //判断被剪曲线是否位于锁定图层上
  49. LayerTableRecord m_ltr = (LayerTableRecord)OpenEntity(tr,cav.LayerId);
  50. if (m_ltr.IsLocked) return cav ;
  51. Point3dCollection insertPoint = new Point3dCollection();
  52. insertPoint.Add(startPoint);
  53. insertPoint.Add(endPoint);
  54. DBObjectCollection m_ObjColl = new DBObjectCollection();
  55. try
  56. {
  57. #region 生成交点处拆分的实体集合
  58. m_ObjColl = cav.GetSplitCurves(insertPoint);//拆分曲线实体
  59. #endregion
  60. #region 判断多义线的时针方向
  61. bool t = false;
  62. t = isAntiClockWise(cav);
  63. #endregion
  64. #region 对拆分实体集合中各实体进行判断,那些需要保留
  65. DBObjectCollection objs = new DBObjectCollection();
  66. foreach (Curve cur in m_ObjColl)
  67. {
  68. ObjectId m_CurId = CreateEntity(btr, tr,cur);//先生成实体
  69. Polyline m_CurNew = OpenEntity(tr, m_CurId) as Polyline;
  70. if ((m_CurNew.StartPoint == endPoint) & t)
  71. {
  72. //如果多义线是逆时针方向且此多义的起点和剪切的起点相同则m_CurNew就是所要的多义线
  73. Polyline tempoly = m_CurNew.Clone() as Polyline;
  74. CreateEntity(btr, tr, tempoly);
  75. objs.Add((DBObject)tempoly);//保存被剪之后的新实体
  76. }
  77. if ((m_CurNew.StartPoint == startPoint) & !t)
  78. {
  79. //如果多义线是顺时针方向则m_CurNew就是所要的多义线
  80. Polyline tempoly = m_CurNew.Clone() as Polyline ;
  81. CreateEntity(btr, tr, tempoly);
  82. objs.Add((DBObject)tempoly);//保存被剪之后的新实体
  83. }
  84. EraseEntity(tr ,m_CurId);
  85. }
  86. Polyline tempoly1= objs[0] as Polyline ;
  87. return tempoly1;
  88. #endregion
  89. }
  90. catch(Exception e)
  91. {
  92. Application.ShowAlertDialog(e.Message);
  93. return cav;
  94. }
  95. }
  96. /// <summary>
  97. /// 在模型空间绘制实体
  98. /// </summary>
  99. /// <param name="acEnt"></param>
  100. public static ObjectId CreateEntity(BlockTableRecord btr, Transaction tr, Entity acEnt)
  101. {
  102. ObjectId m_objid = new ObjectId();
  103. m_objid = btr.AppendEntity(acEnt);
  104. tr.AddNewlyCreatedDBObject(acEnt, true);
  105. return m_objid;
  106. }
复制代码

评分

参与人数 1威望 +1 明经币 +1 金钱 +5 贡献 +5 激情 +5 收起 理由
雪山飞狐_lzh + 1 + 1 + 5 + 5 + 5 【好评】表扬一下

查看全部评分

 楼主| 发表于 2010-11-11 22:19:00 | 显示全部楼层
  1.          /// <summary>
  2.         ///在多义线上两点截取多义线,规定startpoint至endpoint总是顺时针方向
  3.         /// </summary>
  4.         /// <param name="cav">型腔</param>
  5.         /// <param name="startPoint">剪切起点</param>
  6.         /// <param name="endPoint">剪切终点</param>
  7.         /// <param name="newCav" >保留的部分</param>
  8.         public static Polyline GetPolyLineBetweenTwoPoint(BlockTableRecord btr, Transaction tr, Polyline cav, Point3d startPoint, Point3d endPoint)
  9.         {
  10.             bool t = Yds.PublicCalss.CurrStruct.IsAntiClockWise;
  11.             //判断被剪曲线是否位于锁定图层上
  12.             Polyline tempolyline = new Polyline();
  13.             LayerTableRecord m_ltr = (LayerTableRecord)OpenEntity(tr,cav.LayerId);
  14.             if (m_ltr.IsLocked) return tempolyline;
  15.             Point3dCollection insertPoint = new Point3dCollection();
  16.             double startParam = cav.GetParameterAtPoint(startPoint);
  17.             double endParam = cav.GetParameterAtPoint(endPoint);
  18.             //在飞狐的指导下,将Param从小到大加入到insertPoint,再次感谢飞狐,调试很成功!!
  19.             if (startParam < endParam)
  20.             {
  21.                 insertPoint.Add(startPoint);
  22.                 insertPoint.Add(endPoint);
  23.             }
  24.             else
  25.             {
  26.                 insertPoint.Add(endPoint);
  27.                 insertPoint.Add(startPoint);
  28.             }
  29.             DBObjectCollection m_ObjColl = new DBObjectCollection();
  30.             try
  31.             {
  32.                
  33.                 #region 生成交点处拆分的实体集合
  34.                 m_ObjColl = cav.GetSplitCurves(insertPoint);//拆分曲线实体
  35.                 #endregion
  36.                 #region 对拆分实体集合中各实体进行判断,那些需要保留
  37.                 DBObjectCollection objs = new DBObjectCollection();
  38.                 foreach (Curve cur in m_ObjColl)
  39.                 {
  40.                      ObjectId m_CurId = CreateEntity(btr, tr,cur);//先生成实体
  41.                      Polyline m_CurNew = OpenEntity(tr, m_CurId) as Polyline;
  42.                     if ((m_CurNew.StartPoint == endPoint) & t)
  43.                     {
  44.                         //如果多义线是逆时针方向且此多义的起点和剪切的起点相同则m_CurNew就是所要的多义线
  45.                         Polyline tempoly = m_CurNew.Clone() as Polyline;
  46.                         CreateEntity(btr, tr, tempoly);
  47.                         objs.Add((DBObject)tempoly);//保存被剪之后的新实体
  48.                     }
  49.                     if ((m_CurNew.StartPoint == startPoint) & !t)
  50.                     {
  51.                         //如果多义线是顺时针方向则m_CurNew就是所要的多义线
  52.                         Polyline tempoly = m_CurNew.Clone() as Polyline ;
  53.                         CreateEntity(btr, tr, tempoly);
  54.                         objs.Add((DBObject)tempoly);//保存被剪之后的新实体
  55.                     }
  56.                     EraseEntity(tr ,m_CurId);
  57.                 }
  58.                 tempolyline = objs[0] as Polyline;
  59.                 #endregion
  60.             }
  61.             catch(Exception e)
  62.             {
  63.                 Application.ShowAlertDialog(e.Message);
  64.             }
  65.             return tempolyline;
  66.         }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-26 00:28 , Processed in 0.199027 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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