#include #include #include #include #include #include #ifdef __PROGTEST__ #define debug(...) ((void)0) #else #define debug(fmt, ...) \ fprintf(stdout, "[%s:%d %s()] " fmt "\n", __FILE__, __LINE__, __func__, \ ##__VA_ARGS__) #endif double clamp(double d) { if (d > 1.0) { return 1.0; } else if (d < -1.0) { return -1.0; } else { return d; } } // https://www.geeksforgeeks.org/dsa/area-of-intersection-of-two-circles/ double intersection_area(double a_r, double b_r, double distance) { double a_square = a_r * a_r; double b_square = b_r * b_r; double distance_square = distance * distance; double alpha_acos = (distance_square + a_square - b_square) / (2 * a_r * distance); double beta_acos = (distance_square + b_square - a_square) / (2 * b_r * distance); double alpha = acos(clamp(alpha_acos)) * 2; double beta = acos(clamp(beta_acos)) * 2; double a1 = 0.5 * beta * b_square - 0.5 * b_square * sin(beta); double a2 = 0.5 * alpha * a_square - 0.5 * a_square * sin(alpha); double area = a1 + a2; debug("Area = %lf", area); return area; } double circle_area(double radius) { return M_PI * radius * radius; } int main() { double a_center_x = 0, a_center_y = 0, a_radius = 0, b_center_x = 0, b_center_y = 0, b_radius = 0; printf("Zadejte parametry kruznice #1:\n"); int inputs_read = scanf("%lf %lf %lf", &a_center_x, &a_center_y, &a_radius); if (inputs_read != 3 || a_radius <= 0) { printf("Nespravny vstup.\n"); return EXIT_FAILURE; } printf("Zadejte parametry kruznice #2:\n"); inputs_read = scanf("%lf %lf %lf", &b_center_x, &b_center_y, &b_radius); if (inputs_read != 3 || b_radius <= 0) { printf("Nespravny vstup.\n"); return EXIT_FAILURE; } double center_distance = sqrt((b_center_x - a_center_x) * (b_center_x - a_center_x) + (b_center_y - a_center_y) * (b_center_y - a_center_y)); debug("Distance of centers = %0.60lf", center_distance); debug("Radii difference = %0.60lf", a_radius - b_radius); debug("Radii difference = %0.60lf", b_radius - a_radius); debug("Center + #1 = %0.60lf", a_center_x + a_radius); debug("Center + #2 = %0.60lf", b_center_x + b_radius); double radii_sum = a_radius + b_radius; double radii_difference = fabs(a_radius - b_radius); double epsilon = 100 * DBL_EPSILON * fmax(a_radius, b_radius); // Both origin points and radii are identical bool are_identical = a_center_x == b_center_x && a_center_y == b_center_y && a_radius == b_radius; // d = r1 + r2 // d - r1 - r1 < epsilon bool are_touching_from_outside = fabs(center_distance - radii_sum) < epsilon; // d = |r1 - r2| // d - |r1 - r2| < epsilon bool are_touching_from_inside = fabs(center_distance - radii_difference) < epsilon; // d < |r1 - r2| bool is_fully_inside = center_distance < radii_difference; // d < r1 + r2 bool are_overlapping = center_distance < radii_sum; if (are_identical) { printf("Kruznice splyvaji, prekryv: %lf\n", circle_area(a_radius)); } else if (are_touching_from_inside) { if (a_radius > b_radius) { printf( "Vnitrni dotyk, kruznice #2 lezi uvnitr kruznice #1, prekryv: %lf\n", circle_area(b_radius)); } else { printf( "Vnitrni dotyk, kruznice #1 lezi uvnitr kruznice #2, prekryv: %lf\n", circle_area(a_radius)); } } else if (are_touching_from_outside) { printf("Vnejsi dotyk, zadny prekryv.\n"); } else if (is_fully_inside) { if (a_radius > b_radius) { printf("Kruznice #2 lezi uvnitr kruznice #1, prekryv: %lf\n", circle_area(b_radius)); } else { printf("Kruznice #1 lezi uvnitr kruznice #2, prekryv: %lf\n", circle_area(a_radius)); } } else if (are_overlapping) { printf("Kruznice se protinaji, prekryv: %lf\n", intersection_area(a_radius, b_radius, center_distance)); } else { printf("Kruznice lezi vne sebe, zadny prekryv.\n"); } return EXIT_SUCCESS; }