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

MapDataDocument_convert_Tracing.cpp

00001 //$Header: /home/ben/Mapper/c++/RCS/MapDataDocument_convert_Tracing.cpp,v 6.14 2002/07/14 17:25:32 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 
00031 #include <cstdio>
00032 #include <cstdlib>
00033 #include <cstring>
00034 #include <memory>
00035 
00036 #include <dom/DOM_Attr.hpp>
00037 #include <dom/DOM_DOMException.hpp>
00038 #include <dom/DOM_Element.hpp>
00039 #include <dom/DOM_Document.hpp>
00040 #include <dom/DOM_Node.hpp>
00041 
00042 #include <string>
00043 
00044 #include "MapDataDocument.h"
00045 #include "MapperErrorHandler.h"
00046 #include "angle_constraint.h"
00047 #include "assoc.h"
00048 #include "constraint.h"
00049 #include "delaunay.h"
00050 #include "vector2.h"
00051 #include "through_constraint.h"
00052 
00053 
00054 
00055 void MapDataDocument::convert_Traced_point(
00056    map< vector2, vector2 *, order_vector2 > &traced_points, //input, output
00057    map< vector2, double, order_vector2 > &point_uncertainties, //input, output
00058    DOM_Element &elem, //input
00059    const double tracing_width,
00060    const double tracing_height,
00061    const double default_uncertainty
00062    )
00063    throw(
00064       error::element_error
00065       )
00066 {
00067    {//preconditions:
00068       assert( 0 < tracing_width );
00069       assert( 0 < tracing_height );
00070       assert( 0 < default_uncertainty );
00071    };
00072    bool anon;
00073    string name;
00074    vector2 position;
00075    vector2 *point; 
00076    double uncertainty = default_uncertainty;
00077    {//retrieve the attribute values
00078       require_attribute( elem, "tx" );
00079       require_attribute( elem, "ty" );
00080       if( has_attribute( elem, "point" ) ){
00081          anon = false;
00082          get_attribute( name, elem, "point" );
00083          this->get_attribute( point, elem, "point" );
00084       }else{ //anonymous point
00085          anon = true;
00086          name = "(anonymous)";
00087          vector2 global_position( this->random_position() );
00088          if( has_attribute( elem, "x" ) )
00089             get_attribute( global_position.x, elem, "x" );
00090          ;
00091          if( has_attribute( elem, "y" ) )
00092             get_attribute( global_position.y, elem, "y" );
00093          ;
00094          point = new vector2( global_position );
00095       };
00096       get_attribute( position.x, elem, "tx" );
00097       get_attribute( position.y, elem, "ty" );
00098       if( has_attribute( elem, "uncertainty" ) ){
00099          get_attribute( uncertainty, elem, "uncertainty" );
00100       };
00101    };
00102    {//check attribute values
00103       if( position.x < 0 || tracing_width < position.x )
00104          throw error::attribute_error( elem, "out of range", "tx" );
00105       ;
00106       if( position.y < 0 || tracing_height < position.y )
00107          throw error::attribute_error( elem, "out of range", "ty" );
00108       ;
00109       if( 0 < traced_points.count( position ) )
00110          throw error::element_error( elem, "position already traced" );
00111       ;
00112       if( uncertainty <= 0 )
00113          throw error::attribute_error( elem, "not positive", "uncertainty" );
00114       ;
00115    };
00116    {//Add the traced point to data structures
00117       assert( point );
00118       traced_points[ position ] = point;
00119       point_uncertainties[ position ] = uncertainty;
00120       if( anon ){
00121          this->anon_points_.push_back( point );
00122       };
00123       elem.setUserData( point );
00124    };
00125 }
00126 
00127 
00128 
00129 void MapDataDocument::add_angle_constraint(
00130    const vector2 &vf, //local coordinates
00131    const vector2 &va,
00132    const vector2 &vt,
00133    vector2 *pf, //points, input
00134    vector2 *pa,
00135    vector2 *pt,
00136    const double uf, //uncertainties
00137    const double ua,
00138    const double ut
00139    )
00140 {
00141    {//Preconditions
00142       assert( pf );
00143       assert( pa );
00144       assert( pt );
00145       assert( 0 < uf );
00146       assert( 0 < ua );
00147       assert( 0 < ut );
00148    }
00149    const double r1c1 = vf.x - va.x;
00150    const double r1s1 = vf.y - va.y;
00151    const double r2c2 = vt.x - va.x;
00152    const double r2s2 = vt.y - va.y;
00153    const double r1 = hypot( r1c1, r1s1 );
00154    const double r2 = hypot( r2c2, r2s2 );
00155    assert( 0 < r1 );
00156    assert( 0 < r2 );
00157    const double a1 = atan2( r1s1, r1c1 );
00158    const double a2 = atan2( r2s2, r2c2 );
00159    const double angle = a2 - a1;
00160    const double u1 = (uf + ua)/ r1;
00161    const double u2 = (ut + ua)/ r2;
00162    const double uncertainty = u1 + u2;
00163    angle_constraint *a = new angle_constraint( uncertainty, angle );
00164    assoc( *a, *pa, *pf, *pt );
00165    this->constraints_.push_back( a );
00166 }
00167 
00168 
00169 
00170 void MapDataDocument::convert_Tracing(
00171    DOM_Element &elem,
00172    MapperErrorHandler &err_handler
00173    )
00174    throw(
00175       error::attribute_error
00176       )
00177 {
00178    double length_uncertainty;
00179    double tracing_height;
00180    double tracing_width;
00181    {//process the attributes of the Tracing tag
00182       {//get attributes
00183          get_attribute( length_uncertainty, elem, "length-uncertainty" );
00184          get_attribute( tracing_width, elem, "width" );
00185          get_attribute( tracing_height, elem, "height" );
00186       };
00187       {//check attribute values
00188          if( length_uncertainty <= 0 )
00189             throw error::attribute_error(
00190                elem, "not positive", "length-uncertainty"
00191                );
00192          ;
00193          if( tracing_width <= 0 )
00194             throw error::attribute_error( elem, "not positive", "width" );
00195          ;
00196          if( tracing_height <= 0 )
00197             throw error::attribute_error( elem, "not positive", "height" );
00198          ;
00199       };
00200    }
00201    map< vector2, vector2 *, order_vector2 > traced_points;
00202    map< vector2, double, order_vector2 > point_uncertainties;
00203    {//process children of the element
00204       DOM_NodeList children( elem.getChildNodes() );
00205       for( unsigned i = 0; i < children.getLength(); i++ ){
00206          DOM_Node node( children.item(i) );
00207          if( node.getNodeType() != DOM_Node::ELEMENT_NODE ) continue;
00208          DOM_Element &child( static_cast< DOM_Element & >( node ) );
00209          DOMString tag( child.getTagName() );
00210          try{
00211             if(       DOMString("Cite").equals( tag ) )
00212                ;//Do nothing
00213             else if(  DOMString("Traced-point").equals( tag ) )
00214                this->convert_Traced_point(
00215                   traced_points, point_uncertainties,
00216                   child, tracing_width, tracing_height, length_uncertainty
00217                   );
00218             else{
00219                throw error::element_error( child, "unexpected element" );
00220             };
00221          }catch( error::element_error &e ){
00222             err_handler.error( e );
00223          };
00224       };
00225    };
00226    delaunay::triangulation triangulation(
00227       -tracing_width, tracing_width*1.1,
00228       tracing_height*1.1, -tracing_height
00229       );
00230    {//create triangulation
00231       for( map< vector2, vector2 *,order_vector2 >::iterator i =
00232               traced_points.begin();
00233            i != traced_points.end();
00234            i++ ){
00235          const vector2 &position( (*i).first );
00236          triangulation.add_point( position );
00237       };
00238    };
00239    {//create constraints
00240       const vector< delaunay::triangle > &triangles(
00241          triangulation.triangles()
00242          );
00243       for( vector< delaunay::triangle >::const_iterator i = triangles.begin();
00244            i != triangles.end();
00245            i++ ){
00246          const delaunay::triangle &t( *i );
00247          if( ! triangulation.border_triangle( t ) ){
00248             //create an angle constraint for each vertex of that triangle
00249          
00250             const vector2 &v0( t.vertex(0) );
00251             const vector2 &v1( t.vertex(1) );
00252             const vector2 &v2( t.vertex(2) );
00253             vector2 *p0 = traced_points[ v0 ];
00254             vector2 *p1 = traced_points[ v1 ];
00255             vector2 *p2 = traced_points[ v2 ];
00256             const double u0 = point_uncertainties[ v0 ];
00257             const double u1 = point_uncertainties[ v1 ];
00258             const double u2 = point_uncertainties[ v2 ];
00259 
00260             add_angle_constraint(
00261                v0, v1, v2,
00262                p0, p1, p2,
00263                u0, u1, u2
00264                );
00265             add_angle_constraint(
00266                v1, v2, v0,
00267                p1, p2, p0,
00268                u1, u2, u0
00269                );
00270             add_angle_constraint(
00271                v2, v0, v1,
00272                p2, p0, p1,
00273                u2, u0, u1
00274                );
00275          };//else skip that triangle
00276       };
00277    };
00278 }

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