home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / sel2path / math.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-07-30  |  4.4 KB  |  181 lines

  1. /* math.c: define some simple array operations, and other functions.
  2.  
  3. Copyright (C) 1992 Free Software Foundation, Inc.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include <float.h>
  22. #include <math.h>
  23. #include <errno.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <assert.h>
  27.  
  28. #include "libgimp/gimp.h"
  29.  
  30. #include "types.h"
  31. #include "global.h"
  32.  
  33. /* Numerical errors sometimes make a floating point number just slightly
  34.    larger or smaller than its true value.  When it matters, we need to
  35.    compare with some tolerance, REAL_EPSILON, defined in kbase.h.  */
  36.  
  37. boolean
  38. epsilon_equal (real v1, real v2)
  39. {
  40.   return
  41.     v1 == v2               /* Usually they'll be exactly equal, anyway.  */
  42.     || fabs (v1 - v2) <= REAL_EPSILON;
  43. }
  44.  
  45.  
  46. /* Return the Euclidean distance between P1 and P2.  */
  47.  
  48. real
  49. distance (real_coordinate_type p1, real_coordinate_type p2)
  50. {
  51.   return hypot (p1.x - p2.x, p1.y - p2.y);
  52. }
  53.  
  54.  
  55. /* Same thing, for integer points.  */
  56. real
  57. int_distance (coordinate_type p1, coordinate_type p2)
  58. {
  59.   return hypot ((double) p1.x - p2.x, (double) p1.y - p2.y);
  60. }
  61.  
  62.  
  63. /* Return the arc cosine of V, in degrees in the range zero to 180.  V
  64.    is taken to be in radians.  */
  65.  
  66. real
  67. my_acosd (real v)
  68. {
  69.   real a;
  70.  
  71.   if (epsilon_equal (v, 1.0))
  72.     v = 1.0;
  73.   else if (epsilon_equal (v, -1.0))
  74.     v = -1.0;
  75.  
  76.   errno = 0;
  77.   a = acos (v);
  78.   if (errno == ERANGE || errno == EDOM)
  79.     FATAL_PERROR ("acosd");
  80.  
  81.   return a * 180.0 / G_PI;
  82. }
  83.  
  84.  
  85. /* The slope of the line defined by COORD1 and COORD2.  */
  86.  
  87. real
  88. slope (real_coordinate_type coord1, real_coordinate_type coord2)
  89. {
  90.   assert (coord2.x - coord1.x != 0);
  91.  
  92.   return (coord2.y - coord1.y) / (coord2.x - coord1.x);
  93. }
  94.  
  95.  
  96. /* Turn an integer point into a real one, and vice versa.  */
  97.  
  98. real_coordinate_type
  99. int_to_real_coord (coordinate_type int_coord)
  100. {
  101.   real_coordinate_type real_coord;
  102.  
  103.   real_coord.x = int_coord.x;
  104.   real_coord.y = int_coord.y;
  105.  
  106.   return real_coord;
  107. }
  108.  
  109.  
  110. coordinate_type
  111. real_to_int_coord (real_coordinate_type real_coord)
  112. {
  113.   coordinate_type int_coord;
  114.  
  115.   int_coord.x = SROUND (real_coord.x);
  116.   int_coord.y = SROUND (real_coord.y);
  117.  
  118.   return int_coord;
  119. }
  120.  
  121.  
  122. /* See if two points (described by their row and column) are adjacent.  */
  123.  
  124. boolean
  125. points_adjacent_p (int row1, int col1, int row2, int col2)
  126. {
  127.   int row_diff = abs (row1 - row2);
  128.   int col_diff = abs (col1 - col2);
  129.  
  130.   return
  131.     (row_diff == 1 && col_diff == 1)
  132.     || (row_diff == 0 && col_diff == 1)
  133.     || (row_diff == 1 && col_diff == 0);
  134. }
  135.  
  136.  
  137. /* Find the largest and smallest elements in an array of reals.  */
  138.  
  139. void
  140. find_bounds (real *values, unsigned value_count, real *min, real *max)
  141. {
  142.   unsigned this_value;
  143.  
  144.   /* We must use FLT_MAX and FLT_MIN, instead of the corresponding
  145.      values for double, because gcc uses the native atof to parse
  146.      floating point constants, and many atof's choke on the extremes.  */
  147.   *min = FLT_MAX;
  148.   *max = FLT_MIN;
  149.  
  150.   for (this_value = 0; this_value < value_count; this_value++)
  151.     {
  152.       if (values[this_value] < *min)
  153.     *min = values[this_value];
  154.  
  155.       if (values[this_value] > *max)
  156.     *max = values[this_value];
  157.     }
  158. }
  159.  
  160. /* Map a range of numbers, some positive and some negative, into all
  161.    positive, with the greatest being at one and the least at zero.
  162.  
  163.    This allocates new memory.  */
  164.  
  165. real *
  166. map_to_unit (real *values, unsigned value_count)
  167. {
  168.   real smallest, largest;
  169.   int this_value;
  170.   real *mapped_values = g_new (real, value_count);
  171.  
  172.   find_bounds (values, value_count, &smallest, &largest);
  173.  
  174.   largest -= smallest;        /* We never care about largest itself. */
  175.  
  176.   for (this_value = 0; this_value < value_count; this_value++)
  177.     mapped_values[this_value] = (values[this_value] - smallest) / largest;
  178.  
  179.   return mapped_values;
  180. }
  181.