lobf.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /****************************************************************************
  2. *
  3. * MODULE: r.carve
  4. *
  5. * AUTHOR(S): Original author Bill Brown, UIUC GIS Laboratory
  6. * Brad Douglas <rez touchofmadness com>
  7. *
  8. * PURPOSE: Takes vector stream data, converts it to 3D raster and
  9. * subtracts a specified depth
  10. *
  11. * COPYRIGHT: (C) 2006 by the GRASS Development Team
  12. *
  13. * This program is free software under the GNU General Public
  14. * License (>=v2). Read the file COPYING that comes with GRASS
  15. * for details.
  16. *
  17. ****************************************************************************/
  18. /*
  19. * Routines to create a line of best fit when given a set of coord pairs.
  20. */
  21. #include "enforce.h"
  22. #include <grass/glocale.h>
  23. /*
  24. * pg_init - initialize PointGrp variables
  25. */
  26. void pg_init(PointGrp * pg)
  27. {
  28. pg->sum_x = pg->sum_y = pg->sum_xy = pg->sum_x_sq = 0.0;
  29. pg->npts = 0;
  30. }
  31. /*
  32. * pg_y_from_x - determine y value for a given x value in a PointGrp
  33. */
  34. double pg_y_from_x(PointGrp * pg, const double x)
  35. {
  36. return ((pg->slope * x) + pg->yinter);
  37. }
  38. /*
  39. * pg_addpt - Add a point to a PointGrp
  40. */
  41. void pg_addpt(PointGrp * pg, Point2 pt)
  42. {
  43. if (pg->npts < MAX_PTS - 1) {
  44. double x = pt[0];
  45. double y = pt[1];
  46. /* add point to group */
  47. pg->pnts[pg->npts][0] = x;
  48. pg->pnts[pg->npts][1] = y;
  49. pg->sum_x += x;
  50. pg->sum_y += y;
  51. pg->sum_xy += (x * y);
  52. pg->sum_x_sq += SQR(x);
  53. ++pg->npts;
  54. }
  55. if (pg->npts > 1) {
  56. double denom;
  57. /* solve for x and y using Cramer's Rule */
  58. /* check for divide by zero */
  59. if (0 ==
  60. (denom = DET2_2(pg->sum_x_sq, pg->sum_x, pg->sum_x, pg->npts))) {
  61. G_warning(_("trying to divide by zero...no unique solution for "
  62. "system...skipping..."));
  63. pg->slope = pg->yinter = 0.0;
  64. }
  65. else {
  66. pg->slope = DET2_2(pg->sum_xy, pg->sum_x, pg->sum_y, pg->npts) /
  67. denom;
  68. pg->yinter =
  69. DET2_2(pg->sum_x_sq, pg->sum_xy, pg->sum_x,
  70. pg->sum_y) / denom;
  71. }
  72. }
  73. }
  74. /*
  75. * pg_getpoints - returns the Point2 structure from a PointGrp
  76. */
  77. Point2 *pg_getpoints(PointGrp * pg)
  78. {
  79. return pg->pnts;
  80. }
  81. /*
  82. * pg_getpoints_reversed - reverse points in PointGrp and returns Point2
  83. */
  84. Point2 *pg_getpoints_reversed(PointGrp * pg)
  85. {
  86. int i;
  87. int iter = pg->npts / 2;
  88. double x, y;
  89. for (i = 0; i < iter; i++) {
  90. /* swap points */
  91. x = pg->pnts[i][0];
  92. y = pg->pnts[i][1];
  93. pg->pnts[i][0] = pg->pnts[pg->npts - i - 1][0];
  94. pg->pnts[i][1] = pg->pnts[pg->npts - i - 1][1];
  95. pg->pnts[pg->npts - i - 1][0] = x;
  96. pg->pnts[pg->npts - i - 1][1] = y;
  97. }
  98. return pg->pnts;
  99. }