(伪)点到线段的距离 C++

本文探讨了点到线段距离的计算问题,分析了特殊情况并提供了C++代码实现。通过判断三角形形状辅助理解,并在代码中发现并修正了一个错误,最后提出使用海伦公式计算面积来确定距离。

之前写过一篇关于点到直线距离的文章,这回我来研究一下点到线段距离

 

回顾一下,推导出的点到直线距离公式为:

详细请见原博客

 

分析

在某种情况下,线段外一点P到线段AB的距离可以看做上述P到直线AB的距离:

就像这样子:

但是这样却不行(蓝线为实际距离,红线为到直线距离):

 

不难看出:

三角形ABP的形状点到线段的距离
锐角三角形P到直线AB的距离
直角三角形

PA,PB的较小者;P到直线AB的距离

钝角三角形PA,PB的较小者

 

 

如图所示。

 

判断三角形的形状

不妨设三边中,最短的两边为a,b,最长边为c。

不难想到,判断直角三角形,就用勾股定理:

对于锐角三角形:

同理推出,在钝角三角形中,

接下来,便是令人兴奋的代码了。

代码

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
double dist(double x1,double x2,double y1,double y2)
{return sqrt(pow(x2-x1,2)+pow(y2-y1,2));}//返回(x1,y1),(x2,y2)之间的距离 
int main()
{
	double x1,x2,x3,y1,y2,y3;
	/*A(x1,y1)
	  B(x2,y2)
	  P(x3,y3)*/
	cin>>x1>>y1>>x2>>y2>>x3>>y3;
	//判断三角形形状
	double a,b,c,d;
	a=dist(x1,x2,y1,y2);
	b=dist(x2,x3,y2,y3);
	c=dist(x1,x3,y1,y3);
	if(c<a or c<b)
	{
		if(c<a)
		{
			int t=a;
			a=c;
			c=t;
		}
		if(c<b)
		{
			int t=b;
			b=c;
			c=t;
		}
	}
	if(a*a+b*b<=c*c)//直角三角形或钝角三角形 
	d=min(dist(x1,x3,y1,y3),dist(x2,x3,y2,y3));
	else
	d=sqrt(pow((x3-x1)*(y2-y1)+(y3-y1)*(x1-x2),2)/(pow(y2-y1,2)+pow(x1-x2,2)));
	printf("%.3lf",d);
	return 0;
}

但是... ...

 

有2个测试点没过。80分。

 

是哪儿出了问题呢?

 

#以下是改来改去的过程。比较乱。请选择性阅读。#

 

[灵光一闪]   哦!会不会是没考虑到点在线段(所在直线)上的情况呢?

返回判断三角形的那一步,我们考虑一下这种情况。

让我来改一下代码。

if(a*a+b*b<=c*c)//直角三角形或钝角三角形 
	{
		d=min(dist(x1,x3,y1,y3),dist(x2,x3,y2,y3));
		if(a+b==c)//点在线段上
		d=0; 
	}

在此做修改(原代码36行)。

看看对不对呢......?!

 

 

Emmm mmmm mmmm... ... ...(不要急不要急不要急)

[灵光再现] 我使了个坏。看到锐角三角形部分有些乱,会不会是那里错了?

于是我把else后面的计算部分删了,交了上去。

哈哈哈哈!找到了!还是80分,也就是说,是else后的计算错了!

 

让我来换个思路。

由于d是P垂直AB的长度,即AB边上的高,所以通过面积法即可求出!

不知道大家知不知道,有一条根据边长计算面积的公式,叫海伦公式

于是,求出面积,除以AB即可。

if(a*a+b*b>c*c)
{
	int p=(dist(x1,x2,y1,y2)+dist(x1,x3,y1,y3)+dist(x3,x2,y3,y2));
	int s=sqrt(p*(p-dist(x1,x2,y1,y2))*(p-dist(x3,x2,y3,y2))*(p-dist(x1,x3,y1,y3)));
	d=s/dist(x1,x2,y1,y2);
}

 

。。。还是80分。(烂尾警告)

等我!我会搞好的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值