Commit 96ba366ec5ba0b76b58f1d4fb2183848e36c963b
1 parent
6c5b8ca3
first attempt to improve the solid angle method in GWcs::solidangle
Showing
1 changed file
with
13 additions
and
19 deletions
src/sky/GWcs.cpp
| ... | ... | @@ -425,34 +425,28 @@ void GWcs::write(GFitsHDU& hdu) const |
| 425 | 425 | * |
| 426 | 426 | * @param[in] pixel Pixel index (x,y) |
| 427 | 427 | * |
| 428 | - * Estimate solid angles of pixel by computing the coordinates in the 4 pixel | |
| 429 | - * corners. The surface is computed using a cartesian approximation: | |
| 430 | - * a | |
| 431 | - * 1-----5-----2 a+b | |
| 432 | - * / | h \ where A = h --- | |
| 433 | - * 4-------6-------3 2 | |
| 434 | - * b | |
| 435 | - * This is a brute force technique that works sufficiently well for non- | |
| 436 | - * rotated sky maps. Something more intelligent should be implemented in | |
| 437 | - * the future. | |
| 428 | +TODO:: UPDATE THIS DOCSTRING (+link to wikipedia) | |
| 438 | 429 | ***************************************************************************/ |
| 439 | 430 | double GWcs::solidangle(const GSkyPixel& pixel) const |
| 440 | 431 | { |
| 441 | - // Get the sky directions of the 6 points | |
| 432 | + // Get the sky directions of the 4 points | |
| 442 | 433 | GSkyDir dir1 = pix2dir(GSkyPixel(pixel.x()-0.5, pixel.y()-0.5)); |
| 443 | 434 | GSkyDir dir2 = pix2dir(GSkyPixel(pixel.x()+0.5, pixel.y()-0.5)); |
| 444 | 435 | GSkyDir dir3 = pix2dir(GSkyPixel(pixel.x()+0.5, pixel.y()+0.5)); |
| 445 | 436 | GSkyDir dir4 = pix2dir(GSkyPixel(pixel.x()-0.5, pixel.y()+0.5)); |
| 446 | - GSkyDir dir5 = pix2dir(GSkyPixel(pixel.x(), pixel.y()-0.5)); | |
| 447 | - GSkyDir dir6 = pix2dir(GSkyPixel(pixel.x(), pixel.y()+0.5)); | |
| 448 | 437 | |
| 449 | - // Compute distances between sky directions | |
| 450 | - double a = dir1.dist(dir2); | |
| 451 | - double b = dir3.dist(dir4); | |
| 452 | - double h = dir5.dist(dir6); | |
| 438 | + GVector vec1 = dir1.celvector(); | |
| 439 | + GVector vec2 = dir2.celvector(); | |
| 440 | + GVector vec3 = dir3.celvector(); | |
| 441 | + GVector vec4 = dir4.celvector(); | |
| 453 | 442 | |
| 454 | - // Compute solid angle | |
| 455 | - double solidangle = 0.5*(h*(a+b)); | |
| 443 | + double angle1 = std::acos(cross(vec2, (cross(vec1, vec2))) * cross(vec2, (cross(vec3, vec2)))); | |
| 444 | + double angle2 = std::acos(cross(vec3, (cross(vec2, vec3))) * cross(vec3, (cross(vec4, vec3)))); | |
| 445 | + double angle3 = std::acos(cross(vec4, (cross(vec3, vec4))) * cross(vec4, (cross(vec1, vec4)))); | |
| 446 | + double angle4 = std::acos(cross(vec1, (cross(vec4, vec1))) * cross(vec1, (cross(vec2, vec1)))); | |
| 447 | + | |
| 448 | + // http://mathworld.wolfram.com/SphericalPolygon.html | |
| 449 | + double solidangle = (angle1 + angle2 + angle3 + angle4) - (2 * gammalib::pi); | |
| 456 | 450 | |
| 457 | 451 | // Return solid angle |
| 458 | 452 | return solidangle; | ... | ... |