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