# minorlogic

Member

177

150 Neutral

• Rank
Member
1. ## Points matching ?

SIFT Scale Invariant Feature Transform
2. ## quaternion interpolation and velocity

If you using LERP then maximal Error can be some 4.5eg, in case whrn interpolation does full 180 deg arc. In real life you probably use interpolation with maximum 90 deg arc. And in this case the maximum Error (relative to SLERP) IS 0.5 degrees !!! So for example sceletal animation , have no reason to use SLERP. And another one point with LERP. You can do sceletal animation without trigonometry and sqrt. Just LERP quaternions -> you will have unnormalized quaternion. Than convert this unnormalized quaternion with : /** set the rotation to matrix */ inline void to_matrix( matrix33& m )const { float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; float s = 2.0f/norm(); // 4 mul 3 add 1 div x2 = x * s; y2 = y * s; z2 = z * s; xx = x * x2; xy = x * y2; xz = x * z2; yy = y * y2; yz = y * z2; zz = z * z2; wx = w * x2; wy = w * y2; wz = w * z2; m.m[0][0] = 1.0f - (yy + zz); m.m[1][0] = xy - wz; m.m[2][0] = xz + wy; m.m[0][1] = xy + wz; m.m[1][1] = 1.0f - (xx + zz); m.m[2][1] = yz - wx; m.m[0][2] = xz - wy; m.m[1][2] = yz + wx; m.m[2][2] = 1.0f - (xx + yy); } full quaternion code can be found: http://www.gamedev.ru/articles/graph/20040603.zip
3. ## Quaternion - Axis/Angle

[code=cpp] /** create a unit quaternion rotating by axis angle representation */ inline void unit_from_axis_angle(const vector3& axis, const float& angle){ vector3 v(axis); v.norm(); float half_angle = angle*0.5f; float sin_a = (float)sin(half_angle); set(v.x*sin_a, v.y*sin_a, v.z*sin_a, (float)cos(half_angle)); }; //----------------------------------- /** convert a quaternion to axis angle representation, preserve the axis direction and angle from -PI to +PI */ inline void to_axis_angle(vector3& axis, float& angle)const { float vl = (float)sqrt( x*x + y*y + z*z ); if( vl > TINY ) { float ivl = 1.0f/vl; axis.set( x*ivl, y*ivl, z*ivl ); if( w < 0 ) angle = 2.0f*(float)atan2(-vl, -w); //-PI,0 else angle = 2.0f*(float)atan2( vl, w); //0,PI }else{ axis = vector3(0,0,0); angle = 0; } };
4. ## Look-at quaternion

http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/index.htm http://www.euclideanspace.com/maths/algebra/vectors/lookat/index.htm
5. ## Rotating without angles

It is easy ! :) Use "Parallel Transport Frame " with quaternions. 1. Get quaternion that rotate from previous direction vector to current direction vector ( Shortest Arc code ) 2. Multiply Previous Orientation ( in quaternion) by "Shortest Arc" quaternion. 3. You have the current orientation in result quaternion ! Rotation Arc - takes only 1 sqrt. void Step(){ quaternion q; q.shortest_arc( prev_direction, dirtection ); orientation = q*orientation; } here yuo can find the source code of quaternion class http://www.gamedev.ru/articles/graph/20040603.zip
6. ## Scaled Quaternion Combinations

And you don't have to normalize quaternion if only thing you want to get is a rotation matrix from one.
7. ## faster way to get angle between 2 (3D) vectors?

Just use atan2(length(cross product), dot product )
8. ## Renormalization without square root, and without division.(using only + , - , * )

An other one method. 1. Find the Greatest quaternion component . 2. Divide quat by this component. (length will lay close to 1) 3. Use Newton method for normalize more.
9. ## Rotation matrix ortho-normalization

Hi Dmytry. quat 2 matrix formula -> is derived from Quaternion properties. we just use nonunit quat to derive it. matrix 2 qut is good known too, but produce nonunit quat and it is VERY efficient, such one i did not see anywhere.
10. ## Rotation matrix ortho-normalization

Just a note. In algorithm that i posted before, not used SQRT routine. When you do cross and normalization , you use SQRT or invSQRT.
11. ## Rotation matrix ortho-normalization

/** create a nonunit quaternion from rotation matrix martix must contain only rotation (not scale or shear) the result quaternion length is numerical stable */ inline void from_matrix( const matrix33& mtx ) { typedef float mtx_elm[3][3]; const mtx_elm& m = mtx.m; float tr = m[0][0] + m[1][1] + m[2][2]; // trace of martix if (tr > 0.0f){ // if trace positive than "w" is biggest component set( m[1][2] - m[2][1], m[2][0] - m[0][2], m[0][1] - m[1][0], tr + 1.0f ); }else // Some of vector components is bigger if( (m[0][0] > m[1][1] ) && ( m[0][0] > m[2][2]) ) { set( 1.0f + m[0][0] - m[1][1] - m[2][2], m[1][0] + m[0][1], m[2][0] + m[0][2], m[1][2] - m[2][1] ); }else if ( m[1][1] > m[2][2] ){ set( m[1][0] + m[0][1], 1.0f + m[1][1] - m[0][0] - m[2][2], m[2][1] + m[1][2], m[2][0] - m[0][2] ); }else{ set( m[2][0] + m[0][2], m[2][1] + m[1][2], 1.0f + m[2][2] - m[0][0] - m[1][1], m[0][1] - m[1][0] ); } } /** set the rotation to matrix */ inline void to_matrix( matrix33& m )const { float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; float s = 2.0f/norm(); // 4 mul 3 add 1 div x2 = x * s; y2 = y * s; z2 = z * s; xx = x * x2; xy = x * y2; xz = x * z2; yy = y * y2; yz = y * z2; zz = z * z2; wx = w * x2; wy = w * y2; wz = w * z2; m.m[0][0] = 1.0f - (yy + zz); m.m[1][0] = xy - wz; m.m[2][0] = xz + wy; m.m[0][1] = xy + wz; m.m[1][1] = 1.0f - (xx + zz); m.m[2][1] = yz - wx; m.m[0][2] = xz - wy; m.m[1][2] = yz + wx; m.m[2][2] = 1.0f - (xx + yy); } http://www.gamedev.ru/articles/graph/20040603.zip
12. ## Wavelet Transform + Images

It is solved problem Take a look at "ENBLEND" or search the "multiresolution image spline"