UNIVERS  15.3
UNIVERS base processing software API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
zqb_cliplinebyrect.hpp
1 /* zqb_cliplinebyrect.hpp */
2 /* $Id: zqb_cliplinebyrect.hpp 20080 2009-12-15 15:57:52Z vlad $ */
3 #ifndef __zqb_cliplinebyrect_hpp
4 #define __zqb_cliplinebyrect_hpp
5 
6 #include "zqb_macros.h"
7 
8 
18 template<class T> bool
19 ZqbClipLineByRect (T x[2],
20  T y[2],
21  T rx[2],
22  T ry[2]
23  )
24 {
25  /* Resulting coordinates of line segment */
26  T xf[2], yf[2];
27 
28  /* Sorting order of rectangle corner coordinates */
29  ZqbASCENT(rx[0], rx[1]);
30  ZqbASCENT(ry[0], ry[1]);
31 
32  /* Simply outside the rectangle */
33  if((x[0] < rx[0] && x[1] < rx[0]) || (x[0] > rx[1] && x[1] > rx[1]) ||
34  (y[0] < ry[0] && y[1] < ry[0]) || (y[0] > ry[1] && y[1] > ry[1]))
35  return false;
36 
37  /* Simply inside the rectangle */
38  if(rx[0] <= x[0] && x[0] <= rx[1] && rx[0] <= x[1] && x[1] <= rx[1] &&
39  ry[0] <= y[0] && y[0] <= ry[1] && ry[0] <= y[1] && y[1] <= ry[1])
40  return true;
41 
42  /* Horizontal or vertical line segment? */
43  if(x[0] != x[1] && y[0] == y[1])
44  {
45  /* Horizontal line */
46  if(x[0] > x[1])
47  {
48  xf[0] = ZqbMIN(rx[1], x[0]);
49  xf[1] = ZqbMAX(rx[0], x[1]);
50  }
51  else
52  {
53  xf[1] = ZqbMIN(rx[1], x[1]);
54  xf[0] = ZqbMAX(rx[0], x[0]);
55  }
56  yf[0] = yf[1] = y[0];
57  }
58  else if(x[0] == x[1] && y[0] != y[1])
59  {
60  /* Vertical line */
61  if(y[0] > y[1])
62  {
63  yf[0] = ZqbMIN(ry[1], y[0]);
64  yf[1] = ZqbMAX(ry[0], y[1]);
65  }
66  else
67  {
68  yf[1] = ZqbMIN(ry[1], y[1]);
69  yf[0] = ZqbMAX(ry[0], y[0]);
70  }
71  xf[0] = xf[1] = x[0];
72  }
73  else
74  {
75  /* Slanting line */
76 
77  /* Segment --> line */
78  double k = (y[1] - y[0])/(x[1] - x[0]);
79  double b = y[0] - k * x[0];
80 
81  /* min and max x-coord between line intersection with ry[0] and
82  ry[1] */
83  double minx = ZqbMIN((ry[0] - b)/k, (ry[1] - b)/k);
84  double maxx = ZqbMAX((ry[0] - b)/k, (ry[1] - b)/k);
85 
86  if(rx[1] < minx || rx[0] > maxx)
87  /* line don't intersect rectangle area */
88  return false;
89 
90  /* min and max x-coord taking into account rectangle bounds */
91  minx = ZqbMAX(rx[0], minx);
92  maxx = ZqbMIN(rx[1], maxx);
93 
94  if((x[0] < minx && x[1] < minx) ||
95  (x[0] > maxx && x[1] > maxx))
96  /* segment don't intersect rectangle area */
97  return false;
98 
99  if(x[0] > x[1])
100  {
101  xf[0] = ZqbMIN(x[0], maxx);
102  xf[1] = ZqbMAX(x[1], minx);
103  }
104  else
105  {
106  xf[1] = ZqbMIN(x[1], maxx);
107  xf[0] = ZqbMAX(x[0], minx);
108  }
109  yf[0] = k * xf[0] + b;
110  yf[1] = k * xf[1] + b;
111  }
112 
113  /* Results writing */
114  x[0] = xf[0]; y[0] = yf[0];
115  x[1] = xf[1]; y[1] = yf[1];
116 
117  return true;
118 
119 }
120 
121 
122 #endif /* zqb_cliplinebyrect.hpp */