예제 #1
0
파일: pniseg.cpp 프로젝트: prwhite/philibs
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;
}
예제 #2
0
// 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;
}