/**
* @class Plane
*
* @Date: Created by Ray Zhang on 28/07/14.
*
* @Description
* Define a plane, defined by a point and the normal from the point.
*/
#include "Plane.h"
const float NORMALISATION_TOLERANCE = 0.0001f; // I would have expected to use RKEPSILON here, but perhaps I'm missing something.
Plane::Plane(const RKVector& point, const RKVector& normal)
: m_point(point)
, m_normal(normal)
{
RKASSERT(fabs(normal.LengthSquared() - 1) <= NORMALISATION_TOLERANCE, "Plane normal has not been normalised");
}
Plane::Plane(const RKVector& p1, const RKVector& p2, const RKVector& p3)
: m_point(p1)
{
m_normal = (p2 - p1).Cross(p3 - p1);
m_normal.Normalize();
}
bool Plane::Intersection(const RKVector& lineBegin, const RKVector& lineDirectionNormalised, RKVector* outIntersection) const
{
RKASSERT(fabs(lineDirectionNormalised.LengthSquared() - 1) <= NORMALISATION_TOLERANCE, "Ray direction has not been normalised");
RKASSERT(outIntersection, "No outIntersection reference provided");
bool res = false;
float direction_normal_dot_product = lineDirectionNormalised.Dot(m_normal);
if (fabs(direction_normal_dot_product) > NORMALISATION_TOLERANCE) {
RKVector line_to_plane = m_point - lineBegin;
float distance_along_ray = line_to_plane.Dot(m_normal) / direction_normal_dot_product;
*outIntersection = lineBegin + distance_along_ray * lineDirectionNormalised;
res = true;
}
outIntersection->w = 1.f;
return res;
}
bool Plane::Intersection(const Ray& ray, RKVector* outIntersection) const {
return Intersection(ray.GetOrigin(), ray.GetDirection(), outIntersection);
}
Plane::Side Plane::GetSide(const RKVector& test_position) const {
RKVector point_to_plane = m_point - test_position;
float dot_prod = point_to_plane.Dot(m_normal);
if (dot_prod < RKPI_ON_TWO)
return SIDE_FRONT;
else if (dot_prod > RKPI_ON_TWO)
return SIDE_BACK;
return SIDE_NONE;
}