View Javadoc

1   package org.lcsim.geometry.util;
2   
3   import org.apache.commons.math3.geometry.euclidean.threed.Rotation;
4   import org.apache.commons.math3.geometry.euclidean.threed.RotationOrder;
5   import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
6   import org.lcsim.detector.RotationGeant;
7   
8   import hep.physics.vec.BasicHep3Vector;
9   import hep.physics.vec.Hep3Vector;
10  import hep.physics.vec.VecOp;
11  
12  public class TransformationUtils {
13  
14      /**
15       * Extract the Cardan angles that describe a passive XYZ order rotation taking two unit vectors into two new ones. 
16       * @param u - input unit vector
17       * @param v - input unit vector
18       * @param u_prime - result of rotation applied to @param u
19       * @param v_prime - result of rotation applied to @param v
20       * @return
21       */
22      public static Hep3Vector getCardanAngles(Hep3Vector u, Hep3Vector v, Hep3Vector u_prime, Hep3Vector v_prime) {
23      	int debug = 0;
24      	if (debug>0) System.out.printf("getEulerAngles: u %s v%s -> %s %s\n",u.toString(),v.toString(),u_prime.toString(),v_prime.toString());
25      	// Convert to correct API
26      	Vector3D u_3D = new Vector3D(u.v());
27      	Vector3D v_3D = new Vector3D(v.v());
28      	Vector3D u_prime_3D = new Vector3D(u_prime.v());
29      	Vector3D v_prime_3D = new Vector3D(v_prime.v());
30      	
31      	//Create the rotation
32      	// Note that the constructor used here creates the rotation using active transformations
33      	Rotation rot = new Rotation(u_3D,v_3D,u_prime_3D,v_prime_3D);
34      	
35      	// Get the Cardan angles of the rotation
36      	double res[] = rot.getAngles(RotationOrder.ZYX);
37  
38          // Since the rotation was created based on active transformations convert to passive right here. 
39          // This conversion is simply to reverse the order of rotations.
40      	Hep3Vector euler = new BasicHep3Vector(res[2],res[1],res[0]);
41      			
42      	if(debug>0) {
43      		System.out.println("Input: u " + u_3D.toString() + " v " + v_3D.toString() + " u' " + u_prime_3D.toString() + " v' " + v_prime_3D.toString());
44      		System.out.println("rot matrix:");
45      		TransformationUtils.printMatrix(rot.getMatrix());    	
46      		System.out.println("Resulting XYZ angles " + euler.toString());
47      	}
48      	
49      	if(debug>1) {
50      		System.out.println("------- TESTING ");
51      		
52      		Rotation r123 = new Rotation(RotationOrder.XYZ, res[0], res[1], res[2]);
53      		
54      		
55      		Vector3D x_3D = new Vector3D(1,0,0);
56      		Vector3D y_3D = new Vector3D(0,1,0);
57      		Vector3D z_3D = new Vector3D(0,0,1);
58      
59      		
60      		Rotation r1 = new Rotation(x_3D,res[0]);
61      		Vector3D x_3D_p = r1.applyTo(x_3D);
62      		Rotation r3 = new Rotation(z_3D,res[2]);
63      		Rotation r13 = r3.applyTo(r1);
64      		Vector3D x_3D_pp = r13.applyTo(x_3D);
65      		Vector3D y_3D_pp = r13.applyTo(y_3D);
66      		Vector3D y_3D_pp_2 = r123.applyTo(y_3D);
67      		System.out.println("x_3D (" + x_3D.getX() + "," + x_3D.getY() + "," + x_3D.getZ());
68      		System.out.println("y_3D (" + y_3D.getX() + "," + y_3D.getY() + "," + y_3D.getZ());
69      		System.out.println("z_3D (" + z_3D.getX() + "," + z_3D.getY() + "," + z_3D.getZ());
70      		System.out.println("r1 " + r1.toString());
71      		TransformationUtils.printMatrix(r1.getMatrix());
72      		System.out.println("x_3D_p (" + x_3D_p.getX() + "," + x_3D_p.getY() + "," + x_3D_p.getZ());
73      		System.out.println("r3 " + r3.toString());
74      		TransformationUtils.printMatrix(r3.getMatrix());
75      		System.out.println("r13 " + r13.toString());
76      		TransformationUtils.printMatrix(r13.getMatrix());
77      		System.out.println("x_3D_pp (" + x_3D_pp.getX() + "," + x_3D_pp.getY() + "," + x_3D_pp.getZ());
78      		System.out.println("y_3D_pp (" + y_3D_pp.getX() + "," + y_3D_pp.getY() + "," + y_3D_pp.getZ());
79      		System.out.println("r123 " + r123.toString());
80      		TransformationUtils.printMatrix(r123.getMatrix());
81      		System.out.println("y_3D_pp_2 (" + y_3D_pp_2.getX() + "," + y_3D_pp_2.getY() + "," + y_3D_pp_2.getZ());
82      		System.out.println("------- ");
83      	}
84      	return euler;
85      }
86      
87      public static boolean areVectorsEqual(Hep3Vector a, Hep3Vector b, double thresh) {
88          return VecOp.cross(a, b).magnitude() > thresh ? false : true;  
89      }
90      
91      /**
92       * Extract the Cardan angles that describe a passive XYZ order rotation taking a set of three unit vectors into three new one. 
93       * @param u - input unit vector
94       * @param v - input unit vector
95       * @param w - input unit vector
96       * @param u_prime - result of rotation applied to @param u
97       * @param v_prime - result of rotation applied to @param v
98       * @param w_prime - result of rotation applied to @param w
99       * @return
100      */
101     public static Hep3Vector getCardanAngles(Hep3Vector u, Hep3Vector v, Hep3Vector w, 
102                                             Hep3Vector u_prime, Hep3Vector v_prime, Hep3Vector w_prime) {
103 
104         Hep3Vector a1 = getCardanAngles(u, v, u_prime, v_prime);
105         Hep3Vector a2 = getCardanAngles(u, w, u_prime, w_prime);
106         Hep3Vector a3 = getCardanAngles(v, w, v_prime, w_prime);
107         if( !areVectorsEqual(a1, a2, 0.00001) || !areVectorsEqual(a1, a3, 0.00001) || !areVectorsEqual(a2, a3, 0.00001)) {
108             System.out.printf("u: %s -> %s \n", u.toString(), u_prime.toString());
109             System.out.printf("v: %s -> %s \n", v.toString(), v_prime.toString());
110             System.out.printf("w: %s -> %s \n", w.toString(), w_prime.toString());
111             System.out.printf("a1: %s \n", a1.toString());
112             System.out.printf("a2: %s \n", a1.toString());
113             System.out.printf("a3: %s \n", a1.toString());
114             System.out.printf("a1 a2: %f \n", Math.abs(VecOp.dot(a1, a2)-1));
115             System.out.printf("a1 a3: %f \n", Math.abs(VecOp.dot(a1, a3)-1));
116             System.out.printf("a2 a3: %f \n", Math.abs(VecOp.dot(a2, a3)-1));
117             
118             throw new RuntimeException("Cardan angles extracted for transformation depend on input unit vectors:");
119         }
120         return a1;
121     }
122     
123 
124     /**
125      * Print matrix to stdout.
126      * @param mat
127      */
128     public static void printMatrix(double [][] mat) {
129     	for(int r=0;r<3;++r) {
130     		String row = "";
131     		for(int c=0;c<3;++c) {
132     			row += String.format(" %f",mat[r][c]);
133     		}
134     		System.out.println(row);
135     	}
136     }
137 
138    
139 
140    
141     /**
142      * Find the displacement of a point when rotating around an arbitrary position.
143      * @param originOfRotation
144      * @param point to rotate
145      * @param rotationAngles - Cardan angles describing a passive XYZ order rotation 
146      * @return point after rotation
147      */
148     public static Hep3Vector getRotationDisplacement(Hep3Vector originOfRotation,
149     		Hep3Vector point, Hep3Vector rotationAngles) {
150         boolean _debug = false;
151 
152         // Find the vector from the center of rotation to the point
153     	Hep3Vector s = VecOp.sub(point, originOfRotation );
154     	// Build a rotataion object
155     	RotationGeant r = new RotationGeant(rotationAngles.x(), rotationAngles.y(), rotationAngles.z());
156     	// Apply the rotation to the vector
157     	Hep3Vector s_prime = r.rotated(s);
158     	// Find the displaced point
159     	Hep3Vector point_rot = VecOp.add(originOfRotation, s_prime );
160     	
161     	if(_debug) {
162     		System.out.println("--- getRotationDisplacement---");
163     		System.out.println(String.format("point: %s", point.toString()));
164     		System.out.println(String.format("origin_of_rotation: %s", originOfRotation.toString()));
165     		System.out.println(String.format("s:\n%s", s.toString()));
166     		System.out.println(String.format("r:\n%s", r.toString()));
167     		System.out.println(String.format("s_prime:\n%s", s_prime.toString()));
168     		System.out.println(String.format("point_rot:\n%s", point_rot.toString()));
169     		System.out.println("--- getRotationDisplacement END---");
170     	}
171     	
172     	return point_rot;
173     }
174 
175 
176     
177     
178 }