2.1. 解析几何算法
比如说,在平面中判断两线段相交,我们可以很容易通过解析几何来求解,联立两直线的代数方程:

(y−y2)/(y1−y2)=(x−x2)/(x1−x2)
然后对这个二元二次方程进行求解。很容易得到相应算法的代码:

//判断两线段相交
bool IsIntersect(double px1, double py1, double px2, double py2, double px3, double py3, double px4, double py4)
{
bool flag = false;
double d = (px2 - px1) * (py4 - py3) - (py2 - py1) * (px4 - px3);
if (d != 0)
{
double r = ((py1 - py3) * (px4 - px3) - (px1 - px3) * (py4 - py3)) / d;
double s = ((py1 - py3) * (px2 - px1) - (px1 - px3) * (py2 - py1)) / d;
if ((r >= 0) && (r <= 1) && (s >= 0) && (s <= 1))
{
flag = true;
}
}
return flag;
}
可以看出这个算法其实并不严密,其实缺少了对一些极端条件的判断,比如与坐标轴平行的情况,两直线平行的情况,还需要做额外的判断。同时用了很多乘法和除法,算法效率并不高。

2.2. 同侧法
这种算法的思想是:如果两条线段相交,那么一条线段的两端点必然位于另一条线段的两端点的异侧。那么问题就可以转换成点是否在一条线段的同侧。同侧判断可以通过向量叉乘的方法来实现,即判断最后叉乘的方向是否相同。

这个算法与平面中判断点在三角形内算法这篇文章介绍的同侧/异侧判断是一样的,我认为算是比较优秀快速的算法了。不过这个算法可以判断定性判断,无法定量判断准确的交点。而且实际使用过程中,似乎精度不太准确(个人实验结论,尤其是位于三角形边上的点)。

2.3. 向量方程法
2.3.1. 原理
已知空间中线段的起点O和终点E,那么显然方向向量D为:

D=E−O
这时,可以确定线段上某一点P为:

P=O+tD
其中,t为范围满足0<=t<=1的标量。

这个方程就是线段上某一点的向量方程。如果要求两线段的交点,很显然可以将两个线段进行联立:

{P=O1+t1D1P=O2+t2D2
上式-下式,有:

t1D1−t2D2=O2−O1=O12(1)
在平面上展开,也就是使用X和Y分量:

[D1.xD1.y−D2.x−D2.y][t1t2]=[O12.xO12.y]
那么这个问题就转换成了求解2行2列的线性方程组,如果有解,说明存在交点并直接求出。2行2列线性方程组直接使用克莱姆法则求解即可。

2.3.2. 实现
具体的C++实现代码如下:

//空间直线
template
class LineSegment
{
public:
Vec3 startPoint;
Vec3 endPoint;
Vec3 direction;

Vec3<T> min;
Vec3<T> max;LineSegment()
{
}LineSegment(Vec3<T> start, Vec3<T> end)
{startPoint = start;endPoint = end;direction = end - start;CalMinMax();
}inline void Set(Vec3<T> start, Vec3<T> end)
{startPoint = start;endPoint = end;direction = end - start;CalMinMax();
}inline void CalMinMax()
{min.x() = std::min<T>(startPoint.x(), endPoint.x());min.y() = std::min<T>(startPoint.y(), endPoint.y());min.z() = std::min<T>(startPoint.z(), endPoint.z());max.x() = std::max<T>(startPoint.x(), endPoint.x());max.y() = std::max<T>(startPoint.y(), endPoint.y());max.z() = std::max<T>(startPoint.z(), endPoint.z());
}//两条线段相交
inline static bool Intersection2D(LineSegment & line1, LineSegment & line2, Vec3<T>& insPoint)
{double D = -line1.direction.x() * line2.direction.y() + line1.direction.y() * line2.direction.x();if(D == 0.0){return false;}auto O12 = line2.startPoint - line1.startPoint;T D1 = -O12.x() * line2.direction.y() + O12.y() * line2.direction.x();T D2 = line1.direction.x() * O12.y() - line1.direction.y() * O12.x();T t1 = D1 / D;if(t1<0 || t1 > 1){return false;}T t2 = D2 / D;if(t2<0 || t2 > 1){return false;}insPoint = line1.startPoint + line1.direction * t1;     //这样计算得到的Z值是不准确的return true;
}

};
USB Microphone https://www.soft-voice.com/
Wooden Speakers https://www.zeshuiplatform.com/
亚马逊测评 www.yisuping.cn
深圳网站建设www.sz886.com

空间或平面判断两线段相交(求交点)相关推荐

  1. python求交点坐标_Python - 两圆相交求交点坐标

    Python - 两圆相交求交点坐标 Max.Bai 2016-05-16 Python - 两圆相交求交点坐标 三轴机械臂求坐标问题,其实转化为平面问题就是两圆相交求交点问题,交点算出来就可以用反三 ...

  2. 计算几何 快速排斥和跨立实验 判断两线段相交

    线段P1P2, Q1Q2,判断其是否相交,通过快速排斥和跨立实验则说明相交 首先要知道:向量a×向量b(×为向量叉乘),若结果小于0,表示向量b在向量a的逆时针方向:若结果大于0,表示向量b在向量a的 ...

  3. 判断两线段相交[nyoj 1016 德莱联盟]

    题目链接:点击打开链接 题目意思很简单,就是问两个线段是否可以相交. 思路很是简单,两个线段互相跨立就可以相交了.所谓跨立就是,一条线段的两个点在另一条线段的两侧. 这个题目的数据有点水,没有考虑到点 ...

  4. python判断两线段是否相交_c语言 判断两直线段是否相交

    转了多人的放到一起比较!! //功能:求点在有向直线左边还是右边 //返回:0共线.1左边.-1右边 intleft_right(pointa,pointb,doublex,doubley) { do ...

  5. python 求两线段是否相交,如果相交求交点

    代码如下,cal_point = False 不输出交点,cal_point = True 输出交点 def cross(p1,p2,p3):#跨立实验     x1=p2.x-p1.x     y1 ...

  6. [GIS算法] 判断两线段是否相交的四种方案(快速排斥+跨立实验、参数方程求解、凸多边形、点在线的哪一侧)-附C语言实现

    文章目录 算法一:快速排斥+跨立试验 代码 算法二:参数方程求解 代码 算法三:凸多边形 算法四:点在线的哪一侧 算法一:快速排斥+跨立试验 重点掌握 [原理]利用矢量的叉乘 [图解] 代码 #def ...

  7. hdu 1086(判断两线段是否相交)

    题意:给出一些线段,问有多少个交点. 解题思路:这里实际就是一个线段相交的模型,下面这个图给出了思路. 如果两线段相交,则两线段必然相互跨立对方.若P1P2跨立Q1Q2 ,则矢量 ( P1 - Q1 ...

  8. 判断平面上两直线相交

    直线相交 首先引出计算几何学中一个最基本的问题:如何判断向量在的顺时针方向还是逆时针方向? 把p0定为原点,p1的坐标是(x1,y1),p2的坐标是(x2,y2).向量的叉积(cross produc ...

  9. 两条直线求交点c语言,C§ 3.3.1两条直线的交点坐标(5页)-原创力文档

    § 3.1两条直线的交点坐标 学习目标 1.掌握判断两直线相交的方法:会求两直线交点坐标: 2.体会判断两直线相交中的数形结合思想. 学习过程 一.课前准备: (预习教材P112~ P114,找出疑 ...

  10. c语言直线和椭圆的交点,直线与椭圆相交求交点

    已知a,b和直线上的两点,中心在原点,求直线与椭圆相交求交点坐标 #include #include #include void main() { double a,b,c,x1,x2,y1,y2,k ...

最新文章

  1. 二分搜索 POJ 2456 Aggressive cows
  2. Chart.js-雷达图分析(参数分析+例图)
  3. 数组字段查询不包含_不可不知的可变Java长数组
  4. 执行插件超过2分钟超时错误,如何办?
  5. Socket.io发送消息含义
  6. jpa原生query_Spring Data JPA原生SQL查询
  7. (最短路)Shopping
  8. java http 双向认证_HttpsURLConnection使用,并实现双向认证
  9. python怎样清除csv中的数据_使用d清除CSV文件中的数据
  10. 宾州州立计算机科学世界排名,宾州州立大学帕克分校qs世界排名
  11. 原型设计工具——“墨刀”的介绍与基本教程
  12. OpenSSL环境搭建(WIN10+VS2017)
  13. 为啥翻唱的也特别好听呢,听J Fla 的 despacito
  14. PrometheusAlert安装和其基本的使用
  15. 拥抱AI!人工智能如何在疫情期间重塑娱乐业?
  16. 机械/仪表领域北大核心期刊(摘自第九版)
  17. 如何查看笔记本电池损耗情况-不借助软件
  18. 第二届先导杯-在曙光超算平台编译cp2k(二)
  19. 工业互联网如何做到增加30%营收还能节省80%成本?
  20. 史上最短命 Windows 系统!比尔盖茨研发,用过几乎都是差评...

热门文章

  1. 硬盘配置raid5时碰见unconfiguration bad问题记录
  2. 《正在爆发的互联网革命》
  3. 分享一下Android开发11年,我眼中程序员的三六九等
  4. 【全示例通过】防沉迷实名认证系统接口测试代码(包含Golang和Java版本)
  5. 智能家庭系统micropython实现2
  6. HackTheBox Behind The Scenes 逆向题目分析
  7. 我要自学网视频教程ajax,这么逆天的自学网站,还是第一次见,难怪考不上清华北大...
  8. 20120814打工者的悲哀
  9. linux awk 命令
  10. CET.4 一次过备考纪要