|
Isis 3.0 Object Programmers' Reference |
Home |
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 }