xmsgrid  1.0
TrTriangulatorPoints.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
6 //------------------------------------------------------------------------------
7 
8 //----- Included files ---------------------------------------------------------
9 
10 // 1. Precompiled header
11 
12 // 2. My own header
14 
15 // 3. Standard library headers
16 
17 // 4. External library headers
18 
19 // 5. Shared code headers
20 #include <xmscore/stl/vector.h>
21 #include <xmscore/misc/XmError.h>
22 #include <xmsgrid/geometry/geoms.h>
23 #include <xmscore/misc/Observer.h>
25 
26 // 6. Non-shared code headers
27 
28 //----- Forward declarations ---------------------------------------------------
29 
30 //----- External globals -------------------------------------------------------
31 
32 //----- Namespace declaration --------------------------------------------------
33 
34 namespace xms
35 {
36 //----- Constants / Enumerations -----------------------------------------------
37 
38 //----- Classes / Structs ------------------------------------------------------
39 
40 //----- Internal functions -----------------------------------------------------
41 
42 //----- Class / Function definitions -------------------------------------------
43 
48 //------------------------------------------------------------------------------
86 //------------------------------------------------------------------------------
88  VecInt& a_tris,
89  VecInt2d* a_trisAdjToPts)
90 : m_pts(a_pts)
91 , m_idx(0)
92 , m_tris(a_tris)
93 , m_trisAdjToPts(a_trisAdjToPts)
94 , m_areaTol(-1)
95 , m_observer()
96 {
98 }
99 //------------------------------------------------------------------------------
101 //------------------------------------------------------------------------------
102 TrTriangulatorPoints::~TrTriangulatorPoints()
103 {
104 }
105 //------------------------------------------------------------------------------
108 //------------------------------------------------------------------------------
109 void TrTriangulatorPoints::SetObserver(BSHP<Observer> a_)
110 {
111  m_observer = a_;
112 } // TrTriangulatorPoints::SetObserver
113 //------------------------------------------------------------------------------
116 //------------------------------------------------------------------------------
118 {
119  return m_idx;
120 }
121 //------------------------------------------------------------------------------
124 //------------------------------------------------------------------------------
126 {
127  return m_pts[m_idx];
128 }
129 //------------------------------------------------------------------------------
132 //------------------------------------------------------------------------------
134 {
135  return (int)m_pts.size();
136 }
137 //------------------------------------------------------------------------------
139 //------------------------------------------------------------------------------
141 {
142  ++m_idx;
143 }
144 //------------------------------------------------------------------------------
146 //------------------------------------------------------------------------------
148 {
149  if (m_trisAdjToPts)
150  {
151  m_trisAdjToPts->resize(m_pts.size(), VecInt());
152  }
153 } // TrTriangulatorPoints::PrepareToReceiveTriangles
154 //------------------------------------------------------------------------------
156 //------------------------------------------------------------------------------
158 {
160  if (m_trisAdjToPts)
161  {
163  }
164 } // TrTriangulatorPoints::FinalizeTriangulation
165 //------------------------------------------------------------------------------
170 //------------------------------------------------------------------------------
171 void TrTriangulatorPoints::ReceiveTriangle(int a_id1, int a_id2, int a_id3)
172 {
173  // make sure the triangle has positive area
174  double area = trArea(m_pts[a_id1 - 1], m_pts[a_id2 - 1], m_pts[a_id3 - 1]);
175  if (area < m_areaTol)
176  {
177  if (gmColinearWithTol(m_pts[a_id1 - 1], m_pts[a_id2 - 1], m_pts[a_id3 - 1],
178  m_areaTol))
179  {
180  return;
181  }
182  }
183 
184  m_tris.push_back(a_id1 - 1);
185  m_tris.push_back(a_id2 - 1);
186  m_tris.push_back(a_id3 - 1);
187 
188  if (m_trisAdjToPts)
189  {
190  int triIdx = ((int)m_tris.size() / 3) - 1;
191  (*m_trisAdjToPts)[a_id1 - 1].push_back(triIdx);
192  (*m_trisAdjToPts)[a_id2 - 1].push_back(triIdx);
193  (*m_trisAdjToPts)[a_id3 - 1].push_back(triIdx);
194  }
195 } // TrTriangulatorPoints::ReceiveTriangle
196 //------------------------------------------------------------------------------
198 //------------------------------------------------------------------------------
200 {
201  if (m_pts.empty())
202  return;
203 
204  Pt3d ptMin(m_pts[0]), ptMax(m_pts[0]);
205  for (const auto& p : m_pts)
206  gmAddToExtents(p, ptMin, ptMax);
207  m_areaTol = gmComputeXyTol(ptMin, ptMax);
208  // areaTol is used to check if we should see if the points are colinear. So we
209  // will set it to be equal to an XY tol
210 
211  // we don't do this anymore
212 
213  //m_areaTol *= m_areaTol;
214  // this was originally m_areaTol *= 100. That seemed to work most of the time
215  // but test_bug12336 is a case where it did not work so we changed the
216  // tolerance to be multiplied by 1000
217  //m_areaTol *= 1000;
218 } // TrTriangulatorPoints::UpdateAreaTolerance
219 
220 } // namespace xms
221 
222 #if CXX_TEST
223 // UNIT TESTS
226 
228 
231 
232 //----- Namespace declaration --------------------------------------------------
233 
234 // namespace xms {
235 using namespace xms;
236 
241 //------------------------------------------------------------------------------
243 //------------------------------------------------------------------------------
245 {
246  // 10- 3-----------4
247  // | / \ / \
248  // | / \ 2 / \
249  // | / \ / \
250  // | / 0 \ / 1 \
251  // | / \ / \
252  // 0- 0-----------1-----------2
253  //
254  // |-----|-----|-----|-----|
255  // 0 5 10 15 20
256  //
257  // m_tris = 3,0,1, 1,2,4, 1,4,3
258  // m_trisAdjToPts = [0][0,1,2][1][0,2][1,2]
259 
260  VecPt3d pts = {{0, 0, 0}, {10, 0, 0}, {20, 0, 0}, {5, 10, 0}, {15, 10, 0}};
261  VecInt tris;
262  VecInt2d trisAdjToPts;
263  TrTriangulatorPoints client(pts, tris, &trisAdjToPts);
264  trTriangulateIt(client);
265 
266  TS_ASSERT_EQUALS(tris.size(), 9);
267  TS_ASSERT_EQUALS(tris[0], 3);
268  TS_ASSERT_EQUALS(tris[1], 0);
269  TS_ASSERT_EQUALS(tris[2], 1);
270  TS_ASSERT_EQUALS(tris[3], 1);
271  TS_ASSERT_EQUALS(tris[4], 2);
272  TS_ASSERT_EQUALS(tris[5], 4);
273  TS_ASSERT_EQUALS(tris[6], 1);
274  TS_ASSERT_EQUALS(tris[7], 4);
275  TS_ASSERT_EQUALS(tris[8], 3);
276 
277  TS_ASSERT_EQUALS(trisAdjToPts.size(), pts.size());
278  TS_ASSERT_EQUALS((VecInt{0}), trisAdjToPts[0]);
279  TS_ASSERT_EQUALS((VecInt{0, 1, 2}), trisAdjToPts[1]);
280  TS_ASSERT_EQUALS((VecInt{1}), trisAdjToPts[2]);
281  TS_ASSERT_EQUALS((VecInt{0, 2}), trisAdjToPts[3]);
282  TS_ASSERT_EQUALS((VecInt{1, 2}), trisAdjToPts[4]);
283 
284 } // TrTriangulatorPointsUnitTests::test1
285 //------------------------------------------------------------------------------
287 //------------------------------------------------------------------------------
289 {
290  VecPt3d pts = {
291  { 1149577.3999999999, 269746.50000000000, 262.60000000000002 },
292  { 1149627.6000000001, 269588.40000000002, 262.60000000000002 },
293  { 1149970.7503655001, 269500.66684485000, 262.60000000000002 },
294  { 1149582.1655385382, 269748.01315644925, 262.60000000000002 },
295  { 1149607.1846158644, 269755.95722780772, 241.59999999999974 },
296  { 1149631.0330864443, 269592.03509524878, 262.60000000000002 },
297  { 1149649.0567902755, 269611.11934530485, 241.59999999999974 },
298  { 1149971.9888759241, 269505.51102609449, 262.60000000000002 },
299  { 1149978.4910556506, 269530.94297762803, 241.59999999999974 },
300  { 1149572.6344614616, 269744.98684355075, 262.60000000000002 },
301  { 1149547.6153841354, 269737.04277219228, 241.59999999999974 },
302  { 1149624.1669135559, 269584.76490475127, 262.60000000000002 },
303  { 1149606.1432097247, 269565.68065469520, 241.59999999999974 },
304  { 1149969.5118550761, 269495.82266360550, 262.60000000000002 },
305  { 1149963.0096753496, 269470.39071207197, 241.59999999999974 }
306  };
307 
308  VecInt tris;
309  VecInt2d trisAdjToPts;
310  TrTriangulatorPoints client(pts, tris, &trisAdjToPts);
311  trTriangulateIt(client);
312 
313  VecInt baseTris = { 10, 12, 11, 11, 12, 14, 9, 10, 6, 0, 9, 6, 6, 3, 0, 6, 4,
314  3, 10, 11, 1, 6, 14, 13, 6, 13, 2, 6, 2, 7, 5, 6, 10, 1,
315  14, 5, 6, 8, 4, 6, 5, 14, 8, 6, 7, 5, 10, 1, 14, 1, 11 };
316  TS_ASSERT_EQUALS_VEC(baseTris, tris);
317 } // TrTriangulatorPointsUnitTests::test_bug12336
318 
319  //} // namespace xms
320 
321 #endif // CXX_TEST
std::vector< int > VecInt
Code that creates a Delauney triangulation from points.
void test_bug12336()
tests triangulating points
virtual int GetID() const override
Return the current point index (0-based).
double m_areaTol
tolerance for area to be greater than 0.0
Functions dealing with triangles.
virtual void ReceiveTriangle(int a_id1, int a_id2, int a_id3) override
Receive a triangle consisting of the 3 points.
bool trTriangulateIt(TrTriangulator &a_Client)
Do delaunay divide-and-conquer triangulation.
virtual void PrepareToReceiveTriangles() override
Called just before triangles are created.
VecInt2d * m_trisAdjToPts
Triangles adjacent to points.
TrTriangulatorPoints(const VecPt3d &a_pts, VecInt &a_tris, VecInt2d *a_trisAdjToPts=nullptr)
Triangulate Pt3ds returning triangles in a single 1D vector.
int m_idx
Current point index.
bool gmColinearWithTol(const Pt3d &p1, const Pt3d &p2, const Pt3d &p3, const double tol)
Returns true if (the three vertices are gmColinear. Result should be insensitive to the order of the ...
Definition: geoms.cpp:393
virtual Pt3d GetLocation() const override
Get location of current point.
std::vector< VecInt > VecInt2d
const VecPt3d & m_pts
The points.
virtual void FinalizeTriangulation() override
Called after all triangles have been received.
void UpdateAreaTolerance()
calculates the area tolerance
Functions dealing with geometry.
virtual void SetObserver(BSHP< Observer > a_)
Set the observer to use for feedback while processing.
double trArea(const Pt3d &a_pt1, const Pt3d &a_pt2, const Pt3d &a_pt3)
Return the signed planar area of the triangle (CCW Positive).
Definition: triangles.cpp:46
double gmComputeXyTol(const Pt3d &a_mn, const Pt3d &a_mx)
Given extents (min, max), compute a tolerance for the xy plane to be used with geometric functions...
Definition: geoms.cpp:1262
void test1()
tests triangulating points
VecInt & m_tris
The triangles as 0-based indices into m_pts.
virtual int GetNPoints() const override
Return the number of points to be triangulated.
XMS Namespace.
Definition: geoms.cpp:34
virtual void IncrementPoint() override
Increment the current point index by 1.
void stShrinkCapacity(std::vector< T > &v)
void gmAddToExtents(const Pt3d &a_pt, Pt3d &a_min, Pt3d &a_max)
Compares a_pt to a_min and a_max. If a_pt is less than a_min or greater than a_max, a_min and a_max are updated.
Definition: geoms.cpp:787
#define TS_ASSERT_EQUALS_VEC(a, b)
Class to triangulate simple points.
std::vector< Pt3d > VecPt3d
BSHP< Observer > m_observer
Observer.