linestrip.cc

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 2004-2004 California Institute of Technology
00006 // Copyright (c) 2004-2007 University of Southern California
00007 // Rob Peters <rjpeters at usc dot edu>
00008 //
00009 // created: Thu Jun  3 17:03:05 2004
00010 // commit: $Id: linestrip.cc 10065 2007-04-12 05:54:56Z rjpeters $
00011 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/gfx/linestrip.cc $
00012 //
00013 // --------------------------------------------------------------------
00014 //
00015 // This file is part of GroovX.
00016 //   [http://ilab.usc.edu/rjpeters/groovx/]
00017 //
00018 // GroovX is free software; you can redistribute it and/or modify it
00019 // under the terms of the GNU General Public License as published by
00020 // the Free Software Foundation; either version 2 of the License, or
00021 // (at your option) any later version.
00022 //
00023 // GroovX is distributed in the hope that it will be useful, but
00024 // WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026 // General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License
00029 // along with GroovX; if not, write to the Free Software Foundation,
00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00031 //
00033 
00034 #ifndef GROOVX_GFX_LINESTRIP_CC_UTC20050626084024_DEFINED
00035 #define GROOVX_GFX_LINESTRIP_CC_UTC20050626084024_DEFINED
00036 
00037 #include "linestrip.h"
00038 
00039 #include "geom/bezier4.h"
00040 #include "geom/vec3.h"
00041 
00042 #include "gfx/canvas.h"
00043 
00044 #include "rutz/error.h"
00045 
00046 #include "rutz/trace.h"
00047 #include "rutz/debug.h"
00048 GVX_DBG_REGISTER
00049 
00050 using geom::vec2d;
00051 using geom::vec3d;
00052 
00053 Gfx::LineStrip::LineStrip() :
00054   canvas(0),
00055   pts(0),
00056   width(1.0),
00057   join(false),
00058   loop(false)
00059 {
00060 GVX_TRACE("Gfx::LineStrip::LineStrip");
00061 }
00062 
00063 void Gfx::LineStrip::lineJoin(bool doJoin)
00064 {
00065 GVX_TRACE("Gfx::LineStrip::lineJoin");
00066   join = doJoin;
00067 }
00068 
00069 void Gfx::LineStrip::closeLoop(bool doClose)
00070 {
00071 GVX_TRACE("Gfx::LineStrip::closeLoop");
00072   loop = doClose;
00073 }
00074 
00075 void Gfx::LineStrip::begin(Gfx::Canvas& c, double w)
00076 {
00077 GVX_TRACE("Gfx::LineStrip::begin");
00078 
00079   if (pts.size() != 0)
00080     {
00081       throw rutz::error("LineStrip::end() not called before LineStrip::begin()", SRC_POS);
00082     }
00083 
00084   GVX_ASSERT(canvas == 0);
00085 
00086   canvas = &c;
00087   width = w;
00088 }
00089 
00090 void Gfx::LineStrip::vertex(const vec2d& pt)
00091 {
00092 GVX_TRACE("Gfx::LineStrip::vertex");
00093   pts.push_back(pt);
00094 }
00095 
00096 void Gfx::LineStrip::drawBezier4(const vec3d& p1,
00097                                  const vec3d& p2,
00098                                  const vec3d& p3,
00099                                  const vec3d& p4,
00100                                  unsigned int subdivisions,
00101                                  unsigned int start)
00102 {
00103 GVX_TRACE("Gfx::LineStrip::drawBezier4");
00104   geom::bezier4 xb(p1.x(), p2.x(), p3.x(), p4.x());
00105   geom::bezier4 yb(p1.y(), p2.y(), p3.y(), p4.y());
00106   //     geom::bezier4 zb(p1.z(), p2.z(), p3.z(), p4.z());
00107 
00108   for (unsigned int i = start; i < subdivisions; ++i)
00109     {
00110       double u = double(i) / double(subdivisions - 1);
00111       this->vertex(vec2d(xb.eval(u), yb.eval(u)));
00112     }
00113 }
00114 
00115 void Gfx::LineStrip::end()
00116 {
00117 GVX_TRACE("Gfx::LineStrip::end");
00118 
00119   if (pts.size() == 0) return;
00120 
00121   GVX_ASSERT(canvas != 0);
00122 
00123   if (join)
00124     drawJoinedLineStrip();
00125   else
00126     drawSimpleLineStrip();
00127 
00128   canvas = 0;
00129   pts.clear();
00130 }
00131 
00132 void Gfx::LineStrip::drawSimpleLineStrip()
00133 {
00134 GVX_TRACE("Gfx::LineStrip::drawSimpleLineStrip");
00135   if (loop)
00136     canvas->beginLineLoop();
00137   else
00138     canvas->beginLineStrip();
00139   for (unsigned int i = 0; i < pts.size(); ++i)
00140     {
00141       canvas->vertex2(pts[i]);
00142     }
00143   canvas->end();
00144 }
00145 
00146 namespace
00147 {
00148   // Given two line segments with unit-normalized slopes of d1 and d2,
00149   // return the appropriate normal vector at the join point. The angle of
00150   // this result will be halfway between that of the normal vectors to d1
00151   // and d2, and the length of the result will be determined by the angle
00152   // of the intersection.
00153   vec2d joinedNormal(const vec2d& d1, const vec2d& d2)
00154   {
00155     const vec2d n1 = normal_to(d1);
00156     const vec2d n2 = normal_to(d2);
00157 
00158     double c = 0.0;
00159     if      (d1.x()+d2.x() != 0.0) { c = (n2.x() - n1.x()) / (d1.x() + d2.x()); }
00160     else if (d1.y()+d2.y() != 0.0) { c = (n2.y() - n1.y()) / (d1.y() + d2.y()); }
00161 
00162     return vec2d(n2 - d2 * c);
00163   }
00164 }
00165 
00166 void Gfx::LineStrip::drawJoinedLineStrip()
00167 {
00168 GVX_TRACE("Gfx::LineStrip::drawJoinedLineStrip");
00169   canvas->beginQuadStrip();
00170 
00171   vec2d d1;
00172   vec2d d2;
00173 
00174   vec2d start_pt1;
00175   vec2d start_pt2;
00176 
00177   for (unsigned int i = 1; i <= pts.size(); ++i)
00178     {
00179       if (i == pts.size())
00180         {
00181           if (loop) d2 = make_unit_length(pts[0] - pts[i-1]);
00182           else      d2 = d1;
00183         }
00184       else
00185         {
00186           d2 = make_unit_length(pts[i] - pts[i-1]);
00187         }
00188 
00189       if (i == 1)
00190         {
00191           if (loop) d1 = make_unit_length(pts[0] - pts.back());
00192           else      d1 = d2;
00193         }
00194 
00195       const vec2d use_n = joinedNormal(d1, d2);
00196 
00197       const vec2d pt1 = pts[i-1] - use_n*width;
00198       const vec2d pt2 = pts[i-1] + use_n*width;
00199 
00200       canvas->vertex2(pt1);
00201       canvas->vertex2(pt2);
00202 
00203       if (i == 1)
00204         {
00205           start_pt1 = pt1;
00206           start_pt2 = pt2;
00207         }
00208 
00209       d1 = d2;
00210     }
00211 
00212   if (loop)
00213     {
00214       canvas->vertex2(start_pt1);
00215       canvas->vertex2(start_pt2);
00216     }
00217 
00218   canvas->end();
00219 }
00220 
00221 static const char __attribute__((used)) vcid_groovx_gfx_linestrip_cc_utc20050626084024[] = "$Id: linestrip.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00222 #endif // !GROOVX_GFX_LINESTRIP_CC_UTC20050626084024_DEFINED

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:39 2008 by Doxygen version 1.5.5.