00001
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
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
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
00126 double degrees_to_radians = pi / 180.0;
00127 twist *= degrees_to_radians;
00128
00129
00130 TagHeight * tag_height = Map__tag_height_lookup(map, tag_id);
00131
00132
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
00150 double pi = (double)3.14159265358979323846264;
00151 double half_pi = pi / 2.0;
00152 double quarter_pi = half_pi / 2.0;
00153
00154
00155 double half_diagonal = world_diagonal / 2.0;
00156 double twist = this->twist - quarter_pi;
00157
00158
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
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
00177
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
00197 double pi = (double)3.14159265358979323846264;
00198 double r2d = 180.0 / pi;
00199
00200
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
00208
00209
00210
00211
00212
00213
00214 if (this == from_tag) {
00215
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
00224
00225
00226
00227
00228 }
00229 assert (this == to_tag);
00230 assert (this != from_tag);
00231
00232
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
00237
00238
00239
00240
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
00247 if (to_tag->twist != to_tag_twist ||
00248 to_tag->x != to_tag_x || to_tag->y != to_tag_y) {
00249
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
00256 Map map = to_tag->map;
00257 Map__tag_announce(map, to_tag, (bool)1, image, sequence_number);
00258 }
00259
00260
00261
00262 }
00263
00269
00270 void Tag::write(File out_file) {
00271
00272 double pi = (double)3.14159265358979323846264;
00273 double radians_to_degrees = 180.0 / pi;
00274
00275
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
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
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
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 }