Home · All Namespaces · All Classes · Functions · Coding Style · Scripting · Plugins · File Structure

core/StelProjectorClasses.hpp

00001 /*
00002  * Stellarium
00003  * Copyright (C) 2008 Stellarium Developers
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018  */
00019 
00020 #ifndef _STELPROJECTIONS_HPP_
00021 #define _STELPROJECTIONS_HPP_
00022 
00023 #include <limits>
00024 #include "StelProjector.hpp"
00025 
00026 class StelProjectorPerspective : public StelProjector
00027 {
00028 public:
00029     StelProjectorPerspective(const Mat4d& modelViewMat) : StelProjector(modelViewMat) {;}
00030     virtual QString getNameI18() const;
00031     virtual QString getDescriptionI18() const;
00032     virtual float getMaxFov() const {return 120.f;}
00033     bool forward(Vec3f &v) const
00034     {
00035         const float r = std::sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
00036         if (v[2] < 0) {
00037             v[0] /= (-v[2]);
00038             v[1] /= (-v[2]);
00039             v[2] = r;
00040             return true;
00041         }
00042         if (v[2] > 0) {
00043             v[0] /= v[2];
00044             v[1] /= v[2];
00045             v[2] = r;
00046             return false;
00047         }
00048         v[0] = std::numeric_limits<float>::max();
00049         v[1] = std::numeric_limits<float>::max();
00050         v[2] = r;
00051         return false;
00052     }
00053     bool backward(Vec3d &v) const;
00054     float fovToViewScalingFactor(float fov) const;
00055     float viewScalingFactorToFov(float vsf) const;
00056     float deltaZoom(float fov) const;
00057 protected:
00058     virtual bool hasDiscontinuity() const {return false;}
00059     virtual bool intersectViewportDiscontinuityInternal(const Vec3d&, const Vec3d&) const {return false;}
00060     virtual bool intersectViewportDiscontinuityInternal(const Vec3d&, double) const {return false;}
00061 };
00062 
00063 class StelProjectorEqualArea : public StelProjector
00064 {
00065 public:
00066     StelProjectorEqualArea(const Mat4d& modelViewMat) : StelProjector(modelViewMat) {;}
00067     virtual QString getNameI18() const;
00068     virtual QString getDescriptionI18() const;
00069     virtual float getMaxFov() const {return 360.f;}
00070     bool forward(Vec3f &v) const
00071     {
00072         const float r = std::sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
00073         const float f = std::sqrt(2.f/(r*(r-v[2])));
00074         v[0] *= f;
00075         v[1] *= f;
00076         v[2] = r;
00077         return true;
00078     }
00079     bool backward(Vec3d &v) const;
00080     float fovToViewScalingFactor(float fov) const;
00081     float viewScalingFactorToFov(float vsf) const;
00082     float deltaZoom(float fov) const;
00083 protected:
00084     virtual bool hasDiscontinuity() const {return false;}
00085     virtual bool intersectViewportDiscontinuityInternal(const Vec3d&, const Vec3d&) const {return false;}
00086     virtual bool intersectViewportDiscontinuityInternal(const Vec3d&, double) const {return false;}
00087 };
00088 
00089 class StelProjectorStereographic : public StelProjector
00090 {
00091 public:
00092     StelProjectorStereographic(const Mat4d& modelViewMat) : StelProjector(modelViewMat) {;}
00093     virtual QString getNameI18() const;
00094     virtual QString getDescriptionI18() const;
00095     virtual float getMaxFov() const {return 235.f;}
00096     bool forward(Vec3f &v) const
00097     {
00098         const float r = std::sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
00099         const float h = 0.5f*(r-v[2]);
00100         if (h <= 0.f) {
00101             v[0] = std::numeric_limits<float>::max();
00102             v[1] = std::numeric_limits<float>::max();
00103             v[2] = -std::numeric_limits<float>::min();
00104             return false;
00105         }
00106         const float f = 1.f / h;
00107         v[0] *= f;
00108         v[1] *= f;
00109         v[2] = r;
00110         return true;
00111     }
00112 
00113     virtual void project(int n, const Vec3d* in, Vec3f* out)
00114     {
00115         Vec3d v;
00116         for (int i = 0; i < n; ++i, ++out)
00117         {
00118             v = in[i];
00119             v.transfo4d(modelViewMatrix);
00120             out->set(v[0], v[1], v[2]);
00121             StelProjectorStereographic::forward(*out);
00122             out->set(viewportCenter[0] + flipHorz * pixelPerRad * (*out)[0],
00123                 viewportCenter[1] + flipVert * pixelPerRad * (*out)[1],
00124                 ((*out)[2] - zNear) * oneOverZNearMinusZFar);
00125         }
00126     }
00127 
00128     bool backward(Vec3d &v) const;
00129     float fovToViewScalingFactor(float fov) const;
00130     float viewScalingFactorToFov(float vsf) const;
00131     float deltaZoom(float fov) const;
00132 protected:
00133     virtual bool hasDiscontinuity() const {return false;}
00134     virtual bool intersectViewportDiscontinuityInternal(const Vec3d&, const Vec3d&) const {return false;}
00135     virtual bool intersectViewportDiscontinuityInternal(const Vec3d&, double) const {return false;}
00136 };
00137 
00138 class StelProjectorFisheye : public StelProjector
00139 {
00140 public:
00141     StelProjectorFisheye(const Mat4d& modelViewMat) : StelProjector(modelViewMat) {;}
00142     virtual QString getNameI18() const;
00143     virtual QString getDescriptionI18() const;
00144     virtual float getMaxFov() const {return 180.00001f;}
00145     bool forward(Vec3f &v) const
00146     {
00147         const float rq1 = v[0]*v[0] + v[1]*v[1];
00148         if (rq1 > 0.f) {
00149             const float h = std::sqrt(rq1);
00150             const float f = std::atan2(h,-v[2]) / h;
00151             v[0] *= f;
00152             v[1] *= f;
00153             v[2] = std::sqrt(rq1 + v[2]*v[2]);
00154             return true;
00155         }
00156         if (v[2] < 0.f) {
00157             v[0] = 0.f;
00158             v[1] = 0.f;
00159             v[2] = 1.f;
00160             return true;
00161         }
00162         v[0] = std::numeric_limits<float>::max();
00163         v[1] = std::numeric_limits<float>::max();
00164         v[2] = std::numeric_limits<float>::min();
00165         return false;
00166     }
00167     bool backward(Vec3d &v) const;
00168     float fovToViewScalingFactor(float fov) const;
00169     float viewScalingFactorToFov(float vsf) const;
00170     float deltaZoom(float fov) const;
00171 protected:
00172     virtual bool hasDiscontinuity() const {return false;}
00173     virtual bool intersectViewportDiscontinuityInternal(const Vec3d&, const Vec3d&) const {return false;}
00174     virtual bool intersectViewportDiscontinuityInternal(const Vec3d&, double) const {return false;}
00175 };
00176 
00177 class StelProjectorHammer : public StelProjector
00178 {
00179 public:
00180     StelProjectorHammer(const Mat4d& modelViewMat) : StelProjector(modelViewMat) {;}
00181     virtual QString getNameI18() const;
00182     virtual QString getDescriptionI18() const;
00183     virtual float getMaxFov() const {return 360.f;}
00184     virtual void project(int n, const Vec3d* in, Vec3f* out)
00185     {
00186         Vec3d v;
00187         for (int i = 0; i < n; ++i)
00188         {
00189             v = in[i];
00190             v.transfo4d(modelViewMatrix);
00191             out[i].set(v[0], v[1], v[2]);
00192             StelProjectorHammer::forward(out[i]);
00193             out[i][0] = viewportCenter[0] + flipHorz * pixelPerRad * out[i][0];
00194             out[i][1] = viewportCenter[1] + flipVert * pixelPerRad * out[i][1];
00195             out[i][2] = (out[i][2] - zNear) * oneOverZNearMinusZFar;
00196         }
00197     }
00198     bool forward(Vec3f &v) const
00199     {
00200         // Hammer Aitoff
00201         const float r = std::sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
00202         const float alpha = std::atan2(v[0],-v[2]);
00203         const float cosDelta = std::sqrt(1.f-v[1]*v[1]/(r*r));
00204         float z = std::sqrt(1.+cosDelta*std::cos(alpha/2.f));
00205         v[0] = 2.f*M_SQRT2*cosDelta*std::sin(alpha/2.f)/z;
00206         v[1] = M_SQRT2*v[1]/r/z;
00207         v[2] = r;
00208         return true;
00209     }
00210     bool backward(Vec3d &v) const;
00211     float fovToViewScalingFactor(float fov) const;
00212     float viewScalingFactorToFov(float vsf) const;
00213     float deltaZoom(float fov) const;
00214 protected:
00215     virtual bool hasDiscontinuity() const {return true;}
00216     virtual bool intersectViewportDiscontinuityInternal(const Vec3d& p1, const Vec3d& p2) const {return p1[0]*p2[0]<0 && !(p1[2]<0 && p2[2]<0);}
00217     virtual bool intersectViewportDiscontinuityInternal(const Vec3d& capN, double capD) const
00218     {
00219         static const SphericalCap cap1(1,0,0);
00220         static const SphericalCap cap2(-1,0,0);
00221         static const SphericalCap cap3(0,0,-1);
00222         SphericalCap cap(capN, capD);
00223         return cap.intersects(cap1) && cap.intersects(cap2) && cap.intersects(cap2);
00224     }
00225 };
00226 
00227 class StelProjectorCylinder : public StelProjector
00228 {
00229 public:
00230     StelProjectorCylinder(const Mat4d& modelViewMat) : StelProjector(modelViewMat) {;}
00231     virtual QString getNameI18() const;
00232     virtual QString getDescriptionI18() const;
00233     virtual float getMaxFov() const {return 175.f * 4.f/3.f;} // assume aspect ration of 4/3 for getting a full 360 degree horizon
00234     bool forward(Vec3f &win) const;
00235     bool backward(Vec3d &v) const;
00236     float fovToViewScalingFactor(float fov) const;
00237     float viewScalingFactorToFov(float vsf) const;
00238     float deltaZoom(float fov) const;
00239 protected:
00240     virtual bool hasDiscontinuity() const {return true;}
00241     virtual bool intersectViewportDiscontinuityInternal(const Vec3d& p1, const Vec3d& p2) const
00242     {
00243         return p1[0]*p2[0]<0 && !(p1[2]<0 && p2[2]<0);
00244     }
00245     virtual bool intersectViewportDiscontinuityInternal(const Vec3d& capN, double capD) const
00246     {
00247         static const SphericalCap cap1(1,0,0);
00248         static const SphericalCap cap2(-1,0,0);
00249         static const SphericalCap cap3(0,0,-1);
00250         SphericalCap cap(capN, capD);
00251         return cap.intersects(cap1) && cap.intersects(cap2) && cap.intersects(cap2);
00252     }
00253 };
00254 
00255 class StelProjectorMercator : public StelProjector
00256 {
00257 public:
00258     StelProjectorMercator(const Mat4d& modelViewMat) : StelProjector(modelViewMat) {;}
00259     virtual QString getNameI18() const;
00260     virtual QString getDescriptionI18() const;
00261     virtual float getMaxFov() const {return 175.f * 4.f/3.f;} // assume aspect ration of 4/3 for getting a full 360 degree horizon
00262     bool forward(Vec3f &win) const;
00263     bool backward(Vec3d &v) const;
00264     float fovToViewScalingFactor(float fov) const;
00265     float viewScalingFactorToFov(float vsf) const;
00266     float deltaZoom(float fov) const;
00267 protected:
00268     virtual bool hasDiscontinuity() const {return true;}
00269     virtual bool intersectViewportDiscontinuityInternal(const Vec3d& p1, const Vec3d& p2) const
00270     {
00271         return p1[0]*p2[0]<0 && !(p1[2]<0 && p2[2]<0);
00272     }
00273     virtual bool intersectViewportDiscontinuityInternal(const Vec3d& capN, double capD) const
00274     {
00275         static const SphericalCap cap1(1,0,0);
00276         static const SphericalCap cap2(-1,0,0);
00277         static const SphericalCap cap3(0,0,-1);
00278         SphericalCap cap(capN, capD);
00279         return cap.intersects(cap1) && cap.intersects(cap2) && cap.intersects(cap2);
00280     }
00281 };
00282 
00283 class StelProjectorOrthographic : public StelProjector
00284 {
00285 public:
00286     StelProjectorOrthographic(const Mat4d& modelViewMat) : StelProjector(modelViewMat) {;}
00287     virtual QString getNameI18() const;
00288     virtual QString getDescriptionI18() const;
00289     virtual float getMaxFov() const {return 179.9999f;}
00290     bool forward(Vec3f &win) const;
00291     bool backward(Vec3d &v) const;
00292     float fovToViewScalingFactor(float fov) const;
00293     float viewScalingFactorToFov(float vsf) const;
00294     float deltaZoom(float fov) const;
00295 protected:
00296     virtual bool hasDiscontinuity() const {return false;}
00297     virtual bool intersectViewportDiscontinuityInternal(const Vec3d&, const Vec3d&) const {return false;}
00298     virtual bool intersectViewportDiscontinuityInternal(const Vec3d&, double) const {return false;}
00299 };
00300 
00301 class StelProjector2d : public StelProjector
00302 {
00303 public:
00304     StelProjector2d() : StelProjector(Mat4d::identity()) {;}
00305     virtual QString getNameI18() const;
00306     virtual QString getDescriptionI18() const;
00307     virtual float getMaxFov() const {return 360.f;}
00308     bool forward(Vec3f &win) const;
00309     bool backward(Vec3d &v) const;
00310     float fovToViewScalingFactor(float fov) const;
00311     float viewScalingFactorToFov(float vsf) const;
00312     float deltaZoom(float fov) const;
00313 protected:
00314     virtual bool hasDiscontinuity() const {return false;}
00315     virtual bool intersectViewportDiscontinuityInternal(const Vec3d&, const Vec3d&) const {Q_ASSERT(0); return false;}
00316     virtual bool intersectViewportDiscontinuityInternal(const Vec3d&, double) const {Q_ASSERT(0); return false;}
00317     virtual void computeBoundingCap() {;}
00318 };
00319 
00320 #endif // _STELPROJECTIONS_HPP_
00321