uva10263 Railway点到线段的最短距离

来源:互联网 发布:数据有效性 日期 编辑:程序博客网 时间:2024/05/22 14:21



#define DeBUG#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <vector>#include <stack>#include <queue>#include <string>#include <set>#include <sstream>#include <map>#include <bitset>using namespace std ;#define zero {0}#define INF 0x3f3f3f3f#define EPS 1e-6typedef long long LL;const double PI = acos(-1.0);//#pragma comment(linker, "/STACK:102400000,102400000")inline int sgn(double x){    return fabs(x) < EPS ? 0 : (x < 0 ? -1 : 1);}#define N 100005struct Point;typedef Point Vec;struct Point{    double x, y;    Point () {}    Point(double a, double b)    {        x = a;        y = b;    }    Vec operator + (const Vec &b)//点加法    {        return Vec(x + b.x, y + b.y);    }    Vec operator - (const Vec &b)//点减法    {        return Vec(x - b.x, y - b.y);    }    Vec operator * (const double &p)//点与常数相乘    {        return Vec(x * p, y * p);    }    Vec operator / (const double &p)//点除以常数    {        return Vec(x / p, y / p);    }    bool operator < (const Point &b)//平面直角坐标系中左下方的为小    {        return x < b.x || (sgn(x - b.x) == 0 && y < b.y);    }    bool operator == (const Point &b)//点相等判断    {        return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;    }};inline double crossDet(Vec a, Vec b)//叉乘{    return a.x * b.y - a.y * b.x;}inline double dotDet(Vec a, Vec b)//点乘{    return a.x * b.x + a.y * b.y;}inline double vecLen(Vec a)//求一点到原点距离{    return sqrt(dotDet(a, a));}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 pt2Line(Point x, Point a, Point b){    Vec v1 = b - a, v2 = x - a;    return fabs(crossDet(v1, v2) / vecLen(v1));}Point lineIntersect(Point P, Vec v, Point Q, Vec w)//直线相交返回交点{    Vec u = P - Q;    double t = crossDet(w, u) / crossDet(v, w);    return P + v * t;}Point ptOnLine(Point p, Point a, Point b)//p在ab上的投影点,不在ab上依然可以得到坐标{    Vec v = b - a;    return a + v * (dotDet(v, p - a) / dotDet(v, v));}bool onSeg(Point x, Point a, Point b)//判断点在线段ab上,加上||x==a||x==b在端点也算{    return sgn(crossDet(a - x, b - x)) == 0 && sgn(dotDet(a - x, b - x)) < 0 || x == a || x == b;}int main(){#ifdef DeBUGs    freopen("C:\\Users\\Sky\\Desktop\\1.in", "r", stdin);#endif    int n;    Point m;    while (scanf("%lf%lf", &m.x, &m.y) + 1)    {        int n;        scanf("%d", &n);        Point p1, p2;        scanf("%lf%lf", &p2.x, &p2.y);        double minn = INF;        Point it = p2;        Point pt;        for (int i = 1; i <= n; i++)        {            p1 = p2;            scanf("%lf%lf", &p2.x, &p2.y);            if (pt2Line(m, p1, p2) < minn)//到线段垂线最短,看交点是否在线端上            {                pt = ptOnLine(m, p1, p2);                if (onSeg(pt, p1, p2))                {                    minn = pt2Line(m, p1, p2);                    it = pt;                }            }            if (dis(p1, m) < minn)//不在线段上就取端点试试            {                minn = dis(p1, m);                it = p1;            }            if (dis(p2, m) < minn)            {                minn = dis(p2, m);                it = p2;            }        }        printf("%.4lf\n%.4lf\n", it.x, it.y);    }    return 0;}


0 0
原创粉丝点击