00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "face.h"
00011 #include "debug.h"
00012 #include "boundary.h"
00013 #include "heal.h"
00014 #include "map_exception.h"
00015
00016 using namespace std;
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 inline float zero(float x)
00029 {
00030 return fabs(x) < 1e-8 ? 0 : x;
00031 }
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 inline unsigned int min(const uint a, const uint b)
00044 {
00045 return a < b ? a : b;
00046 }
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 void Face::setRigging_NP(const int nside, vector<double> &costhetas, double rad)
00061 {
00062 double ds = 1./nside;
00063 double s = 0, t = 0;
00064 Boundary lower;
00065 Boundary boundry0;
00066 Boundary boundry1;
00067
00068 quadList.resize(nside);
00069 GLVertVI qli = quadList.begin();
00070 lower.set_eq( 0, 0.5*M_PI*(face+0.5), 1);
00071 for(int i = 0; i < nside; i++) {
00072 t = 0;
00073 qli->resize(2*(nside+1));
00074 GLVertI pti = qli->begin();
00075 bool boundry0_reset = false;
00076 bool boundry1_reset = false;
00077 boundry0.set_eq(costhetas[i], lower(costhetas[i]), -1);
00078 boundry1.set_eq(costhetas[i+1], lower(costhetas[i+1]), -1);
00079 for(int j = i; j <= i+nside; j++) {
00080 pti->setVertS(acos(costhetas[j]),boundry0(costhetas[j]),rad);
00081 pti->setTex(s,t);
00082 ++pti;
00083
00084 pti->setVertS(acos(costhetas[j+1]),boundry1(costhetas[j+1]),rad);
00085 pti->setTex(s+ds,t);
00086 ++pti;
00087
00088 if( (costhetas[j] >= 2./3.) && ! boundry0_reset) {
00089 boundry0.set_np(costhetas[j],boundry0(costhetas[j]),face);
00090 boundry0_reset = true;
00091 }
00092
00093 if( (costhetas[j+1 ]>= 2./3.) && ! boundry1_reset) {
00094 boundry1.set_np(costhetas[j+1],boundry1(costhetas[j+1]),face);
00095 boundry1_reset = true;
00096 }
00097
00098 t += ds;
00099 }
00100 s += ds;
00101 ++qli;
00102 }
00103 return;
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 void Face::setRigging_SP(const int nside, vector<double> &costhetas, double rad)
00119 {
00120 double ds = 1./nside;
00121 double s = 0, t = 0;
00122 double phi_boundry = 0.5*M_PI*(face-7);
00123 Boundary boundry0;
00124 Boundary boundry1;
00125
00126 quadList.resize(nside);
00127 GLVertVI qli = quadList.begin();
00128 for(int i = 0; i < nside; i++) {
00129 t = 0;
00130 qli->resize(2*(nside+1));
00131 GLVertI pti = qli->begin();
00132 bool boundry0_reset = false;
00133 bool boundry1_reset = false;
00134 boundry0.set_sp(costhetas[i], phi_boundry, face);
00135 boundry1.set_sp(costhetas[i+1], phi_boundry, face);
00136 for(int j = i; j <= i+nside; j++) {
00137 pti->setVertS(acos(costhetas[j]),boundry0(costhetas[j]),rad);
00138 pti->setTex(s,t);
00139 ++pti;
00140
00141 pti->setVertS(acos(costhetas[j+1]),boundry1(costhetas[j+1]),rad);
00142 pti->setTex(s+ds,t);
00143 ++pti;
00144
00145 if( (costhetas[j] > (-2./3. - 0.001)) && ! boundry0_reset) {
00146 boundry0.set_eq(costhetas[j],boundry0(costhetas[j]),-1);
00147 boundry0_reset = true;
00148 }
00149 if( (costhetas[j+1] > (-2./3. - 0.001)) && ! boundry1_reset) {
00150 boundry1.set_eq(costhetas[j+1],boundry1(costhetas[j+1]),-1);
00151 boundry1_reset = true;
00152 }
00153
00154 t += ds;
00155 }
00156 s += ds;
00157 ++qli;
00158 }
00159 return;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 void Face::setRigging_EQ(const int nside, vector<double> &costhetas, double rad)
00175 {
00176 double ds = 1./nside;
00177 double s = 0, t = 0;
00178 Boundary lower;
00179 lower.set_eq(-2./3., 0.5*M_PI*(face-4), 1);
00180 Boundary boundry0;
00181 Boundary boundry1;
00182
00183 quadList.resize(nside);
00184 GLVertVI qli = quadList.begin();
00185 for(int i = 0; i < nside; i++) {
00186 t = 0;
00187 qli->resize(2*(nside+1));
00188 GLVertI pti = qli->begin();
00189 boundry0.set_eq(costhetas[i], lower(costhetas[i]), -1);
00190 boundry1.set_eq(costhetas[i+1], lower(costhetas[i+1]), -1);
00191 for(int j = i; j <= i+nside; j++) {
00192 pti->setVertS(acos(costhetas[j]),boundry0(costhetas[j]),rad);
00193 pti->setTex(s,t);
00194 ++pti;
00195
00196 pti->setVertS(acos(costhetas[j+1]),boundry1(costhetas[j+1]),rad);
00197 pti->setTex(s+ds,t);
00198 ++pti;
00199
00200 t += ds;
00201 }
00202 s += ds;
00203 ++qli;
00204 }
00205 return;
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 void Face::setRigging(const int nside, vector<double> &costhetas,
00222 bool viewmoll, double rad)
00223 {
00224 double radius = viewmoll ? 1. : rad;
00225 if( face < 4)
00226 setRigging_NP(nside,costhetas,radius);
00227 else if( face > 7)
00228 setRigging_SP(nside,costhetas,radius);
00229 else
00230 setRigging_EQ(nside,costhetas,radius);
00231 rigging_set = true;
00232
00233 GLVertVI qli = quadList.begin();
00234 for(int i = 0; i < nside; i++) {
00235 GLVertI pti = qli->begin();
00236 GLVertI pti_end = qli->end();
00237 for(; pti != pti_end; ++pti) {
00238 pti->s = 0.25*pti->s + 0.25*(face % 4);
00239 pti->t = 0.25*pti->t + 0.25*(face / 4);
00240 }
00241 ++qli;
00242 }
00243
00244 if (viewmoll || showmoll) toMollweide(rad);
00245
00246 return;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 void Face::draw()
00260 {
00261 if (! rigging_set) {
00262 throw (MapException(MapException::Other, 0,
00263 "Face::draw:Rigging not set, face = "));;
00264 }
00265
00266 if( showface6 && face != 6 ) return;
00267
00268 QColor color;
00269 GLVertVI qli = quadList.begin();
00270 GLVertVI qli_end = quadList.end();
00271 GLVertI pti;
00272 GLVertI pti_end;
00273
00274 unsigned int list = 0;
00275 for(; qli != qli_end; ++qli) {
00276 pti_end = qli->end();
00277
00278 if( true || (list==(quadList.size()/2)) ) {
00279
00280 if( showrigging ) {
00281 glColor3f(1.0, 1.0, 1.0);
00282 glLineWidth(1.0);
00283 glBegin(GL_LINE_STRIP);
00284 for(pti = qli->begin(); pti != pti_end; ++pti) {
00285 pti->glSet();
00286 }
00287
00288 glEnd();
00289 }
00290 if( showrigging ) {
00291 glLineWidth(3.0);
00292 glBegin(GL_LINE_STRIP);
00293 }
00294 else
00295 glBegin(GL_QUAD_STRIP);
00296
00297 int pixel = 0;
00298 for(pti = qli->begin(); pti != pti_end; ++pti) {
00299
00300 if( showrigging ) {
00301 color.setHsv((int)(360*pixel/(qli->size()-1.)), 255, 255);
00302 glColor3f(color.red()/255.,color.green()/255.,color.blue()/255.);
00303 }
00304 pti->glSet();
00305 pixel++;
00306 }
00307 glEnd();
00308
00309 }
00310 list++;
00311 }
00312 return;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 void Face::toMollweide(double rad)
00328 {
00329 double r = 1/sqrt(2.);
00330 double phi;
00331 double lambda;
00332 double x,y;
00333
00334 int i = 0;
00335 for(GLVertVI qli = quadList.begin(); qli != quadList.end(); ++qli) {
00336 int j = 0;
00337 for(GLVertI pti = qli->begin(); pti != qli->end(); ++pti) {
00338 phi = asin(pti->z);
00339 lambda = atan2(pti->y,pti->x);
00340 ::toMollweide(phi, lambda, x, y);
00341 if( (face == 2 || face == 10) && x > 0) x *= -1;
00342 pti->y = r*x;
00343 pti->z = r*y;
00344 pti->x = (rad < 1.) ? -(rad - 1.) : 0;
00345 j++;
00346 }
00347 i++;
00348 }
00349 if( face == 6 )
00350 toMollweideBackfaceSplit();
00351
00352 return;
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 void Face::toMollweideBackfaceSplit(void)
00367 {
00368 if( face != 6 )
00369 return;
00370
00371
00372 GLVertVec oldquads;
00373 oldquads.resize(quadList.size());
00374 GLVertVI srcqli = quadList.begin();
00375 GLVertVI destqli = oldquads.begin();
00376 for(uint i = 0; i < quadList.size(); i++) {
00377 destqli->resize(srcqli->size());
00378 GLVertI srcpti = srcqli->begin();
00379 GLVertI destpti = destqli->begin();
00380 for( uint j = 0; j < srcqli->size(); j++)
00381 *destpti++ = *srcpti++;
00382 srcqli++;
00383 destqli++;
00384 }
00385
00386
00387 srcqli = oldquads.begin();
00388 GLVertVI qli;
00389 quadList.resize(0);
00390 uint i = 0;
00391 for(srcqli = oldquads.begin(); srcqli != oldquads.end(); ++srcqli) {
00392 i++;
00393
00394 bool patch = true;
00395 bool leftside = true;
00396
00397 GLVertices newverts1;
00398 GLVertices newverts2;
00399
00400 uint jbreak = srcqli->size();
00401 jbreak = 2*i-2;
00402 for(uint j = 0; j < srcqli->size(); j++ ){
00403
00404 GLPoint p = (*srcqli)[j];
00405 if( leftside ) {
00406 p.y = -fabs(p.y);
00407 newverts1.push_back(p);
00408 leftside = j < jbreak;
00409 }
00410 else if( patch ) {
00411
00412 p.y = -fabs(p.y);
00413 newverts1.push_back(p);
00414
00415 GLPoint p2;
00416 GLVertVI qli = srcqli;
00417 qli++;
00418 if( qli != oldquads.end() ) {
00419 p2 = (*qli)[j+1];
00420 p2.y = -fabs(p2.y);
00421 }
00422 else {
00423 p2.y = -1.66597;
00424 p2.z = 0.553293;
00425 p2.s = 0.75;
00426 p2.t = 0.5;
00427 }
00428 newverts1.push_back(p2);
00429 newverts1.push_back(p);
00430
00431
00432
00433 p = (*srcqli)[j+1];
00434 p.y = fabs(p.y);
00435 if( srcqli != oldquads.begin() ) {
00436 qli = srcqli;
00437 qli--;
00438 p2 = (*qli)[j];
00439 p2.y = fabs(p2.y);
00440 }
00441 else {
00442 p2.y = 1.66597;
00443 p2.z = -0.553293;
00444 p2.s = 0.5;
00445 p2.t = 0.25;
00446 }
00447 newverts2.push_back(p);
00448 newverts2.push_back(p2);
00449
00450 patch = false;
00451 }
00452 else {
00453 p.y = fabs(p.y);
00454 newverts2.push_back(p);
00455 }
00456
00457 }
00458 quadList.push_back(newverts1);
00459 quadList.push_back(newverts2);
00460 }
00461 return;
00462 }