白糖 发表于 2012-12-7 22:02:07

判断点与线段位置关系

通过简单的向量计算判断点与线段位置关系,没有设置点到线段距离容差,所以点击线段时不会判断在线段上


public void Test()
{
Database db = HostApplicationServices.WorkingDatabase;
Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;

using (Transaction trans = db.TransactionManager.StartTransaction())
{
PromptPointOptions ptOpts = new PromptPointOptions("选择第一点A");
PromptPointResult ptRes = ed.GetPoint(ptOpts);
if (ptRes.Status != PromptStatus.OK)
{
   throw new Autodesk.AutoCAD.Runtime.Exception();
}
Point3d pt1 = ptRes.Value;

ptOpts = new PromptPointOptions("\n选择第二点B");
ptRes = ed.GetPoint(ptOpts);
if (ptRes.Status != PromptStatus.OK)
{
   throw new Autodesk.AutoCAD.Runtime.Exception();
}
Point3d pt2 = ptRes.Value;

//生成AB线段
Line lineAB = new Line(pt1,pt2);
AppendEntity(lineAB);
trans.Commit();
Vector3d vec1 = pt2 - pt1;
ed.WriteMessage(vec1.ToString()+"\n");

while (true)
{
   ptOpts = new PromptPointOptions("\n选择第三点C");
   ptRes = ed.GetPoint(ptOpts);
   if (ptRes.Status != PromptStatus.OK)
   {
    throw new Autodesk.AutoCAD.Runtime.Exception();
   }
   Point3d pt3 = ptRes.Value;
   Vector3d vec2 = pt3 - pt1;
   
   //向量叉乘
   double result = vec2.X*vec1.Y-vec1.X*vec2.Y;
   
   if (result>0)
   {
    ed.WriteMessage("C点在AB线右侧");
   }else if (result<0)
   {
    ed.WriteMessage("C点在AB线左侧");
   }else if (result==0)
   {
    ed.WriteMessage("C点在AB线上");
   }
}
}
}
public static ObjectId AppendEntity(Entity ent)
{
Database db = HostApplicationServices.WorkingDatabase;
ObjectId entid;
using (Transaction trans = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId,OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt,OpenMode.ForWrite);
entid = btr.AppendEntity(ent);
trans.AddNewlyCreatedDBObject(ent,true);
trans.Commit();
}
return entid;
}

cdinten 发表于 2012-12-7 22:42:34

语句:
double result = vec2.X*vec1.Y-vec1.X*vec2.Y;
考虑Vector3d结构体的方法CrossProduct 之后向量的Length==0,
另外,还可以使用IsParallelTo方法,看向量AC和向量CB是不是平行的,一旦平行必定共线。
思想不错,但是你抛出异常不处理让我感觉不太好,而且一旦半路取消就会有异常抛出。

cdinten 发表于 2012-12-7 22:50:45

另外,还要啰嗦一下,你的代码和我说的方法都对于点在线段的延长线和在线段上是区分不出来的,呵呵
你可以使用Length属性

cdinten 发表于 2012-12-7 22:51:58

看样子你是新学习这个的吧,觉得有时间可以考虑一下我说的意见,当个练习,祝你成功

白糖 发表于 2012-12-7 22:52:49

cdinten 发表于 2012-12-7 22:42 static/image/common/back.gif
语句:
double result = vec2.X*vec1.Y-vec1.X*vec2.Y;
考虑Vector3d结构体的方法CrossProduct 之后向量的 ...

谢谢提醒,还是不够严谨~
但是我装的是AutoCAD 2007,没有叉乘方法~
共线判断确实可行啊!

cdinten 发表于 2012-12-7 22:55:20

白糖 发表于 2012-12-7 22:52 static/image/common/back.gif
谢谢提醒,还是不够严谨~
但是我装的是AutoCAD 2007,没有叉乘方法~
共线判断确实可行啊!

哦,对的,我没看仔细,不过水平线怎么分左右侧?

白糖 发表于 2012-12-7 23:07:58

cdinten 发表于 2012-12-7 22:55 static/image/common/back.gif
哦,对的,我没看仔细,不过水平线怎么分左右侧?

我个人理解的左右,其实是指的顺时针方向的点在右侧,逆时针方向的在左侧
这样说不知道你是否认同~

cdinten 发表于 2012-12-7 23:17:29

白糖 发表于 2012-12-7 23:07 static/image/common/back.gif
我个人理解的左右,其实是指的顺时针方向的点在右侧,逆时针方向的在左侧
这样说不知道你是否认同~

嗯,相当于角度的正负方向

mkhsj928 发表于 2012-12-10 10:47:47

左右之分不是以顺时针和逆时针来分,而是以曲线的走向来分。
页: [1]
查看完整版本: 判断点与线段位置关系