Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct point {
- double x, y;
- point() {x = y = 0.0;}
- point(double x, double y) : x(x), y(y) {}
- };
- struct line {
- double a, b, c;
- double f (double x) {return -a * x - c;}
- };
- struct circle {
- point c;
- double r;
- circle() {
- r = 0.0;
- c = point();
- }
- circle (point c, double r) : c(c), r(r) {}
- };
- point to_vec (const point& a, const point& b) {
- return point(b.x-a.x, b.y-a.y);
- }
- point scale (const point& v, double s) {
- return point(v.x * s, v.y * s);
- }
- point translate (const point& p, const point& v) {
- return point(p.x+v.x, p.y+v.y);
- }
- double dot (const point& a, const point& b) {
- return a.x * b.x + a.y * b.y;
- }
- double norm_sq (const point& v) {
- return v.x * v.x + v.y * v.y;
- }
- double norm (const point& v) {
- return sqrt(norm_sq(v));
- }
- double dist_point (const point& a, const point& b) {
- return sqrt((a.x-b.x)*(a.x-b.x)*(a.y-b.y)*(a.y-b.y));
- }
- double dist_to_line (const point& p, const point& a, const point& b, point& c) {
- // formula: c = a + u * ab
- point ap = to_vec(a, p), ab = to_vec(a, b);
- double u = dot(ap, ab) / norm_sq(ab);
- c = translate(a, scale(ab, u));
- return dist_point(p, c);
- }
- void points_to_line (const point& p1, const point& p2, line& l) {
- if (fabs(p1.x - p2.x) < EPS) {
- l.a = 1.0; l.b = 0.0; l.c = -p1.x;
- } else {
- l.a = -(p1.y - p2.y) / (p1.x - p2.x);
- l.b = 1.0;
- l.c = -(l.a * p1.x) - p1.y;
- }
- }
- int are_intersect (const circle& c, line& l, pair<point, point>& ans) {
- point close;
- dist_to_line(point(1.0, l.f(1.0)), point(2.0, l.f(2.0)), c.c, close);
- double dis = dist_point(close, c.c);
- if (dis > c.r) return 0;
- if (fabs(dis - c.r) < EPS) {
- ans.first = close;
- return 1;
- }
- double cat = sqrt(c.r*c.r - dis*dis);
- point vec = to_vec(point(1.0, l.f(1.0)), point(2.0, l.f(2.0)));
- vec = scale(vec, cat/norm(vec));
- ans.first = translate(close, vec);
- ans.second = translate(close, scale(vec, -1.0));
- return 2;
- }
- bool in_box (const point& p1, const point& p2, const point& q) {
- return min(p1.x, p2.x) <= q.x && q.x <= max(p1.x, p2.x) && min(p1.y, p2.y) <= q.y && q.y <= max(p1.y, p2.y);
- }
- int are_intersect (const point& p, const point& q, const circle& c, pair<point, point>& ans) {
- line l;
- points_to_line(p, q, l);
- int cnt = are_intersect(c, l, ans);
- if (cnt == 0) return 0;
- if (cnt == 1) {
- if (in_box(p, q, ans.first)) return 1;
- else return 0;
- } else {
- if (in_box(p, q, ans.first)) {
- if (in_box(p, q, ans.second)) {
- ans.first = ans.second;
- return 1;
- } else return 1;
- } else if (in_box(p, q, ans.second)){
- return 2;
- } else {
- return 0;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement