LCOV - code coverage report
Current view: top level - pencil/source/geometry - geometry_non_linear_scale.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.65.6_covts Lines: 52 52 100.0 %
Date: 2025-09-25 21:07:53 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* File: geometry_non_linear_scale.c; Copyright and License: see below */
       2             : 
       3             : #define __STDC_LIMIT_MACROS
       4             : #include "geometry/geometry_non_linear_scale.h"
       5             : #include "u8/u8_trace.h"
       6             : #include "u8/u8_log.h"
       7             : #include <assert.h>
       8             : #include <stdint.h>
       9             : #include <stdbool.h>
      10             : 
      11          14 : void geometry_non_linear_scale_init ( geometry_non_linear_scale_t *this_, double lower_bound, double upper_bound )
      12             : {
      13          14 :     U8_TRACE_BEGIN();
      14          14 :     assert( lower_bound <= upper_bound );
      15             : 
      16          14 :     (*this_).num_points = 2;
      17          14 :     (*this_).location[0] = lower_bound;
      18          14 :     (*this_).order[0] = INT32_MIN;
      19          14 :     (*this_).location[1] = upper_bound;
      20          14 :     (*this_).order[1] = INT32_MAX;
      21             : 
      22          14 :     U8_TRACE_END();
      23          14 : }
      24             : 
      25           5 : void geometry_non_linear_scale_trace ( const geometry_non_linear_scale_t *this_ )
      26             : {
      27           5 :     U8_TRACE_BEGIN();
      28           5 :     assert( (*this_).num_points <= GEOMETRY_NON_LINEAR_SCALE_MAX_POINTS );
      29             : 
      30           5 :     U8_TRACE_INFO( "geometry_non_linear_scale_t" );
      31           5 :     U8_TRACE_INFO_INT( "- num_points:", (*this_).num_points );
      32          17 :     for ( uint32_t pos = 0; pos < (*this_).num_points; pos ++ )
      33             :     {
      34          12 :         U8_TRACE_INFO_INT_INT( "- location-%, order:", (int)((*this_).location[pos]*100.0), (*this_).order[pos] );
      35             :     }
      36             : 
      37           5 :     U8_TRACE_END();
      38           5 : }
      39             : 
      40          34 : u8_error_t geometry_non_linear_scale_add_order ( geometry_non_linear_scale_t *this_, int32_t order )
      41             : {
      42          34 :     U8_TRACE_BEGIN();
      43          34 :     assert( (*this_).num_points <= GEOMETRY_NON_LINEAR_SCALE_MAX_POINTS );
      44          34 :     assert( (*this_).num_points >= 2 );  /* prevent division by zero */
      45          34 :     u8_error_t result = U8_ERROR_NONE;
      46             : 
      47             :     /* check for duplicates and for possible insert position */
      48          34 :     bool duplicate = false;
      49          34 :     uint32_t insert_pos = 0;
      50         570 :     for ( uint32_t pos = 0; pos < (*this_).num_points; pos ++ )
      51             :     {
      52         536 :         if ( order > (*this_).order[pos] )
      53             :         {
      54         501 :             insert_pos = pos+1;
      55             :         }
      56          35 :         else if ( order == (*this_).order[pos] )
      57             :         {
      58           1 :             duplicate = true;
      59           1 :             U8_TRACE_INFO_INT( "duplicate:", order );
      60             :         }
      61             :     }
      62             : 
      63             :     /* insert if possible */
      64          34 :     if ( ! duplicate )
      65             :     {
      66          33 :         if ( (*this_).num_points < GEOMETRY_NON_LINEAR_SCALE_MAX_POINTS )
      67             :         {
      68             :             double lower_bound;
      69             :             double upper_bound;
      70          32 :             lower_bound = (*this_).location[ 0 ];
      71          32 :             upper_bound = (*this_).location[ (*this_).num_points - 1 ];
      72             : 
      73             :             /* insert order value */
      74          64 :             for ( uint32_t pos2 = (*this_).num_points; pos2 > insert_pos; pos2 -- )
      75             :             {
      76          32 :                 (*this_).order[ pos2 ] = (*this_).order[ pos2-1 ];
      77             :             }
      78          32 :             (*this_).order[ insert_pos ] = order;
      79          32 :             (*this_).num_points ++;
      80             : 
      81             :             /* re-location in interval */
      82             :             double interval_width;
      83          32 :             interval_width = ( upper_bound - lower_bound );
      84         564 :             for ( uint32_t pos3 = 0; pos3 < (*this_).num_points; pos3 ++ )
      85             :             {
      86         532 :                 (*this_).location[ pos3 ] = lower_bound + ( (double) pos3 * interval_width ) / (double) ( (*this_).num_points - 1 );
      87             :             }
      88             :         }
      89             :         else
      90             :         {
      91           1 :             U8_LOG_WARNING( "geometry_non_linear_scale_t has not enough points." );
      92           1 :             result = U8_ERROR_ARRAY_BUFFER_EXCEEDED;
      93             :         }
      94             :     }
      95             : 
      96             :     /* check for monotonic increase of order values and location values */
      97             : #ifndef NDEBUG
      98          34 :     assert( (*this_).num_points <= GEOMETRY_NON_LINEAR_SCALE_MAX_POINTS );
      99          34 :     assert( (*this_).num_points >= 2 );
     100         568 :     for ( uint32_t pos2 = 1; pos2 < (*this_).num_points; pos2 ++ )
     101             :     {
     102         534 :         assert( (*this_).order[pos2-1] < (*this_).order[pos2] );
     103         534 :         assert( (*this_).location[pos2-1]-0.000000001 < (*this_).location[pos2] );  /* equal locations are possible if lower_bound == upper_bound */
     104             :     }
     105             : #endif
     106             : 
     107          34 :     U8_TRACE_END_ERR( result );
     108          34 :     return result;
     109             : }
     110             : 
     111             : 
     112             : /*
     113             : Copyright 2016-2025 Andreas Warnke
     114             : 
     115             : Licensed under the Apache License, Version 2.0 (the "License");
     116             : you may not use this file except in compliance with the License.
     117             : You may obtain a copy of the License at
     118             : 
     119             :     http://www.apache.org/licenses/LICENSE-2.0
     120             : 
     121             : Unless required by applicable law or agreed to in writing, software
     122             : distributed under the License is distributed on an "AS IS" BASIS,
     123             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     124             : See the License for the specific language governing permissions and
     125             : limitations under the License.
     126             : */

Generated by: LCOV version 1.16