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