直线相交的交点(Line-Line Intersection)
最近一直在写关于几何方面的代码。涉及到一些非常基础的计算。如在二维世界中,直线和直线的交点。之前一直没有太多优化这段代码。
直线表达:一般直线的表达为 A x + B y + C = 0 Ax+By+C=0 Ax+By+C=0
两个直线的表达:
A 1 x + B 1 y + C 1 = 0 A 2 x + B 2 y + C 2 = 0 A_1x+B_1y+C_1=0 \\ A_2x+B_2y+C_2=0 A1x+B1y+C1=0A2x+B2y+C2=0
一般情况下直接计算方程组即可。使用高斯消元法得到:
x = B 1 ∗ C 2 − B 2 ∗ C 1 A 1 ∗ B 2 − A 2 ∗ B 1 y = A 2 ∗ C 1 − A 1 ∗ C 2 A 1 ∗ B 2 − A 2 ∗ B 1 x = \frac{ B_1 * C_2 - B_2 * C_1}{A_1 * B_2 - A_2 * B_1} \\ y = \frac{ A_2 * C_1 - A_1 * C_2}{A_1 * B_2 - A_2 * B_1} x=A1∗B2−A2∗B1B1∗C2−B2∗C1y=A1∗B2−A2∗B1A2∗C1−A1∗C2
c++代码如下:
#include <iostream>
#include<Eigen/Eigen>const double KMIN_DOUBLE_LINE_THRESHOLD = 1e-8;bool ComputeLine2LineIntersection(const Eigen::Vector3d& f1, const Eigen::Vector3d& f2, Eigen::Vector2d& pnt)
{double det = f1[0]*f2[1] - f2[0]*f1[1];if(std::abs(det) < KMIN_DOUBLE_LINE_THRESHOLD){return false;}else{double x = (f1[1]*f2[2] - f2[1]*f1[2]) / det;double y = (f2[0]*f1[2] - f1[0]*f2[2]) / det;pnt[0] = x;pnt[1] = y;return true;}
}int main(int argc, char** argv)
{Eigen::Vector3d a(1,2,3);Eigen::Vector3d b(4,5,6);Eigen::Vector2d p;ComputeLine2LineIntersection(a, b, p);std::cerr <<"pnt: " << p.transpose() << std::endl;return 0;
}
测试的结果(正确):
补充:如果线段的表达方式为:(用首位顶点表达方式)
l 1 : ( x 0 , y 0 ) − > ( x 1 , y 1 ) l_1: (x_0, y_0) -> (x_1,y_1) l1:(x0,y0)−>(x1,y1)
l 2 : ( x 2 , y 2 ) − > ( x 3 , y 3 ) l_2: (x_2, y_2) -> (x_3,y_3) l2:(x2,y2)−>(x3,y3)
需要转化到上面的通用表达方式表示为:
A = y 1 − y 0 B = x 0 − x 1 C = − ( A x 0 + B y 0 ) A = y_1-y_0 \\ B = x_0-x_1 \\ C =-( Ax_0+By_0) A=y1−y0B=x0−x1C=−(Ax0+By0)
转化函数如下:
//Ax+By+C=0(A,B,C)Eigen::Vector3d ComputeFunctionFromPnts(const Eigen::Vector2d& s, const Eigen::Vector2d& e){double A = e[1] - s[1];double B = s[0] - e[0];double C = -(A*s[0] + B*s[1]);return Eigen::Vector3d(A,B,C);}
融合到上面得到:
#include <iostream>
#include<Eigen/Eigen>const double KMIN_DOUBLE_LINE_THRESHOLD = 1e-8;bool ComputeLine2LineIntersection(const Eigen::Vector3d& f1, const Eigen::Vector3d& f2, Eigen::Vector2d& pnt)
{double det = f1[0]*f2[1] - f2[0]*f1[1];if(std::abs(det) < KMIN_DOUBLE_LINE_THRESHOLD){return false;}else{double x = (f1[1]*f2[2] - f2[1]*f1[2]) / det;double y = (f2[0]*f1[2] - f1[0]*f2[2]) / det;pnt[0] = x;pnt[1] = y;return true;}
}//Ax+By+C=0(A,B,C)
Eigen::Vector3d ComputeFunctionFromPnts(const Eigen::Vector2d& s, const Eigen::Vector2d& e)
{double A = e[1] - s[1];double B = s[0] - e[0];double C = -(A*s[0] + B*s[1]);return Eigen::Vector3d(A,B,C);
}int main(int argc, char** argv)
{Eigen::Vector2d s0(0.0,0.0);Eigen::Vector2d e0(1.0,1.0);Eigen::Vector2d s1(1.0,0.0);Eigen::Vector2d e1(0.0,1.0);Eigen::Vector3d a = ComputeFunctionFromPnts(s0,e0);Eigen::Vector3d b = ComputeFunctionFromPnts(s1,e1);Eigen::Vector2d p;ComputeLine2LineIntersection(a, b, p);std::cerr <<"pnt: " << p.transpose() << std::endl;return 0;
}
测试的结果(正确):
直线相交的交点(Line-Line Intersection)相关推荐
- C++line segment intersection线段求交(交点)(附完整源码)
C++line segment intersection线段求交的实现 C++line segment intersection线段求交实现的完整源码(定义,实现,main函数测试) C++line ...
- c语言直线和椭圆的交点,直线与椭圆相交求交点
已知a,b和直线上的两点,中心在原点,求直线与椭圆相交求交点坐标 #include #include #include void main() { double a,b,c,x1,x2,y1,y2,k ...
- n条直线相交最多有几个邻补角_【东升二中数字课堂】创意微课直线的交点|Super数学璐...
感谢您关注洛阳东升二中官方微信!如果您尚未关注,请点击图片上方的文字"洛阳市东升第二中学",加关注! 课题名称 | <直线的交点> 授课教师 | 王璐 制作团队 ...
- 判断两条线段/直线相交,并求交点
一.矢量基本知识 因为后面的计算需要一些矢量的基本知识,这里只是简单的列举如下,如果需要更加详细的信息,可以自行搜索wikipedia或google. 1.矢量的概念:如果一条线段的端点是 ...
- 两条直线相交的证明以及交点的求解
一.两条直线相交的证明: 首先我们要知道向量的叉乘,向量的叉乘得到的也是一个向量,其值为以最初的两条向量为临边的平行四边形的面积,方向根据右手定则得出. 知道了这个就可以证明了,具体的看以下的图片 从 ...
- 两相交的直线段夹角平分的直线上过交点距离为d的另一点求解公式
两相交的直线段夹角平分的直线上过交点距离为d的另一点求解公式 问题描述: 已知p0,p1,pN三个点,p0到p1走向直线段,pN到p0走向直线段,相交于p0点, 则pN到p0到p1夹角为a,平分夹角为 ...
- 布雷森汉姆直线演算法(Bresenham‘s line algorithm)介绍
布雷森汉姆直线演算法(Bresenham's line algorithm)是用来描述两点间决定一条直线的算法,本人发现它可以用于确定栅格地图中两点间直线经过的栅格位置,它会算出一条线段在点阵图上最接 ...
- php判断直线相交,zoj 1158 判断2线段完全相交
一个正方形的古老墓园,有n面墙,墙的端点都在正方形的边上.已知墓碑的地点(x,y),问从外面一直到达墓碑至少要凿开几个门,而且规定门只能凿在当前点段的中点. 思路很巧妙,因为从一个点到终点不可能&qu ...
- 判断线段和直线相交 POJ 3304
1 // 判断线段和直线相交 POJ 3304 2 // 思路: 3 // 如果存在一条直线和所有线段相交,那么平移该直线一定可以经过线段上任意两个点,并且和所有线段相交. 4 5 #include ...
最新文章
- Arduino超声波测距程序
- 金蝶结账时显示系统错误h80004005_干货!超详细操作流程!金蝶、用友日常账务处理大全!...
- 【CodeForces - 1A】Theatre Square(水题,几何)(CODEFORCES,梦的开始)
- 管理系统中计算机应用 重点章节,11年《管理系统中计算机应用》 第5章 重点要点.doc...
- 宏基因组大数据分析的质量控制流程规范
- php下的jsonp使用实例
- 一位AI研究员+区块链创业者的终极展望:AI DAO将统治世界
- BeanFactory和FactoryBean
- git detached head
- Java简易开发环境搭建
- Oracle VM VirtualBox UUID already exists 问题解决
- 29. 在magento CMS中的标签变量使用
- Android 加载数据等待时 小人奔跑进度动画
- FLASH闪存文件系统研究
- 互联网产品设计思路参考
- 如何一条命令查询笔记本电池损耗情况-生成报告
- CAN总线通信学习笔记
- RGB565,RGB8888等相关
- EasyX 如何使用 Win32 控件
- Multi-modal Transformer for Video Retrieval
热门文章
- 服务器网络协议是什么,介绍网络协议,什么是网络协议三要素?
- 浅谈计算机应用的认识,浅谈《计算机应用基础》教学
- 嵌入式工程师的日常是啥样的?就业现状如何?
- Autofac简单介绍
- 【Microsoft Visual Studio】安装教程超详解
- nodejs学习笔记--Unexpected end of JSON input while parsing near ‘...“解决方法
- mac 关闭系统完整性保护 SIP(System Integrity Protection)的方法
- Android GPS根据经度获取时区
- 深度学习网络结构笔记----Depthwise卷积与Pointwise卷积--深度可分卷积-- GoogleNet,Xception,MobileNetv1--v3
- 解决@Autowired警告