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

📄 triangle.cpp

📁 c++程序
💻 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 + -