GRASS Programmer's Manual  6.5.svn(2014)-r66266
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)) / (dx * dx +
80  dy * dy +
81  dz * dz);
82
83  if (t < 0.0) { /* go to x1,y1,z1 */
84  t = 0.0;
85  st = -1;
86  }
87  else if (t > 1.0) { /* go to x2,y2,z2 */
88  t = 1.0;
89  st = 1;
90  }
91
92  /* go t from x1,y1,z1 towards x2,y2,z2 */
93  tpx = dx * t + x1;
94  tpy = dy * t + y1;
95  tpz = dz * t + z1;
96  dx = tpx - x;
97  dy = tpy - y;
98  dz = tpz - z;
99  }
100
101  if (px)
102  *px = tpx;
103  if (py)
104  *py = tpy;
105  if (pz)
106  *pz = tpz;
107  if (status)
108  *status = st;
109
110  if (pdist) {
111  dpx = tpx - x1;
112  dpy = tpy - y1;
113  dpz = tpz - z1;
114  *pdist = sqrt(dpx * dpx + dpy * dpy + dpz * dpz);
115  }
116
117  return (dx * dx + dy * dy + dz * dz);
118 }
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)
int y
Definition: plot.c:34
#define TOLERANCE
#define ZERO(x)