GraphGenerator.cpp
Go to the documentation of this file.
1 // *****************************************************************
2 // Filename: GraphGenerator.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: 08.07.2008
8 // *****************************************************************
9 
10 #include "GraphGenerator.h"
11 
12 vector<Vec3d> CGraphGenerator::m_Vertices;
13 vector<Face> CGraphGenerator::m_Faces;
14 
15 
16 void CGraphGenerator::generateGraph(CSphericalGraph* pPlainGraph, EPolyhedronType nBaseType, int nLevels, float fRadius)
17 {
18  initBasePolyhedron(nBaseType);
19  projectToSphere(fRadius);
20 
21  for (int L = 0 ; L < nLevels ; L++)
22  {
23  subDivide();
24  projectToSphere(fRadius);
25  }
26 
27  buildNodesAndEdges(pPlainGraph);
28 }
29 
30 void CGraphGenerator::initBasePolyhedron(EPolyhedronType nBaseType)
31 {
32  m_Vertices.clear();
33  m_Faces.clear();
34 
35  switch (nBaseType)
36  {
37  case eTetrahedron:
38  generateTetrahedron();
39  break;
40 
41  case eOctahedron:
42  generateOctahedron();
43  break;
44 
45  case eIcosahedron:
46  generateIcosahedron();
47  break;
48 
49  default:
50  printf("Wrong base type\n");
51  break;
52  }
53 }
54 
55 void CGraphGenerator::generateTetrahedron()
56 {
57  // vertices of a tetrahedron
58  float fSqrt3 = sqrt(3.0);
59  Vec3d v[4];
60 
61  Math3d::SetVec(v[0], fSqrt3, fSqrt3, fSqrt3);
62  Math3d::SetVec(v[1], -fSqrt3, -fSqrt3, fSqrt3);
63  Math3d::SetVec(v[2], -fSqrt3, fSqrt3, -fSqrt3);
64  Math3d::SetVec(v[3], fSqrt3, -fSqrt3, -fSqrt3);
65 
66  for (int i = 0 ; i < 4 ; i++)
67  {
68  m_Vertices.push_back(v[i]);
69  }
70 
71  // structure describing a tetrahedron
72  Face f[4];
73  f[0].set(1, 2, 3);
74  f[1].set(1, 4, 2);
75  f[2].set(3, 2, 4);
76  f[3].set(4, 1, 3);
77 
78  for (int i = 0 ; i < 4 ; i++)
79  {
80  f[i].m_n1--;
81  f[i].m_n2--;
82  f[i].m_n3--;
83  m_Faces.push_back(f[i]);
84  }
85 }
86 
87 void CGraphGenerator::generateOctahedron()
88 {
89  // Six equidistant points lying on the unit sphere
90  Vec3d v[6];
91  Math3d::SetVec(v[0], 1, 0, 0);
92  Math3d::SetVec(v[1], -1, 0, 0);
93  Math3d::SetVec(v[2], 0, 1, 0);
94  Math3d::SetVec(v[3], 0, -1, 0);
95  Math3d::SetVec(v[4], 0, 0, 1);
96  Math3d::SetVec(v[5], 0, 0, -1);
97 
98  for (int i = 0 ; i < 6 ; i++)
99  {
100  m_Vertices.push_back(v[i]);
101  }
102 
103  // Join vertices to create a unit octahedron
104  Face f[8];
105  f[0].set(1, 5, 3);
106  f[1].set(3, 5, 2);
107  f[2].set(2, 5, 4);
108  f[3].set(4, 5, 1);
109  f[4].set(1, 3, 6);
110  f[5].set(3, 2, 6);
111  f[6].set(2, 4, 6);
112  f[7].set(4, 1, 6);
113 
114  for (int i = 0 ; i < 8 ; i++)
115  {
116  f[i].m_n1--;
117  f[i].m_n2--;
118  f[i].m_n3--;
119  m_Faces.push_back(f[i]);
120  }
121 }
122 
123 void CGraphGenerator::generateIcosahedron()
124 {
125  // Twelve vertices of icosahedron on unit sphere
126  float tau = 0.8506508084;
127  float one = 0.5257311121;
128 
129  Vec3d v[12];
130 
131  Math3d::SetVec(v[0], tau, one, 0);
132  Math3d::SetVec(v[1], -tau, one, 0);
133  Math3d::SetVec(v[2], -tau, -one, 0);
134  Math3d::SetVec(v[3], tau, -one, 0);
135  Math3d::SetVec(v[4], one, 0, tau);
136  Math3d::SetVec(v[5], one, 0, -tau);
137  Math3d::SetVec(v[6], -one, 0, -tau);
138  Math3d::SetVec(v[7], -one, 0, tau);
139  Math3d::SetVec(v[8], 0, tau, one);
140  Math3d::SetVec(v[9], 0, -tau, one);
141  Math3d::SetVec(v[10], 0, -tau, -one);
142  Math3d::SetVec(v[11], 0, tau, -one);
143 
144  for (int i = 0 ; i < 12 ; i++)
145  {
146  m_Vertices.push_back(v[i]);
147  }
148 
149 
150  // Structure for unit icosahedron
151  Face f[20];
152  f[0].set(5, 8, 9);
153  f[1].set(5, 10, 8);
154  f[2].set(6, 12, 7);
155  f[3].set(6, 7, 11);
156  f[4].set(1, 4, 5);
157  f[5].set(1, 6, 4);
158  f[6].set(3, 2, 8);
159  f[7].set(3, 7, 2);
160  f[8].set(9, 12, 1);
161  f[9].set(9, 2, 12);
162  f[10].set(10, 4, 11);
163  f[11].set(10, 11, 3);
164  f[12].set(9, 1, 5);
165  f[13].set(12, 6, 1);
166  f[14].set(5, 4, 10);
167  f[15].set(6, 11, 4);
168  f[16].set(8, 2, 9);
169  f[17].set(7, 12, 2);
170  f[18].set(8, 10, 3);
171  f[19].set(7, 3, 11);
172 
173  for (int i = 0 ; i < 20 ; i++)
174  {
175  f[i].m_n1--;
176  f[i].m_n2--;
177  f[i].m_n3--;
178  m_Faces.push_back(f[i]);
179  }
180 }
181 
182 void CGraphGenerator::subDivide()
183 {
184  // buffer new faces
185  vector<Face> faces;
186 
187  // gp through all faces and subdivide
188  for (int f = 0 ; f < int(m_Faces.size()) ; f++)
189  {
190  // get the triangle vertex indices
191  int nA = m_Faces.at(f).m_n1;
192  int nB = m_Faces.at(f).m_n2;
193  int nC = m_Faces.at(f).m_n3;
194 
195  // get the triangle vertex coordinates
196  Vec3d a = m_Vertices.at(nA);
197  Vec3d b = m_Vertices.at(nB);
198  Vec3d c = m_Vertices.at(nC);
199 
200  // Now find the midpoints between vertices
201  Vec3d a_m, b_m, c_m;
202  Math3d::AddVecVec(a, b, a_m);
203  Math3d::MulVecScalar(a_m, 0.5, a_m);
204  Math3d::AddVecVec(b, c, b_m);
205  Math3d::MulVecScalar(b_m, 0.5, b_m);
206  Math3d::AddVecVec(c, a, c_m);
207  Math3d::MulVecScalar(c_m, 0.5, c_m);
208  /* printf("a: %f,%f,%f\n", a.x,a.y,a.z);
209  printf("b: %f,%f,%f\n", b.x,b.y,b.z);
210  printf("c: %f,%f,%f\n", c.x,c.y,c.z);
211 
212  printf("a<->b: %f,%f,%f\n", a_m.x,a_m.y,a_m.z);
213  printf("b<->c: %f,%f,%f\n", b_m.x,b_m.y,b_m.z);
214  printf("c<->a: %f,%f,%f\n", c_m.x,c_m.y,c_m.z);*/
215 
216  // add vertices
217  int nA_m, nB_m, nC_m;
218 
219  int nIndex;
220  nIndex = findVertex(a_m, 0.01);
221 
222  if (nIndex == -1)
223  {
224  m_Vertices.push_back(a_m);
225  nA_m = m_Vertices.size() - 1;
226  }
227  else
228  {
229  nA_m = nIndex;
230  }
231 
232  nIndex = findVertex(b_m, 0.01);
233 
234  if (nIndex == -1)
235  {
236  m_Vertices.push_back(b_m);
237  nB_m = m_Vertices.size() - 1;
238  }
239  else
240  {
241  nB_m = nIndex;
242  }
243 
244  nIndex = findVertex(c_m, 0.01);
245 
246  if (nIndex == -1)
247  {
248  m_Vertices.push_back(c_m);
249  nC_m = m_Vertices.size() - 1;
250  }
251  else
252  {
253  nC_m = nIndex;
254  }
255 
256  // Create new faces with orig vertices plus midpoints
257  Face f[4];
258  f[0].set(nA, nA_m, nC_m);
259  f[1].set(nA_m, nB, nB_m);
260  f[2].set(nC_m, nB_m, nC);
261  f[3].set(nA_m, nB_m, nC_m);
262 
263  for (int i = 0 ; i < 4 ; i++)
264  {
265  faces.push_back(f[i]);
266  }
267  }
268 
269  // assign new faces
270  m_Faces = faces;
271 }
272 
273 void CGraphGenerator::projectToSphere(float fRadius)
274 {
275  TSphereCoord coord;
276  Vec3d point;
277  coord.fDistance = 1.0f;
278 
279  for (int v = 0 ; v < int(m_Vertices.size()) ; v++)
280  {
281  float X = m_Vertices.at(v).x;
282  float Y = m_Vertices.at(v).y;
283  float Z = m_Vertices.at(v).z;
284 
285  float x, y, z;
286 
287  // Convert Cartesian X,Y,Z to spherical (radians)
288  float theta = atan2(Y, X);
289  float phi = atan2(sqrt(X * X + Y * Y), Z);
290 
291  // Recalculate X,Y,Z for constant r, given theta & phi.
292  x = fRadius * sin(phi) * cos(theta);
293  y = fRadius * sin(phi) * sin(theta);
294  z = fRadius * cos(phi);
295 
296  m_Vertices.at(v).x = x;
297  m_Vertices.at(v).y = y;
298  m_Vertices.at(v).z = z;
299  }
300 }
301 
302 void CGraphGenerator::buildNodesAndEdges(CSphericalGraph* pGraph)
303 {
304  // add nodes
305  TSphereCoord coord;
306 
307  for (int v = 0 ; v < int(m_Vertices.size()) ; v++)
308  {
309  // printf("Vertex: %f,%f,%f\n", m_Vertices.at(v).x, m_Vertices.at(v).y, m_Vertices.at(v).z);
310  MathTools::convert(m_Vertices.at(v), coord);
311  CSGNode* pNode = pGraph->getNewNode();
312  pNode->setPosition(coord);
313  pGraph->addNode(pNode);
314  }
315 
316  // add edges
317  // go through all faces (assumes check for duplicate edges in spherical graph!?)
318  for (int f = 0 ; f < int(m_Faces.size()) ; f++)
319  {
320  // printf(" %d,%d,%d\n", m_Faces.at(f).m_n1, m_Faces.at(f).m_n2, m_Faces.at(f).m_n3);
321  pGraph->addEdge(m_Faces.at(f).m_n1, m_Faces.at(f).m_n2);
322  pGraph->addEdge(m_Faces.at(f).m_n2, m_Faces.at(f).m_n3);
323  pGraph->addEdge(m_Faces.at(f).m_n3, m_Faces.at(f).m_n1);
324  }
325 }
326 
327 int CGraphGenerator::findVertex(Vec3d position, float fEpsilon)
328 {
329  float fDistance;
330  float fMinDistance = FLT_MAX;
331  int nIndex = -1;
332 
333  for (int v = 0 ; v < int(m_Vertices.size()) ; v++)
334  {
335  fDistance = Math3d::Angle(position, m_Vertices.at(v));
336 
337  if (fDistance < fMinDistance)
338  {
339  fMinDistance = fDistance;
340  nIndex = v;
341  }
342  }
343 
344  if (fMinDistance > fEpsilon)
345  {
346  nIndex = -1;
347  }
348 
349  return nIndex;
350 }
351 
Face::m_n3
int m_n3
Definition: GraphGenerator.h:53
GfxTL::sqrt
VectorXD< D, T > sqrt(const VectorXD< D, T > &a)
Definition: VectorXD.h:662
Face::m_n1
int m_n1
Definition: GraphGenerator.h:49
CSphericalGraph::addNode
int addNode(CSGNode *pNode)
Definition: SphericalGraph.cpp:96
CGraphGenerator::generateGraph
static void generateGraph(CSphericalGraph *pPlainGraph, EPolyhedronType nBaseType, int nLevels, float fRadius)
Definition: GraphGenerator.cpp:16
GraphGenerator.h
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
CSphericalGraph::getNewNode
virtual CSGNode * getNewNode()
Definition: SphericalGraph.h:103
CSphericalGraph::addEdge
int addEdge(int nIndex1, int nIndex2)
Definition: SphericalGraph.cpp:105
CSGNode::setPosition
void setPosition(TSphereCoord position)
Definition: SphericalGraph.h:57
CSGNode
Definition: SphericalGraph.h:43
eIcosahedron
@ eIcosahedron
Definition: GraphGenerator.h:28
Face::set
void set(int n1, int n2, int n3)
Definition: GraphGenerator.h:44
Face
Definition: GraphGenerator.h:34
armarx::ctrlutil::a
double a(double t, double a0, double j)
Definition: CtrlUtil.h:45
eTetrahedron
@ eTetrahedron
Definition: GraphGenerator.h:26
eOctahedron
@ eOctahedron
Definition: GraphGenerator.h:27
GfxTL::Vec3d
VectorXD< 3, double > Vec3d
Definition: VectorXD.h:695
EPolyhedronType
EPolyhedronType
Definition: GraphGenerator.h:24
Face::m_n2
int m_n2
Definition: GraphGenerator.h:52
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
TSphereCoord::fDistance
float fDistance
Definition: Structs.h:24
CSphericalGraph
Definition: SphericalGraph.h:93
TSphereCoord
Definition: Structs.h:22
MathTools::convert
static void convert(TSphereCoord in, Eigen::Vector3d &out)
Definition: MathTools.cpp:401