数学——点到线段的最短距离
点到线段最短距离的运算与点到直线的最短距离的运算二者之间存在一定的差别,即求点到线段最短距离时需要考虑参考点在沿线段方向的投影点是否在线段上,若在线段上才可采用点到直线距离公式。
通俗的说,我们按照求点到直线的距离作垂线后,交点不一定在线段上。
如图
通常的方法有三种:
解析式法#
该算法直接用高中时所学习到的解析几何知识对点到线段的距离进行求解。其基本思想是先判断点在线段端点、点在线上等等的特殊情况,逐步的由特殊到一般,当忽略点在线段上的特殊情况时,判断点到线段方向的垂线是否落在线段上的方法是通过比较横纵坐标的方式来判断,最后把不同的判断情况用不同的几何方式来进行处理计算得出结果。
具体过程是求线段所在直线的解析式,然后再求垂直于当前直线的直线的斜率,带入点求出解析式,求两直线交点,然后判断是不是在直线上,然后进行特判。
面积法#
该方法主要是先判断投影点是否在线段上,投影点在线段延长线上时,最短距离长度为点到端点的线段长度;当投影点在线段上时,先使用海伦公式计算三角形面积,再计算出三角形的高,即为最短距离。
以上两种求法过于繁琐,而且在实现的过程中容易出现精度问题。
点名模拟退火
矢量法#
由于矢量具有方向性,故一些方向的判断直接根据其正负号就可以得知,使得其中的一些问题得以很简单的解决。
用此方法考虑,我们只需要找到向量
上面的
那么
根据得到的
特殊情况如点在线段上、点在端点、点在线段延长线上等等的情况全部适用于此公式,只是作为特殊情况出现,无需另作讨论。这也是矢量算法思想的优势所在。
故根据
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://www.cnblogs.com/Multitree/p/17649549.html
本站使用「CC BY 4.0」创作共享协议,转载请在文章明显位置注明作者及出处。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战