00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "g-map-vertex.hh"
00026 using namespace std;
00027 using namespace GMap3d;
00028
00029 CDart * CGMapVertex::createPolyline(const vector<CVertex> & AVector)
00030 {
00031 CMesh1VectorDiver ADiver(AVector);
00032 return createMesh1(AVector.size()-1, ADiver);
00033 }
00034
00035 CDart * CGMapVertex::createPole(int An, const CVertex & AVertex)
00036 {
00037 assert(An>0);
00038
00039 CDart * pole = createTopoPole(An);
00040 setVertex(pole, AVertex);
00041 return pole;
00042 }
00043
00044 CDart * CGMapVertex::createOpenedPole(int An, const CVertex & AVertex)
00045 {
00046 assert(An>0);
00047
00048 CDart * pole = createTopoOpenedPole(An);
00049 setVertex(pole, AVertex);
00050 return pole;
00051 }
00052
00053 CDart * CGMapVertex::createRegularPolygon(int An)
00054 {
00055 assert(An>=3);
00056
00057 CTransformationMatrix matrix;
00058 CVertex vertex(OX/2);
00059 matrix.rotate(OZ, 360.0/An);
00060
00061 CDart * current = createTopoPolygon(An);
00062
00063 for (int i=0; i<An; ++i)
00064 {
00065 setVertex(current, vertex);
00066 matrix.applyOn(vertex);
00067 current= alpha01(current);
00068 }
00069
00070 return current;
00071 }
00072
00073 void CGMapVertex::createSphere(int AMeridians, int AParallels,
00074 CDart * * ASouthPole, CDart * * ANorthPole)
00075 {
00076 assert(AMeridians>=3);
00077 assert(AParallels>=1);
00078
00079 CDart * southPole;
00080 CDart * northPole;
00081
00082
00083 CGMapGeneric::createTopoSphere(AMeridians,AParallels, &southPole, &northPole);
00084
00085
00086 CTransformationMatrix rotationMatrix;
00087 rotationMatrix.rotate(OZ, 360.0/AMeridians);
00088
00089 setVertex(southPole, -OZ/2);
00090 setVertex(northPole, +OZ/2);
00091
00092 CDart * currentY = alpha0121(southPole);
00093
00094 for (int j=0; j<AParallels; ++j, currentY = alpha0121(currentY))
00095 {
00096 CVertex vertex;
00097
00098 TCoordinate alpha = 180.0*(j+1)/(AParallels+1) - 90.0;
00099
00100 vertex.setX(dCos(alpha)/2);
00101 vertex.setZ(dSin(alpha)/2);
00102
00103 CDart * currentX = alpha1(currentY);
00104
00105 for (int i=0; i<AMeridians; ++i, currentX = alpha0121(currentX))
00106 {
00107 setVertex(currentX, vertex);
00108 rotationMatrix.applyOn(vertex);
00109 }
00110 }
00111
00112
00113 if (ASouthPole!=NULL) * ASouthPole = southPole;
00114 if (ANorthPole!=NULL) * ANorthPole = northPole;
00115 }
00116
00117 CDart * CGMapVertex::createSphere(int AMeridians, int AParallels)
00118 {
00119 assert(AMeridians>=3);
00120 assert(AParallels>=1);
00121
00122 CDart * southPole;
00123
00124 createSphere(AMeridians,AParallels, &southPole,NULL);
00125
00126 return southPole;
00127 }
00128
00129 void CGMapVertex::createCylinder(int AMeridians, int AParallels,
00130 CDart * * ABorder1, CDart * * ABorder2,
00131 bool AClose1, bool AClose2)
00132 {
00133 assert(AMeridians>=3);
00134 assert(AParallels>=1);
00135
00136 CDart * border1, * border2;
00137
00138
00139 createTopoCylinder(AMeridians,AParallels, &border1,&border2, AClose1,AClose2);
00140
00141
00142 CTransformationMatrix rotationMatrix;
00143 rotationMatrix.rotate(OZ, 360.0/AMeridians);
00144 CVertex vertex((OX-OZ)/2);
00145
00146 CDart * currentY = border1;
00147
00148 for (int i=0; i<AMeridians; ++i, currentY = alpha0121(currentY))
00149 {
00150 CDart * currentX = alpha1(currentY);
00151
00152 for (int j=0; j<=AParallels; ++j, currentX = alpha0121(currentX))
00153 {
00154 setVertex(currentX, vertex);
00155
00156 if (j<AParallels)
00157 vertex += OZ/AParallels;
00158 }
00159
00160 vertex -= OZ;
00161
00162 rotationMatrix.applyOn(vertex);
00163 }
00164
00165
00166 if (ABorder1!=NULL) * ABorder1 = border1;
00167 if (ABorder2!=NULL) * ABorder2 = border2;
00168 }
00169
00170 CDart * CGMapVertex::createCylinder(int AMeridians, int AParallels,
00171 bool AClose1, bool AClose2)
00172 {
00173 assert(AMeridians>=3);
00174 assert(AParallels>=1);
00175
00176 CDart * border1;
00177
00178 createCylinder(AMeridians,AParallels, &border1,NULL, AClose1,AClose2);
00179
00180 return border1;
00181 }
00182
00183 void CGMapVertex::createPyramid(int AMeridians, int AParallels,
00184 CDart * * ABaseDart, CDart * * APoleDart,
00185 bool ACloseBase)
00186 {
00187 assert(AMeridians>=3);
00188 assert(AParallels>=1);
00189
00190 CDart * baseDart, * poleDart;
00191
00192
00193 createTopoPyramid(AMeridians,AParallels, &baseDart,&poleDart, ACloseBase);
00194
00195
00196 setVertex(poleDart, OZ/2);
00197
00198 CTransformationMatrix rotationMatrix;
00199 rotationMatrix.rotate(OZ, 360.0/AMeridians);
00200
00201 CDart * currentX = alpha1(baseDart);
00202
00203 for (int i=0; i<AParallels; ++i, currentX = alpha0121(currentX))
00204 {
00205 CVertex vertex;
00206
00207 vertex.setX(0.5*(AParallels-i)/AParallels);
00208 vertex.setZ(((float) i)/AParallels-0.5);
00209
00210 CDart * currentY = alpha1(currentX);
00211
00212 for (int j=0; j<AMeridians; ++j, currentY = alpha0121(currentY))
00213 {
00214 setVertex(currentY, vertex);
00215 rotationMatrix.applyOn(vertex);
00216 }
00217 }
00218
00219
00220 if (ABaseDart!=NULL) * ABaseDart = baseDart;
00221 if (APoleDart!=NULL) * APoleDart = poleDart;
00222 }
00223
00224 CDart * CGMapVertex::createPyramid(int AMeridians, int AParallels,
00225 bool ACloseBase)
00226 {
00227 assert(AMeridians>=3);
00228 assert(AParallels>=1);
00229
00230 CDart * baseDart;
00231
00232 createPyramid(AMeridians,AParallels, &baseDart,NULL, ACloseBase);
00233
00234 return baseDart;
00235 }
00236
00237 void CGMapVertex::createTorus(int AMeridians, int AParallels,
00238 TCoordinate ARadiusProportion,
00239 CDart * * AEquator)
00240 {
00241 assert(AMeridians>=3);
00242 assert(AParallels>=3);
00243
00244 CDart * equator;
00245
00246
00247 createTopoTorus(AMeridians,AParallels, &equator);
00248
00249
00250 TCoordinate R = 0.5/(1+ARadiusProportion);
00251 TCoordinate r = 0.5 - R;
00252
00253 CTransformationMatrix matrix1; matrix1.rotate(OY, 360.0/AParallels);
00254 CTransformationMatrix matrix2; matrix2.translate(R*OX);
00255 CTransformationMatrix matrix3; matrix3.rotate(OZ, 360.0/AMeridians);
00256
00257 CVertex vertex1(r*OX);
00258
00259 CDart * currentY = alpha1(equator);
00260
00261 for (int j=0; j<AParallels; ++j, currentY = alpha0121(currentY))
00262 {
00263 CVertex vertex2(vertex1);
00264 matrix2.applyOn(vertex2);
00265
00266 CDart * currentX = alpha1(currentY);
00267
00268 for (int i=0; i<AMeridians; ++i, currentX = alpha0121(currentX))
00269 {
00270 setVertex(currentX, vertex2);
00271 matrix3.applyOn(vertex2);
00272 }
00273
00274 matrix1.applyOn(vertex1);
00275 }
00276
00277
00278 if (AEquator!=NULL) * AEquator = equator;
00279 }
00280
00281 CDart * CGMapVertex::createTorus(int AMeridians, int AParallels,
00282 TCoordinate ARadiusProportion)
00283 {
00284 assert(AMeridians>=3);
00285 assert(AParallels>=3);
00286
00287 CDart * equator;
00288
00289 createTorus(AMeridians,AParallels, ARadiusProportion, &equator);
00290
00291 return equator;
00292 }
00293
00294 void CGMapVertex::createSquareIMeshed(int ASx, int ASy, int AMeshDimension,
00295 CDart * ASquareCorners[2][2])
00296 {
00297 assert(ASx>0);
00298 assert(ASy>0);
00299 assert(AMeshDimension>=0 && AMeshDimension<=2);
00300 assert(ASquareCorners!=NULL);
00301
00302 if (AMeshDimension==0)
00303 ASx = ASy = 1;
00304
00305 createTopoSquareIMeshed(ASx,ASy, AMeshDimension, ASquareCorners);
00306
00307 if (AMeshDimension==2)
00308 {
00309 CMesh2BasicDiver diver(ASx,ASy, (-OX-OY)/2, OX,OY);
00310
00311 diveMesh2(ASquareCorners[0][0], diver, GMV_YES);
00312 }
00313 else
00314 {
00315 CMesh1BasicDiver bottom(ASx, (-OX-OY)/2, OX);
00316 CMesh1BasicDiver top (ASx, (-OX+OY)/2, OX);
00317 CMesh1BasicDiver left (ASy, (-OX-OY)/2, OY);
00318 CMesh1BasicDiver right (ASy, (+OX-OY)/2, OY);
00319
00320 diveMesh1( ASquareCorners[0][0] , bottom, GMV_YES);
00321 diveMesh1( ASquareCorners[0][1] , top , GMV_YES);
00322 diveMesh1(alpha1(ASquareCorners[0][0]), left , GMV_NO );
00323 diveMesh1(alpha1(ASquareCorners[1][0]), right , GMV_NO );
00324 }
00325 }
00326
00327 CDart * CGMapVertex::createSquareIMeshed(int ASx, int ASy, int AMeshDimension)
00328 {
00329 CDart * squareCorners[2][2];
00330
00331 createSquareIMeshed(ASx,ASy, AMeshDimension, squareCorners);
00332
00333 return squareCorners[0][0];
00334 }
00335
00336 void CGMapVertex::createCubeIMeshed(int ASx, int ASy, int ASz,
00337 int AMeshDimension,
00338 bool ACreatedFaces[3][2],
00339 CDart * AFacesCorners[3][2][2][2])
00340 {
00341 assert(ASx>0);
00342 assert(ASy>0);
00343 assert(ASz>0);
00344 assert(AMeshDimension>=0 && AMeshDimension<=2);
00345 assert(AFacesCorners!=NULL);
00346
00347
00348 createTopoCubeIMeshed(ASx, ASy, ASz, AMeshDimension,
00349 ACreatedFaces, AFacesCorners);
00350
00351
00352 if (AMeshDimension==0)
00353 ASx = ASy = ASz = 1;
00354
00355 int s[3] = { ASx, ASy, ASz};
00356
00357
00358 for (int i=0; i<2; ++i)
00359 for (int j=0; j<2; ++j)
00360 for (int k=0; k<2; ++k)
00361 {
00362 CDart * corner;
00363
00364 if (ACreatedFaces[0][i]) corner = AFacesCorners[0][i][j][k];
00365 else if (ACreatedFaces[1][j]) corner = AFacesCorners[1][j][k][i];
00366 else if (ACreatedFaces[2][k]) corner = AFacesCorners[2][k][i][j];
00367 else corner = NULL;
00368
00369 if (corner!=NULL)
00370 setVertex(corner, CVertex(i-0.5, j-0.5, k-0.5));
00371 }
00372
00373
00374 if (AMeshDimension>=1)
00375 for (int dim=0; dim<3; ++dim)
00376 {
00377 int dim1 = (dim+1) % 3;
00378 int dim2 = (dim+2) % 3;
00379
00380 for (int side1=0; side1<2; ++side1)
00381 for (int side2=0; side2<2; ++side2)
00382 if (ACreatedFaces[dim1][side1] || ACreatedFaces[dim2][side2])
00383 {
00384 CVertex origin =
00385 (side1-0.5)*BASE[dim1] + (side2-0.5)*BASE[dim2] - BASE[dim]/2;
00386
00387 CMesh1BasicDiver diver(s[dim], origin, BASE[dim]);
00388
00389 CDart * first =
00390 ACreatedFaces[dim2][side2]
00391 ? AFacesCorners[dim2][side2][ 0][side1]
00392 : alpha1(AFacesCorners[dim1][side1][side2][ 0]);
00393
00394 diveMesh1(first, diver, GMV_NO, AMeshDimension);
00395 }
00396 }
00397
00398
00399 if (AMeshDimension==2)
00400 for (int dim=0; dim<3; ++dim)
00401 {
00402 int dim1 = (dim+1) % 3;
00403 int dim2 = (dim+2) % 3;
00404
00405 for (int side=0; side<2; ++side)
00406 if (ACreatedFaces[dim][side])
00407 {
00408 CVertex origin = (side-0.5)*BASE[dim] - (BASE[dim1]+BASE[dim2])/2;
00409
00410 CMesh2BasicDiver diver(s[dim1],s[dim2],
00411 origin, BASE[dim1], BASE[dim2]);
00412
00413 CDart * first = AFacesCorners[dim][side][0][0];
00414
00415 diveMesh2(first, diver, GMV_NO);
00416 }
00417 }
00418 }
00419
00420 void CGMapVertex::createCubeIMeshed(int ASx, int ASy, int ASz,
00421 int AMeshDimension,
00422 bool ACreatedFaces[3][2],
00423 CDart ** ADart1, CDart ** ADart2)
00424 {
00425 CDart * facesCorners[3][2][2][2];
00426
00427 createCubeIMeshed(ASx, ASy, ASz, AMeshDimension, ACreatedFaces, facesCorners);
00428
00429 int dim;
00430
00431 for (dim=0; dim<3; ++dim)
00432 if (ACreatedFaces[dim][0] && ACreatedFaces[dim][1] &&
00433 !ACreatedFaces[(dim+1)%3][0] && !ACreatedFaces[(dim+1)%3][1] &&
00434 !ACreatedFaces[(dim+2)%3][0] && !ACreatedFaces[(dim+2)%3][1])
00435 {
00436 * ADart1 = facesCorners[dim][0][0][0];
00437 * ADart2 = facesCorners[dim][1][0][0];
00438 return;
00439 }
00440
00441 * ADart2 = NULL;
00442
00443 for (dim=0; dim<3; ++dim)
00444 for (int side=0; side<2; ++side)
00445 if (ACreatedFaces[dim][side])
00446 {
00447 * ADart1 = facesCorners[dim][side][0][0];
00448 return;
00449 }
00450
00451 assert(false);
00452 }
00453