/*----------------------------5.1.c--------------------------*/
/* Program uvodi strukture - geometrijske figure */
#include <stdio.h>

/* Zbog funkcije sqrt. */
#include <math.h>
/* Upozorenje : pod linux-om je potrebno program prevoditi sa 
      gcc -lm 7.4.c 
   kada god se koristi <math.h>
*/

/* Tacke su predstavljene sa dve koordinate. Strukturom gradimo novi tip podataka. */
struct point
{
	int x;
	int y;
};

/* Izracunava duzinu duzi zadatu sa dve tacke */
float segment_length(struct point A, struct point B)
{
	int dx = A.x - B.x;
	int dy = A.y - B.y;
	return sqrt(dx*dx + dy*dy);
}

/* Izracunava povrsinu trougla Heronovim obrascem. 
   Argumenti funkcije su tri tacke koje predstavljaju temena trougla */
float Heron(struct point A, struct point B, struct point C)
{
	/* Duzine stranica */
	float a = segment_length(B, C);
	float b = segment_length(A, C);
	float c = segment_length(A, B);

	/* Poluobim */
	float s = (a+b+c)/2;

	return sqrt(s*(s-a)*(s-b)*(s-c));
}

/* Izracunava obim poligona. Argumenti funkcije su niz tacaka 
   koje predstavljaju temena poligona kao i njihov broj */
float circumference(struct point polygon[], int num)
{
	int i;
	float o = 0.0;
	
	/* Dodajemo duzine stranica koje spajaju susedna temena */
	for (i = 0; i<num-1; i++)
		o += segment_length(polygon[i], polygon[i+1]);

	/* Dodajemo duzinu stranice koja spaja prvo i poslednje teme */
	o += segment_length(polygon[num-1], polygon[0]);

	return o;
}

/* Izracunava povsinu konveksnog poligona. Argumenti funkcije su niz tacaka 
   koje predstavljaju temena poligona kao i njihov broj */
float area(struct point polygon[], int num)
{
	/* Povrsina */
	float a = 0.0;
	int i;

	/* Poligon delimo na trouglove i posebno izracunavamo povrsinu svakoga od njih */
	for (i = 1; i < num -1; i++)
		a += Heron(polygon[0], polygon[i], polygon[i+1]);

	return a;
}

main()
{
	/* Definisemo dve promenljive tipa tacke */
	struct point a;

	/* Inicijalizujemo tacku b na (1,2) */
	struct point b = {1, 2};

	/* triangle je niz od tri tacke - trougao (0,0), (0,1), (1,0) */
	struct point triangle[3];

	/* square je niz od cetiri tacke - jedinicni kvadrat. 
	   Obratiti paznju na nacin inicijalizacije niza struktura */
	struct point square[4] = 
	  {{0, 0}, {0, 1}, {1, 1}, {1, 0}};

	/* Postavljamo vrednosti koordinata tacke a*/
	a.x = 0; a.y = 0;

	/* Gradimo trougao (0,0), (0,1), (1,0) */
	triangle[0].x = 0;	triangle[0].y = 0;
	triangle[1].x = 0;	triangle[1].y = 1;
	triangle[2].x = 1;	triangle[2].y = 0;


	/* Ispisujemo velicinu strukture tacka */
	printf("sizeof(struct point) = %d\n", sizeof(struct point));

	/* Ispisujemo vrednosti koordinata tacaka */
	printf("x koordinata tacke a je %d\n", a.x);
	printf("y koordinata tacke a je %d\n", a.y);
	printf("x koordinata tacke b je %d\n", b.x);
	printf("y koordinata tacke b je %d\n", b.y);

	printf("Obim trougla je %f\n",  
		circumference(triangle, 3));
	printf("Obim kvadrata je %f\n", 
		circumference(square, 4));
	printf("Povrsina trougla je %f\n", 
		Heron(triangle[0], triangle[1], triangle[2]));
	/* Broj tacaka je moguce odrediti i putem sizeof */
	printf("Povrsina kvadrata je %f\n", 
		area(square, sizeof(square)/sizeof(struct point)));

}


/*----------------------------5.1a.c--------------------------*/
/* Koriscenje typedef radi lakseg rada */
#include <stdio.h>

#include <math.h>
/* Ovim se omogucava da se nadalje u programu umesto int moze 
   koristiti ceo_broj */
typedef int ceo_broj ;

/* Ovim se omogucuje da se nadalje u programu umesto struct point 
  moze koristiti POINT */
typedef struct point POINT;

struct point
{
	int x;
	int y;
};

main()
{
	/* Umesto int mozemo koristiti ceo_broj */
	ceo_broj x = 3;

	/* Definisemo promenljivu tipa tacke. 
	   Umesto struct point mozemo koristiti POINT */
	POINT a;

	printf("x = %d\n", x);

	/* Postavljamo vrednosti koordinata tacke a*/
	a.x = 1; a.y = 2;
	/* Ispisujemo velicinu strukture tacka */
	printf("sizeof(struct point) = %d\n", sizeof(POINT));

	/* Ispisujemo vrednosti koordinata tacaka */
	printf("x koordinata tacke a je %d\n", a.x);
	printf("y koordinata tacke a je %d\n", a.y);

}


/*----------------------------5.1b.c--------------------------*/
/* Koriscenje typedef radi lakseg rada */
#include <stdio.h>

#include <math.h>

/* Deklaraciju strukture i typedef mozemo spojiti */
typedef struct point
{
	int x;
	int y;
} POINT;

main()
{
	/* Definisemo promenljivu tipa tacke. 
	   Umesto struct point mozemo koristiti POINT */
	POINT a;
	/* Postavljamo vrednosti koordinata tacke a*/
	a.x = 1; a.y = 2;
	/* Ispisujemo velicinu strukture tacka */
	printf("sizeof(struct point) = %d\n", sizeof(POINT));

	/* Ispisujemo vrednosti koordinata tacaka */
	printf("x koordinata tacke a je %d\n", a.x);
	printf("y koordinata tacke a je %d\n", a.y);

}


/*----------------------------5.2.c--------------------------*/
/* Strukture se u funkcije prenose po vrednosti. 
   Moguce je koristiti pokazivace na strukture */

#include <stdio.h>

typedef struct point
{
	int x, y;
} POINT;

/* Zbog prenosa po vrednosti tacka ne moze biti ucitana */
void get_point_wrong(POINT p)
{
	printf("x = ");
	scanf("%d", &p.x);
	printf("y = ");
	scanf("%d", &p.y);
}

/* Koriscenjem prenosa preko pokazivaca, uspevamo */
void get_point(POINT* p)
{
	/* p->x je skraceni zapis za (*p).x */

	printf("x = ");
	scanf("%d", &p->x);
	printf("y = ");
	scanf("%d", &p->y);
}


main()
{
	POINT a = {0, 0};

	printf("get_point_wrong\n");
	get_point_wrong(a);
	printf("a: x = %d, y = %d\n", a.x, a.y);

	printf("get_point\n");
	get_point(&a);
	printf("a: x = %d, y = %d\n", a.x, a.y);

}