int seg:: contains ( const seg& segIn ) const { // TODO: Remove direction vector normalization?? User's responsibility??? vec3 tDir ( segIn.dir ); tDir.normalize (); // vec3 endPt = segIn.pos + tDir * segIn.length; vec3 endPt ( tDir ); endPt *= segIn.length; endPt += segIn.pos; int c1 = contains ( segIn.pos ); int c2 = contains ( endPt ); if ( c1 ) { if ( c2 ) return containsResult::AllIn; return containsResult::SomeIn; } if ( c2 ) return containsResult::SomeIn; // OPTIMIZE: Expensive... if ( segIn.contains ( pos ) ) return containsResult::SomeIn; vec3 endPos = pos + dir * length; if ( segIn.contains ( endPos ) ) return containsResult::SomeIn; return containsResult::NoneIn; }
// OPTIMIZE: This is a HUGE/heavyweight function. Probably several ways to optimize it. int sphere:: contains ( const seg& segIn ) const { vec3 pos; vec3 dir; ValueType len; segIn.get ( pos, dir, len ); dir.normalize (); vec3 endPos = pos + dir * len; // The segment begin and endpoint might lie in the sphere. int c1 = contains ( pos ); int c2 = contains ( endPos ); if ( c1 ) { if ( c2 ) return containsResult::AllIn | containsResult::SomeIn; return containsResult::SomeIn; } if ( c2 ) { return containsResult::SomeIn; } ValueType a = dir.dot ( dir ); //ValueType a = dir.vec[0] * dir.vec[0] + dir.vec[1] * dir.vec[1] + dir.vec[2] * dir.vec[2]; ValueType b = static_cast< ValueType > ( 2.0 ) * dir.vec[0] * ( pos.vec[0] - center.vec[0] ) + static_cast< ValueType > ( 2.0 ) * dir.vec[1] * ( pos.vec[1] - center.vec[1] ) + static_cast< ValueType > ( 2.0 ) * dir.vec[2] * ( pos.vec[2] - center.vec[2] ); ValueType tx = pos.vec[0] - center.vec[0]; ValueType ty = pos.vec[1] - center.vec[1]; ValueType tz = pos.vec[2] - center.vec[2]; ValueType c = tx * tx + ty * ty + tz * tz - radius * radius; //ValueType c = ( pos.vec[0] - center.vec[0] ) * ( pos.vec[0] - center.vec[0] ) + // ( pos.vec[1] - center.vec[1] ) * ( pos.vec[0] - center.vec[0] ) + // ( pos.vec[0] - center.vec[0] ) * ( pos.vec[0] - center.vec[0] ) - // radius * radius; // Check the discriminant to see if there are any solutions. ValueType discriminant = b * b - static_cast< ValueType > ( 4.0 ) * a * c; if ( discriminant < TraitType::zeroVal ) { // No solutions --> no intersections. return containsResult::NoneIn; } ValueType twoA = static_cast< ValueType > ( 2.0 ) * a; if ( discriminant == TraitType::zeroVal ) { // One intersection. Segment is tangential. ValueType t1 = -b / twoA; vec3 ip1 = pos + dir * t1; return segIn.contains ( ip1 ); } // Two intersections. ValueType t1 = ( -b + TraitType::sqrt ( discriminant ) ) / twoA; ValueType t2 = ( -b - TraitType::sqrt ( discriminant ) ) / twoA; vec3 ip1 = pos + dir * t1; vec3 ip2 = pos + dir * t2; if ( segIn.contains ( ip1 ) || segIn.contains ( ip2 ) ) return containsResult::SomeIn; else return containsResult::NoneIn; }