最近一直在写关于几何方面的代码。涉及到一些非常基础的计算。如在二维世界中,直线和直线的交点。之前一直没有太多优化这段代码。

直线表达:一般直线的表达为 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 A1​x+B1​y+C1​=0A2​x+B2​y+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​∗B1​B1​∗C2​−B2​∗C1​​y=A1​∗B2​−A2​∗B1​A2​∗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​−y0​B=x0​−x1​C=−(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)相关推荐

  1. C++line segment intersection线段求交(交点)(附完整源码)

    C++line segment intersection线段求交的实现 C++line segment intersection线段求交实现的完整源码(定义,实现,main函数测试) C++line ...

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

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

  3. n条直线相交最多有几个邻补角_【东升二中数字课堂】创意微课直线的交点|Super数学璐...

    感谢您关注洛阳东升二中官方微信!如果您尚未关注,请点击图片上方的文字"洛阳市东升第二中学",加关注! 课题名称  |  <直线的交点> 授课教师  |  王璐 制作团队 ...

  4. 判断两条线段/直线相交,并求交点

      一.矢量基本知识     因为后面的计算需要一些矢量的基本知识,这里只是简单的列举如下,如果需要更加详细的信息,可以自行搜索wikipedia或google. 1.矢量的概念:如果一条线段的端点是 ...

  5. 两条直线相交的证明以及交点的求解

    一.两条直线相交的证明: 首先我们要知道向量的叉乘,向量的叉乘得到的也是一个向量,其值为以最初的两条向量为临边的平行四边形的面积,方向根据右手定则得出. 知道了这个就可以证明了,具体的看以下的图片 从 ...

  6. 两相交的直线段夹角平分的直线上过交点距离为d的另一点求解公式

    两相交的直线段夹角平分的直线上过交点距离为d的另一点求解公式 问题描述: 已知p0,p1,pN三个点,p0到p1走向直线段,pN到p0走向直线段,相交于p0点, 则pN到p0到p1夹角为a,平分夹角为 ...

  7. 布雷森汉姆直线演算法(Bresenham‘s line algorithm)介绍

    布雷森汉姆直线演算法(Bresenham's line algorithm)是用来描述两点间决定一条直线的算法,本人发现它可以用于确定栅格地图中两点间直线经过的栅格位置,它会算出一条线段在点阵图上最接 ...

  8. php判断直线相交,zoj 1158 判断2线段完全相交

    一个正方形的古老墓园,有n面墙,墙的端点都在正方形的边上.已知墓碑的地点(x,y),问从外面一直到达墓碑至少要凿开几个门,而且规定门只能凿在当前点段的中点. 思路很巧妙,因为从一个点到终点不可能&qu ...

  9. 判断线段和直线相交 POJ 3304

    1 // 判断线段和直线相交 POJ 3304 2 // 思路: 3 // 如果存在一条直线和所有线段相交,那么平移该直线一定可以经过线段上任意两个点,并且和所有线段相交. 4 5 #include ...

最新文章

  1. Arduino超声波测距程序
  2. 金蝶结账时显示系统错误h80004005_干货!超详细操作流程!金蝶、用友日常账务处理大全!...
  3. 【CodeForces - 1A】Theatre Square(水题,几何)(CODEFORCES,梦的开始)
  4. 管理系统中计算机应用 重点章节,11年《管理系统中计算机应用》 第5章 重点要点.doc...
  5. 宏基因组大数据分析的质量控制流程规范
  6. php下的jsonp使用实例
  7. 一位AI研究员+区块链创业者的终极展望:AI DAO将统治世界
  8. BeanFactory和FactoryBean
  9. git detached head
  10. Java简易开发环境搭建
  11. Oracle VM VirtualBox UUID already exists 问题解决
  12. 29. 在magento CMS中的标签变量使用
  13. Android 加载数据等待时 小人奔跑进度动画
  14. FLASH闪存文件系统研究
  15. 互联网产品设计思路参考
  16. 如何一条命令查询笔记本电池损耗情况-生成报告
  17. CAN总线通信学习笔记
  18. RGB565,RGB8888等相关
  19. EasyX 如何使用 Win32 控件
  20. Multi-modal Transformer for Video Retrieval

热门文章

  1. 服务器网络协议是什么,介绍网络协议,什么是网络协议三要素?
  2. 浅谈计算机应用的认识,浅谈《计算机应用基础》教学
  3. 嵌入式工程师的日常是啥样的?就业现状如何?
  4. Autofac简单介绍
  5. 【Microsoft Visual Studio】安装教程超详解
  6. nodejs学习笔记--Unexpected end of JSON input while parsing near ‘...“解决方法
  7. mac 关闭系统完整性保护 SIP(System Integrity Protection)的方法
  8. Android GPS根据经度获取时区
  9. 深度学习网络结构笔记----Depthwise卷积与Pointwise卷积--深度可分卷积-- GoogleNet,Xception,MobileNetv1--v3
  10. 解决@Autowired警告