空间判断点是否在线段上

简介: 空间判断点是否在线段上

空间判断点是否在线段上

目录

1. 概述

判断点是否在线段上的算法非常简单,有很多种实现方式,总结一下我自己的实现。

2. 详论

个人认为通过向量计算的方式是比较好的,因为可以保证在二维和三维的情况都成立。判断空间中点P是否在线段P1P2上,算法思想是分成两部分:

  1. 计算P1P2�1�2→P1P�1�→的向量叉积,可以判断是否存在一条直线上。原理是向量叉积的模(长度)表示两个向量组成的平面四边形的面积,如果叉积的模为0,说明两者共线,无法组成平行四边形。
  2. 计算向量点积,点积的几何意义是一个向量向另外一个向量的投影;如果满足如下公式,说明是在两个端点之间:

0<P1PP1P2<||P1P2||20<�1�→⋅�1�2→<||�1�2→||2

具体的代码实现如下所示:

#include <Eigen/Eigen>
#include <iostream>
using namespace Eigen;
using namespace std;
using LineSegment = Vector2d[2];
const double epsilon = 0.000000001;
//判断点在线段上
bool PointInLine(const Vector2d& point, const LineSegment& lineSegment) {
  Vector3d P1P2;
  P1P2 << lineSegment[1] - lineSegment[0], 0;
  Vector3d P1P;
  P1P << point - lineSegment[0], 0;
  if (fabs((P1P2.cross(P1P)).norm()) > epsilon) {
    return false;
  }
  double dotProduct = P1P2.dot(P1P);
  if (dotProduct > 0 && dotProduct < P1P2.squaredNorm()) {
    return true;
  }
  return false;
}
int main() {
  // LineSegment lineSegment;
  // lineSegment[0] = Vector2d(0, 0);
  // lineSegment[1] = Vector2d(50, 100);
  // Vector2d c(25, 50);
  // Vector2d d(0, 8);
  LineSegment lineSegment;
  lineSegment[0] = Vector2d(2.6, 1.5);
  lineSegment[1] = Vector2d(24.5, 80.6);
  Vector2d ld = lineSegment[1] - lineSegment[0];
  Vector2d c = lineSegment[0] + 0.46 * ld;
  Vector2d d(0, 8);
  cout << PointInLine(c, lineSegment) << endl;
  // cout << PointInLine(d, lineSegment) << endl;
}

说明一下代码实现:

  1. 使用了Eigen中的矢量类,其实自己使用其他库的矢量类或者自己实现也是可以的。
  2. 内置浮点型的精度有限,因此设置epsilon作为容差。
  3. 由于是使用向量计算,因而是可以拓展到三维空间中使用的。

3. 参考

  1. 判断点是否在线段上
  2. How can you determine a point is between two other points on a line segment?

分类: 计算几何

标签: , 计算几何 , 线段


相关文章
|
前端开发 API C#
C#使用外部字体、嵌入字体到程序资源中(Winform)及字体的版权问题
应用程序能够使用一个好的字体,是用户界面很重要的一部分,但是很多字体如果系统没有安装,则需要额外引入,这就涉及到极其重要的字体版权问题,及额外字体的使用和安装。最好的方式应该是将字体嵌入到程序中...
6221 1
C#使用外部字体、嵌入字体到程序资源中(Winform)及字体的版权问题
|
存储 Oracle Java
Maven高级-私服简介与安装及私服仓库分类
Maven高级-私服简介与安装及私服仓库分类
338 0
|
数据可视化 JavaScript 前端开发
推荐8个炫酷的数据可视化大屏项目
推荐8个炫酷的数据可视化大屏项目
6264 1
|
图形学
ThreeJs创建管道效果
这篇文章介绍了在Three.js中创建管道(Tube)效果的方法和技术细节。
626 4
ThreeJs创建管道效果
MATLAB-Simulink仿真实现OFDM通信系统
【8月更文挑战第7天】本文介绍了在MATLAB-Simulink环境中实现OFDM通信系统仿真的方法,包括发送机、信道和接收机的设计,支持BPSK、QAM等多种调制方式,并考虑了Rician、AWGN、Rayleigh等信道模型。
1139 12
MATLAB-Simulink仿真实现OFDM通信系统
ThreeJs绘制圆柱体
这篇文章介绍了在Three.js中绘制圆柱体的方法,包括创建圆柱体几何体、设置材质以及将其正确放置在三维场景中的技巧。
524 0
ThreeJs绘制圆柱体
|
人工智能 自然语言处理 算法
|
Oracle 关系型数据库 分布式数据库
PolarDB 数据备份与恢复策略
【8月更文第27天】PolarDB 是阿里云推出的一款高性能、高可用的关系型数据库服务,支持 MySQL、PostgreSQL 和 Oracle 数据库引擎。对于任何数据库系统来说,数据的安全性和完整性至关重要。本文将详细介绍 PolarDB 的备份机制,并提供数据恢复的最佳实践。
963 0
|
机器学习/深度学习 人工智能 TensorFlow
如何将OpenCV与AI深度学习结合使用
如何将OpenCV与AI深度学习结合使用
867 1
射线法——判断一个点是否在多边形内部(适用于凸多边形和凹多边形)【关键原理解释+文字伪代码】
射线法——判断一个点是否在多边形内部(适用于凸多边形和凹多边形)【关键原理解释+文字伪代码】
1496 0