明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 5221|回复: 8

判断点与线段位置关系

[复制链接]
发表于 2012-12-7 22:02 | 显示全部楼层 |阅读模式
通过简单的向量计算判断点与线段位置关系,没有设置点到线段距离容差,所以点击线段时不会判断在线段上

  1. [CommandMethod("test")]
  2. public void Test()
  3. {
  4. Database db = HostApplicationServices.WorkingDatabase;
  5. Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;

  6. using (Transaction trans = db.TransactionManager.StartTransaction())
  7. {
  8.   PromptPointOptions ptOpts = new PromptPointOptions("选择第一点A");
  9.   PromptPointResult ptRes = ed.GetPoint(ptOpts);
  10.   if (ptRes.Status != PromptStatus.OK)
  11.   {
  12.    throw new Autodesk.AutoCAD.Runtime.Exception();
  13.   }
  14.   Point3d pt1 = ptRes.Value;
  15.   
  16.   ptOpts = new PromptPointOptions("\n选择第二点B");
  17.   ptRes = ed.GetPoint(ptOpts);
  18.   if (ptRes.Status != PromptStatus.OK)
  19.   {
  20.    throw new Autodesk.AutoCAD.Runtime.Exception();
  21.   }
  22.   Point3d pt2 = ptRes.Value;
  23.   
  24.   //生成AB线段
  25.   Line lineAB = new Line(pt1,pt2);
  26.   AppendEntity(lineAB);
  27.   trans.Commit();
  28.   Vector3d vec1 = pt2 - pt1;
  29.   ed.WriteMessage(vec1.ToString()+"\n");
  30.   
  31.   while (true)
  32.   {
  33.    ptOpts = new PromptPointOptions("\n选择第三点C");
  34.    ptRes = ed.GetPoint(ptOpts);
  35.    if (ptRes.Status != PromptStatus.OK)
  36.    {
  37.     throw new Autodesk.AutoCAD.Runtime.Exception();
  38.    }
  39.    Point3d pt3 = ptRes.Value;
  40.    Vector3d vec2 = pt3 - pt1;
  41.    
  42.    //向量叉乘
  43.    double result = vec2.X*vec1.Y-vec1.X*vec2.Y;
  44.    
  45.    if (result>0)
  46.    {
  47.     ed.WriteMessage("C点在AB线右侧");
  48.    }else if (result<0)
  49.    {
  50.     ed.WriteMessage("C点在AB线左侧");
  51.    }else if (result==0)
  52.    {
  53.     ed.WriteMessage("C点在AB线上");
  54.    }
  55.   }
  56. }
  57. }
  58. public static ObjectId AppendEntity(Entity ent)
  59. {
  60. Database db = HostApplicationServices.WorkingDatabase;
  61. ObjectId entid;
  62. using (Transaction trans = db.TransactionManager.StartTransaction())
  63. {
  64.   BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId,OpenMode.ForRead);
  65.   BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace],OpenMode.ForWrite);
  66.   entid = btr.AppendEntity(ent);
  67.   trans.AddNewlyCreatedDBObject(ent,true);
  68.   trans.Commit();
  69. }
  70. return entid;
  71. }

发表于 2012-12-7 22:42 | 显示全部楼层
语句:
double result = vec2.X*vec1.Y-vec1.X*vec2.Y;
考虑Vector3d结构体的方法CrossProduct 之后向量的Length==0,
另外,还可以使用IsParallelTo方法,看向量AC和向量CB是不是平行的,一旦平行必定共线。
思想不错,但是你抛出异常不处理让我感觉不太好,而且一旦半路取消就会有异常抛出。
发表于 2012-12-7 22:50 | 显示全部楼层
另外,还要啰嗦一下,你的代码和我说的方法都对于点在线段的延长线和在线段上是区分不出来的,呵呵
你可以使用Length属性
发表于 2012-12-7 22:51 | 显示全部楼层
看样子你是新学习这个的吧,觉得有时间可以考虑一下我说的意见,当个练习,祝你成功
 楼主| 发表于 2012-12-7 22:52 | 显示全部楼层
cdinten 发表于 2012-12-7 22:42
语句:
double result = vec2.X*vec1.Y-vec1.X*vec2.Y;
考虑Vector3d结构体的方法CrossProduct 之后向量的 ...

谢谢提醒,还是不够严谨~
但是我装的是AutoCAD 2007,没有叉乘方法~
共线判断确实可行啊!
发表于 2012-12-7 22:55 | 显示全部楼层
白糖 发表于 2012-12-7 22:52
谢谢提醒,还是不够严谨~
但是我装的是AutoCAD 2007,没有叉乘方法~
共线判断确实可行啊!

哦,对的,我没看仔细,不过水平线怎么分左右侧?
 楼主| 发表于 2012-12-7 23:07 | 显示全部楼层
cdinten 发表于 2012-12-7 22:55
哦,对的,我没看仔细,不过水平线怎么分左右侧?

我个人理解的左右,其实是指的顺时针方向的点在右侧,逆时针方向的在左侧
这样说不知道你是否认同~
发表于 2012-12-7 23:17 | 显示全部楼层
白糖 发表于 2012-12-7 23:07
我个人理解的左右,其实是指的顺时针方向的点在右侧,逆时针方向的在左侧
这样说不知道你是否认同~

嗯,相当于角度的正负方向
发表于 2012-12-10 10:47 | 显示全部楼层
左右之分不是以顺时针和逆时针来分,而是以曲线的走向来分。

点评

对头!  发表于 2012-12-11 11:04
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-5 03:31 , Processed in 0.916882 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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