| 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 (4→3) taken 77320 times.
✓ Branch 1 (4→5) 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 (4→3) taken 77320 times.
✓ Branch 1 (4→5) 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 (2→3) not taken.
✓ Branch 1 (2→4) 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 (7→8) taken 15466 times.
✓ Branch 1 (7→10) taken 6934 times.
|
22400 | if(diff > 0) |
| 194 | state = 1; | ||
| 195 |
2/2✓ Branch 0 (8→9) taken 2275 times.
✓ Branch 1 (8→10) 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 (24→11) taken 291200 times.
✓ Branch 1 (24→25) 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 (11→12) taken 136243 times.
✓ Branch 1 (11→17) taken 154957 times.
|
291200 | if(diff > 0){ |
| 213 | /* If previously increasing ... */ | ||
| 214 |
2/2✓ Branch 0 (12→13) taken 13998 times.
✓ Branch 1 (12→23) 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 (13→14) taken 13385 times.
✓ Branch 1 (13→15) 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 (15→16) taken 96 times.
✓ Branch 1 (15→23) 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 (17→18) taken 115673 times.
✓ Branch 1 (17→23) taken 39284 times.
|
154957 | else if(diff < 0){ |
| 264 | /* If previously decreasing ... */ | ||
| 265 |
2/2✓ Branch 0 (18→19) taken 7092 times.
✓ Branch 1 (18→23) 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 (19→20) taken 5430 times.
✓ Branch 1 (19→21) 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 (21→22) taken 282 times.
✓ Branch 1 (21→23) 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 (5→3) taken 72437 times.
✓ Branch 1 (5→6) taken 41614 times.
|
114051 | for(i = 0; i < len; i++){ |
| 407 | /* If search item found in list ... */ | ||
| 408 |
2/2✓ Branch 0 (3→4) taken 72411 times.
✓ Branch 1 (3→6) taken 26 times.
|
72437 | if(list[i] == item) |
| 409 | /* Return the location in list where found. */ | ||
| 410 | 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 (5→3) taken 83733 times.
✓ Branch 1 (5→6) 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 (3→4) taken 57462 times.
✓ Branch 1 (3→6) taken 26271 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 | 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 (2→3) taken 10317 times.
✓ Branch 1 (2→4) taken 113486 times.
✓ Branch 2 (3→4) taken 10311 times.
✓ Branch 3 (3→5) 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 (3→4) not taken.
✓ Branch 1 (3→5) taken 3061 times.
|
3061 | theta = trunc_dbl_precision(theta, TRUNC_SCALE); |
| 544 |
1/2✗ Branch 0 (6→7) not taken.
✓ Branch 1 (6→8) 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 (2→3) taken 390859 times.
✓ Branch 1 (2→4) 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 |