GraphTriangulation.cpp
Go to the documentation of this file.
1 // *****************************************************************
2 // Filename: GraphProcessor.cpp
3 // Copyright: Kai Welke, Chair Prof. Dillmann (IAIM),
4 // Institute for Computer Science and Engineering (CSE),
5 // University of Karlsruhe. All rights reserved.
6 // Author: Kai Welke
7 // Date: 12.06.2007
8 // *****************************************************************
9 
10 
11 // *****************************************************************
12 // includes
13 // *****************************************************************
14 // local includes
15 #include "GraphTriangulation.h"
16 #include "GraphProcessor.h"
17 #include "Base/Math/MathTools.h"
18 #include "Base/Tools/DebugMemory.h"
19 
21 {
22  TC3DNodeList* pC3DNodeList = new TC3DNodeList();
23  int nNodes = (int) pGraph->getNodes()->size();
24 
25  for (int i = 0; i < nNodes; i++)
26  {
27  // project point to polar coordinates
28  Vec3d cartesian_point;
29  MathTools::convert(pGraph->getNode(i)->getPosition(), cartesian_point);
30 
31  CC3DNode* pC3DNode = new CC3DNode(cartesian_point);
32  pC3DNodeList->push_back(pC3DNode);
33  }
34 
35  // generate the delaunay triangulation by computing the
36  // convex hull of the sphere
37  CCHGiftWrap giftWrapping = CCHGiftWrap(pC3DNodeList);
38  CSphericalGraph* pCopy = new CSphericalGraph();
39  giftWrapping.generateConvexHull(pCopy);
40 
41  // add edges from triangulated graph to pGraph
42  TEdgeList* pEdges = pCopy->getEdges();
43 
44  for (int e = 0 ; e < pEdges->size() ; e++)
45  {
46  pGraph->addEdge(pEdges->at(e)->nIndex1, pEdges->at(e)->nIndex2);
47  }
48 
49  delete pCopy;
50 }
51 
52 
54 {
55  int nNumberViews = (int) pGraph->getNodes()->size();
56 
57  // create graph with nodes and nodes + 360
58  CSphericalGraph* pDoubleGraph = doubleNodes(pGraph);
59 
60  // do triangulation on the double size graph
61  //triangulationQuadratic(pDoubleGraph);
62  triangulationQuartic(pDoubleGraph);
63 
64  // insert detrmined edges in original graph
65  int nIndex1, nIndex2;
66  CSGEdge* pCurrentEdge;
67 
68  for (int e = 0 ; e < int(pDoubleGraph->getEdges()->size()) ; e++)
69  {
70  pCurrentEdge = pDoubleGraph->getEdges()->at(e);
71  nIndex1 = pCurrentEdge->nIndex1;
72  nIndex2 = pCurrentEdge->nIndex2;
73 
74  // HACK: delete outer edges
75  if ((pDoubleGraph->getNode(nIndex1)->getPosition().fTheta < 30.0) || (pDoubleGraph->getNode(nIndex1)->getPosition().fTheta > 690.0))
76  {
77  continue;
78  }
79 
80  if ((pDoubleGraph->getNode(nIndex2)->getPosition().fTheta < 30.0) || (pDoubleGraph->getNode(nIndex2)->getPosition().fTheta > 690.0))
81  {
82  continue;
83  }
84 
85  /* if( (pDoubleGraph->getNode(nIndex1)->getPosition().fPhi < 30.0) || (pDoubleGraph->getNode(nIndex1)->getPosition().fPhi > 330.0))
86  continue;
87  if( (pDoubleGraph->getNode(nIndex2)->getPosition().fPhi < 30.0) || (pDoubleGraph->getNode(nIndex2)->getPosition().fPhi > 330.0))
88  continue;
89  if( (pDoubleGraph->getNode(nIndex1)->getPosition().fPhi < 180.0) && (pDoubleGraph->getNode(nIndex2)->getPosition().fPhi > 180.0))
90  continue;
91  if( (pDoubleGraph->getNode(nIndex2)->getPosition().fPhi < 180.0) && (pDoubleGraph->getNode(nIndex1)->getPosition().fPhi > 180.0))
92  continue;
93  */
94  // eliminate virtual nodes
95  if (nIndex1 >= nNumberViews)
96  {
97  nIndex1 %= nNumberViews;
98  }
99 
100  if (nIndex2 >= nNumberViews)
101  {
102  nIndex2 %= nNumberViews;
103  }
104 
105  // update graph
106  if (nIndex1 != nIndex2)
107  if (!GraphProcessor::isEdgePresent(pGraph, nIndex1, nIndex2))
108  {
109  pGraph->addEdge(nIndex1, nIndex2);
110  }
111  }
112 
113  delete pDoubleGraph;
114 }
115 
117 {
118  TNodeList* pNodes = pGraph->getNodes();
119 
120  int nNumberPoints = int(pNodes->size());
121  bool bPointFree;
122  int i, j, k, l;
123 
124  for (i = 0 ; i < nNumberPoints - 2 ; i++)
125  {
126  printf("Round %d / %d\n", i, nNumberPoints - 2);
127 
128  for (j = i + 1 ; j < nNumberPoints - 1 ; j++)
129  {
130  if (j != i)
131  {
132  for (k = j + 1; k < nNumberPoints; k++)
133  {
134  if (k != i && k != j)
135  {
136 
137  // check if this rectangle is point free
138  bPointFree = true;
139 
140  for (l = 0; l < nNumberPoints ; l++)
141  {
142  // only if not one of the triangle points
143  if (l != i && l != j && l != k)
144  {
145  bool bInside;
146 
147  if (!GraphProcessor::insideCircumcircle(pGraph, i, j, k, l, bInside))
148  {
149  bPointFree = false;
150  break;
151  }
152 
153  if (bInside)
154  {
155  bPointFree = false;
156  break;
157  }
158  }
159  }
160 
161  if (bPointFree)
162  {
163  TSphereCoord p_i, p_j, p_k;
164  p_i = pNodes->at(i)->getPosition();
165  p_j = pNodes->at(j)->getPosition();
166  p_k = pNodes->at(k)->getPosition();
167 
168  // add triangle
169  if (MathTools::getDistanceOnArc(p_i, p_j) < fThreshold)
170  {
171  pGraph->addEdge(i, j);
172  }
173 
174  if (MathTools::getDistanceOnArc(p_i, p_k) < fThreshold)
175  {
176  pGraph->addEdge(i, k);
177  }
178 
179  if (MathTools::getDistanceOnArc(p_k, p_j) < fThreshold)
180  {
181  pGraph->addEdge(k, j);
182  }
183  }
184 
185  }
186  }
187  }
188  }
189  }
190 }
191 
192 
194 {
195  TEdgeList* pEdges = pGraph->getEdges();
196 
197  int nCurrentEdge;
198  int nFaces = 0;
199  int s = 0, t = 0;
200 
201  // find two closest neighbours and add edge to triangulation.
203 
204  // Create seed edge
205  int nEdgeIndex = pGraph->addEdge(s, t, -1, -1);
206 
207  nCurrentEdge = 0;
208 
209  while (nCurrentEdge < int(pEdges->size()))
210  {
211  if (pEdges->at(nCurrentEdge)->nLeftFace == -1)
212  {
213  completeFacet(pGraph, nCurrentEdge, nFaces);
214  }
215 
216  if (pEdges->at(nCurrentEdge)->nRightFace == -1)
217  {
218  completeFacet(pGraph, nCurrentEdge, nFaces);
219  }
220 
221  nCurrentEdge++;
222  }
223 }
224 
225 void GraphTriangulation::completeFacet(CSphericalGraph* pGraph, int nEdgeIndex, int nFaces)
226 {
227  TNodeList* pNodes = pGraph->getNodes();
228  TEdgeList* pEdges = pGraph->getEdges();
229  int s, t, u;
230 
231  // Cache s and t.
232  if (pEdges->at(nEdgeIndex)->nLeftFace == -1)
233  {
234  s = pEdges->at(nEdgeIndex)->nIndex1;
235  t = pEdges->at(nEdgeIndex)->nIndex2;
236  }
237  else if (pEdges->at(nEdgeIndex)->nRightFace == -1)
238  {
239  s = pEdges->at(nEdgeIndex)->nIndex2;
240  t = pEdges->at(nEdgeIndex)->nIndex1;
241  }
242  else
243  {
244  // Edge already completed.
245  return;
246  }
247 
248 
249  // Find a point on left of edge.
250  for (u = 0; u < int(pNodes->size()); u++)
251  {
252  if (u == s || u == t)
253  {
254  continue;
255  }
256 
257  // check side
258  float fAngle = MathTools::CalculateCrossProductFromDifference(pNodes->at(s)->getPosition(), pNodes->at(t)->getPosition(), pNodes->at(u)->getPosition());
259 
260  if (fAngle > 0.0)
261  {
262  break;
263  }
264  }
265 
266  // Find best point on left of edge.
267  int nBestPoint = u;
268  float fCp;
269 
270  if (nBestPoint < int(pNodes->size()))
271  {
272  TSphereCoord center;
273  float fRadius;
274  GraphProcessor::getCircumcircle(pGraph, s, t, nBestPoint, center, fRadius);
275 
276  for (u = nBestPoint + 1; u < int(pNodes->size()); u++)
277  {
278  if (u == s || u == t)
279  {
280  continue;
281  }
282 
283  fCp = MathTools::CalculateCrossProductFromDifference(pNodes->at(s)->getPosition(), pNodes->at(t)->getPosition(), pNodes->at(u)->getPosition());
284 
285  if (fCp > 0.0)
286  {
287  bool bInside;
288 
289  if (GraphProcessor::insideCircumcircle(pGraph, s, t, nBestPoint, u, bInside))
290  {
291  if (bInside)
292  {
293  nBestPoint = u;
294  }
295  }
296  }
297  }
298  }
299 
300  // Add new triangle or update edge info if s-t is on hull.
301  if (nBestPoint < int(pNodes->size()))
302  {
303  // Update face information of edge being completed.
304  updateLeftFace(pGraph, nEdgeIndex, s, t, nFaces);
305  nFaces++;
306 
307  // Add new edge or update face info of old edge.
308  nEdgeIndex = GraphProcessor::findEdge(pGraph, nBestPoint, s);
309 
310  if (nEdgeIndex == -1)
311  {
312  // New edge.
313  nEdgeIndex = pGraph->addEdge(nBestPoint, s, nFaces, -1);
314  }
315  else
316  {
317  // Old edge.
318  updateLeftFace(pGraph, nEdgeIndex, nBestPoint, s, nFaces);
319  }
320 
321  // Add new edge or update face info of old edge.
322  nEdgeIndex = GraphProcessor::findEdge(pGraph, t, nBestPoint);
323 
324  if (nEdgeIndex == -1)
325  {
326  // New edge.
327  nEdgeIndex = pGraph->addEdge(t, nBestPoint, nFaces, -1);
328  }
329  else
330  {
331  // Old edge.
332  updateLeftFace(pGraph, nEdgeIndex, t, nBestPoint, nFaces);
333  }
334  }
335  else
336  {
337  updateLeftFace(pGraph, nEdgeIndex, s, t, -2);
338  }
339 }
340 
341 void GraphTriangulation::updateLeftFace(CSphericalGraph* pGraph, int nEdgeIndex, int nIndex1, int nIndex2, int nFace)
342 {
343  // vector<TView*>* pViews = &pGraph->getAspectPool()->m_Views;
344  vector<CSGEdge*>* pEdges = pGraph->getEdges();
345 
346  bool bValid = false;
347 
348  if ((pEdges->at(nEdgeIndex)->nIndex1 == nIndex1) && (pEdges->at(nEdgeIndex)->nIndex2 == nIndex2))
349  {
350  bValid = true;
351  }
352 
353  if ((pEdges->at(nEdgeIndex)->nIndex1 == nIndex2) && (pEdges->at(nEdgeIndex)->nIndex2 == nIndex1))
354  {
355  bValid = true;
356  }
357 
358  if (!bValid)
359  {
360  printf("updateLeftFace: adj. matrix and edge table mismatch\n");
361  }
362 
363  if ((pEdges->at(nEdgeIndex)->nIndex1 == nIndex1) && (pEdges->at(nEdgeIndex)->nLeftFace == -1))
364  {
365  pEdges->at(nEdgeIndex)->nLeftFace = nFace;
366  }
367  else if ((pEdges->at(nEdgeIndex)->nIndex2 == nIndex1) && (pEdges->at(nEdgeIndex)->nRightFace == -1))
368  {
369  pEdges->at(nEdgeIndex)->nRightFace = nFace;
370  }
371 
372 }
373 
374 CSphericalGraph* GraphTriangulation::doubleNodes(CSphericalGraph* pSourceGraph)
375 {
376  // list to source views
377  TNodeList* pNodes = pSourceGraph->getNodes();
378  int nNumberSourceNodes = (int) pNodes->size();
379 
380  // add views to aspectpool
381  vector<TSphereCoord> coordinates;
382 
383 
384  for (int i = 0 ; i < nNumberSourceNodes ; i++)
385  {
386  coordinates.push_back(pNodes->at(i)->getPosition());
387  }
388 
389  TSphereCoord shiftedCoord;
390 
391  for (int i = 0 ; i < nNumberSourceNodes ; i++)
392  {
393  shiftedCoord = pNodes->at(i)->getPosition();
394  shiftedCoord.fTheta += 360.0f;
395  coordinates.push_back(shiftedCoord);
396  }
397 
398  /* TSphereCoord shifted2Coord, shifted3Coord;
399  for(int i = 0 ; i < nNumberSourceNodes ; i++)
400  {
401  shifted2Coord = pNodes->at(i)->getPosition();
402  shifted2Coord.fPhi += 180.0f;
403  coordinates.push_back(shifted2Coord);
404  }
405 
406  for(int i = 0 ; i < nNumberSourceNodes ; i++)
407  {
408  shifted3Coord = pNodes->at(i)->getPosition();
409  shifted3Coord.fPhi += 180.0f;
410  shifted3Coord.fTheta += 360.0f;
411  coordinates.push_back(shifted3Coord);
412  }
413  */
414  CSphericalGraph* pTmpGraph = new CSphericalGraph();
415 
416  for (int i = 0 ; i < 2 * nNumberSourceNodes ; i++)
417  {
418  CSGNode* pNode = new CSGNode(coordinates.at(i));
419  pTmpGraph->addNode(pNode);
420  }
421 
422  return pTmpGraph;
423 }
GraphProcessor::findEdge
int findEdge(CSphericalGraph *pGraph, int nIndex1, int nIndex2)
Definition: GraphProcessor.cpp:159
TNodeList
std::vector< CSGNode * > TNodeList
Definition: SphericalGraph.h:88
GraphTriangulation.h
GraphProcessor::insideCircumcircle
bool insideCircumcircle(CSphericalGraph *pGraph, int nIndex1, int nIndex2, int nIndex3, int nPointIndex, bool &bInside)
Definition: GraphProcessor.cpp:180
TSphereCoord::fTheta
float fTheta
Definition: Structs.h:26
CSphericalGraph::getEdges
TEdgeList * getEdges()
Definition: SphericalGraph.cpp:157
GraphProcessor.h
CSphericalGraph::addNode
int addNode(CSGNode *pNode)
Definition: SphericalGraph.cpp:96
GraphProcessor::isEdgePresent
bool isEdgePresent(CSphericalGraph *pGraph, int nIndex1, int nIndex2)
Definition: GraphProcessor.cpp:288
CSGNode::getPosition
TSphereCoord getPosition()
Definition: SphericalGraph.h:53
CSphericalGraph::addEdge
int addEdge(int nIndex1, int nIndex2)
Definition: SphericalGraph.cpp:105
CSGEdge::nIndex2
int nIndex2
Definition: SphericalGraph.h:36
GraphProcessor::findClosestNeighbours
void findClosestNeighbours(CSphericalGraph *pGraph, int &s, int &t)
Definition: GraphProcessor.cpp:128
CSGEdge
Definition: SphericalGraph.h:31
GraphTriangulation::triangulationQuartic
static void triangulationQuartic(CSphericalGraph *pGraph, float fThreshold=FLT_MAX)
Definition: GraphTriangulation.cpp:116
CSGNode
Definition: SphericalGraph.h:43
GraphProcessor::getCircumcircle
bool getCircumcircle(CSphericalGraph *pGraph, int nIndex1, int nIndex2, int nIndex3, TSphereCoord &center, float &fRadius)
Definition: GraphProcessor.cpp:202
GfxTL::Vec3d
VectorXD< 3, double > Vec3d
Definition: VectorXD.h:695
MathTools::CalculateCrossProductFromDifference
static float CalculateCrossProductFromDifference(TSphereCoord p1, TSphereCoord p2, TSphereCoord p3)
Definition: MathTools.cpp:258
GraphTriangulation::triangulationQuadratic
static void triangulationQuadratic(CSphericalGraph *pGraph)
Definition: GraphTriangulation.cpp:193
GraphTriangulation::triangulationQuadraticSpherical
static void triangulationQuadraticSpherical(CSphericalGraph *pGraph)
Definition: GraphTriangulation.cpp:53
CSphericalGraph::getNodes
TNodeList * getNodes()
Definition: SphericalGraph.cpp:162
CSGEdge::nIndex1
int nIndex1
Definition: SphericalGraph.h:35
TEdgeList
std::vector< CSGEdge * > TEdgeList
Definition: SphericalGraph.h:87
GraphTriangulation::delaunayTriangulationQuadratic
static void delaunayTriangulationQuadratic(CSphericalGraph *pGraph)
Definition: GraphTriangulation.cpp:20
MathTools::getDistanceOnArc
static float getDistanceOnArc(TSphereCoord p1, TSphereCoord p2)
Definition: MathTools.cpp:277
CSphericalGraph
Definition: SphericalGraph.h:93
TSphereCoord
Definition: Structs.h:22
MathTools::convert
static void convert(TSphereCoord in, Eigen::Vector3d &out)
Definition: MathTools.cpp:401
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
CSphericalGraph::getNode
CSGNode * getNode(int nIndex)
Definition: SphericalGraph.cpp:172