From c57c78754b95e54c48e24c15f360062697040088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Kl=C3=A9ger?= Date: Sun, 12 Oct 2025 10:36:26 +0200 Subject: [PATCH 1/7] hw-01: Assignment description --- homework-01-two-circles/README.md | 98 +++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 homework-01-two-circles/README.md diff --git a/homework-01-two-circles/README.md b/homework-01-two-circles/README.md new file mode 100644 index 0000000..7814b09 --- /dev/null +++ b/homework-01-two-circles/README.md @@ -0,0 +1,98 @@ +Úkolem je napsat program, který rozhodne vzájemnou polohu 2 kružnic. + +Vstupem programu je zadání dvou kružnic. Každá kružnice je zadaná svým středem (x a y souřadnice) a poloměrem. Čísla jsou zadaná v pořadí x y r, jedná se o desetinná čísla. + +Výstupem programu je rozhodnutí o vzájemné poloze kružnic. Celkem může nastat 6 variant vzájemné polohy: + +- kružnice splývají, +- jedna kružnice leží zcela uvnitř druhé, +- jedna kružnice se zevnitř dotýká druhé, +- kružnice se protínají, +- kružnice se dotýkají zvenku, +- kružnice leží zcela mimo sebe. + +Program rozhodne o poloze a vypíše ji. Dále, pokud je to relevantní, program vypíše plochu překryvu kružnic. Formát výstupu pro všech 6 variant je uveden v ukázkovém běhu níže. Pozor, za výstupem je odřádkování (\n). + +Program musí být schopen detekovat nesprávný vstup. Pokud je na vstupu nesmyslné zadání, program to zjistí, vypíše chybové hlášení a ukončí se. Formát chybového hlášení je uveden v ukázce níže. Pozor, za případným chybovým hlášením je odřádkování (\n). Chybové hlášení zasílejte na standardní výstup (printf), nezasílejte jej na chybový výstup. Za chybu je považováno: + +- nečíselná hodnota nějaké souřadnice, +- nečíselná hodnota poloměru, +- poloměr nulový nebo záporný. + +**Ukázka práce programu:** + +``` +Zadejte parametry kruznice #1: +0 0 5 +Zadejte parametry kruznice #2: +0 10 5 +Vnejsi dotyk, zadny prekryv. +``` + +--- + +``` +Zadejte parametry kruznice #1: +0 0 3 +Zadejte parametry kruznice #2: +1.5 1.5 0.8 +Kruznice #2 lezi uvnitr kruznice #1, prekryv: 2.010619 +``` + +--- + +``` +Zadejte parametry kruznice #1: +0 0 4 +Zadejte parametry kruznice #2: +2 0 2 +Vnitrni dotyk, kruznice #2 lezi uvnitr kruznice #1, prekryv: 12.566371 +``` + +--- + +``` +Zadejte parametry kruznice #1: +0 0 5 +Zadejte parametry kruznice #2: +100 100 10 +Kruznice lezi vne sebe, zadny prekryv. +``` + +--- + +``` +Zadejte parametry kruznice #1: +0 0 4.5 +Zadejte parametry kruznice #2: +10 10 15 +Kruznice se protinaji, prekryv: 37.475800 +``` + +--- + +``` +Zadejte parametry kruznice #1: +-10.25 -20.5 4 +Zadejte parametry kruznice #2: +-10.25 -20.5 4 +Kruznice splyvaji, prekryv: 50.265482 +``` + +--- + +``` +Zadejte parametry kruznice #1: +0 0 -2 +Nespravny vstup. +``` + +--- + +``` +Zadejte parametry kruznice #1: +0 12 5 +Zadejte parametry kruznice #2: +3 7 abc +Nespravny vstup. +``` From 2a857d1efeaa43250c8be54815492578137bf33a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Kl=C3=A9ger?= Date: Sun, 12 Oct 2025 10:38:38 +0200 Subject: [PATCH 2/7] hw-01: Test data --- homework-01-two-circles/test_data/0000_in.txt | 2 ++ homework-01-two-circles/test_data/0000_out.txt | 3 +++ homework-01-two-circles/test_data/0000_out_win.txt | 3 +++ homework-01-two-circles/test_data/0001_in.txt | 2 ++ homework-01-two-circles/test_data/0001_out.txt | 3 +++ homework-01-two-circles/test_data/0001_out_win.txt | 3 +++ homework-01-two-circles/test_data/0002_in.txt | 2 ++ homework-01-two-circles/test_data/0002_out.txt | 3 +++ homework-01-two-circles/test_data/0002_out_win.txt | 3 +++ homework-01-two-circles/test_data/0003_in.txt | 2 ++ homework-01-two-circles/test_data/0003_out.txt | 3 +++ homework-01-two-circles/test_data/0003_out_win.txt | 3 +++ homework-01-two-circles/test_data/0004_in.txt | 2 ++ homework-01-two-circles/test_data/0004_out.txt | 3 +++ homework-01-two-circles/test_data/0004_out_win.txt | 3 +++ homework-01-two-circles/test_data/0005_in.txt | 2 ++ homework-01-two-circles/test_data/0005_out.txt | 3 +++ homework-01-two-circles/test_data/0005_out_win.txt | 3 +++ homework-01-two-circles/test_data/0006_in.txt | 1 + homework-01-two-circles/test_data/0006_out.txt | 2 ++ homework-01-two-circles/test_data/0006_out_win.txt | 2 ++ homework-01-two-circles/test_data/0007_in.txt | 2 ++ homework-01-two-circles/test_data/0007_out.txt | 3 +++ homework-01-two-circles/test_data/0007_out_win.txt | 3 +++ 24 files changed, 61 insertions(+) create mode 100644 homework-01-two-circles/test_data/0000_in.txt create mode 100644 homework-01-two-circles/test_data/0000_out.txt create mode 100644 homework-01-two-circles/test_data/0000_out_win.txt create mode 100644 homework-01-two-circles/test_data/0001_in.txt create mode 100644 homework-01-two-circles/test_data/0001_out.txt create mode 100644 homework-01-two-circles/test_data/0001_out_win.txt create mode 100644 homework-01-two-circles/test_data/0002_in.txt create mode 100644 homework-01-two-circles/test_data/0002_out.txt create mode 100644 homework-01-two-circles/test_data/0002_out_win.txt create mode 100644 homework-01-two-circles/test_data/0003_in.txt create mode 100644 homework-01-two-circles/test_data/0003_out.txt create mode 100644 homework-01-two-circles/test_data/0003_out_win.txt create mode 100644 homework-01-two-circles/test_data/0004_in.txt create mode 100644 homework-01-two-circles/test_data/0004_out.txt create mode 100644 homework-01-two-circles/test_data/0004_out_win.txt create mode 100644 homework-01-two-circles/test_data/0005_in.txt create mode 100644 homework-01-two-circles/test_data/0005_out.txt create mode 100644 homework-01-two-circles/test_data/0005_out_win.txt create mode 100644 homework-01-two-circles/test_data/0006_in.txt create mode 100644 homework-01-two-circles/test_data/0006_out.txt create mode 100644 homework-01-two-circles/test_data/0006_out_win.txt create mode 100644 homework-01-two-circles/test_data/0007_in.txt create mode 100644 homework-01-two-circles/test_data/0007_out.txt create mode 100644 homework-01-two-circles/test_data/0007_out_win.txt diff --git a/homework-01-two-circles/test_data/0000_in.txt b/homework-01-two-circles/test_data/0000_in.txt new file mode 100644 index 0000000..78791a8 --- /dev/null +++ b/homework-01-two-circles/test_data/0000_in.txt @@ -0,0 +1,2 @@ +0 0 5 +0 10 5 diff --git a/homework-01-two-circles/test_data/0000_out.txt b/homework-01-two-circles/test_data/0000_out.txt new file mode 100644 index 0000000..02f020f --- /dev/null +++ b/homework-01-two-circles/test_data/0000_out.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Vnejsi dotyk, zadny prekryv. diff --git a/homework-01-two-circles/test_data/0000_out_win.txt b/homework-01-two-circles/test_data/0000_out_win.txt new file mode 100644 index 0000000..e6e2fdd --- /dev/null +++ b/homework-01-two-circles/test_data/0000_out_win.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Vnejsi dotyk, zadny prekryv. diff --git a/homework-01-two-circles/test_data/0001_in.txt b/homework-01-two-circles/test_data/0001_in.txt new file mode 100644 index 0000000..4dc3fb1 --- /dev/null +++ b/homework-01-two-circles/test_data/0001_in.txt @@ -0,0 +1,2 @@ +0 0 3 +1.5 1.5 0.8 diff --git a/homework-01-two-circles/test_data/0001_out.txt b/homework-01-two-circles/test_data/0001_out.txt new file mode 100644 index 0000000..6d38b13 --- /dev/null +++ b/homework-01-two-circles/test_data/0001_out.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Kruznice #2 lezi uvnitr kruznice #1, prekryv: 2.010619 diff --git a/homework-01-two-circles/test_data/0001_out_win.txt b/homework-01-two-circles/test_data/0001_out_win.txt new file mode 100644 index 0000000..021888b --- /dev/null +++ b/homework-01-two-circles/test_data/0001_out_win.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Kruznice #2 lezi uvnitr kruznice #1, prekryv: 2.010619 diff --git a/homework-01-two-circles/test_data/0002_in.txt b/homework-01-two-circles/test_data/0002_in.txt new file mode 100644 index 0000000..444a621 --- /dev/null +++ b/homework-01-two-circles/test_data/0002_in.txt @@ -0,0 +1,2 @@ +0 0 4 +2 0 2 diff --git a/homework-01-two-circles/test_data/0002_out.txt b/homework-01-two-circles/test_data/0002_out.txt new file mode 100644 index 0000000..fd98a10 --- /dev/null +++ b/homework-01-two-circles/test_data/0002_out.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Vnitrni dotyk, kruznice #2 lezi uvnitr kruznice #1, prekryv: 12.566371 diff --git a/homework-01-two-circles/test_data/0002_out_win.txt b/homework-01-two-circles/test_data/0002_out_win.txt new file mode 100644 index 0000000..5368fdd --- /dev/null +++ b/homework-01-two-circles/test_data/0002_out_win.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Vnitrni dotyk, kruznice #2 lezi uvnitr kruznice #1, prekryv: 12.566371 diff --git a/homework-01-two-circles/test_data/0003_in.txt b/homework-01-two-circles/test_data/0003_in.txt new file mode 100644 index 0000000..eb4ccea --- /dev/null +++ b/homework-01-two-circles/test_data/0003_in.txt @@ -0,0 +1,2 @@ +0 0 5 +100 100 10 diff --git a/homework-01-two-circles/test_data/0003_out.txt b/homework-01-two-circles/test_data/0003_out.txt new file mode 100644 index 0000000..a6df52f --- /dev/null +++ b/homework-01-two-circles/test_data/0003_out.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Kruznice lezi vne sebe, zadny prekryv. diff --git a/homework-01-two-circles/test_data/0003_out_win.txt b/homework-01-two-circles/test_data/0003_out_win.txt new file mode 100644 index 0000000..f7c95c7 --- /dev/null +++ b/homework-01-two-circles/test_data/0003_out_win.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Kruznice lezi vne sebe, zadny prekryv. diff --git a/homework-01-two-circles/test_data/0004_in.txt b/homework-01-two-circles/test_data/0004_in.txt new file mode 100644 index 0000000..6998a0b --- /dev/null +++ b/homework-01-two-circles/test_data/0004_in.txt @@ -0,0 +1,2 @@ +0 0 4.5 +10 10 15 diff --git a/homework-01-two-circles/test_data/0004_out.txt b/homework-01-two-circles/test_data/0004_out.txt new file mode 100644 index 0000000..71b08d4 --- /dev/null +++ b/homework-01-two-circles/test_data/0004_out.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Kruznice se protinaji, prekryv: 37.475800 diff --git a/homework-01-two-circles/test_data/0004_out_win.txt b/homework-01-two-circles/test_data/0004_out_win.txt new file mode 100644 index 0000000..86d9544 --- /dev/null +++ b/homework-01-two-circles/test_data/0004_out_win.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Kruznice se protinaji, prekryv: 37.475800 diff --git a/homework-01-two-circles/test_data/0005_in.txt b/homework-01-two-circles/test_data/0005_in.txt new file mode 100644 index 0000000..a3c5c82 --- /dev/null +++ b/homework-01-two-circles/test_data/0005_in.txt @@ -0,0 +1,2 @@ +-10.25 -20.5 4 +-10.25 -20.5 4 diff --git a/homework-01-two-circles/test_data/0005_out.txt b/homework-01-two-circles/test_data/0005_out.txt new file mode 100644 index 0000000..801d044 --- /dev/null +++ b/homework-01-two-circles/test_data/0005_out.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Kruznice splyvaji, prekryv: 50.265482 diff --git a/homework-01-two-circles/test_data/0005_out_win.txt b/homework-01-two-circles/test_data/0005_out_win.txt new file mode 100644 index 0000000..fc2f1d3 --- /dev/null +++ b/homework-01-two-circles/test_data/0005_out_win.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Kruznice splyvaji, prekryv: 50.265482 diff --git a/homework-01-two-circles/test_data/0006_in.txt b/homework-01-two-circles/test_data/0006_in.txt new file mode 100644 index 0000000..e7fa176 --- /dev/null +++ b/homework-01-two-circles/test_data/0006_in.txt @@ -0,0 +1 @@ +0 0 -2 diff --git a/homework-01-two-circles/test_data/0006_out.txt b/homework-01-two-circles/test_data/0006_out.txt new file mode 100644 index 0000000..49ee44b --- /dev/null +++ b/homework-01-two-circles/test_data/0006_out.txt @@ -0,0 +1,2 @@ +Zadejte parametry kruznice #1: +Nespravny vstup. diff --git a/homework-01-two-circles/test_data/0006_out_win.txt b/homework-01-two-circles/test_data/0006_out_win.txt new file mode 100644 index 0000000..11f0bd0 --- /dev/null +++ b/homework-01-two-circles/test_data/0006_out_win.txt @@ -0,0 +1,2 @@ +Zadejte parametry kruznice #1: +Nespravny vstup. diff --git a/homework-01-two-circles/test_data/0007_in.txt b/homework-01-two-circles/test_data/0007_in.txt new file mode 100644 index 0000000..b672100 --- /dev/null +++ b/homework-01-two-circles/test_data/0007_in.txt @@ -0,0 +1,2 @@ +0 12 5 +3 7 abc diff --git a/homework-01-two-circles/test_data/0007_out.txt b/homework-01-two-circles/test_data/0007_out.txt new file mode 100644 index 0000000..b7e57c3 --- /dev/null +++ b/homework-01-two-circles/test_data/0007_out.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Nespravny vstup. diff --git a/homework-01-two-circles/test_data/0007_out_win.txt b/homework-01-two-circles/test_data/0007_out_win.txt new file mode 100644 index 0000000..8b367ce --- /dev/null +++ b/homework-01-two-circles/test_data/0007_out_win.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Nespravny vstup. From 02507b30d5f4fec052f815745f9c584ff81fe763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Kl=C3=A9ger?= Date: Sun, 12 Oct 2025 14:31:14 +0200 Subject: [PATCH 3/7] hw-01: Working solution --- homework-01-two-circles/main.c | 86 ++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 homework-01-two-circles/main.c diff --git a/homework-01-two-circles/main.c b/homework-01-two-circles/main.c new file mode 100644 index 0000000..f9df9ac --- /dev/null +++ b/homework-01-two-circles/main.c @@ -0,0 +1,86 @@ +#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 + +// 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 distane_square = distance * distance; + + double alpha = acos((distane_square + a_square - b_square) / (2 * a_r * distance)) * 2; + double beta = acos((distane_square + b_square - a_square) / (2 * b_r * distance)) * 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)); + + double radii_sum = a_radius + b_radius; + if(a_center_x == b_center_x && a_center_y == b_center_y && a_radius == b_radius) { + printf("Kruznice splyvaji, prekryv: %lf\n", circle_area(a_radius)); + } else if(center_distance <= a_radius - b_radius) { + debug("B radius = %lf", b_radius); + debug("Double A radius = %lf", a_radius * 2); + if(a_radius == 2 * b_radius) { + printf("Vnitrni dotyk, kruznice #2 lezi uvnitr kruznice #1, prekryv: %lf\n", circle_area(b_radius)); + } else { + printf("Kruznice #2 lezi uvnitr kruznice #1, prekryv: %lf\n", circle_area(b_radius)); + } + } else if(center_distance <= b_radius - a_radius) { + debug("A radius = %lf", a_radius); + debug("Double B radius = %lf", b_radius * 2); + if(b_radius == 2 * a_radius) { + printf("Vnitrni dotyk, kruznice #1 lezi uvnitr kruznice #2, prekryv: %lf\n", circle_area(a_radius)); + } else { + printf("Kruznice #1 lezi uvnitr kruznice #2, prekryv: %lf\n", circle_area(a_radius)); + } + } else if(center_distance < radii_sum) { + printf("Kruznice se protinaji, prekryv: %lf\n", intersection_area(a_radius, b_radius, center_distance)); + } else if(center_distance == radii_sum) { + printf("Vnejsi dotyk, zadny prekryv.\n"); + } else { + printf("Kruznice lezi vne sebe, zadny prekryv.\n"); + } + + return EXIT_SUCCESS; +} From 11b00c4195f8aaece5aaecc57a5fcb9a9619580c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Kl=C3=A9ger?= Date: Sun, 12 Oct 2025 14:32:32 +0200 Subject: [PATCH 4/7] hw-01: Additional test cases --- homework-01-two-circles/test_data/0008_in.txt | 2 ++ homework-01-two-circles/test_data/0008_out.txt | 3 +++ homework-01-two-circles/test_data/0009_in.txt | 2 ++ homework-01-two-circles/test_data/0009_out.txt | 3 +++ 4 files changed, 10 insertions(+) create mode 100644 homework-01-two-circles/test_data/0008_in.txt create mode 100644 homework-01-two-circles/test_data/0008_out.txt create mode 100644 homework-01-two-circles/test_data/0009_in.txt create mode 100644 homework-01-two-circles/test_data/0009_out.txt diff --git a/homework-01-two-circles/test_data/0008_in.txt b/homework-01-two-circles/test_data/0008_in.txt new file mode 100644 index 0000000..b5d8d0e --- /dev/null +++ b/homework-01-two-circles/test_data/0008_in.txt @@ -0,0 +1,2 @@ +9.7e-39 -1.85e-38 4.16e-38 +4.03e-38 2.3e-39 4.6e-39 diff --git a/homework-01-two-circles/test_data/0008_out.txt b/homework-01-two-circles/test_data/0008_out.txt new file mode 100644 index 0000000..f3a07ca --- /dev/null +++ b/homework-01-two-circles/test_data/0008_out.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Vnitrni dotyk, kruznice #2 lezi uvnitr kruznice #1, prekryv: 0.000000 diff --git a/homework-01-two-circles/test_data/0009_in.txt b/homework-01-two-circles/test_data/0009_in.txt new file mode 100644 index 0000000..a55d30d --- /dev/null +++ b/homework-01-two-circles/test_data/0009_in.txt @@ -0,0 +1,2 @@ +4.03e-38 2.3e-39 4.6e-39 +9.7e-39 -1.85e-38 4.16e-38 diff --git a/homework-01-two-circles/test_data/0009_out.txt b/homework-01-two-circles/test_data/0009_out.txt new file mode 100644 index 0000000..3f0df88 --- /dev/null +++ b/homework-01-two-circles/test_data/0009_out.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Vnitrni dotyk, kruznice #1 lezi uvnitr kruznice #2, prekryv: 0.000000 From 372cdc6be8c66348c028afb20c54a934264eba6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Kl=C3=A9ger?= Date: Sun, 12 Oct 2025 21:54:42 +0200 Subject: [PATCH 5/7] hw-01: Fix incorrect check for inner touching point --- homework-01-two-circles/main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/homework-01-two-circles/main.c b/homework-01-two-circles/main.c index f9df9ac..fee4a52 100644 --- a/homework-01-two-circles/main.c +++ b/homework-01-two-circles/main.c @@ -59,17 +59,17 @@ int main() { if(a_center_x == b_center_x && a_center_y == b_center_y && a_radius == b_radius) { printf("Kruznice splyvaji, prekryv: %lf\n", circle_area(a_radius)); } else if(center_distance <= a_radius - b_radius) { - debug("B radius = %lf", b_radius); - debug("Double A radius = %lf", a_radius * 2); - if(a_radius == 2 * b_radius) { + debug("B radius = %0.60lf", b_radius); + debug("Double A radius = %0.60lf", a_radius * 2); + if(center_distance + b_radius == a_radius) { printf("Vnitrni dotyk, kruznice #2 lezi uvnitr kruznice #1, prekryv: %lf\n", circle_area(b_radius)); } else { printf("Kruznice #2 lezi uvnitr kruznice #1, prekryv: %lf\n", circle_area(b_radius)); } } else if(center_distance <= b_radius - a_radius) { - debug("A radius = %lf", a_radius); - debug("Double B radius = %lf", b_radius * 2); - if(b_radius == 2 * a_radius) { + debug("A radius = %0.60lf", a_radius); + debug("Double B radius = %0.60lf", b_radius * 2); + if(center_distance + a_radius == b_radius) { printf("Vnitrni dotyk, kruznice #1 lezi uvnitr kruznice #2, prekryv: %lf\n", circle_area(a_radius)); } else { printf("Kruznice #1 lezi uvnitr kruznice #2, prekryv: %lf\n", circle_area(a_radius)); From 0b0f66ddd5c3f0da4e3e54b82324ff10bfe19969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Kl=C3=A9ger?= Date: Mon, 13 Oct 2025 11:14:33 +0200 Subject: [PATCH 6/7] hw-01: Additional tests --- homework-01-two-circles/test_data/0010_in.txt | 2 ++ homework-01-two-circles/test_data/0010_out.txt | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 homework-01-two-circles/test_data/0010_in.txt create mode 100644 homework-01-two-circles/test_data/0010_out.txt diff --git a/homework-01-two-circles/test_data/0010_in.txt b/homework-01-two-circles/test_data/0010_in.txt new file mode 100644 index 0000000..b5683b0 --- /dev/null +++ b/homework-01-two-circles/test_data/0010_in.txt @@ -0,0 +1,2 @@ +-2.21e-38 -1.11e-38 1.4862e-36 +1.2253e-36 5.721e-37 1.092e-37 diff --git a/homework-01-two-circles/test_data/0010_out.txt b/homework-01-two-circles/test_data/0010_out.txt new file mode 100644 index 0000000..f3a07ca --- /dev/null +++ b/homework-01-two-circles/test_data/0010_out.txt @@ -0,0 +1,3 @@ +Zadejte parametry kruznice #1: +Zadejte parametry kruznice #2: +Vnitrni dotyk, kruznice #2 lezi uvnitr kruznice #1, prekryv: 0.000000 From 8781656616e0183d1d92c758a210adb96558137b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Kl=C3=A9ger?= Date: Mon, 13 Oct 2025 14:24:56 +0200 Subject: [PATCH 7/7] hw-01: Fix floating point imprecision --- homework-01-two-circles/main.c | 166 ++++++++++++++++++++++----------- 1 file changed, 109 insertions(+), 57 deletions(-) diff --git a/homework-01-two-circles/main.c b/homework-01-two-circles/main.c index fee4a52..0492238 100644 --- a/homework-01-two-circles/main.c +++ b/homework-01-two-circles/main.c @@ -1,86 +1,138 @@ #include -#include -#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__) +#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 distane_square = distance * distance; + double a_square = a_r * a_r; + double b_square = b_r * b_r; + double distance_square = distance * distance; - double alpha = acos((distane_square + a_square - b_square) / (2 * a_r * distance)) * 2; - double beta = acos((distane_square + b_square - a_square) / (2 * b_r * distance)) * 2; + 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 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 alpha = acos(clamp(alpha_acos)) * 2; + double beta = acos(clamp(beta_acos)) * 2; - double area = a1 + a2; + 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); - debug("Area = %lf", area); + double area = a1 + a2; - return area; + debug("Area = %lf", area); + + return area; } -double circle_area(double radius) { - return M_PI * radius * radius; -} +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; + 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"); + 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; - } + 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"); + 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; - } + 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)); - 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; - if(a_center_x == b_center_x && a_center_y == b_center_y && a_radius == b_radius) { - printf("Kruznice splyvaji, prekryv: %lf\n", circle_area(a_radius)); - } else if(center_distance <= a_radius - b_radius) { - debug("B radius = %0.60lf", b_radius); - debug("Double A radius = %0.60lf", a_radius * 2); - if(center_distance + b_radius == a_radius) { - printf("Vnitrni dotyk, kruznice #2 lezi uvnitr kruznice #1, prekryv: %lf\n", circle_area(b_radius)); - } else { - printf("Kruznice #2 lezi uvnitr kruznice #1, prekryv: %lf\n", circle_area(b_radius)); - } - } else if(center_distance <= b_radius - a_radius) { - debug("A radius = %0.60lf", a_radius); - debug("Double B radius = %0.60lf", b_radius * 2); - if(center_distance + a_radius == b_radius) { - printf("Vnitrni dotyk, kruznice #1 lezi uvnitr kruznice #2, prekryv: %lf\n", circle_area(a_radius)); - } else { - printf("Kruznice #1 lezi uvnitr kruznice #2, prekryv: %lf\n", circle_area(a_radius)); - } - } else if(center_distance < radii_sum) { - printf("Kruznice se protinaji, prekryv: %lf\n", intersection_area(a_radius, b_radius, center_distance)); - } else if(center_distance == radii_sum) { - printf("Vnejsi dotyk, zadny prekryv.\n"); - } else { - printf("Kruznice lezi vne sebe, zadny prekryv.\n"); - } + 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); - return EXIT_SUCCESS; + // 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; }