Main Page   Namespace List   Class Hierarchy   Compound List   File List   Header Files   Sources   Namespace Members   Compound Members   File Members  

bearing_constraint.cpp

00001 //$Header: /home/ben/Mapper/c++/RCS/bearing_constraint.cpp,v 6.2 2002/06/14 22:28:47 ben Exp $
00002 // Copyright Benedict Adamson 2002.
00003 // This file is part of Mapper.
00004 
00005 // Mapper is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or
00008 // (at your option) any later version.
00009 
00010 // Mapper is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 
00015 // You should have received a copy of the GNU General Public License
00016 // along with Mapper; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00027 #include "bearing_constraint.h"
00028 
00029 
00030 
00031 #include <cmath>
00032 #include "vector2.h"
00033 
00034 
00035 
00036 static const double pi = M_PI;
00037 
00038 
00039 
00040 bearing_constraint::bearing_constraint(
00041    const double u,
00042    const double b
00043    )
00044    :
00045    constraint( u ),
00046    wanted_bearing_( b )
00047 {
00048    this->points_.reserve( 2 );
00049    const vector< vector2* > zero( 2U, 0 );
00050    this->points_ = zero;
00051    {//postconditions:
00052       assert( this->uncertainty() == u );
00053       assert( this->wanted_bearing() == b );
00054       assert( this->points().size() == 2 );
00055    };
00056 }
00057 
00058 
00059 
00060 bearing_constraint::~bearing_constraint(void)
00061 {
00062    if( this->points_[0] ) unassoc( *this );
00063 }
00064 
00065 
00066 
00067 void bearing_constraint::energy(
00068    const double /*tol*/,
00069    const vector< vector2 > &p,
00070    double &e, //output
00071    vector< vector2 > &dedp //output
00072    ) const
00073 {
00074    //tol is a dimensionless calculation tolerance.
00075    //Calculate a dimensionless measure of the potential energy (e)
00076    //of the constraint,
00077    //if this->(*point)[i] had position (x[i], y[i]),
00078    //and the rates of change of that energy (dedx, dedy)
00079    //with respect to the point positions.
00080    //Larger values indicate the constraint is less well satisfied.
00081    //Conventionally, 0 is defined as the minimum possible energy,
00082    //And energy <= 1 indicates that the constraint is satisifed
00083    //to within the uncertainty of the constraint.
00084    {//precondition:
00085       assert( p.size() == 2 );
00086       //assert( 0 < tol && tol < 1 );
00087    };
00088    {//ensure returned gradient vector has the correct dimension
00089      static const vector< vector2 > empty( 2 );
00090      dedp = empty;
00091    };
00092    const vector2 v( p[1] - p[0] );
00093    const double r2 = v*v;
00094    if( 0.0 < r2 ){
00095       //calculate angles
00096       const double a = atan2( v.x, v.y );
00097       double da = a - this->wanted_bearing();
00098       while( pi < da ) da -= 2.0*pi;
00099       while( da < -pi ) da += 2.0*pi;
00100       assert( -pi <= da && da <= pi );
00101       //calculate energy
00102       const double ae = da / this->uncertainty();
00103       e =  ae*ae;
00104       {//calculate gradients
00105          const vector2 grad(
00106             vector2( -v.y, v.x ) * 2.0*ae/
00107             (r2 * this->uncertainty())
00108             );
00109          dedp[0] = grad;
00110          dedp[1] = -grad;
00111       };
00112    }else{
00113       e = 0.0;
00114       dedp[0] = vector2( 0, 0 );
00115       dedp[1] = vector2( 0, 0 );
00116    };
00117    {//postconditions:
00118       assert( dedp.size() == 2 );
00119    };
00120 }
00121 
00122 
00123 
00124 void bearing_constraint::wanted_bearing(
00125    const double d
00126    )
00127 {
00128    {//preconditions:
00129       assert( 0.0 <= d );
00130    };
00131    this->wanted_bearing_ = d;
00132    {//postconditions:
00133       assert( this->wanted_bearing() == d );
00134    };
00135 }

Generated at Sun Jul 14 20:38:07 2002 for Mapper by doxygen 1.0.0 written by Dimitri van Heesch, © 1997-1999