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