src/vamos/geometry/Linear_Interpolator.cc

Go to the documentation of this file.
00001 // Linear_Interpolator.h - a piecewise-linear interpolator.
00002 //
00003 //      Vamos Automotive Simulator
00004 //  Copyright (C) 2003 Sam Varner
00005 //
00006 //  This program is free software; you can redistribute it and/or modify
00007 //  it under the terms of the GNU General Public License as published by
00008 //  the Free Software Foundation; either version 2 of the License, or
00009 //  (at your option) any later version.
00010 //
00011 //  This program is distributed in the hope that it will be useful,
00012 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //  GNU General Public License for more details.
00015 //
00016 //  You should have received a copy of the GNU General Public License
00017 //  along with this program; if not, write to the Free Software
00018 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 #include <vamos/geometry/Linear_Interpolator.h>
00021 
00022 #include <cmath>
00023 #include <cassert>
00024 
00025 Vamos_Geometry::
00026 Linear_Interpolator::Linear_Interpolator () :
00027   m_delta_x (0.0),
00028   m_delta_y (0.0)
00029 {
00030 }
00031 
00032 Vamos_Geometry::
00033 Linear_Interpolator::
00034 Linear_Interpolator (const std::vector <Two_Point>& points) :
00035   m_points (points),
00036   m_delta_x (0.0),
00037   m_delta_y (0.0)
00038 {
00039 }
00040 
00041 void Vamos_Geometry::
00042 Linear_Interpolator::load (const Two_Point& point)
00043 {
00044   m_points.push_back (point);
00045 }
00046 
00047 void Vamos_Geometry::
00048 Linear_Interpolator::load (const std::vector <Two_Point>& points)
00049 {
00050   for (std::vector <Two_Point>::const_iterator it = points.begin ();
00051            it != points.end ();
00052            it++)
00053         {
00054           m_points.push_back (*it);
00055         }
00056 }
00057 
00058 void Vamos_Geometry::
00059 Linear_Interpolator::clear ()
00060 {
00061   m_points.clear ();
00062 }
00063 
00064 // Remove points with x > LIMIT.
00065 void Vamos_Geometry::
00066 Linear_Interpolator::remove_greater (double limit)
00067 {
00068   size_t size = 0;
00069   for (std::vector <Two_Point>::const_iterator it = m_points.begin ();
00070            it != m_points.end ();
00071            it++)
00072         {
00073           if (it->x > limit)
00074                 {
00075                   m_points.resize (size);
00076                   break;
00077                 }
00078           size++;
00079         }
00080 }
00081 
00082 void Vamos_Geometry::
00083 Linear_Interpolator::scale (double factor)
00084 {
00085   for (std::vector <Two_Point>::iterator it = m_points.begin ();
00086            it != m_points.end ();
00087            it++)
00088         {
00089           it->x *= factor;
00090         }
00091 }
00092 
00093 double Vamos_Geometry::
00094 Linear_Interpolator::interpolate (double dist) const
00095 {
00096   assert (m_points.size () > 0);
00097 
00098   if (m_points.size () == 1)
00099         return m_points [0].y;
00100 
00101   if (dist > (m_points.end () - 1)->x)
00102         return (m_points.end () - 1)->y;
00103   if (dist < m_points.begin ()->x)
00104         return m_points.begin ()->y;
00105 
00106   size_t low = 0;
00107   size_t high = m_points.size () - 1;
00108   size_t index;
00109 
00110   // Bisect to find the interval that dist is on.
00111   while ((high - low) > 1)
00112         {
00113           index = size_t ((high + low) / 2.0);
00114           if (m_points [index].x > dist)
00115                 high = index;
00116           else
00117                 low = index;
00118         }
00119 
00120   // Make sure that x_high > x_low.
00121   m_delta_x = m_points [high].x - m_points [low].x;
00122   assert (m_delta_x > 0.0);
00123 
00124   m_delta_y = m_points [high].y - m_points [low].y;
00125 
00126   return m_points [low].y + m_delta_y * (dist - m_points [low].x) / m_delta_x;
00127 }
00128 
00129 Vamos_Geometry::Two_Point Vamos_Geometry::
00130 Linear_Interpolator::normal (double dist) const
00131 {
00132   interpolate (dist);
00133   double theta = std::atan2 (m_delta_y, m_delta_x);
00134   return Two_Point (-std::sin (theta), std::cos (theta));
00135 }

Generated on Thu Oct 19 04:05:55 2006 by  doxygen 1.4.6