Line data Source code
1 : /* File: geometry_non_linear_scale.inl; Copyright and License: see below */
2 :
3 : #include "u8/u8_trace.h"
4 : #include "u8/u8_log.h"
5 : #include <assert.h>
6 : #include <stdbool.h>
7 :
8 1 : static inline void geometry_non_linear_scale_reinit ( geometry_non_linear_scale_t *this_, double lower_bound, double upper_bound )
9 : {
10 1 : geometry_non_linear_scale_init( this_, lower_bound, upper_bound );
11 1 : }
12 :
13 4 : static inline void geometry_non_linear_scale_destroy ( geometry_non_linear_scale_t *this_ )
14 : {
15 4 : }
16 :
17 5 : static inline double geometry_non_linear_scale_get_location ( const geometry_non_linear_scale_t *this_, int32_t order )
18 : {
19 5 : U8_TRACE_BEGIN();
20 5 : assert( (*this_).num_points <= GEOMETRY_NON_LINEAR_SCALE_MAX_POINTS );
21 5 : assert( (*this_).num_points >= 2 );
22 5 : double result = (*this_).location[(*this_).num_points-1];
23 : bool found;
24 :
25 5 : found = false;
26 5 : if ( order <= (*this_).order[0] )
27 : {
28 2 : found = true;
29 2 : result = (*this_).location[0];
30 2 : U8_TRACE_INFO_INT( "result-%", result*100 );
31 : }
32 10 : for ( uint32_t pos = 1; ( pos < (*this_).num_points ) && ( ! found ) ; pos ++ )
33 : {
34 5 : if ( order < (*this_).order[pos] )
35 : {
36 2 : found = true;
37 2 : const double loc_interval_width = (*this_).location[pos] - (*this_).location[pos-1];
38 2 : const uint32_t ord_interval_width = (*this_).order[pos] - (*this_).order[pos-1];
39 : /* prevent division by zero */
40 2 : const uint32_t ord_interval_width_nonzero = ( ord_interval_width < 1 ) ? 1 : ord_interval_width;
41 2 : const uint32_t order_interval_offset = order - (*this_).order[pos-1];
42 2 : result = (*this_).location[pos-1] + ( loc_interval_width * ((double)order_interval_offset) / ((double)ord_interval_width_nonzero) );
43 :
44 2 : U8_TRACE_INFO_INT( "interval id:", pos );
45 2 : U8_TRACE_INFO_INT_INT( "interval [i-1,i]:", (int32_t)(*this_).location[pos-1], (int32_t)(*this_).location[pos] );
46 2 : U8_TRACE_INFO_INT( "result", (int32_t)result );
47 : }
48 3 : else if ( order == (*this_).order[pos] )
49 : {
50 1 : found = true;
51 1 : result = (*this_).location[pos];
52 1 : U8_TRACE_INFO_INT( "result", (int32_t)result );
53 : }
54 : }
55 :
56 5 : U8_TRACE_END();
57 5 : return result;
58 : }
59 :
60 6 : static inline int32_t geometry_non_linear_scale_get_order ( const geometry_non_linear_scale_t *this_, double location, double snap_interval )
61 : {
62 6 : U8_TRACE_BEGIN();
63 6 : assert( (*this_).num_points <= GEOMETRY_NON_LINEAR_SCALE_MAX_POINTS );
64 6 : assert( (*this_).num_points >= 2 );
65 6 : assert( snap_interval >= 0.0 );
66 6 : int32_t result = (*this_).order[(*this_).num_points-1];
67 : bool found;
68 :
69 6 : found = false;
70 6 : if ( location <= (*this_).location[0] ) /* on left border, no snap_interval */
71 : {
72 1 : found = true;
73 1 : result = (*this_).order[0];
74 1 : U8_TRACE_INFO_INT( "result", result );
75 : }
76 16 : for ( uint32_t pos = 1; ( pos < (*this_).num_points ) && ( ! found ) ; pos ++ )
77 : {
78 10 : const double snap_dist = ( pos == ( (*this_).num_points - 1 ) ) ? 0.0 : snap_interval; /* no snap at right border */
79 10 : if ( location <= ( (*this_).location[pos] + snap_dist ) )
80 : {
81 4 : if ( location > ( (*this_).location[pos] - snap_dist ) )
82 : {
83 1 : found = true;
84 1 : result = (*this_).order[pos];
85 1 : U8_TRACE_INFO_INT( "result", result );
86 : }
87 : else
88 : {
89 3 : found = true;
90 3 : const double loc_interval_width = (*this_).location[pos] - (*this_).location[pos-1];
91 : /* prevent division by zero */
92 3 : const double loc_interval_width_nonzero = ( loc_interval_width < 0.000000001 ) ? 0.000000001 : loc_interval_width;
93 3 : const uint32_t ord_interval_width = (*this_).order[pos] - (*this_).order[pos-1];
94 3 : const uint32_t order_interval_offset = ((double)ord_interval_width) * ( location - (*this_).location[pos-1] ) / loc_interval_width_nonzero;
95 3 : result = (*this_).order[pos-1] + order_interval_offset;
96 :
97 3 : U8_TRACE_INFO_INT( "interval id:", pos );
98 3 : U8_TRACE_INFO_INT_INT( "interval [i-1,i]:", (*this_).order[pos-1], (*this_).order[pos] );
99 3 : U8_TRACE_INFO_INT( "result", result );
100 : }
101 : }
102 : }
103 :
104 6 : U8_TRACE_END();
105 6 : return result;
106 : }
107 :
108 6 : static inline bool geometry_non_linear_scale_is_order_on_grid ( const geometry_non_linear_scale_t *this_, int32_t order )
109 : {
110 6 : U8_TRACE_BEGIN();
111 6 : assert( (*this_).num_points <= GEOMETRY_NON_LINEAR_SCALE_MAX_POINTS );
112 6 : assert( (*this_).num_points >= 2 );
113 6 : bool found = false;
114 6 : bool result = false;
115 :
116 6 : found = false;
117 70 : for ( uint32_t pos = 1; ( pos < ( (*this_).num_points - 1 ) ) && ( ! found ) ; pos ++ )
118 : {
119 64 : if ( order < (*this_).order[pos] )
120 : {
121 2 : found = true;
122 2 : result = false;
123 : }
124 62 : else if ( order == (*this_).order[pos] )
125 : {
126 2 : found = true;
127 2 : result = true;
128 : }
129 : }
130 :
131 6 : U8_TRACE_END();
132 6 : return result;
133 : }
134 :
135 2 : static inline uint32_t geometry_non_linear_scale_get_grid_intervals ( const geometry_non_linear_scale_t *this_ )
136 : {
137 2 : assert( (*this_).num_points >= 2 );
138 2 : return( (*this_).num_points - 1 );
139 : }
140 :
141 1 : static inline double geometry_non_linear_scale_get_grid_distances ( const geometry_non_linear_scale_t *this_ )
142 : {
143 1 : assert( (*this_).num_points >= 2 );
144 1 : assert( (*this_).num_points <= GEOMETRY_NON_LINEAR_SCALE_MAX_POINTS );
145 1 : return(( (*this_).location[(*this_).num_points-1] - (*this_).location[0] )/( (*this_).num_points - 1 ));
146 : }
147 :
148 :
149 : /*
150 : Copyright 2016-2025 Andreas Warnke
151 :
152 : Licensed under the Apache License, Version 2.0 (the "License");
153 : you may not use this file except in compliance with the License.
154 : You may obtain a copy of the License at
155 :
156 : http://www.apache.org/licenses/LICENSE-2.0
157 :
158 : Unless required by applicable law or agreed to in writing, software
159 : distributed under the License is distributed on an "AS IS" BASIS,
160 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
161 : See the License for the specific language governing permissions and
162 : limitations under the License.
163 : */
|