1
More Drawing Tools
- 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
- R > W/H
world window is relatively short and wide, so
setViewport ( 0, W, 0, W/R );
- 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 );
}
- Developing the Canvas Calss
- Supporting classes
class Point2: A Point with Real Coordinates
// Support Classes for Canvasclass 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 classclass 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);
}
- 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
} ;
- 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();
}
- 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();
}
- Drawing Arcs and Circles using Canvas
- 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 );
} /
- 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.
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.