1 #include <stdio.h>
2 #include <math.h>
3 #include <grass/vector.h>
4 #include "sw_defs.h"
5 #include "defs.h"
6
7 /*-extend_line() finds coordinates along the boundary of a window
8 * that also lie on a specified line (ax+by=c). The
9 * line can cross at least two boundaries---the line
10 * that intersects the midpoint of s1 and s2 determines
11 * which coordinates are placed in (c_x, c_y).
12 *
13 * The limits of the window are described by:
14 * e: east
15 * w: west
16 * s: south
17 * n: north
18 * Note that the following constraints must be true:
19 * ( w < e ) ( s < n )
20 *
21 * x and y are points on the line ax + by = c that are assumed
22 * to lie within the window.
23 *
24 * the c_x and c_y values are changed.
25 *
26 * returns: 0 on error, 1 otherwise
27 */
28
extend_line(double s,double n,double w,double e,double a,double b,double c,double x,double y,double * c_x,double * c_y,int knownPointAtLeft)29 int extend_line(double s, double n, double w, double e,
30 double a, double b, double c, double x, double y,
31 double *c_x, double *c_y, int knownPointAtLeft)
32 {
33 double nx, ny; /* intersection coordinates */
34
35 if (x >= w && x <= e && y >= s && y <= n) {
36 /* horizontal line? */
37 if (a == 0) {
38 *c_x = knownPointAtLeft ? e : w;
39 *c_y = y;
40 return 1;
41 }
42
43 /* vertical line? */
44 if (b == 0) {
45 *c_x = x;
46 *c_y = knownPointAtLeft ? s : n;
47 return 1;
48 }
49
50 /* south */
51 nx = (c - b * (s - ycenter)) / a + xcenter;
52 if (Vect_point_in_box(nx, s, 0.0, &Box) &&
53 ((nx > x && knownPointAtLeft) || (nx <= x && !knownPointAtLeft)))
54 {
55 *c_x = nx;
56 *c_y = s;
57 return 1;
58 }
59
60 /* north */
61 nx = (c - b * (n - ycenter)) / a + xcenter;
62 if (Vect_point_in_box(nx, n, 0.0, &Box) &&
63 ((nx > x && knownPointAtLeft) || (nx <= x && !knownPointAtLeft)))
64 {
65 *c_x = nx;
66 *c_y = n;
67 return 1;
68 }
69
70 if (knownPointAtLeft) {
71 /* east */
72 ny = (c - a * (e - xcenter)) / b + ycenter;
73 if (Vect_point_in_box(e, ny, 0.0, &Box)) {
74 *c_x = e;
75 *c_y = ny;
76 return 1;
77 }
78 }
79 else {
80 /* west */
81 ny = (c - a * (w - xcenter)) / b + ycenter;
82 if (Vect_point_in_box(w, ny, 0.0, &Box)) {
83 *c_x = w;
84 *c_y = ny;
85 return 1;
86 }
87 }
88 }
89 return 0;
90 }
91