00001 /** 00002 \file Robots/LoBot/misc/LoLineRasterizer.H 00003 \brief Bresenham's line rasterization algorithm. 00004 00005 This file defines a function that rasterizes a line given its two end 00006 points. The whole thing works entirely with integer math and ought to 00007 be a fairly quick way of performing ray casting operations (for 00008 example). 00009 */ 00010 00011 // //////////////////////////////////////////////////////////////////// // 00012 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00013 // by the University of Southern California (USC) and the iLab at USC. // 00014 // See http://iLab.usc.edu for information about this project. // 00015 // //////////////////////////////////////////////////////////////////// // 00016 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00017 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00018 // in Visual Environments, and Applications'' by Christof Koch and // 00019 // Laurent Itti, California Institute of Technology, 2001 (patent // 00020 // pending; application number 09/912,225 filed July 23, 2001; see // 00021 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00022 // //////////////////////////////////////////////////////////////////// // 00023 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00024 // // 00025 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00026 // redistribute it and/or modify it under the terms of the GNU General // 00027 // Public License as published by the Free Software Foundation; either // 00028 // version 2 of the License, or (at your option) any later version. // 00029 // // 00030 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00031 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00032 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00033 // PURPOSE. See the GNU General Public License for more details. // 00034 // // 00035 // You should have received a copy of the GNU General Public License // 00036 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00037 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00038 // Boston, MA 02111-1307 USA. // 00039 // //////////////////////////////////////////////////////////////////// // 00040 // 00041 // Primary maintainer for this file: mviswana usc edu 00042 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/misc/LoLineRasterizer.H $ 00043 // $Id: LoLineRasterizer.H 13445 2010-05-21 06:12:57Z mviswana $ 00044 // 00045 00046 #ifndef LOBOT_LINE_RASTERIZER_DOT_H 00047 #define LOBOT_LINE_RASTERIZER_DOT_H 00048 00049 //------------------------------ HEADERS -------------------------------- 00050 00051 // lobot headers 00052 #include "Robots/LoBot/util/LoMath.H" 00053 00054 // Standard C++ headers 00055 #include <algorithm> 00056 00057 //----------------------------- NAMESPACE ------------------------------- 00058 00059 namespace lobot { 00060 00061 //------------------------- CLASS DEFINITION ---------------------------- 00062 00063 /** 00064 \function lobot::rasterize_line 00065 \brief Rasterize a line using Bresenham's algorithm. 00066 00067 This function implements Bresenham's line rasterization algorithm to 00068 compute the pixels that lie between two points (x0, y0) and (x1, y1). 00069 For each pixel along the way, it will invoke the set_pixel function, 00070 which is to be supplied by the client. This function will be passed 00071 two parameters, viz., the x and y coordinates of the pixel being 00072 visited. As the set_pixel function is a template parameter, it can 00073 also be a function object rather than a function. 00074 00075 This implementation of Bresenham's line algorithm also includes an 00076 early exit test. If the client-supplied set_pixel visitor function 00077 returns false, the algorithm will terminate. This feature is useful in 00078 a ray casting/collision detection context. Thus, in addition to taking 00079 two integers, the client-supplied set_pixel visitor function is also 00080 expected to return a bool to indicate whether the rasterization should 00081 continue on to the next pixel or not. 00082 00083 NOTE: This implementation is a slightly modified version of the 00084 optimized, integer math based one described on Wikipedia. The 00085 modification ensures that we *always* start at (x0, y0) and rasterize 00086 towards (x1, y1). This is required when the algorithm is employed in a 00087 ray casting context (which is what it is in fact used for in 00088 Robolocust). The early exit test is also an addition in this version. 00089 */ 00090 template<typename visitor_fn> 00091 void rasterize_line(int x0, int y0, int x1, int y1, visitor_fn set_pixel) 00092 { 00093 bool steep = abs(y1 - y0) > abs(x1 - x0) ; 00094 if (steep) { 00095 std::swap(x0, y0) ; 00096 std::swap(x1, y1) ; 00097 } 00098 00099 int deltax = abs(x1 - x0) ; 00100 int deltay = abs(y1 - y0) ; 00101 int error = deltax/2 ; 00102 int ystep = (y0 < y1) ? 1 : -1 ; 00103 int xstep ; 00104 if (x0 < x1) 00105 { 00106 xstep = 1 ; 00107 ++x1 ; ++y1 ; 00108 } 00109 else 00110 { 00111 xstep = -1 ; 00112 --x1 ; --y1 ; 00113 } 00114 00115 int y = y0 ; 00116 for (int x = x0; x != x1; x += xstep) 00117 { 00118 bool cont = true ; 00119 if (steep) 00120 cont = set_pixel(y, x) ; 00121 else 00122 cont = set_pixel(x, y) ; 00123 if (! cont) 00124 break ; 00125 error -= deltay ; 00126 if (error < 0) { 00127 y += ystep ; 00128 error += deltax ; 00129 } 00130 } 00131 } 00132 00133 //----------------------------------------------------------------------- 00134 00135 } // end of namespace encapsulating this file's definitions 00136 00137 #endif 00138 00139 /* So things look consistent in everyone's emacs... */ 00140 /* Local Variables: */ 00141 /* indent-tabs-mode: nil */ 00142 /* End: */