summaryrefslogtreecommitdiffstats
path: root/fiz/naloga/numerično.c
blob: e10289912cc51f8982f6695759ff6d56a20036f3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include <stdlib.h>
#include <stdio.h>
#include <error.h>
#include <math.h>
#define UVOD "program za numerični izračun jakosti magnetnega polja okoli helmholtzove tuljave\n" \
	"sem spisal anton luka šijanec za projektno nalogo pri fiziki v tretjem letniku gimb.\n" \
	"uporaba: %s	in argumenti po vrsti:\n" \
	"	1. radij enega navitja v metrih\n" \
	"	2. tok, ki teče po vodniku v amperih\n" \
	"	3. število navojev na enem navitju\n" \
	"	4. razmak med merilnimi točkami v metrih\n" \
	"	5. koliko meritev od središča v obe dimenziji naj napravimo\n" \
	"	6. koliko kotov naj ima navitje - računamo, kot da je mnogokotnik\n" \
	"	7. tip izhodnih podatkov (pgm ali csv)\n" \
	"oblika izhodnih podatkov, če je 7. parameter pgm, so pgm slike z vrednostmi 0-255\n" \
	"	- slika je prerez tuljave. magnetno polje teče vodoravno.\n" \
	"	- vrednosti direktno korelirajo z izračunano jakostjo v decigaussih: 10e-5 tesla\n" \
	"	- slika je široka 1+2*koliko in visoka 1+2*koliko (5. argument) slikovnih točk\n" \
	"oblika izhodnih podatkov, če je 7. parameter csv, je csv, z naslednjimi stolpci:\n" \
	"	1. vodoravna komponenta oddaljenosti od središča tuljave v metrih\n" \
	"	2. navpična komponenta oddaljenosti od središča tuljave v metrih\n" \
	"	3. jakost magnetnega polja v teslah - tokrat ni v decigaussih!\n" \
	"	4. smer vektorja magnetnega polja v radianih. 0 radianov je smer v desno"
enum oblika {
	PGM,
	CSV
};
struct vektor {
	long double i; // x - desno na sliki
	long double j; // y - gor na sliki
	long double k; // z - v monitor
};
struct vektor seštej (struct vektor a, struct vektor b) {
	struct vektor r = {
		.i = a.i + b.i,
		.j = a.j + b.j,
		.k = a.k + b.k,
	};
	return r;
}
struct vektor vektorski_produkt (struct vektor a, struct vektor b) {	// ne bom implementiral
	struct vektor r = {						// matrik
		.i = a.j*b.k - a.k*b.j,
		.j = a.k*b.i - a.i*b.k,
		.k = a.i*b.j - a.j*b.i
	};
	return r;
}
struct vektor množi (struct vektor a, long double d) {
	struct vektor r = {
		.i = a.i * d,
		.j = a.j * d,
		.k = a.k * d
	};
	return r;
}
long double absolutno (struct vektor a) {
	return sqrtl(a.i*a.i+a.j*a.j+a.k*a.k);
}
#define MU0 4e-6*M_PI
struct vektor tuljava (long double R,	unsigned kotov, struct vektor m /* meritev - krajevni */) {
	long double dl_abs = 2*M_PI*R/kotov;	// metri - dolžina vodnika
	long double dr = 2*M_PI/kotov;		// radiani - kot med dl in točko na (0,R - vrh zanke)
	struct vektor B = {
		.i = 0,
		.j = 0,
		.k = 0
	};
	for (unsigned i = 0; i < kotov; i++) {
		long double theta = dr*i;	// kot na krogu
		struct vektor dl;
		dl.j = cosl(theta)*dl_abs;
		dl.k = -sinl(theta)*dl_abs;	// minus po skici sodeč ://of.sijanec.eu/sfu/skic.jpg
		dl.i = 0;			// sicer je vseeno, m je na z = 0 in gledamo vse
		struct vektor r;
		r.i = 0;
		r.j = sinl(theta)*R;
		r.k = cosl(theta)*R;
		r = seštej(r, m);
		B =	seštej(B,
				množi(
					vektorski_produkt(dl, r),
					1/(absolutno(r)*absolutno(r)*absolutno(r))
				)
			);
	}
	B = množi(B, MU0/(4*M_PI));
	return B;
} // ena zanka ob toku 1 A. pomnoži s tokom in številom navitij. 0,0 je v sredini. B teče v desno.
void natisni (FILE * f, struct vektor v, const char * i) {
	fprintf(f, "vektor %s {\n\t.i = %Lf,\n\t.j = %Lf,\n\t.k = %Lf\n}\n", i, v.i, v.j, v.k);
}
int main (int argc, char ** argv) {
	if (argc != 1 + 7)
		error(1, 0, UVOD, argv[0] ? argv[0] : "./numerično");
	long double R = strtold(argv[1], NULL);
	long double I = strtold(argv[2], NULL);
	unsigned n = strtol(argv[3], NULL, 10);
	long double razmak = strtold(argv[4], NULL);
	int koliko = strtold(argv[5], NULL);
	unsigned kotov = strtol(argv[6], NULL, 10);
	enum oblika oblika = argv[7][0] == 'p' || argv[7][0] == 'P' ? PGM : CSV;
	struct vektor merilno_mesto = {	// krajevni vektor
		.k = 0
	};
	if (oblika == CSV)
		error(2, 0, "CSV oblika še ni implementirana.");
	printf("P5 %u %u 255\n", koliko*2+1, koliko*2+1);
	struct vektor Rpolovic = {
		.i = R/2,
		.j = 0,
		.k = 0
	};
	for (int i = -koliko; i <= koliko; i++) {
		merilno_mesto.i = i*razmak;
		for (int j = -koliko; j <= koliko; j++) {
			merilno_mesto.j = j*razmak;
			unsigned long long int out =
				1000*absolutno(seštej(
					množi(
						množi(
							tuljava(
								R,
								kotov,
								seštej(
									merilno_mesto,
									Rpolovic
								)
							),
							n
						),
						I
					),
					množi(
						množi(
							tuljava(
								R,
								kotov,
								seštej(
									merilno_mesto,
									množi(
										Rpolovic,
										-1
									)
								)
							),
							n
						),
						I
					)
				));
			if (out > 255)
				putchar(255);
			else
				putchar(out);
		}
	}
	return 0;
}