// Spherical linear interpolation between direction vectors. // Intermediate vectors follow great circle path with constant velocity. vec3d slerp( const vec3d& a, const vec3d& b, const double &t ) { vec3d an = a / a.mag(); vec3d bn = b / b.mag(); double dp = dot( an, bn ); double theta = 0.0; if ( dp >= -1.0 && dp <= 1.0 ) { theta = acos( dp ); } // Initialize retvec as a-direction. vec3d retvec = an; // If vectors are not parallel, interpolate between them. if ( std::abs( theta ) > 1.0e-6 ) { // Drop division by sin(theta) because .normalize() will scale double coeff1 = sin( ( 1.0 - t ) * theta ); // implied / sin(theta) double coeff2 = sin( t * theta ); // implied / sin(theta) retvec = coeff1 * an + coeff2 * bn; retvec.normalize(); } return retvec; }
//******* Angle Between Vectors ******// double angle(const vec3d& a, const vec3d& b) { double angle = dot(a, b)/(a.mag()*b.mag()); if ( angle < -1.0 ) angle = -1.0; else if ( angle > 1.0 ) angle = 1.0; return(acos(angle)); }
//******* Cosine of Angle Between Vectors ******// double cos_angle(const vec3d& a, const vec3d& b) { double angle = dot(a, b)/(a.mag()*b.mag()); if (angle < -1.0 ) return -1.0; else if ( angle > 1.0) return 1.0; return angle; }
//******* Angle Between Vectors ******// double angle( const vec3d& a, const vec3d& b ) { double angle = dot( a, b ) / ( a.mag() * b.mag() ); if ( angle >= -1.0 && angle <= 1.0 ) { return( acos( angle ) ); } else { return( 0.0 ); } }
//to return projection vector vec3d vec3d :: proj(const vec3d& vec) const { float m = vec.mag(); if(m == 0) throw "invalid vector"; return vec.unit()*(operator*(vec)/m); }
//to return the angle between vectors in radians double vec3d :: angle(const vec3d& vec) const { float this_mag = mag(); float vec_mag = vec.mag(); if(this_mag == 0 || vec_mag == 0) throw "invalid vector"; return acos(operator*(vec)/(this_mag*vec_mag)); }