/[opencvs]/eyes/holo_complex.c
ViewVC logotype

Contents of /eyes/holo_complex.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.6 - (show annotations)
Thu May 26 00:01:50 2011 UTC (9 years, 4 months ago) by hib
Branch: MAIN
Changes since 1.5: +142 -135 lines
File MIME type: text/plain
Added maxrate to dullen the effect of the hologram - this should keep the printing of black a bit more under control, but not always.

1
2 #include <stdio.h>
3 #include <math.h>
4 #include <stdlib.h>
5 #include "holo_complex.h"
6
7 /* $Revision: 1.4 $
8 This allows us to do complex functions yeah!
9
10 $Log: holo_complex.h,v $
11
12 */
13
14
15
16
17 /* Randomize the phase to make the effect look better.
18 In actuality, the phase should be determined by z position or something
19 because oif this, we need to set the random number being used - so we can reconstruct the
20 same image over and over again, and also make sub-images like my eyes will demand
21 */
22 complex crandomize_phase2(complex a) {
23 complex c;
24 double amp;
25 amp = camplitude(a);
26 csetpol(c,amp, ((double)(random() % 1000000)) / (PI*2.0));
27 return c;
28 }
29
30
31
32
33
34
35 /* Set it up with a point, wave, and lamda */
36 point_source point_source_init_point(point3d p,complex wave, double lamda)
37 {
38 point_source c;
39 c.point = p;
40 c.wave = wave;
41 c.lamda = lamda;
42 c.one_over_lamda_times_twopi = 1.0/lamda* TWOPI;
43 c.amp = camplitude(c.wave);
44 c.phase = cphase(c.wave);
45 return c;
46 }
47
48
49 point_source point_source_init_xyz_amp_lamda_phase(double x, double y, double z, double amp, double lamda, double phase)
50 {
51 point_source c;
52 c.point.x = x;
53 c.point.y = y;
54 c.point.z = z;
55 csetpol(c.wave,amp,phase);
56 c.lamda = lamda;
57 c.one_over_lamda_times_twopi = 1.0/lamda * TWOPI;
58 c.amp = amp;
59 c.phase = phase;
60 return c;
61 }
62
63
64 point_source point_source_init_xyz_amp_lamda_phase_atten(double x, double y, double z, double amp, double lamda, double phase, double atten)
65 {
66 /* attn is ignored */
67 point_source c;
68 c.point.x = x;
69 c.point.y = y;
70 c.point.z = z;
71 csetpol(c.wave,amp,phase);
72 c.lamda = lamda;
73 c.one_over_lamda_times_twopi = 1.0/lamda * TWOPI;
74 c.amp = amp;
75 c.phase = phase;
76 return c;
77 }
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 void psa_add_point_source(point_source_array *psa,point_source ps) {
101 if (psa->size==psa->alloc_size) {
102 psa->alloc_size = psa->alloc_size + psa->alloc_size;
103 if (!psa->alloc_size) psa->alloc_size=1024;
104 point_source *new_source = malloc(sizeof(point_source)*psa->alloc_size);
105 if (!(new_source)) {
106 fprintf(stderr,"out of memory trying to get %ld bytes\n",sizeof(point_source)*psa->alloc_size);
107 exit(-1);
108 }
109 int i;
110 for (i=0;i<psa->size;i++) {
111 new_source[i] = psa->point_sources[i];
112 }
113 free(psa->point_sources);
114 psa->point_sources = new_source;
115 }
116 psa->point_sources[(psa->size)++] = ps;
117 }
118
119
120
121
122 void psa_clear_point_source_array(point_source_array *psa)
123 {
124 if (psa->point_sources) free(psa->point_sources);
125 psa->point_sources = NULL;
126 psa->size = 0;
127 psa->alloc_size = 0;
128 }
129
130
131
132
133
134 void psa_randomize_phases(point_source_array *psa)
135 { int i;
136 for (i = 0; i < psa->size; i++)
137 {
138 psa->point_sources[i].wave=crandomize_phase2(psa->point_sources[i].wave);
139 }
140 }
141
142
143
144
145
146
147
148 void cpp_initialize_plate(complex_photo_plate *cpp,int xResolution, int yResolution, int x_offset, int y_offset,
149 double xSampling, double ySampling, int center)
150 {
151 cpp->max_x_res=xResolution;
152 cpp->max_y_res=yResolution;
153 cpp->x_sampling_rate=xSampling;
154 cpp->y_sampling_rate=ySampling;
155 cpp->x_offset=x_offset;
156 cpp->y_offset=y_offset;
157 cpp->elements = calloc(sizeof(double),xResolution*yResolution);
158
159 }
160
161
162 void cpp_initialize_plate_xysxsyc(complex_photo_plate *cpp,
163 int xResolution, int yResolution,
164 double xSampling, double ySampling, int center)
165 {
166 int x_offset=0, y_offset=0;
167
168 if(center)
169 {
170 cpp->x_offset=(int)(cpp->max_x_res*xSampling/2.0);
171 cpp->y_offset=(int)(cpp->max_y_res*ySampling/2.0);
172 }
173
174 cpp_initialize_plate(cpp,xResolution, yResolution, x_offset, y_offset, xSampling, ySampling, center);
175 }
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195 int find_the_two_colors (int r,int g,int b,int maxrate, int *rl, int *rh, int *gl, int *gh, int *bl, int *bh) {
196 /* maxrate is 128 for full on or off to the maximum of the pixel - which is great, except that
197 when printing things, the printer generally will use too much black ink, and the picture is too dark.
198 So a rate of 25% will make the pixel look much less evident - sometimes the rate is less than the 25 % because of
199 the base pixel, and thats ok, this is just eh maximum setting to give the printers a break.
200 */
201
202
203 if (r<127) { /* simple. low is 0,0,0 and high is 2x value */
204 int diff = r;
205 if (diff > maxrate) diff=maxrate;
206 *rl = r-diff;
207 *rh = r+diff;
208 }
209 else { /* can't fluxuate fully, need to go from 255 (white) to 255 - the difference */
210 int diff=255-r;
211 if (diff > maxrate) diff=maxrate;
212 *rh = r+diff;
213 *rl = r-diff;
214 }
215 if (g<127) { /* simple. low is 0,0,0 and high is 2x value */
216 int diff = g;
217 if (diff > maxrate) diff=maxrate;
218 *gl = g-diff;
219 *gh = g+diff;
220 }
221 else { /* can't fluxuate fully, need to go from 255 (white) to 255 - the difference */
222 int diff=255-g;
223 if (diff > maxrate) diff=maxrate;
224 *gh = g+diff;
225 *gl = g-diff;
226 }
227 if (b<127) { /* simple. low is 0,0,0 and high is 2x value */
228 int diff = b;
229 if (diff > maxrate) diff=maxrate;
230 *bl = b-diff;
231 *bh = b+diff;
232 }
233 else { /* can't fluxuate fully, need to go from 255 (white) to 255 - the difference */
234 int diff=255-b;
235 if (diff > maxrate) diff=maxrate;
236 *bh = b+diff;
237 *bl = b-diff;
238 }
239
240 }
241
242
243
244 int holo_output_vary_constant_background(double *elements,int xspan, int yspan,int r,int g,int b,int maxrate) {
245 double max;
246 double min;
247 int rl,rh;
248 int gl,gh;
249 int bl,bh;
250 find_the_two_colors(r,g,b,maxrate,&rl,&rh,&gl,&gh,&bl,&bh);
251 max = min = elements[0];
252 int i;
253 for (i = 0; i < yspan; i++)
254 {
255 int j;
256 for (j = 0; j < xspan; j++)
257 {
258 double re = (elements[i*xspan+j]);
259 if (re > max) max=re;
260 if (re<min) min=re;
261 }
262 }
263
264
265 /* This adjusts the average point up or down to make the image 50/50.
266 This is important to get the colors spot on */
267 int iter;
268 double delta = (max-min)*0.5;
269 double avg = (max+min)*0.5;
270 for (iter=0;iter<100;iter++) {
271 double sum;
272 sum = 0.;
273 for (i = 0; i < yspan; i++)
274 {
275 int j;
276 for (j = 0; j < xspan; j++)
277 {
278 double re= (elements[i*xspan+j]);
279 if (re >= avg) sum= sum+1.;
280 }
281 }
282 sum = sum / (double)(yspan);
283 sum = sum / (double)(xspan);
284 if (sum>0.5) {
285 delta = delta * 0.5;
286 avg = avg + delta;
287 }
288 else {
289 delta = delta * 0.5;
290 avg = avg - delta;
291 }
292 }
293
294 printf("# ImageMagick pixel enumeration: %d,%d,255,rgb\n",xspan,yspan);
295
296 for (i = 0; i < yspan; i++)
297 {
298 int j;
299 for (j = 0; j < xspan; j++)
300 {
301 double val = elements[i*xspan+j];
302 if (val >=avg) {
303 printf("%d,%d: (%d,%d,%d) #%06x rgb(%d,%d,%d)\n",j,i,rh,gh,bh,rh*65536+gh*256+bh,rh,gh,bh);
304 }
305 else {
306 printf("%d,%d: (%d,%d,%d) #%06x rgb(%d,%d,%d)\n",j,i,rl,gl,bl,rl*65536+gl*256+bl,rl,gl,bl);
307 }
308 }
309 }
310 }
311
312
313
314
315
316
317 int holo_output_simple(complex_photo_plate *cpp) {
318 double max;
319 double min;
320 max = min = cpp->elements[0];
321 int i;
322 for (i = 0; i < cpp->max_y_res; i++)
323 {
324 int j;
325 for (j = 0; j < cpp->max_x_res; j++)
326 {
327 double re = (cpp->elements[i*cpp->max_x_res+j]);
328 if (re > max) max=re;
329 if (re<min) min=re;
330 }
331 }
332
333 int binary=1;
334
335 printf("# ImageMagick pixel enumeration: %d,%d,255,rgb\n",cpp->max_x_res,cpp->max_y_res);
336
337 for (i = 0; i < cpp->max_y_res; i++)
338 {
339 int j;
340 for (j = 0; j < cpp->max_x_res; j++)
341 {
342 int val = (((cpp->elements[i*cpp->max_x_res+j]) - min) / (max-min) *256.);
343
344 if (binary) {
345
346 if (val>=128 ) {
347 printf("%d,%d: (255,255,255) #FFFFFF rgb(255,255,255)\n",j,i);
348 }
349 else {
350 printf("%d,%d: (0,0,0) #000000 rgb(0,0,0)\n",j,i);
351 }
352 }
353 else {
354 if (val>255) val=255;
355 printf("%d,%d: (%d,%d,%d) #%06x rgb(%d,%d,%d)\n",j,i,val,val,val,val*65536+val*256+val,val,val,val);
356 }
357 }
358 }
359 }
360
361
362
363
364
365
366
367
368
369
370 double apply_point_sources(point_source_array *psa,double spot,point3d n) {
371 double v;
372 v = spot; /* should normally be 0 */
373
374 /* get the phase and amplituyde - could be done once yo */
375 double amp;
376 double phase;
377 double dist;
378 int i;
379 for (i=0;i<psa->size;i++) {
380 point_source ps;
381 ps = psa->point_sources[i];
382 dist = point3d_distance_points((ps.point),(n));
383 /*phase = phase * time*C * p.one_over_lamda_times_twopi;
384 Stupid time is dist / c so why /c and *c? */
385 phase = ps.phase + dist * ps.one_over_lamda_times_twopi;
386 v = v + ps.amp * cos(phase);
387 }
388 return v;
389
390 }
391
392
393
394
395
396 int holo_sample () {
397 complex_photo_plate cppx;
398 complex_photo_plate *cpp = &cppx;
399 point_source_array psax;
400 point_source_array *psa = &(psax);
401 psa->point_sources = NULL;
402 psa_clear_point_source_array(psa);
403
404 cpp_initialize_plate(cpp,1200,1200,0,0,423.e-7,423e-7,1);
405 point_source ps;
406 {int a;
407 for (a=0;a<100;a++) {
408 double b=((double)(a))*0.001;
409 ps = point_source_init_xyz_amp_lamda_phase(b+0.01269,0.01269,4.,1.,630.e-9,-1.25);
410 psa_add_point_source(psa,ps);
411 ps = point_source_init_xyz_amp_lamda_phase(0.,b+0.01269,4.,1.,500.e-9,-1.25);
412 psa_add_point_source(psa,ps);
413 ps = point_source_init_xyz_amp_lamda_phase(b+-0.01269,0.01269,4.,1.,450.e-9,-1.25);
414 psa_add_point_source(psa,ps);
415 }
416 }
417 double x_sampling = 423e-7;
418 double y_sampling = 423e-7;
419
420
421 int i;
422 int y;
423 int x;
424 double z=0.0;
425 for (y=0;y<cpp->max_y_res;y++) {
426 double v;
427 double yy = y*cpp->x_sampling_rate;
428 for (x=0;x<cpp->max_x_res;x++) {
429 double xx = x*cpp->x_sampling_rate;
430 v = cpp->elements[y*cpp->max_x_res+x];
431
432 /* get the phase and amplituyde - could be done once yo */
433 complex w;
434 double amp;
435 double phase;
436 double dist;
437 point3d n;
438 n.x = xx;
439 n.y = yy;
440 n.z = z;
441
442 for (i=0;i<psa->size;i++) {
443 point_source ps;
444 ps = psa->point_sources[i];
445 dist = point3d_distance_points((ps.point),(n));
446 /*phase = phase * time*C * p.one_over_lamda_times_twopi;
447 Stupid time is dist / c so why /c and *c? */
448 phase = ps.phase + dist * ps.one_over_lamda_times_twopi;
449 v = v + ps.amp * cos(phase);
450 }
451 cpp->elements[y*cpp->max_x_res+x] = v;
452 }
453 }
454
455
456 holo_output_simple(cpp);
457 exit(0);
458 }

  ViewVC Help
Powered by ViewVC 1.1.26