⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3dmath.cpp

📁 VC++ DEMO, used for the beginners and the amour
💻 CPP
字号:

#include "HEADERS.H"
#include "3DMATH.H"
//////////////////////////////////////////////////////////////////////////////////////////
// 函数: NearestPointOnLine()
// 功能: 求选择点p与线段(va,vb)上最近的点
//////////////////////////////////////////////////////////////////////////////////////////
D3DXVECTOR3 CGE::MATHIN3D::NearestPointOnLine(const D3DXVECTOR3 &va, const D3DXVECTOR3 &vb, const D3DXVECTOR3 &vp)
{
	// 向量c为pa(vp - va)
	// t为向量c在线段上的投影值
	// 如果t < 0,则va为最近的点
	// 如果t > d,则vb为最近的点
	// 否则,最近的点为:va + v * t (v为线段的单位向量)
	D3DXVECTOR3 c = vp - va;
	D3DXVECTOR3 v = vb - va;
	FLOAT d = D3DXVec3Length(&v);
	D3DXVec3Normalize(&v, &v);

	FLOAT t = D3DXVec3Dot(&v, &c);
	if (t < 0) return va;
	if (t > d) return vb;

	return (va + v * t);
}
//////////////////////////////////////////////////////////////////////////////////////////
// 函数: NearestPointOnTriangle()
// 功能: 求选择点p与三角形(va,vb,vc)上最近的点
//////////////////////////////////////////////////////////////////////////////////////////
D3DXVECTOR3 CGE::MATHIN3D::NearestPointOnTriangle(const D3DXVECTOR3 &va, const D3DXVECTOR3 &vb, const D3DXVECTOR3 &vc, const D3DXVECTOR3 &vp)
{
	D3DXVECTOR3 vRab = CGE::MATHIN3D::NearestPointOnLine(va, vb, vp);
	D3DXVECTOR3 vRac = CGE::MATHIN3D::NearestPointOnLine(va, vc, vp);
	D3DXVECTOR3 vRbc = CGE::MATHIN3D::NearestPointOnLine(vb, vc, vp);

	FLOAT fRab = D3DXVec3Length(&(vRab - vp));
	FLOAT fRac = D3DXVec3Length(&(vRac - vp));
	FLOAT fRbc = D3DXVec3Length(&(vRbc - vp));

	if (fRab < fRac && fRab < fRbc) return vRab;
	if (fRac < fRab && fRac < fRbc) return vRac;

	return (vRbc);
}
//////////////////////////////////////////////////////////////////////////////////////////
// 函数: PlaneIntersectRay()
// 功能: 求射点与平面交点的长度
//////////////////////////////////////////////////////////////////////////////////////////
FLOAT CGE::MATHIN3D::PlaneIntersectRay(const D3DXVECTOR3 &vOriginPos, const D3DXVECTOR3 &vNormal, const D3DXVECTOR3 &vOriginRay, const D3DXVECTOR3 &vVectorRay)
{
	// 射线(原点vOriginRay, 规格化的方向vVectorRay)
	// 平面(原点vOriginPos, 规格化的方向vNomal)
	// numer为射线原点到平面的投影值 - 平面的距离
	// denom射线为方向到平面的投影值
	FLOAT d = -D3DXVec3Dot(&vNormal,&vOriginPos);
	FLOAT numer = D3DXVec3Dot(&vNormal,&vOriginRay) + d;
	FLOAT denom = D3DXVec3Dot(&vNormal,&vVectorRay);
	return (-(numer/denom));
}
//////////////////////////////////////////////////////////////////////////////////////////
// 函数: IsPointInTriangle()
// 功能: 判断一个点是否在一个三角形内
//////////////////////////////////////////////////////////////////////////////////////////
BOOL CGE::MATHIN3D::IsPointInTriangle(const D3DXVECTOR3 &va, const D3DXVECTOR3 &vb, const D3DXVECTOR3 &vc, const D3DXVECTOR3 &vp)
{
	D3DXVECTOR3 vba, vca, vpa, vpb, vcb, vab;
	
	D3DXVec3Normalize(&vba, &(vb - va));
	D3DXVec3Normalize(&vca, &(vc - va));
	D3DXVec3Normalize(&vpa, &(vp - va));
	D3DXVec3Normalize(&vpb, &(vp - vb));
	D3DXVec3Normalize(&vcb, &(vc - vb));
	D3DXVec3Normalize(&vab, &(va - vb));
	
	// cab为边ac与边ab的夹角的余弦值
	float cab = D3DXVec3Dot(&vba, &vca);
	if (D3DXVec3Dot(&vpa, &vba) < cab)
		return FALSE;
	if (D3DXVec3Dot(&vpa, &vca) < cab)
		return FALSE;

	// cba为边bc与边ba的夹角的余弦值
	float cba = D3DXVec3Dot(&vcb, &vab);
	if (D3DXVec3Dot(&vpb, &vcb) < cba)
		return FALSE;
	if (D3DXVec3Dot(&vpb, &vab) < cba)
		return FALSE;

	return TRUE;
}

VOID CGE::MATHIN3D::Scale3DVector(D3DXVECTOR3 & v,FLOAT xScale,FLOAT yScale,FLOAT zScale)
{
	v.x *= xScale;
	v.y *= yScale;
	v.z *= zScale;
}

FLOAT CGE::MATHIN3D::SphereIntersectRay(const D3DXVECTOR3 &vOrigin_s, FLOAT fRadius, const D3DXVECTOR3 &vOrigin_r, const D3DXVECTOR3 &vVector_r)
{
	// 计算射线(原点vOrigin_r, 方向vVector_r)与
	// 球(原点vOrigin_s, 半径fRadius)相交的距离
	// 如果没有相交则返回-1.0f
	D3DXVECTOR3 vq = vOrigin_s - vOrigin_r;
	FLOAT v = D3DXVec3Dot(&vq, &vVector_r);
	FLOAT d = fRadius * fRadius - (D3DXVec3LengthSq(&vq) - v * v);

	if (d < 0.0f)
		return -1.0f;
	return (v - sqrtf(d));
}

BOOL CGE::MATHIN3D::IsPolygonInBox(const D3DXVECTOR3 &va, const D3DXVECTOR3 &vb, const D3DXVECTOR3 &vc, const D3DXVECTOR3 &vCenter, FLOAT xSize, FLOAT ySize, FLOAT zSize)
{
	// 判断一个多边形是否在一个长方体内
	// 不能简单的判断每一个点是否在长方体内
	// 而要通过建造一个围绕多边形的长方体来判断
	FLOAT xMax = max(max(va.x, vb.x), vc.x);
	FLOAT xMin = min(min(va.x, vb.x), vc.x);
	FLOAT yMax = max(max(va.y, vb.y), vc.y);
	FLOAT yMin = min(min(va.y, vb.y), vc.y);
	FLOAT zMax = max(max(va.z, vb.z), vc.z);
	FLOAT zMin = min(min(va.z, vb.z), vc.z);

	if (xMax < vCenter.x - xSize)
		return FALSE;
	if (xMin > vCenter.x + xSize)
		return FALSE;
	if (yMax < vCenter.y - ySize)
		return FALSE;
	if (yMin > vCenter.y + ySize)
		return FALSE;
	if (zMax < vCenter.z - zSize)
		return FALSE;
	if (zMin > vCenter.z + zSize)
		return FALSE;

	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -