LCOV - code coverage report
Current view: top level - pencil/include/geometry - geometry_connector.inl (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.61.0_covts Lines: 208 290 71.7 %
Date: 2024-10-26 21:44:38 Functions: 14 27 51.9 %

          Line data    Source code
       1             : /* File: geometry_connector.inl; Copyright and License: see below */
       2             : 
       3             : #include "u8/u8_trace.h"
       4             : #include "u8/u8_log.h"
       5             : #include <math.h>
       6             : 
       7           8 : static inline void geometry_connector_init_vertical ( geometry_connector_t *this_,
       8             :                                                       double source_end_x,
       9             :                                                       double source_end_y,
      10             :                                                       double destination_end_x,
      11             :                                                       double destination_end_y,
      12             :                                                       double main_line_x )
      13             : {
      14           8 :     (*this_).source_end_x = source_end_x;
      15           8 :     (*this_).source_end_y = source_end_y;
      16           8 :     (*this_).main_line_source_x = main_line_x;
      17           8 :     (*this_).main_line_source_y = source_end_y;
      18           8 :     (*this_).main_line_destination_x = main_line_x;
      19           8 :     (*this_).main_line_destination_y = destination_end_y;
      20           8 :     (*this_).destination_end_x = destination_end_x;
      21           8 :     (*this_).destination_end_y = destination_end_y;
      22           8 : }
      23             : 
      24           8 : static inline void geometry_connector_init_horizontal ( geometry_connector_t *this_,
      25             :                                                         double source_end_x,
      26             :                                                         double source_end_y,
      27             :                                                         double destination_end_x,
      28             :                                                         double destination_end_y,
      29             :                                                         double main_line_y )
      30             : {
      31           8 :     (*this_).source_end_x = source_end_x;
      32           8 :     (*this_).source_end_y = source_end_y;
      33           8 :     (*this_).main_line_source_x = source_end_x;
      34           8 :     (*this_).main_line_source_y = main_line_y;
      35           8 :     (*this_).main_line_destination_x = destination_end_x;
      36           8 :     (*this_).main_line_destination_y = main_line_y;
      37           8 :     (*this_).destination_end_x = destination_end_x;
      38           8 :     (*this_).destination_end_y = destination_end_y;
      39           8 : }
      40             : 
      41           5 : static inline void geometry_connector_reinit_vertical ( geometry_connector_t *this_,
      42             :                                                         double source_end_x,
      43             :                                                         double source_end_y,
      44             :                                                         double destination_end_x,
      45             :                                                         double destination_end_y,
      46             :                                                         double main_line_x )
      47             : {
      48           5 :     (*this_).source_end_x = source_end_x;
      49           5 :     (*this_).source_end_y = source_end_y;
      50           5 :     (*this_).main_line_source_x = main_line_x;
      51           5 :     (*this_).main_line_source_y = source_end_y;
      52           5 :     (*this_).main_line_destination_x = main_line_x;
      53           5 :     (*this_).main_line_destination_y = destination_end_y;
      54           5 :     (*this_).destination_end_x = destination_end_x;
      55           5 :     (*this_).destination_end_y = destination_end_y;
      56           5 : }
      57             : 
      58           2 : static inline void geometry_connector_reinit_horizontal ( geometry_connector_t *this_,
      59             :                                                           double source_end_x,
      60             :                                                           double source_end_y,
      61             :                                                           double destination_end_x,
      62             :                                                           double destination_end_y,
      63             :                                                           double main_line_y )
      64             : {
      65           2 :     (*this_).source_end_x = source_end_x;
      66           2 :     (*this_).source_end_y = source_end_y;
      67           2 :     (*this_).main_line_source_x = source_end_x;
      68           2 :     (*this_).main_line_source_y = main_line_y;
      69           2 :     (*this_).main_line_destination_x = destination_end_x;
      70           2 :     (*this_).main_line_destination_y = main_line_y;
      71           2 :     (*this_).destination_end_x = destination_end_x;
      72           2 :     (*this_).destination_end_y = destination_end_y;
      73           2 : }
      74             : 
      75             : static inline void geometry_connector_copy ( geometry_connector_t *this_, const geometry_connector_t *original )
      76             : {
      77             :     (*this_) = (*original);
      78             : }
      79             : 
      80           1 : static inline void geometry_connector_replace ( geometry_connector_t *this_, const geometry_connector_t *original )
      81             : {
      82           1 :     (*this_) = (*original);
      83           1 : }
      84             : 
      85        2139 : static inline void geometry_connector_init_empty ( geometry_connector_t *this_ )
      86             : {
      87        2139 :     (*this_).source_end_x = 0.0;
      88        2139 :     (*this_).source_end_y = 0.0;
      89        2139 :     (*this_).main_line_source_x = 0.0;
      90        2139 :     (*this_).main_line_source_y = 0.0;
      91        2139 :     (*this_).main_line_destination_x = 0.0;
      92        2139 :     (*this_).main_line_destination_y = 0.0;
      93        2139 :     (*this_).destination_end_x = 0.0;
      94        2139 :     (*this_).destination_end_y = 0.0;
      95        2139 : }
      96             : 
      97             : static inline void geometry_connector_reinit_empty ( geometry_connector_t *this_ )
      98             : {
      99             :     (*this_).source_end_x = 0.0;
     100             :     (*this_).source_end_y = 0.0;
     101             :     (*this_).main_line_source_x = 0.0;
     102             :     (*this_).main_line_source_y = 0.0;
     103             :     (*this_).main_line_destination_x = 0.0;
     104             :     (*this_).main_line_destination_y = 0.0;
     105             :     (*this_).destination_end_x = 0.0;
     106             :     (*this_).destination_end_y = 0.0;
     107             : }
     108             : 
     109        2153 : static inline void geometry_connector_destroy ( geometry_connector_t *this_ )
     110             : {
     111        2153 : }
     112             : 
     113           0 : static inline double geometry_connector_get_source_end_x ( const geometry_connector_t *this_ )
     114             : {
     115           0 :     return (*this_).source_end_x;
     116             : }
     117             : 
     118           0 : static inline double geometry_connector_get_source_end_y ( const geometry_connector_t *this_ )
     119             : {
     120           0 :     return (*this_).source_end_y;
     121             : }
     122             : 
     123           0 : static inline double geometry_connector_get_main_line_source_x ( const geometry_connector_t *this_ )
     124             : {
     125           0 :     return (*this_).main_line_source_x;
     126             : }
     127             : 
     128           0 : static inline double geometry_connector_get_main_line_source_y ( const geometry_connector_t *this_ )
     129             : {
     130           0 :     return (*this_).main_line_source_y;
     131             : }
     132             : 
     133           0 : static inline double geometry_connector_get_main_line_destination_x ( const geometry_connector_t *this_ )
     134             : {
     135           0 :     return (*this_).main_line_destination_x;
     136             : }
     137             : 
     138           0 : static inline double geometry_connector_get_main_line_destination_y ( const geometry_connector_t *this_ )
     139             : {
     140           0 :     return (*this_).main_line_destination_y;
     141             : }
     142             : 
     143           0 : static inline double geometry_connector_get_destination_end_x ( const geometry_connector_t *this_ )
     144             : {
     145           0 :     return (*this_).destination_end_x;
     146             : }
     147             : 
     148           0 : static inline double geometry_connector_get_destination_end_y ( const geometry_connector_t *this_ )
     149             : {
     150           0 :     return (*this_).destination_end_y;
     151             : }
     152             : 
     153           8 : static inline geometry_point_t geometry_connector_calculate_waypoint ( const geometry_connector_t *this_,
     154             :                                                                        double distance_covered )
     155             : {
     156             :     geometry_point_t result;
     157             : 
     158           8 :     const double source_end_length = fabs( (*this_).source_end_x - (*this_).main_line_source_x )
     159           8 :                                      + fabs( (*this_).source_end_y - (*this_).main_line_source_y );
     160           8 :     const double main_line_length = fabs( (*this_).main_line_source_x - (*this_).main_line_destination_x )
     161           8 :                                     + fabs( (*this_).main_line_source_y - (*this_).main_line_destination_y );
     162           8 :     const double dest_end_length = fabs( (*this_).main_line_destination_x - (*this_).destination_end_x )
     163           8 :                                    + fabs( (*this_).main_line_destination_y - (*this_).destination_end_y );
     164             : 
     165           8 :     if ( distance_covered < source_end_length ) {
     166           2 :         if (( distance_covered <= 0.0 )||( source_end_length < 0.000000001 ))
     167             :         {
     168           1 :             geometry_point_init ( &result, (*this_).source_end_x, (*this_).source_end_y );
     169             :         }
     170             :         else
     171             :         {
     172           1 :             geometry_point_init ( &result, (*this_).source_end_x, (*this_).source_end_y );
     173           1 :             const double segment_part1 = distance_covered / source_end_length;
     174           1 :             geometry_point_shift( &result,
     175           1 :                                   segment_part1 * ( (*this_).main_line_source_x - (*this_).source_end_x ),
     176           1 :                                   segment_part1 * ( (*this_).main_line_source_y - (*this_).source_end_y )
     177             :                                 );
     178             :         }
     179             :     }
     180             :     else {
     181           6 :         const double shifted_distance = distance_covered - source_end_length;
     182           6 :         if (( shifted_distance < main_line_length )&&( main_line_length >= 0.000000001 ))
     183           2 :         {
     184           2 :             geometry_point_init ( &result, (*this_).main_line_source_x, (*this_).main_line_source_y );
     185           2 :             const double segment_part2 = shifted_distance / main_line_length;
     186           2 :             geometry_point_shift( &result,
     187           2 :                                   segment_part2 * ( (*this_).main_line_destination_x - (*this_).main_line_source_x ),
     188           2 :                                   segment_part2 * ( (*this_).main_line_destination_y - (*this_).main_line_source_y )
     189             :                                 );
     190             :         }
     191             :         else
     192             :         {
     193           4 :             const double shifted2_distance = shifted_distance - main_line_length;
     194           4 :             if (( shifted2_distance < dest_end_length )&&( dest_end_length >= 0.000000001 ))
     195           2 :             {
     196           2 :                 geometry_point_init ( &result, (*this_).main_line_destination_x, (*this_).main_line_destination_y );
     197           2 :                 const double segment_part3 = shifted2_distance / dest_end_length;
     198           2 :                 geometry_point_shift( &result,
     199           2 :                                     segment_part3 * ( (*this_).destination_end_x - (*this_).main_line_destination_x ),
     200           2 :                                     segment_part3 * ( (*this_).destination_end_y - (*this_).main_line_destination_y )
     201             :                                     );
     202             :             }
     203             :             else
     204             :             {
     205           2 :                 geometry_point_init ( &result, (*this_).destination_end_x, (*this_).destination_end_y );
     206             :             }
     207             :         }
     208             :     }
     209             : 
     210           8 :     return result;
     211             : }
     212             : 
     213           2 : static inline double geometry_connector_get_length ( const geometry_connector_t *this_ )
     214             : {
     215           2 :     const double source_end_length
     216           2 :         = fabs( (*this_).source_end_x - (*this_).main_line_source_x )
     217           2 :         + fabs( (*this_).source_end_y - (*this_).main_line_source_y );
     218           2 :     const double main_line_length
     219           2 :         = fabs( (*this_).main_line_source_x - (*this_).main_line_destination_x )
     220           2 :         + fabs( (*this_).main_line_source_y - (*this_).main_line_destination_y );
     221           2 :     const double dest_end_length
     222           2 :         = fabs( (*this_).main_line_destination_x - (*this_).destination_end_x )
     223           2 :         + fabs( (*this_).main_line_destination_y - (*this_).destination_end_y );
     224           2 :     return source_end_length + main_line_length + dest_end_length;
     225             : }
     226             : 
     227           0 : static inline double geometry_connector_get_source_length ( const geometry_connector_t *this_ )
     228             : {
     229           0 :     const double source_end_length
     230           0 :         = fabs( (*this_).source_end_x - (*this_).main_line_source_x )
     231           0 :         + fabs( (*this_).source_end_y - (*this_).main_line_source_y );
     232           0 :     return source_end_length;
     233             : }
     234             : 
     235           0 : static inline double geometry_connector_get_main_length ( const geometry_connector_t *this_ )
     236             : {
     237           0 :     const double main_line_length
     238           0 :         = fabs( (*this_).main_line_source_x - (*this_).main_line_destination_x )
     239           0 :         + fabs( (*this_).main_line_source_y - (*this_).main_line_destination_y );
     240           0 :     return main_line_length;
     241             : }
     242             : 
     243           0 : static inline double geometry_connector_get_destination_length ( const geometry_connector_t *this_ )
     244             : {
     245           0 :     const double dest_end_length
     246           0 :         = fabs( (*this_).main_line_destination_x - (*this_).destination_end_x )
     247           0 :         + fabs( (*this_).main_line_destination_y - (*this_).destination_end_y );
     248           0 :     return dest_end_length;
     249             : }
     250             : 
     251           4 : static inline bool geometry_connector_is_close ( const geometry_connector_t *this_, double x, double y, double max_distance )
     252             : {
     253           4 :     const bool close_to_source_end_line
     254           4 :         = ((( (*this_).source_end_x - max_distance < x ) && ( x < (*this_).main_line_source_x + max_distance ))
     255           1 :         || (( (*this_).main_line_source_x - max_distance < x ) && ( x < (*this_).source_end_x + max_distance )))
     256          10 :         && ((( (*this_).source_end_y - max_distance < y ) && ( y < (*this_).main_line_source_y + max_distance ))
     257           2 :         || (( (*this_).main_line_source_y - max_distance < y ) && ( y < (*this_).source_end_y + max_distance )));
     258           4 :     const bool close_to_main_line
     259           4 :         = ((( (*this_).main_line_destination_x - max_distance < x ) && ( x < (*this_).main_line_source_x + max_distance ))
     260           1 :         || (( (*this_).main_line_source_x - max_distance < x ) && ( x < (*this_).main_line_destination_x + max_distance )))
     261          11 :         && ((( (*this_).main_line_destination_y - max_distance < y ) && ( y < (*this_).main_line_source_y + max_distance ))
     262           3 :         || (( (*this_).main_line_source_y - max_distance < y ) && ( y < (*this_).main_line_destination_y + max_distance )));
     263           4 :     const bool close_to_destination_end_line
     264           4 :         = ((( (*this_).main_line_destination_x - max_distance < x ) && ( x < (*this_).destination_end_x + max_distance ))
     265           0 :         || (( (*this_).destination_end_x - max_distance < x ) && ( x < (*this_).main_line_destination_x + max_distance )))
     266          12 :         && ((( (*this_).main_line_destination_y - max_distance < y ) && ( y < (*this_).destination_end_y + max_distance ))
     267           4 :         || (( (*this_).destination_end_y - max_distance < y ) && ( y < (*this_).main_line_destination_y + max_distance )));
     268           4 :     return ( close_to_source_end_line || close_to_main_line || close_to_destination_end_line );
     269             : }
     270             : 
     271          10 : static inline bool geometry_connector_is_intersecting_rectangle ( const geometry_connector_t *this_, const geometry_rectangle_t *rect )
     272             : {
     273             :     geometry_rectangle_t source;
     274             :     geometry_rectangle_t main_line;
     275             :     geometry_rectangle_t destination;
     276          10 :     geometry_rectangle_init_by_corners( &source,
     277          10 :                                         (*this_).source_end_x, (*this_).source_end_y,
     278          10 :                                         (*this_).main_line_source_x, (*this_).main_line_source_y
     279             :                                       );
     280          10 :     geometry_rectangle_init_by_corners( &main_line,
     281          10 :                                         (*this_).main_line_source_x, (*this_).main_line_source_y,
     282          10 :                                         (*this_).main_line_destination_x, (*this_).main_line_destination_y
     283             :                                       );
     284          10 :     geometry_rectangle_init_by_corners( &destination,
     285          10 :                                         (*this_).main_line_destination_x, (*this_).main_line_destination_y,
     286          10 :                                         (*this_).destination_end_x, (*this_).destination_end_y
     287             :                                       );
     288             : 
     289          10 :     const bool result
     290          10 :         = geometry_rectangle_is_intersecting( &source, rect )
     291          10 :         || geometry_rectangle_is_intersecting( &main_line, rect )
     292          20 :         || geometry_rectangle_is_intersecting( &destination, rect );
     293             : 
     294          10 :     geometry_rectangle_destroy( &source );
     295          10 :     geometry_rectangle_destroy( &main_line );
     296          10 :     geometry_rectangle_destroy( &destination );
     297             : 
     298          10 :     return result;
     299             : }
     300             : 
     301           6 : static inline uint32_t geometry_connector_count_connector_intersects ( const geometry_connector_t *this_, const geometry_connector_t *that )
     302             : {
     303           6 :     uint32_t result = 0;
     304             : 
     305             :     /* do some simple prechecks */
     306             :     geometry_rectangle_t this_bounds;
     307             :     geometry_rectangle_t that_bounds;
     308             : 
     309           6 :     this_bounds = geometry_connector_get_bounding_rectangle( this_ );
     310           6 :     that_bounds = geometry_connector_get_bounding_rectangle( that );
     311             : 
     312           6 :     if ( geometry_rectangle_is_contiguous( &this_bounds, &that_bounds ) )
     313             :     {
     314             :         /* do some more complicated checks */
     315             :         geometry_rectangle_t this_source_end;
     316             :         geometry_rectangle_t this_main_line;
     317             :         geometry_rectangle_t this_destination_end;
     318             :         geometry_rectangle_t that_source_end;
     319             :         geometry_rectangle_t that_main_line;
     320             :         geometry_rectangle_t that_destination_end;
     321             : 
     322           5 :         geometry_rectangle_init_by_corners( &this_source_end,
     323           5 :                                             (*this_).main_line_source_x, (*this_).main_line_source_y, (*this_).source_end_x, (*this_).source_end_y
     324             :                                           );
     325           5 :         geometry_rectangle_init_by_corners( &this_main_line,
     326           5 :                                             (*this_).main_line_destination_x, (*this_).main_line_destination_y, (*this_).main_line_source_x, (*this_).main_line_source_y
     327             :                                           );
     328           5 :         geometry_rectangle_init_by_corners( &this_destination_end,
     329           5 :                                             (*this_).destination_end_x, (*this_).destination_end_y, (*this_).main_line_destination_x, (*this_).main_line_destination_y
     330             :                                           );
     331           5 :         geometry_rectangle_init_by_corners( &that_source_end,
     332           5 :                                             (*that).main_line_source_x, (*that).main_line_source_y, (*that).source_end_x, (*that).source_end_y
     333             :                                           );
     334           5 :         geometry_rectangle_init_by_corners( &that_main_line,
     335           5 :                                             (*that).main_line_destination_x, (*that).main_line_destination_y, (*that).main_line_source_x, (*that).main_line_source_y
     336             :                                           );
     337           5 :         geometry_rectangle_init_by_corners( &that_destination_end,
     338           5 :                                             (*that).destination_end_x, (*that).destination_end_y, (*that).main_line_destination_x, (*that).main_line_destination_y
     339             :                                           );
     340             : 
     341           5 :         if ( geometry_rectangle_is_contiguous( &this_source_end, &that_source_end ) )
     342             :         {
     343           3 :             result += 1;
     344             :         }
     345           5 :         if ( geometry_rectangle_is_contiguous( &this_main_line, &that_source_end ) )
     346             :         {
     347           3 :             result += 1;
     348             :         }
     349           5 :         if ( geometry_rectangle_is_contiguous( &this_destination_end, &that_source_end ) )
     350             :         {
     351           1 :             result += 1;
     352             :         }
     353           5 :         if ( geometry_rectangle_is_contiguous( &this_source_end, &that_main_line ) )
     354             :         {
     355           2 :             result += 1;
     356             :         }
     357           5 :         if ( geometry_rectangle_is_contiguous( &this_main_line, &that_main_line ) )
     358             :         {
     359           2 :             result += 1;
     360             :         }
     361           5 :         if ( geometry_rectangle_is_contiguous( &this_destination_end, &that_main_line ) )
     362             :         {
     363           2 :             result += 1;
     364             :         }
     365           5 :         if ( geometry_rectangle_is_contiguous( &this_source_end, &that_destination_end ) )
     366             :         {
     367           2 :             result += 1;
     368             :         }
     369           5 :         if ( geometry_rectangle_is_contiguous( &this_main_line, &that_destination_end ) )
     370             :         {
     371           3 :             result += 1;
     372             :         }
     373           5 :         if ( geometry_rectangle_is_contiguous( &this_destination_end, &that_destination_end ) )
     374             :         {
     375           3 :             result += 1;
     376             :         }
     377             : 
     378           5 :         geometry_rectangle_destroy( &this_source_end );
     379           5 :         geometry_rectangle_destroy( &this_main_line );
     380           5 :         geometry_rectangle_destroy( &this_destination_end );
     381           5 :         geometry_rectangle_destroy( &that_source_end );
     382           5 :         geometry_rectangle_destroy( &that_main_line );
     383           5 :         geometry_rectangle_destroy( &that_destination_end );
     384             :     }
     385             :     /* else no intersects, result = 0 */
     386             : 
     387           6 :     geometry_rectangle_destroy( &this_bounds );
     388           6 :     geometry_rectangle_destroy( &that_bounds );
     389             : 
     390           6 :     return result;
     391             : }
     392             : 
     393          15 : static inline geometry_rectangle_t geometry_connector_get_bounding_rectangle ( const geometry_connector_t *this_ )
     394             : {
     395             :     geometry_rectangle_t result;
     396             : 
     397          15 :     const double left = fmin ( (*this_).main_line_source_x, fmin( (*this_).source_end_x, (*this_).destination_end_x ) );
     398          15 :     const double right = fmax ( (*this_).main_line_source_x, fmax( (*this_).source_end_x, (*this_).destination_end_x ) );
     399          15 :     const double top = fmin ( (*this_).main_line_source_y, fmin( (*this_).source_end_y, (*this_).destination_end_y ) );
     400          15 :     const double bottom = fmax ( (*this_).main_line_source_y, fmax( (*this_).source_end_y, (*this_).destination_end_y ) );
     401             : 
     402          15 :     geometry_rectangle_init( &result,
     403             :                              left,
     404             :                              top,
     405             :                              right - left,
     406             :                              bottom - top
     407             :                            );
     408             : 
     409          15 :     return result;
     410             : }
     411             : 
     412           3 : static inline geometry_rectangle_t geometry_connector_get_segment_bounds ( const geometry_connector_t *this_,
     413             :                                                                            geometry_connector_segment_t segment_id )
     414             : {
     415             :     geometry_rectangle_t result;
     416             : 
     417           3 :     switch ( segment_id )
     418             :     {
     419           1 :         case GEOMETRY_CONNECTOR_SEGMENT_SOURCE:
     420             :         {
     421           1 :             const double left = fmin ( (*this_).main_line_source_x, (*this_).source_end_x );
     422           1 :             const double right = fmax ( (*this_).main_line_source_x, (*this_).source_end_x );
     423           1 :             const double top = fmin ( (*this_).main_line_source_y, (*this_).source_end_y );
     424           1 :             const double bottom = fmax ( (*this_).main_line_source_y, (*this_).source_end_y );
     425           1 :             geometry_rectangle_init( &result, left, top, right - left, bottom - top );
     426             :         }
     427           1 :         break;
     428             : 
     429           1 :         case GEOMETRY_CONNECTOR_SEGMENT_MAIN:
     430             :         {
     431           1 :             const double left = fmin ( (*this_).main_line_source_x, (*this_).main_line_destination_x );
     432           1 :             const double right = fmax ( (*this_).main_line_source_x, (*this_).main_line_destination_x );
     433           1 :             const double top = fmin ( (*this_).main_line_source_y, (*this_).main_line_destination_y );
     434           1 :             const double bottom = fmax ( (*this_).main_line_source_y, (*this_).main_line_destination_y );
     435           1 :             geometry_rectangle_init( &result, left, top, right - left, bottom - top );
     436             :         }
     437           1 :         break;
     438             : 
     439           1 :         case GEOMETRY_CONNECTOR_SEGMENT_DESTINATION:
     440             :         {
     441           1 :             const double left = fmin ( (*this_).destination_end_x, (*this_).main_line_destination_x );
     442           1 :             const double right = fmax ( (*this_).destination_end_x, (*this_).main_line_destination_x );
     443           1 :             const double top = fmin ( (*this_).destination_end_y, (*this_).main_line_destination_y );
     444           1 :             const double bottom = fmax ( (*this_).destination_end_y, (*this_).main_line_destination_y );
     445           1 :             geometry_rectangle_init( &result, left, top, right - left, bottom - top );
     446             :         }
     447           1 :         break;
     448             : 
     449           0 :         default:
     450             :         {
     451           0 :             assert( false );
     452             :             geometry_rectangle_init_empty( &result );
     453             :         }
     454             :     }
     455             : 
     456           3 :     return result;
     457             : }
     458             : 
     459           0 : static inline geometry_3dir_t geometry_connector_get_directions ( const geometry_connector_t *this_ )
     460             : {
     461           0 :     const double very_small = 0.000000001;
     462             : 
     463           0 :     const double src_dx = (*this_).main_line_source_x - (*this_).source_end_x;
     464           0 :     const double src_dy = (*this_).main_line_source_y - (*this_).source_end_y;
     465           0 :     const double abs_src_dx = fabs( src_dx );
     466           0 :     const double abs_src_dy = fabs( src_dy );
     467           0 :     const bool src_exists = (( abs_src_dx > very_small )||( abs_src_dy > very_small ));
     468           0 :     const bool src_is_horizontal = ( abs_src_dx > abs_src_dy );
     469             : 
     470           0 :     const geometry_direction_t src_dir
     471           0 :        = ( ! src_exists )
     472             :        ? GEOMETRY_DIRECTION_CENTER
     473           0 :        : src_is_horizontal
     474             :        ? (( src_dx > 0.0 ) ? GEOMETRY_DIRECTION_RIGHT : GEOMETRY_DIRECTION_LEFT )
     475             :        : (( src_dy > 0.0 ) ? GEOMETRY_DIRECTION_DOWN : GEOMETRY_DIRECTION_UP );
     476             : 
     477           0 :     const double main_dx = (*this_).main_line_destination_x - (*this_).main_line_source_x;
     478           0 :     const double main_dy = (*this_).main_line_destination_y - (*this_).main_line_source_y;
     479           0 :     const double abs_main_dx = fabs( main_dx );
     480           0 :     const double abs_main_dy = fabs( main_dy );
     481           0 :     const bool main_exists = (( abs_main_dx > very_small )||( abs_main_dy > very_small ));
     482           0 :     const bool main_is_horizontal = ( abs_main_dx > abs_main_dy );
     483             : 
     484           0 :     const geometry_direction_t main_dir
     485           0 :        = ( ! main_exists )
     486             :        ? GEOMETRY_DIRECTION_CENTER
     487           0 :        : main_is_horizontal
     488             :        ? (( main_dx > 0.0 ) ? GEOMETRY_DIRECTION_RIGHT : GEOMETRY_DIRECTION_LEFT )
     489             :        : (( main_dy > 0.0 ) ? GEOMETRY_DIRECTION_DOWN : GEOMETRY_DIRECTION_UP );
     490             : 
     491           0 :     const double dst_dx = (*this_).destination_end_x - (*this_).main_line_destination_x;
     492           0 :     const double dst_dy = (*this_).destination_end_y - (*this_).main_line_destination_y;
     493           0 :     const double abs_dst_dx = fabs( dst_dx );
     494           0 :     const double abs_dst_dy = fabs( dst_dy );
     495           0 :     const bool dst_exists = (( abs_dst_dx > very_small )||( abs_dst_dy > very_small ));
     496           0 :     const bool dst_is_horizontal = ( abs_dst_dx > abs_dst_dy );
     497             : 
     498           0 :     const geometry_direction_t dst_dir
     499           0 :        = ( ! dst_exists )
     500             :        ? GEOMETRY_DIRECTION_CENTER
     501           0 :        : dst_is_horizontal
     502             :        ? (( dst_dx > 0.0 ) ? GEOMETRY_DIRECTION_RIGHT : GEOMETRY_DIRECTION_LEFT )
     503             :        : (( dst_dy > 0.0 ) ? GEOMETRY_DIRECTION_DOWN : GEOMETRY_DIRECTION_UP );
     504             : 
     505           0 :     const geometry_3dir_t result = { .first = src_dir, .second = main_dir, .third = dst_dir };
     506           0 :     return result;
     507             : }
     508             : 
     509           0 : static inline void geometry_connector_trace ( const geometry_connector_t *this_ )
     510             : {
     511             :     static const char geometry_mnemomic[GEOMETRY_DIRECTION_MAX]
     512             :         = { '.', '<', 'F', '^', '7', '>', 'J', 'v', 'L' };
     513             : 
     514           0 :     const geometry_3dir_t pattern = geometry_connector_get_directions( this_ );
     515           0 :     const char pattern_as_str[6]
     516           0 :         = { [0] = geometry_mnemomic[pattern.first],
     517             :             [1] = ' ',
     518           0 :             [2] = geometry_mnemomic[pattern.second],
     519             :             [3] = ' ',
     520           0 :             [4] = geometry_mnemomic[pattern.third],
     521             :             [5] = '\0' };
     522             : 
     523           0 :     U8_TRACE_INFO( "geometry_connector_t" );
     524           0 :     U8_TRACE_INFO_INT( "- source_end_x:", (*this_).source_end_x );
     525           0 :     U8_TRACE_INFO_INT( "- source_end_y:", (*this_).source_end_y );
     526           0 :     U8_TRACE_INFO_INT( "- main_line_source_x:", (*this_).main_line_source_x );
     527           0 :     U8_TRACE_INFO_INT( "- main_line_source_y:", (*this_).main_line_source_y );
     528           0 :     U8_TRACE_INFO_INT( "- main_line_destination_x:", (*this_).main_line_destination_x );
     529           0 :     U8_TRACE_INFO_INT( "- main_line_destination_y:", (*this_).main_line_destination_y );
     530           0 :     U8_TRACE_INFO_INT( "- destination_end_x:", (*this_).destination_end_x );
     531           0 :     U8_TRACE_INFO_INT( "- destination_end_y:", (*this_).destination_end_y );
     532           0 :     U8_TRACE_INFO_STR( "- get_directions:", pattern_as_str );
     533           0 : }
     534             : 
     535             : 
     536             : /*
     537             : Copyright 2017-2024 Andreas Warnke
     538             : 
     539             : Licensed under the Apache License, Version 2.0 (the "License");
     540             : you may not use this file except in compliance with the License.
     541             : You may obtain a copy of the License at
     542             : 
     543             :     http://www.apache.org/licenses/LICENSE-2.0
     544             : 
     545             : Unless required by applicable law or agreed to in writing, software
     546             : distributed under the License is distributed on an "AS IS" BASIS,
     547             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     548             : See the License for the specific language governing permissions and
     549             : limitations under the License.
     550             : */

Generated by: LCOV version 1.16