|
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 #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 }