00001 /* ============================================================================ 00002 'polarargline.cpp' defines the polarization vectors. 00003 00004 Written by Nicholas Phillips. 00005 QT4 adaption by Michael R. Greason, ADNET, 27 August 2007 00006 ============================================================================ */ 00007 /* 00008 Fetch header files. 00009 */ 00010 #include <iostream> 00011 #include "polarargline.h" 00012 #include "heal.h" 00013 00014 using namespace std; 00015 using namespace qglviewer; 00016 00017 const double boost = 0.001; // Distance to assign to a vector to get it 00018 // above the sphere. 00019 /* ---------------------------------------------------------------------------- 00020 'spinVector' computes the spin vector of a vector given a base vector and 00021 a rotation angle. 00022 00023 Arguments: 00024 v0 - The base vector. 00025 vin - The other vector 00026 psi - A rotation angle 00027 00028 Returned: 00029 vout - The spin vector. 00030 00031 Written by Nicholas Phillips. 00032 ---------------------------------------------------------------------------- */ 00033 Vec spinVector(const Vec &v0, const Vec &vin, double psi) 00034 { 00035 double e1,e2,e3; 00036 double A[3][3]; 00037 00038 e1 = v0[0]; e2 = v0[1]; e3 = v0[2]; 00039 double cosp = cos(psi); 00040 double sinp = sin(psi); 00041 00042 A[0][0] = cosp + e1*e1*(1-cosp); A[0][1] = e1*e2*(1-cosp)+e3*sinp; A[0][2] = e1*e3*(1-cosp)-e2*sinp; 00043 A[1][0] = e1*e2*(1-cosp)-e3*sinp; A[1][1] = cosp+e2*e2*(1-cosp); A[1][2] = e2*e3*(1-cosp)+e1*sinp; 00044 A[2][0] = e1*e3*(1-cosp)+e2*sinp; A[2][1] = e2*e3*(1-cosp)-e1*sinp; A[2][2] = cosp+e3*e3*(1-cosp); 00045 00046 Vec vout; 00047 for(int i = 0; i < 3; i++) { 00048 vout[i] = 0; 00049 for(int j = 0; j < 3; j++) 00050 vout[i] += A[i][j]*vin[j]; 00051 } 00052 return vout; 00053 } 00054 /* ---------------------------------------------------------------------------- 00055 'toMollweide' converts a vector from a spherical to Mollweide projection. 00056 00057 Arguments: 00058 v - The vector to transform. Assume that it is a unit vector. 00059 hgt - The height above the screen/plane to assign to the new vector. 00060 00061 Returned: 00062 t - The transformed vector. 00063 00064 Written by Nicholas Phillips. 00065 ---------------------------------------------------------------------------- */ 00066 Vec toMollweide (Vec v, double hgt) 00067 { 00068 Vec t; 00069 double rad, phi, lambda, x, y; 00070 rad = sqrt((v.x * v.x) + (v.y * v.y) + (v.z * v.z)); 00071 phi = asin(v.z / rad); 00072 lambda = atan2(v.y, v.x); 00073 toMollweide(phi, lambda, x, y); 00074 t.x = hgt; 00075 t.y = x / sqrt(2.); 00076 t.z = y / sqrt(2.); 00077 return t; 00078 } 00079 /* ============================================================================ 00080 'PolarArgLine' manages a single polarization angle vector on the viewer. 00081 ============================================================================ */ 00082 /* ---------------------------------------------------------------------------- 00083 'PolarArgLine' is the class constructor. 00084 00085 Arguments: 00086 None. 00087 00088 Written by Nicholas Phillips. 00089 ---------------------------------------------------------------------------- */ 00090 PolarArgLine::PolarArgLine (void) 00091 { 00092 on = false; 00093 moll = false; 00094 } 00095 /* ---------------------------------------------------------------------------- 00096 'set' defines the vector. 00097 00098 Arguments: 00099 theta - The colatitude in radians measured southward from the north pole 00100 (0--PI). 00101 phi - The longitude in radians measured eastward from the X-axis 00102 (0--2PI). 00103 gamma - The polarization angle, in radians, from the meridian. 00104 size - Essentially theta for pixel 0 over two--a scaling factor. 00105 00106 Returned: 00107 Nothing. 00108 00109 Written by Nicholas Phillips. 00110 ---------------------------------------------------------------------------- */ 00111 void PolarArgLine::set(double theta, double phi, double gamma, double size) 00112 { 00113 /* 00114 Compute the vector we will rotate about: the pixel center 00115 */ 00116 Vec v0(cos(phi)*sin(theta),sin(phi)*sin(theta),cos(theta)); 00117 /* 00118 Compute the vector we will rotate: points to the North Pole, Q=1, U=0 00119 */ 00120 theta -= M_PI/2; 00121 Vec vin(cos(phi)*sin(theta),sin(phi)*sin(theta),cos(theta)); 00122 /* 00123 Compute the end points: either end of a headless (spin-2) vector 00124 */ 00125 v1 = (1+boost)*v0 + size*spinVector(v0,vin,gamma); 00126 v2 = (1+boost)*v0 + size*spinVector(v0,vin,gamma+M_PI); 00127 /* 00128 Done! 00129 */ 00130 setColor(); 00131 setOn(true); 00132 return; 00133 } 00134 /* ---------------------------------------------------------------------------- 00135 'setColor' assigns a color to the vector. 00136 00137 Arguments: 00138 r - The red component of the color. 00139 g - The green component of the color. 00140 b - The blue component of the color. 00141 00142 Returned: 00143 Nothing. 00144 00145 Written by Nicholas Phillips. 00146 ---------------------------------------------------------------------------- */ 00147 void PolarArgLine::setColor(uchar r, uchar g, uchar b) 00148 { 00149 col.setValue(r/255.,g/255.,b/255.); 00150 return; 00151 } 00152 /* ---------------------------------------------------------------------------- 00153 'draw' draws the vector on the viewer. 00154 00155 Arguments: 00156 None. 00157 00158 Returned: 00159 Nothing. 00160 00161 Written by Nicholas Phillips. 00162 ---------------------------------------------------------------------------- */ 00163 void PolarArgLine::draw() 00164 { 00165 Vec a, b; 00166 if (moll) 00167 { 00168 double l; 00169 a = toMollweide(v1, boost); 00170 b = toMollweide(v2, boost); 00171 l = sqrt(((a.x - b.x) * (a.x - b.x)) 00172 + ((a.y - b.y) * (a.y - b.y)) 00173 + ((a.z - b.z) * (a.z - b.z))); 00174 if (l > 2.2) return; 00175 } 00176 else 00177 { 00178 a = v1; 00179 b = v2; 00180 } 00181 00182 glColor3fv(col); 00183 glBegin(GL_LINES); 00184 glVertex3fv(a); 00185 glVertex3fv(b); 00186 glEnd(); 00187 00188 return; 00189 } 00190 /* ============================================================================ 00191 'PolarArgLineSet' manages a set of polarization angle vectors. 00192 ============================================================================ */ 00193 /* ---------------------------------------------------------------------------- 00194 'PolarArgLineSet' is the class constructor. 00195 00196 Arguments: 00197 None. 00198 00199 Written by Nicholas Phillips. 00200 ---------------------------------------------------------------------------- */ 00201 PolarArgLineSet::PolarArgLineSet (void) 00202 { 00203 on = false; 00204 } 00205 /* ---------------------------------------------------------------------------- 00206 'set' defines the vectors from a sky map. 00207 00208 Arguments: 00209 skymap - The map, with polarization, to compute the vectors from. 00210 00211 Returned: 00212 Nothing. 00213 00214 Written by Nicholas Phillips. 00215 ---------------------------------------------------------------------------- */ 00216 void PolarArgLineSet::set(HealpixMap *skymap) 00217 { 00218 long i, nsiz, npix; 00219 double theta,phi; 00220 double pixsize; 00221 if (! (skymap->has_Polarization() && skymap->has_Nobs())) return; 00222 /* 00223 Start assuming the entire map. Discard pixels with no observations. 00224 */ 00225 nsiz = npix = skymap->size(); 00226 for (i = 0; i < nsiz; i++) 00227 { 00228 if ((*skymap)[i].Nobs() <= 0) npix--; 00229 } 00230 resize(npix); 00231 if (npix <= 0) return; 00232 /* 00233 Fill the vector list. 00234 */ 00235 iterator it = begin(); 00236 pixsize = (sqrt(M_PI / 3.) / skymap->nside()) / 2.; 00237 for (i = 0; i < nsiz; i++) 00238 { 00239 if ((*skymap)[i].Nobs() <= 0) continue; 00240 skymap->pixel2angles(i, theta, phi); 00241 it->set(theta, phi, (*skymap)[i].Pang(), pixsize); 00242 ++it; 00243 } 00244 return; 00245 } 00246 /* ---------------------------------------------------------------------------- 00247 'setMollweide' sets the Mollweide projection flag. 00248 00249 Arguments: 00250 b - Indicates whether (true) or not (false) to display the vectors in a 00251 Mollweide projection. 00252 00253 Returned: 00254 Nothing. 00255 00256 Written by Michael R. Greason, ADNET, 05 September 2007. 00257 ---------------------------------------------------------------------------- */ 00258 void PolarArgLineSet::setMollweide (bool b) 00259 { 00260 for (iterator it = begin(); it != end(); it++) 00261 { 00262 it->setMollweide(b); 00263 } 00264 } 00265 /* ---------------------------------------------------------------------------- 00266 'draw' draws the vectors on the viewer. 00267 00268 Arguments: 00269 None. 00270 00271 Returned: 00272 Nothing. 00273 00274 Written by Nicholas Phillips. 00275 ---------------------------------------------------------------------------- */ 00276 void PolarArgLineSet::draw() 00277 { 00278 if( ! isOn() ) 00279 return; 00280 00281 for( iterator it = begin(); it != end(); ++it){ 00282 if( it->isOn() ) 00283 it->draw(); 00284 } 00285 return; 00286 }