Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

glutm/shape.cpp

Go to the documentation of this file.
00001 #include "shape.h"
00002 
00007 #include <glutm/glut.h>
00008 
00009 #include <glt/error.h>
00010 
00011 #include <math/plane.h>
00012 #include <math/vector3.h>
00013 #include <math/matrix4.h>
00014 #include <math/volume.h>
00015 
00016 #include <vector>
00017 #include <cmath>
00018 #include <iostream>
00019 using namespace std;
00020 
00022 
00023 GlutSphere::GlutSphere(const bool solid,const GLdouble radius,const GLint slices,const GLint stacks)
00024 : GltShape(solid), _radius(radius), _slices(slices), _stacks(stacks)
00025 {
00026 }
00027 
00028 GlutSphere::~GlutSphere()
00029 {
00030 }
00031 
00032 void 
00033 GlutSphere::draw() const
00034 {
00035     GLERROR;
00036 
00037     glPushMatrix();
00038         transformation().glMultMatrix();
00039         glColor();
00040         if (solid())
00041             glutSolidSphere(_radius,_slices,_stacks);
00042         else
00043             glutWireSphere(_radius,_slices,_stacks);
00044     glPopMatrix();
00045 
00046     GLERROR;
00047 }
00048 
00049 GLdouble 
00050 GlutSphere::volume() const
00051 {
00052     return sphereVolume(_radius);
00053 }
00054 
00055 bool
00056 GlutSphere::inside(const Vector &pos) const
00057 {
00058     const Vector p = transformation().inverse()*pos;
00059     return (p*p)<_radius*_radius;
00060 }
00061 
00062 bool 
00063 GlutSphere::povrayExport(ostream &os) const
00064 {
00065     os << "sphere { ";
00066     Vector0.writePov(os) << ", " << _radius << endl;
00067     
00068 
00069     os << "pigment { color rgb ";
00070     color().writePov(os) << '}' << endl;
00071 
00072     transformation().writePov(os) << endl;
00073 
00074     os << "}" << endl;
00075 
00076     return true;
00077 }
00078 
00079 void 
00080 GlutSphere::boundingBox(BoundingBox &box) const
00081 {
00082     vector<Vector> p;
00083     p.reserve(8);
00084     p.push_back(Vector( _radius, _radius, _radius));
00085     p.push_back(Vector( _radius, _radius,-_radius));
00086     p.push_back(Vector( _radius,-_radius, _radius));
00087     p.push_back(Vector( _radius,-_radius,-_radius));
00088     p.push_back(Vector(-_radius, _radius, _radius));
00089     p.push_back(Vector(-_radius, _radius,-_radius));
00090     p.push_back(Vector(-_radius,-_radius, _radius));
00091     p.push_back(Vector(-_radius,-_radius,-_radius));
00092     transformPoints(p);
00093 
00094     box.reset();
00095     box += p;
00096 }
00097 
00098 void 
00099 GlutSphere::position(const Vector &pos,const double radius)
00100 {
00101     _radius = radius;
00102     transformation() = matrixTranslate(pos);
00103 }
00104 
00105 /*
00106 bool 
00107 GlutSphere::intersects(const GltShape &shape) const
00108 {
00109     // Find the bounding box of the other shape
00110 
00111     Vector min,max;
00112     if (!shape.boundingBox(min,max))
00113         return false;
00114 
00115     // Transform the verticies of bounding box 
00116     // to be relative to this sphere on the origin
00117 
00118     vector<Vector> p;
00119     boundingPoints(min,max,p);
00120 
00121     Matrix mat = transformation().inverse();
00122     for (int i=0; i<p.size(); i++)
00123         p[i] = mat * p[i];
00124 
00125     // Find a new bounding box, relative to
00126     // this sphere, untransformed.
00127 
00128     if (!GltShape::boundingBox(min,max,p))
00129         return false;
00130 
00131     // Quick check against the bounding box of the sphere
00132 
00133     if (min[0]>_radius || min[1]>_radius || min[2]>_radius)
00134         return false;
00135 
00136     if (max[0]<-_radius || max[1]<-_radius || max[2]<-_radius)
00137         return false;
00138 
00139     // More exacting check
00140 
00141     boundingPoints(min,max,p);
00142     for (i=0; i<p.size(); i++)
00143     {
00144         // Form a plane on the surface
00145         // of the sphere between the origin
00146         // and the point on the box.  If
00147         // all points on the box are on the
00148         // "outside" of the plane, then the
00149         // box doesn't intersect the sphere.
00150 
00151         const Vector n = p[i];
00152         const double l = n.norm();
00153 
00154         // If a point of the box is inside the
00155         // circle, then there is an intersection.
00156 
00157         if (l<_radius)
00158             return true;
00159 
00160         Plane plane(n/l*_radius,n);
00161 
00162         bool allOutside = true;
00163         for (int j=0; j<p.size(); j++)
00164             if (!plane.inside(p[j]))
00165             {
00166                 allOutside =false;
00167                 break;
00168             }
00169 
00170         if (allOutside)
00171             return false;
00172     }
00173 
00174     return true;
00175 }
00176 */
00177 
00178       GLdouble &GlutSphere::radius()       { return _radius; }
00179       GLint    &GlutSphere::slices()       { return _slices; }
00180       GLint    &GlutSphere::stacks()       { return _stacks; }
00181 
00182 const GLdouble &GlutSphere::radius() const { return _radius; }
00183 const GLint    &GlutSphere::slices() const { return _slices; }
00184 const GLint    &GlutSphere::stacks() const { return _stacks; }
00185 
00186 
00188 
00189 GlutCube::GlutCube(const bool solid,const GLdouble size)
00190 : GltShape(solid), _size(size)
00191 {
00192 }
00193 
00194 GlutCube::GlutCube(const bool solid,const Vector &min,const Vector &max)
00195 : GltShape(solid), _size(1.0)
00196 {
00197     position(min,max);
00198 }
00199 
00200 GlutCube::~GlutCube()
00201 {
00202 }
00203 
00204 void 
00205 GlutCube::draw() const
00206 {
00207     GLERROR;
00208 
00209     glPushMatrix();
00210         transformation().glMultMatrix();
00211         glColor();
00212         if (solid())
00213             glutSolidCube(_size);
00214         else
00215             glutWireCube(_size);
00216     glPopMatrix();
00217 
00218     GLERROR;
00219 }
00220 
00221 GLdouble 
00222 GlutCube::volume() const
00223 {
00224     return boxVolume(_size,_size,_size);
00225 }
00226 
00227 void 
00228 GlutCube::boundingBox(BoundingBox &box) const
00229 {
00230     const real size = _size*0.5;
00231 
00232     vector<Vector> p;
00233     p.reserve(8);
00234     p.push_back(Vector( size, size, size));
00235     p.push_back(Vector( size, size,-size));
00236     p.push_back(Vector( size,-size, size));
00237     p.push_back(Vector( size,-size,-size));
00238     p.push_back(Vector(-size, size, size));
00239     p.push_back(Vector(-size, size,-size));
00240     p.push_back(Vector(-size,-size, size));
00241     p.push_back(Vector(-size,-size,-size));
00242     transformPoints(p);
00243 
00244     box.reset();
00245     box += p;
00246 }
00247 
00248 bool 
00249 GlutCube::povrayExport(ostream &os) const
00250 {
00251     os << "box { ";
00252     (Vector1*_size* 0.5).writePov(os) << ", ";
00253     (Vector1*_size*-0.5).writePov(os) << endl;
00254 
00255     os << "pigment { color rgb ";
00256     color().writePov(os) << '}' << endl;
00257 
00258     transformation().writePov(os) << endl;
00259 
00260     os << "}" << endl;
00261 
00262     return true;
00263 }
00264 
00265 void 
00266 GlutCube::position(const Vector &min,const Vector &max)
00267 {
00268     _size = 1.0;
00269 
00270     const Vector center = (min+max)*0.5;
00271     Vector size = max-min;
00272     size.abs();
00273 
00274     transformation() = matrixScale(size) * matrixTranslate(center);
00275 }
00276 
00277 void 
00278 GlutCube::position(const Vector &pos,const real width,const real height,const real depth)
00279 {
00280     _size = 1.0;
00281     Vector size(width,height,depth);
00282     size.abs();
00283     size *= 0.5;
00284 
00285     transformation() = 
00286         matrixScale(size) *
00287         matrixTranslate(pos);
00288 }
00289 
00290       GLdouble &GlutCube::size()       { return _size; }
00291 const GLdouble &GlutCube::size() const { return _size; }
00292 
00294 
00295 GlutCylinder::GlutCylinder(const bool solid,const GLdouble radius,const GLdouble height,const GLint slices,const GLint stacks,const GLint loops)
00296 : GltShape(solid), _radius(radius), _height(height), _slices(slices), _stacks(stacks), _loops(loops)
00297 {
00298 }
00299 
00300 GlutCylinder::~GlutCylinder()
00301 {
00302 }
00303 
00304 void 
00305 GlutCylinder::draw() const
00306 {
00307     // Well, GLUT doesn't have cylinder, so we resort
00308     // to glu quadric
00309 
00310     GLERROR;
00311 
00312     glPushMatrix();
00313         transformation().glMultMatrix();
00314         glColor();
00315         GLUquadricObj *quadObj = gluNewQuadric();
00316         gluQuadricDrawStyle(quadObj, (GLenum) (solid() ? GLU_FILL : GLU_SILHOUETTE));
00317         gluQuadricNormals(quadObj, (GLenum) GLU_SMOOTH);
00318         gluQuadricOrientation(quadObj, (GLenum) GLU_OUTSIDE);
00319         gluCylinder(quadObj, _radius, _radius, _height, _slices,_stacks);
00320         if (solid())
00321         {
00322             gluQuadricOrientation(quadObj, (GLenum) GLU_INSIDE);
00323             gluDisk(quadObj,0.0,_radius,_slices,_loops);
00324             glTranslatef(0.0,0.0,_height);
00325             glRotatef(180,0.0,1.0,0.0);
00326             gluDisk(quadObj,0.0,_radius,_slices,_loops);
00327         }
00328         gluDeleteQuadric(quadObj);
00329     glPopMatrix();
00330 
00331     GLERROR;
00332 }
00333 
00334 GLdouble 
00335 GlutCylinder::volume() const
00336 {
00337     return cylinderVolume(_radius,_height);
00338 }
00339 
00340 void 
00341 GlutCylinder::boundingBox(BoundingBox &box) const
00342 {
00343     vector<Vector> p;
00344     p.reserve(8);
00345     p.push_back(Vector( _radius, _radius, 0));
00346     p.push_back(Vector( _radius,-_radius, 0));
00347     p.push_back(Vector(-_radius, _radius, 0));
00348     p.push_back(Vector(-_radius,-_radius, 0));
00349     p.push_back(Vector( _radius, _radius, _height));
00350     p.push_back(Vector( _radius,-_radius, _height));
00351     p.push_back(Vector(-_radius, _radius, _height));
00352     p.push_back(Vector(-_radius,-_radius, _height));
00353     transformPoints(p);
00354 
00355     box.reset();
00356     box += p;
00357 }
00358 
00359 bool 
00360 GlutCylinder::povrayExport(ostream &os) const
00361 {
00362     os << "cylinder { ";
00363     Vector0          .writePov(os) << ", ";
00364     (VectorZ*_height).writePov(os) << ", " << _radius << endl;
00365 
00366     os << "pigment { color rgb ";
00367     color().writePov(os) << '}' << endl;
00368 
00369     transformation().writePov(os) << endl;
00370 
00371     os << "}" << endl;
00372 
00373     return true;
00374 }
00375 
00376 void 
00377 GlutCylinder::position(const Vector &begin,const Vector &end,const double radius)
00378 {
00379     Vector dir  = end - begin;
00380 
00381     _radius = radius;
00382     _height = dir.length();
00383     dir.normalize();
00384 
00385     // Create new co-ordinate system
00386     // with [0,0,1] in direction of end,
00387     // [1,0,0] and [0,1,0] mutually orthogonal.
00388 
00389     if (fabs(dir.z())>0.8)
00390     {
00391         const Vector a = xProduct(dir,VectorY);
00392         const Vector b = xProduct(dir,a);
00393         transformation() = matrixOrient(a/a.length(),b/b.length(),dir);
00394     }
00395     else
00396     {
00397         const Vector a = xProduct(dir,VectorZ);
00398         const Vector b = xProduct(dir,a);
00399         transformation() = matrixOrient(a/a.length(),b/b.length(),dir);
00400     }
00401 
00402     transformation() = transformation() * matrixTranslate(begin);
00403 }
00404 
00405       GLdouble &GlutCylinder::radius()       { return _radius; }
00406       GLdouble &GlutCylinder::height()       { return _height; }
00407       GLint    &GlutCylinder::slices()       { return _slices; }
00408       GLint    &GlutCylinder::stacks()       { return _stacks; }
00409       GLint    &GlutCylinder::loops()        { return _loops; }
00410 
00411 const GLdouble &GlutCylinder::radius() const { return _radius; }
00412 const GLdouble &GlutCylinder::height() const { return _height; }
00413 const GLint    &GlutCylinder::slices() const { return _slices; }
00414 const GLint    &GlutCylinder::stacks() const { return _stacks; }
00415 const GLint    &GlutCylinder::loops()  const { return _loops;  }
00416 
00418 
00419 GlutCone::GlutCone(const bool solid,const GLdouble base,const GLdouble height,const GLint slices,const GLint stacks)
00420 : GltShape(solid), _base(base), _height(height), _slices(slices), _stacks(stacks)
00421 {
00422 }
00423 
00424 GlutCone::~GlutCone()
00425 {
00426 }
00427 
00428 void 
00429 GlutCone::draw() const
00430 {
00431     GLERROR;
00432 
00433     glPushMatrix();
00434         transformation().glMultMatrix();
00435         glColor();
00436         if (solid())
00437             glutSolidCone(_base,_height,_slices,_stacks);
00438         else
00439             glutWireCone(_base,_height,_slices,_stacks);
00440     glPopMatrix();
00441 
00442     GLERROR;
00443 }
00444 
00445 GLdouble 
00446 GlutCone::volume() const
00447 {
00448     return coneVolume(_base,_height);
00449 }
00450 
00451 void 
00452 GlutCone::boundingBox(BoundingBox &box) const
00453 {
00454     vector<Vector> p;
00455     p.reserve(8);
00456     p.push_back(Vector( _base, _base, 0));
00457     p.push_back(Vector( _base,-_base, 0));
00458     p.push_back(Vector(-_base, _base, 0));
00459     p.push_back(Vector(-_base,-_base, 0));
00460     p.push_back(Vector(     0,     0, _height));
00461     transformPoints(p);
00462 
00463     box.reset();
00464     box += p;
00465 }
00466 
00467       GLdouble &GlutCone::base()         { return _base;   }
00468       GLdouble &GlutCone::height()       { return _height; }
00469       GLint    &GlutCone::slices()       { return _slices; }
00470       GLint    &GlutCone::stacks()       { return _stacks; }
00471 
00472 const GLdouble &GlutCone::base() const   { return _base;   }
00473 const GLdouble &GlutCone::height() const { return _height; }
00474 const GLint    &GlutCone::slices() const { return _slices; }
00475 const GLint    &GlutCone::stacks() const { return _stacks; }
00476 
00478 
00479 GlutTorus::GlutTorus(const bool solid,const GLdouble innerRadius,const GLdouble outerRadius,const GLint nsides,const GLint rings)
00480 : GltShape(solid), _innerRadius(innerRadius), _outerRadius(outerRadius), _nsides(nsides), _rings(rings)
00481 {
00482 }
00483 
00484 GlutTorus::~GlutTorus()
00485 {
00486 }
00487 
00488 void 
00489 GlutTorus::draw() const
00490 {
00491     GLERROR;
00492 
00493     glPushMatrix();
00494         transformation().glMultMatrix();
00495         glColor();
00496         if (solid())
00497             glutSolidTorus(_innerRadius,_outerRadius,_nsides,_rings);
00498         else
00499             glutWireTorus(_innerRadius,_outerRadius,_nsides,_rings);
00500     glPopMatrix();
00501 
00502     GLERROR;
00503 }
00504 
00505       GLdouble &GlutTorus::innerRadius()       { return _innerRadius; }
00506       GLdouble &GlutTorus::outerRadius()       { return _outerRadius; }
00507       GLint    &GlutTorus::nsides()            { return _nsides;      }
00508       GLint    &GlutTorus::rings()             { return _rings;       }
00509 
00510 const GLdouble &GlutTorus::innerRadius() const { return _innerRadius; }
00511 const GLdouble &GlutTorus::outerRadius() const { return _outerRadius; }
00512 const GLint    &GlutTorus::nsides()      const { return _nsides;      }
00513 const GLint    &GlutTorus::rings()       const { return _rings;       }
00514 
00516 
00517 GlutDodecahedron::GlutDodecahedron(const bool solid)
00518 : GltShape(solid)
00519 {
00520 }
00521 
00522 GlutDodecahedron::~GlutDodecahedron()
00523 {
00524 }
00525 
00526 void 
00527 GlutDodecahedron::draw() const
00528 {
00529     GLERROR;
00530 
00531     glPushMatrix();
00532         transformation().glMultMatrix();
00533         glColor();
00534         if (solid())
00535             glutSolidDodecahedron();
00536         else
00537             glutWireDodecahedron();
00538     glPopMatrix();
00539 
00540     GLERROR;
00541 }
00542 
00544 
00545 GlutOctahedron::GlutOctahedron(const bool solid)
00546 : GltShape(solid)
00547 {
00548 }
00549 
00550 GlutOctahedron::~GlutOctahedron()
00551 {
00552 }
00553 
00554 void 
00555 GlutOctahedron::draw() const
00556 {
00557     GLERROR;
00558 
00559     glPushMatrix();
00560         transformation().glMultMatrix();
00561         glColor();
00562         if (solid())
00563             glutSolidOctahedron();
00564         else
00565             glutWireOctahedron();
00566     glPopMatrix();
00567 
00568     GLERROR;
00569 }
00570 
00572 
00573 GlutTetrahedron::GlutTetrahedron(const bool solid)
00574 : GltShape(solid)
00575 {
00576 }
00577 
00578 GlutTetrahedron::~GlutTetrahedron()
00579 {
00580 }
00581 
00582 void 
00583 GlutTetrahedron::draw() const
00584 {
00585     GLERROR;
00586 
00587     glPushMatrix();
00588         transformation().glMultMatrix();
00589         glColor();
00590         if (solid())
00591             glutSolidTetrahedron();
00592         else
00593             glutWireTetrahedron();
00594     glPopMatrix();
00595 
00596     GLERROR;
00597 }
00598 
00600 
00601 GlutIcosahedron::GlutIcosahedron(const bool solid)
00602 : GltShape(solid)
00603 {
00604 }
00605 
00606 GlutIcosahedron::~GlutIcosahedron()
00607 {
00608 }
00609 
00610 void 
00611 GlutIcosahedron::draw() const
00612 {
00613     GLERROR;
00614 
00615     glPushMatrix();
00616         transformation().glMultMatrix();
00617         glColor();
00618         if (solid())
00619             glutSolidIcosahedron();
00620         else
00621             glutWireIcosahedron();
00622     glPopMatrix();
00623 
00624     GLERROR;
00625 }
00626 
00628 
00629 GlutTeapot::GlutTeapot(const bool solid,const GLdouble size)
00630 : GltShape(solid), _size(size)
00631 {
00632 }
00633 
00634 GlutTeapot::~GlutTeapot()
00635 {
00636 }
00637 
00638 void 
00639 GlutTeapot::draw() const
00640 {
00641     GLERROR;
00642 
00643     glPushMatrix();
00644         transformation().glMultMatrix();
00645         glColor();
00646         if (solid())
00647             glutSolidTeapot(_size);
00648         else
00649             glutWireTeapot(_size);
00650     glPopMatrix();
00651 
00652     GLERROR;
00653 }
00654 
00655       GLdouble &GlutTeapot::size()       { return _size; }
00656 const GLdouble &GlutTeapot::size() const { return _size; }
00657 

Generated on Tue Nov 5 11:11:04 2002 for GLT by doxygen1.2.18