Tag.cpp
Go to the documentation of this file.
00001 // Copyright (c) 2013-2014 by Wayne C. Gramlich.  All rights reserved.
00002 
00003 #include <assert.h>
00004 #include <angles/angles.h>
00005 
00006 #include "Arc.hpp"
00007 #include "Bounding_Box.hpp"
00008 #include "SVG.hpp"
00009 #include "Tag.hpp"
00010 
00011 // *Tag* routines:
00012 
00018 
00019 void Tag::arc_append(Arc * arc) {
00020     assert(arc->from_tag == this || arc->to_tag == this);
00021     arcs_.push_back(arc);
00022 }
00023 
00031 
00032 void Tag::bounding_box_update(BoundingBox *bounding_box) {
00033     double half_diagonal = world_diagonal / 2.0;
00034     bounding_box->update(x - half_diagonal , y - half_diagonal);
00035     bounding_box->update(x + half_diagonal , y + half_diagonal);
00036 }
00037 
00045 
00046 int Tag::equal(Tag *tag1, Tag *tag2) {
00047   return tag1->id == tag2->id;
00048 }
00049 
00050 bool Tag::less(Tag *tag1, Tag *tag2) {
00051   return tag1->id < tag2->id;
00052 }
00053 
00062 
00063 Tag::Tag(unsigned int id, Map map) :
00064     twist(0.0),
00065     diagonal(0.0),
00066     hop_count(0),
00067     id(id),
00068     initialized(false),
00069     map(map),
00070     visit(map->visit),
00071     x(0.0), y(0.0), 
00072     updated(true)
00073 {
00074     TagHeight * tag_height = Map__tag_height_lookup(map, id);
00075     world_diagonal = tag_height->world_diagonal;
00076     z = tag_height->z;
00077 }
00078 
00093 
00094 void Tag::initialize(double twist, double x, double y, double diagonal,
00095     unsigned int visit) {
00096     this->diagonal = diagonal; 
00097     this->initialized = (bool)1;
00098     this->twist = twist;
00099     this->x = x;
00100     this->y = y;
00101     this->visit = visit;
00102 }
00103 
00111 
00112 Tag * Tag::read(File in_file, Map map) {
00113     // Read in "<Tag .../>":
00114     File__tag_match(in_file, "Tag");
00115     unsigned int tag_id = (unsigned int)File__integer_attribute_read(in_file, "Id");
00116     double diagonal = File__double_attribute_read(in_file, "Diagonal");
00117     double pi = (double)3.14159265358979323846264;
00118     double twist = File__double_attribute_read(in_file, "Twist");
00119     double x = File__double_attribute_read(in_file, "X");
00120     double y = File__double_attribute_read(in_file, "Y");
00121     unsigned int hop_count =
00122       (unsigned int)File__integer_attribute_read(in_file, "Hop_Count");
00123     File__string_match(in_file, "/>\n");
00124 
00125     // Convert *twist* from *degrees_to_radians*:
00126     double degrees_to_radians = pi / 180.0;
00127     twist *= degrees_to_radians;
00128 
00129     // Grab some additional information about *tag_id* from *map*:
00130     TagHeight * tag_height = Map__tag_height_lookup(map, tag_id);
00131 
00132     // Load up *tag*:
00133     Tag * tag = Map__tag_lookup(map, tag_id);
00134     tag->initialize(twist, x, y, diagonal, map->visit);
00135     tag->hop_count = hop_count;
00136     tag->z = tag_height->z;
00137 
00138     return tag;
00139 }
00140 
00147 
00148 void Tag::svg_write(SVG *svg) {
00149   // Some constants:
00150     double pi = (double)3.14159265358979323846264;
00151     double half_pi = pi / 2.0;
00152     double quarter_pi = half_pi / 2.0;
00153 
00154     // Grab some values from *tag*:
00155     double half_diagonal = world_diagonal / 2.0;
00156     double twist = this->twist - quarter_pi;
00157 
00158     // Compute the 4 corners:
00159     double x1 = x + half_diagonal * cos(twist);
00160     double y1 = y + half_diagonal * sin(twist);
00161     double x2 = x + half_diagonal * cos(twist + half_pi);
00162     double y2 = y + half_diagonal * sin(twist + half_pi);
00163     double x3 = x + half_diagonal * cos(twist + pi);
00164     double y3 = y + half_diagonal * sin(twist + pi);
00165     double x4 = x + half_diagonal * cos(twist - half_pi);
00166     double y4 = y + half_diagonal * sin(twist - half_pi);
00167 
00168     // Plot the 4 sides:
00169     String_Const other_edge = "black";
00170     String_Const bottom_edge = "purple";
00171     svg->line(x1, y1, x2, y2, other_edge);
00172     svg->line(x2, y2, x3, y3, other_edge);
00173     svg->line(x3, y3, x4, y4, other_edge);
00174     svg->line(x4, y4, x1, y1, bottom_edge);
00175 
00176     // Plot the id number:
00177     //String id_text = String__format("%d", id);
00178     char id_text[20];
00179     (void)sprintf(id_text, "%d", id);
00180     svg->text(id_text, x, y, "ariel", 20);
00181 }
00182 
00183 
00193 
00194 void Tag::update_via_arc(Arc *arc, CV_Image image,
00195     unsigned int sequence_number) {
00196     // Some values to use for radian/degree conversion:
00197     double pi = (double)3.14159265358979323846264;
00198     double r2d = 180.0 / pi;
00199 
00200     // Read out *arc* contents:
00201     Tag * from_tag = arc->from_tag;
00202     double arc_from_twist = arc->from_twist;
00203     double distance = arc->distance;
00204     Tag * to_tag = arc->to_tag;
00205     double arc_to_twist = arc->to_twist;
00206 
00207     // For debugging:
00208     //File__format(stderr,
00209     //  "Tag__update_via_arc: Arc[%d, %d]: d=%.4f, ft=%.1f, tt=%.1f)\n",
00210     //  from_tag->id, to_tag->id,
00211     //  distance, arc_from_twist * r2d, arc_to_twist * r2d);
00212 
00213     // Figure out whether *tag* is the *from* or *to* and conjugate if needed:
00214     if (this == from_tag) {
00215         // Compute the conjugate of *Arc* (see Arc.h for conjugate discussion):
00216         Tag * temporary_tag = from_tag;
00217         from_tag = to_tag;
00218         to_tag = temporary_tag;
00219         double temporary_twist = arc_from_twist;
00220         arc_from_twist = arc_to_twist;
00221         arc_to_twist = temporary_twist;
00222 
00223         // For debugging show the conjucate:
00224         //File__format(stderr,
00225         //  "Tag__update_via_arc: Arc'[%d, %d]: (d=%.4f, a=%.1f, t=%.1f)\n",
00226         //  from_tag->id, from_tag->id,
00227         //  distance, arc_from_twist * r2d, arc_to_twist * r2d);
00228     }
00229     assert (this == to_tag);
00230     assert (this != from_tag);
00231 
00232     // Grab the starting values from *from_tag*:
00233     double from_tag_twist = from_tag->twist;
00234     double from_tag_x = from_tag->x;
00235     double from_tag_y = from_tag->y;
00236     //File__format(stderr,
00237     //  "Tag__update_via_arc: From: id=%d x=%.2f y=%.2f twist=%.4f\n",
00238     //  from_tag->id, from_tag_x, from_tag_y, from_tag_twist * r2d);
00239 
00240     // Compute the new *Tag* values:
00241     double angle = angles::normalize_angle(-arc_from_twist + from_tag_twist);
00242     double to_tag_x = from_tag_x + distance * cos(angle);
00243     double to_tag_y = from_tag_y + distance * sin(angle);
00244     double to_tag_twist = angles::normalize_angle(angle - pi + arc_to_twist);
00245 
00246     // If *to_tag* values are to change
00247     if (to_tag->twist != to_tag_twist ||
00248       to_tag->x != to_tag_x || to_tag->y != to_tag_y) {
00249         // Load new values into *to_tag*:
00250         to_tag->twist = to_tag_twist;
00251         to_tag->x = to_tag_x;
00252         to_tag->y = to_tag_y;
00253         to_tag->updated = (bool)1;
00254 
00255         // Let any interested party know that tag values changed.
00256         Map map = to_tag->map;
00257         Map__tag_announce(map, to_tag, (bool)1, image, sequence_number);
00258     }
00259 
00260     //File__format(stderr, "To_Tag[id:%d x:%.2f y:%.2f tw:%.4f] angle=%.4f\n",
00261     //  to_tag->id, to_tag->x, to_tag->y, to_tag->twist * r2d, angle * r2d);
00262 }
00263 
00269 
00270 void Tag::write(File out_file) {
00271     // We store angles in degress and convert to/from radians.
00272     double pi = (double)3.14159265358979323846264;
00273     double radians_to_degrees = 180.0 / pi;
00274 
00275     // Write out "<Tag ... >":
00276     File__format(out_file, " <Tag");
00277     File__format(out_file, " Id=\"%d\"", id);
00278     File__format(out_file, " Diagonal=\"%f\"", diagonal);
00279     File__format(out_file,
00280       " Twist=\"%f\"", twist * radians_to_degrees);
00281     File__format(out_file, " X=\"%f\"", x);
00282     File__format(out_file, " Y=\"%f\"", y);
00283     File__format(out_file, " Hop_Count=\"%d\"", hop_count);
00284     File__format(out_file, "/>\n");
00285 }
00286 
00287 // *Tag_Height* routines:
00288 
00296 
00297 bool TagHeight::less(TagHeight * tag_height1, TagHeight * tag_height2)
00298 {
00299     return tag_height1->first_id < tag_height2->last_id;
00300 }
00301 
00308 
00309 TagHeight * TagHeight::xml_read(File xml_in_file) {
00310     // Read in "<Tag_Height .../>":
00311     File__tag_match(xml_in_file, "Tag_Height");
00312     unsigned int first_id =
00313       (unsigned int)File__integer_attribute_read(xml_in_file, "First_Id");
00314     unsigned int last_id =
00315       (unsigned int)File__integer_attribute_read(xml_in_file, "Last_Id");
00316 
00317     double World_Diagonal = 
00318        File__double_attribute_read(xml_in_file, "World_Diagonal");
00319 
00320     double z = File__double_attribute_read(xml_in_file, "Z");
00321 
00322     File__string_match(xml_in_file, "/>\n");
00323 
00324     // Load up *tag_height*:
00325     TagHeight * tag_height = new TagHeight();
00326     tag_height->world_diagonal = World_Diagonal;
00327     tag_height->first_id = first_id;
00328     tag_height->last_id = last_id;
00329     tag_height->z = z;
00330 
00331     return tag_height;
00332 }


fiducial_lib
Author(s): Wayne Gramlich
autogenerated on Thu Jun 6 2019 18:08:04