00001
00006 #include <assert.h>
00007 #include <iostream>
00008 #include "misc.hh"
00009 #include "matrix.hh"
00010
00011 #ifndef GEOMETRY_HH
00012 #define GEOMETRY_HH
00013
00014 class Color;
00015 template <unsigned int n> class Point;
00016 template <unsigned int n> class Vector;
00017 template <unsigned int n> class Ray;
00018 template <unsigned int n> class Object;
00019 class Sphere;
00020
00026 class Color {
00027 public:
00029 Color() { data[0] = 0.0; data[1] = 0.0; data[2] = 0.0; }
00030
00035 Color (double r, double g, double b);
00036
00041 static Color makeRGB (double r, double g, double b) { return Color(r,g,b); }
00042
00047 static Color makeHSV (double h, double s, double v) {
00048 Color c; c.setHSV (h, s, v); return c;
00049 }
00050
00057 void setRGB (double r, double g, double b) {
00058 data[0] = r; data[1] = g; data[2] = b;
00059 }
00060
00067 void setHSV (double h, double s, double v);
00068
00070 const Color& operator+= (const Color &c);
00071
00073 const Color& operator*= (const Color &c);
00074
00076 const Color& operator*= (double s);
00077
00079 double operator[] (unsigned int i) const { assert (i < 3); return data[i]; }
00080
00085 const static Color BLACK;
00086 const static Color RED;
00087 const static Color GREEN;
00088 const static Color BLUE;
00089 const static Color WHITE;
00091 private:
00093 double data[3];
00094 };
00095
00101 inline Color operator+ (const Color &a, const Color &b)
00102 { Color c (a); c += b; return c; }
00103
00109 inline Color operator* (const Color &a, const Color &b)
00110 { Color c (a); c *= b; return c; }
00111
00117 inline Color operator* (const Color &a, double b)
00118 { Color c (a); c *= b; return c; }
00119
00125 inline Color operator* (double a, const Color &b)
00126 { Color c (b); c *= a; return c; }
00127
00131 template <unsigned int n>
00132 class Point {
00133 public:
00135 Point();
00136
00138 Point (const double data[n]);
00139
00141 double operator[] (unsigned int i) const
00142 { assert (i < n); return data(i,0); }
00143
00145 const Point<n>& operator+= (const Vector<n> &v)
00146 { data += v.getMatrix(); return *this; }
00147
00149 const Point<n>& operator-= (const Vector<n> &v)
00150 { data -= v.getMatrix(); return *this; }
00151
00153 const Matrix<n+1,1>& getMatrix() const { return data; }
00154 private:
00159 Matrix<n+1,1> data;
00160 };
00161
00167 template <unsigned int n>
00168 Point<n> operator+ (const Point<n> &a, const Vector<n> &b)
00169 { Point<n> r (a); r += b; return r; }
00170
00176 template <unsigned int n>
00177 Point<n> operator- (const Point<n> &a, const Vector<n> &b)
00178 { Point<n> r (a); r -= b; return r; }
00179
00184 template <unsigned int n>
00185 inline std::ostream& operator<< (std::ostream&, const Point<n>&);
00186
00190 template <unsigned int n>
00191 class Vector {
00193 template <unsigned int n2> friend Vector<n2> operator-
00194 (const Point<n2> &a, const Point<n2> &b);
00195 public:
00197 Vector() { assert (n > 0); }
00198
00200 Vector (const double data[n]);
00201
00203 double getLength() const;
00204
00210 const static double NORMAL_EPSILON;
00211
00219 bool isNormalized() const { return abs(getLength()-1.0) < NORMAL_EPSILON; }
00220
00227 void normalize();
00228
00233 void translateGL() const;
00234
00236 double operator[] (unsigned int i) const
00237 { assert (i < n); return data(i,0); }
00238
00240 const Vector<n>& operator*= (double d) { data *= d; return *this; }
00241
00243 const Vector<n>& operator/= (double d) { data /= d; return *this; }
00244
00246 const Vector<n>& operator+= (const Vector<n> &v)
00247 { data += v.data; return *this; }
00248
00250 const Vector<n>& operator-= (const Vector<n> &v)
00251 { data -= v.data; return *this; }
00252
00254 Vector<n> operator-() const;
00255
00257 const Matrix<n+1,1>& getMatrix() const { return data; }
00258 private:
00263 Matrix<n+1,1> data;
00264 };
00265
00270 template <unsigned int n>
00271 Vector<n> operator* (const Vector<n> &a, double b)
00272 { Vector<n> r (a); r *= b; return r; }
00273
00278 template <unsigned int n>
00279 Vector<n> operator/ (const Vector<n> &a, double b)
00280 { Vector<n> r (a); r /= b; return r; }
00281
00286 template <unsigned int n>
00287 Vector<n> operator* (double b, const Vector<n> &a)
00288 { Vector<n> r (a); r *= b; return r; }
00289
00294 template <unsigned int n>
00295 Vector<n> operator+ (const Vector<n> &a, const Vector<n> &b)
00296 { Vector<n> r (a); r += b; return r; }
00297
00302 template <unsigned int n>
00303 Vector<n> operator- (const Vector<n> &a, const Vector<n> &b)
00304 { Vector<n> r (a); r -= b; return r; }
00305
00310 template <unsigned int n>
00311 double operator* (const Vector<n> &a, const Vector<n> &b);
00312
00318 template <unsigned int n>
00319 inline std::ostream& operator<< (std::ostream&, const Vector<n>&);
00320
00324 template <unsigned int n>
00325 class Ray {
00326 public:
00331 Ray();
00332
00337 Ray (const Point<n> &start, const Vector<n> &dir) : start(start), dir(dir) {
00338 assert (n > 0);
00339 assert (dir.isNormalized());
00340 }
00341
00343 const Point<n>& getStart() const { return start; }
00344
00346 const Vector<n>& getDirection() const { return dir; }
00347
00349 Point<n> operator() (double d) const { return start + dir*d; }
00350 private:
00351 Point<n> start;
00352 Vector<n> dir;
00353 };
00354
00360 template <unsigned int n>
00361 std::ostream& operator<< (std::ostream&, const Ray<n>&);
00362
00366 template <unsigned int n>
00367 class Object {
00368 public:
00374 virtual Pair<double> getCoordRange (int axis) const = 0;
00375
00377 const static double INTERSECT_EPSILON;
00378
00388 virtual bool testIntersection (const Ray<n>&, double &d) const = 0;
00389
00395 virtual Vector<n> computeNormal (const Point<n>&) const = 0;
00396
00398 virtual void drawGL() const = 0;
00399
00401 const Color& getAmbient() const { return ambient; }
00402
00404 void setAmbient (const Color &newambient) { ambient = newambient; }
00405
00407 double getShininess() const { return shininess; }
00408
00413 void setShininess (double newshininess)
00414 { assert (shininess >= 0.0); shininess = newshininess; }
00415
00417 const Color& getDiffuse() const { return diffuse; }
00418
00420 void setDiffuse (const Color &newdiffuse) { diffuse = newdiffuse; }
00421
00423 const Color& getSpecular() const { return specular; }
00424
00426 void setSpecular (const Color &newspecular) { specular = newspecular; }
00427
00428 private:
00429 Color ambient;
00430 Color diffuse;
00431
00432 Color specular;
00433
00434 double shininess;
00435
00436 };
00437
00442 class Sphere : public Object<3> {
00443 public:
00445 Sphere (const Point<3> ¢er = Point<3>(), double radius = 1.0)
00446 : center(center), radius(radius) {}
00447
00448 Pair<double> getCoordRange (int axis) const;
00449 bool testIntersection (const Ray<3>&, double &d) const;
00450 Vector<3> computeNormal (const Point<3> &p) const
00451 { Vector<3> n (p-center); n.normalize(); return n; }
00452 void drawGL() const;
00453
00454 private:
00455 Point<3> center;
00456 double radius;
00457 };
00458
00463 class Light {
00464 public:
00465 Light (const Point<3> &position, const Color &ambient,
00466 const Color &diffuse, const Color &specular) :
00467 position(position), ambient(ambient), diffuse(diffuse),
00468 specular(specular) {}
00469
00470 const Point<3>& getPosition() const { return position; }
00471
00472 const Color& getAmbient() const { return ambient; }
00473 void setAmbient (const Color &newambient) { ambient = newambient; }
00474
00475 const Color& getDiffuse() const { return diffuse; }
00476 void setDiffuse (const Color &newdiffuse) { diffuse = newdiffuse; }
00477
00478 const Color& getSpecular() const { return specular; }
00479 void setSpecular (const Color &newspecular) { specular = newspecular; }
00480
00481 private:
00482 Point<3> position;
00483 Color ambient, diffuse, specular;
00484 };
00485
00486 #include "geometry.impl"
00487
00488 #endif // !GEOMETRY_HH