]> Creatis software - FrontAlgorithms.git/blob - appli/TempAirwaysAppli/AirwaysLib/airwaysEdge.cxx
56a908435729a7ccf443ed8c7f0eec7950306229
[FrontAlgorithms.git] / appli / TempAirwaysAppli / AirwaysLib / airwaysEdge.cxx
1 /*
2  * airwaysEdge.cxx
3  *
4  *  Created on: May 12, 2014
5  *      Author: caceres
6  */
7
8 #include "airwaysEdge.h"
9 #include <iostream>
10
11 namespace airways
12 {
13
14 Edge::Edge() : m_id(0), m_source(NULL), m_target(NULL), m_mark(false), m_angle(0), m_length(
15                 0), m_eDistance(0), m_aRadius(0), m_minRadius(0), m_maxRadius(0)
16 {
17
18 }
19
20 Edge::Edge(Edge* edge) :  m_id(0), m_source(NULL), m_target(NULL), m_mark(false), m_angle(0), m_length(
21                 0), m_eDistance(0), m_aRadius(0), m_minRadius(0), m_maxRadius(0)
22 {
23         this->m_id = edge->m_id;
24         this->m_source = edge->m_source;
25         this->m_target = edge->m_target;
26         this->m_angle = edge->m_angle;
27         this->m_length = edge->m_length;
28         this->m_eDistance = edge->m_eDistance;
29         this->m_vec_pair_posVox_rad = edge->m_vec_pair_posVox_rad;
30         this->m_aRadius = edge->m_aRadius;
31         this->m_minRadius = edge->m_minRadius;
32         this->m_maxRadius = edge->m_maxRadius;
33 }
34
35 Edge::~Edge()
36 {
37 }
38
39 int  Edge::GetAngle() const
40 {
41         return this->m_angle;
42 }
43
44 double  Edge::GetARadius() const
45 {
46         return this->m_aRadius;
47 }
48
49 double  Edge::GetEDistance() const
50 {
51         return this->m_eDistance;
52 }
53
54 double  Edge::GetLength() const
55 {
56         return this->m_length;
57 }
58
59 double  Edge::GetMaxRadius() const
60 {
61         return this->m_maxRadius;
62 }
63
64 double  Edge::GetMinRadius() const
65 {
66         return this->m_minRadius;
67 }
68
69 Node*  Edge::GetSource() const
70 {
71         return this->m_source;
72 }
73
74 Node*  Edge::GetTarget() const
75 {
76         return this->m_target;
77 }
78
79 const vec_pair_posVox_rad&  Edge::GetEdgeInfo() const
80 {
81         return m_vec_pair_posVox_rad;
82 }
83
84 bool  Edge::IsMarked() const
85 {
86         return this->m_mark;
87 }
88
89 bool Edge::IsPointInfluencedByEdge(float point_x, float point_y, float point_z) const
90 {
91         // Variables
92         float minDistance = -1.0;
93         bool first = true;
94         float distanceTemp = 0.0;
95         bool influenced = false;
96         Vec3 vector(point_x, point_y, point_z);
97
98         // Iterate over all voxel in the edge
99         vec_pair_posVox_rad::const_iterator it = this->m_vec_pair_posVox_rad.begin();
100         for (; it != this->m_vec_pair_posVox_rad.end() && !influenced; ++it)
101         {
102                 // Get the vector from the compared source to each voxel
103                 Vec3 voxel_actual = ((*it).first);
104                 //Vec3 source_actual = this->m_source->GetCoords( );
105                 //Vec3 vector_actual(voxel_actual - source_actual);
106
107                 // Get the difference vector
108                 Vec3 vector_diff = vector - voxel_actual;
109
110                 // Get the distance
111                 distanceTemp = vector_diff.Norm();
112
113                 // Get the minimum
114                 if(first)
115                 {
116                         minDistance = distanceTemp;
117                         first = false;
118                         if(minDistance < ((*it).second*1.8))
119                                 influenced = true;
120                 }
121                 else if(distanceTemp < minDistance)
122                 {
123                         minDistance = distanceTemp;
124                         if(minDistance < ((*it).second)*1.8)
125                                 influenced = true;
126                 }
127         }
128
129         return influenced;
130 }
131
132 void  Edge::SetAngle(const double& angle)
133 {
134         this->m_angle = angle;
135 }
136
137 void  Edge::SetARadius(const double& aRadius)
138 {
139         this->m_aRadius = aRadius;
140 }
141
142 void  Edge::SetEDistance(const double& eDistance)
143 {
144         this->m_eDistance = eDistance;
145 }
146
147 void  Edge::SetLength(const double& length)
148 {
149         this->m_length = length;
150 }
151
152 void  Edge::SetMaxRadius(const unsigned int& maxRadius)
153 {
154         this->m_maxRadius = maxRadius;
155 }
156
157 void  Edge::SetMinRadius(const unsigned int& minRadius)
158 {
159         this->m_minRadius = minRadius;
160 }
161
162 void  Edge::SetSource(Node* source)
163 {
164         this->m_source = source;
165 }
166
167 void  Edge::SetTarget(Node* target)
168 {
169         this->m_target = target;
170 }
171
172 void  Edge::AddSkeletonPairInfo(const pair_posVox_rad& skPairInfo)
173 {
174         this->m_vec_pair_posVox_rad.push_back(skPairInfo);
175 }
176
177 void  Edge::SetSkeletonPairVector(const vec_pair_posVox_rad& skPInfoVector)
178 {
179         this->m_vec_pair_posVox_rad = skPInfoVector;
180         UpdateEdgeInfo();
181 }
182
183 void  Edge::UpdateEdgeInfo()
184 {
185         if (this->m_vec_pair_posVox_rad.empty())
186         {
187                 std::cout << "   ------------------------ This edge has no information" << std::endl;
188                 std::cout << "Source:" << this->m_source->GetCoords() << std::endl;
189                 std::cout << "Target:" << this->m_target->GetCoords() << std::endl;
190                 return;
191         }
192         double min = std::numeric_limits<unsigned int>::max();
193         double max = std::numeric_limits<unsigned int>::min();
194         double average = 0;
195         vec_pair_posVox_rad::iterator it = this->m_vec_pair_posVox_rad.begin();
196         for (; it != this->m_vec_pair_posVox_rad.end(); ++it)
197         {
198                 pair_posVox_rad info = *it;
199                 average += info.second;
200                 if (info.second < min)
201                         min = info.second;
202                 else if (info.second > max)
203                         max = info.second;
204         }
205         this->m_aRadius = average / this->m_vec_pair_posVox_rad.size();
206         this->m_minRadius = min;
207         this->m_maxRadius = max;
208 }
209
210 double Edge::CompareWith(Edge* edge)
211 {
212         //std::cout << "Comparing ... " << std::endl;
213         // To compared the edges, the distance in each component
214         // is calculated and a distance function between edges is calculated.
215         // The components are:
216         // - Each component of the quaternion (son-parent quaterion). (4 components)
217         // - Edge distance
218         // - Edge average radius
219
220         // Difference in each quaternion component
221         //                  p
222         //                  |
223         //                  |
224         //                  |
225         //                  s
226         //                 /
227         //                              /
228         //               /
229         //              g
230         /*const Edge* edgeActualParent = this->m_source->GetEdge( );
231         Vec3 sourceActualParent = edgeActualParent->m_source->GetCoords( );
232         Vec3 targetActualParent = edgeActualParent->m_target->GetCoords( );
233         Vec3 sourceActual = this->m_source->GetCoords( );
234         Vec3 targetActual = this->m_target->GetCoords( );
235
236         Vec3 sp_actual( sourceActualParent - targetActualParent );
237         Vec3 sg_actual( targetActual - sourceActual );
238
239         const Edge* edgeComparedParent = edge.m_source->GetEdge( );
240         Vec3 sourceComparedParent = edgeComparedParent->m_source->GetCoords( );
241         Vec3 targetComparedParent = edgeComparedParent->m_target->GetCoords( );
242         Vec3 sourceCompared = edge.m_source->GetCoords( );
243         Vec3 targetCompared = edge.m_target->GetCoords( );
244
245         Vec3 sp_compared( sourceComparedParent - targetComparedParent );
246         Vec3 sg_compared( targetCompared - sourceCompared );
247
248         Quaternion q_actual(sp_actual, sg_actual);
249         Quaternion q_compared(sp_compared, sg_compared);
250
251         float dif_r = q_actual.getR() - q_compared.getR();
252         float dif_i = q_actual.getI() - q_compared.getI();
253         float dif_j = q_actual.getJ() - q_compared.getJ();
254         float dif_k = q_actual.getK() - q_compared.getK();
255         float dif_distance = this->m_length - edge.m_length;
256         float dif_radius = this->m_aRadius - edge.m_aRadius;
257          */
258         double distanceEdge = GetDistanceToEdge(edge);
259
260         //std::cout << "Comparing ... OK" << std::endl;
261
262         return distanceEdge;
263 }
264
265 float Edge::GetDistanceToEdge(Edge* edge)
266 {
267         // a. The parent edges must be aligned before calculate the distance.
268         // b. Parent end-points are aligned also.
269         // Steps a and b represent a rotation and a translation respectively.
270         // c. For each point in the actual Edge (this) the closest point in the
271         // compared edge is found. This distance is calculated and then averaged
272         // for all the points. Must be done in both ways?
273         // We can take the maximum of both distances max(D(a,b),D(b,a))
274
275         // Variables
276         float averageDistance = 0.0;
277         float numPoints = 0;
278
279         // Get the parent Edges
280         /*const Edge* edgeActualParent = this->m_source->GetEdge( );
281         Vec3 sourceActualParent = edgeActualParent->m_source->GetCoords( );
282         Vec3 targetActualParent = edgeActualParent->m_target->GetCoords( );
283         Vec3 sourceActual = this->m_source->GetCoords( );
284         Vec3 targetActual = this->m_target->GetCoords( );
285
286         Vec3 sp_actual( sourceActualParent - targetActualParent );
287         Vec3 sg_actual( targetActual - sourceActual );
288
289         const Edge* edgeComparedParent = edge.m_source->GetEdge( );
290         Vec3 sourceComparedParent = edgeComparedParent->m_source->GetCoords( );
291         Vec3 targetComparedParent = edgeComparedParent->m_target->GetCoords( );
292         Vec3 sourceCompared = edge.m_source->GetCoords( );
293         Vec3 targetCompared = edge.m_target->GetCoords( );
294
295         Vec3 sp_compared( sourceComparedParent - targetComparedParent );
296         Vec3 sg_compared( targetCompared - sourceCompared );
297
298         //Get the quaternion between parents
299         Quaternion q_parent(sp_actual, sp_compared);
300
301         // Get the translation vector to translate the compared parent to the actual parent
302         const Vec3 transParents( targetActualParent - targetComparedParent);
303          */
304
305         // Iterate over the voxels in the compared edge
306         for(vec_pair_posVox_rad::iterator it = edge->m_vec_pair_posVox_rad.begin(); it != edge->m_vec_pair_posVox_rad.end(); ++it)
307         {
308                 // Get the vector from the compared source to each voxel in the compared edge
309                 Vec3 voxel_actual = (*it).first;
310                 /*Vec3 vector_compared(voxel_actual - sourceCompared);
311
312                 // Rotate the vector using the parental quaternion
313                 Vec3 vector_compared_rotated = q_parent.rotateVector(vector_compared);
314                  */
315
316                 // Find the distance to the closest point in the actual edge
317                 //averageDistance += getDistanceToClosestPoint(sourceActual+vector_compared_rotated);
318                 averageDistance += this->GetSmallestDistanceToPoint(voxel_actual);
319
320                 ++numPoints;
321         }
322
323         // Get the average value
324         if(numPoints > 0)
325                 averageDistance = averageDistance / numPoints;
326
327         return averageDistance;
328 }
329
330 float Edge::GetDistanceToTranslatedEdge(Edge* edge, Vec3 vector_translation)
331 {
332         // a. The parent edges must be aligned before calculate the distance.
333         // b. Parent end-points are aligned also.
334         // Steps a and b represent a rotation and a translation respectively.
335         // c. For each point in the actual Edge (this) the closest point in the
336         // compared edge is found. This distance is calculated and then averaged
337         // for all the points. Must be done in both ways?
338         // We can take the maximum of both distances max(D(a,b),D(b,a))
339
340         // Variables
341         float averageDistance = 0.0;
342         float numPoints = 0;
343
344         // Iterate over the voxels in the compared edge
345         for(vec_pair_posVox_rad::iterator it = edge->m_vec_pair_posVox_rad.begin(); it != edge->m_vec_pair_posVox_rad.end(); ++it)
346         {
347                 // Get the vector from the compared source to each voxel in the compared edge
348                 Vec3 voxel_actual = (*it).first;
349
350                 // Translate the voxel
351                 Vec3 voxel_translated = voxel_actual + vector_translation;
352
353                 // Find the distance to the closest point in the actual edge
354                 averageDistance += this->GetSmallestDistanceToPoint(voxel_translated);
355
356                 ++numPoints;
357         }
358
359         // Get the average value
360         if(numPoints > 0)
361                 averageDistance = averageDistance / numPoints;
362
363         return averageDistance;
364 }
365
366 float Edge::GetDistanceWeigthedToTranslatedEdge(Edge* edge, Vec3 vector_translation)
367 {
368         // a. The parent edges must be aligned before calculate the distance.
369         // b. Parent end-points are aligned also.
370         // Steps a and b represent a rotation and a translation respectively.
371         // c. For each point in the actual Edge (this) the closest point in the
372         // compared edge is found. This distance is calculated and then averaged
373         // for all the points. Must be done in both ways?
374         // We can take the maximum of both distances max(D(a,b),D(b,a))
375
376         // Variables
377         double alfa = 4; // Weight for duplicated closest points
378         float distance_average = 0.0;
379         float distance_actual = 0.0;
380         float numPoints = 0;
381         std::map<Vec3, vec_pair_posVox_rad > map_vector_pair_vector_distance; // Map to save the correspondences between the given edge voxels and this voxels, and the distance between them.
382
383         // Iterate over the voxels in the compared edge
384         for(vec_pair_posVox_rad::iterator it = edge->m_vec_pair_posVox_rad.begin(); it != edge->m_vec_pair_posVox_rad.end(); ++it)
385         {
386                 // Get the vector from the compared source to each voxel in the compared edge
387                 Vec3 voxel_actual = (*it).first;
388
389                 // Translate the voxel
390                 Vec3 voxel_translated = voxel_actual + vector_translation;
391
392                 // Find the distance to the closest point in the actual edge
393                 Vec3 point_closest = this->GetClosestPoint(voxel_translated, distance_actual);
394                 distance_average += distance_actual;
395
396                 // Add the link
397                 pair_posVox_rad pair_vector_distance(voxel_actual, distance_actual);
398                 map_vector_pair_vector_distance[point_closest].push_back(pair_vector_distance);
399
400                 ++numPoints;
401         }
402
403         // Add the weight to shared closest points
404         float distance_weighted = 0.0;
405         for(std::map<Vec3, vec_pair_posVox_rad>::iterator it = map_vector_pair_vector_distance.begin(); it != map_vector_pair_vector_distance.end(); ++it)
406         {
407                 vec_pair_posVox_rad vector_pair_vector_distance = (*it).second;
408                 if(vector_pair_vector_distance.size() > 1)
409                 {
410                         for(vec_pair_posVox_rad::iterator it_vector = vector_pair_vector_distance.begin(); it_vector != vector_pair_vector_distance.end(); ++it_vector)
411                                 distance_weighted += (*it_vector).second * alfa;
412                 }
413                 else
414                 {
415                         for(vec_pair_posVox_rad::iterator it_vector = vector_pair_vector_distance.begin(); it_vector != vector_pair_vector_distance.end(); ++it_vector)
416                                 distance_weighted += (*it_vector).second;
417                 }
418         }
419
420         // Get the average value
421         if(numPoints > 0)
422         {
423                 distance_average = distance_average / numPoints;
424                 distance_weighted = distance_weighted / numPoints;
425         }
426
427         //std::cout << "[DistanceW;DistAvg][" << distance_weighted << ";" << distance_average << "];;";
428         //return distance_average;
429         return distance_weighted;
430 }
431
432 float Edge::GetDistanceToPoint(Vec3 point)
433 {
434         // Variables
435         bool first = true;
436         float distance = 0.0;
437
438         // Iterate over all voxel in the edge
439         vec_pair_posVox_rad::iterator it = this->m_vec_pair_posVox_rad.begin();
440         for (; it != this->m_vec_pair_posVox_rad.end(); ++it)
441         {
442                 // Get the vector from the compared source to each voxel
443                 Vec3 voxel_actual = ((*it).first);
444
445                 // Get the difference vector
446                 Vec3 vector_diff = point - voxel_actual;
447
448                 // Get the distance
449                 distance += vector_diff.Norm();
450         }
451
452         return distance;
453 }
454
455
456 float Edge::GetSmallestDistanceToPoint(Vec3 vector)
457 {
458         // Variables
459         float minDistance = -1.0;
460         bool first = true;
461         float distanceTemp = 0.0;
462
463         // Iterate over all voxel in the edge
464         vec_pair_posVox_rad::iterator it = this->m_vec_pair_posVox_rad.begin();
465         for (; it != this->m_vec_pair_posVox_rad.end(); ++it)
466         {
467                 // Get the vector from the compared source to each voxel
468                 Vec3 voxel_actual = ((*it).first);
469                 //Vec3 source_actual = this->m_source->GetCoords( );
470                 //Vec3 vector_actual(voxel_actual - source_actual);
471
472                 // Get the difference vector
473                 Vec3 vector_diff = vector - voxel_actual;
474
475                 // Get the distance
476                 distanceTemp = vector_diff.Norm();
477
478                 // Get the minimum
479                 if(first)
480                 {
481                         minDistance = distanceTemp;
482                         first = false;
483                 }
484                 else if(distanceTemp < minDistance)
485                         minDistance = distanceTemp;
486         }
487
488         return minDistance;
489 }
490
491 Vec3 Edge::GetClosestPoint(Vec3 vector, float& distance)
492 {
493         // Variables
494         Vec3 point_closest;
495         bool first = true;
496         float distanceTemp = 0.0;
497
498         // Iterate over all voxel in the edge
499         vec_pair_posVox_rad::iterator it = this->m_vec_pair_posVox_rad.begin();
500         for (; it != this->m_vec_pair_posVox_rad.end(); ++it)
501         {
502                 // Get the vector from the compared source to each voxel
503                 Vec3 voxel_actual = ((*it).first);
504                 //Vec3 source_actual = this->m_source->GetCoords( );
505                 //Vec3 vector_actual(voxel_actual - source_actual);
506
507                 // Get the difference vector
508                 Vec3 vector_diff = vector - voxel_actual;
509
510                 // Get the distance
511                 distanceTemp = vector_diff.Norm();
512
513                 // Get the minimum
514                 if(first)
515                 {
516                         point_closest = voxel_actual;
517                         distance = distanceTemp;
518                         first = false;
519                 }
520                 else if(distanceTemp < distance)
521                 {
522                         point_closest = voxel_actual;
523                         distance = distanceTemp;
524                 }
525         }
526
527         return point_closest;
528 }
529
530 Edge* Edge::ConcatenateToSuperior(Edge* superior)
531 {
532         if(superior == NULL)
533                 return new Edge(this);
534
535         // Check concatenation condition in the nodes
536         if(superior->GetTarget()->GetCoords() != this->GetSource()->GetCoords())
537         {
538                 std::cout << "Edge::ConcatenateToSuperior - superior.target != actualEdge.source. Actual idNode:" << this->m_id << std::endl;
539                 std::cout << "[superior.target;actualEdge.source]: [" << superior->GetTarget()->GetCoords() << ";" << this->GetSource()->GetCoords() << "]" << std::endl;
540                 return NULL;
541         }
542
543         // Check concatenation condition in the edge information
544         vec_pair_posVox_rad vectorInfo_thisEdge = this->GetEdgeInfo(); // Actual edge information
545         vec_pair_posVox_rad vectorInfo_superiorEdge = superior->GetEdgeInfo(); // Superior edge information
546
547         // Check that last superior edge position is equal to first initial actual edge position
548         if(vectorInfo_superiorEdge[vectorInfo_superiorEdge.size()-1].first != vectorInfo_thisEdge[0].first)
549         {
550                 std::cout << "Edge::ConcatenateToSuperior - superior.info[end] != actualEdge.info[begin]. Actual idNode:" << this->m_id << std::endl;
551                 return NULL;
552         }
553
554         // Change the superior edge target, the superior length, and the euclidian distance
555         superior->SetTarget(this->GetTarget());
556         superior->SetLength(superior->GetLength()+this->GetLength()-1);
557         superior->SetEDistance(superior->GetEDistance()+this->GetEDistance());
558
559         // Add the position information
560         vec_pair_posVox_rad::iterator it_actualInfo = vectorInfo_thisEdge.begin();
561         ++it_actualInfo; // Skip the first position because is it shared between both edges
562         for(; it_actualInfo != vectorInfo_thisEdge.end(); ++it_actualInfo)
563                 vectorInfo_superiorEdge.push_back((*it_actualInfo));
564
565         // Set the new information
566         superior->SetSkeletonPairVector(vectorInfo_superiorEdge);
567
568         return superior;
569
570 }
571
572 Edge&  Edge::operator=(Edge& edge)
573 {
574         this->m_mark = edge.m_mark;
575         this->m_angle = edge.m_angle;
576         this->m_length = edge.m_length;
577         this->m_eDistance = edge.m_eDistance;
578         this->m_aRadius = edge.m_aRadius;
579         this->m_minRadius = edge.m_minRadius;
580         this->m_maxRadius = edge.m_maxRadius;
581         this->m_source = edge.m_source;
582         this->m_target = edge.m_target;
583         this->m_vec_pair_posVox_rad = edge.m_vec_pair_posVox_rad;
584         return *this;
585 }
586
587 const Edge&  Edge::operator=(const Edge& edge)
588 {
589         this->m_mark = edge.m_mark;
590         this->m_angle = edge.m_angle;
591         this->m_length = edge.m_length;
592         this->m_eDistance = edge.m_eDistance;
593         this->m_aRadius = edge.m_aRadius;
594         this->m_minRadius = edge.m_minRadius;
595         this->m_maxRadius = edge.m_maxRadius;
596         this->m_source = edge.m_source;
597         this->m_target = edge.m_target;
598         this->m_vec_pair_posVox_rad = edge.m_vec_pair_posVox_rad;
599         return *this;
600 }
601
602 bool  Edge::operator==(const Edge& edge)
603                                                                                                                   {
604         bool cmp1 = true;
605         bool cmp2 = true;
606         bool cmp3 = true;
607         bool cmp4 = true;
608         bool cmp5 = true;
609         bool cmp6 = true;
610         /*if (this->m_angle != edge.m_angle)
611      {
612      double max =
613      this->m_angle >= edge.m_angle ? this->m_angle : edge.m_angle;
614      double tol = 0.3 * max;
615      double diff = this->m_angle - edge.m_angle;
616      if (!((-tol <= diff) && (diff <= tol)))
617      cmp1 = false;
618      }*/
619         if (this->m_length != edge.m_length)
620         {
621                 double max =
622                                 this->m_length >= edge.m_length ? this->m_length : edge.m_length;
623                 double tol = 0.3 * max;
624                 double diff = abs(this->m_length - edge.m_length);
625                 if (diff > tol)
626                         cmp2 = false;
627         }
628         if (this->m_eDistance != edge.m_eDistance)
629         {
630                 double max =
631                                 this->m_eDistance >= edge.m_eDistance ?
632                                                 this->m_eDistance : edge.m_eDistance;
633                 double tol = 0.3 * max;
634                 double diff = abs(this->m_eDistance - edge.m_eDistance);
635                 if (diff > tol)
636                         cmp3 = false;
637         }
638         /*if (this->m_aRadius != edge.m_aRadius)
639      {
640      double max =
641      this->m_aRadius >= edge.m_aRadius ?
642      this->m_aRadius : edge.m_aRadius;
643      double tol = 0.3 * max;
644      double diff = abs(this->m_aRadius - edge.m_aRadius);
645      if (diff > tol)
646      cmp4 = false;
647      }
648      if (this->m_minRadius != edge.m_minRadius)
649      {
650      double max =
651      this->m_minRadius >= edge.m_minRadius ?
652      this->m_minRadius : edge.m_minRadius;
653      double tol = 0.3 * max;
654      double diff = abs(this->m_minRadius - edge.m_minRadius);
655      if (diff > tol)
656      cmp5 = false;
657      }
658      if (this->m_maxRadius != edge.m_maxRadius)
659      {
660      double max =
661      this->m_maxRadius >= edge.m_maxRadius ?
662      this->m_maxRadius : edge.m_maxRadius;
663      double tol = 0.3 * max;
664      double diff = abs(this->m_maxRadius - edge.m_maxRadius);
665      if (diff > tol)
666      cmp6 = false;
667      }*/
668         return (cmp1 && cmp2 && cmp3 && cmp4 && cmp5 && cmp6);
669                                                                                                                   }
670
671 bool  Edge::operator!=(const Edge& edge)
672                                                                                                                   {
673         return !(*this == edge);
674                                                                                                                   }
675
676 bool  Edge::operator<(const Edge& edge)
677 {
678         bool cmp1 = true;
679         bool cmp2 = true;
680         if (this->m_length != edge.m_length)
681         {
682                 double max =
683                                 this->m_length >= edge.m_length ? this->m_length : edge.m_length;
684                 double tol = 0.3 * max;
685                 double diff = abs(this->m_length - edge.m_length);
686                 if (diff > tol)
687                         cmp2 = false;
688         }
689         if (this->m_eDistance != edge.m_eDistance)
690         {
691                 double max =
692                                 this->m_eDistance >= edge.m_eDistance ?
693                                                 this->m_eDistance : edge.m_eDistance;
694                 double tol = 0.3 * max;
695                 double diff = abs(this->m_eDistance - edge.m_eDistance);
696                 if (diff > tol)
697                         cmp2 = false;
698         }
699         if (cmp1 && cmp2)
700                 return false;
701         if ((this->m_length < edge.m_length)
702                         || (this->m_eDistance < edge.m_eDistance))
703                 return true;
704         return false;
705
706 }
707
708 bool  Edge::operator>(const Edge& edge)
709 {
710         bool cmp1 = true;
711         bool cmp2 = true;
712         if (this->m_length != edge.m_length)
713         {
714                 double max =
715                                 this->m_length >= edge.m_length ? this->m_length : edge.m_length;
716                 double tol = 0.3 * max;
717                 double diff = abs(this->m_length - edge.m_length);
718                 if (diff > tol)
719                         cmp2 = false;
720         }
721         if (this->m_eDistance != edge.m_eDistance)
722         {
723                 double max =
724                                 this->m_eDistance >= edge.m_eDistance ?
725                                                 this->m_eDistance : edge.m_eDistance;
726                 double tol = 0.3 * max;
727                 double diff = abs(this->m_eDistance - edge.m_eDistance);
728                 if (diff > tol)
729                         cmp2 = false;
730         }
731         if (cmp1 && cmp2)
732                 return false;
733         if ((this->m_length > edge.m_length)
734                         || (this->m_eDistance > edge.m_eDistance))
735                 return true;
736         return false;
737 }
738
739 } /* namespace airways */