topical media & game development

talk show tell print

basic-visual-08-Orient2D.c

? / basic-visual-08-Orient2D.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: Orient2D.cpp
  // 
  // Description: 2D Orientation predicate demo with visualization in OpenGL
  // ------------------------------------------------------------------------
  
  include <stdafx.h>
  include <windows.h>
  include <GL/gl.h>
  include <GL/glut.h>
  
  using namespace std;
  
  define W 800
  define H 800
  
  define CW 1
  define CCW -1
  define ON 0
  
  int sign;
  
  inline float drand(){return rand()/(double)RAND_MAX;}
  
  class Point2D{
  public: double x,y;
  
                  Point2D::Reset()
                  {x=drand();y=drand();}
  
                  Point2D::Point2D()
                  {Reset();}
  };
  
  // Orientation test: 2x2 determinant sign
  // This is not the best bound but enough for this screen demo.
  define ERR 1.0e-6
  
  int Orient2D( const Point2D& p, const Point2D& q, const Point2D& r)
    {
            if ((q.x-p.x)*(r.y-p.y) > (r.x-p.x)*(q.y-p.y)+ERR) return CCW;
             if ((q.x-p.x)*(r.y-p.y) < (r.x-p.x)*(q.y-p.y)-ERR) return CW;
  
     return ON;
    }
  
    Point2D p,q,r;
    
  
  void disp( void ) 
  {
          char buffer[256];
  
  glClearColor(1,1,1,1);
  glClear(GL_COLOR_BUFFER_BIT);
  
  if (sign==ON) {glColor3f(1,0,0);sprintf(buffer,"Degenerate case: collinearity");}
  if (sign==CW) {glColor3f(0,1,0);sprintf(buffer,"Clockwise order of P,Q,R");}
  if (sign==CCW) {glColor3f(0,0,1);sprintf(buffer,"Counterclockwise order of P,Q,R");}
  
  if (sign!=ON){
  glBegin(GL_TRIANGLES);
  glVertex2f(p.x,p.y);
  glVertex2f(q.x,q.y);
  glVertex2f(r.x,r.y);
  glEnd();}
  else
  {
  glBegin(GL_LINE_LOOP);
  glVertex2f(p.x,p.y);
  glVertex2f(q.x,q.y);
  glVertex2f(r.x,r.y);
  glEnd();
  }
  
  glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glOrtho (0.0, W, 0.0, H, -1.0, 1.0);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
  
    glColor3f (0, 0, 0);
  
    glRasterPos2f(W*p.x,H*p.y);
     glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'P');
  
     glRasterPos2f(W*q.x,H*q.y);
     glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'Q');
  
     glRasterPos2f(W*r.x,H*r.y);
     glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, 'R');
  
     glRasterPos2f(50,H-50);
     for(int i=0;buffer[i]!=0;i++)
     glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, buffer[i]);
  
     glRasterPos2f(50,30);
     sprintf(buffer,"Press any key for another point sequence sample.");
     for(int i=0;buffer[i]!=0;i++)
     glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, buffer[i]);
  
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();      
  
          glFlush();
  }
  
  void key(unsigned char key , int x , int y) 
  {
  
  p.Reset();
  q.Reset();
  if (drand()<0.5) 
          {double lambda=drand();
          r.x=lambda*p.x+(1.0-lambda)*q.x;
          r.y=lambda*p.y+(1.0-lambda)*q.y;
          }
  else
  r.Reset();
  
  sign=Orient2D(p,q,r);
  glutPostRedisplay(); 
  }
  
  int _tmain(int argc, _TCHAR* argv[])
  {
  
          glutInit(&argc , argv);
          glutInitWindowPosition(50,50);
          glutInitWindowSize(W,H);
          glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
  
          glutCreateWindow("Orientation test demo: Predicate Orient2D.");
          glutDisplayFunc(disp);
          srand(2005);
  
          
          cout<<"Visual Computing: Geometry, Graphics, and Vision (ISBN:1-58450-427-7)"<<endl;
          cout<<"Demo program\n\n"<<endl;
  
          cout<<"Visualize the orientation tests Orient2D."<<endl;
  
          glMatrixMode(GL_PROJECTION);
          glLoadIdentity();
          glOrtho(0,1,0,1,-1,1);
          glMatrixMode(GL_MODELVIEW);
          glutKeyboardFunc(key);
          sign=Orient2D(p,q,r);
          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.