URAL 1348 求垂足

题意:

就是求点到线段的最短和最长距离。如果最短距离比L大,输出L - MIN 否则输出0。最长距离也是。

 

题解:

利用坐标旋转+向量的点积求投影向量从而得到垂足。这样做的精度远远高于解析几何方法,而且不用考虑任何边界情况~

ym applepi!!~

 

View Code
  1 #include <iostream>

  2 #include <cstring>

  3 #include <cstdlib>

  4 #include <algorithm>

  5 #include <cstdio>

  6 #include <cmath>

  7 

  8 #define PI 3.14159265358979

  9 #define EPS 1e-4

 10 

 11 using namespace std;

 12 

 13 struct PO

 14 {

 15     double x,y;

 16 };

 17 

 18 struct LI

 19 {

 20     PO a,b;

 21 }li[5];

 22 

 23 double len;

 24 

 25 inline void read()

 26 {

 27     scanf("%lf%lf%lf%lf%lf%lf%lf",&li[1].a.x,&li[1].a.y,&li[1].b.x,&li[1].b.y,&li[2].a.x,&li[2].a.y,&len);

 28 }

 29 

 30 inline int doublecmp(double x)

 31 {

 32     if(x>EPS) return 1;

 33     else if(x<-EPS) return -1;

 34     return 0;

 35 }

 36 

 37 inline double dot(PO &a,PO &b,PO &c)

 38 {

 39     return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y);

 40 }

 41 

 42 inline double cross(PO &a,PO &b,PO &c)

 43 {

 44     return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);

 45 }

 46 

 47 inline double getlen(PO &a)//向量的模 

 48 {

 49     return sqrt(a.x*a.x+a.y*a.y);

 50 }

 51 

 52 inline double getdis(PO &a,PO &b)

 53 {

 54     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));

 55 }

 56 

 57 inline PO getty(PO b,PO a)//投影向量 

 58 {

 59     PO res=a;

 60     double k=dot(li[0].a,a,b)/(getlen(a)*getlen(a));

 61     res.x*=k; res.y*=k;

 62     return res;

 63 }

 64 

 65 inline PO rotate(PO a,double hd)//旋转 

 66 {

 67     PO c;

 68     c.x=a.x*cos(hd)-a.y*sin(hd);

 69     c.y=a.x*sin(hd)+a.y*cos(hd);

 70     return c;

 71 }

 72 

 73 inline void go()

 74 {

 75     if(doublecmp(cross(li[1].a,li[1].b,li[2].a))==0)//在线段所在直线上 

 76     {

 77         if(doublecmp(dot(li[2].a,li[1].a,li[1].b))<=0)//在线段上 

 78         {

 79             puts("0.00");

 80             printf("%.2f\n",max(0.0,max(getdis(li[1].a,li[2].a),getdis(li[1].b,li[2].a))-len));

 81         }

 82         else

 83         {

 84             double a=getdis(li[1].a,li[2].a)-len;

 85             double b=getdis(li[1].b,li[2].a)-len;

 86             if(a>b) swap(a,b);

 87             printf("%.2f\n%.2f\n",max(a,0.0),max(b,0.0));

 88         }

 89     }

 90     else

 91     {

 92         li[2].b.x=li[1].b.x-li[1].a.x;

 93         li[2].b.y=li[1].b.y-li[1].a.y;

 94         li[2].b=rotate(li[2].b,-PI*0.5);

 95         PO s=li[1].b;

 96         s.x-=li[2].a.x;

 97         s.y-=li[2].a.y;

 98         PO ty=getty(s,li[2].b);

 99         PO t;

100         t.x=li[2].a.x+ty.x;

101         t.y=li[2].a.y+ty.y;

102         if(doublecmp(dot(t,li[1].a,li[1].b))<=0)//垂足在线段上 

103         {

104             printf("%.2lf\n",max(0.0,getlen(ty)-len));

105             printf("%.2lf\n",max(0.0,max(getdis(li[1].a,li[2].a),getdis(li[1].b,li[2].a))-len));

106         }

107         else

108         {

109             double a=getdis(li[1].a,li[2].a)-len;

110             double b=getdis(li[1].b,li[2].a)-len;

111             if(a>b) swap(a,b);

112             printf("%.2lf\n%.2lf\n",max(a,0.0),max(b,0.0));

113         }

114     }

115 }

116 

117 int main()

118 {

119     read(),go();

120     return 0;

121 }

 

 

 

你可能感兴趣的:(r)