GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
vector/diglib/line_dist.c
Go to the documentation of this file.
1 /*
2  ****************************************************************************
3  *
4  * MODULE: Vector library
5  *
6  * AUTHOR(S): Original author CERL, probably Dave Gerdes.
7  * Update to GRASS 5.7 Radim Blazek.
8  *
9  * PURPOSE: Lower level functions for reading/writing/manipulating vectors.
10  *
11  * COPYRIGHT: (C) 2001 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 #include <math.h>
19 
20 #define ZERO(x) ((x) < tolerance && (x) > -tolerance)
21 #define TOLERANCE 1.0e-10
22 static double tolerance = TOLERANCE;
23 
25 {
26  if (t <= 0.0)
27  t = TOLERANCE;
28  tolerance = t;
29 
30  return 0;
31 }
32 
33 /*
34  * dig_distance2_point_to_line ()
35  * compute square of distance of point (x,y) to line segment (x1,y1 - x2,y2)
36  * ( works correctly for x1==x2 && y1==y2 )
37  *
38  * returns: square distance
39  * sets (if not NULL): *px, *py - nearest point on segment
40  * *pdist - distance of px,py from segment start
41  * *status = 0 if ok, -1 if t < 0 and 1 if t > 1
42  * (tells if point is w/in segment space, or past ends)
43  */
44 
45 double dig_distance2_point_to_line(double x, double y, double z, /* point */
46  double x1, double y1, double z1, /* line segment */
47  double x2, double y2, double z2, int with_z, /* use z coordinate, (3D calculation) */
48  double *px, double *py, double *pz, /* point on segment */
49  double *pdist, /* distance of point on segment from the first point of segment */
50  int *status)
51 {
52  register double dx, dy, dz;
53  register double dpx, dpy, dpz;
54  register double tpx, tpy, tpz;
55  double t;
56  int st;
57 
58  st = 0;
59 
60  if (!with_z) {
61  z = 0;
62  z1 = 0;
63  z2 = 0;
64  }
65 
66  dx = x2 - x1;
67  dy = y2 - y1;
68  dz = z2 - z1;
69 
70  if (ZERO(dx) && ZERO(dy) && ZERO(dz)) { /* line is degenerate */
71  dx = x1 - x;
72  dy = y1 - y;
73  dz = z1 - z;
74  tpx = x1;
75  tpy = y1;
76  tpz = z1;
77  }
78  else {
79  t = (dx * (x - x1) + dy * (y - y1) + dz * (z - z1)) /
80  (dx * dx + dy * dy + dz * dz);
81 
82  if (t <= 0.0) { /* go to x1,y1,z1 */
83  if (t < 0.0) {
84  st = -1;
85  }
86  tpx = x1;
87  tpy = y1;
88  tpz = z1;
89  }
90  else if (t >= 1.0) { /* go to x2,y2,z2 */
91  if (t > 1.0) {
92  st = 1;
93  }
94  tpx = x2;
95  tpy = y2;
96  tpz = z2;
97  }
98  else {
99  /* go t from x1,y1,z1 towards x2,y2,z2 */
100  tpx = dx * t + x1;
101  tpy = dy * t + y1;
102  tpz = dz * t + z1;
103  }
104  dx = tpx - x;
105  dy = tpy - y;
106  dz = tpz - z;
107  }
108 
109  if (px)
110  *px = tpx;
111  if (py)
112  *py = tpy;
113  if (pz)
114  *pz = tpz;
115  if (status)
116  *status = st;
117 
118  if (pdist) {
119  dpx = tpx - x1;
120  dpy = tpy - y1;
121  dpz = tpz - z1;
122  *pdist = sqrt(dpx * dpx + dpy * dpy + dpz * dpz);
123  }
124 
125  return (dx * dx + dy * dy + dz * dz);
126 }
int dig_set_distance_to_line_tolerance(double t)
double dig_distance2_point_to_line(double x, double y, double z, double x1, double y1, double z1, double x2, double y2, double z2, int with_z, double *px, double *py, double *pz, double *pdist, int *status)
#define x
struct state * st
Definition: parser.c:104
double t
Definition: r_raster.c:39
#define TOLERANCE
#define ZERO(x)