Transform Subtract(const Transform one, const Transform two){ assert(one.parent == two.parent); return Transform_Create(GLKVector3Subtract(one.position, two.position), GLKQuaternionSubtract(one.orientation, two.orientation), // GLKVector4Subtract(one.rotation, two.rotation), GLKVector3Subtract(one.scale, two.scale), 0); }
bool IntersectWithEllipsoid( GLKVector3 start, GLKVector3 end, GLKVector3* hit ) { // transform endpoints into unit sphere basis start = GLKMatrix4MultiplyAndProjectVector3(kEllipsoidToUnitSphere, start); end = GLKMatrix4MultiplyAndProjectVector3(kEllipsoidToUnitSphere, end); // use unit sphere const double r = 1.; GLKVector3 diff = GLKVector3Subtract(end, start); // calculate quadratic components double a = GLKVector3DotProduct( diff, diff ); double b = GLKVector3DotProduct( GLKVector3MultiplyScalar(diff, 2.0), start ); double c = GLKVector3DotProduct( start, start ) - ( r * r ); // calculate discriminant double disc = ( b * b ) - ( 4.0 * a * c ); // consider intersection for positive disc only (discard edge cases) if ( disc > 0.0 ) { // calculate two solutions double t1 = ( -b - sqrt(disc) ) / ( 2.0 * a ); double t2 = ( -b + sqrt(disc) ) / ( 2.0 * a ); // calculate points of intersection and normals if ( t1 > 0.0 && t1 < 1.0 ) { if ( hit ) { *hit = GLKVector3Add( start, GLKVector3MultiplyScalar(diff, t1)); *hit = GLKMatrix4MultiplyAndProjectVector3(kUnitSphereToEllipsoid, *hit); } return true; } if ( t2 > 0.0 && t2 < 1.0 ) { if ( hit ) { *hit = GLKVector3Add( start, GLKVector3MultiplyScalar(diff, t2)); *hit = GLKMatrix4MultiplyAndProjectVector3(kUnitSphereToEllipsoid, *hit); } return true; } } return false; }