diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2946ad0 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ + +ifdef WIN32 +export CPPFLAGS += -I"$(shell cd)" +else +export CPPFLAGS += -I"$(shell pwd)" +endif + +all: + make -C util + make -C shapes + make -C test + +clean: + make -C test clean + make -C shapes clean + make -C util clean diff --git a/shapes/Makefile b/shapes/Makefile new file mode 100644 index 0000000..0ba20fe --- /dev/null +++ b/shapes/Makefile @@ -0,0 +1,20 @@ + +OBJS := $(patsubst %.cc,%.o,$(wildcard *.cc)) + +all: $(OBJS) + +%.o: %.cc + $(CXX) -c -o $@ $(CPPFLAGS) $(CXXFLAGS) $< + +# Make dependency files +%.dep: %.cc + @set -e; rm -f $@; \ + $(CXX) -MM $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +clean: + -$(RM) -f *.o *.dep $(ARCHIVE) + +# Include dependency files +include $(OBJS:.o=.dep) diff --git a/shapes/Shape.h b/shapes/Shape.h new file mode 100644 index 0000000..8e4d6a3 --- /dev/null +++ b/shapes/Shape.h @@ -0,0 +1,15 @@ + +#ifndef SHAPE_H +#define SHAPE_H SHAPE_H + +#include "util/Solver.h" +#include "util/Ray.h" + +class Shape +{ + public: + virtual Solver::Result intersect(const Ray & ray) = 0; +}; + +#endif + diff --git a/shapes/Sphere.cc b/shapes/Sphere.cc new file mode 100644 index 0000000..810aee1 --- /dev/null +++ b/shapes/Sphere.cc @@ -0,0 +1,22 @@ + +#include "Sphere.h" +#include "util/Solver.h" + +Sphere::Sphere(double radius) +{ + m_radius = radius; +} + +Solver::Result Sphere::intersect(const Ray & ray) +{ + Solver::Result res; + QuadraticSolver solver(1.0, + 2 * ( ray.getOrigin()[0] * ray.getDirection()[0] + + ray.getOrigin()[1] * ray.getDirection()[1] + + ray.getOrigin()[2] * ray.getDirection()[2] ), + ray.getOrigin()[0] * ray.getOrigin()[0] + + ray.getOrigin()[1] * ray.getOrigin()[1] + + ray.getOrigin()[2] * ray.getOrigin()[2] ); + Solver::Result quadSolutions = solver.solve(); + return res; +} diff --git a/shapes/Sphere.h b/shapes/Sphere.h new file mode 100644 index 0000000..d577b72 --- /dev/null +++ b/shapes/Sphere.h @@ -0,0 +1,18 @@ + +#ifndef SPHERE_H +#define SPHERE_H SPHERE_H + +#include "Shape.h" + +class Sphere : public Shape +{ + public: + Sphere(double radius); + Solver::Result intersect(const Ray & ray); + + private: + double m_radius; +}; + +#endif + diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..174d30f --- /dev/null +++ b/test/Makefile @@ -0,0 +1,6 @@ + +all: + @echo Nothing yet. + +clean: + @echo Nothing yet. diff --git a/util/Makefile b/util/Makefile new file mode 100644 index 0000000..0ba20fe --- /dev/null +++ b/util/Makefile @@ -0,0 +1,20 @@ + +OBJS := $(patsubst %.cc,%.o,$(wildcard *.cc)) + +all: $(OBJS) + +%.o: %.cc + $(CXX) -c -o $@ $(CPPFLAGS) $(CXXFLAGS) $< + +# Make dependency files +%.dep: %.cc + @set -e; rm -f $@; \ + $(CXX) -MM $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +clean: + -$(RM) -f *.o *.dep $(ARCHIVE) + +# Include dependency files +include $(OBJS:.o=.dep) diff --git a/util/Ray.cc b/util/Ray.cc new file mode 100644 index 0000000..1d48344 --- /dev/null +++ b/util/Ray.cc @@ -0,0 +1,26 @@ + +#include "Ray.h" + +Ray::Ray() +{ +} + +Ray::Ray(const Vector & origin, const Vector & direction) +{ + m_origin = origin; + m_direction = direction; + m_direction.normalize(); +} + +/* + * return a vector for the point at distance dist + * from the ray's origin point, along its direction. + */ +Vector Ray::getPositionAt(double dist) const +{ + Vector v; + v[0] = m_origin[0] + dist * m_direction[0]; + v[1] = m_origin[1] + dist * m_direction[1]; + v[2] = m_origin[2] + dist * m_direction[2]; + return v; +} diff --git a/util/Ray.h b/util/Ray.h new file mode 100644 index 0000000..39fa6de --- /dev/null +++ b/util/Ray.h @@ -0,0 +1,22 @@ + +#ifndef RAY_H +#define RAY_H RAY_H + +#include "Vector.h" + +class Ray +{ + public: + Ray(); + Ray(const Vector & origin, const Vector & direction); + const Vector & getOrigin() const { return m_origin; } + const Vector & getDirection() const { return m_direction; } + Vector getPositionAt(double dist) const; + + private: + Vector m_origin; + Vector m_direction; +}; + +#endif + diff --git a/util/Solver.cc b/util/Solver.cc new file mode 100644 index 0000000..decf408 --- /dev/null +++ b/util/Solver.cc @@ -0,0 +1,77 @@ + +#include "Solver.h" +#include + +/* Generic Solver constructor */ +Solver::Solver(double a, double b, double c, double d, double e) +{ + this->a = a; + this->b = b; + this->c = c; + this->d = d; + this->e = e; +} + + +/************************************************************************** + * QuadraticSolver methods * + *************************************************************************/ +QuadraticSolver::QuadraticSolver(double a, double b, double c) + : Solver(a, b, c) +{ +} + +/* solve a quadratic equation */ +Solver::Result QuadraticSolver::solve() +{ + Result res; + double discriminant = b * b - 4 * a * c; + if (discriminant < 0.0) + { + res.numResults = 0; + } + else + { + double sqrt_discriminant = sqrt(discriminant); + double two_a = 2.0 * a; + if (sqrt_discriminant = 0.0) + { + res.numResults = 1; + res.results[0] = (-b) / two_a; + } + else + { + res.numResults = 2; + res.results[0] = (-b - sqrt_discriminant) / two_a; + res.results[1] = (-b + sqrt_discriminant) / two_a; + } + } + + return res; +} + + +/************************************************************************** + * CubicSolver methods * + *************************************************************************/ +CubicSolver::CubicSolver(double a, double b, double c, double d) + : Solver(a, b, c, d) +{ +} + +Solver::Result CubicSolver::solve() +{ +} + + +/************************************************************************** + * QuarticSolver methods * + *************************************************************************/ +QuarticSolver::QuarticSolver(double a, double b, double c, double d, double e) + : Solver(a, b, c, d, e) +{ +} + +Solver::Result QuarticSolver::solve() +{ +} diff --git a/util/Solver.h b/util/Solver.h new file mode 100644 index 0000000..3edc7b1 --- /dev/null +++ b/util/Solver.h @@ -0,0 +1,47 @@ + +#ifndef SOLVER_H +#define SOLVER_H SOLVER_H + +class Solver +{ + public: + typedef struct + { + int numResults; + double results[4]; + } Result; + + Solver(double a = 0.0, + double b = 0.0, + double c = 0.0, + double d = 0.0, + double e = 0.0); + virtual Result solve() = 0; + + protected: + double a, b, c, d, e; +}; + +class QuadraticSolver : public Solver +{ + public: + QuadraticSolver(double a, double b, double c); + Result solve(); +}; + +class CubicSolver : public Solver +{ + public: + CubicSolver(double a, double b, double c, double d); + Result solve(); +}; + +class QuarticSolver : public Solver +{ + public: + QuarticSolver(double a, double b, double c, double d, double e); + Result solve(); +}; + +#endif + diff --git a/util/Vector.cc b/util/Vector.cc new file mode 100644 index 0000000..b239769 --- /dev/null +++ b/util/Vector.cc @@ -0,0 +1,43 @@ + +#include "Vector.h" +#include +#include + +Vector::Vector() +{ + m_array[0] = 0.0; + m_array[1] = 0.0; + m_array[2] = 0.0; +} + +void Vector::normalize() +{ + double length = sqrt(m_array[0] * m_array[0] + + m_array[1] * m_array[1] + + m_array[2] * m_array[2]); + m_array[0] /= length; + m_array[1] /= length; + m_array[2] /= length; +} + +std::ostream & operator<<(std::ostream & out, const Vector & v) +{ + out << "[" << v[0] << ", " << v[1] << ", " << v[2] << "]"; + return out; +} + +/* Compute the dot-product of two vectors */ +double operator%(const Vector & v1, const Vector & v2) +{ + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; +} + +/* Compute the cross-product of two vectors */ +Vector operator*(const Vector & v1, const Vector & v2) +{ + Vector result; + result[0] = v1[1] * v2[2] - v1[2] * v2[1]; + result[1] = v1[2] * v2[0] - v1[0] * v2[2]; + result[2] = v1[0] * v2[1] - v1[1] * v2[0]; + return result; +} diff --git a/util/Vector.h b/util/Vector.h new file mode 100644 index 0000000..885df4f --- /dev/null +++ b/util/Vector.h @@ -0,0 +1,24 @@ + +#ifndef VECTOR_H +#define VECTOR_H VECTOR_H + +#include + +class Vector +{ + public: + Vector(); + ~Vector(); + double & operator[](int idx) { return m_array[idx]; } + double operator[](int idx) const { return m_array[idx]; } + void normalize(); + + private: + double m_array[3]; +}; + +std::ostream & operator<<(std::ostream & out, const Vector & v); +double operator%(const Vector & v1, const Vector & v2); +Vector operator*(const Vector & v1, const Vector & v2); + +#endif