首页 > 其他分享 >数学——点到线段的最短距离

数学——点到线段的最短距离

时间:2023-08-22 19:56:47浏览次数:50  
标签:AB overrightarrow 线段 AP 短距离 sb 点到 向量

点到线段最短距离的运算与点到直线的最短距离的运算二者之间存在一定的差别,即求点到线段最短距离时需要考虑参考点在沿线段方向的投影点是否在线段上,若在线段上才可采用点到直线距离公式。

通俗的说,我们按照求点到直线的距离作垂线后,交点不一定在线段上。

如图 \(1\) 所示。

image

通常的方法有三种:

解析式法

该算法直接用高中时所学习到的解析几何知识对点到线段的距离进行求解。其基本思想是先判断点在线段端点、点在线上等等的特殊情况,逐步的由特殊到一般,当忽略点在线段上的特殊情况时,判断点到线段方向的垂线是否落在线段上的方法是通过比较横纵坐标的方式来判断,最后把不同的判断情况用不同的几何方式来进行处理计算得出结果。

具体过程是求线段所在直线的解析式,然后再求垂直于当前直线的直线的斜率,带入点求出解析式,求两直线交点,然后判断是不是在直线上,然后进行特判。

面积法

该方法主要是先判断投影点是否在线段上,投影点在线段延长线上时,最短距离长度为点到端点的线段长度;当投影点在线段上时,先使用海伦公式计算三角形面积,再计算出三角形的高,即为最短距离。

以上两种求法过于繁琐,而且在实现的过程中容易出现精度问题。

点名模拟退火

矢量法

由于矢量具有方向性,故一些方向的判断直接根据其正负号就可以得知,使得其中的一些问题得以很简单的解决。

用此方法考虑,我们只需要找到向量 $\overrightarrow{AP} $ 在 $\overrightarrow{AB} $ 方向上的投影,具体如下:

image

上面的 \(\frac{\overrightarrow{AB} }{|\overrightarrow{AB} |}\) 是 $\overrightarrow{AB} $ 方向上的单位向量,其意义是给所求向量确定方向。$(\overrightarrow{AP} \cdot \overrightarrow{AB} ) $ 是两个向量的内积,且 \((\overrightarrow{AP} \cdot \overrightarrow{AB} ) = |\overrightarrow{AP} ||\overrightarrow{AB} |\cos \theta\) ,其中 \(\theta\) 为向量 \(\overrightarrow{AP}\) 与 $\overrightarrow{AB} $ 之间的夹角。\(|\overrightarrow{AB} |\) 是向量长度。

那么 \(\frac{(\overrightarrow{AP}\cdot \overrightarrow{AB} )}{|\overrightarrow{AB} |} = \frac{|\overrightarrow{AP} ||\overrightarrow{AB} |\cos\theta}{|\overrightarrow{AB} |} = |\overrightarrow{AP} |\cos \theta\) 即为上图中线段 \(AC\) 的长度值,不带有方向性。此数值与上述表征方向的 \(\frac{\overrightarrow{AB} }{|\overrightarrow{AB} |}\) 整体构成有大小、有方向的新向量 $\overrightarrow{AC} $,即为 $\overrightarrow{AP} $ 在 $\overrightarrow{AB} $ 方向上的投影向量,\(C\) 为投影点。

根据得到的 \(r = \frac{(\overrightarrow{AP} \cdot \overrightarrow{AB})}{|\overrightarrow{AB} |^{2}}\),由向量的方向性可知:如果情况是上图 \((a)\) 所示,那么 \(0<r<1\);如果是如图 \((b)\) 所示的情况,那么 \(r \ge 1\);如果是如图 \((c)\) 所示的情况,那么得到 \(r \le 0\)。

特殊情况如点在线段上、点在端点、点在线段延长线上等等的情况全部适用于此公式,只是作为特殊情况出现,无需另作讨论。这也是矢量算法思想的优势所在。

故根据 \(r\) 值的不同,最短距离:

\[d = \left\{\begin{matrix} |\overrightarrow{AP} | & r\le 0\\ |\overrightarrow{BP} | & r\ge 1\\ |\overrightarrow{AC} | & 0 < r < 1 \end{matrix}\right. \]

c++ 代码:

#include <bits/stdc++.h>

#define int long long
#define DB double
#define N 10010

using namespace std;

int n;
DB ax, ay, ans;
 
struct sb
{
	DB x, y;
	inline DB len(){return sqrt(x * x + y * y);}
} a[N], b[N];
 
inline sb operator + (const sb &a, const sb &b){return (sb){a.x + b.x, a.y + b.y};}
inline sb operator - (const sb &a, const sb &b){return (sb){a.x - b.x, a.y - b.y};}
inline DB dot(sb a, sb b){return a.x * b.x + a.y * b.y;}
inline DB cross(sb a, sb b){return a.x * b.y - a.y * b.x;}
 
inline DB dis(sb p, sb a, sb b)
{
	sb x = p - a, y = p - b, z = b - a;//向量AP,BP,AB,终点坐标减起点坐标
	if(dot(x, z) < 0) return x.len();//AP在AB的投影向量与AB方向相反,AP向量的模
	else if (dot(y, z) > 0) return y.len();//BP在AB的投影向量与AB方向相同,BP向量的模
	else return fabs(cross(x, y)) / z.len();//利用叉积计算距离
}

参考:https://blog.csdn.net/angelazy/article/details/38489293

标签:AB,overrightarrow,线段,AP,短距离,sb,点到,向量
From: https://www.cnblogs.com/Multitree/p/17649549.html

相关文章

  • [Trick] [算法学习笔记] 线段树
    事先声明:本文并非线段树教学。只是一些理解Trick。若您需从0学起线段树建议您移步其他博文呢qwq感谢Idea提供尺子姐姐的博客!,尺子好闪,拜谢尺子!我们在学习线段树的时候,对于乘法“lazytag先乘再加”是不是难以理解?这里介绍一种线段树思考方法。我们可以将序列中的每个元素......
  • 线段树进阶
    多信息合并\(\text{GSS3Solution}\)\(\text{link}\)对于线段树的每个结点,记录其区间和(\(sum\)),区间前后缀最大子段和(\(lmax,rmax\))和区间最大子段和(\(vmax\))。合并:\[vmax=\max\{vmax_{lson},vmax_{rson},rmax_{lson}+lmax_{rson}\}\]\[lmax=\max\{lmax_{lson},sum_{lson}+lm......
  • 【学习笔记】优化建图相关(线段树优化,倍增优化)
    优化建图发现并没有人写得很详细的样子,那我也摆烂好惹点击查看目录目录前言线段树优化建图单点连区间区间连区间例题解题:倍增优化建图例题解题:前言众所周知,连边的时间复杂度一般是\(O(1)\),但,当连边的对象是一个连续的树上区间的时候,我们或许有更优的连边方式:优化建图。......
  • 大抄线段树历史值问题
    历史值问题历史值:在维护序列\(A\)的同时,在每次操作后,序列\(A\)会对序列\(B\)的对应位置产生贡献。历史版本和:每次操作后,\(B_i\leftarrowB_i+A_i\)。历史最大值:每次操作后,\(B_i=\max(B_i,A_i)\)。历史版本和:给定操作:①区间加。②查询区间和。③查询区间......
  • 【230820-1】▲ABC中,AC=根号二,BC=根号六,S△ABC=根号三/2,若线段BA上的延长线存在点D,使
    ......
  • 线段树与树状数组
    $$\texttt{线段树}$$OI-wikiLink线段树是一种用于维护区间信息的数据结构,可以在\(O(\logn)\)的复杂度下求出一个大小为\(n\)的数组的区间信息(如区间和、区间最大值等),也可以在同样时间复杂度下实现单点修改和区间修改等操作。基本结构:......
  • checkmin 线段树
    题意:给你一个长为\(n\)的序列\(a\),支持:1lrx:\(\foralla_i\in[l,r],a_i\gets\min(a_i,x)\)。2lr:求\(\sum_{i\in[l,r]}a_i\)。3lr:求\(\max_{i\in[l,r]}a_i\)。数据范围:\(n,m\le10^5\)。思路:考虑线段树,显然一个结点需要维护的基本信息为\(sum\)和......
  • dfs序线段树
    dfs序线段树1.树上操作思路遍历一整棵树,记录一下节点\(u\)的所对应的子树的节点数\(siz_u\)以及\(dfs\)序\(dfn_u\)根据整棵树的\(dfs\)序,我们可以把树变成了一个序列再维护线段树,\(\text{update(l,r,x)}\)表示将\([\text{l,r}]\)上值加上\(x\).\(\text{query(......
  • 杭电23多校第九场Capoo on tree(二分+树链剖分+可持久化线段树)
    2023HDU多校9__Capooontree(二分+树链剖分+可持久化线段树)题目链接Solution\(Hint1\)考虑如何进行对某一相同点权的所有点进行点权\(+1\)操作,如果我们建立权值线段树,那只需要将权值为\(x\)的点并入权值\(x+1\)即可,但是这样就算我们建立以节点编号为版本的可持久化线段树,也是......
  • 线段树&树状数组
    P4246首先注意到两个点应该怎么联通,有可能直接走进去对吧,也有可能是绕一圈走过去,我们考虑整个在求连通性的时候最重要的是哪些点,是左上角,左下角,右上角和右下角,所以我们考虑维护他们之间的连通性。然后连通性很好合并,所以我我们可以把这个东西搬上线段树维护一大段区间的四个角互......