Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- double eps=1e-6;
- double mod(double x){
- if (x<0){
- x=-x;
- }
- return x;
- }
- bool equal(double a, double b){
- if (mod(a-b)<eps){
- return true;
- }
- return false;
- }
- bool less_than(double a, double b){
- if (a<b-eps){
- return true;
- }
- return false;
- }
- bool less_than_or_equal_to(double a, double b){
- if (less_than(a, b) || equal(a, b)){
- return true;
- }
- return false;
- }
- int sign(double a){
- if (less_than(a, 0)){
- return -1;
- }
- if (equal(a, 0)){
- return 0;
- }
- return 1;
- }
- struct Point{
- double x;
- double y;
- };
- struct Line{
- double a;
- double b;
- double c;
- };
- struct Circle{
- Point o;
- double r;
- };
- bool equal_points(Point p, Point q){
- if (equal(p.x, q.x) && equal(p.y, q.y)){
- return true;
- }
- return false;
- }
- Point draw_vector(Point p, Point q){
- return {q.x-p.x, q.y-p.y};
- }
- Point sum_of_two_points(Point p, Point q){
- return {p.x+q.x, p.y+q.y};
- }
- double cross_product(Point p, Point q){
- return p.x*q.x+p.y*q.y;
- }
- double dot_product(Point p, Point q){
- return p.x*q.y-p.y*q.x;
- }
- Point change_length(Point p, double l){
- return {(p.x*l)/(sqrt(p.x*p.x+p.y*p.y)), (p.y*l)/(sqrt(p.x*p.x+p.y*p.y))};
- }
- Point rotate_90_deg(Point p){
- return {-p.y, p.x};
- }
- double angle_between_vectors(Point p, Point q){
- return atan2(dot_product(p, q), cross_product(p, q));
- }
- double distance_between_two_points(Point p, Point q){
- return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y));
- }
- Line line_by_two_points(Point p, Point q){
- return {q.y-p.y, p.x-q.x, p.y*q.x-p.x*q.y};
- }
- bool check_if_3_points_are_collinear(Point p, Point q, Point r){
- if (equal(dot_product(draw_vector(q, p), draw_vector(q, r)), 0)){
- return true;
- }
- return false;
- }
- bool same_lines(Line f, Line g){
- if (!equal(f.a*g.b,g.a*f.b)){
- return false;
- }
- if (!equal(f.a*g.c, f.c*g.a)){
- return false;
- }
- return true;
- }
- bool parallel_lines(Line f, Line g){
- if (same_lines(f, g)){
- return false;
- }
- if (equal(f.a*g.b, f.b*g.a)){
- return true;
- }
- return false;
- }
- Point intersection_of_two_lines(Line f, Line g){
- return {(f.c*g.b-f.b*g.c)/(1.0*(f.b*g.a-g.b*f.a)), (f.c*g.a-g.c*f.a)/(1.0*(f.a*g.b-g.a*f.b))};
- }
- double distance_from_point_to_line(Point p, Line f){
- return (abs(f.a*p.x+f.b*p.y+f.c))/sqrt(f.a*f.a+f.b*f.b);
- }
- Point base_of_a_perpendicular(Point p, Line f){
- if (equal(distance_from_point_to_line(sum_of_two_points(p, change_length({f.a, f.b}, distance_from_point_to_line(p, f))), f), 0)){
- return sum_of_two_points(p, change_length({f.a, f.b}, distance_from_point_to_line(p, f)));
- }
- Point r=change_length({f.a, f.b}, distance_from_point_to_line(p, f));
- Point q;
- q.x=-r.x;
- q.y=-r.y;
- return sum_of_two_points(p, q);
- }
- double distance_from_point_to_segment(Point r, Point p, Point q){
- if (less_than(cross_product(draw_vector(q, p), draw_vector(q, r)), (double) 0)){
- return distance_between_two_points(q, r);
- }
- if (less_than(cross_product(draw_vector(p, q), draw_vector(p, r)), (double) 0)){
- return distance_between_two_points(p, r);
- }
- return distance_from_point_to_line(r, line_by_two_points(p, q));
- }
- bool two_segments_intersect(Point a, Point b, Point c, Point d){
- if (equal(dot_product(draw_vector(c, a), draw_vector(c, d)), 0)){
- if (equal(dot_product(draw_vector(c, b), draw_vector(c, d)), 0)) {
- if (less_than_or_equal_to(cross_product(draw_vector(a, c), draw_vector(a, d)), 0)){
- return true;
- }
- if (less_than_or_equal_to(cross_product(draw_vector(b, c), draw_vector(b, d)), 0)){
- return true;
- }
- if (less_than_or_equal_to(cross_product(draw_vector(c, a), draw_vector(c, b)), 0)){
- return true;
- }
- if (less_than_or_equal_to(cross_product(draw_vector(d, a), draw_vector(d, b)), 0)){
- return true;
- }
- return false;
- }
- if (less_than_or_equal_to(cross_product(draw_vector(a, c), draw_vector(a, d)), 0)){
- return true;
- }
- return false;
- }
- if (equal(dot_product(draw_vector(c, b), draw_vector(c, d)), 0)){
- if (less_than_or_equal_to(cross_product(draw_vector(b, c), draw_vector(b, d)), 0)){
- return true;
- }
- return false;
- }
- if (sign(dot_product(draw_vector(c, d), draw_vector(c, a)))!=sign(dot_product(draw_vector(c, d), draw_vector(c, b)))){
- if (sign(dot_product(draw_vector(a, b), draw_vector(a, c)))!=sign(dot_product(draw_vector(a, b), draw_vector(a, d)))){
- return true;
- }
- }
- return false;
- }
- bool segment_intersect_ray(Point a, Point b, Point c, Point d){
- if (equal(dot_product(draw_vector(c, a), draw_vector(c, d)), 0)){
- if (equal(dot_product(draw_vector(c, b), draw_vector(c, d)), 0)){
- if (less_than(0, cross_product(draw_vector(c, a), draw_vector(c, d)))){
- return true;
- }
- if(less_than(0, cross_product(draw_vector(c, b), draw_vector(c, d)))){
- return true;
- }
- }
- if (less_than(0, cross_product(draw_vector(c, a), draw_vector(c, d)))){
- return true;
- }
- return false;
- }
- if (equal(dot_product(draw_vector(c, b), draw_vector(c, d)), 0)){
- if (less_than_or_equal_to(0, cross_product(draw_vector(c, b), draw_vector(c, d)))){
- return true;
- }
- return false;
- }
- if (sign(dot_product(draw_vector(c, d), draw_vector(c, a)))!=sign(dot_product(draw_vector(c, d), draw_vector(c, b)))){
- Point x= intersection_of_two_lines(line_by_two_points(a, b), line_by_two_points(c, d));
- if (less_than_or_equal_to(0, cross_product(draw_vector(c, x), draw_vector(c, d)))){
- return true;
- }
- return false;
- }
- return false;
- }
- double distance_from_segment_to_ray(Point a, Point b, Point c, Point d) {
- Line f = line_by_two_points(c, d);
- Line g = line_by_two_points(a, b);
- if (segment_intersect_ray(a, b, c, d)) {
- return 0;
- } else {
- Point h2 = base_of_a_perpendicular(c, g);
- double d5;
- if (less_than(cross_product(draw_vector(c, d), draw_vector(c, a)), 0)) {
- d5 = distance_between_two_points(a, c);
- } else {
- d5 = distance_from_point_to_line(a, f);
- }
- double d6;
- if (less_than(cross_product(draw_vector(c, d), draw_vector(c, b)), 0)) {
- d6 = distance_between_two_points(b, c);
- } else {
- d6 = distance_from_point_to_line(b, f);
- }
- double minimum = min(d5, d6);
- if (less_than_or_equal_to(cross_product(draw_vector(h2, a), draw_vector(h2, b)), 0)) {
- minimum = min(minimum, distance_between_two_points(c, h2));
- }
- return minimum;
- }
- }
- double distance_from_point_to_ray(Point c, Point a, Point b){
- Point h = base_of_a_perpendicular(c, line_by_two_points(a, b));
- if (less_than_or_equal_to(0, cross_product(draw_vector(a, h), draw_vector(a, b)))){
- return distance_from_point_to_line(c, line_by_two_points(a, b));
- }
- return distance_between_two_points(c, a);
- }
- double distance_between_rays(Point a, Point b, Point c, Point d){
- if (parallel_lines(line_by_two_points(a, b), line_by_two_points(c, d)) || same_lines(line_by_two_points(a, b), line_by_two_points(c, d))) {
- return min(distance_from_point_to_ray(a, c, d), distance_from_point_to_ray(c, a, b));
- }
- Point f = intersection_of_two_lines(line_by_two_points(a, b), line_by_two_points(c, d));
- if (less_than_or_equal_to(0, cross_product(draw_vector(a, b), draw_vector(a, f)))) {
- if (less_than_or_equal_to(0, cross_product(draw_vector(c, d), draw_vector(c, f)))) {
- return 0;
- }
- }
- return min(distance_from_point_to_ray(a, c, d), distance_from_point_to_ray(c, a, b));
- }
- double distance_from_ray_to_line(Point a, Point b, Line f){
- if (parallel_lines(line_by_two_points(a, b), f) || same_lines(line_by_two_points(a, b), f)){
- return distance_from_point_to_line(a, f);
- }
- Point x= intersection_of_two_lines(line_by_two_points(a, b), f);
- if (less_than_or_equal_to(0, cross_product(draw_vector(a, x), draw_vector(a, b)))){
- return 0;
- }
- return distance_from_point_to_line(a, f);
- }
- double distance_between_lines(Line g, Line f, Point a){
- if (same_lines(f, g)){
- return 0;
- }
- if (parallel_lines(f, g)){
- return distance_from_point_to_line(a, f);
- }
- return 0;
- }
- bool point_inside_of_circle(Point p, Circle omega){
- return less_than(distance_between_two_points(p, omega.o), omega.r);
- }
- bool point_lie_on_circle(Point p, Circle omega){
- return equal(distance_between_two_points(p, omega.o), omega.r);
- }
- bool point_outside_of_circle(Point p, Circle omega){
- return ((!point_inside_of_circle(p, omega)) && (!point_lie_on_circle(p, omega)));
- }
- bool line_tangent_circle(Line f, Circle omega){
- return equal(distance_from_point_to_line(omega.o, f), omega.r);
- }
- bool line_intersect_circle(Line f, Circle omega){
- return less_than(distance_from_point_to_line(omega.o, f), omega.r);
- }
- Point tangency_point(Line f, Circle omega){
- return base_of_a_perpendicular(omega.o, f);
- }
- pair<Point, Point> intersection_points_line_circle(Line f, Circle omega){
- double d = distance_from_point_to_line(omega.o, f);
- Point p1, p2;
- p1 = sum_of_two_points(base_of_a_perpendicular(omega.o, f), change_length(rotate_90_deg({f.a, f.b}), sqrt(omega.r*omega.r-d*d)));
- p2 = sum_of_two_points(base_of_a_perpendicular(omega.o, f), change_length(rotate_90_deg({-f.a, -f.b}), sqrt(omega.r*omega.r-d*d)));
- return {p1, p2};
- }
- int main(){
- int t;
- cin>>t;
- cout.precision(20);
- while(t--){
- Circle omega1, omega2;
- cin>>omega1.o.x>>omega1.o.y>>omega1.r>>omega2.o.x>>omega2.o.y>>omega2.r;
- if (equal_points(omega1.o, omega2.o) && equal(omega1.r, omega2.r)){
- cout<<3<<"\n";
- continue;
- }
- Circle newc1, newc2;
- newc1.o={0, 0};
- newc1.r=omega1.r;
- newc2.o={omega2.o.x-omega1.o.x, omega2.o.y-omega1.o.y};
- newc2.r=omega2.r;
- Line g = {2*newc2.o.x, 2*newc2.o.y, newc2.r*newc2.r-newc1.r*newc1.r-newc2.o.x*newc2.o.x-newc2.o.y*newc2.o.y};
- if (line_tangent_circle(g, newc2)){
- Point p1 = tangency_point(g, newc2);
- cout<<1<<"\n";
- cout<<p1.x+omega1.o.x<<" "<<p1.y+omega1.o.y<<"\n";
- continue;
- }
- if (line_intersect_circle(g, newc2)){
- pair<Point, Point> p= intersection_points_line_circle(g, newc2);
- Point q1, q2;
- q1.x=p.first.x+omega1.o.x;
- q1.y=p.first.y+omega1.o.y;
- q2.x=p.second.x+omega1.o.x;
- q2.y=p.second.y+omega1.o.y;
- Line f = line_by_two_points(omega1.o, omega2.o);
- Point H= base_of_a_perpendicular(q1, f);
- cout<<2<<"\n";
- cout<<H.x<<" "<<H.y<<"\n";
- cout<<distance_between_two_points(omega1.o, H)<<" "<<distance_from_point_to_line(q1, f)<<"\n";
- cout<<q1.x<<" "<<q1.y<<"\n";
- cout<<q2.x<<" "<<q2.y<<"\n";
- continue;
- }
- cout<<0<<"\n";
- continue;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement