Tačke u trodimenzionalnom prostoru

Autor zadatka: Rade Radišić <radisic.rade@uns.ac.rs>

Tačke u trodimenzionalnom Dekartovom koordinatnom sistemu opisane su preko njihovih koordinata:

  • Vrednost na x-osi (realan broj dvostruke preciznosti)

  • Vrednost na y-osi (realan broj dvostruke preciznosti)

  • Vrednost na z-osi (realan broj dvostruke preciznosti)

  • Rastojanje od koordinatnog početka (realan broj dvostruke preciznosti)

Učitati tačke iz ulazne datoteke, potom uraditi sledeće:

  1. Prilikom učitavanja izračunati rastojanje od koordinatnog početka (formula data pre sekcije "Napomene"). Nakon toga, zapisati koordinate u izlaznu datoteku čije ime se zadaje kao argument komandne linije u sledećem formatu: "(x, y, z), d", gde su x, y i z redom koordinate tačke, a d rastojanje od koordinatnog početka.

  2. Pronaći najbližu i najdalju tačku tačku od koordinatnog početka. Izračunati njihovu međusobnu udaljenost, potom izračunati zapreminu kocke čija je stranica dužine udaljenosti između tih tačaka.

  3. Izračunati zapreminu kocke čija stranica se unosi u program kao argument komandne linije (može biti realna vrednost). Upisati zapreminu iz prethodnog koraka (pod b) i dobijenu zapreminu u izlaznu datoteku, kao zapreminu tela koje bi nastalo kada bi se od veće kocke odsekao deo veličine manje kocke. Izlazna datoteka treba da nosi ime koje počinje sa "sracunata"/"argument", "_kocka_minus_", "sracunata"/"argument", "_kocka.txt", gde će prva biti kocka sa većom, a druga kocka sa manjom zapreminom.

Primer poziva programa:

./a.out tacke.txt tacke_formatirano.txt 5

Primer ulazne datoteke tacke.txt:

1 1 1
2 1 3
4 1 7
3 5 3
7 7 7
1 8 7

Primer izlazne datoteke tacke_formatirano.txt:

(1.00, 1.00, 1.00), 1.73
(2.00, 1.00, 3.00), 3.74
(4.00, 1.00, 7.00), 8.12
(3.00, 5.00, 3.00), 6.56
(7.00, 7.00, 7.00), 12.12
(1.00, 8.00, 7.00), 10.68

Primer izlazne datoteke sracunata_kocka_minus_argument_kocka.txt:

Zapremina sracunate kocke: 1122.37
Zapremina argument kocke: 125.00
Razlika u zapreminama: 997.37

Korisne matematičke formule

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:

\[d = \sqrt{(x_{1} - x_{2})^2 + (y_{1} - y_{2})^2}\]

Zapremina kocke

Zapremina kocke za kocku stranice \(a\) računa se na sledeći način:

\[P = a^3\]

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 42
  8
  9typedef struct tacka_st {
 10    double x;
 11    double y;
 12    double z;
 13    double udaljenost_od_pocetka;
 14} TACKA;
 15
 16FILE *safe_fopen(char *, char *, int);
 17void ucitaj_tacke(FILE *, TACKA *, int *);
 18void ispisi_tacke(FILE *, TACKA *, int);
 19void ispisi_tacku(FILE *, TACKA);
 20
 21TACKA najbliza_pocetku(TACKA *, int);
 22TACKA najdalja_od_pocetka(TACKA *, int);
 23
 24double udaljenost(TACKA, TACKA);
 25double udaljenost_od_pocetka(TACKA);
 26double zapremina_kocke(double);
 27
 28int main(int args_num, char **args) {
 29    TACKA tacke[MAX_SIZE], pripadaju_krugu[MAX_SIZE];
 30    int n, m;
 31
 32    if(args_num != 4) {
 33        printf("Niste dobro pozvali program. Primer poziva: ./a.out tacke.txt tacke_formatirano.txt 5");
 34        exit(EXIT_FAILURE);
 35    }
 36
 37    FILE *pin = safe_fopen(args[1], "r", EXIT_FAILURE);
 38    ucitaj_tacke(pin, tacke, &n);
 39    fclose(pin);
 40
 41    // a)
 42    
 43    FILE *pout = safe_fopen(args[2], "w", EXIT_FAILURE);
 44    ispisi_tacke(pout, tacke, n);
 45    fclose(pout);
 46    
 47    // b)
 48    
 49    double zapremina_koord_kocke = zapremina_kocke(udaljenost(najbliza_pocetku(tacke, n),
 50                                                              najdalja_od_pocetka(tacke, n)));
 51    
 52    // c)
 53    
 54    double zapremina_arg_kocke = zapremina_kocke(atof(args[3]));
 55    char naziv[MAX_NAZIV];
 56               
 57    if(zapremina_koord_kocke > zapremina_arg_kocke) {
 58        strcpy(naziv, "sracunata_kocka_minus_argument_kocka.txt");
 59    } else {
 60        strcpy(naziv, "argument_kocka_minus_sracunata_kocka.txt");
 61    }
 62    
 63    pout = safe_fopen(naziv, "w", EXIT_FAILURE);
 64    fprintf(pout, "Zapremina sracunate kocke: %.2lf\n", zapremina_koord_kocke);
 65    fprintf(pout, "Zapremina argument kocke: %.2lf\n", zapremina_arg_kocke);
 66    fprintf(pout, "Razlika u zapreminama: %.2lf\n", fabs(zapremina_arg_kocke - zapremina_koord_kocke));
 67    
 68    fclose(pout);
 69
 70    return EXIT_SUCCESS;
 71}
 72
 73FILE *safe_fopen(char *pname, char *pmode, int error_code) {
 74    FILE *pf = fopen(pname, pmode);
 75
 76    if(pf == NULL) {
 77        printf("Datoteka sa imenom %s nije uspesno otvorena.\n", pname);
 78        exit(error_code);
 79    }
 80
 81    return pf;
 82}
 83
 84void ucitaj_tacke(FILE *pin, TACKA *tacke, int *pn) {
 85    int i = 0;
 86
 87    while(fscanf(pin, "%lf %lf %lf", &tacke[i].x,
 88                                     &tacke[i].y,
 89                                     &tacke[i].z) != EOF) {
 90        tacke[i].udaljenost_od_pocetka = udaljenost_od_pocetka(tacke[i]);
 91        i++;
 92    }
 93
 94    *pn = i;
 95}
 96
 97void ispisi_tacke(FILE *pout, TACKA *tacke, int n) {
 98    int i;
 99
100    for(i = 0;i < n;i++) {
101        ispisi_tacku(pout, tacke[i]); 
102    }
103}
104
105void ispisi_tacku(FILE *pout, TACKA tacka) {
106    fprintf(pout, "(%.2lf, %.2lf, %.2lf), %.2lf\n", tacka.x, tacka.y, tacka.z, tacka.udaljenost_od_pocetka);
107}
108
109TACKA najbliza_pocetku(TACKA *tacke, int n) {
110    int i;
111    TACKA najbliza_tacka = tacke[0];
112    double min_udaljenost = udaljenost_od_pocetka(najbliza_tacka);
113    
114    for(i = 1;i < n;i++) {
115        if(udaljenost_od_pocetka(tacke[i]) < min_udaljenost) {
116            min_udaljenost = udaljenost_od_pocetka(tacke[i]);
117            najbliza_tacka = tacke[i];
118        }
119    }
120    
121    return najbliza_tacka;
122}
123
124TACKA najdalja_od_pocetka(TACKA *tacke, int n) {
125    int i;
126    TACKA najdalja_tacka = tacke[0];
127    double max_udaljenost = udaljenost_od_pocetka(najdalja_tacka);
128    
129    for(i = 1;i < n;i++) {
130        if(udaljenost_od_pocetka(tacke[i]) > max_udaljenost) {
131            max_udaljenost = udaljenost_od_pocetka(tacke[i]);
132            najdalja_tacka = tacke[i];
133        }
134    }
135    
136    return najdalja_tacka;
137}
138
139double udaljenost(TACKA t1, TACKA t2) {
140    return sqrt(pow(t1.x - t2.x, 2) + pow(t1.y - t2.y, 2) + pow(t1.z - t2.z, 2));
141}
142
143double udaljenost_od_pocetka(TACKA t) {
144    return sqrt(pow(t.x, 2) + pow(t.y, 2) + pow(t.z, 2));
145}
146
147double zapremina_kocke(double a) {
148    return pow(a, 3);
149}
150