📄 3dmath.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 + -