LoClipper.C

Go to the documentation of this file.
00001 /**
00002    \file Robots/LoBot/misc/LoClipper.C
00003 
00004    This file defines the non-inline member functions of the
00005    lobot::Clipper class.
00006 */
00007 
00008 // //////////////////////////////////////////////////////////////////// //
00009 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00010 // by the University of Southern California (USC) and the iLab at USC.  //
00011 // See http://iLab.usc.edu for information about this project.          //
00012 // //////////////////////////////////////////////////////////////////// //
00013 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00014 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00015 // in Visual Environments, and Applications'' by Christof Koch and      //
00016 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00017 // pending; application number 09/912,225 filed July 23, 2001; see      //
00018 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00019 // //////////////////////////////////////////////////////////////////// //
00020 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00023 // redistribute it and/or modify it under the terms of the GNU General  //
00024 // Public License as published by the Free Software Foundation; either  //
00025 // version 2 of the License, or (at your option) any later version.     //
00026 //                                                                      //
00027 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00028 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00029 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00030 // PURPOSE.  See the GNU General Public License for more details.       //
00031 //                                                                      //
00032 // You should have received a copy of the GNU General Public License    //
00033 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00034 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00035 // Boston, MA 02111-1307 USA.                                           //
00036 // //////////////////////////////////////////////////////////////////// //
00037 //
00038 // Primary maintainer for this file: mviswana usc edu
00039 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/misc/LoClipper.C $
00040 // $Id: LoClipper.C 13445 2010-05-21 06:12:57Z mviswana $
00041 //
00042 
00043 //------------------------------ HEADERS --------------------------------
00044 
00045 // lobot headers
00046 #include "Robots/LoBot/misc/LoClipper.H"
00047 
00048 //----------------------------- NAMESPACE -------------------------------
00049 
00050 namespace lobot {
00051 
00052 //------------------------- INITIALIZATION -----------------------------
00053 
00054 Clipper::Clipper(float left, float right, float bottom, float top)
00055 {
00056    clip_boundary(left, right, bottom, top) ;
00057 }
00058 
00059 Clipper::Clipper(const float boundary[4])
00060 {
00061    clip_boundary(boundary) ;
00062 }
00063 
00064 //------------------ COHEN-SUTHERLAND LINE CLIPPING ---------------------
00065 
00066 unsigned char
00067 Clipper::
00068 clip(const float end_points[4], float new_end_points[4]) const
00069 {
00070    unsigned char return_code = 0 ;
00071 
00072    new_end_points[0] = end_points[0] ;
00073    new_end_points[1] = end_points[1] ;
00074    new_end_points[2] = end_points[2] ;
00075    new_end_points[3] = end_points[3] ;
00076 
00077    float dx = new_end_points[2] - new_end_points[0] ;
00078    float dy = new_end_points[3] - new_end_points[1] ;
00079 
00080    for(;;)
00081    {
00082       unsigned char code1 = cs_code(new_end_points) ;
00083       unsigned char code2 = cs_code(new_end_points + 2) ;
00084 
00085       if (trivial_accept(code1, code2)) {
00086          if (return_code == 0)
00087             return_code = COMPLETELY_INSIDE ;
00088          return return_code ;
00089       }
00090 
00091       if (trivial_reject(code1, code2))
00092          return COMPLETELY_OUTSIDE ;
00093 
00094       if (outside(new_end_points))
00095       {  // first end-point outside clipping rectangle
00096          chop(new_end_points, code1, dx, dy) ;
00097          return_code |= FIRST_POINT_CLIPPED ;
00098       }
00099       else // second end-point must be outside clipping rectangle
00100       {    // or else the line would have been accepted or rejected
00101          chop(new_end_points + 2, code2, dx, dy) ;
00102          return_code |= SECOND_POINT_CLIPPED ;
00103       }
00104    }
00105 
00106    return return_code ;
00107 }
00108 
00109 /// The Cohen-Sutherland code for a point consists of four bit flags as
00110 /// described below:
00111 ///    bit 3 = 1 ==> point is to the left of the clipping rectangle
00112 ///    bit 2 = 1 ==> point is above the clipping rectangle
00113 ///    bit 1 = 1 ==> point is to the right of the clipping rectangle
00114 ///    bit 0 = 1 ==> point is below the clipping rectangle
00115 unsigned char Clipper::cs_code(const float point[2]) const
00116 {
00117    unsigned char code = 0 ; // initially assume point is inside
00118 
00119    if (point[0] < m_clip_boundary[0])
00120       code |= LEFT_BIT ;
00121 
00122    if (point[1] > m_clip_boundary[3])
00123       code |= TOP_BIT ;
00124 
00125    if (point[0] > m_clip_boundary[1])
00126       code |= RIGHT_BIT ;
00127 
00128    if (point[1] < m_clip_boundary[2])
00129       code |= BOTTOM_BIT ;
00130 
00131    return code ;
00132 }
00133 
00134 /*
00135    If a line can not be trivially accepted or rejected, we break the line
00136    into two parts at the appropriate clipping boundary and reject the
00137    portion that lies outside. Then we test the remaining portion against
00138    the edges and continue until we get an acceptance or rejection.
00139 
00140    The remaining portion of the line is obtained by "moving" that point
00141    along the line to the intersection of the line with the clipping
00142    boundary it is being tested against. For eg., consider the situation
00143    shown below:
00144 
00145                            +--------
00146                            | P2
00147                            | /|
00148                            |/ |
00149                           I/  |
00150                           /|  dy
00151                          / h  |
00152                         /  |  |
00153                        /-+-|--+
00154                       P1 |
00155                          +--> dx
00156 
00157    We need to compute the intersection of P1-P2 with the left boundary
00158    of the clipping rectangle and make P1 that intersection. Let the
00159    intersection point be I. Obviously, the x-coordinate of I is the
00160    x-coordinate of the left edge. Let the horizontal distance between
00161    P1 and the left edge be d. From similar triangles, we get:
00162 
00163       h/dy = d/dx ==> h = d * dy/dx
00164 
00165    We can easily compute d:
00166 
00167       d = left - P1.x
00168 
00169    Therefore,
00170 
00171       I.y = P1.y + (left - P1.x) * dy/dx
00172 
00173    And if P1 were to become I, then we'd get:
00174 
00175       P1.y  = P1.y + (left - P1.x) * dy/dx
00176    or P1.y += (left - P1.x) * dy/dx
00177 
00178    Similar reasoning can be applied for the other cases.
00179 */
00180 void
00181 Clipper::
00182 chop(float point[2], unsigned char code, float dx, float dy) const
00183 {
00184    if (code & LEFT_BIT)
00185    {
00186       point[1] += (m_clip_boundary[0] - point[0]) * dy/dx ;
00187       point[0]  =  m_clip_boundary[0] ;
00188    }
00189    else if (code & RIGHT_BIT)
00190    {
00191       point[1] += (m_clip_boundary[1] - point[0]) * dy/dx ;
00192       point[0]  =  m_clip_boundary[1] ;
00193    }
00194    else if (code & BOTTOM_BIT)
00195    {
00196       point[0] += (m_clip_boundary[2] - point[1]) * dx/dy ;
00197       point[1]  =  m_clip_boundary[2] ;
00198    }
00199    else if (code & TOP_BIT)
00200    {
00201       point[0] += (m_clip_boundary[3] - point[1]) * dx/dy ;
00202       point[1]  =  m_clip_boundary[3] ;
00203    }
00204 }
00205 
00206 //----------------------------------------------------------------------
00207 
00208 } // end of namespace encapsulating this file's definitions
00209 
00210 /* So things look consistent in everyone's emacs... */
00211 /* Local Variables: */
00212 /* indent-tabs-mode: nil */
00213 /* End: */
Generated on Sun May 8 08:41:31 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3