点到线段的距离计算方法

本文介绍了点C到线段AB距离的计算方法,包括点在线段上、点不在线段上的两种情况。对于点不在线段上时,可以通过垂线与线段的交点D来判断位置关系。文中提到了数学计算法和向量叉积法,其中向量法是最简单的方法。点积和向量的几何定义也被详细阐述,用于确定两个向量之间的角度关系。

点C到线段AB的距离计算有以下几种计算方法

和点到直线的距离计算方式不一样,直线是无限延伸的所以直接计算即可,但由于点和线段的位置不确定,所以我们不管使用何种办法都需要判断点和线段的位置关系,其存在以下几种关系:

第一种:点在线段上没啥好说的判断一下即可

第二种:点不在线段上:点C向线段AB做垂线,与线段AB所在直线的交点为D

       第一类:D点不在线段上,一种可能是在A点这边,另一种在B点这边

     第二类:D点在线段AB上如下

第一种最好想到的:数学计算方式,需要高中知识即可求解,先判断点和线段的关系属于哪一种,从在线段上再到上面的,然后进行计算,判断点到线段方向的垂线是否落在线段上的方法是通过比较横纵坐标的方式来判断。这种方法思路简单,比较容易理解,但是由于需要计算的东西比较多,设计的计算量比较大,计算比较复杂,所以我们一般是不会采用这种计算方式。

第二种

第三种利用叉积点积向量法来做,这种方法感觉有点复杂(PS:实际是自己太菜了)但是是最简单的一种方法

这个图只是其中一种情况其它的都大差不差,不在一一列举,这里我们用点积判断

点积:(是一个标量,不需要考虑方向)

代数定义

设二维空间内有两个向量 和 ,定义它们的数量积(又叫内积、点积)为以下实数

更一般地,n维向量的内积定义如下: 

几何定义

设二维空间内有两个向量 和 和 表示向量a和b的大小,它们的夹角为 则内积定义为以下实数:该定义只对二维和三维空间有效。

这个运算可以简单地理解为:在点积运算中,第一个向量投影到第二个向量上(这里,向量的顺序是不重要的,点积运算是可交换的),然后通过除以它们的标量长度来“标准化”。这样,这个分数一定是小于等于1的,可以简单地转化成一个角度值。

这里可得到角的余弦值=/()因为分母肯定大于0所以我们只需要判断向量ab积的正负即可

正为锐角,0为垂直,负为钝角

代码:

#include<set>
#include<map>
#include<ctime>
#include<stack>
#include<queue>
#include<cmath>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f
#define bug  printf("bug\n")
const int maxn=1e6+10;
const double pi=acos(-1.0);
const double esp=1e-6;
const int N=2e2+10;
struct point
{
    double x,y;
};
struct line
{
    point st,ed;
    double k,b;
};
int sign(double x)
{
    if(fabs(x)<esp)
        return 0;
    return x>0?1:-1;
}
double dis(point a,point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double cmult(point a,point b,point c)///叉积
{
    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
double pmult(point a,point b)///点积 这里的ab表示的是向量
{
    return a.x*b.x+a.y*b.y;
}
///如何判断点是否在线段上且距离线段的最短距离是多少
double pldis(point a,line l)
{
    point s1,s2,s3;
    s1.x=l.ed.x-l.st.x,s1.y=l.ed.y-l.st.y;
    s2.x=a.x-l.st.x,s2.y=a.y-l.st.y;
    s3.x=a.x-l.ed.x,s3.y=a.y-l.ed.y;
    if(l.st.x==l.ed.x&&l.st.y==l.ed.y)
        return dis(a,l.st);
    if(sign(pmult(s1,s2))<0)///两向量成钝角
        return dis(a,l.st);
    else if(sign(pmult(s1,s3))>0)
        return dis(a,l.ed);
    else///该处为c在线段上方
        return fabs(cmult(l.st,a,l.ed))/dis(l.st,l.ed);///两向量组成的三角形的面积为此两向的叉积的二倍,所以知道面积和底边就可以求出高
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值