32 #include <QTextStream> 60 public std::unary_function<double, double > {
65 m_surfacePoint = surPt;
81 double lookC[3] = {0.0, 0.0, 0.0};
88 double startTime = m_camera->cacheStartTime().Et();
89 double endTime = m_camera->cacheEndTime().Et();
90 if (et < startTime || et > endTime) {
91 IString msg =
"Ephemeris time passed to LineOffsetFunctor is not within the image " 96 m_camera->Sensor::setTime(et);
99 if (!m_camera->Sensor::SetGround(m_surfacePoint,
false)) {
100 IString msg =
"Sensor::SetGround failed for surface point in LineScanCameraGroundMap.cpp" 101 " LineOffsetFunctor";
106 m_camera->Sensor::LookDirection(lookC);
107 ux = m_camera->FocalLength() * lookC[0] / lookC[2];
108 uy = m_camera->FocalLength() * lookC[1] / lookC[2];
131 if (m_camera->DistortionMap()->SetUndistortedFocalPlane(ux, uy)) {
133 dx = m_camera->DistortionMap()->FocalPlaneX();
134 dy = m_camera->DistortionMap()->FocalPlaneY();
141 if (!m_camera->FocalPlaneMap()->SetFocalPlane(dx, dy)) {
142 IString msg =
"FocalPlaneMap::SetFocalPlane failed for surface point in " 143 "LineScanCameraGroundMap.cpp LineOffsetFunctor";
148 return (m_camera->FocalPlaneMap()->DetectorLineOffset() -
149 m_camera->FocalPlaneMap()->DetectorLine());
165 public std::unary_function<double, double > {
170 surfacePoint = surPt;
177 double operator()(
double et) {
181 double startTime = m_camera->cacheStartTime().Et();
182 double endTime = m_camera->cacheEndTime().Et();
184 if (et < startTime || et > endTime) {
185 IString msg =
"Ephemeris time passed to SensorSurfacePointDistanceFunctor is not within the image " 189 m_camera->Sensor::setTime(et);
190 if (!m_camera->Sensor::SetGround(surfacePoint,
false)) {
191 IString msg =
"Sensor::SetGround failed for surface point in LineScanCameraGroundMap.cpp" 192 "SensorSurfacePointDistanceFunctor";
194 m_camera->instrumentPosition(s);
195 m_camera->Coordinate(p);
196 return sqrt((s[0] - p[0]) * (s[0] - p[0]) +
197 (s[1] - p[1]) * (s[1] - p[1]) +
198 (s[2] - p[2]) * (s[2] - p[2]) );
232 if (radius.isValid()) {
250 FindFocalPlaneStatus status = FindFocalPlane(approxLine, surfacePoint);
251 if (status == Success)
return true;
264 FindFocalPlaneStatus status = FindFocalPlane(-1, surfacePoint);
266 if (status == Success)
return true;
272 double LineScanCameraGroundMap::FindSpacecraftDistance(
int line,
277 if (!
p_camera->Sensor::SetGround(surfacePoint,
false)) {
285 LineScanCameraGroundMap::FindFocalPlaneStatus
286 LineScanCameraGroundMap::FindFocalPlane(
const int &approxLine,
292 double approxTime = 0;
293 double approxOffset = 0;
294 double lookC[3] = {0.0, 0.0, 0.0};
299 const double cacheStart =
p_camera->Spice::cacheStartTime().Et();
300 const double cacheEnd =
p_camera->Spice::cacheEndTime().Et();
304 if (lineRate == 0.0)
return Failure;
311 if (approxLine >= 0.5) {
317 approxOffset = offsetFunc(approxTime);
320 if (fabs(approxOffset) < 1e-2) {
321 p_camera->Sensor::setTime(approxTime);
323 if (!
p_camera->Sensor::SetGround(surfacePoint,
true)) {
326 p_camera->Sensor::LookDirection(lookC);
336 double fl, fh, xl, xh;
340 if (xh + lineRate < cacheEnd) {
352 for (
int j=0; j < 10; j++) {
356 double etGuess = xl + (xh - xl) * fl / (fl - fh);
358 if (etGuess < cacheStart) etGuess = cacheStart;
359 if (etGuess > cacheEnd) etGuess = cacheEnd;
361 double f = offsetFunc(etGuess);
365 if (fabs( xl- etGuess) > fabs( xh - etGuess)) {
375 if (fabs(f) < 1e-2) {
376 p_camera->Sensor::setTime(approxTime);
378 if (!
p_camera->Sensor::SetGround(surfacePoint,
true)) {
381 p_camera->Sensor::LookDirection(lookC);
401 double offsetNodes[3];
409 timeNodes[0] = cacheStart;
410 timeNodes[2] = cacheEnd;
411 timeNodes[1] = (cacheStart+cacheEnd) / 2.0;
416 for (
int i=0; i<3; i++) {
417 offsetNodes[i] = offsetFunc(timeNodes[i]);
421 timeAverage = (timeNodes[0] + timeNodes[1] + timeNodes[2]) / 3.0;
422 timeNodes[0] -= timeAverage;
423 timeNodes[1] -= timeAverage;
424 timeNodes[2] -= timeAverage;
426 scale = 1.0 / sqrt((timeNodes[0] - timeNodes[2]) *
427 (timeNodes[0] - timeNodes[2]) +
428 (offsetNodes[0] - offsetNodes[2]) *
429 (offsetNodes[0] - offsetNodes[2]));
431 timeNodes[0] *= scale;
432 timeNodes[1] *= scale;
433 timeNodes[2] *= scale;
435 offsetNodes[0] *= scale;
436 offsetNodes[1] *= scale;
437 offsetNodes[2] *= scale;
442 quadPoly[0] = quadPoly[1] = quadPoly[2] = 0.0;
444 temp = offsetNodes[0] / ((timeNodes[0] - timeNodes[1]) * (timeNodes[0] - timeNodes[2]));
446 quadPoly[1] += temp * (-timeNodes[1] - timeNodes[2]);
447 quadPoly[2] += temp * timeNodes[1] * timeNodes[2];
449 temp = offsetNodes[1] / ((timeNodes[1] - timeNodes[0]) * (timeNodes[1] - timeNodes[2]));
451 quadPoly[1] += temp * (-timeNodes[0] - timeNodes[2]);
452 quadPoly[2] += temp * timeNodes[0] * timeNodes[2];
454 temp = offsetNodes[2] / ((timeNodes[2] - timeNodes[0]) * (timeNodes[2] - timeNodes[1]));
456 quadPoly[1] += temp * (-timeNodes[0] - timeNodes[1]);
457 quadPoly[2] += temp * timeNodes[0] * timeNodes[1];
461 temp = quadPoly[1] * quadPoly[1] - 4.0 * quadPoly[0] * quadPoly[2];
468 if (quadPoly[1] >= 0.0) {
469 temp = -0.5 * (quadPoly[1] + sqrt(temp));
472 temp = -0.5 * (quadPoly[1] - sqrt(temp));
475 if (quadPoly[0] != 0.0) {
476 root.push_back(temp/quadPoly[0]);
479 if (quadPoly[2] != 0.0) {
480 root.push_back(quadPoly[2]/temp);
484 for (
int i=root.size()-1; i>=0; i--) {
485 if ( root[i] < timeNodes[0] || root[i] > timeNodes[2] ) {
491 for (
int i=0; i<root.size(); i++) {
492 root[i] = root[i]/scale + timeAverage;
496 if (root.size() == 0) {
506 for (
int i=0; i<root.size(); i++) {
507 dist << distanceFunc(root[i]);
508 offset << offsetFunc(root[i]);
514 for (
int i=1; i<root.size(); i++) {
515 if (dist[i] < dist[j]) j=i;
518 approxTime = root[j];
519 approxOffset = offset[j];
522 if (fabs(approxOffset) < 1.0e-2) {
523 p_camera->Sensor::setTime(approxTime);
526 if (!
p_camera->Sensor::SetGround(surfacePoint,
true)) {
530 p_camera->Sensor::LookDirection(lookC);
559 for (
int i=0; i<3; i++) {
561 pt << timeNodes[i] / scale + timeAverage;
562 pt << offsetNodes[i] / scale;
566 for (
int i=0; i<root.size(); i++) {
573 qSort(pts.begin(), pts.end(), ptXLessThan);
576 for (
int i=1; i<pts.size(); i++) {
578 if ( (pts[i-1][1] > 0) - (pts[i-1][1] < 0) != (pts[i][1] > 0) - (pts[i][1] < 0) ) {
580 if (FunctionTools::brentsRootFinder <LineOffsetFunctor> (offsetFunc, pts[i-1], pts[i],
581 1.0e-3, 200, temp)) {
588 for (
int i = root.size()-1; i>=0; i--) {
591 if (!
p_camera->Sensor::SetGround(surfacePoint,
true)) {
597 if (root.size() == 0) {
604 for (
int i=0; i<root.size(); i++) {
605 dist << distanceFunc(root[i]);
606 offset << offsetFunc(root[i]);
612 for (
int i=1; i<root.size(); i++) {
613 if (dist[i] < dist[j]) j=i;
620 p_camera->Sensor::LookDirection(lookC);
633 return l1[0] < l2[0];
This class defines a body-fixed surface point.
CameraDetectorMap * DetectorMap()
Returns a pointer to the CameraDetectorMap object.
virtual bool SetParent(const double sample, const double line)
Compute detector position from a parent image coordinate.
double p_focalPlaneY
Camera's y focal plane coordinate.
double operator()(double et)
Compute the number of lines between the current line (i.e., the line imaged at the et as set in the c...
double p_focalPlaneX
Camera's x focal plane coordinate.
Namespace for the standard library.
This class is designed to encapsulate the concept of a Latitude.
double SlantDistance() const
Return the distance between the spacecraft and surface point in kmv.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
Distance measurement, usually in meters.
Distance LocalRadius() const
Returns the local radius at the intersection point.
virtual bool SetGround(const Latitude &lat, const Longitude &lon)
Compute undistorted focal plane coordinate from ground position.
Convert between parent image coordinates and detector coordinates.
This class is designed to encapsulate the concept of a Longitude.
Convert between undistorted focal plane and ground coordinates.
#define _FILEINFO_
Macro for the filename and line number.
double FocalLength() const
Returns the focal length.
int ParentSamples() const
Returns the number of samples in the parent alphacube.
virtual ~LineScanCameraGroundMap()
Destructor.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
Adds specific functionality to C++ strings.
Namespace for ISIS/Bullet specific routines.
Convert between parent image coordinates and detector coordinates.
double Et() const
Returns the ephemeris time (TDB) representation of the time as a double.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
iTime time() const
Returns the ephemeris time in seconds which was used to obtain the spacecraft and sun positions...