HDU 5572--An Easy Physics Problem(射线和圆的交点)
Posted flyerbird
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5572--An Easy Physics Problem(射线和圆的交点)相关的知识,希望对你有一定的参考价值。
An Easy Physics Problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3845 Accepted Submission(s): 768
Problem Description
On an infinite smooth table, there‘s a big round fixed cylinder and a little ball whose volume can be ignored.
Currently the ball stands still at point A, then we‘ll give it an initial speed and a direction. If the ball hits the cylinder, it will bounce back with no energy losses.
We‘re just curious about whether the ball will pass point B after some time.
Currently the ball stands still at point A, then we‘ll give it an initial speed and a direction. If the ball hits the cylinder, it will bounce back with no energy losses.
We‘re just curious about whether the ball will pass point B after some time.
Input
First line contains an integer T, which indicates the number of test cases.
Every test case contains three lines.
The first line contains three integers Ox, Oy and r, indicating the center of cylinder is (Ox,Oy) and its radius is r.
The second line contains four integers Ax, Ay, Vx and Vy, indicating the coordinate of A is (Ax,Ay) and the initial direction vector is (Vx,Vy).
The last line contains two integers Bx and By, indicating the coordinate of point B is (Bx,By).
Every test case contains three lines.
The first line contains three integers Ox, Oy and r, indicating the center of cylinder is (Ox,Oy) and its radius is r.
The second line contains four integers Ax, Ay, Vx and Vy, indicating the coordinate of A is (Ax,Ay) and the initial direction vector is (Vx,Vy).
The last line contains two integers Bx and By, indicating the coordinate of point B is (Bx,By).
? 1 ≤ T ≤ 100.
? |Ox|,|Oy|≤ 1000.
? 1 ≤ r ≤ 100.
? |Ax|,|Ay|,|Bx|,|By|≤ 1000.
? |Vx|,|Vy|≤ 1000.
? Vx≠0 or Vy≠0.
? both A and B are outside of the cylinder and they are not at same position.
Output
For every test case, you should output "Case #x: y", where x indicates the case number and counts from 1. y is "Yes" if the ball will pass point B after some time, otherwise y is "No".
Sample Input
2 0 0 1 2 2 0 1 -1 -1 0 0 1 -1 2 1 -1 1 2
Sample Output
Case #1: No Case #2: Yes
先判断射线和圆交点个数,如果小于2再看是否B在A的前进方向上,没有则NO,否则YES。如果等于2,就先找到第一个交点,将这个交点和圆心连成直线,那么A的路径关于这条直线对称,那么如果A关于此直线的对称点在圆心->B路径上,则可以相撞,否则不行。
这里有一个小问题,如果反过来求B关于此直线的对称点在圆心->A路径上,是会WA的.
这里有一个小问题,如果反过来求B关于此直线的对称点在圆心->A路径上,是会WA的.
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include<algorithm> 5 #include <cstdlib> 6 #include <cmath> 7 using namespace std; 8 const double eps = 1e-8; 9 int sgn(double x) { 10 if (fabs(x) < eps)return 0; 11 if (x < 0)return -1; 12 else return 1; 13 } 14 struct point { 15 double x, y; 16 point() {} 17 point(double x, double y) : x(x), y(y) {} 18 void input() { 19 scanf("%lf%lf", &x, &y); 20 } 21 bool operator ==(point b)const { 22 return sgn(x - b.x) == 0 && sgn(y - b.y) == 0; 23 } 24 bool operator <(point b)const { 25 return sgn(x - b.x) == 0 ? sgn(y - b.y)<0 : x<b.x; 26 } 27 point operator -(const point &b)const { //返回减去后的新点 28 return point(x - b.x, y - b.y); 29 } 30 point operator +(const point &b)const { //返回加上后的新点 31 return point(x + b.x, y + b.y); 32 } 33 point operator *(const double &k)const { //返回相乘后的新点 34 return point(x * k, y * k); 35 } 36 point operator /(const double &k)const { //返回相除后的新点 37 return point(x / k, y / k); 38 } 39 double operator ^(const point &b)const { //叉乘 40 return x*b.y - y*b.x; 41 } 42 double operator *(const point &b)const { //点乘 43 return x*b.x + y*b.y; 44 } 45 double len() { //返回长度 46 return hypot(x, y); 47 } 48 double len2() { //返回长度的平方 49 return x*x + y*y; 50 } 51 point trunc(double r) { 52 double l = len(); 53 if (!sgn(l))return *this; 54 r /= l; 55 return point(x*r, y*r); 56 } 57 }; 58 struct line { 59 point s; 60 point e; 61 line() { 62 63 } 64 line(point _s, point _e) { 65 s = _s; 66 e = _e; 67 } 68 bool operator ==(line v) { 69 return (s == v.s) && (e == v.e); 70 } 71 //返回点p在直线上的投影 72 point lineprog(point p) { 73 return s + (((e - s)*((e - s)*(p - s))) / ((e - s).len2())); 74 } 75 //返回点p关于直线的对称点 76 point symmetrypoint(point p) { 77 point q = lineprog(p); 78 return point(2 * q.x - p.x, 2 * q.y - p.y); 79 } 80 //点是否在线段上 81 bool pointonseg(point p) { 82 return sgn((p - s) ^ (e - s)) == 0 && sgn((p - s)*(p - e)) <= 0; 83 } 84 }; 85 struct circle {//圆 86 double r; //半径 87 point p; //圆心 88 void input() { 89 p.input(); 90 scanf("%lf", &r); 91 } 92 circle() { } 93 circle(point _p, double _r) { 94 p = _p; 95 r = _r; 96 } 97 circle(double x, double y, double _r) { 98 p = point(x, y); 99 r = _r; 100 } 101 //求直线和圆的交点,返回交点个数 102 int pointcrossline(line l, point &r1, point &r2) { 103 double dx = l.e.x - l.s.x, dy = l.e.y - l.s.y; 104 double A = dx*dx + dy*dy; 105 double B = 2 * dx * (l.s.x - p.x) + 2 * dy * (l.s.y - p.y); 106 double C = (l.s.x - p.x)*(l.s.x - p.x) + (l.s.y - p.y)*(l.s.y - p.y) - r*r; 107 double del = B*B - 4 * A * C; 108 if (sgn(del) < 0) return 0; 109 int cnt = 0; 110 double t1 = (-B - sqrt(del)) / (2 * A); 111 double t2 = (-B + sqrt(del)) / (2 * A); 112 if (sgn(t1) >= 0) { 113 r1 = point(l.s.x + t1 * dx, l.s.y + t1 * dy); 114 cnt++; 115 } 116 if (sgn(t2) >= 0) { 117 r2 = point(l.s.x + t2 * dx, l.s.y + t2 * dy); 118 cnt++; 119 } 120 return cnt; 121 } 122 }; 123 point A, V, B; 124 circle tc; 125 point r1, r2; 126 int main() { 127 int t, d = 1; 128 scanf("%d", &t); 129 while (t--) { 130 tc.input(); 131 A.input(); 132 V.input(); 133 B.input(); 134 int f = 0; 135 int num = tc.pointcrossline(line(A, A + V), r1, r2); 136 if (num < 2) { 137 point t = B - A; 138 if (t.trunc(1) == V.trunc(1)) f = 1; 139 else f = 0; 140 } 141 else { 142 line l = line(tc.p, r1); 143 line l1 = line(A, r1); 144 line l2 = line(r1, B); 145 point t = l.symmetrypoint(A); 146 if (l1.pointonseg(B))f = 1; 147 else if (l2.pointonseg(t))f = 1; //求B的对称点会WA 148 else f = 0; 149 } 150 if (f == 1) 151 printf("Case #%d: Yes ", d++); 152 else 153 printf("Case #%d: No ", d++); 154 } 155 return 0; 156 }
以上是关于HDU 5572--An Easy Physics Problem(射线和圆的交点)的主要内容,如果未能解决你的问题,请参考以下文章