libsurf
Programmer's Documentation

sides.h (r6227/r5337)
1 
2 /* Copyright (C) 2015 David Eller <david@larosterna.com>
3  *
4  * Commercial License Usage
5  * Licensees holding valid commercial licenses may use this file in accordance
6  * with the terms contained in their respective non-exclusive license agreement.
7  * For further information contact david@larosterna.com .
8  *
9  * GNU General Public License Usage
10  * Alternatively, this file may be used under the terms of the GNU General
11  * Public License version 3.0 as published by the Free Software Foundation and
12  * appearing in the file gpl.txt included in the packaging of this file.
13  */
14 
15 #ifndef SURF_SIDES_H
16 #define SURF_SIDES_H
17 
18 #include <genua/forward.h>
19 #include <genua/strutils.h>
20 
21 typedef enum {west=0, north=1, east=2, south=3, none} side_t;
22 
23 // problem : will only return one side for corner points
24 inline side_t whichside(Real u, Real v, Real tol = gmepsilon)
25 {
26  if (u <= tol)
27  return west;
28  else if (u >= 1.0-tol)
29  return east;
30  else if (v <= tol)
31  return south;
32  else if (v >= 1.0-tol)
33  return north;
34  else
35  return none;
36 }
37 
38 inline side_t whichside(const Vct2 & p, Real tol = gmepsilon)
39 {
40  return whichside(p[0], p[1], tol);
41 }
42 
43 inline bool onside(Real u, Real v, side_t s, Real tol = gmepsilon)
44 {
45  if (s == west and u <= tol)
46  return true;
47  else if (s == east and u >= 1.-tol)
48  return true;
49  else if (s == south and v <= tol)
50  return true;
51  else if (s == north and v >= 1.-tol)
52  return true;
53  else if (s == none and u > tol and u < 1.-tol and v > tol and v < 1.-tol)
54  return true;
55  else
56  return false;
57 }
58 
59 inline bool onside(const Vct2 & p, side_t s, Real tol = gmepsilon)
60 {
61  return onside(p[0], p[1], s, tol);
62 }
63 
64 inline void force2side(side_t s, Vct2 & p)
65 {
66  switch (s) {
67  case west:
68  p[0] = 0.0;
69  break;
70  case north:
71  p[1] = 1.0;
72  break;
73  case east:
74  p[0] = 1.0;
75  break;
76  case south:
77  p[1] = 0.0;
78  break;
79  case none:
80  default:
81  return;
82  }
83 }
84 
85 inline side_t forceNearBnd(Real maxdist, Vct2 & p)
86 {
87  // compute distances from boundaries
88  Real dst[4];
89  dst[0] = std::max(0.0, p[0]); // west
90  dst[1] = std::max(0.0, 1.0-p[1]); // north
91  dst[2] = std::max(0.0, 1.0-p[0]); // east
92  dst[3] = std::max(0.0, p[1]); // south
93  int imin = std::distance(dst, std::min_element(dst, dst+4));
94  if (dst[imin] > maxdist)
95  return none;
96  else {
97  side_t s = side_t(imin);
98  force2side(s, p);
99  return s;
100  }
101 }
102 
103 inline side_t oppside(side_t s)
104 {
105  switch (s) {
106  case west:
107  return east;
108  case north:
109  return south;
110  case east:
111  return west;
112  case south:
113  return north;
114  case none:
115  return none;
116  }
117  return none;
118 }
119 
120 inline void fromString(const std::string & str, side_t & s)
121 {
122  std::string lstr = toLower(str);
123  if (lstr == "west")
124  s = west;
125  else if (lstr == "east")
126  s = east;
127  else if (lstr == "south")
128  s = south;
129  else if (lstr == "north")
130  s = north;
131  else
132  s = none;
133 }
134 
135 inline std::string str(side_t sd)
136 {
137  switch (sd) {
138  case west:
139  return "west";
140  case south:
141  return "south";
142  case east:
143  return "east";
144  case north:
145  return "north";
146  default:
147  return "none";
148  }
149 }
150 
151 template <int c>
153 {
154 public:
155  BndCompare(const PointList<2> & pts) : ppt(pts) {}
156  bool operator() (uint a, uint b) const {
157  return ppt[a][c] < ppt[b][c];
158  }
159 private:
160  const PointList<2> & ppt;
161 };
162 
166 {
167 public:
168  CcwCompare(const PointList<2> & pts) : ppt(pts) {}
169  bool operator() (uint a, uint b) const {
170  const Vct2 & pa( ppt[a] );
171  const Vct2 & pb( ppt[b] );
172  side_t sa = whichside( pa );
173  side_t sb = whichside( pb );
174  if ( sa != sb ) {
175  return sa > sb;
176  }
177  const int c[4] = {1, 0, 1, 0};
178  const Real sgn[4] = {-1.0, -1.0, 1.0, 1.0};
179  assert(int(sa) < 4 and int(sb) < 4);
180  return sgn[sa]*pa[c[sa]] < sgn[sa]*pb[c[sa]];
181  }
182 private:
183  const PointList<2> & ppt;
184 };
185 
187 {
188 public:
189 
191  enum {None=0, OnLoU = 1, OnHiU = 2, OnLoV = 4, OnHiV = 8};
192 
194  static int eval(const Vct2 & p, Real tol = gmepsilon) {
195  int pBoundary = BoundaryFlag::None;
196  if ( p[0] <= tol )
197  pBoundary |= OnLoU;
198  else if (p[0] >= 1.0-tol)
199  pBoundary |= OnHiU;
200  if ( p[1] <= tol )
201  pBoundary |= OnLoV;
202  else if (p[1] >= 1.0-tol)
203  pBoundary |= OnHiV;
204  return pBoundary;
205  }
206 
208  static bool share(int a, int b) {
209  if (a == 0 and b != 0)
210  return false;
211  if ( (a & OnLoU) and (b & OnLoU) )
212  return true;
213  else if ( (a & OnHiU) and (b & OnHiU) )
214  return true;
215  if ( (a & OnLoV) and (b & OnLoV) )
216  return true;
217  else if ( (a & OnHiV) and (b & OnHiV) )
218  return true;
219  return false;
220  }
221 
223  static bool onU(int a) {
224  return (a & OnLoU) or (a & OnHiU);
225  }
226 
228  static bool onV(int a) {
229  return (a & OnLoV) or (a & OnHiV);
230  }
231 };
232 
233 #endif
static bool onV(int a)
determine whether a is on a v boundary
Definition: sides.h:228
Definition: sides.h:152
Definition: sides.h:186
static bool onU(int a)
determine whether a is on a u boundary
Definition: sides.h:223
static bool share(int a, int b)
determine whether two points are on the same boundary
Definition: sides.h:208
static int eval(const Vct2 &p, Real tol=gmepsilon)
compute bitmask
Definition: sides.h:194
Sort nodes along all boundaries, ccw order.
Definition: sides.h:165
Generated on Wed Jan 19 2022 03:03:15 for libsurf by   doxygen 1.8.5