//判读点是否在线上面(各种线的特性需要考虑)
	Bool HawkLine3D::IsPointOnLine(const HawkVector3D& oVec) const
	{
		HawkVector3D oTmp = oVec - Point;
		oTmp.Normalize();

		return (oTmp == Direction) || (oTmp == -Direction);
	}
	//直线和球相交
	Bool HawkLine3D::Intersect(const HawkSphere& oSphere,Vec3IntrResult* pResult) const
	{
		HawkVector3D vDiff = Point - oSphere.Center;
		Float a0  = vDiff.DotProduct(vDiff) - oSphere.Radius*oSphere.Radius;
		Float a1  = Direction.DotProduct(vDiff);
		Float dis = a1*a1 - a0;

		if (dis >= 0)
		{
			if (pResult)
			{
				if (dis >= HawkMath::FLOAT_DIFF)
				{
					Float root = HawkMath::Sqrt(dis);
					Float t0 = -a1 - root;
					Float t1 = -a1 + root;

					pResult->Factor = HawkMath::Abs<Float>(t0) < HawkMath::Abs<Float>(t1)?t0:t1;
					pResult->Point  = Point + pResult->Factor*Direction;
				}
				else
				{
					Float t0 = -a1;
					pResult->Factor = t0;
					pResult->Point  = Point + t0*Direction;
				}
			}			

			return true;
		}

		return false;
	}
	void HawkTriangle3D::GetProjection (const HawkVector3D& vAxis,Float& fMin, Float& fMax) const
	{
		Float dot[3] =
		{
			vAxis.DotProduct(GetPoint(0)),
			vAxis.DotProduct(GetPoint(1)),
			vAxis.DotProduct(GetPoint(2))
		};

		fMin = dot[0];
		fMax = fMin;

		if (dot[1] < fMin)
		{
			fMin = dot[1];
		}
		else if (dot[1] > fMax)
		{
			fMax = dot[1];
		}

		if (dot[2] < fMin)
		{
			fMin = dot[2];
		}
		else if (dot[2] > fMax)
		{
			fMax = dot[2];
		}
	}
	//两点在直线同一边(vP1,vP2在A,B同一边)
	Bool HawkTriangle3D::IsOnSameSide(const HawkVector3D& vP1,const HawkVector3D& vP2,const HawkVector3D& vA, const HawkVector3D& vB)
	{
		HawkVector3D bminusa = vB - vA;
		HawkVector3D cp1 = bminusa.CrossProduct(vP1 - vA);
		HawkVector3D cp2 = bminusa.CrossProduct(vP2 - vA);
		return (cp1.DotProduct(cp2) >= 0.0f);
	}  
	Bool  HawkLine3D::Intersect(const HawkOBB& oBox,Vec3IntrResult* pResult) const
	{
		const HawkVector3D* Axis = oBox.GetAxis();
		HawkVector3D diff        = Point - oBox.Center;
		HawkVector3D BOrigin(
			diff.DotProduct(Axis[0]),
			diff.DotProduct(Axis[1]),
			diff.DotProduct(Axis[2])
			);
		HawkVector3D BDirection(
			Direction.DotProduct(Axis[0]),
			Direction.DotProduct(Axis[1]),
			Direction.DotProduct(Axis[2])
			);

		Float t0 = -FLT_MAX,t1 = FLT_MAX;
		bool notAllClipped =
			geoClip(+BDirection.X, -BOrigin.X-oBox.Extent[0], t0, t1) &&
			geoClip(-BDirection.X, +BOrigin.X-oBox.Extent[0], t0, t1) &&
			geoClip(+BDirection.Y, -BOrigin.Y-oBox.Extent[1], t0, t1) &&
			geoClip(-BDirection.Y, +BOrigin.Y-oBox.Extent[1], t0, t1) &&
			geoClip(+BDirection.Z, -BOrigin.Z-oBox.Extent[2], t0, t1) &&
			geoClip(-BDirection.Z, +BOrigin.Z-oBox.Extent[2], t0, t1);

		if (notAllClipped)
		{
			//2交点
			if (t1 > t0)
			{
				if (pResult)
				{
					pResult->Factor = HawkMath::Abs<Float>(t0) < HawkMath::Abs<Float>(t1)? t0 : t1;
					pResult->Point  = Point + Direction * pResult->Factor;
				}
				return true;
			}
			//1交点
			else
			{
				if (pResult)
				{
					pResult->Factor = t0;
					pResult->Point  = Point + Direction * pResult->Factor;
				}
				return true;
			}
		}
		return false;
	}
	//////////////////////////////////////////////////////////////////////////
	//直线和三角形相交
	Bool HawkLine3D::Intersect(const HawkTriangle3D& oTriangle,Vec3IntrResult* pResult) const
	{
		HawkVector3D vDiff   = Point - oTriangle.GetPoint(0);
		HawkVector3D edge1  = oTriangle.GetEdge(0);
		HawkVector3D edge2  = oTriangle.GetEdge(1);
		HawkVector3D normal = edge1.CrossProduct(edge2);

		Float DdN   = Direction.DotProduct(normal);
		Float fSign = 0.0f;
		if (DdN > HawkMath::FLOAT_DIFF)
		{
			fSign = 1.0f;
		}
		else if (DdN < -HawkMath::FLOAT_DIFF)
		{
			fSign = -1.0f;
			DdN  = -DdN;
		}
		else
		{
			return false;
		}

		Float DdQxE2 = fSign*Direction.DotProduct(vDiff.CrossProduct(edge2));
		if (DdQxE2 >= 0.0f)
		{
			Float DdE1xQ = fSign*Direction.DotProduct(edge1.CrossProduct(vDiff));
			if (DdE1xQ >= 0.0f)
			{
				if (DdQxE2 + DdE1xQ <= DdN)
				{
					if (pResult)
					{
						Float QdN = -fSign*vDiff.DotProduct(normal);
						pResult->Factor = QdN / DdN;
						pResult->Point = Point + pResult->Factor*Direction;
					}					
					return true;
				}
			}
		}

		return false;
	}
Exemple #7
0
	void HawkQuaternion::GetAsAxisAngle(HawkVector3D& vAxis,Float& fRadian) const
	{
		//cos(A/2)+sin(A/2)*(x*i+y*j+z*k)

		Float fSqrLength = X*X+Y*Y+Z*Z;
		if (fSqrLength > 0.0f)
		{
			fRadian = 2.0f*HawkMath::Acos(W);
			Float fInvLength = HawkMath::Invsqrt(fSqrLength);
			vAxis.X = X*fInvLength;
			vAxis.Y = Y*fInvLength;
			vAxis.Z = Z*fInvLength;
		}
		else
		{
			fRadian  = 0.0f;
			vAxis.X  = 1.0f;
			vAxis.Y  = 0.0f;
			vAxis.Z  = 0.0f;
		}

		vAxis.Normalize();
	}
	//计算线段上面和oVec相隔最近的点
	HawkVector3D HawkLine3D::GetClosestPoint(const HawkVector3D& oVec) const
	{
		HawkVector3D oTmp = oVec - Point;
		
		return Point + Direction*oTmp.DotProduct(Direction);
	}
	Bool HawkTriangle3D::IsFrontFacing(const HawkVector3D& vVec3) const
	{
		HawkVector3D vNormal = GetNormal();
		Float fDis = vNormal.DotProduct(vVec3);
		return fDis >= 0.0f;
	}