git clone https://git.lucas.co/hou-control.git
vex/include/hctl_utils.h (7.5K)
1 #ifndef _im_utils_
2 #define _im_utils_
3
4 // Iterated Neighbours
5 int[] im_nbrs(int geo; int pt_in; int depth) {
6 int pt_arr[] = array(pt_in);
7 int searched[] = array(pt_in);
8 int result[] = array(pt_in);
9 for(int i = 0; i < depth; i++) {
10 int new_pt_arr[] = {};
11 foreach(int pt; pt_arr) {
12 int nbr_arr[] = neighbours(geo, pt);
13 foreach(int nbr; nbr_arr) {
14 int idx = find(searched, nbr);
15 if(idx < 0) {
16 append(searched, nbr);
17 append(new_pt_arr, nbr);
18 append(result, nbr);
19 }
20 }
21 }
22 pt_arr = new_pt_arr;
23 }
24 return result;
25 }
26 int[] im_nbrs(int geo; int pt_arr_in[]; int depth) {
27 int pt_arr[] = pt_arr_in;
28 int searched[] = pt_arr_in;
29 int result[] = pt_arr_in;
30 for(int i = 0; i < depth; i++) {
31 int new_pt_arr[] = {};
32 foreach(int pt; pt_arr) {
33 int nbr_arr[] = neighbours(geo, pt);
34 foreach(int nbr; nbr_arr) {
35 int idx = find(searched, nbr);
36 if(idx < 0) {
37 append(searched, nbr);
38 append(new_pt_arr, nbr);
39 append(result, nbr);
40 }
41 }
42 }
43 pt_arr = new_pt_arr;
44 }
45 return result;
46 }
47
48 // neighbours Shortcut
49 int[] im_nbrs(int geo; int pt) {
50 int nbrs[] = neighbours(geo, pt);
51 return nbrs;
52 }
53
54 // Neighbours in Group
55 int[] im_nbrs_in_group(int geo; string group; int pt) {
56 int nbrs_0[] = neighbours(geo, pt);
57 int nbrs_1[];
58 int group_pts[] = expandpointgroup(0, group);
59 foreach(int nbr; nbrs_0) {
60 int idx = find(group_pts, nbr);
61 if(idx >= 0)
62 append(nbrs_1, nbr);
63 }
64 return(nbrs_1);
65 }
66
67 // setpointattrib Shortcut
68 void im_set_pt_attr(int geo; string attr; int pt; int val) {
69 setpointattrib(geo, attr, pt, val);
70 }
71 void im_set_pt_attr(int geo; string attr; int pt; int val[]) {
72 setpointattrib(geo, attr, pt, val);
73 }
74
75 // setpointgroup Shortcut
76 void im_set_pt_grp(int geo; string group; int pt; int val) {
77 setpointgroup(geo, group, pt, val);
78 }
79
80 // npoints Shortcut
81 int im_npts(int geo) {
82 return(npoints(geo));
83 }
84
85 // Float to String
86 string im_ftoa(const float f; const int decimal_places) {
87 return sprintf("%.*g", decimal_places + (int)log10(abs(f)) + (abs(f) >= 1.0), f);
88 }
89 string im_ftoa(const float f) {
90 return im_ftoa(f, 3);
91 }
92
93 // Binary Search
94 float im_bin_search(const int arr[], target_val; export int success) {
95 success = 0;
96 int ct = len(arr);
97 if(ct == 0)
98 return -1.0;
99 int l = 0;
100 int r = ct - 1;
101 int m = -1;
102
103 while(l <= r) {
104 m = (l + r) / 2;
105 if(arr[m] < target_val)
106 l = m + 1;
107 else if(arr[m] > target_val)
108 r = m - 1;
109 else {
110 success = 1;
111 break;
112 }
113 }
114 // Only happens when the left index is 1 less than the right
115 // index and the target value is between the two values
116 if(l > r)
117 m = r;
118 // If the target value is greater than a few duplicated values
119 // but less than the next value, the middle index will always
120 // move to the last of the duplicates
121 float idx = m;
122 if(!success) {
123 if(target_val < arr[0] || target_val > arr[ct - 1])
124 idx = -1.0;
125 else if(m + 1 < ct)
126 // In VEX division by zero returns zero.
127 idx += float(target_val - arr[m]) / (arr[m + 1] - arr[m]);
128 }
129 return idx;
130 }
131 float im_bin_search(const float arr[], target_val; export int success) {
132 success = 0;
133 int ct = len(arr);
134 if(ct == 0)
135 return -1.0;
136 int l = 0;
137 int r = ct - 1;
138 int m = -1;
139 // Forces the target value to have the same floating-point precision as the array elements
140 float target_val_safe = set(target_val, 0)[0];
141
142 while (l <= r) {
143 m = (l + r) / 2;
144 if(arr[m] < target_val_safe)
145 l = m + 1;
146 else if(arr[m] > target_val_safe)
147 r = m - 1;
148 else {
149 success = 1;
150 break;
151 }
152 }
153 // Only happens when the left index is 1 less than the right
154 // index and the target value is between the two values
155 if(l > r)
156 m = r;
157 // If the target value is greater than a few duplicated values
158 // but less than the next value, the middle index will always
159 // move to the last of the duplicates
160 float idx = m;
161 if(!success) {
162 if(target_val_safe < arr[0] || target_val_safe > arr[ct - 1])
163 idx = -1.0;
164 else if(m + 1 < ct)
165 // In VEX division by zero returns zero.
166 idx += float(target_val_safe - arr[m]) / (arr[m + 1] - arr[m]);
167 }
168 return idx;
169 }
170 int im_bin_search(const string arr[], target_val; export int success) {
171 success = 0;
172 int ct = len(arr);
173 if(ct == 0)
174 return -1;
175 int l = 0;
176 int r = ct - 1;
177 int m = -1;
178
179 while(l <= r) {
180 m = (l + r) / 2;
181 if(arr[m] < target_val)
182 l = m + 1;
183 else if(arr[m] > target_val)
184 r = m - 1;
185 else {
186 success = 1;
187 break;
188 }
189 }
190 // Only happens when the left index is 1 less than the right
191 // index and the target value is between the two values
192 if(l > r)
193 m = r;
194 // If the target value is greater than a few duplicated values
195 // but less than the next value, the middle index will always
196 // move to the last of the duplicates
197 int idx = m;
198 if(!success) {
199 if(target_val < arr[0] || target_val > arr[ct - 1])
200 idx = -1;
201 }
202 return idx;
203 }
204
205 // Append Unique
206 void im_append_unique(export int arr[]; const int val) {
207 if(find(arr, val) < 0)
208 append(arr, val);
209 }
210 void im_append_unique(export float arr[]; const float val) {
211 if(find(arr, val) < 0)
212 append(arr, val);
213 }
214 void im_append_unique(export vector2 arr[]; const vector2 val) {
215 if(find(arr, val) < 0)
216 append(arr, val);
217 }
218 void im_append_unique(export vector arr[]; const vector val) {
219 if(find(arr, val) < 0)
220 append(arr, val);
221 }
222 void im_append_unique(export vector4 arr[]; const vector4 val) {
223 if(find(arr, val) < 0)
224 append(arr, val);
225 }
226 void im_append_unique(export string arr[]; const string val) {
227 if(find(arr, val) < 0)
228 append(arr, val);
229 }
230 void im_append_unique(export string str; const string val) {
231 if(find(str, val) < 0)
232 append(str, val);
233 }
234
235 // Make Array Unique
236 int[] im_unique_arr(const int arr[]) {
237 int new_arr[] = {};
238 foreach(int val; arr)
239 im_append_unique(new_arr, val);
240 return new_arr;
241 }
242 float[] im_unique_arr(const float arr[]) {
243 float new_arr[] = {};
244 foreach(float val; arr)
245 im_append_unique(new_arr, val);
246 return unique_arr;
247 }
248 vector2[] im_unique_arr(const vector2 arr[]) {
249 vector2 new_arr[] = {};
250 foreach(vector2 val; arr)
251 im_append_unique(new_arr, val);
252 return new_arr;
253 }
254 vector[] im_unique_arr(const vector arr[]) {
255 vector new_arr[] = {};
256 foreach(vector val; arr)
257 im_append_unique(new_arr, val);
258 return new_arr;
259 }
260 vector4[] im_unique_arr(const vector4 arr[]) {
261 vector4 new_arr[] = {};
262 foreach(vector4 val; arr)
263 im_append_unique(new_arr, val);
264 return new_arr;
265 }
266 string[] im_unique_arr(const string arr[]) {
267 string new_arr[] = {};
268 foreach(string val; arr)
269 im_append_unique(new_arr, val);
270 return new_arr;
271 }
272 string im_unique_arr(const string str) {
273 string new_str = "";
274 foreach(string val; str)
275 im_append_unique(new_str, val);
276 return new_str;
277 }
278
279 #endif