1. Introduction
This document describes the drawableObject
Library (dolt) and discusses its interfaces and usage information.
dolt was designed for use in Rensselaer Polytechnic Institute's
Algorithmic Robotics
Laboratory, specifically as a tool for creating small
simulations and for generating figures and demonstrations.
dolt makes use of the GLUT OpenGL graphics library and requires the library to be installed. Optionally, it can also be used in conjunction with the Computational Geometry Algorithms Library (CGAL), though CGAL is not required for use of dolt.
Because dolt was created quickly and for specific purposes, there are likely some problems (e.g. bugs, design flaws, etc.) that haven't presented themselves to us. As such, dolt is to be considered a still-developing project.
Before sending bug reports or suggestions, please read this entire document (especially the Errata/Todo Section) and send detailed information about the problem.
2. Installation
dolt has been installed and tested in versions of Unix, Linux, and
in Microsoft Windows 9x/NT/2k/XP. In its default configuration
it requires only the
OpenGL Utility Toolkit (GLUT) library. It can also be compiled
with the Computational Geometry
Algorithms Library (CGAL).
$ gunzip dolt-0.95.tar.gz | tar -xf -Depending on your system, it may be necessary to edit the
Makefile
for dolt. Make sure the paths for GLUT and
(if necessary) CGAL includes are correct. You may also wish to
change the default installation directory for dolt. Once
this is done, simply run:
$ make $ make cgal # optional, only if you are using CGAL support $ make install
In the win32
subdirectory of the unzipped package
is a .dsw (workspace) file. Open this in Visual Studio and
compile the 'dolt' project. This should produce the file dolt.lib
.
Move this file to your Visual Studio library directory.
If you wish to compile a version of dolt with CGAL support,
do the same for the project called 'dolt_cgal' (which will produce
dolt-cgal.lib
). Finally,
move the files in include
to your Visual Studio
include directory, in a subdirectory called dolt
.
-ldolt
(or -ldolt-cgal
with CGAL support)
compiler flag, and should be able to include dolt header files
in your code like so: #include <dolt/graphics.h>
. Additionally, because dolt makes use of GLUT (and
optionally CGAL), you will need to take any necessary steps to
compile with these libraries. It may be necessary for you to
specify the library and include directories manually if you
did not install to common include/lib directories, i.e.:
$ g++ program.cc -I/path/to/dolt/include -L/path/to/dolt/lib \ -ldolt -lglut -lGL -lGLU -lX11
#include <dolt/graphics.h>
.
3. Structure
dolt provides a number of interface classes and functions
for operations including:
Class | Inherits |
drawableObject | -- |
drawableLineObject | drawableObject |
drawableEnclosedObject | drawableLineObject |
Class | Inherits |
drawablePoint | drawableObject, Point |
drawableSegment | drawableLineObject, Segment |
drawableLineStrip | drawableLineObject, lineStrip |
drawablePolygon | drawableEnclosedObject, Polygon |
drawableEllipse | drawableEnclosedObject, Ellipse |
drawableCircle | drawableEnclosedObject, Circle |
drawableRectangle | drawableEnclosedObject, Rectangle |
drawableSquare | drawableEnclosedObject, Square |
drawableArc | drawableLineObject, Arc |
drawableWedge | drawableEnclosedObject, Arc |
drawableText | drawableObject |
drawableImage | drawableObject |
Class | Inherits |
Color | -- |
Graphics | -- |
psFile | -- |
Class | Inherits |
Bbox | -- |
Point | -- |
Segment | -- |
lineStrip | -- |
Polygon | -- |
Ellipse | -- |
Circle | -- |
Rectangle | -- |
Square | Rectangle |
Arc | Circle |
4. Base Classes
dolt makes significant use of inheritance. All classes derived
from the following base classes inherit several important
properties. Derive your own objects from these if you find a
need for drawing new types of objects that aren't among those
provided by dolt. It is recommended that you look at
drawable.h
and drawable.cpp
in the source
distribution for examples before doing so.
drawable.h
This is the base class for all objects capable of being rendered
(to screen or to Postscript) by dolt. It stores information
common to all "drawable objects," specifically color information,
and provides a default color for all objects to use. It is an
abstract class and cannot be instantiated by itself.
drawableObject
provides the following public functions:
static inline void setDefaultObjectColor( const Color &c )
     |
Functionality: Sets the (global) default object color
for all objects. Note that this affects only newly created
objects; previously created objects will retain the former
default color that was assigned them when they were created.
Arguments:
drawableObject::setDefaultColor( Color(1.0,0.0,0.0) );
|
inline void setColor( const Color &c )
     |
Functionality:
Sets the color of the object.
Arguments:
drawablePoint p(0.0,1.0); p.setColor( Color(1.0,0.0,0.0) );
|
inline void setAlpha( float a )
     |
Functionality:
Sets the alpha component of the color for the object.
Arguments:
drawablePoint p(0.0,1.0); p.setAlpha( 0.5 ); // 50% transparent
|
inline const Color & getColor() const
     |
Functionality:
Get the color of the object.
Arguments: None Example: drawablePoint p(0.0,1.0); Color c = p.getColor();
|
virtual void drawGL( const Graphics &out ) const
     |
Functionality:
An abstract function that must be implemented by all
objects derived from drawableObject . Renders the
object to the output device described by out using
OpenGL. Note that in general, the user does not need to
directly call this function to render the object, as this is
taken care of internally.
Arguments:
|
virtual void drawPS( const Graphics &out, psFile &ps, const Bbox &bounds, const double &scale ) const
     |
Functionality:
An abstract function that must be implemented by all
objects derived from drawableObject . Renders the
object to the Postscript file described by ps using
the scene from out , the page bounding box
bounds and the scaling factor scale .
Note that in general, the user does not need to directly call
this function to render the object, as this is taken care of
internally.
Arguments:
|
drawable.h
drawableLineObject
, derived from drawableObject
, should be used to represent any objects that consist only
of "line art" (e.g. that are not filled in any way). It stores
information about line width and dash patterns (stippling), and
a global default line width. An accessory to
drawableLineObject
is the lineStyle
type for
describing dash patterns. See the setLineStyle
function for more information on this. The
drawableLineObject
class cannot be directly instantiated;
only classes derived from it that provide drawGL
and
drawPS
functions can be instantiated.
drawableLineObject( lineStyle style = SOLID, float lineWidth = defaultWidth )
     |
Functionality:
Constructor; sets style (dash pattern) of line and width of line.
Arguments:
|
static inline void setDefaultLineWidth( float width )
     |
Functionality:
Sets the (global) default line width
for all lined objects. Note that this affects only newly created
objects; previously created objects will retain the
line width that was assigned them when they were created.
Arguments:
drawableLineObject::setDefaultLineWidth( 1.0 ); // 1 pixel wide
|
inline void setLineStyle( lineStyle style )
     |
Functionality:
Sets the dash pattern for the object. A dash pattern is defined
by the 16-bit lineStyle type. An on bit specifies
that a pixel at that bit's offset should be opaque, while an off
bit specifies that the pixel should be transparent. The pattern
is repeated over the entire line. Default values are defined.
They are SOLID (0xffff ), DASHED
(0xff00 ) and DOTTED
(0xcccc ).
Arguments:
drawableSegment s( Point(0.0,0.0), Point(1.0,1.0) ); s.setLineStyle( DASHED ); // 1111111100000000 s.setLineStyle( 0x0101 ); // 0000000100000001
|
inline void setLineWidth( float width )
     |
Functionality:
Sets the width of the object (in pixels).
Arguments:
drawableSegment s( Point(0.0,0.0), Point(1.0,1.0) ); s.setLineWidth( 3.0 ); // 3 pixels wide
|
inline lineStyle getLineStyle() const
     |
Functionality:
Get the line style of the object.
Arguments: None Example: drawableSegment s( Point(0.0,0.0), Point(1.0,1.0) ); lineStyle ls = p.getLineStyle();
|
inline float getLineWidth() const
     |
Functionality:
Get the line width of the object.
Arguments: None Example: drawableSegment s( Point(0.0,0.0), Point(1.0,1.0) ); float w = p.getLineWidth();
|
drawable.h
drawableEnclosedObject
, derived from
drawableLineObject
, should be used to represent any
objects that are filled in some way (e.g. polygons, circles,
etc.) and that might have a border. It stores information
about whether or not the object should be filled, whether its
border should be drawn, the color of the border, and a global
default border width. The drawableEnclosedObject
class cannot be directly instantiated; only classes
derived from it that provide drawGL
and
drawPS
functions can be instantiated. Note: to
set the border width of the enclosed object, the
setLineWidth
member of the parent class (
drawableLineObject
) can be called.
drawableEnclosedObject( bool filled = true, lineStyle style = SOLID, float lineWidth = defaultWidth )
     |
Functionality:
Constructor; sets flag indicating whether or not the object is
filled, and sets style (dash pattern) of border and width of
border.
Arguments:
|
static inline void setDefaultBorderColor( const Color &c )
     |
Functionality:
Sets the (global) default border color for all enclosed objects.
Note that this affects only newly created
objects; previously created objects will retain the
border color that was assigned them when they were created.
Arguments:
Color red(1.0,0.0,0.0); drawableEnclosedObject::setDefaultBorderColor( red );
|
static inline void setDefaultLineWidth( float width )
     |
Functionality:
Sets the (global) default border width (in pixels) for all
enclosed objects. Note that this affects only newly created
objects; previously created objects will retain the
border width that was assigned them when they were created.
Arguments:
drawableEnclosedObject::setDefaultLineWidth( 2.0 ); // 2 pixels
|
inline void setFilled( bool filled )
     |
Functionality:
Sets the flag indicating whether or not the object should be
filled (with the color associated with the object).
Arguments:
drawablePolygon p; p.setFilled( false );
|
inline void setBorderColor( const Color &c )
     |
Functionality:
Sets the border color for the object.
Arguments:
drawablePolygon p; p.setBorderColor( Color(1.0,0.0,0.0) );
|
inline bool getFilled() const
     |
Functionality:
Get the fill flag for the object.
Arguments: None Example: drawablePolygon p; bool filled = p.getFilled();
|
inline const Color & getBorderColor() const
     |
Functionality:
Get the border color of the object.
Arguments: None Example: drawablePolygon p; Color c = p.getBorderColor();
|
5. Drawable Objects
Header: Declared in drawable.h
The most important functionality of dolt (and its purpose) is
to render 2-dimensional geometric objects to the screen. This
is accomplished by providing a set of "drawable" versions of
the geometric objects discussed above. The drawable versions
inherit methods from both drawableObject
and their
geometric representation, and thus provide the public
interfaces of both. For example, a drawablePoint
stores information both about the location of a point and
about its color. See the Class Heirarchy
for information about which drawable objects inherit what.
The following drawable objects are provided:
drawablePoint
drawableSegment
drawableLineStrip
drawablePolygon
drawableEllipse
drawableCircle
drawablePoint
drawableRectangle
drawableSquare
drawableArc
drawableWedge
drawableText
drawableImage
drawableText
and
drawableImage
do not map to a
geometric counterpart. The rest of the objects are in most
cases interchangeable with their geometry-only versions, i.e.:
void foo( const Point &point ) { ... } void bar( const drawablePoint &dpoint ) { ... } Point p(1.0,1.0); drawablePoint q(p); foo( p ); // ok foo( q ); // ok foo( drawablePoint(8.0,8.0) ); // ok bar( q ); // ok bar( p ); // ok bar( Point(0.0,0.0) ); // ok
One exception is drawablePolygon
, which extends
Polygon
to allow for holes in the polygon. To
insert a hole in a drawablePolygon
, use
drawablePolygon::addHole
; note also that a
drawablePolygon
can be nonconvex:
void addHole( const Polygon &hole )
     |
Functionality:
Add a 'hole' in a polygonal object. Note that if the hole is
not fully in the interior of the object, the drawing behavior
of the drawablePolygon is undefined. The even-odd
winding rule is used in determining which portions of the
overall polygon are inside (and will be filled).
Arguments:
drawablePolygon poly; // create a nonconvex polygon poly.push_back( Point(1.0,1.0) ); poly.push_back( Point(5.0,4.0) ); poly.push_back( Point(9.0,1.0) ); poly.push_back( Point(6.0,5.0) ); poly.push_back( Point(9.0,9.0) ); poly.push_back( Point(5.0,6.0) ); poly.push_back( Point(1.0,9.0) ); poly.push_back( Point(4.0,5.0) ); Polygon hole; // add a square hole in the middle hole.push_back( Point(4.5,4.5) ); hole.push_back( Point(5.5,4.5) ); hole.push_back( Point(5.5,5.5) ); hole.push_back( Point(4.5,5.5) ); poly.addHole( hole );
|
drawable.h
drawableText
is meant to be a (very) simple
text-drawing interface that makes use of system-available fonts.
It is cross-platform compatible for
Win32 and *nix, though the user may have to handle the cross-
platform case using preprocessor commands if this compatibility
is desired because of the differences in font-naming conventions
across platforms.
drawableText( const Point &location, const char *text = "", int points = 12, const char *postscriptFont = "Palatino-Roman", const char *screenFont = DEFAULTFONT );
     |
Functionality:
Constructor; set world coordinate location for bottom
left of text, string to draw, point size and fonts for both
Postscript and screen output. Note that in Unix the point
size specified is ignored for screen output and that specified
as part of the font string is used instead. DEFAULTFONT is
defined to be "Arial" in Win32 and
"-adobe-helvetica-medium-r-normal--12-*-*-*-p-*-iso8859-1" in
other operating environments.
Arguments:
#ifdef _WIN32 drawableText txt(Point(1.0,1.0),"Test",12,"Helvetica","Helvetica"); #else drawableText txt(Point(1.0,1.0),"Test",12,"Helvetica", "-adobe-helvetica-medium-r-normal--12-*-*-*-p-*-iso8859-1"); #endif
|
drawable.h
drawableImage
provides an interface for sampled image
(bitmap) drawing, loading, saving and manipulation within the
drawableObject
framework. It can perform its
functionality for images with one byte per pixel (grayscale) or
three bytes per pixel (RGB). Images are mapped to world coordinates
with a bounding box, and thus can be stretched or compressed to fit
within the bounding box. Individual pixels or the entire color
buffer can be manipulated.
Image drawing to screen is done via a raster operation, which is slower than texture mapping but allows for the use of images of arbitrary size (OpenGL textures must be 2^n x 2^n pixels).
Note that the image is stored as a single buffer of increasing x and y pixel coordinates. The image coordinate frame origin is at the lower left of the image.
drawableImage() drawableImage( const Bbox &worldLocation ) drawableImage( const Bbox &worldLocation, unsigned int w, unsigned int h, bytespp bytes = BPP3 ); drawableImage( const drawableImage &i );
     |
Functionality:
Constructors; if specified, sets world bounding box for image and
pixel width, height and bytes per pixel. The copy constructor
duplicates the color buffer of an image in memory, so use it with
caution. If width and height of the image are specified, an empty
color buffer of that size is created; this functionality should
not be used if an image will be loaded from file, as loading causes
any current color buffer to be destroyed.
Arguments:
drawableImage img; // no color buffer created drawableImage img2( Bbox(0.0,0.0,10.0,10.0) ); // no color buffer created drawableImage img3( Bbox(0.0,0.0,10.0,10.0), 100, 100, BPP3 ); // color buffer created drawableImage img4( img3 ); // copies color buffer of img3
|
inline void setWorldLocation( const Bbox &worldLocation )
     |
Functionality:
Set the bounding box specifying the region occupied by the image in
world space.
Arguments:
drawableImage img; img.setWorldLocation( Bbox(0.0,0.0,10.0,10.0) );
|
inline unsigned int getWidth() const inline unsigned int getHeight() const
     |
Functionality:
Get width or height, respectively, in pixels of the image.
Arguments: None Example: drawableImage img( Bbox(), 640, 480 ); unsigned int w = img.getWidth(); // 640 unsigned int h = img.getHeight(); // 480
|
inline unsigned char * getBuffer()
     |
Functionality:
Access the color buffer of the image directly.
Arguments: None Example: drawableImage img( Bbox(), 640, 480 ); unsigned char *buf = img.getBuffer();
|
void setPixel( unsigned int x, unsigned int y, const unsigned char *col ) const unsigned char * const getPixel( unsigned int x, unsigned int y ) const
     |
Functionality:
Set or retrieve the value of the pixel in the image at (x ,
y ). Note that the value at the retrieved pointer to the
pixel cannot be modified.
Arguments:
drawableImage img( Bbox(), 640, 480, BPP1 ); unsigned char pix; pix = *img.getPixel( 10, 10 ); pix = 0xf0; img.setPixel( 10, 10, &pix ); drawableImage img2( Bbox(), 640, 480, BPP3 ); unsigned char pix2[3], *pix3; pix3 = img.getPixel( 10, 10 ); pix2[0] = pix2[1] = 0xff; pix2[2] = 0x00; img.setPixel( 10, 10, pix2 ); // set to yellow
|
bool loadPPM( const char *filename )
     |
Functionality:
Load a PPM file into the drawableImage object; this
will destroy any existing image information. Any properly
formatted ASCII- or binary-formatted PPM image can be loaded.
Note that ASCII images inherently load much more slowly than
binary images.
Arguments:
drawableImage img( Bbox(0.0,0.0,10.0,10.0) ); if( !img.loadPPM( "test.ppm" ) ) cout << "Error loading test.ppm" << endl;
|
bool savePPM( const char *filename, bool binaryFile = true ) const
     |
Functionality:
Save the color buffer of the drawableImage to a PPM
file (in either ASCII or binary format).
Arguments:
drawableImage img( Bbox(0.0,0.0,10.0,10.0), 200, 200, BPP3 ); ... // perform operations on the image color buffer if( !img.savePPM( "out.ppm", true ) ) cout << "Error saving out.ppm" << endl;
|
6. Color
Header: Declared in color.h
Color
provides an interface for all color
assignment and use within dolt. It stores red, green,
blue and alpha (transparency) values for colors. Additionally, it
provides functionality for mapping names (strings) to
color values. Note: the default value (if one
is never assigned) for a color is white (1.0,1.0,1.0).
Also, color names should not begin with any of the digit
characters (0-9) or the period character (though this is
not enforced).
Color( float r = 1.0, float g = 1.0, float b = 1.0, float a = 1.0 )
     |
Functionality:
Constructor; assigns RGBA values to color and defaults
to white if none are specified.
Arguments:
Color red(1.0,0.0,0.0); Color yellow(1.0,1.0,0.0); Color transparent(1.0,0.0,0.0,0.5); // 50% transparent
|
Color( const char *name )
     |
Functionality:
Constructor; assigns color values based on a name if the
name exists in the global color map, or the default color
if the name does not exist.
Arguments:
Color red("red");
|
inline void setRGB( float r, float g, float b )
     |
Functionality:
Set the rgb values of the color.
Arguments:
Color c; c.setRGB( 1.0, 0.0, 0.0 );
|
inline void setAlpha( float a )
     |
Functionality:
Set the alpha transparency of the color.
Arguments:
Color c("red"); c.setAlpha( 0.5 ); // 50% transparent c.setAlpha( 0.0 ); // completely transparent c.setAlpha( 1.0 ); // completely opaque
|
inline float r() const inline float g() const inline float b() const inline float a() const
     |
Functionality:
Retreive the red, green, blue or alpha components (respectively)
of the color.
Arguments: None Example: Color c("red"); c.r(); // returns 1.0 c.g(); // returns 0.0
|
void nameColor( const char *name )
     |
Functionality:
Map the color to a name in the global color map. The name can
then be used in the initialization of future Color objects. If
the name already exists in the color map, it is replaced. Color
names should not begin with a digit (0-9) or a period. A large
number of default colors are placed in the map at program
startup; some of the more commonly used ones are as follows:
color.cpp .
Arguments:
Color c(1.0,0.0,0.0); c.nameColor( "red" ); Color x("red"); // x == c
|
7. Output
Header: Declared in graphics.h
The Graphics
class provides two important types
of functionality. It stores scene information (i.e. all
objects to be drawn in any rendering context), and if
necessary renders to the screen (using GLUT).
Following are the initializers for the Graphics
class:
Graphics()
     |
Functionality:
Constructor; create a scene with a default world boundary.
Arguments: None
|
Graphics( const Bbox &world )
     |
Functionality:
Constructor; create a scene with the world boundary specified
in world ; world coordinates will be automatically
mapped to any rendering context.
Arguments:
Graphics g( Bbox(0.0,0.0,10.0,10.0) );
|
inline void setWorldBounds( const Bbox &world )
     |
Functionality:
Set the world boundary of the scene.
Arguments:
Graphics g; g.setWorldBounds( Bbox(0.0,0.0,5.0,5.0) );
|
Graphics
class stores
information about a single scene. This information is
in the form of a list of lists of
drawableObject
s. The rationale behind this structure
is that it provides a simple method for grouping objects so
that, for example, all objects of a certain "class" can be
removed from the scene at once.
In order to add objects to a scene, one must first create an
objectList
-- which is simply a
std::list<drawableObject *>
and can be treated as such.
So, for example, to create a list of Point
s to
draw to the screen, one could do the following:
Point a(0.0,0.0); Point b(1.0,1.0); Point c(2.0,2.0); objectList objects; objects.push_back( &a ); objects.push_back( &b ); objects.push_back( &c );
The list is now ready to be inserted into the scene. This
can be done with the addObjectList
function
(objecList
s can be removed with the counterpart
delObjectList
function).
void addObjectList( const objectList &olist )
     |
Functionality:
Add a list of objects to the scene.
Arguments:
g.addObjectList( objects );
|
void delObjectList( const objectList &olist )
     |
Functionality:
Delete the list of objects at the address of olist
from the scene, if such a list exists.
Arguments:
g.addObjectList( objects ); g.delObjectList( objects );
|
Graphics
class is
that it is only able to render one scene at a time (i.e., dolt
is unable to render to multiple simultaneous windows). However,
your program can creates multiple scenes and switch between.
The first scene to be created is the default current scene.
static void setCurrentScene( Graphics &g )
     |
Functionality:
Sets a global pointer to the currently rendering scene. All
screen and Postscript output will be from this scene.
Arguments:
Graphics g1; Graphics g2; // g1 is the currently rendering scene Graphics::setCurrentScene( g2 ); // g2 is the currently rendering scene
|
void setKeyboardHandler( void (*kb)( unsigned char key ) )
     |
Functionality:
Set the handler for incoming keyboard events to a user-defined
function.
Arguments:
void kb( unsigned char key ) { cout << key << " was pressed!" << endl; } ... g.setKeyboardHandler( kb );
|
void setMouseHandler( void (*mouse)( int button, int state, int x, int y ) )
     |
Functionality:
Set the handler for incoming mouse click events to be a
user-defined function
Arguments:
void mouse( int button, int state, int x, int y ) { ... } ... g.setMouseHandler( mouse );
|
void setMotionHandler( void (*motion)( int x, int y ) )
     |
Functionality:
Set the handler for incoming mouse motion events to be a
user-defined function.
Arguments:
void motion( int x, int y ) { ... } ... g.setMotionHandler( motion );
|
void setIdleFunction( void (*idle)( void ) )
     |
Functionality:
Set a pointer to a user-defined function that is called when
dolt (and GLUT) are idle.
Arguments:
void motion( int x, int y ) { ... } ... g.setMotionHandler( motion );
|
void printControlKeyBindings() const
     |
Functionality:
Print (to STDOUT) a list of the default control (zoom/pan) key
bindings for dolt.
Arguments: None Example: cout << "Keyboard Commands:" << endl; g.printControlKeyBindings();
|
q
' exits the program.
Also, a built-in handler for special keyboard events exists, and is used for the control of zooming and panning of the scene. The built in controls are as follows:
Graphics
class interface.
void zoom( float newZoom = 1.0 )
     |
Functionality:
Zoom in or out of the scene. The argument is the percentage
of the original size of the scene to zoom to. In other words,
a zoom of 1.0 (100%) restores the scene to its original size,
with the world bounding box exactly fitting the output window.
A zoom of 0.5 (50%) displays the scene at 50% of its original
size, etc. Note that zooming is relative to the center of the
current view.
Arguments:
g.zoom(); // original size g.zoom( 0.25 ); // 1/4 original size
|
void pan( float panX, float panY )
     |
Functionality:
Pan over the scene. Pans panX percent of the
x-dimension of the scene, and panY percent of
the y-dimension of the scene relative to the current scene
location (not the original).
Arguments:
g.pan( 0.05, 0.0 ); // move right 5% of scene x dimension g.pan( -0.1, -0.1 ); // move down and left
|
double findScale( const Bbox &newBounds ) const
     |
Functionality:
Find the scaling factor between the world bounding box and
newBounds
Arguments:
g.setWorldBounds( Bbox(0.0,0.0,10.0,10.0) ); Bbox newWorld(0.0,0.0,5.0,5.0); double scale = g.findScale( newWorld );
|
Point mapPoint( const Bbox &bounds, const double &scale, const Point &p ) const
     |
Functionality:
Find the point within the world bounded by bounds
that is mapped to from the current scene, given a factor by
which to scale distances and the point in the current scene
to map.
Arguments:
g.setWorldBounds( Bbox(0.0,0.0,10.0,10.0) ); Bbox newWorld(0.0,0.0,5.0,5.0); double scale = g.findScale( newWorld ); Point q = g.mapPoint( newWorld, scale, Point(1.0,1.0) );
|
void pixelsPerMeter( float &ppmx, float &ppmy ) const
     |
Functionality:
Returns the ratio of pixels (on-screen) to world units ('meters'),
taking into account current zoom, in ppmx and
ppmy .
Arguments:
// for a window of width 640 and height 480 with no zoom g.setWorldBounds( Bbox(0.0,0.0,10.0,10.0) ); g.pixelsPerMeter( ppmx, ppmy ); // ppmx == 64, ppmy = 48
|
initGL
function. Following this, calling the
runEventLoop
function begins the rendering to the
screen. Be advised that runEventLoop
will never
return!
void initGL( int *argc, char **argv, const char *name = 0, int winWidth = 750, int winHeight = 0, int winPosX = 100, int winPosY = 100 )
     |
Functionality:
Initialize OpenGL output and create a window. Note: you
might find it useful to use a similar ratio in your window
width and height as the same ratio in your world bounding
box.
Arguments:
Graphics g; g.initGL( &argc, argv, "example", 640, 480 );
|
static void runEventLoop()
     |
Functionality:
Run the main OpenGL event-handling loop. This function
will never return.
Arguments: None Example: Graphics g; ... // set up scene g.initGL( &argc, argv, "example", 640, 480 ); g.runEventLoop();
|
void setBackgroundColor( const Color &c )
     |
Functionality:
Set the background color of the current rendering context
(default is white).
Arguments:
Graphics g; g.setBackgroundColor( Color("black") );
|
inline int getPixWidth() const inline int getPixHeight() const
     |
Functionality:
Get the width and height, respectively (in pixels) of the
window for the Graphics object.
Arguments: None Example: int w = g.getPixWidth(); int h = g.getPixHeight();
|
Graphics
class can be
outputted to non-screen contexts (not in real time).
postscript.h
To set up Postscript output, you must first create a
psFile
output file. A psFile
should be initialized as follows:
psFile p( "filename.ps" );Note that no copy constructor exists for
psFile
;
it is derived from ofstream
, which also provides
no copy constructor. This means that the following is
illegal:
void foo( const psFile &file ) { ... } foo( psFile( "filename.ps" ) ); // illegal psFile out( "filename.ps" ); foo( out ); // okTo render the scene to a Postscript file, use the
writePS
function.
void writePS( psFile &out, const Bbox &bounds = Bbox(0.5,0.5,8.0,10.5) ) const
     |
Functionality:
Write the scene to a Postscript file, using the bounding box
described by bounds to position the scene on the
page.
Arguments:
Graphics g; ... // set up scene psFile out( "filename.ps" ); g.writePS( out, Bbox(0.5,0.5,8.0,7.5) );
|
Graphics
object whose screen should be saved. They
are written in binary PPM format.
bool writePPM( const char *filename ) const
     |
Functionality:
Write the screen pixels (directly from the framebuffer) to the
specified file in binary PPM format. Returns false on failure,
true on success.
Arguments:
Graphics g; ... // set up scene g.writePPM( "screenshot.ppm" );
|
8. Geometric Representations
Header: Declared in geometry.h
dolt provides a number of geometric objects with interfaces that emulate those of their counterparts in CGAL, and also provides several objects not avaliable with CGAL. As a general rule, all of the accessor functions provided by the CGAL counterparts are implemented, but none of the other functionality exists. As such, the built-in geometric objects are not well-suited to applications that need to do anything with them besides draw.
In order for the provided objects to provide exactly the
same interface as CGAL, a number of CGAL typedefs exist
(see geometry.h
) that create 2-dimensional CGAL
types. These should be used when possible if CGAL is being used because the
drawable*
classes in drawable.h
derive from them in order to work with both CGAL and the
built-in geometric objects.
Point
: similar to CGAL's Point_2
Point( const double &px, const double &py )
bool operator==( const Point &p ) const
bool operator!=( const Point &p ) const
double x() const
double y() const
Point operator+( const Point &p ) const
: Point addition
Point operator-( const Point &p ) const
: Point subtraction
Point operator+=( const Point &p )
: Unary Point addition
Point operator-=( const Point &p )
: Unary Point subtraction
Point operator-()
: Point negation
Point rotate( double th )
: Point rotation (radians)
Point rotate90() const
: Return Point rotated 90 degrees
double length() const
: Distance from (0,0)
Point normal() const
: Normal of vector represented by Point
Point operator*( double s ) const
: Scalar multiplication
Point operator/( double s ) const
: Scalar division
Point operator*=( double s )
: Unary scalar multiplication
Point operator/=( double s )
: Unary scalar division
double dot( const Point &p, const Point &q )
: Dot product
double cross( const Point &p, const Point &q )
: Planar
cross product (returns magnitude of cross product)
Point unitNormal( double th )
: Return unit normal in
direction th
(radians)
Bbox
: similar to CGAL's Bbox_2
Bbox( const double &xMin, const double &yMin, const double &xMax, const double &yMax )
double xmin() const
double ymin() const
double xmax() const
double ymax() const
Segment
: similar to CGAL's Segment_2
Segment( const Point &startPoint, const Point &endPoint )
Point start() const
Point end() const
Polygon
: similar to CGAL's Polygon_2 with
std::vector<Point> as the container
Vertex_iterator vertices_begin()
Vertex_iterator vertices_end()
Edge_const_iterator edges_begin() const
Edge_const_iterator edges_end() const
Circle
: similar to CGAL's Circle_2
Circle( const Point ¢er, const double &squaredRad )
inline Point center() const
inline double squared_radius() const
Additionally, several objects not provided by CGAL are available (though primarily only for drawing) with dolt.
Ellipse( const Point &p, const double &orient, const double &majorRadius, const double &minorRadius )
     |
Functionality:
Constructor; initialize the ellipse's center, orientation,
major radius and minor radius.
Arguments:
// ellipse centered at origin, rotated 90 degrees, // with a major radius of 3 and a minor radius of // 1.5 Ellipse e( Point(0.0,0.0), M_PI / 2.0, 3.0, 1.5 );
|
inline void setPos( const Point &p ) inline void setOrientation( const double &o ) inline void setMajorRadius( const double &r ) inline void setMinorRadius( const double &r ) inline Point getPos() const inline double getOrientation() const inline double getMajorRadius() const inline double getMinorRadius() const
     |
Functionality:
Set or retrieve the values associated with the ellipse
Example: Ellipse e( Point(0.0,0.0), M_PI / 2.0, 3.0, 1.5 ); e.setOrientation( 0.0 ); double orient = e.getOrientation(); // 0.0
|
lineStrip
is simply a series of
Points
. It is derived directly from
std::vector<Point>
, and thus provides the
same interface.
Example:
// create an upside-down 'v' lineStrip s; s.push_back( Point(0.0,0.0) ); s.push_back( Point(1.0,1.0) ); s.push_back( Point(2.0,0.0) );
Rectangle
stores the lower left and upper
right corners of a rectangle.
Rectangle( const Point ¢er, const double &width, const double &height )
     |
Functionality:
Constructor; create a rectangle given a center point, a
width (x axis) and a height (y axis).
Arguments:
// rectangle centered at origin with width 3 and // height 1.5 Rectangle r( 0.0, 3.0, 1.5 );
|
Rectangle( const Point &lowerLeft, const Point &upperRight )
     |
Functionality:
Constructor; create a rectangle given the lower left and
upper right corners
Arguments:
Rectangle r( Point(0.0,0.0), Point(3.0,2.0) );
|
inline Point getMinPoint() inline Point getMaxPoint()
     |
Functionality:
Retrieve the minimum and maximum points of the rectangle
(respectively)
Example: Rectangle r( Point(0.0,0.0), Point(3.0,2.0) ); Point p = r.getMinPoint(); // (0.0, 0.0)
|
Square
is derived from Rectangle
,
and thus provides the same accessors.
Square( const Point &lowerLeft, const double &sideLen )
     |
Functionality:
Constructor; create a square given the lower left corner
and the length of the square's sides
Arguments:
Square s( Point(0.0,0.0), 3.0 );
|
Arc
is derived from Circle
, and
thus provides the same accessors as Circle
in
addition to its own. Only circular arcs may be represented.
Arc( const Point ¢er, const double &squaredRad, const double &minAngle, const double &maxAngle )
     |
Functionality:
Constructor; create a circular arc given a center, squared
radius, minimum and maximum angle (on the circle) of the arc.
Arguments:
// an arc through 90 degrees Arc a( Point(0.0,0.0), 1.0, 0.0, M_PI / 2.0 );
|
inline double getMinAngle() const inline double getMaxAngle() const
     |
Functionality:
Retrieve the minimum and maximum angles of the arc (respectively)
Example: Arc a( Point(0.0,0.0), 1.0, 0.0, M_PI / 2.0 ); double x = a.getMinAngle(); // x == 0.0
|
9. Example Program
The following example program demonstrates a number of the
features of dolt.
// // Test program for dolt // Creates a variety of drawableObjects and displays them, // and demonstrates keyboard handling and multiple scenes // #include// for screen output #include // for postscript output #include // for M_PI #ifndef M_PI #define M_PI 3.1415926535897932384626433833 #endif Graphics g, g2; // keyboard handler for primary scene void gkeyboard( unsigned char key ) { switch( key ) { case 'q': exit( 0 ); // quit case 's': Graphics::setCurrentScene( g2 ); // switch scenes break; case 'p': { psFile f("test.ps"); // open postscript file g.writePS( f ); // write postscript file } break; } } // keyboard handler for secondary scene void g2keyboard( unsigned char key ) { switch( key ) { case 'q': exit( 0 ); case 's': Graphics::setCurrentScene( g ); break; case 'p': { psFile f("test.ps"); g2.writePS( f ); } break; } } int main( int argc, char **argv ) { // initialize screen output for both scenes g.initGL( &argc, argv, "Test", 640, 640 ); g2.initGL( &argc, argv, "Test 2", 480, 480 ); // register keyboard callbacks for both scenes g.setKeyboardHandler( gkeyboard ); g2.setKeyboardHandler( g2keyboard ); // create a drawable point object at (2,2) with a // diameter of 8 drawablePoint p(2.0,2.0,8.0); // create a drawable line segment from (1,1) to (9,1) // with a custom dash pattern drawableSegment s( Point(1.0,1.0),Point(9.0,1.0), 0xfcfc ); // make the segment red s.setColor( Color(1.0, 0, 0) ); // create a line strip (a series of vertices) drawableLineStrip ls; ls.setColor( Color(0, 1.0, 0) ); // green ls.push_back( Point(3.0,3.0) ); // first point ls.push_back( Point(4.0,3.5) ); // second point ls.push_back( Point(3.0,4.0) ); // third point // create a polygon (solid border, filled, border width of 3) drawablePolygon o(SOLID,true,3.0f); o.setColor( Color(0, 0, 1.0) ); // blue filling o.push_back( Point(7.0,7.0) ); // first point o.push_back( Point(9.0,9.0) ); // second point o.push_back( Point(9.5,7.0) ); // third point o.push_back( Point(8.0,6.5) ); // fourth point // create an ellipse centered at (2,8), with an orientation // of -1.2 radians, a major radius of 2.0 and a minor radius // of 1.0 drawableEllipse e( Point(2.0,8.0),-1.2,2.0,1.0 ); e.setColor( Color(1.0, 1.0, 0) ); // yellow // create a circle centered at (8,2) with a radius of 1.5, a // dashed border, filled, with a border width of 3 drawableCircle c( Point(8.0,2.0),1.5,DASHED,true,3.0f ); // set the circle's color to cyan, 50% transparent c.setColor( Color(0, 1.0, 1.0, 0.5) ); // create a rectangle with a lower left corner at (5,5) and an // upper right corner at (7,7), with a solid border, filled, // and a border width of 5 drawableRectangle r(Point(5.0,5.0),Point(7.0,7.0),SOLID,true,5.0f); // set the filling color to 50% gray r.setColor( Color("gray50") ); // set the border color to red r.setBorderColor( Color("red") ); // create a square with a lower left corner at (5.75,5.75) // with a side length of 0.5, a dotted border, filled, and a // border width of 3 drawableSquare q(Point(5.75,5.75),0.5,DOTTED,true,3.0f); q.setColor( Color(0.0,1.0,1.0) ); // cyan // create an arc centered at (5,8.5), with a squared radius of // 1.0, arcing (counterclockwise) from PI/2 to PI drawableArc a(Point(5.0,8.5),1.0,M_PI / 2.0,M_PI,SOLID,3.0f); a.setColor( "green" ); // create a wedge centered at (5,8.5) with a squared radius of // 1.0, arcing (counterclockwise) from PI to 2PI drawableWedge w(Point(5.0,8.5),1.0,M_PI,M_PI * 2.0,SOLID,true,2.0f); w.setColor( "magenta" ); // some text #ifdef _WIN32 drawableText t(Point(3.0,3.0),"Some Text",24,"Palatino-Roman","Helvetica"); #else drawableText t(Point(3.0,3.0),"Some Text",24,"Palatino-Roman", "-adobe-helvetica-medium-r-normal--24-*-*-*-p-*-iso8859-1"); #endif t.setColor( "blue" ); // create a new objectList so that we can add all of the // objects to the first scene objectList olist; olist.push_back( &p ); // add point olist.push_back( &s ); // add line segment olist.push_back( &ls ); // add line strip olist.push_back( &o ); // add polygon olist.push_back( &e ); // add ellipse olist.push_back( &c ); // add circle olist.push_back( &r ); // add rectangle olist.push_back( &q ); // add square olist.push_back( &a ); // add arc olist.push_back( &w ); // add wedge olist.push_back( &t ); // add text g.addObjectList( olist ); // add the objectList to the scene // create a new objectList to add objects to the second scene objectList olist2; olist2.push_back( &r ); // add rectangle g2.addObjectList( olist2 ); // add the objectList to the scene // run the main event loop, drawing everything on the screen g.runEventLoop(); return 0; };
initGL
did not produce proper result
drawableText
and cross-platform font
support
Color
input operator for reading from an
istream
getColor
, getLineStyle
,
getLineWidth
, getFilled
,
getBorderColor
to base
drawable{Line,Enclosed}Object
classes
printControlKeyBindings
to Graphics
Graphics::printControlKeyBindings
function and prints
'q' (quit) and 'h' (help) command info
drawableImage
, with ASCII/binary
PPM loading and saving
Graphics::writePPM
(screenshot)
Graphics::pixelsPerMeter
(ratio of pixels
to world units)
Graphics::getPix{Width,Height}
drawablePolygon
to handle concave
polygons (both screen and Postscript output)
drawablePolygon::addHole
;
drawablePolygon
's can now have holes
dolt.h
(which just includes all other
dolt files for ease)
Copyright (c) 2002 Rensselaer Polytechnic Institute