topical media & game development

talk show tell print

basic-visual-02-traits-geometrykernel.c

? / basic-visual-02-traits-geometrykernel.c


  // ------------------------------------------------------------------------
  // This program is complementary material for the book:
  //
  // Frank Nielsen
  //
  // Visual Computing: Geometry, Graphics, and Vision
  //
  // ISBN: 1-58450-427-7
  //
  // Charles River Media, Inc.
  //
  //
  // All programs are available at www.charlesriver.com/visualcomputing/
  //
  // You may use this program for ACADEMIC and PERSONAL purposes ONLY. 
  //
  //
  // The use of this program in a commercial product requires EXPLICITLY
  // written permission from the author. The author is NOT responsible or 
  // liable for damage or loss that may be caused by the use of this program. 
  //
  // Copyright (c) 2005. Frank Nielsen. All rights reserved.
  // ------------------------------------------------------------------------
   
  // ------------------------------------------------------------------------
  // File: traits-geometrykernel.cpp
  // 
  // Description: Compute the convex hull of a 2D point set using Andrew's algorithm.
  // The geometric kernel (arithmetic+predicate) is given to a traits class.
  // ------------------------------------------------------------------------
  
  // This code has been adapted from an original code of Lutz Kettner 
  
  include <stdafx.h>
  include <vector>
  include <queue>
  include <algorithm>
  include <windows.h>
  include <GL/gl.h>
  include <GL/glut.h>
  
  define W 800
  define H 800
  
  // Notice: This code is not robust. See Chapter "Robustness"
  
  using namespace std;
  
  template <class NumberType> class Point2D {
  public:
      NumberType x;
      NumberType y;
  
  bool operator <  ( const Point2D<NumberType> & rhs)
  {return (x<rhs.x);}
  
  bool operator >  (const Point2D<NumberType> & rhs)
  {return (x>rhs.x);}
  
  bool operator ==  (const Point2D<NumberType> & rhs)
  {return (x==rhs.x);}
  
   
  };
  
  template <class NumberType> struct ConvexHullTraits
  {
      typedef Point2D<NumberType> Point;
  
      struct Leftturn {
          bool operator()( const Point& p, const Point& q, const Point& r)
                  {
                          if ((q.x-p.x) * (r.y-p.y) >(r.x-p.x) * (q.y-p.y)) return true;
                          else return false;
          }
      };
  
      Leftturn leftturn() const { return Leftturn(); }
  };
  
  template <class BidirectionalIterator, class OutputIterator, class ConvexHullTraits>
  OutputIterator 
  ConvexHull( BidirectionalIterator first, BidirectionalIterator beyond,
               OutputIterator result, const ConvexHullTraits& traits) {
      typedef typename ConvexHullTraits::Point Point;
      vector<Point> hull;
      hull.push_back( *first); 
      hull.push_back( *first);
  
          // First compute the  lower convex hull 
      BidirectionalIterator i = first;
      for ( ++i; i != beyond; ++i) {
          while ( traits.leftturn()( hull.end()[-2], *i, hull.back()))
              hull.pop_back();
          hull.push_back( *i);
      }
  
      // Now compute the upper convex hull 
      i = beyond;
      for ( --i; i != first; ) {
          --i;
          while ( traits.leftturn()( hull.end()[-2], *i, hull.back()))
              hull.pop_back();
          hull.push_back( *i);
      }
  
      // Finally, get the full convex hull (intersection of lower and upper hulls)
      hull.pop_back();
      hull.front() = hull.back();
      hull.pop_back();
      return copy( hull.begin(), hull.end(), result);
  }
  
  define N 150
  
  Point2D<double> point;
  priority_queue<Point2D<double> >  q;
  vector<Point2D<double> > set,  result;
  ConvexHullTraits<double> MyConvexHullPolicy;
  
  inline double drand()
  {
  return 0.1+0.8*(rand()/(double)RAND_MAX);
  }
  
  void disp( void ) 
  {
  int i;
  
  glClearColor(1,1,1,1);
  glClear(GL_COLOR_BUFFER_BIT);
  
  glColor3f(0,0,1);
  glPointSize(2);
  glBegin(GL_POINTS);
  for(i=0;i<N;i++)
  glVertex2f(set[i].x,set[i].y);
  glEnd();
  
  glColor3f(1,0,0);
  glBegin(GL_LINE_LOOP);
  for(i=0;i<result.size();i++)
  glVertex2f(result[i].x,result[i].y);
  glEnd();
  
  glFlush();
  }
  
  void key(unsigned char key , int x , int y) 
  {
  
          set.clear();
          result.clear();
  
  for(int i=0;i<N;i++)
          {
          point.x=drand();
          point.y=drand();
          set.push_back(point);
          }
  
          sort(set.begin(),set.end());
  
  ConvexHull(set.begin(), set.end(), back_inserter(result), MyConvexHullPolicy);
  cout<<"Number of extreme points on the hull:"<<result.size()<<endl;
  
  glutPostRedisplay(); 
  }
  
  int _tmain(int argc, _TCHAR* argv[])
  {
          
          cout<<"Visual Computing: Geometry, Graphics, and Vision (ISBN:1-58450-427-7)"<<endl;
          cout<<"Demo program\n\n"<<endl;
  
          cout<<"Geometric traits class using STL."<<endl;
  
          glutInit(&argc , argv);
          glutInitWindowPosition(50,50);
          glutInitWindowSize(W,H);
          glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
  
          glutCreateWindow("Convex Hull (Geometric Traits Class)| Push any key for another set");
          glutDisplayFunc(disp);
  
          srand(2005);
          glMatrixMode(GL_PROJECTION);
          glLoadIdentity();
          glOrtho(0,1,0,1,-1,1);
          glMatrixMode(GL_MODELVIEW);
          
          glutKeyboardFunc(key);
          key(0,0,0);
          glutMainLoop();
  
          return 0;
  }
  
  


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.