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

distance_constraint.cpp

00001 //$Header: /home/ben/Mapper/c++/RCS/distance_constraint.cpp,v 6.4 2002/07/07 18:23:13 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 
00029 #include <cassert>
00030 #include <cmath>
00031 
00032 #include "distance_constraint.h"
00033 #include "vector2.h"
00034 
00035 
00036 
00037 distance_constraint::distance_constraint(
00038    const double u,
00039    const double d
00040    )
00041    :
00042    constraint( u ),
00043    wanted_distance_( d )
00044 {
00045    {//preconditions:
00046       assert( 0.0 < u );
00047       assert( 0.0 <= d );
00048    };
00049    this->points_.reserve( 2 );
00050    static const vector< vector2* > zero( 2U, 0 );
00051    this->points_ = zero;
00052    {//postconditions:
00053       assert( this->uncertainty() == u );
00054       assert( this->wanted_distance() == d );
00055       assert( this->points().size() == 2 );
00056       assert( this->points()[0] == 0 );
00057       assert( this->points()[1] == 0 );
00058    };
00059 }
00060 
00061 
00062 
00063 distance_constraint::~distance_constraint(void)
00064 {
00065    if( this->points_[0] ) unassoc( *this );
00066 }
00067 
00068 
00069 
00070 void distance_constraint::energy(
00071    const double /*tol*/,
00072    const vector< vector2 > &p,
00073    double &e, //output
00074    vector< vector2 > &dedp //output
00075    ) const
00076 {
00077    //tol is a dimensionless calculation tolerance.
00078    //Calculate a dimensionless measure of the potential energy (e)
00079    //of the constraint,
00080    //if this->(*point)[i] had position p[i],
00081    //and the rates of change of that energy dedp
00082    //with respect to the point positions.
00083    //Larger values indicate the constraint is less well satisfied.
00084    //Conventionally, 0 is defined as the minimum possible energy,
00085    //And energy <= 1 indicates that the constraint is satisifed
00086    //to within the uncertainty of the constraint.
00087    {//precondition:
00088       assert( p.size() == 2 );
00089       //assert( 0 < tol && tol < 1 );
00090    };
00091    const vector2 v( p[1] - p[0] );
00092    const double r2 = v * v;
00093    const double r = sqrt( r2 );
00094    const double re = (r - this->wanted_distance())/this->uncertainty();
00095    e = re*re;
00096    {//ensure the output vector haathe correct dimension
00097       static const vector< vector2 > empty2( 2 );
00098       dedp = empty2;
00099    };
00100    if( 0.0 < r2 ){
00101       const vector2 grad( v * (2.0*re/(this->uncertainty() * r2)) );
00102       dedp[1] = grad;
00103       dedp[0] = -grad;
00104    }else{ //special case: coincident points (local maximum)
00105       dedp[0] = vector2( 0, 0 );
00106       dedp[1] = vector2( 0, 0 );
00107    };
00108    {//postconditions:
00109       assert( dedp.size() == 2 );
00110    };
00111 }
00112 
00113 
00114 
00115 void distance_constraint::wanted_distance(
00116    const double d
00117    )
00118 {
00119    {//preconditions:
00120       assert( 0.0 <= d );
00121    };
00122    this->wanted_distance_ = d;
00123    {//postconditions:
00124       assert( this->wanted_distance() == d );
00125    };
00126 }

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