截取两点间的部分
现在我想在多义线上 截取两点间的部分,我在网上看到相关的东西,还是不怎么懂。/// <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是什么意思?
哪位帮帮忙解释下,我相信还有许多和我一样不清楚的人。
<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> 本帖最后由 作者 于 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();
}
}
}
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
}
}
谢谢,我研究下 <p>谢谢你抽出时间给我回复。</p>
<p>主要是我的问题没有被我描述清楚、</p>
<p>我的意思是定义一个函数</p>
<p>public static Curve GetPolyLineBetweenTwoPoint(Curve cav, Point3d P1, Point3d P2,bool StoE ) </p>
<p>1,首先我知道截取的两点在一个封闭的多义线cav上。(封闭的多义线cav---我也是事先就知道的)</p>
<p>2,假如起始点设为P1,终点设为P2,p1到p2是顺时针方向还是逆时针方向是由StoE决定。假如事先规定StoE为true时表示顺时针方向。</p>
<p>3,返回沿P1到P2顺时针或逆时针方向的一段多义线。</p>
<p> </p> <p>这个有点麻烦</p>
<p>提供算法先考虑下吧</p>
<p> </p>
<p>1、首先判断多段线的顺逆</p>
<p>2、按stoe和p1,p2的参数数值判断取舍</p>
<p>3、如果取起点所在的两段,还要把两段连接为一条</p> 谢谢,现在还不懂,先收藏,以后我也研究下 谢谢飞狐,在你的指导下以及查阅了相关资料,我实现了此功能
/// <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;
}
/// <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]