URAL 1348 Goat in the Garden 2(点到线段的距离)

【题目链接】:click here~~

【题目大意】:求某点到一条线段的最小距离与最大距离。

【思路】:

分析可知,最大距离一定在端点处取得。那么接下来求最小距离时,先求出垂线与线段所在直线的交点,然后判断交点在不在线段上。如果在,则最小距离为垂线段的距离,即交点到此点的距离。如果不在,则最小距离必在另一端点取得。问题转换如何判断点与线段的垂足是否在线段上,可以利用叉积方便的求出。

代码:

/*
* Problem: NO:URAL 1348
* Running time: 1MS
* Complier: G++
* Author: herongwei
* Create Time: 20:00 2015/10/4 星期日
*/
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
typedef long long LL;
using namespace std;

#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b

const double eps=1e-8;
const double pi=acos(-1.0);

int sgn(double x)
{
    if(fabs(x) < eps)return 0;
    if(x < 0)return -1;
    else return 1;
}

struct POINT //点
{
    double x,y;
    POINT(){}
    POINT(double _x ,double _y)
    {
        x = _x;
        y = _y;
    }
    POINT operator -(const POINT &b)const
    {
        return POINT(x - b.x, y - b.y);
    }
    double operator ^(const POINT &b)const
    {
        return x*b.y - y*b.x;
    }
};

struct Seg //线段
{
    POINT s,e;
    Seg(){}
    Seg(POINT _s,POINT _e)
    {
        s=_s;
        e=_e;
    }
};

struct Line//直线
{
    POINT s,e;
    Line(){}
    Line(POINT _s,POINT _e)
    {
        s=_s;
        e=_e;
    }
};

//叉乘
double cross(POINT o, POINT a, POINT b)
{
    return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);
}

//求两点间的距离
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 Point_to_Line(POINT p,Line l)
{
    return fabs(cross(p,l.s,l.e)) / dis(l.s,l.e);
}

// 点到线段的距离
double Point_to_Seg(POINT p,Seg s)
{
    POINT tmp=p;
    tmp.x += s.s.y-s.e.y;
    tmp.y += s.e.x-s.s.x;
    if(cross(s.s, p, tmp) * cross(s.e, p, tmp) >= 0) /// 叉积判断垂足是否在线段上
    {
        return min(dis(p, s.s), dis(p, s.e));
    }
    return Point_to_Line(p, Line(s.s, s.e));///垂足在线段上
}

Seg s;
POINT p;
double L;

void solve()
{
    double ans1=Point_to_Seg(p,s),ans2=max(dis(p,s.s),dis(p,s.e));
    ans1=ans1>L?ans1-L:0,ans2=ans2>L?ans2-L:0;
    printf("%.2f\n%.2f\n",ans1,ans2);
}

int main()
{
   while(cin>>s.s.x>>s.s.y>>s.e.x>>s.e.y)
   {
       cin>>p.x>>p.y>>L;solve();
   }
   return 0;
}

/*
input	output
8 -6 8 6
0 0 7
1.00
3.00
*/



你可能感兴趣的:(计算几何,点到线段距离)