📄 triangle.cpp
字号:
// Triangle.cpp: Implementierung der Klasse CTriangle.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Triangle.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
// Axis constants
const short unsigned int x = 0;
const short unsigned int y = 1;
const short unsigned int z = 2;
//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////
CTriangle::CTriangle()
{
}
CTriangle::~CTriangle()
{
}
void CTriangle::CalcNormal()
{
// Calculates the normal vector of the triangle
// taken from the member data of the class
// Call general CalcNormal() and store result in the
// class's member data
CalcNormal(m_Vertices, m_Normal);
}
void CTriangle::CalcNormal(const float v[][3], float out[])
{
// Calculates the normal vector of the passed
// triangle.
// Two vectors
float v1[3], v2[3];
// Calculate two vectors from the three points
v1[x] = v[0][x] - v[1][x];
v1[y] = v[0][y] - v[1][y];
v1[z] = v[0][z] - v[1][z];
v2[x] = v[1][x] - v[2][x];
v2[y] = v[1][y] - v[2][y];
v2[z] = v[1][z] - v[2][z];
// Take the cross product of the two vectors to get
// the normal vector which will be stored in out
CrossProduct(v1, v2, out);
// Normalize the vector (shorten length to one)
ReduceToUnit(out);
}
void CTriangle::CrossProduct(const float v1[], const float v2[], float out[])
{
// Take the cross product of the two vectors
out[x] = v1[y] * v2[z] - v1[z] * v2[y];
out[y] = v1[z] * v2[x] - v1[x] * v2[z];
out[z] = v1[x] * v2[y] - v1[y] * v2[x];
}
void CTriangle::ReduceToUnit(float vector[])
{
// Reduces a normal vector specified as a set of three coordinates,
// to a unit normal vector of length one.
// Calculate the length of the vector
float length = (float) sqrt(( vector[0] * vector[0]) +
( vector[1] * vector[1]) +
( vector[2] * vector[2]) );
// Keep the program from blowing up by providing an exceptable
// value for vectors that may calculated too close to zero.
if(length == 0.0f)
length = 1.0f;
// Dividing each element by the length will result in a
// unit normal vector.
vector[0] /= length;
vector[1] /= length;
vector[2] /= length;
}
void CTriangle::CalcAntiPlanes()
{
// Calculate the three infinite anti-planes (represented by triangles)
// and stores them in the class member variables. Also calculate and store
// their normals. A calculated normal for the base triangle is required.
// Calculate anti-planes (described by 3 vertices)
float AntiPlane1[3][3] = {{ m_Vertices[2][x], m_Vertices[2][y], m_Vertices[2][z] },
{ m_Vertices[1][x], m_Vertices[1][y], m_Vertices[1][z] },
{ m_Vertices[0][x] + m_Normal[x], m_Vertices[0][y]
+ m_Normal[y], m_Vertices[0][z] + m_Normal[z] }};
float AntiPlane2[3][3] = {{ m_Vertices[2][x], m_Vertices[2][y], m_Vertices[2][z] },
{ m_Vertices[1][x] + m_Normal[x], m_Vertices[1][y]
+ m_Normal[y], m_Vertices[1][z] + m_Normal[z] },
{ m_Vertices[0][x], m_Vertices[0][y], m_Vertices[0][z] }};
float AntiPlane3[3][3] = {{ m_Vertices[2][x] + m_Normal[x], m_Vertices[2][y]
+ m_Normal[y], m_Vertices[2][z] + m_Normal[z] },
{ m_Vertices[1][x], m_Vertices[1][y], m_Vertices[1][z] },
{ m_Vertices[0][x], m_Vertices[0][y], m_Vertices[0][z] }};
// Save for each anti-plane one vertex that lays
// on the anti-plane
m_AntiPlane1[x] = AntiPlane1[2][0];
m_AntiPlane1[y] = AntiPlane1[2][1];
m_AntiPlane1[z] = AntiPlane1[2][2];
m_AntiPlane2[x] = AntiPlane2[1][0];
m_AntiPlane2[y] = AntiPlane2[1][1];
m_AntiPlane2[z] = AntiPlane2[1][2];
m_AntiPlane3[x] = AntiPlane3[0][0];
m_AntiPlane3[y] = AntiPlane3[0][1];
m_AntiPlane3[z] = AntiPlane3[0][2];
// Calculate the anti-plane's normals and save it in the
// class's member data
CalcNormal(AntiPlane1, m_AntiPlane1Normal);
CalcNormal(AntiPlane2, m_AntiPlane2Normal);
CalcNormal(AntiPlane3, m_AntiPlane3Normal);
}
float CTriangle::GetInfinitePlaneDistance(const float fPoint[])
{
// Calculates the distance from a point to an infinite plane
// described by three vertices on it. The three vertices are taken
// from the triangle of the member data. A calculated normal for the
// base triangle is required.
// Return distance
return GetInfinitePlaneDistance(m_Vertices[0], fPoint, m_Normal);
}
float CTriangle::GetInfinitePlaneDistance(const float fPlaneVertex[], const float fPoint[], const float fNormal[])
{
// Calculates the distance from a point to an infinite plane
// described by one vertex and its normal
// Distance of the polygon to the origin
float fD = fNormal[x] * fPlaneVertex[x] + fNormal[y] * fPlaneVertex[y] + fNormal[z] * fPlaneVertex[z];
// Return distance
return (fNormal[x] * fPoint[x] + fNormal[y] * fPoint[y] + fNormal[z] * fPoint[z] - fD);
}
bool CTriangle::CheckAntiPlaneDistance(const float fPoint[])
{
// Checks the point against the anti-planes of the triangle
// taken from the class's member data. Returns true if the
// distance to all anti-planes is positive. The three anti-planes
// must be already calculated
// Get distance of the point from the anti-planes and return FALSE
// if one of them is negativ
if (GetInfinitePlaneDistance(m_AntiPlane1, fPoint, m_AntiPlane1Normal) < 0.0f)
return FALSE;
if (GetInfinitePlaneDistance(m_AntiPlane2, fPoint, m_AntiPlane2Normal) < 0.0f)
return FALSE;
if (GetInfinitePlaneDistance(m_AntiPlane3, fPoint, m_AntiPlane3Normal) < 0.0f)
return FALSE;
// All distances are positive
return TRUE;
}
bool CTriangle::CheckCollision(const float fPointBefore[], const float fPointAfter[])
{
// Checks if a object that moves from fPointBefore to fPointAfter will collide
// with the triangle. In case of collision it returns true. The three anti-planes
// must be already calculated.
// Get distance to the infinite plane of the triangle before and after the movement
float fDistanceBefore = GetInfinitePlaneDistance(fPointBefore);
float fDistanceAfter = GetInfinitePlaneDistance(fPointAfter);
// Has a collision with the infinite plane occured ?
if ( ((fDistanceBefore >= 0.0f) && (fDistanceAfter <= 0.0f))
|| ((fDistanceBefore <= 0.0f) && (fDistanceAfter >= 0.0f))
|| fabs(fDistanceAfter) < 0.003)
{
// Has this collision occured inside the triangle ?
if (CheckAntiPlaneDistance(fPointAfter) == TRUE)
return TRUE; // Yes
if (CheckAntiPlaneDistance(fPointBefore) == TRUE)
return TRUE; // Yes
}
// No collision occured
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -