Moka kernel
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gmv-primitive.cc
Go to the documentation of this file.
1 /*
2  * lib-gmapkernel : Un noyau de 3-G-cartes et des opérations.
3  * Copyright (C) 2004, Moka Team, Université de Poitiers, Laboratoire SIC
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * Copyright (C) 2009, Guillaume Damiand, CNRS, LIRIS,
6  * guillaume.damiand@liris.cnrs.fr, http://liris.cnrs.fr/
7  *
8  * This file is part of lib-gmapkernel
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 //******************************************************************************
25 #include "g-map-vertex.hh"
26 using namespace std;
27 using namespace GMap3d;
28 //******************************************************************************
29 CDart * CGMapVertex::createPolyline(const vector<CVertex> & AVector)
30 {
31  CMesh1VectorDiver ADiver(AVector);
32  return createMesh1(AVector.size()-1, ADiver);
33 }
34 //******************************************************************************
35 CDart * CGMapVertex::createPole(int An, const CVertex & AVertex)
36 {
37  assert(An>0);
38 
39  CDart * pole = createTopoPole(An);
40  setVertex(pole, AVertex);
41  return pole;
42 }
43 //******************************************************************************
44 CDart * CGMapVertex::createOpenedPole(int An, const CVertex & AVertex)
45 {
46  assert(An>0);
47 
48  CDart * pole = createTopoOpenedPole(An);
49  setVertex(pole, AVertex);
50  return pole;
51 }
52 //******************************************************************************
54 {
55  assert(An>=3);
56 
57  CTransformationMatrix matrix;
58  CVertex vertex(OX/2);
59  matrix.rotate(OZ, 360.0/An);
60 
61  CDart * current = createTopoPolygon(An);
62 
63  for (int i=0; i<An; ++i)
64  {
65  setVertex(current, vertex);
66  matrix.applyOn(vertex);
67  current= alpha01(current);
68  }
69 
70  return current;
71 }
72 //******************************************************************************
73 void CGMapVertex::createSphere(int AMeridians, int AParallels,
74  CDart * * ASouthPole, CDart * * ANorthPole)
75 {
76  assert(AMeridians>=3);
77  assert(AParallels>=1);
78 
79  CDart * southPole;
80  CDart * northPole;
81 
82  // Topologie:
83  CGMapGeneric::createTopoSphere(AMeridians,AParallels, &southPole, &northPole);
84 
85  // Géométrie:
86  CTransformationMatrix rotationMatrix;
87  rotationMatrix.rotate(OZ, 360.0/AMeridians);
88 
89  setVertex(southPole, -OZ/2);
90  setVertex(northPole, +OZ/2);
91 
92  CDart * currentY = alpha0121(southPole);
93 
94  for (int j=0; j<AParallels; ++j, currentY = alpha0121(currentY))
95  {
96  CVertex vertex;
97 
98  TCoordinate alpha = 180.0*(j+1)/(AParallels+1) - 90.0;
99 
100  vertex.setX(dCos(alpha)/2);
101  vertex.setZ(dSin(alpha)/2);
102 
103  CDart * currentX = alpha1(currentY);
104 
105  for (int i=0; i<AMeridians; ++i, currentX = alpha0121(currentX))
106  {
107  setVertex(currentX, vertex);
108  rotationMatrix.applyOn(vertex);
109  }
110  }
111 
112  // Paramètres en sortie:
113  if (ASouthPole!=NULL) * ASouthPole = southPole;
114  if (ANorthPole!=NULL) * ANorthPole = northPole;
115 }
116 //******************************************************************************
117 CDart * CGMapVertex::createSphere(int AMeridians, int AParallels)
118 {
119  assert(AMeridians>=3);
120  assert(AParallels>=1);
121 
122  CDart * southPole;
123 
124  createSphere(AMeridians,AParallels, &southPole,NULL);
125 
126  return southPole;
127 }
128 //******************************************************************************
129 void CGMapVertex::createCylinder(int AMeridians, int AParallels,
130  CDart * * ABorder1, CDart * * ABorder2,
131  bool AClose1, bool AClose2)
132 {
133  assert(AMeridians>=3);
134  assert(AParallels>=1);
135 
136  CDart * border1, * border2;
137 
138  // Topologie:
139  createTopoCylinder(AMeridians,AParallels, &border1,&border2, AClose1,AClose2);
140 
141  // Géométrie:
142  CTransformationMatrix rotationMatrix;
143  rotationMatrix.rotate(OZ, 360.0/AMeridians);
144  CVertex vertex((OX-OZ)/2);
145 
146  CDart * currentY = border1;
147 
148  for (int i=0; i<AMeridians; ++i, currentY = alpha0121(currentY))
149  {
150  CDart * currentX = alpha1(currentY);
151 
152  for (int j=0; j<=AParallels; ++j, currentX = alpha0121(currentX))
153  {
154  setVertex(currentX, vertex);
155 
156  if (j<AParallels)
157  vertex += OZ/AParallels;
158  }
159 
160  vertex -= OZ;
161 
162  rotationMatrix.applyOn(vertex);
163  }
164 
165  // Paramètres en sortie:
166  if (ABorder1!=NULL) * ABorder1 = border1;
167  if (ABorder2!=NULL) * ABorder2 = border2;
168 }
169 //******************************************************************************
170 CDart * CGMapVertex::createCylinder(int AMeridians, int AParallels,
171  bool AClose1, bool AClose2)
172 {
173  assert(AMeridians>=3);
174  assert(AParallels>=1);
175 
176  CDart * border1;
177 
178  createCylinder(AMeridians,AParallels, &border1,NULL, AClose1,AClose2);
179 
180  return border1;
181 }
182 //******************************************************************************
183 void CGMapVertex::createPyramid(int AMeridians, int AParallels,
184  CDart * * ABaseDart, CDart * * APoleDart,
185  bool ACloseBase)
186 {
187  assert(AMeridians>=3);
188  assert(AParallels>=1);
189 
190  CDart * baseDart, * poleDart;
191 
192  // Topologie:
193  createTopoPyramid(AMeridians,AParallels, &baseDart,&poleDart, ACloseBase);
194 
195  // Géométrie:
196  setVertex(poleDart, OZ/2);
197 
198  CTransformationMatrix rotationMatrix;
199  rotationMatrix.rotate(OZ, 360.0/AMeridians);
200 
201  CDart * currentX = alpha1(baseDart);
202 
203  for (int i=0; i<AParallels; ++i, currentX = alpha0121(currentX))
204  {
205  CVertex vertex;
206 
207  vertex.setX(0.5*(AParallels-i)/AParallels);
208  vertex.setZ(((float) i)/AParallels-0.5);
209 
210  CDart * currentY = alpha1(currentX);
211 
212  for (int j=0; j<AMeridians; ++j, currentY = alpha0121(currentY))
213  {
214  setVertex(currentY, vertex);
215  rotationMatrix.applyOn(vertex);
216  }
217  }
218 
219  // Paramètres en sortie:
220  if (ABaseDart!=NULL) * ABaseDart = baseDart;
221  if (APoleDart!=NULL) * APoleDart = poleDart;
222 }
223 //******************************************************************************
224 CDart * CGMapVertex::createPyramid(int AMeridians, int AParallels,
225  bool ACloseBase)
226 {
227  assert(AMeridians>=3);
228  assert(AParallels>=1);
229 
230  CDart * baseDart;
231 
232  createPyramid(AMeridians,AParallels, &baseDart,NULL, ACloseBase);
233 
234  return baseDart;
235 }
236 //******************************************************************************
237 void CGMapVertex::createTorus(int AMeridians, int AParallels,
238  TCoordinate ARadiusProportion,
239  CDart * * AEquator)
240 {
241  assert(AMeridians>=3);
242  assert(AParallels>=3);
243 
244  CDart * equator;
245 
246  // Topologie:
247  createTopoTorus(AMeridians,AParallels, &equator);
248 
249  // Géométrie:
250  TCoordinate R = 0.5/(1+ARadiusProportion);
251  TCoordinate r = 0.5 - R;
252 
253  CTransformationMatrix matrix1; matrix1.rotate(OY, 360.0/AParallels);
254  CTransformationMatrix matrix2; matrix2.translate(R*OX);
255  CTransformationMatrix matrix3; matrix3.rotate(OZ, 360.0/AMeridians);
256 
257  CVertex vertex1(r*OX);
258 
259  CDart * currentY = alpha1(equator);
260 
261  for (int j=0; j<AParallels; ++j, currentY = alpha0121(currentY))
262  {
263  CVertex vertex2(vertex1);
264  matrix2.applyOn(vertex2);
265 
266  CDart * currentX = alpha1(currentY);
267 
268  for (int i=0; i<AMeridians; ++i, currentX = alpha0121(currentX))
269  {
270  setVertex(currentX, vertex2);
271  matrix3.applyOn(vertex2);
272  }
273 
274  matrix1.applyOn(vertex1);
275  }
276 
277  // Paramètre en sortie:
278  if (AEquator!=NULL) * AEquator = equator;
279 }
280 //******************************************************************************
281 CDart * CGMapVertex::createTorus(int AMeridians, int AParallels,
282  TCoordinate ARadiusProportion)
283 {
284  assert(AMeridians>=3);
285  assert(AParallels>=3);
286 
287  CDart * equator;
288 
289  createTorus(AMeridians,AParallels, ARadiusProportion, &equator);
290 
291  return equator;
292 }
293 //******************************************************************************
294 void CGMapVertex::createSquareIMeshed(int ASx, int ASy, int AMeshDimension,
295  CDart * ASquareCorners[2][2])
296 {
297  assert(ASx>0);
298  assert(ASy>0);
299  assert(AMeshDimension>=0 && AMeshDimension<=2);
300  assert(ASquareCorners!=NULL);
301 
302  if (AMeshDimension==0)
303  ASx = ASy = 1;
304 
305  createTopoSquareIMeshed(ASx,ASy, AMeshDimension, ASquareCorners);
306 
307  if (AMeshDimension==2)
308  {
309  CMesh2BasicDiver diver(ASx,ASy, (-OX-OY)/2, OX,OY);
310 
311  diveMesh2(ASquareCorners[0][0], diver, GMV_YES);
312  }
313  else
314  {
315  CMesh1BasicDiver bottom(ASx, (-OX-OY)/2, OX);
316  CMesh1BasicDiver top (ASx, (-OX+OY)/2, OX);
317  CMesh1BasicDiver left (ASy, (-OX-OY)/2, OY);
318  CMesh1BasicDiver right (ASy, (+OX-OY)/2, OY);
319 
320  diveMesh1( ASquareCorners[0][0] , bottom, GMV_YES);
321  diveMesh1( ASquareCorners[0][1] , top , GMV_YES);
322  diveMesh1(alpha1(ASquareCorners[0][0]), left , GMV_NO );
323  diveMesh1(alpha1(ASquareCorners[1][0]), right , GMV_NO );
324  }
325 }
326 //******************************************************************************
327 CDart * CGMapVertex::createSquareIMeshed(int ASx, int ASy, int AMeshDimension)
328 {
329  CDart * squareCorners[2][2];
330 
331  createSquareIMeshed(ASx,ASy, AMeshDimension, squareCorners);
332 
333  return squareCorners[0][0];
334 }
335 //******************************************************************************
336 void CGMapVertex::createCubeIMeshed(int ASx, int ASy, int ASz,
337  int AMeshDimension,
338  bool ACreatedFaces[3][2],
339  CDart * AFacesCorners[3][2][2][2])
340 {
341  assert(ASx>0);
342  assert(ASy>0);
343  assert(ASz>0);
344  assert(AMeshDimension>=0 && AMeshDimension<=2);
345  assert(AFacesCorners!=NULL);
346 
347  // Topologie:
348  createTopoCubeIMeshed(ASx, ASy, ASz, AMeshDimension,
349  ACreatedFaces, AFacesCorners);
350 
351  // Plongements:
352  if (AMeshDimension==0)
353  ASx = ASy = ASz = 1;
354 
355  int s[3] = { ASx, ASy, ASz};
356 
357  // Sommets:
358  for (int i=0; i<2; ++i)
359  for (int j=0; j<2; ++j)
360  for (int k=0; k<2; ++k)
361  {
362  CDart * corner;
363 
364  if (ACreatedFaces[0][i]) corner = AFacesCorners[0][i][j][k];
365  else if (ACreatedFaces[1][j]) corner = AFacesCorners[1][j][k][i];
366  else if (ACreatedFaces[2][k]) corner = AFacesCorners[2][k][i][j];
367  else corner = NULL;
368 
369  if (corner!=NULL)
370  setVertex(corner, CVertex(i-0.5, j-0.5, k-0.5));
371  }
372 
373  // Arêtes:
374  if (AMeshDimension>=1)
375  for (int dim=0; dim<3; ++dim)
376  {
377  int dim1 = (dim+1) % 3;
378  int dim2 = (dim+2) % 3;
379 
380  for (int side1=0; side1<2; ++side1)
381  for (int side2=0; side2<2; ++side2)
382  if (ACreatedFaces[dim1][side1] || ACreatedFaces[dim2][side2])
383  {
384  CVertex origin =
385  (side1-0.5)*BASE[dim1] + (side2-0.5)*BASE[dim2] - BASE[dim]/2;
386 
387  CMesh1BasicDiver diver(s[dim], origin, BASE[dim]);
388 
389  CDart * first =
390  ACreatedFaces[dim2][side2]
391  ? AFacesCorners[dim2][side2][ 0][side1]
392  : alpha1(AFacesCorners[dim1][side1][side2][ 0]);
393 
394  diveMesh1(first, diver, GMV_NO, AMeshDimension);
395  }
396  }
397 
398  // Faces:
399  if (AMeshDimension==2)
400  for (int dim=0; dim<3; ++dim)
401  {
402  int dim1 = (dim+1) % 3;
403  int dim2 = (dim+2) % 3;
404 
405  for (int side=0; side<2; ++side)
406  if (ACreatedFaces[dim][side])
407  {
408  CVertex origin = (side-0.5)*BASE[dim] - (BASE[dim1]+BASE[dim2])/2;
409 
410  CMesh2BasicDiver diver(s[dim1],s[dim2],
411  origin, BASE[dim1], BASE[dim2]);
412 
413  CDart * first = AFacesCorners[dim][side][0][0];
414 
415  diveMesh2(first, diver, GMV_NO);
416  }
417  }
418 }
419 //******************************************************************************
420 void CGMapVertex::createCubeIMeshed(int ASx, int ASy, int ASz,
421  int AMeshDimension,
422  bool ACreatedFaces[3][2],
423  CDart ** ADart1, CDart ** ADart2)
424 {
425  CDart * facesCorners[3][2][2][2];
426 
427  createCubeIMeshed(ASx, ASy, ASz, AMeshDimension, ACreatedFaces, facesCorners);
428 
429  int dim;
430 
431  for (dim=0; dim<3; ++dim)
432  if (ACreatedFaces[dim][0] && ACreatedFaces[dim][1] &&
433  !ACreatedFaces[(dim+1)%3][0] && !ACreatedFaces[(dim+1)%3][1] &&
434  !ACreatedFaces[(dim+2)%3][0] && !ACreatedFaces[(dim+2)%3][1])
435  {
436  * ADart1 = facesCorners[dim][0][0][0];
437  * ADart2 = facesCorners[dim][1][0][0];
438  return;
439  }
440 
441  * ADart2 = NULL;
442 
443  for (dim=0; dim<3; ++dim)
444  for (int side=0; side<2; ++side)
445  if (ACreatedFaces[dim][side])
446  {
447  * ADart1 = facesCorners[dim][side][0][0];
448  return;
449  }
450 
451  assert(false);
452 }
453 //******************************************************************************