/* object_plane.h * * Planes are Shapes defined by a point and two direction vectors. * * Eryn Wells */ #include #include #include #include #include "basics.h" #include "object.h" #include "objectPlane.hh" namespace charles { /* * charles::Plane::Plane -- */ Plane::Plane() : mNormal(Vector3::Y), mDistance(0.0) { } const Vector3& Plane::GetNormal() const { return mNormal; } void Plane::SetNormal(const Vector3& normal) { mNormal = normal.normalized(); } Double Plane::GetDistance() const { return mDistance; } void Plane::SetDistance(Double distance) { mDistance = distance; } /* * charles::Plane::DoesIntersect -- */ bool Plane::DoesIntersect(const Ray &ray, TVector& t, Stats& stats) 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: * * 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. * * 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). * * A(ROx + RDx * t) + B(ROy + RDy * t) + C(ROz + RDz * t) + D = 0 * * We then solve for t. * * t = -(A * ROx + B * ROy + C * ROz + D) / (A * RDx + B * RDy + C * RDz) * * In vector notation, this works out more cleanly. * * t = -(n . RO + D) / (n . RD) */ stats.planeIntersectionTests++; /* The denominator for the t equation above. */ Double vd = mNormal.dot(ray.direction); if (NearZero(vd)) { /* The ray is parallel to the plane. */ return false; } /* The numerator of the equation for t above. */ Double vo = -(mNormal.dot(ray.origin) + mDistance); Double t0 = vo / vd; if (t0 < 0.0) { /* The plane is behind the ray's origin. */ return false; } if (TooFar(t0)) { return false; } stats.planeIntersections++; t.push_back(t0); return true; } /* * charles::Plane::point_is_on_surface -- */ bool Plane::point_is_on_surface(const Vector3 &p) const { /* * Plug point p into the equation for a plane: * * A * x + B * y + C * z + D = 0 * * where (A, B, C) are the coordinates of the normal vector, and D is the * distance along that vector from the origin. */ return NearZero(mNormal.dot(p) + mDistance); } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-parameter" /* * charles::Plane::compute_normal -- */ Vector3 Plane::compute_normal(const Vector3 &p) const { return mNormal; } #pragma clang diagnostic pop } /* namespace charles */