1 package org.lcsim.spacegeom;
2 import static java.lang.Math.cos;
3 import static java.lang.Math.sin;
4 import static java.lang.Math.sqrt;
5 import static java.lang.Math.abs;
6 import static org.lcsim.spacegeom.Representation.Cartesian;
7 import hep.physics.vec.Hep3Vector;
8
9 import java.io.Serializable;
10 import static java.lang.Math.acos;
11 import static java.lang.Math.sqrt;
12
13
14
15
16
17
18
19
20
21
22
23 public class SpacePoint implements Serializable, Cloneable, Hep3Vector
24 {
25 Representation _representation;
26 double _x;
27 double _y;
28 double _z;
29 double _xy;
30 double _xyz;
31 double _phi;
32 double _theta;
33
34 public double[] v()
35 {
36 switch(_representation)
37 {
38 case Cartesian: return new double[] {_x, _y, _z};
39 case Spherical: return new double[] {_xyz, _phi, _theta};
40 case Cylindrical: return new double[] {_xy, _phi, _z};
41 default: return new double[3];
42 }
43 }
44
45 private void cartesianToCylindricalR()
46 {
47 _xy = Math.sqrt(_x*_x+_y*_y);
48 }
49
50 private void cartesianToPhi()
51 {
52 _phi = Math.atan2(_y,_x);
53 }
54
55 private void cartesianToTheta()
56 {
57 if (Double.isNaN(_xy))
58 cartesianToCylindricalR();
59 _theta = Math.atan2(_xy,_z);
60 }
61
62 public double magnitude()
63 {
64 return _xyz;
65 }
66
67 public double magnitudeSquared()
68 {
69 return _xyz*_xyz;
70 }
71
72
73
74
75
76
77 public SpacePoint()
78 {
79 _representation = Cartesian;
80 _x = _y = _z = 0.0;
81 _xy = _xyz = 0.0;
82 _phi = _theta = 0.0;
83 }
84
85
86
87
88
89
90 public SpacePoint( SpacePoint spt )
91 {
92 _representation = spt._representation;
93 _x = spt.x();
94 _y = spt.y();
95 _z = spt.z();
96 _xy = spt.rxy();
97 _xyz = spt.rxyz();
98 _phi = spt.phi();
99 _theta = spt.theta();
100 }
101
102 public SpacePoint(Hep3Vector vec)
103 {
104 _representation = Cartesian;
105 _x = vec.x();
106 _y = vec.y();
107 _z = vec.z();
108 _xyz = sqrt(_x*_x + _y*_y + _z*_z);
109 _xy = _phi = _theta = Double.NaN;
110 }
111
112 private void cylindricalToCartesianX()
113 {
114 _x = _xy*cos(_phi);
115 }
116
117 private void sphericalToCartesianX()
118 {
119 _x = _xyz*cos(_phi)*sin(_theta);
120 }
121
122 private void sphericalToCartesianY()
123 {
124 _y = _xyz*sin(_phi)*sin(_theta);
125 }
126
127 private void sphericalToCartesianZ()
128 {
129 _z = _xyz*cos(_theta);
130 }
131
132
133
134
135
136 public double x()
137 {
138 if (Double.isNaN(_x))
139 switch(_representation)
140 {
141 case Spherical: sphericalToCartesianX(); break;
142 case Cylindrical: cylindricalToCartesianX(); break;
143 }
144 return _x;
145 }
146
147
148 private void cylindricalToCartesianY()
149 {
150 _y = _xy*sin(_phi);
151 }
152
153
154
155
156
157
158 public double y()
159 {
160 if (Double.isNaN(_y))
161 switch(_representation)
162 {
163 case Spherical: sphericalToCartesianY(); break;
164 case Cylindrical: cylindricalToCartesianY(); break;
165 }
166 return _y;
167 }
168
169
170
171
172
173
174 public double z()
175 {
176 if (Double.isNaN(_z))
177 sphericalToCartesianZ();
178 return _z;
179 }
180
181 private void sphericalToCylindricalR()
182 {
183 _xy = _xyz*Math.sin(_theta);
184 }
185
186
187
188
189
190 public double rxy()
191 {
192 if (Double.isNaN(_xy))
193 switch(_representation)
194 {
195 case Spherical: sphericalToCylindricalR(); break;
196 case Cartesian: cartesianToCylindricalR(); break;
197 }
198 return _xy;
199 }
200
201
202
203
204
205 public double phi()
206 {
207 if (Double.isNaN(_phi))
208 cartesianToPhi();
209 return _phi;
210 }
211
212
213
214
215
216 public double rxyz()
217 {
218 return _xyz;
219 }
220
221
222
223
224
225 public double theta()
226 {
227 if (Double.isNaN(_theta))
228 switch(_representation)
229 {
230 case Cartesian: cartesianToTheta(); break;
231 case Cylindrical: cylindricalToTheta(); break;
232 }
233 return _theta;
234 }
235
236 private void cylindricalToTheta()
237 {
238 _theta = Math.atan2(_xy,_z);
239 }
240
241
242
243
244
245 public double cosPhi()
246 {
247 if ( !Double.isNaN(_x) && !Double.isNaN(_xy) && _xy != 0. )
248 return _x/_xy;
249 if (Double.isNaN(_phi))
250 cartesianToPhi();
251 return cos(_phi);
252 }
253
254
255
256
257
258 public double sinPhi()
259 {
260 if (!Double.isNaN(_y) && !Double.isNaN(_xy) && _xy != 0. )
261 return _y/_xy;
262 if (Double.isNaN(_phi))
263 cartesianToPhi();
264 return sin(_phi);
265 }
266
267
268
269
270
271 public double sinTheta()
272 {
273 if ( !Double.isNaN(_xy) && _xyz != 0. )
274 return _xy/_xyz;
275 if (Double.isNaN(_theta))
276 switch(_representation)
277 {
278 case Cartesian: cartesianToTheta(); break;
279 case Cylindrical: cylindricalToTheta(); break;
280 }
281 return sin(_theta);
282 }
283
284
285
286
287
288 public double cosTheta()
289 {
290 if ( !Double.isNaN(_z) && _xyz != 0. )
291 return _z/_xyz;
292 if (Double.isNaN(_theta))
293 switch(_representation)
294 {
295 case Cartesian: cartesianToTheta(); break;
296 case Cylindrical: cylindricalToTheta(); break;
297 }
298 return cos(_theta);
299 }
300
301
302
303
304
305
306 public String toString()
307 {
308 return _representation + " SpacePoint: " + "\n" +
309 " x: " + x() + "\n" +
310 " y: " + y() + "\n" +
311 " z: " + z() + "\n" +
312 " rxy: " + rxy() + "\n" +
313 " rxyz: " + rxyz() + "\n" +
314 " phi: " + phi() + "\n" +
315 "theta: " + theta() + "\n" ;
316 }
317
318
319
320
321
322
323
324
325
326 public boolean equals(SpacePoint spt, double precision)
327 {
328 return ( abs(x() - spt.x()) < precision ) &&
329 ( abs(y() - spt.y()) < precision ) &&
330 ( abs(z() - spt.z()) < precision );
331 }
332
333
334
335
336
337
338
339
340 public boolean equals(Hep3Vector spt, double precision)
341 {
342 return ( abs(x() - spt.x()) < precision ) &&
343 ( abs(y() - spt.y()) < precision ) &&
344 ( abs(z() - spt.z()) < precision );
345 }
346
347
348
349
350
351
352 public boolean equals(SpacePoint x) {
353 return equals(x, 1e-10);
354 }
355
356
357
358
359
360
361
362 public boolean notEquals(SpacePoint spt)
363 {
364 return ! (equals(spt));
365 }
366
367
368
369
370
371
372
373 public static double distance(SpacePoint spt1, SpacePoint spt2)
374 {
375 double dx = spt2.x() - spt1.x();
376 double dy = spt2.y() - spt1.y();
377 double dz = spt2.z() - spt1.z();
378 return Math.sqrt( dx*dx + dy*dy + dz*dz );
379 }
380
381
382
383
384
385
386
387 public static double openingAngle(SpacePoint p1, SpacePoint p2)
388 {
389
390
391 double dot = p1.x()*p2.x()+p1.y()*p2.y()+p1.z()*p2.z();
392
393 double d1 = sqrt(p1.x()*p1.x()+p1.y()*p1.y()+p1.z()*p1.z());
394 double d2 = sqrt(p2.x()*p2.x()+p2.y()*p2.y()+p2.z()*p2.z());
395
396 return acos(dot/(d1*d2));
397 }
398
399
400
401
402
403
404 public Object clone()
405 {
406 Object o = null;
407 try
408 {
409 o = super.clone();
410 }
411 catch (CloneNotSupportedException e)
412 {
413 e.printStackTrace();
414 }
415 return o;
416 }
417
418
419
420
421 public double[] getCartesianArray()
422 {
423 return new double[] {_x, _y, _z};
424 }
425
426
427
428
429 public Representation getRepresentation()
430 {
431 return _representation;
432 }
433 }
434