Tačke u dvodimenzionalnom prostoru¶
Autor zadatka: Rade Radišić <radisic.rade@uns.ac.rs>
- Tačke u dvodimenzionalnom Dekartovom koordinatnom sistemu opisane su preko njihovih koordinata:
Vrednost na x-osi (realan broj dvostruke preciznosti)
Vrednost na y-osi (realan broj dvostruke preciznosti)
- Učitati tačke iz ulazne datoteke, potom uraditi sledeće:
Pronaći koordinate težišne tačke za niz učitanih tačaka. Za pronalaženje koordinata težišne tačke potrebno je naći posebno aritmetičku sredinu x i y koordinata tačaka čija se težišna tačka nalazi (formula je na drugoj stranici dokumenta).
Pronaći sve tačke koje pripadaju krugu sa centrom u težišnoj tački (rezultat prethodnog koraka) i poluprečnika koji se unosi kao argument komandne linije (može biti realna vrednost). Rezultat ovog i prethodnog koraka upisati u izlaznu datoteku čiji se naziv sastoji od stringa
pripada_krugu_poluprecnika_
, vrednost poluprečnika (argument komandne linije) i ekstenzijom.txt
.Pronaći ukupan broj jedinstvenih trouglova koji može da nastane od datog niza tačaka. Da bi neke tri tačke sačinjavale trougao, potrebno je da duži koje one međusobno grade zadovoljavaju nejednakost trougla (formula je na drugoj stranici dokumenta). Dobijeni broj trouglova upisati u izlaznu datoteku "trouglovi.txt".
Primer poziva programa:
./a.out tacke.txt 5
Primer ulazne datoteke tacke.txt
:
1 1
2 2
3 1
5 5
6 1
Primer izlazne datoteke trouglovi.txt
:
Broj trouglova: 8
Primer izlazne datoteke pripada_krugu_poluprecnika_2.txt
Krug poluprecnika 2.00 sa centrom u tacki (3.40, 2.00)
(2.00, 2.00)
(3.00, 1.00)
Primer poziva programa gde tačke ne sačinjavaju trougao:
./a.out ne_trougao.txt 5
Primer ulazne datoteke ne_trougao.txt
:
1 1
2 2
3 3
Primer izlazne datoteke trouglovi.txt
:
Broj trouglova: 0
Primer izlazne datoteke pripada_krugu_poluprecnika_5.txt
Krug poluprecnika 5.00 sa centrom u tacki (2.00, 2.00)
(1.00, 1.00)
(2.00, 2.00)
(3.00, 3.00)
Korisne matematičke formule
Računanje težišne tačke
Koordinate težišne tačke \((x_{T}, y_{T})\) za \(n\) tačaka računaju se na sledeći način:
Nejednakost trougla
Za svaki trougao sa stranicama \(a\), \(b\) i \(c\) treba da važe sledeće nejednakosti:
Rastojanje između dve tačke u dvodimenzionalnom koordinatnom sistemu
Date su dve tačke sa koordinatama \((x_{1}, y_{1})\) i \((x_{2}, y_{2})\). Njihovo rastojanje može se odrediti na sledeći način:
Primer rešenja¶
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4#include <math.h>
5
6#define MAX_SIZE 30
7#define MAX_NAZIV 41
8
9typedef struct tacka_st {
10 double x;
11 double y;
12} TACKA;
13
14FILE *safe_fopen(char *, char *, int);
15void ucitaj_tacke(FILE *, TACKA *, int *);
16void ispisi_tacke(FILE *, TACKA *, int);
17void ispisi_tacku(FILE *, TACKA);
18
19unsigned prebroj_trouglove(TACKA *, int);
20TACKA pronadji_teziste(TACKA *, int);
21void pripada_krugu(TACKA *, TACKA *,
22 int, int *, TACKA, double);
23
24int obrazuju_trougao(TACKA, TACKA, TACKA);
25double udaljenost(TACKA, TACKA);
26
27int main(int argc, char **argv) {
28 TACKA tacke[MAX_SIZE], pripadaju_krugu[MAX_SIZE];
29 int n, m;
30
31 if(argc != 3) {
32 printf("Niste dobro pozvali program. Primer poziva: %s tacke.txt 5\n", argv[0]);
33 exit(EXIT_FAILURE);
34 }
35
36 FILE *pin = safe_fopen(argv[1], "r", EXIT_FAILURE);
37 ucitaj_tacke(pin, tacke, &n);
38 fclose(pin);
39
40 // a)
41
42 char naziv[MAX_NAZIV];
43 strcpy(naziv, "pripada_krugu_poluprecnika_");
44 strcat(naziv, argv[2]);
45 strcat(naziv, ".txt");
46
47 double r = atof(argv[2]);
48 TACKA teziste = pronadji_teziste(tacke, n);
49
50 FILE *pout = safe_fopen(naziv, "w", EXIT_FAILURE);
51 fprintf(pout, "Krug poluprecnika %.2lf sa centrom u tacki ", r);
52 ispisi_tacku(pout, teziste);
53 fprintf(pout, "\n");
54
55 // b)
56
57 pripada_krugu(pripadaju_krugu, tacke, n, &m, teziste, r);
58 ispisi_tacke(pout, pripadaju_krugu, m);
59
60 fclose(pout);
61
62 // c)
63
64 pout = safe_fopen("trouglovi.txt", "w", EXIT_FAILURE);
65 fprintf(pout, "Broj trouglova: %u\n", prebroj_trouglove(tacke, n));
66
67 fclose(pout);
68
69 return EXIT_SUCCESS;
70}
71
72FILE *safe_fopen(char *pname, char *pmode, int error_code) {
73 FILE *pf = fopen(pname, pmode);
74
75 if(pf == NULL) {
76 printf("Datoteka sa imenom %s nije uspesno otvorena.\n", pname);
77 exit(error_code);
78 }
79
80 return pf;
81}
82
83void ucitaj_tacke(FILE *pin, TACKA *tacke, int *pn) {
84 int i = 0;
85
86 while(fscanf(pin, "%lf %lf", &tacke[i].x,
87 &tacke[i].y) != EOF) {
88 i++;
89 }
90
91 *pn = i;
92}
93
94void ispisi_tacke(FILE *pout, TACKA *tacke, int n) {
95 int i;
96
97 for(i = 0;i < n;i++) {
98 ispisi_tacku(pout, tacke[i]);
99 }
100}
101
102void ispisi_tacku(FILE *pout, TACKA tacka) {
103 fprintf(pout, "(%.2lf, %.2lf)\n", tacka.x, tacka.y);
104}
105
106unsigned prebroj_trouglove(TACKA *tacke, int n) {
107 int i, j, k;
108 unsigned broj_trouglova = 0;
109
110 for(i = 0;i < n;i++) {
111 for(j = i + 1;j < n;j++) {
112 for(k = j + 1;k < n;k++) {
113 if(obrazuju_trougao(tacke[i],
114 tacke[j],
115 tacke[k])) {
116 broj_trouglova++;
117 }
118 }
119 }
120 }
121
122 return broj_trouglova;
123}
124
125TACKA pronadji_teziste(TACKA *tacke, int n) {
126 int i;
127 double suma_x = 0, suma_y = 0;
128
129 TACKA tezisna_tacka;
130
131 for(i = 0;i < n;i++) {
132 suma_x += tacke[i].x;
133 suma_y += tacke[i].y;
134 }
135
136 tezisna_tacka.x = suma_x / n;
137 tezisna_tacka.y = suma_y / n;
138
139 return tezisna_tacka;
140}
141
142void pripada_krugu(TACKA *pripada, TACKA *tacke,
143 int n, int *pm, TACKA centar, double r) {
144 int i, j = 0;
145
146 for(i = 0;i < n;i++) {
147 if(udaljenost(tacke[i], centar) <= r) {
148 pripada[j] = tacke[i];
149 j++;
150 }
151 }
152
153 *pm = j;
154}
155
156int obrazuju_trougao(TACKA t1, TACKA t2, TACKA t3) {
157 double a = udaljenost(t1, t2);
158 double b = udaljenost(t2, t3);
159 double c = udaljenost(t1, t3);
160
161 return (a + b > c) && (b + c > a) && (c + a > b);
162}
163
164double udaljenost(TACKA t1, TACKA t2) {
165 return sqrt(pow(t1.x - t2.x, 2) + pow(t1.y - t2.y, 2));
166}
167