1 

2 
#include <stdio.h> 
3 
#include <math.h> 
4 
#include <stdlib.h> 
5 

6 
/* 
7 
computer_generated_hologram_c V1.0 
8 

9 
holo_complex.h 
10 
Include this file if you are going to do the hologram complex stuff. 
11 

12 

13 
$Revision: 1.8 $ 
14 
$Log: holo_complex.h,v $ 
15 
Revision 1.8 20111018 03:37:19 hib 
16 
axnay the table based lookup  locality of reference killed it it was real slow. 
17 

18 
Revision 1.7 20111018 03:31:35 hib 
19 
intermediary where the sin and square root are done with a lookup table. 
20 
It ran slower! 
21 

22 
Revision 1.6 20111015 22:01:46 hib 
23 
Added build_double, find_gery_range, and fp_to_txt so that we can do some real cool stuff 
24 
like having the sin and cosine at the same time, for color, and 
25 
attenuate and all that. We are starting from scratch. Which sucks, because 
26 
it will take that much longer for 2880  but the effect will be beautiful 
27 
This time  we are going to start at the center part and then expand from there. 
28 
So we can get something cool out earlier. and we can test it computing the real version 
29 
oh yeah we now limit based on the nyquest frequency so we can really speed things up. 
30 

31 
Revision 1.5 20110712 06:05:09 hib 
32 
encirculate is a proof in concept for japan. 
33 

34 
Revision 1.4 20110623 05:07:56 hib 
35 
adding stuff  ben ,arissa partially done. Havent started stephanie. 
36 
Kelly and vikroia are shipped  did a demo of edition 2 of enlightenment 
37 
and building first version of japan 
38 
. 
39 

40 
Revision 1.3 20110605 05:18:17 hib 
41 
kelly and viktoria are done. Enlightenment is being cranked out at 1800x1800. 
42 
Just started work on Japan and enlightenment second edition  with alpha appropriated hologram pixels. 
43 
And also can print money with any percentage value I want  to save ink. 
44 

45 
Revision 1.2 20110526 00:01:50 hib 
46 
Added maxrate to dullen the effect of the hologram  this should keep the printing of black a bit more under control, but not always. 
47 

48 
Revision 1.4 20110525 23:00:52 hib 
49 
holo_complex  got rid of useless functions left over from the java conversion. 
50 
Now this thing is lean and mean, much closer to what we need. 
51 

52 
*/ 
53 

54 
/* 
55 
computer_generated_hologram_c V1.0 
56 

57 
Copyright (C) 2011 Hibbard M. Engler 
58 

59 
This program is free software: you can redistribute it and/or modify 
60 
it under the terms of the GNU General Public License as published by 
61 
the Free Software Foundation, either version 3 of the License, or 
62 
(at your option) any later version. 
63 

64 
This program is distributed in the hope that it will be useful, 
65 
but WITHOUT ANY WARRANTY; without even the implied warranty of 
66 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
67 
GNU General Public License for more details. 
68 

69 
You should have received a copy of the GNU General Public License 
70 
along with this program. If not, see <http://www.gnu.org/licenses/>. 
71 

72 
*/ 
73 
typedef double real; 
74 

75 

76 

77 
#define PI 3.1415926535897932384626433832795028 
78 

79 

80 

81 
/* complex psuedo functions */ 
82 
#define cset(c,r,i) {c=r;} 
83 
#define csetpol(c,amplitude,phase) {c.re =amplitude*cos(phase); c.im = amplitude * sin(phase);} 
84 
#define cplus(a,b,c) {c.re = a.re + b.re;c.im = a.im + b.im;} 
85 
#define cminus(a,b,c) { c.re = a.re  b.re; c.im = a.im  b.im;} 
86 
#define ctimes(a,b,c) { c.re = a.re * b.re  a.im * b.im; c.im = a.im * b.re + b.re * a.im;} 
87 
#define ctimes_d (a,x,c) { c.re = a.re * x; c.im = a.im * x;} 
88 
#define cpluseq = (c,b) { c.re += b.re;c.im += b.im;} 
89 
#define cconjugate(a,c) { c.re = a.re; c.im = a.im;} 
90 
#define camplitude(a) (sqrt(a.re*a.re+a.im*a.im)) 
91 
#define cphase(a) (atan2(a.im,a.re)) 
92 
#define creal(a) (a.re) 
93 
#define cimaginary(a) (a.im) 
94 
#define crandomize_phase(a,c) ((c)=randomize_phase2(a)) 
95 

96 
#define new_c2d(a,x,y) { a.array = malloc(x*y*sizeof(complex));} 
97 
#define free_c2d(a) { if (a.array) {free(a.array); a.array=NULL;}} 
98 
#define c2d(a,x,y) (a.array[a.x*y+x]); 
99 
#define c2dset(a,x,y,c) (a.array[a.x*y+x]=(c)) 
100 

101 

102 
#define point3d_distance_points(a,b) (sqrt((a.xb.x)*(a.xb.x)+(a.yb.y)*(a.yb.y) + (a.zb.z) * (a.zb.z))) 
103 
#define point3d_distance_squared_points(a,b) (((a.xb.x)*(a.xb.x)+(a.yb.y)*(a.yb.y) + (a.zb.z) * (a.zb.z))) 
104 
#define point3d_distance(a) (sqrt(a.x*a.x + a.y*a.y + a.z*a.z)) 
105 

106 
#define point_source_lamda_default 670e9; /* red light wavelength approx */ 
107 
#define TWOPI 6.28318531 
108 
#define C 3e+8 //speed of light (m/s) 
109 
#define ONE_OVER_C 3.333333333333333333e9 
110 

111 

112 
/* Complex data type  soon we wille schew this and just use cosine because we only care about real yo */ 
113 
struct complex { 
114 
real re; 
115 
real im; 
116 
}; 
117 

118 
typedef struct complex complex; 
119 

120 

121 

122 
/* 3 dimensional point  used for point sources */ 
123 
struct point3d { 
124 
real x; 
125 
real y; 
126 
real z; 
127 
}; 
128 

129 

130 
typedef struct point3d point3d; 
131 

132 

133 

134 

135 

136 
/* point source  we will usually have many of these */ 
137 

138 
struct point_source 
139 
{ 
140 
point3d point; /* where it is */ 
141 
complex wave; /* probably the phase of the wave or something */ 
142 
real amp; /* better to store this */ 
143 
real phase; /* ditto */ 
144 
real lamda; //approx wavelength of red light (m) but this could be different 
145 
/* one thing I was thinking of doing, is doing the point source 3 times  
146 
one for each color of each rod  base on being printed out at 720 dpi 
147 
the rgb effect should allow us to see something in space  maybee */ 
148 
real one_over_lamda_times_twopi; /* he he he speed increase */ 
149 
real max_distance_pixels; /* max distance in pixels to go before we end up so far away we start aliasing  new! */ 
150 
real max_distance_m; /* max distance in meters */ 
151 
real max_distance_m_squared; /* max distance in meters squared */ 
152 
}; 
153 

154 
typedef struct point_source point_source; 
155 

156 

157 
/* This is dynamically grown X2 over and over again */ 
158 
struct point_source_array { 
159 
int size; 
160 
int alloc_size; 
161 
point_source * point_sources; 
162 
}; 
163 

164 
typedef struct point_source_array point_source_array; 
165 

166 

167 

168 
/* The complex photo plat is what is struck on to make the actual picture 
169 
We will probably eschew this quickly too as we just need a real photo plate */ 
170 
struct complex_photo_plate { 
171 
int max_x_res; 
172 
int max_y_res; 
173 
real x_sampling_rate; 
174 
real y_sampling_rate; 
175 
int x_offset; 
176 
int y_offset; 
177 
real *elements; 
178 
}; 
179 

180 
typedef struct complex_photo_plate complex_photo_plate; 
181 

182 

183 

184 

185 
/* A kiss is not real, but it is what we wish was real */ 
186 
struct real_photo_plate { 
187 
int min, max, median; 
188 
complex_photo_plate plate; 
189 
/* BufferedImage im; */ 
190 
int output_type; 
191 
char * descr; 
192 
}; 
193 
typedef struct real_photo_plate real_photo_plate; 
194 

195 

196 

197 

198 
/*Complex2darray is malloc and free*/ 
199 
struct complex2darray { 
200 
int x; int y; 
201 
complex * array; 
202 
}; 
203 

204 

205 

206 

207 

208 
/* Randomize the phase to make the effect look better. 
209 
In actuality, the phase should be determined by z position or something 
210 
because oif this, we need to set the random number being used  so we can reconstruct the 
211 
same image over and over again, and also make subimages like my eyes will demand 
212 
*/ 
213 
complex crandomize_phase2(complex a); 
214 

215 

216 
/* Set it up with a point, wave, and lamda */ 
217 
point_source point_source_init_point(point3d p,complex wave, real lamda); 
218 

219 
point_source point_source_init_xyz_amp_lamda_phase(real x, real y, real z, real amp, real lamda, real phase); 
220 

221 
point_source point_source_init_xyz_amp_lamda_phase_atten(real x, real y, real z, real amp, real lamda, 
222 
real phase, real atten); 
223 

224 

225 
void psa_add_point_source(point_source_array *psa,point_source ps); 
226 

227 
void psa_clear_point_source_array(point_source_array *psa); 
228 

229 
void psa_randomize_phases(point_source_array *psa); 
230 

231 
void cpp_initialize_plate(complex_photo_plate *cpp,int xResolution, int yResolution, int x_offset, int y_offset, 
232 
real xSampling, real ySampling, int center); 
233 

234 

235 
void cpp_initialize_plate_xysxsyc(complex_photo_plate *cpp, 
236 
int xResolution, int yResolution, 
237 
real xSampling, real ySampling, int center); 
238 

239 
int holo_output_simple(real *elements,int xspan,int yspan); 
240 

241 

242 
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); 
243 

244 
int holo_output_vary_constant_background(real *elements,int xspan, int yspan 
245 
,int r,int g,int b,int maxrate,real threshold /* usually 0.5*/); 
246 
/* This is used to vary a constant color to fluxuate congruent to our hologram. */ 
247 

248 

249 

250 

251 
int holo_output_vary_grey_background(real *elements,int xspan, int yspan); 
252 
/* This makes a normalized grey scale image that can be used to apply the hologram at any one of 256 different levels 
253 
This is good for doing the duality calculations  so that the dots are not longer random, but help make up a hologram */ 
254 

255 

256 

257 
real apply_point_sources(point_source_array *psa,real spot,point3d n,int attenuation); /* the magic code! */ 
258 

259 
int holo_sample(); 
260 

261 

262 

263 

264 
void set_max_nyquest_point(point_source *p,real factor,real xdpi,real ydpi); 
265 
/* sets the calculated distance that would be the farthest to go in pixels from the center point. 
266 
This is useful to stop the aliasing of frequencies, and also 
267 
as an added bonus, allows us to eliminate points from the list if they are not in the current range that we 
268 
are computing for 
269 
*/ 
270 

271 

272 
point_source point_source_init_xyz_amp_lamda_phase_atten_nyquest 
273 
(real x, real y, real z, real amp, real lamda, real phase, real atten,real factor,real xdpi,real ydpi); 
274 

275 

276 

277 

278 

279 

280 

281 

282 

283 
void apply_point_sources_complex(point_source_array *psa,real spot,real spoti,point3d n,int attenuation,real *pe); 
284 

285 

286 

287 

288 

289 

290 

291 

292 

293 

294 

295 

296 

297 

298 

299 

300 

301 

302 

303 

304 

305 
int compute_grey_from_files(int file_count,char *file_names[],real *grays,int offset,int span,int gmin,int gmax,real min,real max); 
306 
/* reading double files where they are double precision real/imiginary  figure out the grey scale ranges */ 
307 

308 

309 
void find_min_max_from_files(int file_count,char *file_names[],int offset,int span,real *pmin, real *pmax) ; 
310 
