USGS

Isis 3.0 Object Programmers' Reference

Home

CameraGroundMap.cpp

Go to the documentation of this file.
00001 
00023 #include "CameraGroundMap.h"
00024 
00025 #include <iostream>
00026 
00027 #include "NaifStatus.h"
00028 #include "SurfacePoint.h"
00029 #include "Latitude.h"
00030 #include "Longitude.h"
00031 
00032 using namespace std;
00033 
00034 namespace Isis {
00035   CameraGroundMap::CameraGroundMap(Camera *parent) {
00036     p_camera = parent;
00037     p_camera->SetGroundMap(this);
00038   }
00039 
00052   bool CameraGroundMap::SetFocalPlane(const double ux, const double uy,
00053                                       double uz) {
00054     NaifStatus::CheckErrors();
00055 
00056     SpiceDouble lookC[3];
00057     lookC[0] = ux;
00058     lookC[1] = uy;
00059     lookC[2] = uz;
00060 
00061     SpiceDouble unitLookC[3];
00062     vhat_c(lookC, unitLookC);
00063 
00064     NaifStatus::CheckErrors();
00065 
00066     bool result = p_camera->SetLookDirection(unitLookC);
00067     return result;
00068   }
00069 
00077   bool CameraGroundMap::SetGround(const Latitude &lat, const Longitude &lon) {
00078     Distance radius(p_camera->LocalRadius(lat, lon));
00079     if (radius.Valid()) {
00080       if(p_camera->Sensor::SetGround(SurfacePoint(lat, lon, radius))) {
00081         LookCtoFocalPlaneXY();
00082         return true;
00083       }
00084     }
00085 
00086     return false;
00087   }
00088 
00090   void CameraGroundMap::LookCtoFocalPlaneXY() {
00091     double lookC[3];
00092     p_camera->Sensor::LookDirection(lookC);
00093     double scale = p_camera->FocalLength() / lookC[2];
00094     p_focalPlaneX = lookC[0] * scale;
00095     p_focalPlaneY = lookC[1] * scale;
00096   }
00097 
00106   bool CameraGroundMap::SetGround(const SurfacePoint &surfacePoint) {
00107     if(p_camera->Sensor::SetGround(surfacePoint)) {
00108       LookCtoFocalPlaneXY();
00109       return true;
00110     }
00111 
00112     return false;
00113   }
00114 
00115 
00127   bool CameraGroundMap::GetXY(const SurfacePoint &point, double *cudx, double *cudy) {
00128 
00129     double pB[3];
00130     pB[0] = point.GetX().GetKilometers();
00131     pB[1] = point.GetY().GetKilometers();
00132     pB[2] = point.GetZ().GetKilometers();
00133 
00134     // Check for Sky images
00135     if(p_camera->IsSky()) {
00136       return false;
00137     }
00138 
00139     // Should a check be added to make sure SetImage has been called???
00140 
00141     // Compute the look vector in body-fixed coordinates
00142 //    double pB[3]; // Point on surface
00143 //    latrec_c(radius / 1000.0, lon * Isis::PI / 180.0, lat * Isis::PI / 180.0, pB);
00144 
00145     // Get spacecraft vector in body-fixed coordinates
00146     SpiceRotation *bodyRot = p_camera->BodyRotation();
00147     SpiceRotation *instRot = p_camera->InstrumentRotation();
00148     std::vector<double> sB = bodyRot->ReferenceVector(p_camera->InstrumentPosition()->Coordinate());
00149     std::vector<double> lookB(3);
00150     for(int ic = 0; ic < 3; ic++)   lookB[ic] = pB[ic] - sB[ic];
00151 
00152     // Check for point on back of planet by checking to see if surface point is viewable (test emission angle)
00153     // During iterations, we may not want to do the back of planet test???
00154     double upsB[3], upB[3], dist;
00155     vminus_c((SpiceDouble *) &lookB[0], upsB);
00156     unorm_c(upsB, upsB, &dist);
00157     unorm_c(pB, upB, &dist);
00158     double angle = vdot_c(upB, upsB);
00159     double emission;
00160     if(angle > 1) {
00161       emission = 0;
00162     }
00163     else if(angle < -1) {
00164       emission = 180.;
00165     }
00166     else {
00167       emission = acos(angle) * 180.0 / Isis::PI;
00168     }
00169     if(fabs(emission) > 90.) return false;
00170 
00171     // Get the look vector in the camera frame and the instrument rotation
00172     p_lookJ.resize(3);
00173     p_lookJ = p_camera->BodyRotation()->J2000Vector(lookB);
00174     std::vector <double> lookC(3);
00175     lookC = instRot->ReferenceVector(p_lookJ);
00176 
00177     // Get focal length with direction for scaling coordinates
00178     double fl = p_camera->DistortionMap()->UndistortedFocalPlaneZ();
00179 
00180     *cudx = lookC[0] * fl / lookC[2];
00181     *cudy = lookC[1] * fl / lookC[2];
00182     return true;
00183   }
00184 
00185 
00186 
00187 
00201   bool CameraGroundMap::GetXY(const double lat, const double lon,
00202                               const double radius, double *cudx, double *cudy) {
00203     SurfacePoint spoint(Latitude(lat, Angle::Degrees),
00204                     Longitude(lon, Angle::Degrees),
00205                     Distance(radius, Distance::Meters));
00206     return GetXY(spoint, cudx, cudy);
00207   }
00208 
00209 
00223   //  also have a GetDxyDorientation and a GetDxyDpoint
00224   bool CameraGroundMap::GetdXYdPosition(const SpicePosition::PartialType varType, int coefIndex,
00225                                         double *dx, double *dy) {
00226 
00227     //  TODO  add a check to make sure p_lookJ has been set
00228 
00229     // Get directional fl for scaling coordinates
00230     double fl = p_camera->DistortionMap()->UndistortedFocalPlaneZ();
00231 
00232     // Rotate look vector into camera frame
00233     SpiceRotation *instRot = p_camera->InstrumentRotation();
00234     std::vector <double> lookC(3);
00235     lookC = instRot->ReferenceVector(p_lookJ);
00236 
00237     SpicePosition *instPos = p_camera->InstrumentPosition();
00238 
00239     std::vector<double> d_lookJ = instPos->CoordinatePartial(varType, coefIndex);
00240     for(int j = 0; j < 3; j++) d_lookJ[j] *= -1.0;
00241     std::vector<double> d_lookC =  instRot->ReferenceVector(d_lookJ);
00242     *dx = fl * DQuotient(lookC, d_lookC, 0);
00243     *dy = fl * DQuotient(lookC, d_lookC, 1);
00244     return true;
00245   }
00246 
00260   //  also have a GetDxyDorientation and a GetDxyDpoint
00261   bool CameraGroundMap::GetdXYdOrientation(const SpiceRotation::PartialType varType, int coefIndex,
00262       double *dx, double *dy) {
00263 
00264     //  TODO  add a check to make sure p_lookJ has been set
00265 
00266     // Get directional fl for scaling coordinates
00267     double fl = p_camera->DistortionMap()->UndistortedFocalPlaneZ();
00268 
00269     // Rotate look vector into camera frame
00270     SpiceRotation *instRot = p_camera->InstrumentRotation();
00271     std::vector <double> lookC(3);
00272     lookC = instRot->ReferenceVector(p_lookJ);
00273 
00274     std::vector<double> d_lookC = instRot->ToReferencePartial(p_lookJ, varType, coefIndex);
00275     *dx = fl * DQuotient(lookC, d_lookC, 0);
00276     *dy = fl * DQuotient(lookC, d_lookC, 1);
00277     return true;
00278   }
00279 
00293   bool CameraGroundMap::GetdXYdPoint(std::vector<double> d_lookB, double *dx, double *dy) {
00294 
00295     //  TODO  add a check to make sure p_lookJ has been set
00296 
00297     // Get directional fl for scaling coordinates
00298     double fl = p_camera->DistortionMap()->UndistortedFocalPlaneZ();
00299 
00300     // Rotate look vector into camera frame
00301     SpiceRotation *instRot = p_camera->InstrumentRotation();
00302     std::vector <double> lookC(3);
00303     lookC = instRot->ReferenceVector(p_lookJ);
00304 
00305     SpiceRotation *bodyRot = p_camera->BodyRotation();
00306     std::vector<double> d_lookJ = bodyRot->J2000Vector(d_lookB);
00307     std::vector<double> d_lookC = instRot->ReferenceVector(d_lookJ);
00308 
00309     *dx = fl * DQuotient(lookC, d_lookC, 0);
00310     *dy = fl * DQuotient(lookC, d_lookC, 1);
00311     return true;
00312   }
00313 
00314 
00324   std::vector<double> CameraGroundMap::PointPartial(SurfacePoint spoint, PartialType wrt) {
00325     double rlat = spoint.GetLatitude().GetRadians();
00326     double rlon = spoint.GetLongitude().GetRadians();
00327     double sinLon = sin(rlon);
00328     double cosLon = cos(rlon);
00329     double sinLat = sin(rlat);
00330     double cosLat = cos(rlat);
00331     double radkm = spoint.GetLocalRadius().GetKilometers();
00332 
00333     std::vector<double> v(3);
00334     if(wrt == WRT_Latitude) {
00335       v[0] = -radkm * sinLat * cosLon;
00336       v[1] = -radkm * sinLon * sinLat;
00337       v[2] =  radkm * cosLat;
00338     }
00339     else if(wrt == WRT_Longitude) {
00340       v[0] = -radkm * cosLat * sinLon;
00341       v[1] =  radkm * cosLat * cosLon;
00342       v[2] =  0.0;
00343     }
00344     else {
00345       v[0] = cosLon * cosLat;
00346       v[1] = sinLon * cosLat;
00347       v[2] = sinLat;
00348     }
00349 
00350     return v;
00351   }
00352 
00353 
00366   double CameraGroundMap::DQuotient(std::vector<double> &look,
00367                                     std::vector<double> &dlook,
00368                                     int index) {
00369     return (look[2] * dlook[index] - look[index] * dlook[2]) /
00370            (look[2] * look[2]);
00371   }
00372 }