Quaternion2 Quaternion2::DecomposeRotation2(const VectorR3 vB) const { //we need to compute v in A's coordinates VectorR3 vA = this->rotate(vB); vA.Normalize(); double temp = 0; //compute the rotation that aligns the vector v in the two coordinate frames (A and T) VectorR3 rotAxis = vA * vB; rotAxis.Normalize(); double rotAngle = -safeACOS(vA.Dot(vB)); Quaternion2 TqA = getRotationQuaternion2(rotAngle, rotAxis*(-1)); return TqA * (*this); }
// Returns a righthanded orthonormal basis to complement vector u void GetOrtho( const VectorR3& u, VectorR3& v, VectorR3& w) { if ( u.x > 0.5 || u.x<-0.5 || u.y > 0.5 || u.y<-0.5 ) { v.Set ( u.y, -u.x, 0.0 ); } else { v.Set ( 0.0, u.z, -u.y); } v.Normalize(); w = u; w *= v; w.Normalize(); // w.NormalizeFast(); return; }
// Returns a vector v orthonormal to unit vector u void GetOrtho( const VectorR3& u, VectorR3& v ) { if ( u.x > 0.5 || u.x<-0.5 || u.y > 0.5 || u.y<-0.5 ) { v.Set ( u.y, -u.x, 0.0 ); } else { v.Set ( 0.0, u.z, -u.y); } v.Normalize(); return; }
// Returns an intersection if found with distance maxDistance // viewDir must be a unit vector. // intersectDistance and visPoint are returned values. bool ViewableEllipsoid::FindIntersectionNT ( const VectorR3& viewPos, const VectorR3& viewDir, double maxDistance, double *intersectDistance, VisiblePoint& returnedPoint ) const { VectorR3 v = viewPos; v -= Center; double pdotuA = v^AxisA; double pdotuB = v^AxisB; double pdotuC = v^AxisC; double udotuA = viewDir^AxisA; double udotuB = viewDir^AxisB; double udotuC = viewDir^AxisC; double C = Square(pdotuA) + Square(pdotuB) + Square(pdotuC) - 1.0; double B = ( pdotuA*udotuA + pdotuB*udotuB + pdotuC*udotuC ); if ( C>0.0 && B>=0.0 ) { return false; // Pointing away from the ellipsoid } B += B; // Double B to get final factor of 2. double A = Square(udotuA) + Square(udotuB) + Square(udotuC); double alpha1, alpha2; int numRoots = QuadraticSolveRealSafe( A, B, C, &alpha1, &alpha2 ); if ( numRoots==0 ) { return false; } if ( alpha1>0.0 ) { if ( alpha1>=maxDistance ) { return false; // Too far away } // Found an intersection from outside. returnedPoint.SetFrontFace(); returnedPoint.SetMaterial( *OuterMaterial ); *intersectDistance = alpha1; } else if ( numRoots==2 && alpha2>0.0 && alpha2<maxDistance ) { // Found an intersection from inside. returnedPoint.SetBackFace(); returnedPoint.SetMaterial( *InnerMaterial ); *intersectDistance = alpha2; } else { return false; // Both intersections behind us (should never get here) } // Calculate intersection position v=viewDir; v *= (*intersectDistance); v += viewPos; returnedPoint.SetPosition( v ); // Intersection Position v -= Center; // Now v is the relative position double vdotuA = v^AxisA; double vdotuB = v^AxisB; double vdotuC = v^AxisC; v = vdotuA*AxisA + vdotuB*AxisB + vdotuC*AxisC; v.Normalize(); returnedPoint.SetNormal( v ); // Calculate u-v coordinates ViewableSphere::CalcUV( vdotuB, vdotuC, vdotuA, uvProjectionType, &returnedPoint.GetUV() ); returnedPoint.SetFaceNumber( 0 ); return true; }