00001
00002
00003 #include <assert.h>
00004
00005 #include "Arc.hpp"
00006 #include "File.hpp"
00007 #include "Map.hpp"
00008 #include "SVG.hpp"
00009 #include "Tag.hpp"
00010
00011
00012
00020
00021 bool Arc::equal(Arc *arc1, Arc *arc2) {
00022 return Tag::equal(arc1->from_tag, arc2->from_tag) &&
00023 Tag::equal(arc1->to_tag, arc2->to_tag);
00024 }
00025
00026
00027 bool Arc::less(Arc *arc1, Arc *arc2) {
00028 if( Tag::less(arc1->from_tag, arc2->from_tag) ) {
00029 return true;
00030 } else if( Tag::equal(arc1->from_tag, arc2->from_tag) ) {
00031 return Tag::less(arc1->to_tag, arc2->to_tag);
00032 }
00033 return false;
00034 }
00035
00048
00049 Arc::Arc(Tag *from_tag, double from_twist,
00050 double distance, Tag *to_tag, double to_twist, double goodness) {
00051
00052 if (from_tag->id > to_tag->id) {
00053
00054 Tag *temporary_tag = from_tag;
00055 from_tag = to_tag;
00056 to_tag = temporary_tag;
00057
00058 double temporary_twist = from_twist;
00059 from_twist = to_twist;
00060 to_twist = temporary_twist;
00061 }
00062
00063
00064 this->distance = distance;
00065 this->from_tag = from_tag;
00066 this->from_twist = from_twist;
00067 this->goodness = goodness;
00068 this->to_tag = to_tag;
00069 this->to_twist = to_twist;
00070
00071
00072 from_tag->arc_append(this);
00073 to_tag->arc_append(this);
00074 Map__arc_append(from_tag->map, this);
00075 }
00076
00084
00085 bool Arc::distance_less(Arc *arc1, Arc *arc2) {
00086 if( arc1->distance > arc2->distance ) {
00087
00088 return true;
00089 } else if( arc1->distance == arc2->distance ) {
00090 unsigned int arc1_lowest_hop_count =
00091 std::min(arc1->from_tag->hop_count, arc1->to_tag->hop_count);
00092 unsigned int arc2_lowest_hop_count =
00093 std::min(arc2->from_tag->hop_count, arc2->to_tag->hop_count);
00094 if( arc1_lowest_hop_count > arc2_lowest_hop_count ) {
00095
00096
00097 return true;
00098 }
00099 }
00100 return false;
00101 }
00102
00107
00108 Arc::Arc() {
00109 distance = -1.0;
00110 from_tag = NULL;
00111 from_twist = 0.0;
00112 goodness = 123456789.0;
00113 in_tree = (bool)0;
00114 to_tag = NULL;
00115 to_twist = 0.0;
00116 visit = 0;
00117 }
00118
00127
00128 Arc * Arc::read(File in_file, Map map) {
00129
00130 File__tag_match(in_file, "Arc");
00131 unsigned int from_tag_id =
00132 (unsigned int)File__integer_attribute_read(in_file, "From_Tag_Id");
00133 double from_twist = File__double_attribute_read(in_file, "From_Twist");
00134
00135 double distance = File__double_attribute_read(in_file, "Distance");
00136 unsigned int to_tag_id =
00137 (unsigned int)File__integer_attribute_read(in_file, "To_Tag_Id");
00138 double to_twist = File__double_attribute_read(in_file, "To_Twist");
00139 double goodness = File__double_attribute_read(in_file, "Goodness");
00140 bool in_tree = (bool)File__integer_attribute_read(in_file, "In_Tree");
00141 File__string_match(in_file, "/>\n");
00142
00143
00144 double pi = (double)3.14159265358979323846264;
00145 double degrees_to_radians = pi / 180.0;
00146 from_twist *= degrees_to_radians;
00147 to_twist *= degrees_to_radians;
00148
00149
00150 Tag * from_tag = Map__tag_lookup(map, from_tag_id);
00151 Tag * to_tag = Map__tag_lookup(map, to_tag_id);
00152 Arc * arc = Map__arc_lookup(map, from_tag, to_tag);
00153
00154
00155 if (arc->goodness > goodness) {
00156 arc->update(from_twist, distance, to_twist, goodness);
00157 arc->in_tree = in_tree;
00158 Map__arc_announce(map, arc, (CV_Image)0, 0);
00159 }
00160
00161 return arc;
00162 }
00163
00169
00170 void Arc::svg_write(SVG *svg) {
00171 String_Const color = "green";
00172 if (in_tree) {
00173 color = "red";
00174 }
00175 svg->line(from_tag->x, from_tag->y, to_tag->x, to_tag->y, color);
00176 }
00177
00188
00189 void Arc::update(double from_twist, double distance, double to_twist,
00190 double goodness) {
00191
00192 assert (this->from_tag->id < this->to_tag->id);
00193 this->from_twist = from_twist;
00194 assert (distance > 0.0);
00195 this->distance = distance;
00196 this->goodness = goodness;
00197 this->to_twist = to_twist;
00198 }
00199
00206
00207 void Arc::write(File out_file) {
00208
00209 double pi = (double)3.14159265358979323846264;
00210 double radians_to_degrees = 180.0 / pi;
00211 double from_twist_degrees = from_twist * radians_to_degrees;
00212 double to_twist_degrees = to_twist * radians_to_degrees;
00213
00214
00215 File__format(out_file, " <Arc");
00216 File__format(out_file, " From_Tag_Id=\"%d\"", from_tag->id);
00217 File__format(out_file, " From_Twist=\"%f\"", from_twist_degrees);
00218 File__format(out_file, " Distance=\"%f\"", distance);
00219 File__format(out_file, " To_Tag_Id=\"%d\"", to_tag->id);
00220 File__format(out_file, " To_Twist=\"%f\"", to_twist_degrees);
00221 File__format(out_file, " Goodness=\"%f\"", goodness);
00222 File__format(out_file, " In_Tree=\"%d\"", in_tree);
00223 File__format(out_file, "/>\n");
00224 }
00225