1

More Drawing Tools

  1. Handy Functions to set World Windows and Viewports

//------setWindow ------
void setWindow (float left, float right, float bottom, float top)
{
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluOrtho2D ((GLdouble)1eft, (GLdouble)right, (GLdouble)bottom, (GLdouble)top);
}
//------setViewport ------
void setViewport (int left, int right, int bottom, int top)
{
glViewport(left, bottom, right - left, top - bottom );
}

We may use these functions to automatically set World Window and Viewport

Aspect ratio of a rectangle = / width
-----
height

Suppose world window has aspect ratio R, screen window has width W and height H

  1. R > W/H
    world window is relatively short and wide, so

setViewport ( 0, W, 0, W/R );

  1. R < W/H
    world window is relatively tall and narrow, so

setViewport ( 0, H * R, 0, H );

We can resize the window by

glutReshapeFunc ( myReshape );

void myReshape( GLsize W, GLsizei H )
{
if ( R > W/H ) //use global aspect ratio R
setViewport( 0, W, 0, W/R );
else
setViewport( 0, H * R, 0, H );
}
  1. Developing the Canvas Calss
  2. Supporting classes

class Point2: A Point with Real Coordinates

// Support Classes for Canvas
class Point2 //single point w/ floating point coordinates
{
public:
Point2(); //contructor 1
Point2(float xx, float yy); //constructor 2
void set(float xx, float yy);
float getX();
float getY();
void draw(void);
private:
float x, y;
};
//constructor 1
Point2::Point2()
{
x = y = 0.0f;
}
//constructor 2
Point2::Point2(float xx, float yy)
{
x=xx; y=yy;
}
void Point2::set(float xx, float yy)
{
x=xx; y=yy;
}
float Point2::getX()
{
return x;
}
float Point2::getY()
{
return y;
}
void Point2::draw(void)
{
glBegin(GL_POINTS); //draw this point
glVertex2f((GLfloat)x, (GLfloat)y);
glEnd();
}

class RealRect: A rectangle class with real coordinates

//world window rectangle class
class RealRect
{
public:
RealRect(); //constructors
RealRect(float left, float right, float bottom, float top);
void set(float left, float right, float bottom, float top);
float getL(void); //left boundary
float getR(void); //right
float getT(void);
float getB(void);
void draw(void); //draw this rectangle using OpenGL
private:
float l, r, b, t;
};
//constructors
RealRect::RealRect()
{
l = 0; r=100; b=0; t=100;
}
RealRect::RealRect(float left, float right, float bottom, float top)
{
l = left; r=right; b=bottom; t=top;
}
void RealRect::set(float left, float right, float bottom, float top)
{
l=left; r=right; b=bottom; t=top;
}
float RealRect::getL(void) //left boundary
{
return l;
}
float RealRect::getR(void) //right
{
return r;
}
float RealRect::getT(void)
{
return t;
}
float RealRect::getB(void)
{
return b;
}
void RealRect::draw(void)
{
glRectf( l, b, r, t);
}
  1. Class Canvas Interface

class Canvas
{
public:
Canvas(int width, int height, char* windowTitle); //constructor
void setWindow(float l, float r, float b, float t);
void setViewport(int l, int r, int b, int t);
IntRect getViewport(void); //divulge the viewport data
RealRect getWindow(void); // divulge the window data
float getWindowAspectRatio(void);
void clearScreen();
void setBackgroundColor(float r, float g, float b);
void setColor(float r, float g, float b);
void lineTo(float x, float y);
void lineTo(Point2 p);
void moveTo(float x, float y);
void moveTo(Point2 p);
void moveRel(float dx, float dy);
private:
Point2 CP; //current position in the world
IntRect viewport; //the current window
RealRect window; //the current viewport
} ;
  1. Class Canvas Implementations
    Some member functions implementation of Canvas

//constructor
Canvas:: Canvas(int width, int height, char* windowTitle)
{
char* argv[1]; //dummy argument list for glutinit()
char dummyString[8];
argv[0] = dummyString; //hook up the pointer
int argc = 1;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(width, height);
glutInitWindowPosition (20,20);
glutCreateWindow (windowTitle);
setWindow(0, (float)width, 0, (float)height); // default world window
setViewport (0, width, 0, height); //default viewport
CP.set(0.0f, 0.0f); //initialize the cp to (0,0)
}
void Canvas:: moveTo(Point2 p) //moves current point CP to point p object
{
float x1, y1;
x1 = p.getX();
y1 = p.getY();
CP.set(x1, y1);
}
void Canvas:: lineTo(Point2 p)
{
glBegin (GL_LINES);
glVertex2f((GLfloat) CP.getX(), (GLfloat) CP.getY());
glVertex2f((GLfloat) p.getX(), (GLfloat) p.getY());
glEnd();
CP.set(p.getX(), p.getY());
glFlush();
}
  1. Example of using Class Canvas

main() function

//main.cpp
//main loop for canvas graphics
#include "canvas.h"
void display( void );
void main(void)
{
extern Canvas cvs;
cvs.setWindow(-10.0, 10.0, -10.0, 10.0);
cvs.setViewport(0, 500, 0, 500);
cvs.setBackgroundColor(1.0, 1.0, 1.0);
cvs.setColor(0.0, 0.0, 0.0);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutDisplayFunc(display);
glutMainLoop();
}

demo_canvas

//demo_canvas.cpp
#include "canvas.h"
Canvas cvs(640, 480, "try out Canvas"); //global canvas object
void display()
{
cvs.clearScreen(); //clear screen
cvs.setColor ( 1.0, 0.0, 0.0 );
cvs.moveTo( 0, 0.0 ); //draw line
cvs.lineTo( 5, 5.0 );
cvs.setColor ( 0.0, 1.0, 0.0 );
RealRect box( -1.0, 1.0, -1.0, 2.0 ); //construct a box
box.draw(); //draw box
glFlush();
}
  1. Drawing Arcs and Circles using Canvas
  2. Polygon

Canvas cvs(500, 500, "try out Canvas"); //global canvas object
void polygon(int n, float cx, float cy, float radius, float rotAngle)
{
//assumes global Canvas object, cvs
if( n < 3 ) return ; //bad number of sides
double angle = rotAngle * 3.14159265 / 180; //initial angle
double angleInc = 2 * 3.14159265 / n; //angle increment
cvs.moveTo(radius * cos(angle) + cx, radius * sin(angle) + cy);
for(int k=0; k < n; k++) //repeat n times
{
angle += angleInc;
cvs.lineTo(radius * cos(angle) + cx, radius * sin(angle) + cy);
}
} //polygon
  • Circle

void drawCircle(Point2 center, float radius)
{
glColor3f(1.0, 0.0, 0.0); //red
glLineWidth( 2.0 );
const int numVerts = 50; //many-sided polygon to approximate circle.
polygon(numVerts, center.getX(), center.getY(), radius, 0);
glPointSize ( 3 );
center.draw();
glFlush();
}//drawCircle
  • Arc

void drawArc(Point2 center, float radius, float startAngle, float sweep)
{ // startAngle and sweep are in degrees
glColor3f(0.0, 0.0, 1.0); //blue
const int n = 30; // number of intermediate segments in arc
float angle = startAngle * 3.14159265 / 180; // initial angle in radians
float angleInc = sweep * 3.14159265 /(180 * n); // angle increment
float cx = center.getX(), cy = center.getY();
cvs.moveTo(cx + radius * cos(angle), cy + radius * sin(angle));
for(int k = 1; < < n; k++, angle += angleInc)
cvs.lineTo(cx + radius * cos(angle), cy + radius * sin(angle));
}
  • An example of drawing polygon, circle, arc

void display(void)
{
int n = 5;
float radius = 3.0;
//display at upper right hand quadrant
float cx = 4.0, cy = 4.0;
cvs.clearScreen();
//draw a polygon
polygon( n, cx, cy, radius, 0.0);
//center at lower left quadrant
Point2 circle_center( -4.0, -4.5 );
drawCircle( circle_center, radius );
//center at lower right quadrant
Point2 arc_center( 4.0, -4.5 );
//starts at 30 deg, sweep through 120 degrees
drawArc( arc_center, radius, 30, 120 );
} /
  1. Turtle Graphics

Turtle graphics is a style of computer drawing based on preserved state (position and orientation) and a small number of operations against that state (forward, turn, pen up & down).
The state was called the turtle and programs taught the turtle how to draw.
Easy for kids to pick up.

to draw-a-box
forward 10
turn 90
forward 10
turn 90
forward 10
turn 90
forward 10
turn 90
to draw-a-window
draw-a-box
turn 90
draw-a-box
turn 90
draw-a-box
turn 90
draw-a-box
turn 90 / You can apply turtle graphics to draw fractals

A coding example: drawing a hook

void Canvas::forward ( float dist, int isVisible )
{
const float RadPerDeg = 0.017453393; //radians per degree
float x = CP.getX() + dist * cos ( RadPerDeg * CD );
float y = CP.getY() + dist * sin ( RadPerDeg * CD );
if ( isVisible )
lineTo( x, y );
else
moveTo ( x, y );
}//forward
//L is length of short side
void draw_hook( float L )
{
cvs.forward( 3*L, 1 );
cvs.turn( 90 );
cvs.forward( L, 1 );
cvs.turn( 90 );
cvs.forward( L, 1 );
cvs.turn( 90 );
}
void display(void)
{
cvs.clearScreen();
cvs.moveTo(0.0, 0.0); //starts at center
cvs.turnTo ( 0.0 ); //points horizontally
draw_hook ( 0.5 );
}
/

Class exercise:

Use turtle graphics to draw a star pattern.