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 : */
|