charles/src/objectPlane.cc

164 lines
3.1 KiB
C++
Raw Normal View History

2013-09-22 09:58:40 -07:00
/* object_plane.h
*
* Planes are Shapes defined by a point and two direction vectors.
*
* Eryn Wells <eryn@erynwells.me>
*/
#include <cassert>
#include <cmath>
#include <cstdlib>
#include <cstdio>
#include "objectPlane.hh"
2013-09-22 09:58:40 -07:00
2014-08-09 10:58:30 -07:00
using charles::basics::Ray;
using charles::basics::Vector4;
namespace charles {
2013-09-22 09:58:40 -07:00
/*
* charles::Plane::Plane --
2013-09-22 09:58:40 -07:00
*/
Plane::Plane()
2014-08-09 10:58:30 -07:00
: mNormal(0, 1, 0),
mDistance(0.0)
2013-09-22 09:58:40 -07:00
{ }
2014-08-09 10:58:30 -07:00
/*
* charles::Plane::GetNormal --
*/
const Vector4&
Plane::GetNormal()
const
{
return mNormal;
}
2013-09-22 09:58:40 -07:00
2014-08-09 10:58:30 -07:00
/*
* charles::Plane::SetNormal --
*/
void
2014-08-09 10:58:30 -07:00
Plane::SetNormal(const Vector4& normal)
{
2014-08-09 10:58:30 -07:00
mNormal = basics::Normalized(normal);
}
2014-08-09 10:58:30 -07:00
/*
* charles::Plane::GetDistance --
*/
Double
Plane::GetDistance()
const
{
return mDistance;
}
2014-08-09 10:58:30 -07:00
/*
* charles::Plane::SetDistance --
*/
void
Plane::SetDistance(Double distance)
{
mDistance = distance;
}
2013-09-22 09:58:40 -07:00
/*
* charles::Plane::DoesIntersect --
2013-09-22 09:58:40 -07:00
*/
bool
2014-08-09 10:58:30 -07:00
Plane::DoIntersect(const Ray& ray,
TVector& t,
Stats& stats)
2013-09-22 09:58:40 -07:00
const
{
/*
* Planes are defined in terms of [A B C D], where [A B C] make up the unit
* normal vector, and D is the distance from the origin. We can write the
* equation for a plane like this:
2013-09-22 09:58:40 -07:00
*
* A * x + B * y + C * z + D = 0, where
* A^2 + B^2 + C^2 = 1.
*
* The sign of D determines which side of the origin the plane is on.
2013-09-22 09:58:40 -07:00
*
* We can figure out the distance from the ray's origin to the intersection
* point (there will be only one for planes) by substituting the ray's
* parameters into the above equation. In the equations below, RO is the
* ray's origin, RD is the ray's direction, and components thereof are
* indicated with lowercase letters (ROx is the x component of RO).
2013-09-22 09:58:40 -07:00
*
* A(ROx + RDx * t) + B(ROy + RDy * t) + C(ROz + RDz * t) + D = 0
*
* We then solve for t.
2013-09-22 09:58:40 -07:00
*
* t = -(A * ROx + B * ROy + C * ROz + D) / (A * RDx + B * RDy + C * RDz)
2013-09-22 09:58:40 -07:00
*
* In vector notation, this works out more cleanly.
2013-09-22 09:58:40 -07:00
*
* t = -(n . RO + D) / (n . RD)
2013-09-22 09:58:40 -07:00
*/
stats.planeIntersectionTests++;
/* The denominator for the t equation above. */
2014-08-09 10:58:30 -07:00
Double vd = mNormal.Dot(ray.direction);
if (NearZero(vd)) {
/* The ray is parallel to the plane. */
return false;
2013-09-22 09:58:40 -07:00
}
/* The numerator of the equation for t above. */
2014-08-09 10:58:30 -07:00
Double vo = -(mNormal.Dot(ray.origin) + mDistance);
2013-09-22 09:58:40 -07:00
Double t0 = vo / vd;
2013-09-22 09:58:40 -07:00
if (t0 < 0.0) {
/* The plane is behind the ray's origin. */
return false;
2013-09-22 09:58:40 -07:00
}
if (TooFar(t0)) {
return false;
}
stats.planeIntersections++;
t.push_back(t0);
return true;
2013-09-22 09:58:40 -07:00
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
2013-09-22 09:58:40 -07:00
/*
2014-08-09 10:58:30 -07:00
* charles::Plane::DoNormal --
2013-09-22 09:58:40 -07:00
*/
2014-08-09 10:58:30 -07:00
Vector4
Plane::DoNormal(const Vector4& p)
2013-09-22 09:58:40 -07:00
const
{
return mNormal;
2013-09-22 09:58:40 -07:00
}
#pragma clang diagnostic pop
2014-08-09 10:58:30 -07:00
/*
* charles::Plane::Write --
*/
void
Plane::Write(std::ostream& ost)
const
{
ost << "[Plane normal=" << mNormal << " distance=" << mDistance << "]";
}
} /* namespace charles */