CoordsysNode.cc

00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                              OpenFlipper                                  *
00004  *      Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openflipper.org                             *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------*
00008  *  This file is part of OpenFlipper.                                        *
00009  *                                                                           *
00010  *  OpenFlipper is free software: you can redistribute it and/or modify      *
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenFlipper is distributed in the hope that it will be useful,           *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenFlipper. If not,                                  *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/
00034 
00035 /*===========================================================================*\
00036  *                                                                           *
00037  *   $Revision: 7017 $                                                       *
00038  *   $Author: moebius $                                                      *
00039  *   $Date: 2009-09-09 09:15:50 +0200 (Mi, 09. Sep 2009) $                   *
00040  *                                                                           *
00041 \*===========================================================================*/
00042 
00043 
00044 
00045 
00046 //=============================================================================
00047 //
00048 //  CLASS CoordsysNode - IMPLEMENTATION
00049 //
00050 //=============================================================================
00051 
00052 //== INCLUDES =================================================================
00053 
00054 #include "CoordsysNode.hh"
00055 #include "../GL/gl.hh"
00056 #include <iostream>
00057 #include <math.h>
00058 
00059 
00060 //== NAMESPACES ===============================================================
00061 
00062 namespace ACG {
00063 namespace SceneGraph {
00064 
00065 
00066 //== IMPLEMENTATION ==========================================================
00067 
00068 
00069 void
00070 CoordsysNode::
00071 boundingBox(Vec3f& /*_bbMin*/, Vec3f& /*_bbMax*/)
00072 {
00073         //_bbMin.minimize( Vect3f  )
00074 }
00075 
00076 
00077 //----------------------------------------------------------------------------
00078 
00079 
00080 unsigned int
00081 CoordsysNode::
00082 availableDrawModes() const
00083 {
00084   return ( DrawModes::POINTS |
00085                 DrawModes::POINTS_SHADED |
00086                 DrawModes::POINTS_COLORED );
00087 }
00088 
00089 
00090 //----------------------------------------------------------------------------
00091 
00092 void
00093 CoordsysNode::
00094 drawCoordsys( GLState&  _state) {
00095 
00096   double topRadius = 0.01;
00097   double arrowLength = 0.04;
00098   double bodyRadius = 0.004;
00099   double bodyLength = 0.06;
00100   int slices = 10;
00101   int stacks = 10;
00102   int loops = 10;
00103   double sphereRadius = 0.01;
00104 
00105   GLUquadricObj *quadric = gluNewQuadric();
00106 
00107   // Origin
00108   glColor3f(0.5, 0.5, 0.5);
00109   gluSphere( quadric, sphereRadius, slices, stacks );
00110 
00111   // X-Axis
00112   glColor3f(1.0, 0.0, 0.0);
00113   _state.push_modelview_matrix ();
00114   _state.rotate (-90, 0, 1, 0);
00115   _state.translate ( 0, 0, -bodyLength );
00116   gluCylinder( quadric, bodyRadius, bodyRadius, bodyLength, slices, stacks );
00117   gluDisk( quadric, 0, topRadius, slices, loops );
00118   _state.translate ( 0, 0, -arrowLength );
00119   gluCylinder( quadric, 0, topRadius, arrowLength, slices, stacks );
00120   _state.pop_modelview_matrix ();
00121 
00122   // Y-Axis
00123   glColor3f(0.0, 1.0, 0.0);
00124   _state.push_modelview_matrix ();
00125   _state.rotate (90, 1, 0, 0);
00126   _state.translate ( 0, 0, -bodyLength );
00127   gluCylinder( quadric, bodyRadius, bodyRadius, bodyLength, slices, stacks );
00128   gluDisk( quadric, 0, topRadius, slices, loops );
00129   _state.translate ( 0, 0, -arrowLength );
00130   gluCylinder( quadric, 0, topRadius, arrowLength, slices, stacks );
00131   _state.pop_modelview_matrix ();
00132 
00133   // Z-Axis
00134   glColor3f(0.0, 0.0, 1.0);
00135   _state.push_modelview_matrix ();
00136   _state.rotate (180, 0, 1, 0);
00137   _state.translate ( 0, 0, -bodyLength );
00138   gluCylinder( quadric, bodyRadius, bodyRadius, bodyLength, slices, stacks );
00139   gluDisk( quadric, 0, topRadius, slices, loops );
00140   _state.translate ( 0, 0, -arrowLength );
00141   gluCylinder( quadric, 0, topRadius, arrowLength, slices, stacks );
00142   _state.pop_modelview_matrix ();
00143 
00144   gluDeleteQuadric(quadric);
00145 }
00146 
00147 //============================================================================
00148 
00149 void
00150 CoordsysNode::drawCoordsysPick( GLState&  _state) {
00151 
00152   double topRadius = 0.01;
00153   double arrowLength = 0.04;
00154   double bodyRadius = 0.004;
00155   double bodyLength = 0.06;
00156   int slices = 10;
00157   int stacks = 10;
00158   int loops = 10;
00159   double sphereRadius = 0.01;
00160 
00161   GLUquadricObj *quadric = gluNewQuadric();
00162 
00163   // Origin
00164   _state.pick_set_name (1);
00165   gluSphere( quadric, sphereRadius, slices, stacks );
00166 
00167   // X-Axis
00168   _state.pick_set_name (2);
00169   _state.push_modelview_matrix ();
00170   _state.rotate (-90, 0, 1, 0);
00171   _state.translate ( 0, 0, -bodyLength );
00172   gluCylinder( quadric, bodyRadius, bodyRadius, bodyLength, slices, stacks );
00173   gluDisk( quadric, 0, topRadius, slices, loops );
00174   _state.translate ( 0, 0, -arrowLength );
00175   gluCylinder( quadric, 0, topRadius, arrowLength, slices, stacks );
00176   _state.pop_modelview_matrix ();
00177 
00178   // Y-Axis
00179   _state.pick_set_name (3);
00180   _state.push_modelview_matrix ();
00181   _state.rotate (90, 1, 0, 0);
00182   _state.translate ( 0, 0, -bodyLength );
00183   gluCylinder( quadric, bodyRadius, bodyRadius, bodyLength, slices, stacks );
00184   gluDisk( quadric, 0, topRadius, slices, loops );
00185   _state.translate ( 0, 0, -arrowLength );
00186   gluCylinder( quadric, 0, topRadius, arrowLength, slices, stacks );
00187   _state.pop_modelview_matrix ();
00188 
00189   // Z-Axis
00190   _state.pick_set_name (4);
00191   _state.push_modelview_matrix ();
00192   _state.rotate (180, 0, 1, 0);
00193   _state.translate ( 0, 0, -bodyLength );
00194   gluCylinder( quadric, bodyRadius, bodyRadius, bodyLength, slices, stacks );
00195   gluDisk( quadric, 0, topRadius, slices, loops );
00196   _state.translate ( 0, 0, -arrowLength );
00197   gluCylinder( quadric, 0, topRadius, arrowLength, slices, stacks );
00198   _state.pop_modelview_matrix ();
00199 
00200 
00201   gluDeleteQuadric(quadric);
00202 
00203 }
00204 
00205 
00206 //============================================================================
00207 
00208 
00209 void
00210 CoordsysNode::
00211 draw(GLState&  _state  , unsigned int /*_drawMode*/)
00212 {
00213   GLboolean colorMask[4];
00214   glGetBooleanv (GL_COLOR_WRITEMASK, colorMask);
00215   
00216   // Push Modelview-Matrix
00217   _state.push_modelview_matrix();
00218 
00219   Vec4f lastBaseColor = _state.base_color();
00220 
00221   glPushAttrib( GL_LIGHTING_BIT ); // STACK_ATTRIBUTES <- LIGHTING_ATTRIBUTE
00222   glEnable(GL_LIGHTING);
00223   glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
00224   glEnable(GL_COLOR_MATERIAL);
00225   glShadeModel(GL_SMOOTH);
00226 
00227   // Init state - changes when mode_ != POSITION
00228   Vec3d pos3D(0.0,0.0,0.0);
00229 
00230   if ( mode_ == SCREENPOS ) {
00231 
00232     int left, bottom, width, height;
00233     double aspect = 1.0;
00234 
00235     _state.get_viewport(left, bottom, width, height);
00236 
00237     if (width && height)
00238       aspect = (double)width / (double)height;
00239 
00240     // Projection reset
00241     _state.push_projection_matrix();
00242     _state.reset_projection();
00243     _state.perspective(45.0, aspect, 0.8, 20.0);
00244 
00245     float posx = left + width - 30.0 ;
00246     float posy = bottom + height - 30.0 ;
00247 
00248     Vec3d screenposCenterPoint( posx , posy , 0.0);
00249 
00250     _state.push_modelview_matrix();
00251     _state.reset_modelview();
00252 
00253     // get our desired coordsys position in scene coordinates
00254     pos3D = _state.unproject (Vec3d (posx, posy, 0.5));
00255     _state.pop_modelview_matrix();
00256 
00257     // reset scene translation
00258     // we want only the scene rotation to rotate the coordsys
00259     GLMatrixd modelview = _state.modelview();
00260 
00261     modelview(0,3) = 0.0;
00262     modelview(1,3) = 0.0;
00263     modelview(2,3) = 0.0;
00264 
00265     _state.set_modelview (modelview);
00266     _state.translate (pos3D[0], pos3D[1], pos3D[2]-0.3, MULT_FROM_LEFT);
00267 
00268 
00269     // clear the depth buffer behind the coordsys
00270     glDepthRange (1.0, 1.0);
00271     glDepthFunc (GL_ALWAYS);
00272 
00273     drawCoordsys(_state);
00274 
00275     glDepthRange (0.0, 1.0);
00276     glDepthFunc (GL_LESS);
00277 
00278     // draw coordsys
00279     drawCoordsys(_state);
00280 
00281     // set depth buffer to 0 so tah nothing can paint over cordsys
00282     glDepthRange (0.0, 0.0);
00283     glDepthFunc (GL_ALWAYS);
00284     glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
00285 
00286     // Koordinatensystem zeichnen
00287     drawCoordsys(_state);
00288 
00289     glDepthRange (0.0, 1.0);
00290     glDepthFunc (GL_LESS);
00291     glColorMask (colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
00292 
00293     // Projection reload
00294     _state.pop_projection_matrix();
00295 
00296 
00297   } else if (mode_ == POSITION) { /* mode_ == POSITION */
00298 
00299     GLMatrixd modelview = _state.modelview();
00300 
00301     modelview(0,3) = 0.0;
00302     modelview(1,3) = 0.0;
00303     modelview(2,3) = 0.0;
00304 
00305     _state.set_modelview (modelview);
00306 
00307     // clear depth buffer in coordsys region
00308     glDepthRange (1.0, 1.0);
00309     glDepthFunc (GL_ALWAYS);
00310 
00311     // Koordinatensystem zeichnen
00312     drawCoordsys(_state);
00313 
00314     // draw coordsys in normal mode
00315     glDepthRange (0.0, 1.0);
00316     glDepthFunc (GL_LESS);
00317 
00318     // Koordinatensystem zeichnen
00319     drawCoordsys(_state);
00320 
00321     // set depth buffer to 0 so tah nothing can paint over cordsys
00322     glDepthRange (0.0, 0.0);
00323     glDepthFunc (GL_ALWAYS);
00324     glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
00325 
00326     // Koordinatensystem zeichnen
00327     drawCoordsys(_state);
00328 
00329     // reset to default
00330     glDepthRange (0.0, 1.0);
00331     glDepthFunc (GL_LESS);
00332     glColorMask (colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
00333 
00334   }
00335 
00336   glPopAttrib();
00337 
00338   glColor4fv(lastBaseColor.data());
00339 
00340   // Reload old configuration
00341   _state.pop_modelview_matrix();
00342 }
00343 
00344 
00345 void
00346 CoordsysNode::
00347 setMode(const CoordsysMode _mode)
00348 {
00349   mode_ = _mode;
00350 }
00351 
00352 void
00353 CoordsysNode::
00354 setPosition(const Vec3f& _pos)
00355 {
00356   pos3f_ = _pos;
00357 }
00358 
00359 CoordsysNode::CoordsysMode
00360 CoordsysNode::
00361 getMode() const
00362 {
00363   return mode_;
00364 }
00365 
00366 void
00367 CoordsysNode::pick(GLState& _state, PickTarget _target)
00368 {
00369   if (_target == PICK_ANYTHING) {
00370 
00371     GLdouble mat[16];
00372 
00373     // Push Modelview-Matrix
00374     _state.push_modelview_matrix();
00375     _state.pick_set_maximum (5);
00376     _state.pick_set_name (0);
00377 
00378     // Init state - changes when mode_ != POSITION
00379     Vec3d pos3D(0.0,0.0,0.0);
00380 
00381     if ( mode_ == SCREENPOS ) {
00382 
00383       int left, bottom, width, height;
00384       double aspect = 1.0;
00385 
00386       _state.get_viewport(left, bottom, width, height);
00387 
00388       if (width && height)
00389         aspect = (double)width / (double)height;
00390 
00391       // Projection reset
00392       _state.push_projection_matrix();
00393       _state.reset_projection();
00394       _state.perspective(45.0, aspect, 0.8, 20.0);
00395 
00396       float posx = left + width - 30.0 ;
00397       float posy = bottom + height - 30.0 ;
00398 
00399       Vec3d screenposCenterPoint( posx , posy , 0.0);
00400 
00401       _state.push_modelview_matrix();
00402       _state.reset_modelview();
00403 
00404       pos3D = _state.unproject (Vec3d (posx, posy, 0.5));
00405       _state.pop_modelview_matrix();
00406 
00407       // reset scene translation
00408       GLMatrixd modelview = _state.modelview();
00409 
00410       modelview(0,3) = 0.0;
00411       modelview(1,3) = 0.0;
00412       modelview(2,3) = 0.0;
00413 
00414       _state.set_modelview (modelview);
00415       _state.translate (pos3D[0], pos3D[1], pos3D[2]-0.3, MULT_FROM_LEFT);
00416 
00417       // We don't have access to the pick matrix used during selection buffer picking
00418       // so we can't draw our pick area circle in this case
00419       if (_state.color_picking ())
00420       {
00421         // clear depth buffer behind coordsys node
00422         clearPickArea(_state, true, 1.0);
00423 
00424         // Koordinatensystem zeichnen
00425         drawCoordsysPick(_state);
00426 
00427         // set depth buffer to 0.0 so that nothing can paint above
00428         clearPickArea(_state, false, 0.0);
00429       }
00430       else
00431       {
00432         // clear depth buffer in coordsys region
00433         glDepthRange (1.0, 1.0);
00434         glDepthFunc (GL_ALWAYS);
00435 
00436         // Koordinatensystem zeichnen
00437         drawCoordsys(_state);
00438 
00439         // draw coordsys in normal mode
00440         glDepthRange (0.0, 1.0);
00441         glDepthFunc (GL_LESS);
00442 
00443         // Koordinatensystem zeichnen
00444         drawCoordsys(_state);
00445 
00446         // set depth buffer to 0 so tah nothing can paint over cordsys
00447         glDepthRange (0.0, 0.0);
00448         glDepthFunc (GL_ALWAYS);
00449         glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
00450 
00451         // Koordinatensystem zeichnen
00452         drawCoordsys(_state);
00453 
00454         // reset to default
00455         glDepthRange (0.0, 1.0);
00456         glDepthFunc (GL_LESS);
00457         glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
00458       }
00459 
00460       // Projection reload
00461       _state.pop_projection_matrix();
00462 
00463     } else if (mode_ == POSITION) { /* mode_ == POSITION */
00464 
00465       // The selection buffer picking method might have set a 
00466       // pick matrix that has been multiplied with the projection matrix.
00467       // This is the only way to get the gl pick matrix again
00468       glMatrixMode(GL_PROJECTION);
00469 
00470       glPushMatrix ();
00471       glMultMatrixd( _state.inverse_projection().get_raw_data());
00472 
00473       glGetDoublev(GL_PROJECTION_MATRIX, mat);
00474 
00475       glPopMatrix ();
00476 
00477       GLMatrixd pickMat (mat);
00478 
00479       glMatrixMode(GL_MODELVIEW);
00480 
00481       GLMatrixd modelview = _state.modelview();
00482 
00483       modelview(0,3) = 0.0;
00484       modelview(1,3) = 0.0;
00485       modelview(2,3) = 0.0;
00486 
00487       // We don't have access to the pick matrix used during selection buffer picking
00488       // so we can't draw our pick area circle in this case
00489       if (_state.color_picking ())
00490       {
00491         // clear depth buffer behind coordsys node
00492         clearPickArea(_state, true, 1.0);
00493 
00494         // Koordinatensystem zeichnen
00495         drawCoordsysPick(_state);
00496 
00497         // set depth buffer to 0.0 so that nothing can paint above
00498         clearPickArea(_state, false, 0.0);
00499       }
00500       else
00501       {
00502         // clear depth buffer in coordsys region
00503         glDepthRange (1.0, 1.0);
00504         glDepthFunc (GL_ALWAYS);
00505 
00506         // Koordinatensystem zeichnen
00507         drawCoordsys(_state);
00508 
00509         // draw coordsys in normal mode
00510         glDepthRange (0.0, 1.0);
00511         glDepthFunc (GL_LESS);
00512 
00513         // Koordinatensystem zeichnen
00514         drawCoordsys(_state);
00515 
00516         // set depth buffer to 0 so tah nothing can paint over cordsys
00517         glDepthRange (0.0, 0.0);
00518         glDepthFunc (GL_ALWAYS);
00519         glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
00520 
00521         // Koordinatensystem zeichnen
00522         drawCoordsys(_state);
00523 
00524         // reset to default
00525         glDepthRange (0.0, 1.0);
00526         glDepthFunc (GL_LESS);
00527         glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
00528       }
00529     }
00530     // Reload old configuration
00531     _state.pop_modelview_matrix();
00532 
00533   }
00534 }
00535 
00536 //----------------------------------------------------------------------------
00537 
00538 void CoordsysNode::clearPickArea(GLState&  _state, bool _draw, GLfloat _depth)
00539 {
00540   std::vector<Vec2f> points;
00541   Vec2f center;
00542   float radius;
00543 
00544   int left, bottom, width, height;
00545   _state.get_viewport(left, bottom, width, height);
00546 
00547   GLboolean colorMask[4];
00548   glGetBooleanv (GL_COLOR_WRITEMASK, colorMask);
00549 
00550   GLUquadricObj *quadric = gluNewQuadric();
00551 
00552   // respect sphere radius
00553   Vec3d proj = _state.project (Vec3d (-0.01, -0.01, -0.01));
00554   points.push_back (Vec2f (proj[0], proj[1]));
00555 
00556   proj = _state.project (Vec3d (0.1, 0.0, 0.0));
00557   points.push_back (Vec2f (proj[0], proj[1]));
00558 
00559   proj = _state.project (Vec3d (0.0, 0.1, 0.0));
00560   points.push_back (Vec2f (proj[0], proj[1]));
00561 
00562   proj = _state.project (Vec3d (0.0, 0.0, 0.1));
00563   points.push_back (Vec2f (proj[0], proj[1]));
00564 
00565 
00566   // get bounding circle of projected 4 points of the coord node
00567   boundingCircle(points, center, radius);
00568 
00569   _state.push_projection_matrix();
00570   _state.reset_projection();
00571 
00572   _state.ortho (left, left + width, bottom, bottom + height, 0.0, 1.0);
00573 
00574   _state.push_modelview_matrix();
00575   _state.reset_modelview();
00576   glDepthFunc (GL_ALWAYS);
00577   glDepthRange (_depth, _depth);
00578   _state.translate (center[0], center[1], -0.5);
00579 
00580   if (_draw)
00581     _state.pick_set_name (0);
00582   else
00583     glColorMask(false, false, false, false);
00584 
00585   // 10% more to ensure everything is in
00586   gluDisk( quadric, 0, radius * 1.1, 10, 10 );
00587 
00588   glDepthFunc (GL_LESS);
00589   _state.pop_modelview_matrix();
00590   _state.pop_projection_matrix();
00591 
00592   glDepthRange (0.0, 1.0);
00593 
00594   if (!_draw)
00595     glColorMask (colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
00596 
00597   gluDeleteQuadric(quadric);
00598 }
00599 
00600 //----------------------------------------------------------------------------
00601 
00602 void CoordsysNode::boundingCircle(std::vector<Vec2f> &_in, Vec2f &_center, float &_radius)
00603 {
00604   if (_in.size () == 0)
00605     return;
00606   if (_in.size () < 2)
00607   {
00608     _center = _in[0];
00609     _radius = 0.0f;
00610     return;
00611   }
00612   bool found = false;
00613 
00614   // try all circumcircles of all possible lines
00615   for (unsigned int i = 0; i < _in.size () - 1; i++)
00616     for (unsigned int j = i + 1; j < _in.size (); j++)
00617     {
00618       Vec2f cen = (_in[i] + _in[j]) * 0.5;
00619       float rad = (_in[i] - cen).length ();
00620       bool allin = true;
00621 
00622       for (unsigned int k = 0; k < _in.size (); k++)
00623         if (k != i && k != j && (_in[k] - cen).length () > rad)
00624         {
00625           allin = false;
00626           break;
00627         }
00628 
00629       if (!allin)
00630         continue;
00631 
00632       if (found)
00633       {
00634         if (rad < _radius)
00635         {
00636           _center = cen;
00637           _radius = rad;
00638         }
00639       }
00640       else
00641       {
00642         found = true;
00643         _center = cen;
00644         _radius = rad;
00645       }
00646     }
00647 
00648   if (found)
00649     return;
00650 
00651   // try all circumcircles of all possible triangles
00652   for (unsigned int i = 0; i < _in.size () - 2; i++)
00653     for (unsigned int j = i + 1; j < _in.size () - 1; j++)
00654       for (unsigned int k = j + 1; k < _in.size (); k++)
00655       {
00656         float v = ((_in[k][0]-_in[j][0])*((_in[i][0]*_in[i][0])+(_in[i][1]*_in[i][1]))) +
00657                   ((_in[i][0]-_in[k][0])*((_in[j][0]*_in[j][0])+(_in[j][1]*_in[j][1]))) +
00658                   ((_in[j][0]-_in[i][0])*((_in[k][0]*_in[k][0])+(_in[k][1]*_in[k][1])));
00659         float u = ((_in[j][1]-_in[k][1])*((_in[i][0]*_in[i][0])+(_in[i][1]*_in[i][1]))) +
00660                   ((_in[k][1]-_in[i][1])*((_in[j][0]*_in[j][0])+(_in[j][1]*_in[j][1]))) +
00661                   ((_in[i][1]-_in[j][1])*((_in[k][0]*_in[k][0])+(_in[k][1]*_in[k][1])));
00662         float d = (_in[i][0]*_in[j][1])+(_in[j][0]*_in[k][1])+(_in[k][0]*_in[i][1]) -
00663                   (_in[i][0]*_in[k][1])-(_in[j][0]*_in[i][1])-(_in[k][0]*_in[j][1]);
00664         Vec2f cen(0.5 * (u/d), 0.5 * (v/d));
00665         float rad = (_in[i] - cen).length ();
00666         bool allin = true;
00667 
00668         for (unsigned int l = 0; l < _in.size (); l++)
00669           if (l != i && l != j && l != k && (_in[l] - cen).length () > rad)
00670           {
00671             allin = false;
00672             break;
00673           }
00674 
00675         if (!allin)
00676           continue;
00677 
00678         if (found)
00679         {
00680           if (rad < _radius)
00681           {
00682             _center = cen;
00683             _radius = rad;
00684           }
00685         }
00686         else
00687         {
00688           found = true;
00689           _center = cen;
00690           _radius = rad;
00691         }
00692       }
00693 }
00694 
00695 //=============================================================================
00696 } // namespace SceneGraph
00697 } // namespace ACG
00698 //=============================================================================

acg pic Project OpenFlipper, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .