bezier4.h

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 2002-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: Wed Nov 20 12:17:39 2002
00010 // commit: $Id: bezier4.h 10065 2007-04-12 05:54:56Z rjpeters $
00011 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/geom/bezier4.h $
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_GEOM_BEZIER4_H_UTC20050626084023_DEFINED
00035 #define GROOVX_GEOM_BEZIER4_H_UTC20050626084023_DEFINED
00036 
00037 #include "rutz/algo.h"
00038 
00039 #include <cmath>
00040 
00041 namespace geom
00042 {
00043   //  #######################################################
00044   //  =======================================================
00045 
00047 
00048   class bezier4
00049   {
00050   private:
00051     double m_ctrl[4];        // control points
00052 
00053     // coefficients of the Bezier polynomial
00054     // p(u) = c0[0] + c0[1]*u + c0[2]*u^2 + c0[3]*u^3
00055     double m_c0[4];
00056 
00057     // coefficients of the derivative polynomial
00058     // p'(u) = c1[0] + c1[1]*u + c1[2]*u^2
00059     double m_c1[4];
00060 
00061     double m_val_min;
00062     double m_val_max;
00063 
00064     bool m_have_min_max;
00065 
00066     void compute_min_max();
00067 
00068   public:
00070     inline bezier4(double R0, double R1, double R2, double R3);
00071 
00073     inline void set_control_points(double R0, double R1,
00074                                    double R2, double R3);
00075 
00077     inline double eval(double u);
00079     inline double eval_deriv(double u);
00080 
00082     inline double eval_min();
00084     inline double eval_max();
00085   };
00086 
00087 } // end namespace geom
00088 
00089 
00090 //  #######################################################
00091 //  =======================================================
00092 
00093 inline geom::bezier4::bezier4(double R0, double R1,
00094                               double R2, double R3) :
00095   m_ctrl(),
00096   m_c0(),
00097   m_c1(),
00098   m_val_min(0.0),
00099   m_val_max(0.0),
00100   m_have_min_max(false)
00101 {
00102   set_control_points(R0, R1, R2, R3);
00103 }
00104 
00105 inline void geom::bezier4::compute_min_max()
00106 {
00107   double b2_4ac = m_c1[1]*m_c1[1] - 4*m_c1[0]*m_c1[2];
00108 
00109   using rutz::max;
00110   using rutz::min;
00111 
00112   m_val_min = min(eval(0.0), eval(1.0));
00113   m_val_max = max(eval(0.0), eval(1.0));
00114 
00115   if (b2_4ac >= 0.0)
00116     {
00117       double part1 = -m_c1[1] / (2*m_c1[2]);
00118       double part2 = sqrt(b2_4ac) / (2*m_c1[2]);
00119 
00120       double extremum1 = rutz::clamp(part1 + part2, 0.0, 1.0);
00121       double extremum2 = rutz::clamp(part1 - part2, 0.0, 1.0);
00122 
00123       double v1 = eval(extremum1);
00124       double v2 = eval(extremum2);
00125 
00126       if      (v1 < m_val_min) m_val_min = v1;
00127       else if (v1 > m_val_max) m_val_max = v1;
00128 
00129       if      (v2 < m_val_min) m_val_min = v2;
00130       else if (v2 > m_val_max) m_val_max = v2;
00131     }
00132 
00133   m_have_min_max = true;
00134 }
00135 
00136 inline void geom::bezier4::set_control_points(double R0, double R1,
00137                                               double R2, double R3)
00138 {
00139   m_have_min_max = false;
00140 
00141   m_ctrl[0] = R0;
00142   m_ctrl[1] = R1;
00143   m_ctrl[2] = R2;
00144   m_ctrl[3] = R3;
00145 
00146   // Compute polynomial coefficients
00147   m_c0[0] =    m_ctrl[0];
00148   m_c0[1] = -3*m_ctrl[0] + 3*m_ctrl[1];
00149   m_c0[2] =  3*m_ctrl[0] - 6*m_ctrl[1] + 3*m_ctrl[2];
00150   m_c0[3] =   -m_ctrl[0] + 3*m_ctrl[1] - 3*m_ctrl[2] + m_ctrl[3];
00151 
00152   // Compute polynomial coefficients of derivative
00153   m_c1[0] = 1 * m_c0[1];
00154   m_c1[1] = 2 * m_c0[2];
00155   m_c1[2] = 3 * m_c0[3];
00156 }
00157 
00158 inline double geom::bezier4::eval(double u)
00159 {
00160   return (m_c0[0] + m_c0[1]*u + m_c0[2]*u*u + m_c0[3]*u*u*u);
00161 }
00162 
00163 inline double geom::bezier4::eval_deriv(double u)
00164 {
00165   return (m_c1[0] + m_c1[1]*u + m_c1[2]*u*u);
00166 }
00167 
00168 inline double geom::bezier4::eval_max()
00169 {
00170   if (!m_have_min_max) compute_min_max();
00171   return m_val_max;
00172 }
00173 
00174 inline double geom::bezier4::eval_min()
00175 {
00176   if (!m_have_min_max) compute_min_max();
00177   return m_val_min;
00178 }
00179 
00180 static const char __attribute__((used)) vcid_groovx_geom_bezier4_h_utc20050626084023[] = "$Id: bezier4.h 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00181 #endif // !GROOVX_GEOM_BEZIER4_H_UTC20050626084023_DEFINED

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