Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

Draw.h

Go to the documentation of this file.
00001 #ifndef INCLUDED_Draw_h_
00002 #define INCLUDED_Draw_h_
00003 
00004 #include "Shared/BoundingBox.h"
00005 #include "Planners/PlannerObstacles.h"
00006 
00007 typedef struct _cairo cairo_t;
00008 typedef struct _cairo_surface cairo_surface_t;
00009 
00010 //! A very simple drawing environment, originally to visualize planner stuff
00011 /*! Default origin is in the lower left corner, positive x and y to the right and up */
00012 class Draw {
00013 public:
00014   //! Default constructor, must still call setFile() before any drawing commands
00015   Draw()
00016     : cr(NULL), surface(NULL), filename(), origin(), scale(1), surfaceWidth(), surfaceHeight(), addPath(false) {}
00017   
00018   //! Constructor, sets up output
00019   Draw(const std::string& file, double width, double height)
00020     : cr(NULL), surface(NULL), filename(), origin(), scale(1), surfaceWidth(), surfaceHeight(), addPath(false) { setFile(file,width,height); }
00021   
00022   //! Destructor
00023   ~Draw() { teardown(); }
00024   
00025   //! This must be called to setup output destination before calling any drawing commands
00026   Draw& setFile(const std::string& file, double width, double height);
00027   
00028   //! Writes the current page and starts a new one
00029   Draw& flushPage();
00030   
00031   //! Moves the origin (lower left corner)
00032   Draw& setOrigin(const fmat::Column<2>& p) { origin=p; resetTransform(); return *this;}
00033   //! Moves the origin (lower left corner)
00034   Draw& setOrigin(double x, double y) { origin=fmat::pack(x,y); resetTransform(); return *this;}
00035   //! Moves the origin in order to center the viewport on the specified point
00036   Draw& centerView(const fmat::Column<2>& p) { return centerView(p[0],p[1]); }
00037   //! Moves the origin in order to center the viewport on the specified point
00038   Draw& centerView(double x, double y);
00039   
00040   //! Clips further drawing to the current path area
00041   Draw& setClip();
00042   //! Clears the clipping region
00043   Draw& clearClip();
00044   
00045   //! Changes the scaling factor, to display more or less within the bounds given to setFile()
00046   /*! The apparent stroke width is unchanged unless you set @a scaleStroke */
00047   Draw& setScale(double x, bool scaleStroke=false);
00048   //! Converts from display units to scaled coordinates
00049   double displayToScaled(double x) const { return x/scale; }
00050   //! Converts from scaled coordinates to display units
00051   double scaledToDisplay(double x) const { return x*scale; }
00052   
00053   //! Changes scale and origin to fit the specified drawing region to the output
00054   Draw& setRegion(const BoundingBox2D& region, bool scaleStroke=false);
00055   //! Draws a grid of the specified horizontal and vertical resolution across the visible region (doesn't stroke)
00056   Draw& drawGrid(double xRes, double yRes, double xOff=0, double yOff=0);
00057   //! Draws the axes across the visible region (doesn't stroke)
00058   Draw& drawAxes();
00059   
00060   //! Sets the stroke width using output dimension units, i.e. scale factor invariant
00061   Draw& setStrokeWidth(double x);
00062   //! Sets the stroke width using coordinate-space units, i.e. relative to scale factor
00063   Draw& setScaledStrokeWidth(double x);
00064   //! Returns the stroke width in output dimension units
00065   double getStrokeWidth() const  { return getScaledStrokeWidth()*scale; }
00066   //! Returns the stroke width in coordinate-space units
00067   double getScaledStrokeWidth() const;
00068   
00069   //! Convenient color constants
00070   enum Colors {
00071     BLACK, DK_GRAY, GRAY, LT_GRAY, WHITE, RED, YELLOW, GREEN, CYAN, BLUE, MAGENTA
00072   };
00073   
00074   //! Sets the color for future drawing operations
00075   Draw& setColorRGB(double red, double green, double blue, double alpha=1);
00076   //! Sets the color for future drawing operations
00077   Draw& setColorGray(double x, double alpha=1) { return setColorRGB(x,x,x,alpha); }
00078   //! Sets the color for future drawing operations
00079   Draw& setColor(Colors c, double alpha=1);
00080   
00081   //! Outline the current path
00082   Draw& stroke();
00083   //! Outline the current path with specified color
00084   Draw& stroke(Colors c, double alpha=1) { return setColor(c,alpha).stroke(); }
00085   //! Outline the current path with specified color
00086   Draw& stroke(double red, double green, double blue, double alpha=1) { return setColorRGB(red,green,blue,alpha).stroke(); }
00087   //! Stroke a single line; if drawing a polygon, better to use lineTo and stroke as a batch
00088   Draw& strokeLine(const fmat::Column<2>& p1, const fmat::Column<2>& p2) { return strokeLine(p1[0],p1[1],p2[0],p2[1]); }
00089   //! Stroke a single line; if drawing a polygon, better to use lineTo and stroke as a batch
00090   Draw& strokeLine(double x1, double y1, double x2, double y2);
00091 
00092   
00093   //! Paint the current path
00094   Draw& fill();
00095   //! Paint the current path with specified color
00096   Draw& fill(Colors c, double alpha=1) { return setColor(c,alpha).fill(); }
00097   //! Paint the current path with specified color
00098   Draw& fill(double red, double green, double blue, double alpha=1) { return setColorRGB(red,green,blue,alpha).fill(); }
00099   
00100   
00101   //! Provides different point() styles
00102   enum PointStyles {
00103     CIRCLE, SQUARE, DIAMOND
00104   };
00105   
00106   //! Produces a output-dimension (i.e. unscaled) symbol at the specified point (follow up with fill() and/or stroke())
00107   Draw& point(const fmat::Column<2>& p, double size, PointStyles style=CIRCLE) { return point(p[0],p[1],size,style); }
00108   //! Produces a output-dimension (i.e. unscaled) symbol at the specified point (follow up with fill() and/or stroke())
00109   Draw& point(double x, double y, double size, PointStyles style=CIRCLE);
00110   
00111   //! Produces an arc of the specified range
00112   Draw& arc(const fmat::Column<2>& p, double r, double begin, double end) { return arc(p[0],p[1],r,begin,end); }
00113   //! Produces an arc of the specified range
00114   Draw& arc(double x, double y, double r, double begin, double end);
00115   
00116   //! Produces a closed path for a circle at the specified point
00117   Draw& circle(const fmat::Column<2>& c, double r) { return arc(c[0],c[1],r,0,2*M_PI); }
00118   //! Produces a closed path for a circle at the specified point
00119   Draw& circle(double x, double y, double r) { return arc(x,y,r,0,2*M_PI); }
00120   
00121   //! Produces an ellipse, note width and height, not major/minor
00122   Draw& ellipse(const fmat::Column<2>& c, double width, double height, double orientation=0);
00123   
00124   //! Produces a closed path for an axis-aligned rectangle
00125   Draw& rect(const BoundingBox2D& r) { return rect(r.min,r.max); }
00126   //! Produces a closed path for an axis-aligned rectangle between the specified points
00127   Draw& rect(const fmat::Column<2>& p1, const fmat::Column<2>& p2);
00128   
00129   //! Draws a line between points with an arrowhead at @a p2, the @a headWidth and @a headLength are multiples of the stroke width
00130   /*! You can stroke to get a barbed head, or fill to get a little triangle.  For a really
00131    *  perfect filled arrowhead, call closePath() first to avoid a little bit of mitred corners sticking out. */
00132   Draw& arrow(const fmat::Column<2>& p1, const fmat::Column<2>& p2, double headWidth=2, double headLength=5);
00133 
00134   //! Produces a closed path for a planner obstacle
00135   Draw& draw(const PlannerObstacle2D& o);
00136   //! Produces a closed path for a planner obstacle
00137   Draw& draw(const RectangularObstacle& o);
00138   //! Produces a closed path for a planner obstacle
00139   Draw& draw(const CircularObstacle& o);
00140   //! Produces a closed path for a planner obstacle
00141   Draw& draw(const EllipticalObstacle& o);
00142   //! Produces a closed path for a planner obstacle
00143   Draw& draw(const ConvexPolyObstacle& o);
00144   //! Produces a closed path for a planner obstacle
00145   Draw& draw(const HierarchicalObstacle& o);
00146   
00147   //! Set the pen location without adding a line segment to the current path.
00148   Draw& moveTo(const fmat::Column<2>& p) { return moveTo(p[0],p[1]); }
00149   //! Set the pen location without adding a line segment to the current path.
00150   /*! Clears previous path unless holdPath() has been called. */
00151   Draw& moveTo(double x, double y);
00152   
00153   //! Add a line segment to the current path
00154   Draw& lineTo(const fmat::Column<2>& p) { return lineTo(p[0],p[1]); }
00155   //! Add a line segment to the current path
00156   Draw& lineTo(double x, double y);
00157   
00158   //! Produces an arc of the specified range (continuing the current path)
00159   Draw& arcTo(const fmat::Column<2>& p, double r, double begin, double end) { return arcTo(p[0],p[1],r,begin,end); }
00160   //! Produces an arc of the specified range (continuing the current path)
00161   Draw& arcTo(double x, double y, double r, double begin, double end);
00162   
00163   //! Add a line segment back to the last moveTo location
00164   Draw& closePath();
00165   
00166   //! Clears path unless @a continuePath is set, additional paths will be collected together until releasePath() is called
00167   Draw& holdPath(bool continuePath=false) { if(!continuePath) clearPath(); addPath=true; return *this; }
00168   //! Clears the hold flag from holdPath(), but does not actually clear the path
00169   Draw& releasePath() { addPath=false; return *this; }
00170   //! Returns current hold setting
00171   bool getHoldMode() const { return addPath; }
00172   
00173   //! Erase current path, but does not reset holdPath() mode
00174   Draw& clearPath();
00175   
00176 protected:
00177   //! Flush pending output and release resources
00178   void teardown();
00179   //! Recomputes and applies the surface transform
00180   void resetTransform();
00181   //! Throws an exception if surface status is not success
00182   void checkSurfaceStatus(const std::string& msg);
00183   //! Throws an exception if either cairo or surface status is not success
00184   void checkStatus(const std::string& msg);
00185   
00186   cairo_t *cr;
00187   cairo_surface_t *surface;
00188   std::string filename;
00189   
00190   fmat::Column<2> origin;
00191   double scale;
00192   double surfaceWidth;
00193   double surfaceHeight;
00194   
00195   //! Indicates state of holdPath()/releasePath(), if true the path isn't cleared between draw calls.
00196   bool addPath;
00197   
00198 private:
00199   Draw(const Draw& o); //!< Do not call
00200   Draw& operator=(const Draw& o); //!< Do not call
00201 };
00202 
00203 /*! @file
00204  * @brief Describes Draw, which provides a simple interface to draw images
00205  * @author ejt (Creator)
00206  */
00207 
00208 #endif

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:37 2016 by Doxygen 1.6.3