ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/g3sphere.c
Revision: 2.1
Committed: Wed Aug 12 23:07:59 2015 UTC (8 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Added Jan Wienold's evalglare to distribution

File Contents

# Content
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 #include "g3sphere.h"
6
7 static g3Float get_equator_rad(g3Vec cc,int c1,int c2)
8 {
9 g3Float res;
10
11 if (gb_epseq(cc[c2],0.0)) {
12 if (gb_epseq(cc[c1],0.0)) {
13 res = 0;
14 } else {
15 res = (cc[c1] > 0.0) ? M_PI/2.0 : -M_PI/2.0;
16 }
17 } else {
18 res = (cc[c2] < 0.0) ? M_PI - fabs(atan(cc[c1]/cc[c2])) :
19 fabs(atan(cc[c1]/cc[c2]));
20 if (cc[c1] < 0.0)
21 res *= -1.0;
22 }
23 return res;
24 }
25
26
27
28 g3Vec g3s_cctomtr(g3Vec res,g3Vec cc)
29 {
30 int copy = 0;
31 if (res == cc) {
32 res = g3v_create();
33 copy = 1;
34 }
35 res[G3S_RAD] = g3v_length(cc);
36 res[G3S_MY] = res[G3S_RAD]*get_equator_rad(cc,1,0);
37 if (cc[2] >= res[G3S_RAD])
38 res[G3S_MZ] = atanh((1.0 - GB_EPSILON)/res[G3S_RAD]);
39 else
40 res[G3S_MZ] = res[G3S_RAD]*atanh(cc[2]/res[G3S_RAD]);
41 if (copy) {
42 g3v_copy(cc,res);
43 g3v_free(res);
44 res = cc;
45 }
46 return res;
47 }
48
49 g3Vec g3s_mtrtocc(g3Vec res,g3Vec mtr)
50 {
51 g3Float r = mtr[G3S_RAD];
52
53 res[0] = r*cos(mtr[G3S_MY]/r)/cosh(mtr[G3S_MZ]/r);
54 res[1] = r*sin(mtr[G3S_MY]/r)/cosh(mtr[G3S_MZ]/r);
55 res[2] = r*tanh(mtr[G3S_MZ]/r);
56 return res;
57 }
58
59 g3Vec g3s_cctotr(g3Vec res,g3Vec cc)
60 {
61 g3Float len;
62 G3S_RESCOPY(res,cc);
63 if (gb_epseq((res[G3S_RAD] = g3v_length(cc)),0)) {
64 fprintf(stderr,"g3s_cctotr: zero vector\n");
65 G3S_RESFREE(res,cc);
66 return NULL;
67 }
68 g3v_copy(res,cc);
69 res[1] = 0;
70 len = g3v_length(res);
71 if (gb_epseq(len,0.0)) {
72 res[G3S_THETA] = M_PI/2.0;
73 res[G3S_PHI] = gb_signum(cc[1])*M_PI/2.0;
74 } else {
75 res[G3S_THETA] = acos(cc[2]/len);
76 res[G3S_PHI] = atan(cc[1]/len);
77 if (cc[0] < 0.0)
78 res[G3S_THETA] *= -1.0;
79 }
80 res[G3S_RAD] = g3v_length(cc);
81 g3s_trwrap(res);
82 G3S_RESFREE(res,cc);
83 return res;
84 }
85
86 g3Vec g3s_trtocc(g3Vec res,g3Vec tr)
87 {
88 g3Vec v;
89 G3S_RESCOPY(res,tr);
90 v = g3v_create();
91 g3v_set(v,0,-1,0);
92 g3v_set(res,0,0,1);
93 g3v_rotate(res,res,v,tr[G3S_THETA]);
94 g3v_cross(v,res,v);
95 g3v_rotate(res,res,v,tr[G3S_PHI]);
96 g3v_free(v);
97 g3v_scale(res,res,tr[G3S_RAD]);
98 G3S_RESFREE(res,tr);
99 return res;
100 }
101
102 g3Vec g3s_sphtotr(g3Vec res,g3Vec sph)
103 {
104 g3s_sphtocc(res,sph);
105 return g3s_cctotr(res,res);
106 }
107
108 g3Vec g3s_trtosph(g3Vec res,g3Vec tr)
109 {
110 g3s_trtocc(res,tr);
111 return g3s_cctosph(res,res);
112 }
113
114 g3Vec g3s_sphtocc(g3Vec res,g3Vec sph)
115 {
116 g3Float r,s2,t;
117 r = sph[G3S_RAD];
118 s2 = sin(sph[G3S_THETA]);
119 t = sph[G3S_THETA];
120 res[0] = r*cos(sph[G3S_PHI])*s2;
121 res[1] = r*sin(sph[G3S_PHI])*s2;
122 res[2] = r*cos(t);
123 return res;
124 }
125
126 g3Vec g3s_cctosph(g3Vec res,g3Vec cc)
127 {
128 int copy = 0;
129 if (res == cc) {
130 res = g3v_create();
131 copy = 1;
132 }
133 res[G3S_RAD] = g3v_length(cc);
134 res[G3S_THETA] = acos(cc[2]/res[G3S_RAD]);
135 res[G3S_PHI] = get_equator_rad(cc,1,0);
136 if (copy) {
137 g3v_copy(cc,res);
138 g3v_free(res);
139 res = cc;
140 }
141 return res;
142 }
143
144 g3Vec g3s_sphwrap(g3Vec sph)
145 {
146 sph[G3S_THETA] = fmod((fmod(sph[G3S_THETA],2.0*M_PI) + 2.0*M_PI),2.0*M_PI);
147 sph[G3S_PHI] = fmod((fmod(sph[G3S_PHI],2.0*M_PI) + 2.0*M_PI),2.0*M_PI);
148 return sph;
149 }
150
151 g3Vec g3s_trwrap(g3Vec tr)
152 {
153 tr[G3S_THETA] = fmod((fmod(tr[G3S_THETA],2.0*M_PI) + 2.0*M_PI),2.0*M_PI);
154 tr[G3S_PHI] += M_PI;
155 tr[G3S_PHI] = fmod((fmod(tr[G3S_PHI],2.0*M_PI) + 2.0*M_PI),2.0*M_PI);
156 tr[G3S_PHI] -= M_PI;
157 return tr;
158 }
159
160 g3Float g3s_dist(const g3Vec cc1,const g3Vec cc2)
161 {
162 return acos(g3v_dot(cc1,cc2));
163 }
164
165 g3Float g3s_dist_norm(const g3Vec cc1,const g3Vec cc2)
166 {
167 return acos(g3v_dot(g3v_normalize(cc1),g3v_normalize(cc2)));
168 }
169
170
171
172
173 #ifdef G3SPHERE_TEST
174
175 int main(int argc,char** argv)
176 {
177 g3Vec a,b,e,z,ang;
178 int i;
179 g3Float vo,v,vr;
180
181 if (argc < 4) {
182 fprintf(stderr,"usage: %s <s | e> <x1> <y1> <z1>\n",argv[0]);
183 return EXIT_FAILURE;
184 }
185
186 a = g3v_create();
187 e = g3v_create();
188 if (!strcmp(argv[1],"s")) {
189 g3v_set(a,1.0,DEG2RAD(atof(argv[2])),DEG2RAD(atof(argv[3])));
190 g3v_print(g3s_sphtocc(a,a),stdout);;
191 //g3s_trtosph(a,a);
192 //g3v_print(a,stdout);
193 //printf("%f %f",RAD2DEG(a[1]),RAD2DEG(a[2]));
194 printf("\n");
195 } else {
196 g3v_set(a,atof(argv[2]),atof(argv[3]),atof(argv[4]));
197 g3s_cctosph(a,a);
198 printf("%f %f",RAD2DEG(a[1]),RAD2DEG(a[2]));
199 printf("\n");
200 }
201 exit(1);
202 for(i=0;i<10000;i++) {
203 a[0] = 1.0;
204 a[1] = M_PI/2.0*rand()/RAND_MAX;
205 a[2] = 2.0*M_PI*rand()/RAND_MAX;
206 g3s_sphtocc(a,a);
207 g3s_cctotr(e,a);
208 g3s_trtocc(e,e);
209 if (!g3v_epseq(e,a)) {
210 fprintf(stderr,"aaaa \n");
211 g3v_print(a,stderr);
212 g3v_print(e,stderr);
213 }
214 }
215 fprintf(stderr,"ok\n");
216 exit(1);
217 g3v_set(a,atof(argv[1]),DEG2RAD(atof(argv[2])),DEG2RAD(atof(argv[3])));
218 b = g3v_create();
219 z = g3v_create();
220 ang = g3v_create();
221 g3v_set(z,0,0,1);
222 g3v_normalize(a);
223 for(i=0;i<5000;i++) {
224 b[0] = 1.0;
225 b[1] = M_PI/2.0*rand()/RAND_MAX;
226 b[2] = 2.0*M_PI*rand()/RAND_MAX;
227 g3v_copy(ang,b);
228 g3s_sphtocc(b,b);
229 v = g3s_dist(a,b);
230 if (!gb_epseq(sqrt(2.0 - 2.0*cos(v)),g3v_length(g3v_sub(ang,b,a))))
231 fprintf(stderr,"oops %f %f\n",sqrt(2.0 - 2.0*cos(v)),g3v_length(g3v_sub(ang,b,a)));
232 vo = (v > 0.2) ? 0.1 : (0.4 - v);
233 vr = sqrt(2.0 - 2.0*cos(0.2));
234 if (fabs(a[0] - b[0]) > vr || fabs(a[1] - b[1]) > vr || fabs(a[2] - b[2]) > vr) {
235 vo -= 0.1;
236 if (v < 0.2) {
237 vo = 3;
238 fprintf(stderr,"autsch %f %f\n",v,vr);
239 }
240 }
241 g3s_cctosph(b,b);
242 printf("%f %f %f\n",b[G3S_THETA],b[G3S_PHI],vo);
243 }
244 //printf("%f\n",g3s_dist_norm(a,b));
245 //g3v_print(g3s_cctomtr(b,a),stdout);
246 //g3v_print(g3s_cctosph(b,a),stdout);
247 //printf("\n");
248 return EXIT_SUCCESS;
249 }
250
251 #endif