diff --git a/shapes/Plane.cc b/shapes/Plane.cc new file mode 100644 index 0000000..a3c3468 --- /dev/null +++ b/shapes/Plane.cc @@ -0,0 +1,50 @@ + +#include "Plane.h" +#include "util/Solver.h" +#include +#include +using namespace std; + +Plane::Plane(double a, double b, double c, double d) +{ + m_a = a; + m_b = b; + m_c = c; + m_d = d; +} + +Shape::IntersectList Plane::intersect(const Ray & ray) +{ + Ray ray_inv = m_inverse.transform_ray(ray); + + IntersectList res; + /* + * Plane equation: ax + by + cz + d = 0 + * Ray equation: R = R0 + tRd + * x = R0x + tRdx + * y = R0y + tRdy + * z = R0z + tRdz + * Combined: a(R0x + tRdx) + b(R0y + tRdy) + c(R0z + tRdz) + d = 0 + * aR0x + (t)aRdx + bR0y + (t)bRdy + cR0z + (t)cRdz + d = 0 + * (t)(aRdx + bRdy + cRdz) + aR0x + bR0y + cR0z + d = 0 + */ + LinearSolver solver( m_a * ray.getDirection()[0] + + m_b * ray.getDirection()[1] + + m_c * ray.getDirection()[2], + m_a * ray.getOrigin()[0] + + m_b * ray.getOrigin()[1] + + m_c * ray.getOrigin()[2] + + m_d); + Solver::Result solutions = solver.solve(); + if (solutions.numResults > 0) + { + res.push_back(m_transform.transform_point(ray_inv[solutions.results[0]])); + } + return res; +} + +Vector Plane::getNormalAt(const Vector & pt) +{ + Vector normal(m_a, m_b, m_c); + return normal.normalize(); +} diff --git a/shapes/Plane.h b/shapes/Plane.h new file mode 100644 index 0000000..eccff60 --- /dev/null +++ b/shapes/Plane.h @@ -0,0 +1,19 @@ + +#ifndef PLANE_H +#define PLANE_H PLANE_H + +#include "Shape.h" + +class Plane : public Shape +{ + public: + Plane(double a, double b, double c, double d); + IntersectList intersect(const Ray & ray); + Vector getNormalAt(const Vector & pt); + + private: + double m_a, m_b, m_c, m_d; +}; + +#endif + diff --git a/util/Solver.cc b/util/Solver.cc index 125760d..b6cb565 100644 --- a/util/Solver.cc +++ b/util/Solver.cc @@ -13,6 +13,40 @@ Solver::Solver(double a, double b, double c, double d, double e) } +/************************************************************************** + * LinearSolver methods * + *************************************************************************/ +LinearSolver::LinearSolver(double a, double b) + : Solver(a, b) +{ +} + +/* solve a linear equation */ +Solver::Result LinearSolver::solve() +{ + /* equation ax + b = 0 */ + Result res; + if (a == 0.0) + { + if (b == 0.0) + { + res.numResults = 1; + res.results[0] = 0.0; + } + else + { + res.numResults = 0; + } + } + else + { + res.numResults = 1; + res.results[0] = -b / a; + } + return res; +} + + /************************************************************************** * QuadraticSolver methods * *************************************************************************/ diff --git a/util/Solver.h b/util/Solver.h index 9795b0b..e409ed2 100644 --- a/util/Solver.h +++ b/util/Solver.h @@ -24,6 +24,13 @@ class Solver double a, b, c, d, e; }; +class LinearSolver : public Solver +{ + public: + LinearSolver(double a, double b); + Result solve(); +}; + class QuadraticSolver : public Solver { public: