yds_009 发表于 2010-11-1 22:05:00

截取两点间的部分

现在我想在多义线上 截取两点间的部分,我在网上看到相关的东西,还是不怎么懂。
/// <summary>
///在多义线上两点截取多义线
/// </summary>
/// <param name="cav">多义线</param>
/// <param name="startPoint">剪切起点</param>
/// <param name="endPoint">剪切终点</param>
/// <param name="StoE">表示所需的部分是两点之间还是两点之外的部分</param>
/// <param name="newCav" >保留的部分</param>
/// <returns></returns>
public static bool GetPolyLineBetweenTwoPoint(Curve cav, Point3d startPoint, Point3d endPoint,bool StoE ,ref Curve newCav)


。。。。
Point3dCollection insertPoint = new Point3dCollection();
insertPoint.Add(startPoint);
insertPoint.Add(endPoint);
DBObjectCollection m_Objs = new DBObjectCollection();
m_Objs = cav.GetSplitCurves(insertPoint)
foreach (Curve cur in m_Objs)
{
ObjectId m_CurId = CreateEntity(cur);
Curve m_CurNew = OpenEntity(m_CurId) as Curve;
//这里对m_Objs里进行取舍,那怎样取得我想要的部分呢(比如两点间的部分)?
if (...)
m_ObjColl.Add((DBObject)m_CurNew.Clone());//保存被剪之后的新实体
EraseEntity(m_CurId);
}
newCav = m_ObjColl as Curve ;
...
}
另外如
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是什么意思?
哪位帮帮忙解释下,我相信还有许多和我一样不清楚的人。

雪山飞狐_lzh 发表于 2010-11-1 22:11:00

<p>GetPointAtParameter</p>
<p class="Element10">This function determines the point on the curve that corresponds to value, and returns the point.</p>
<p>GetClosestPointTo</p>
<p class="Element10">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.</p>
<p class="Element10">GetFirstDerivative</p>
<p class="Element10">Returns the first derivative of the vector.</p>

雪山飞狐_lzh 发表于 2010-11-3 21:10:00

本帖最后由 作者 于 2010-11-3 22:41:10 编辑

下面的代码可以适应任何曲线

      
      public void test()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            using (doc.LockDocument())
            {
                PromptEntityOptions optEnt = new PromptEntityOptions("\n请选择曲线上的点:");
                optEnt.SetRejectMessage("你选择的不是曲线!");
                optEnt.AddAllowedClass(typeof(Curve), false);
                PromptEntityResult resEnt = ed.GetEntity(optEnt);
                if (resEnt.Status != PromptStatus.OK)
                  return;
                ObjectId id = resEnt.ObjectId;
                Point3d pt1 = resEnt.PickedPoint;
                SystemManager.OSModeType oldos = SystemManager.OSMode;
                SystemManager.OSMode = SystemManager.OSModeType.Nearest;
                PromptPointOptions optPt2 = new PromptPointOptions("\n请选取第二个点:");
                PromptPointResult resPt2 = ed.GetPoint(optPt2);
                SystemManager.OSMode = oldos;
                if (resPt2.Status != PromptStatus.OK)
                  return;
                Point3d pt2 = resPt2.Value;
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                  BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite, false);
                  Curve oldCurve = tr.GetObject(id, OpenMode.ForWrite) as Curve;
                  if (pt2.DistanceTo(oldCurve.GetClosestPointTo(pt2, false)) > 5)
                  {
                        ed.WriteMessage("\n点不在曲线上!");
                        return;
                  }
                  pt1 = oldCurve.GetClosestPointTo(pt1, false);
                  pt2 = oldCurve.GetClosestPointTo(pt2, false);
                  double par1 = oldCurve.GetParameterAtPoint(pt1);
                  double par2 = oldCurve.GetParameterAtPoint(pt2);
                  if (par1 > par2)
                  {
                        double temp = par1;
                        par1 = par2;
                        par2 = temp;
                  }
                  DoubleCollection pars = new DoubleCollection { par1, par2 };
                  
                  var curves = oldCurve.GetSplitCurves(pars);
                  Curve newCurve = null;
                  foreach (Curve curve in curves)
                  {
                        if (curve.GetClosestPointTo(pt1, false) == pt1 && curve.GetClosestPointTo(pt2, false) == pt2)
                        {
                            newCurve = curve;
                            break;
                        }
                  }
                  if (newCurve != null)
                  {
                        oldCurve.Erase();
                        btr.AppendEntity(newCurve);
                        tr.AddNewlyCreatedDBObject(newCurve, true);
                  }
                  tr.Commit();
                }
            }
      }

雪山飞狐_lzh 发表于 2010-11-3 21:13:00

SystemManager类

using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.GraphicsSystem;
namespace TlsCad.Runtime
{
    public static class SystemManager
    {
      #region Goal
      public static Database CurrentDatabase
      {
            get
            {
                return HostApplicationServices.WorkingDatabase;
            }
      }
      public static Document ActiveDocument
      {
            get
            {
                return Application.DocumentManager.MdiActiveDocument;
            }
      }
      public static Editor Editor
      {
            get
            {
                return ActiveDocument.Editor;
            }
      }
      public static Manager GsManager
      {
            get
            {
                return ActiveDocument.GraphicsManager;
            }
      }
      #endregion
      #region Preferences
      public static object GetCurrentProfileProperty(string subSectionName, string propertyName)
      {
            UserConfigurationManager ucm = Application.UserConfigurationManager;
            IConfigurationSection cpf = ucm.OpenCurrentProfile();
            IConfigurationSection ss = cpf.OpenSubsection(subSectionName);
            return ss.ReadProperty(propertyName, "");
      }
      public static IConfigurationSection GetDialogSection(object dialog, string propertyName)
      {
            UserConfigurationManager ucm = Application.UserConfigurationManager;
            IConfigurationSection ds = ucm.OpenDialogSection(dialog);
            return ds;
      }
      public static IConfigurationSection GetGlobalSection(string propertyName)
      {
            UserConfigurationManager ucm = Application.UserConfigurationManager;
            IConfigurationSection gs = ucm.OpenGlobalSection();
            IConfigurationSection ss = gs.OpenSubsection(propertyName);
            return ss;
      }
      #endregion
      #region Enum
      private static T ToEnum<T>(this string value)
      {
            return (T)Enum.Parse(typeof(T), value, true);
      }
      private static string GetName<T>(this T value)
      {
            return Enum.GetName(typeof(T), value);
      }
      
      #region Dimblk
      public enum DimblkType
      {
            Defult,
            Dot,
            DotSmall,
            DotBlank,
            Origin,
            Origin2,
            Open,
            Open90,
            Open30,
            Closed,
            Small,
            None,
            Oblique,
            BoxFilled,
            BoxBlank,
            ClosedBlank,
            DatumFilled,
            DatumBlank,
            Integral,
            ArchTick,
      }
      public static DimblkType Dimblk
      {
            get
            {
                string s = (string)Application.GetSystemVariable("dimblk");
                if (s == "" || s == null)
                {
                  return DimblkType.Defult;
                }
                else
                {
                  return s.ToEnum<DimblkType>();
                }
            }
            set
            {
                string s =
                  value == DimblkType.Defult ?
                  "." : "_" + value.GetName();
                Application.SetSystemVariable("dimblk", s);
            }
      }
      public static ObjectId GetDimblkId(DimblkType dimblkname)
      {
            DimblkType oldDimblk = Dimblk;
            Dimblk = dimblkname;
            ObjectId id = HostApplicationServices.WorkingDatabase.Dimblk;
            Dimblk = oldDimblk;
            return id;
      }
      #endregion
      #region OsMode
      public enum OSModeType
      {
            None = 0,
            End = 1,
            Middle = 2,
            Center = 4,
            Node = 8,
            Quadrant = 16,
            Intersection = 32,
            Insert = 64,
            Pedal = 128,
            Tangent = 256,
            Nearest = 512,
            Quick = 1024,
            Appearance = 2048,
            Extension = 4096,
            Parallel = 8192
      }
      public static OSModeType OSMode
      {
            get
            {
                return (OSModeType)Convert.ToInt16(Application.GetSystemVariable("osmode"));
            }
            set
            {
                Application.SetSystemVariable("osmode", (int)value);
            }
      }

      public static void AppendOSMode(OSModeType osm)
      {
            OSMode |= osm;
      }
      public static bool CheckOSMode(OSModeType osm)
      {
            return (OSMode & osm) == osm;
      }
      public static void RemoveOSMode(OSModeType osm)
      {
            OSMode ^= osm;
      }
      #endregion
      #endregion
    }
}


yds_009 发表于 2010-11-3 22:45:00

谢谢,我研究下

yds_009 发表于 2010-11-5 21:09:00

<p>谢谢你抽出时间给我回复。</p>
<p>主要是我的问题没有被我描述清楚、</p>
<p>我的意思是定义一个函数</p>
<p>public static&nbsp;Curve GetPolyLineBetweenTwoPoint(Curve cav, Point3d P1, Point3d P2,bool StoE&nbsp;) </p>
<p>1,首先我知道截取的两点在一个封闭的多义线cav上。(封闭的多义线cav---我也是事先就知道的)</p>
<p>2,假如起始点设为P1,终点设为P2,p1到p2是顺时针方向还是逆时针方向是由StoE决定。假如事先规定StoE为true时表示顺时针方向。</p>
<p>3,返回沿P1到P2顺时针或逆时针方向的一段多义线。</p>
<p>&nbsp;</p>

雪山飞狐_lzh 发表于 2010-11-5 23:26:00

<p>这个有点麻烦</p>
<p>提供算法先考虑下吧</p>
<p>&nbsp;</p>
<p>1、首先判断多段线的顺逆</p>
<p>2、按stoe和p1,p2的参数数值判断取舍</p>
<p>3、如果取起点所在的两段,还要把两段连接为一条</p>

chpmould 发表于 2010-11-9 12:23:00

谢谢,现在还不懂,先收藏,以后我也研究下

yds_009 发表于 2010-11-9 19:16:00

谢谢飞狐,在你的指导下以及查阅了相关资料,我实现了此功能

/// <summary>
/// 求点集组成的多边形面积
/// </summary>
/// <param name="nPts"></param>
/// <returns></returns>
public static double getPtArrayArea(Point3dCollection nPts)
{
int len = nPts.Count; Polyline3d s = new Polyline3d();
double area = 0;
if (len < 3)
return 0;
Point3d spt; Point3d p1; Point3d p2;
spt = nPts;
for (int i = 0; i < len - 1; i++)
{
p2 = nPts;
area += p1.X * p2.Y - p2.X * p1.Y;
}
area = (area + (p2.X * spt.Y - spt.X * p2.Y)) / 2;
return area;
}
/// <summary>
/// 如果逆时针,面积为正,顺时针,面积为负;如果逆时针,返回true,顺时针,返回false
/// </summary>
/// <param name="cur"></param>
/// <returns>如果逆时针,返回true,顺时针,返回false</returns>
public static bool isAntiClockWise(Polyline cur)
{
Point3dCollection points=new Point3dCollection();
double m = cur.EndParam;
int n = int.Parse(m.ToString());
for (int i = 0; i < n; i++)
{
points.Add(cur.GetPoint3dAt(i));
}
return (getPtArrayArea(points) > 0);
}

/// <summary>
///在多义线上两点截取多义线,规定startpoint至endpoint总是逆时针方向
/// </summary>
/// <param name="cav">封闭的多义线</param>
/// <param name="startPoint">剪切起点</param>
/// <param name="endPoint">剪切终点</param>
/// <param name="newCav" >保留的部分</param>
public static Polyline GetPolyLineBetweenTwoPoint(BlockTableRecord btr, Transaction tr, Polyline cav, Point3d startPoint, Point3d endPoint)
{
//判断被剪曲线是否位于锁定图层上
LayerTableRecord m_ltr = (LayerTableRecord)OpenEntity(tr,cav.LayerId);
if (m_ltr.IsLocked) return cav ;
Point3dCollection insertPoint = new Point3dCollection();
insertPoint.Add(startPoint);
insertPoint.Add(endPoint);
DBObjectCollection m_ObjColl = new DBObjectCollection();
try
{
#region 生成交点处拆分的实体集合
m_ObjColl = cav.GetSplitCurves(insertPoint);//拆分曲线实体
#endregion

#region 判断多义线的时针方向
bool t = false;
t = isAntiClockWise(cav);
#endregion

#region 对拆分实体集合中各实体进行判断,那些需要保留
DBObjectCollection objs = new DBObjectCollection();
foreach (Curve cur in m_ObjColl)
{
ObjectId m_CurId = CreateEntity(btr, tr,cur);//先生成实体
Polyline m_CurNew = OpenEntity(tr, m_CurId) as Polyline;
if ((m_CurNew.StartPoint == endPoint) & t)
{
//如果多义线是逆时针方向且此多义的起点和剪切的起点相同则m_CurNew就是所要的多义线
Polyline tempoly = m_CurNew.Clone() as Polyline;
CreateEntity(btr, tr, tempoly);
objs.Add((DBObject)tempoly);//保存被剪之后的新实体
}
if ((m_CurNew.StartPoint == startPoint) & !t)
{
//如果多义线是顺时针方向则m_CurNew就是所要的多义线
Polyline tempoly = m_CurNew.Clone() as Polyline ;
CreateEntity(btr, tr, tempoly);
objs.Add((DBObject)tempoly);//保存被剪之后的新实体
}
EraseEntity(tr ,m_CurId);
}
Polyline tempoly1= objs as Polyline ;
return tempoly1;
#endregion
}
catch(Exception e)
{
Application.ShowAlertDialog(e.Message);
return cav;
}

}
/// <summary>
/// 在模型空间绘制实体
/// </summary>
/// <param name="acEnt"></param>
public static ObjectId CreateEntity(BlockTableRecord btr, Transaction tr, Entity acEnt)
{
ObjectId m_objid = new ObjectId();
m_objid = btr.AppendEntity(acEnt);
tr.AddNewlyCreatedDBObject(acEnt, true);
return m_objid;
}

yds_009 发表于 2010-11-11 22:19:00


         /// <summary>
      ///在多义线上两点截取多义线,规定startpoint至endpoint总是顺时针方向
      /// </summary>
      /// <param name="cav">型腔</param>
      /// <param name="startPoint">剪切起点</param>
      /// <param name="endPoint">剪切终点</param>
      /// <param name="newCav" >保留的部分</param>
      public static Polyline GetPolyLineBetweenTwoPoint(BlockTableRecord btr, Transaction tr, Polyline cav, Point3d startPoint, Point3d endPoint)
      {
            bool t = Yds.PublicCalss.CurrStruct.IsAntiClockWise;
            //判断被剪曲线是否位于锁定图层上
            Polyline tempolyline = new Polyline();
            LayerTableRecord m_ltr = (LayerTableRecord)OpenEntity(tr,cav.LayerId);
            if (m_ltr.IsLocked) return tempolyline;
            Point3dCollection insertPoint = new Point3dCollection();
            double startParam = cav.GetParameterAtPoint(startPoint);
            double endParam = cav.GetParameterAtPoint(endPoint);
            //在飞狐的指导下,将Param从小到大加入到insertPoint,再次感谢飞狐,调试很成功!!
            if (startParam < endParam)
            {
                insertPoint.Add(startPoint);
                insertPoint.Add(endPoint);
            }
            else
            {
                insertPoint.Add(endPoint);
                insertPoint.Add(startPoint);
            }
            DBObjectCollection m_ObjColl = new DBObjectCollection();
            try
            {
               
                #region 生成交点处拆分的实体集合
                m_ObjColl = cav.GetSplitCurves(insertPoint);//拆分曲线实体
                #endregion
                #region 对拆分实体集合中各实体进行判断,那些需要保留
                DBObjectCollection objs = new DBObjectCollection();
                foreach (Curve cur in m_ObjColl)
                {
                     ObjectId m_CurId = CreateEntity(btr, tr,cur);//先生成实体
                     Polyline m_CurNew = OpenEntity(tr, m_CurId) as Polyline;
                  if ((m_CurNew.StartPoint == endPoint) & t)
                  {
                        //如果多义线是逆时针方向且此多义的起点和剪切的起点相同则m_CurNew就是所要的多义线
                        Polyline tempoly = m_CurNew.Clone() as Polyline;
                        CreateEntity(btr, tr, tempoly);
                        objs.Add((DBObject)tempoly);//保存被剪之后的新实体
                  }
                  if ((m_CurNew.StartPoint == startPoint) & !t)
                  {
                        //如果多义线是顺时针方向则m_CurNew就是所要的多义线
                        Polyline tempoly = m_CurNew.Clone() as Polyline ;
                        CreateEntity(btr, tr, tempoly);
                        objs.Add((DBObject)tempoly);//保存被剪之后的新实体
                  }
                  EraseEntity(tr ,m_CurId);
                }
                tempolyline = objs as Polyline;
                #endregion
            }
            catch(Exception e)
            {
                Application.ShowAlertDialog(e.Message);
            }
            return tempolyline;
      }

页: [1]
查看完整版本: 截取两点间的部分