Commit c685653db5f9456aa040e1583989c6ceb2858fc6

Authored by David Mayerich
1 parent 8718a1a0

fixed a bug in the quaternion class that caused an ambiguity for rotation angles…

… greater than 90-degrees
stim/image/image.h
@@ -248,7 +248,7 @@ public: @@ -248,7 +248,7 @@ public:
248 outfile.close(); 248 outfile.close();
249 } 249 }
250 250
251 - cimg_library::CImg<T> cimg(R[1], R[2], 1, R[0]); 251 + cimg_library::CImg<T> cimg((unsigned int)R[1], (unsigned int)R[2], 1, (unsigned int)R[0]);
252 get_noninterleaved(cimg.data()); 252 get_noninterleaved(cimg.data());
253 cimg.save(filename.c_str()); 253 cimg.save(filename.c_str());
254 } 254 }
stim/math/quaternion.h
@@ -24,6 +24,11 @@ public: @@ -24,6 +24,11 @@ public:
24 z=z/length; 24 z=z/length;
25 } 25 }
26 26
  27 + //calculate the quaternion length (norm)
  28 + CUDA_CALLABLE T norm() {
  29 + return sqrt(w*w + x * x + y * y + z * z);
  30 + }
  31 +
27 CUDA_CALLABLE void CreateRotation(T theta, T ux, T uy, T uz){ 32 CUDA_CALLABLE void CreateRotation(T theta, T ux, T uy, T uz){
28 33
29 vec3<T> u(ux, uy, uz); 34 vec3<T> u(ux, uy, uz);
@@ -46,10 +51,12 @@ public: @@ -46,10 +51,12 @@ public:
46 from = from.norm(); 51 from = from.norm();
47 to = to.norm(); 52 to = to.norm();
48 vec3<T> r = from.cross(to); //compute the rotation vector 53 vec3<T> r = from.cross(to); //compute the rotation vector
49 - T l = r.len();  
50 - if (l > 1) l = 1; //we have seen degenerate cases where |r| > 1 (probably due to loss of precision in the cross product)  
51 - T theta = asin(l); //compute the angle of the rotation about r 54 + //T l = r.len();
  55 + //if (l > 1) l = 1; //we have seen degenerate cases where |r| > 1 (probably due to loss of precision in the cross product)
  56 + //T theta = asin(l); //compute the angle of the rotation about r
52 //deal with a zero vector (both k and kn point in the same direction) 57 //deal with a zero vector (both k and kn point in the same direction)
  58 + T cos_theta = from.dot(to); //calculate the cosine between the two vectors
  59 + T theta = acos(cos_theta); //calculate the angle between the two vectors
53 if(theta == (T)0){ 60 if(theta == (T)0){
54 return; 61 return;
55 } 62 }
@@ -117,12 +124,34 @@ public: @@ -117,12 +124,34 @@ public:
117 } 124 }
118 125
119 CUDA_CALLABLE matrix_sq<T, 4> toMatrix4(){ 126 CUDA_CALLABLE matrix_sq<T, 4> toMatrix4(){
120 -  
121 - matrix_sq<T, 4> result;  
122 - T wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; 127 + matrix_sq<T, 4> R;
  128 + T s, wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
  129 + s = sqrt(norm());
  130 + xx = x * x; xy = x * y; xz = x * z;
  131 + yy = y * y; yz = y * z;
  132 + zz = z * z;
  133 + wx = w * x; wy = w * y; wz = w * z;
  134 +
  135 + R(0, 0) = 1 - 2 * s * (yy + zz);
  136 + R(0, 1) = 2 * s * (xy - wz);
  137 + R(0, 2) = 2 * s * (xz + wy);
  138 + R(1, 0) = 2 * s * (xy + wz);
  139 + R(1, 1) = 1 - 2 * s * (xx + zz);
  140 + R(1, 2) = 2 * s * (yz - wx);
  141 + R(2, 0) = 2 * s * (xz - wy);
  142 + R(2, 1) = 2 * s * (yz + wx);
  143 + R(2, 2) = 1 - 2 * s * (xx + yy);
  144 +
  145 + R(0, 3) = 0;
  146 + R(1, 3) = 0;
  147 + R(2, 3) = 0;
  148 + R(3, 0) = 0;
  149 + R(3, 1) = 0;
  150 + R(3, 2) = 0;
  151 + R(3, 3) = 1;
123 152
124 // calculate coefficients 153 // calculate coefficients
125 - x2 = x + x; y2 = y + y; 154 + /*x2 = x + x; y2 = y + y;
126 z2 = z + z; 155 z2 = z + z;
127 xx = x * x2; xy = x * y2; xz = x * z2; 156 xx = x * x2; xy = x * y2; xz = x * z2;
128 yy = y * y2; yz = y * z2; zz = z * z2; 157 yy = y * y2; yz = y * z2; zz = z * z2;
@@ -143,9 +172,9 @@ public: @@ -143,9 +172,9 @@ public:
143 172
144 result(2, 2) = 1 - (xx + yy); 173 result(2, 2) = 1 - (xx + yy);
145 174
146 - result(3, 3) = 1; 175 + result(3, 3) = 1;*/
147 176
148 - return result; 177 + return R;
149 } 178 }
150 179
151 180
@@ -157,6 +186,20 @@ public: @@ -157,6 +186,20 @@ public:
157 w=c; x=i; y=j; z=k; 186 w=c; x=i; y=j; z=k;
158 } 187 }
159 188
  189 + // create a pure quaternion from a vector
  190 + CUDA_CALLABLE quaternion(vec3<T> v){
  191 + w = 0; x = v[0]; y = v[1]; z = v[2];
  192 + }
  193 +
  194 + CUDA_CALLABLE quaternion<T> conj(){
  195 + quaternion<T> c;
  196 + c.w = w;
  197 + c.x = -x;
  198 + c.y = -y;
  199 + c.z = -z;
  200 + return c;
  201 + }
  202 +
160 }; 203 };
161 204
162 } //end rts namespace 205 } //end rts namespace
stim/ui/progressbar.h
@@ -7,7 +7,6 @@ @@ -7,7 +7,6 @@
7 using namespace std; 7 using namespace std;
8 8
9 void stimPrintTime(unsigned long long s) { 9 void stimPrintTime(unsigned long long s) {
10 - char buffer[26];  
11 std::cout << std::fixed << std::showpoint << std::setprecision(1); 10 std::cout << std::fixed << std::showpoint << std::setprecision(1);
12 if (s >= 60) { //if there are more than 60 seconds 11 if (s >= 60) { //if there are more than 60 seconds
13 unsigned long long m = s / 60; //get the number of minutes 12 unsigned long long m = s / 60; //get the number of minutes
@@ -49,12 +48,12 @@ static void rtsProgressBar(unsigned int percent, double elapsed_s = 0) @@ -49,12 +48,12 @@ static void rtsProgressBar(unsigned int percent, double elapsed_s = 0)
49 cout << "\r"; // carriage return back to beginning of line 48 cout << "\r"; // carriage return back to beginning of line
50 cout << bar.str() << " " << slash[x] << " " << percent << " %"; // print the bars and percentage 49 cout << bar.str() << " " << slash[x] << " " << percent << " %"; // print the bars and percentage
51 if (elapsed_s > 0) { 50 if (elapsed_s > 0) {
52 - stimPrintTime(elapsed_s); 51 + stimPrintTime((unsigned long long)elapsed_s);
53 if (percent > 0) { 52 if (percent > 0) {
54 std::cout << " / "; 53 std::cout << " / ";
55 double s_per_percent = elapsed_s / percent; 54 double s_per_percent = elapsed_s / percent;
56 double total = s_per_percent * 100; 55 double total = s_per_percent * 100;
57 - stimPrintTime(total); 56 + stimPrintTime((unsigned long long)total);
58 } 57 }
59 } 58 }
60 cout.flush(); 59 cout.flush();