Line | Branch | Exec | Source |
---|---|---|---|
1 | /******************************************************************************* | ||
2 | |||
3 | License: | ||
4 | This software and/or related materials was developed at the National Institute | ||
5 | of Standards and Technology (NIST) by employees of the Federal Government | ||
6 | in the course of their official duties. Pursuant to title 17 Section 105 | ||
7 | of the United States Code, this software is not subject to copyright | ||
8 | protection and is in the public domain. | ||
9 | |||
10 | This software and/or related materials have been determined to be not subject | ||
11 | to the EAR (see Part 734.3 of the EAR for exact details) because it is | ||
12 | a publicly available technology and software, and is freely distributed | ||
13 | to any interested party with no licensing requirements. Therefore, it is | ||
14 | permissible to distribute this software as a free download from the internet. | ||
15 | |||
16 | Disclaimer: | ||
17 | This software and/or related materials was developed to promote biometric | ||
18 | standards and biometric technology testing for the Federal Government | ||
19 | in accordance with the USA PATRIOT Act and the Enhanced Border Security | ||
20 | and Visa Entry Reform Act. Specific hardware and software products identified | ||
21 | in this software were used in order to perform the software development. | ||
22 | In no case does such identification imply recommendation or endorsement | ||
23 | by the National Institute of Standards and Technology, nor does it imply that | ||
24 | the products and equipment identified are necessarily the best available | ||
25 | for the purpose. | ||
26 | |||
27 | This software and/or related materials are provided "AS-IS" without warranty | ||
28 | of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY, | ||
29 | NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY | ||
30 | or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the | ||
31 | licensed product, however used. In no event shall NIST be liable for any | ||
32 | damages and/or costs, including but not limited to incidental or consequential | ||
33 | damages of any kind, including economic damage or injury to property and lost | ||
34 | profits, regardless of whether NIST shall be advised, have reason to know, | ||
35 | or in fact shall know of the possibility. | ||
36 | |||
37 | By using this software, you agree to bear all risk relating to quality, | ||
38 | use and performance of the software and/or related materials. You agree | ||
39 | to hold the Government harmless from any claim arising from your use | ||
40 | of the software. | ||
41 | |||
42 | *******************************************************************************/ | ||
43 | |||
44 | |||
45 | /*********************************************************************** | ||
46 | LIBRARY: LFS - NIST Latent Fingerprint System | ||
47 | |||
48 | FILE: UTIL.C | ||
49 | AUTHOR: Michael D. Garris | ||
50 | DATE: 03/16/1999 | ||
51 | |||
52 | Contains general support routines required by the NIST | ||
53 | Latent Fingerprint System (LFS). | ||
54 | |||
55 | *********************************************************************** | ||
56 | ROUTINES: | ||
57 | maxv() | ||
58 | minv() | ||
59 | minmaxs() | ||
60 | distance() | ||
61 | squared_distance() | ||
62 | in_int_list() | ||
63 | remove_from_int_list() | ||
64 | find_incr_position_dbl() | ||
65 | angle2line() | ||
66 | line2direction() | ||
67 | closest_dir_dist() | ||
68 | ***********************************************************************/ | ||
69 | |||
70 | #include <stdio.h> | ||
71 | #include <lfs.h> | ||
72 | |||
73 | /************************************************************************* | ||
74 | ************************************************************************** | ||
75 | #cat: maxv - Determines the maximum value in the given list of integers. | ||
76 | #cat: NOTE, the list is assumed to be NOT empty! | ||
77 | |||
78 | Input: | ||
79 | list - non-empty list of integers to be searched | ||
80 | num - number of integers in the list | ||
81 | Return Code: | ||
82 | Maximum - maximum value in the list | ||
83 | **************************************************************************/ | ||
84 | 5960 | int maxv(const int *list, const int num) | |
85 | { | ||
86 | 5960 | int i; | |
87 | 5960 | int maxval; | |
88 | |||
89 | /* NOTE: The list is assumed to be NOT empty. */ | ||
90 | /* Initialize running maximum to first item in list. */ | ||
91 | 5960 | maxval = list[0]; | |
92 | |||
93 | /* Foreach subsequent item in the list... */ | ||
94 |
2/2✓ Branch 0 taken 77320 times.
✓ Branch 1 taken 5960 times.
|
83280 | for(i = 1; i < num; i++){ |
95 | /* If current item is larger than running maximum... */ | ||
96 | 77320 | if(list[i] > maxval) | |
97 | /* Set running maximum to the larger item. */ | ||
98 | maxval = list[i]; | ||
99 | /* Otherwise, skip to next item. */ | ||
100 | } | ||
101 | |||
102 | /* Return the resulting maximum. */ | ||
103 | 5960 | return(maxval); | |
104 | } | ||
105 | |||
106 | /************************************************************************* | ||
107 | ************************************************************************** | ||
108 | #cat: minv - Determines the minimum value in the given list of integers. | ||
109 | #cat: NOTE, the list is assumed to be NOT empty! | ||
110 | |||
111 | Input: | ||
112 | list - non-empty list of integers to be searched | ||
113 | num - number of integers in the list | ||
114 | Return Code: | ||
115 | Minimum - minimum value in the list | ||
116 | **************************************************************************/ | ||
117 | 5960 | int minv(const int *list, const int num) | |
118 | { | ||
119 | 5960 | int i; | |
120 | 5960 | int minval; | |
121 | |||
122 | /* NOTE: The list is assumed to be NOT empty. */ | ||
123 | /* Initialize running minimum to first item in list. */ | ||
124 | 5960 | minval = list[0]; | |
125 | |||
126 | /* Foreach subsequent item in the list... */ | ||
127 |
2/2✓ Branch 0 taken 77320 times.
✓ Branch 1 taken 5960 times.
|
83280 | for(i = 1; i < num; i++){ |
128 | /* If current item is smaller than running minimum... */ | ||
129 | 77320 | if(list[i] < minval) | |
130 | /* Set running minimum to the smaller item. */ | ||
131 | minval = list[i]; | ||
132 | /* Otherwise, skip to next item. */ | ||
133 | } | ||
134 | |||
135 | /* Return the resulting minimum. */ | ||
136 | 5960 | return(minval); | |
137 | } | ||
138 | |||
139 | /************************************************************************* | ||
140 | ************************************************************************** | ||
141 | #cat: minmaxs - Takes a list of integers and identifies points of relative | ||
142 | #cat: minima and maxima. The midpoint of flat plateaus and valleys | ||
143 | #cat: are selected when they are detected. | ||
144 | |||
145 | Input: | ||
146 | items - list of integers to be analyzed | ||
147 | num - number of items in the list | ||
148 | Output: | ||
149 | ominmax_val - value of the item at each minima or maxima | ||
150 | ominmax_type - identifies a minima as '-1' and maxima as '1' | ||
151 | ominmax_i - index of item's position in list | ||
152 | ominmax_alloc - number of allocated minima and/or maxima | ||
153 | ominmax_num - number of detected minima and/or maxima | ||
154 | Return Code: | ||
155 | Zero - successful completion | ||
156 | Negative - system error | ||
157 | **************************************************************************/ | ||
158 | 22400 | int minmaxs(int **ominmax_val, int **ominmax_type, int **ominmax_i, | |
159 | int *ominmax_alloc, int *ominmax_num, | ||
160 | const int *items, const int num) | ||
161 | { | ||
162 | 22400 | int i, diff, state, start, loc; | |
163 | 22400 | int *minmax_val, *minmax_type, *minmax_i, minmax_alloc, minmax_num; | |
164 | |||
165 | |||
166 | /* Determine maximum length for allocation of buffers. */ | ||
167 | /* If there are fewer than 3 items ... */ | ||
168 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 22400 times.
|
22400 | if(num < 3){ |
169 | /* Then no min/max is possible, so set allocated length */ | ||
170 | /* to 0 and return. */ | ||
171 | ✗ | *ominmax_alloc = 0; | |
172 | ✗ | *ominmax_num = 0; | |
173 | ✗ | return(0); | |
174 | } | ||
175 | /* Otherwise, set allocation length to number of items - 2 */ | ||
176 | /* (one for the first item in the list, and on for the last). */ | ||
177 | /* Every other intermediate point can potentially represent a */ | ||
178 | /* min or max. */ | ||
179 | 22400 | minmax_alloc = num - 2; | |
180 | /* Allocate the buffers. */ | ||
181 | 22400 | minmax_val = (int *)g_malloc(minmax_alloc * sizeof(int)); | |
182 | 22400 | minmax_type = (int *)g_malloc(minmax_alloc * sizeof(int)); | |
183 | 22400 | minmax_i = (int *)g_malloc(minmax_alloc * sizeof(int)); | |
184 | |||
185 | /* Initialize number of min/max to 0. */ | ||
186 | 22400 | minmax_num = 0; | |
187 | |||
188 | /* Start witht the first item in the list. */ | ||
189 | 22400 | i = 0; | |
190 | |||
191 | /* Get starting state between first pair of items. */ | ||
192 | 22400 | diff = items[1] - items[0]; | |
193 |
2/2✓ Branch 0 taken 15466 times.
✓ Branch 1 taken 6934 times.
|
22400 | if(diff > 0) |
194 | state = 1; | ||
195 |
2/2✓ Branch 0 taken 2275 times.
✓ Branch 1 taken 13191 times.
|
15466 | else if (diff < 0) |
196 | state = -1; | ||
197 | else | ||
198 | 2275 | state = 0; | |
199 | |||
200 | /* Set start location to first item in list. */ | ||
201 | start = 0; | ||
202 | |||
203 | /* Bump to next item in list. */ | ||
204 | i++; | ||
205 | |||
206 | /* While not at the last item in list. */ | ||
207 |
2/2✓ Branch 0 taken 291200 times.
✓ Branch 1 taken 22400 times.
|
313600 | while(i < num-1){ |
208 | |||
209 | /* Compute difference between next pair of items. */ | ||
210 | 291200 | diff = items[i+1] - items[i]; | |
211 | /* If items are increasing ... */ | ||
212 |
2/2✓ Branch 0 taken 136243 times.
✓ Branch 1 taken 154957 times.
|
291200 | if(diff > 0){ |
213 | /* If previously increasing ... */ | ||
214 |
2/2✓ Branch 0 taken 13998 times.
✓ Branch 1 taken 122245 times.
|
136243 | if(state == 1){ |
215 | /* Reset start to current location. */ | ||
216 | start = i; | ||
217 | } | ||
218 | /* If previously decreasing ... */ | ||
219 |
2/2✓ Branch 0 taken 13385 times.
✓ Branch 1 taken 613 times.
|
13998 | else if (state == -1){ |
220 | /* Then we have incurred a minima ... */ | ||
221 | /* Compute midpoint of minima. */ | ||
222 | 13385 | loc = (start + i)/2; | |
223 | /* Store value at minima midpoint. */ | ||
224 | 13385 | minmax_val[minmax_num] = items[loc]; | |
225 | /* Store type code for minima. */ | ||
226 | 13385 | minmax_type[minmax_num] = -1; | |
227 | /* Store location of minima midpoint. */ | ||
228 | 13385 | minmax_i[minmax_num++] = loc; | |
229 | /* Change state to increasing. */ | ||
230 | 13385 | state = 1; | |
231 | /* Reset start location. */ | ||
232 | 13385 | start = i; | |
233 | } | ||
234 | /* If previously level (this state only can occur at the */ | ||
235 | /* beginning of the list of items) ... */ | ||
236 | else { | ||
237 | /* If more than one level state in a row ... */ | ||
238 |
2/2✓ Branch 0 taken 96 times.
✓ Branch 1 taken 517 times.
|
613 | if(i-start > 1){ |
239 | /* Then consider a minima ... */ | ||
240 | /* Compute midpoint of minima. */ | ||
241 | 96 | loc = (start + i)/2; | |
242 | /* Store value at minima midpoint. */ | ||
243 | 96 | minmax_val[minmax_num] = items[loc]; | |
244 | /* Store type code for minima. */ | ||
245 | 96 | minmax_type[minmax_num] = -1; | |
246 | /* Store location of minima midpoint. */ | ||
247 | 96 | minmax_i[minmax_num++] = loc; | |
248 | /* Change state to increasing. */ | ||
249 | 96 | state = 1; | |
250 | /* Reset start location. */ | ||
251 | 96 | start = i; | |
252 | } | ||
253 | /* Otherwise, ignore single level state. */ | ||
254 | else{ | ||
255 | /* Change state to increasing. */ | ||
256 | state = 1; | ||
257 | /* Reset start location. */ | ||
258 | start = i; | ||
259 | } | ||
260 | } | ||
261 | } | ||
262 | /* If items are decreasing ... */ | ||
263 |
2/2✓ Branch 0 taken 115673 times.
✓ Branch 1 taken 39284 times.
|
154957 | else if(diff < 0){ |
264 | /* If previously decreasing ... */ | ||
265 |
2/2✓ Branch 0 taken 7092 times.
✓ Branch 1 taken 108581 times.
|
115673 | if(state == -1){ |
266 | /* Reset start to current location. */ | ||
267 | start = i; | ||
268 | } | ||
269 | /* If previously increasing ... */ | ||
270 |
2/2✓ Branch 0 taken 5430 times.
✓ Branch 1 taken 1662 times.
|
7092 | else if (state == 1){ |
271 | /* Then we have incurred a maxima ... */ | ||
272 | /* Compute midpoint of maxima. */ | ||
273 | 5430 | loc = (start + i)/2; | |
274 | /* Store value at maxima midpoint. */ | ||
275 | 5430 | minmax_val[minmax_num] = items[loc]; | |
276 | /* Store type code for maxima. */ | ||
277 | 5430 | minmax_type[minmax_num] = 1; | |
278 | /* Store location of maxima midpoint. */ | ||
279 | 5430 | minmax_i[minmax_num++] = loc; | |
280 | /* Change state to decreasing. */ | ||
281 | 5430 | state = -1; | |
282 | /* Reset start location. */ | ||
283 | 5430 | start = i; | |
284 | } | ||
285 | /* If previously level (this state only can occur at the */ | ||
286 | /* beginning of the list of items) ... */ | ||
287 | else { | ||
288 | /* If more than one level state in a row ... */ | ||
289 |
2/2✓ Branch 0 taken 282 times.
✓ Branch 1 taken 1380 times.
|
1662 | if(i-start > 1){ |
290 | /* Then consider a maxima ... */ | ||
291 | /* Compute midpoint of maxima. */ | ||
292 | 282 | loc = (start + i)/2; | |
293 | /* Store value at maxima midpoint. */ | ||
294 | 282 | minmax_val[minmax_num] = items[loc]; | |
295 | /* Store type code for maxima. */ | ||
296 | 282 | minmax_type[minmax_num] = 1; | |
297 | /* Store location of maxima midpoint. */ | ||
298 | 282 | minmax_i[minmax_num++] = loc; | |
299 | /* Change state to decreasing. */ | ||
300 | 282 | state = -1; | |
301 | /* Reset start location. */ | ||
302 | 282 | start = i; | |
303 | } | ||
304 | /* Otherwise, ignore single level state. */ | ||
305 | else{ | ||
306 | /* Change state to decreasing. */ | ||
307 | state = -1; | ||
308 | /* Reset start location. */ | ||
309 | start = i; | ||
310 | } | ||
311 | } | ||
312 | } | ||
313 | /* Otherwise, items are level, so continue to next item pair. */ | ||
314 | |||
315 | /* Advance to next item pair in list. */ | ||
316 | 291200 | i++; | |
317 | } | ||
318 | |||
319 | /* Set results to output pointers. */ | ||
320 | 22400 | *ominmax_val = minmax_val; | |
321 | 22400 | *ominmax_type = minmax_type; | |
322 | 22400 | *ominmax_i = minmax_i; | |
323 | 22400 | *ominmax_alloc = minmax_alloc; | |
324 | 22400 | *ominmax_num = minmax_num; | |
325 | |||
326 | /* Return normally. */ | ||
327 | 22400 | return(0); | |
328 | } | ||
329 | |||
330 | /************************************************************************* | ||
331 | ************************************************************************** | ||
332 | #cat: distance - Takes two coordinate points and computes the | ||
333 | #cat: Euclidean distance between the two points. | ||
334 | |||
335 | Input: | ||
336 | x1 - x-coord of first point | ||
337 | y1 - y-coord of first point | ||
338 | x2 - x-coord of second point | ||
339 | y2 - y-coord of second point | ||
340 | Return Code: | ||
341 | Distance - computed Euclidean distance | ||
342 | **************************************************************************/ | ||
343 | 825781 | double distance(const int x1, const int y1, const int x2, const int y2) | |
344 | { | ||
345 | 825781 | double dx, dy, dist; | |
346 | |||
347 | /* Compute delta x between points. */ | ||
348 | 825781 | dx = (double)(x1 - x2); | |
349 | /* Compute delta y between points. */ | ||
350 | 825781 | dy = (double)(y1 - y2); | |
351 | /* Compute the squared distance between points. */ | ||
352 | 825781 | dist = (dx*dx) + (dy*dy); | |
353 | /* Take square root of squared distance. */ | ||
354 | 825781 | dist = sqrt(dist); | |
355 | |||
356 | /* Return the squared distance. */ | ||
357 | 825781 | return(dist); | |
358 | } | ||
359 | |||
360 | /************************************************************************* | ||
361 | ************************************************************************** | ||
362 | #cat: squared_distance - Takes two coordinate points and computes the | ||
363 | #cat: squared distance between the two points. | ||
364 | |||
365 | Input: | ||
366 | x1 - x-coord of first point | ||
367 | y1 - y-coord of first point | ||
368 | x2 - x-coord of second point | ||
369 | y2 - y-coord of second point | ||
370 | Return Code: | ||
371 | Distance - computed squared distance | ||
372 | **************************************************************************/ | ||
373 | 59516 | double squared_distance(const int x1, const int y1, const int x2, const int y2) | |
374 | { | ||
375 | 59516 | double dx, dy, dist; | |
376 | |||
377 | /* Compute delta x between points. */ | ||
378 | 59516 | dx = (double)(x1 - x2); | |
379 | /* Compute delta y between points. */ | ||
380 | 59516 | dy = (double)(y1 - y2); | |
381 | /* Compute the squared distance between points. */ | ||
382 | 59516 | dist = (dx*dx) + (dy*dy); | |
383 | |||
384 | /* Return the squared distance. */ | ||
385 | 59516 | return(dist); | |
386 | } | ||
387 | |||
388 | /************************************************************************* | ||
389 | ************************************************************************** | ||
390 | #cat: in_int_list - Determines if a specified value is store in a list of | ||
391 | #cat: integers and returns its location if found. | ||
392 | |||
393 | Input: | ||
394 | item - value to search for in list | ||
395 | list - list of integers to be searched | ||
396 | len - number of integers in search list | ||
397 | Return Code: | ||
398 | Zero or greater - first location found equal to search value | ||
399 | Negative - search value not found in the list of integers | ||
400 | **************************************************************************/ | ||
401 | 41640 | int in_int_list(const int item, const int *list, const int len) | |
402 | { | ||
403 | 41640 | int i; | |
404 | |||
405 | /* Foreach item in list ... */ | ||
406 |
2/2✓ Branch 0 taken 72437 times.
✓ Branch 1 taken 41614 times.
|
114051 | for(i = 0; i < len; i++){ |
407 | /* If search item found in list ... */ | ||
408 |
2/2✓ Branch 0 taken 26 times.
✓ Branch 1 taken 72411 times.
|
72437 | if(list[i] == item) |
409 | /* Return the location in list where found. */ | ||
410 | 26 | return(i); | |
411 | } | ||
412 | |||
413 | /* If we get here, then search item not found in list, */ | ||
414 | /* so return -1 ==> NOT FOUND. */ | ||
415 | return(-1); | ||
416 | } | ||
417 | |||
418 | /************************************************************************* | ||
419 | ************************************************************************** | ||
420 | #cat: remove_from_int_list - Takes a position index into an integer list and | ||
421 | #cat: removes the value from the list, collapsing the resulting | ||
422 | #cat: list. | ||
423 | |||
424 | Input: | ||
425 | index - position of value to be removed from list | ||
426 | list - input list of integers | ||
427 | num - number of integers in the list | ||
428 | Output: | ||
429 | list - list with specified integer removed | ||
430 | num - decremented number of integers in list | ||
431 | Return Code: | ||
432 | Zero - successful completion | ||
433 | Negative - system error | ||
434 | **************************************************************************/ | ||
435 | |||
436 | /************************************************************************* | ||
437 | ************************************************************************** | ||
438 | #cat: ind_incr_position_dbl - Takes a double value and a list of doubles and | ||
439 | #cat: determines where in the list the double may be inserted, | ||
440 | #cat: preserving the increasing sorted order of the list. | ||
441 | |||
442 | Input: | ||
443 | val - value to be inserted into the list | ||
444 | list - list of double in increasing sorted order | ||
445 | num - number of values in the list | ||
446 | Return Code: | ||
447 | Zero or Positive - insertion position in the list | ||
448 | **************************************************************************/ | ||
449 | 33683 | int find_incr_position_dbl(const double val, double *list, const int num) | |
450 | { | ||
451 | 33683 | int i; | |
452 | |||
453 | /* Foreach item in double list ... */ | ||
454 |
2/2✓ Branch 0 taken 83733 times.
✓ Branch 1 taken 7412 times.
|
91145 | for(i = 0; i < num; i++){ |
455 | /* If the value is smaller than the current item in list ... */ | ||
456 |
2/2✓ Branch 0 taken 26271 times.
✓ Branch 1 taken 57462 times.
|
83733 | if(val < list[i]) |
457 | /* Then we found were to insert the value in the list maintaining */ | ||
458 | /* an increasing sorted order. */ | ||
459 | 26271 | return(i); | |
460 | |||
461 | /* Otherwise, the value is still larger than current item, so */ | ||
462 | /* continue to next item in the list. */ | ||
463 | } | ||
464 | |||
465 | /* Otherwise, we never found a slot within the list to insert the */ | ||
466 | /* the value, so place at the end of the sorted list. */ | ||
467 | return(i); | ||
468 | } | ||
469 | |||
470 | /************************************************************************* | ||
471 | ************************************************************************** | ||
472 | #cat: angle2line - Takes two coordinate points and computes the angle | ||
473 | #cat: to the line formed by the two points. | ||
474 | |||
475 | Input: | ||
476 | fx - x-coord of first point | ||
477 | fy - y-coord of first point | ||
478 | tx - x-coord of second point | ||
479 | ty - y-coord of second point | ||
480 | Return Code: | ||
481 | Angle - angle to the specified line | ||
482 | **************************************************************************/ | ||
483 | 123803 | double angle2line(const int fx, const int fy, const int tx, const int ty) | |
484 | { | ||
485 | 123803 | double dx, dy, theta; | |
486 | |||
487 | /* Compute slope of line connecting the 2 specified points. */ | ||
488 | 123803 | dy = (double)(fy - ty); | |
489 | 123803 | dx = (double)(tx - fx); | |
490 | /* If delta's are sufficiently small ... */ | ||
491 |
4/4✓ Branch 0 taken 10317 times.
✓ Branch 1 taken 113486 times.
✓ Branch 2 taken 10311 times.
✓ Branch 3 taken 6 times.
|
123803 | if((fabs(dx) < MIN_SLOPE_DELTA) && (fabs(dy) < MIN_SLOPE_DELTA)) |
492 | theta = 0.0; | ||
493 | /* Otherwise, compute angle to the line. */ | ||
494 | else | ||
495 | 123797 | theta = atan2(dy, dx); | |
496 | |||
497 | /* Return the compute angle in radians. */ | ||
498 | 123803 | return(theta); | |
499 | } | ||
500 | |||
501 | /************************************************************************* | ||
502 | ************************************************************************** | ||
503 | #cat: line2direction - Takes two coordinate points and computes the | ||
504 | #cat: directon (on a full circle) in which the first points | ||
505 | #cat: to the second. | ||
506 | |||
507 | Input: | ||
508 | fx - x-coord of first point (pointing from) | ||
509 | fy - y-coord of first point (pointing from) | ||
510 | tx - x-coord of second point (pointing to) | ||
511 | ty - y-coord of second point (pointing to) | ||
512 | ndirs - number of IMAP directions (in semicircle) | ||
513 | Return Code: | ||
514 | Direction - determined direction on a "full" circle | ||
515 | **************************************************************************/ | ||
516 | 3061 | int line2direction(const int fx, const int fy, | |
517 | const int tx, const int ty, const int ndirs) | ||
518 | { | ||
519 | 3061 | double theta, pi_factor; | |
520 | 3061 | int idir, full_ndirs; | |
521 | 3061 | static double pi2 = M_PI*2.0; | |
522 | |||
523 | /* Compute angle to line connecting the 2 points. */ | ||
524 | /* Coordinates are swapped and order of points reversed to */ | ||
525 | /* account for 0 direction is vertical and positive direction */ | ||
526 | /* is clockwise. */ | ||
527 | 3061 | theta = angle2line(ty, tx, fy, fx); | |
528 | |||
529 | /* Make sure the angle is positive. */ | ||
530 | 3061 | theta += pi2; | |
531 | 3061 | theta = fmod(theta, pi2); | |
532 | /* Convert from radians to integer direction on range [0..(ndirsX2)]. */ | ||
533 | /* Multiply radians by units/radian ((ndirsX2)/(2PI)), and you get */ | ||
534 | /* angle in integer units. */ | ||
535 | /* Compute number of directions on full circle. */ | ||
536 | 3061 | full_ndirs = ndirs<<1; | |
537 | /* Compute the radians to integer direction conversion factor. */ | ||
538 | 3061 | pi_factor = (double)full_ndirs/pi2; | |
539 | /* Convert radian angle to integer direction on full circle. */ | ||
540 | 3061 | theta *= pi_factor; | |
541 | /* Need to truncate precision so that answers are consistent */ | ||
542 | /* on different computer architectures when rounding doubles. */ | ||
543 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3061 times.
|
3061 | theta = trunc_dbl_precision(theta, TRUNC_SCALE); |
544 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3061 times.
|
3061 | idir = sround(theta); |
545 | /* Make sure on range [0..(ndirsX2)]. */ | ||
546 | 3061 | idir %= full_ndirs; | |
547 | |||
548 | /* Return the integer direction. */ | ||
549 | 3061 | return(idir); | |
550 | } | ||
551 | |||
552 | /************************************************************************* | ||
553 | ************************************************************************** | ||
554 | #cat: closest_dir_dist - Takes to integer IMAP directions and determines the | ||
555 | #cat: closest distance between them accounting for | ||
556 | #cat: wrap-around either at the beginning or ending of | ||
557 | #cat: the range of directions. | ||
558 | |||
559 | Input: | ||
560 | dir1 - integer value of the first direction | ||
561 | dir2 - integer value of the second direction | ||
562 | ndirs - the number of possible directions | ||
563 | Return Code: | ||
564 | Non-negative - distance between the 2 directions | ||
565 | **************************************************************************/ | ||
566 | 410025 | int closest_dir_dist(const int dir1, const int dir2, const int ndirs) | |
567 | { | ||
568 | 410025 | int d1, d2, dist; | |
569 | |||
570 | /* Initialize distance to -1 = INVALID. */ | ||
571 | 410025 | dist = INVALID_DIR; | |
572 | |||
573 | /* Measure shortest distance between to directions. */ | ||
574 | /* If both neighbors are VALID ... */ | ||
575 |
2/2✓ Branch 0 taken 390859 times.
✓ Branch 1 taken 19166 times.
|
410025 | if((dir1 >= 0)&&(dir2 >= 0)){ |
576 | /* Compute inner and outer distances to account for distances */ | ||
577 | /* that wrap around the end of the range of directions, which */ | ||
578 | /* may in fact be closer. */ | ||
579 | 390859 | d1 = abs(dir2 - dir1); | |
580 | 390859 | d2 = ndirs - d1; | |
581 | 390859 | dist = min(d1, d2); | |
582 | } | ||
583 | /* Otherwise one or both directions are INVALID, so ignore */ | ||
584 | /* and return INVALID. */ | ||
585 | |||
586 | /* Return determined closest distance. */ | ||
587 | 410025 | return(dist); | |
588 | } | ||
589 | |||
590 |