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

# User Rev Content
1 greg 2.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