Isis 3 Programmer Reference
VimsGroundMap.cpp
1 
7 /* SPDX-License-Identifier: CC0-1.0 */
8 
9 #include "VimsGroundMap.h"
10 
11 #include <iostream>
12 #include <iomanip>
13 
14 #include <QDebug>
15 #include <QVector>
16 
17 #include "BasisFunction.h"
18 #include "Camera.h"
19 #include "Constants.h"
20 #include "Distance.h"
21 #include "FileName.h"
22 #include "IException.h"
23 #include "IString.h"
24 #include "iTime.h"
25 #include "Latitude.h"
26 #include "LeastSquares.h"
27 #include "Longitude.h"
28 #include "PolynomialBivariate.h"
29 #include "Preference.h"
30 #include "SpecialPixel.h"
31 #include "Target.h"
32 
33 using namespace std;
34 
35 namespace Isis {
42  VimsGroundMap::VimsGroundMap(Camera *parent, Pvl &lab) :
43  CameraGroundMap(parent) {
44 
45  p_minX = DBL_MAX;
46  p_maxX = -DBL_MAX;
47  p_minY = DBL_MAX;
48  p_maxY = -DBL_MAX;
49  p_minZ = DBL_MAX;
50  p_maxZ = -DBL_MAX;
51 
52  if (parent->ParentSamples() > 64 || parent->ParentLines() > 64) {
53  IString msg = "The Vims ground map does not understand cubes that "
54  "initially have more than 64 lines or 64 samples.";
55  throw IException(IException::Programmer, msg, _FILEINFO_);
56  }
57  }
58 
59 
60 
65 
66  }
67 
68 
69 
117 
118  PvlGroup inst = lab.findGroup("Instrument", Pvl::Traverse);
119 
120  // Vis or IR
121  p_channel = (QString) inst ["Channel"];
122  // Get the start time in et
123  QString stime = (QString) inst ["NativeStartTime"];
124  QString intTime = stime.split(".").first();
125  stime = stime.split(".").last();
126 
127  p_etStart = p_camera->getClockTime(intTime).Et();
128  p_etStart += toDouble(stime) / 15959.0;
129  //----------------------------------------------------------------------
130  // Because of inaccuracy with the 15 Mhz clock, the IR exposure and
131  // interline delay need to be adjusted.
132  //----------------------------------------------------------------------
133  p_irExp = (toDouble(inst ["ExposureDuration"][0]) * 1.01725) / 1000.;
134  p_visExp = (toDouble(inst ["ExposureDuration"][1])) / 1000.;
135  p_interlineDelay = (toDouble(inst ["InterlineDelayDuration"]) * 1.01725) / 1000.;
136 
137  // Get summation mode
138  QString sampMode = QString((QString)inst ["SamplingMode"]).toUpper();
139 
140  // Get sample/line offsets
141  int sampOffset = inst ["XOffset"];
142  int lineOffset = inst ["ZOffset"];
143 
144  // Get swath width/length which will be image size unless occultation image
145  p_swathWidth = inst ["SwathWidth"];
146  p_swathLength = inst ["SwathLength"];
147 
148  if (p_channel == "VIS") {
149  if (sampMode == "NORMAL") {
150  p_xPixSize = p_yPixSize = 0.00051;
151  p_xBore = p_yBore = 31;
152  p_camSampOffset = sampOffset - 1;
153  p_camLineOffset = lineOffset - 1;
154 
155  }
156  else if (sampMode == "HI-RES") {
157  p_xPixSize = p_yPixSize = 0.00051 / 3.0;
158  p_xBore = p_yBore = 94;
159  //New as of 2009-08-04 per Dyer Lytle's email
160  // Old Values:p_camSampOffset = 3 * (sampOffset - 1) + p_swathWidth;
161  // p_camLineOffset = 3 * (lineOffset - 1) + p_swathLength;
162  p_camSampOffset = (3 * (sampOffset + p_swathWidth / 2)) - p_swathWidth / 2;
163  p_camLineOffset = (3 * (lineOffset + p_swathLength / 2)) - p_swathLength / 2;
164  }
165  else {
166  string msg = "Unsupported SamplingMode [" + IString(sampMode) + "]";
167  throw IException(IException::Programmer, msg, _FILEINFO_);
168  }
169  }
170  else if (p_channel == "IR") {
171  if (sampMode == "NORMAL") {
172  p_xPixSize = p_yPixSize = 0.000495;
173  p_xBore = p_yBore = 31;
174  p_camSampOffset = sampOffset - 1;
175  p_camLineOffset = lineOffset - 1;
176  }
177  else if (sampMode == "HI-RES") {
178  p_xPixSize = 0.000495 / 2.0;
179  p_yPixSize = 0.000495;
180  p_xBore = 62.5;
181  p_yBore = 31;
182  p_camSampOffset = 2 * ((sampOffset - 1) + ((p_swathWidth - 1) / 4));
183  p_camLineOffset = lineOffset - 1;
184  }
185  else {
186  string msg = "Unsupported SamplingMode [" + IString(sampMode) + "]";
187  throw IException(IException::Programmer, msg, _FILEINFO_);
188  }
189  }
190 
191  //---------------------------------------------------------------------
192  // Loop for each pixel in cube, get pointing information and calculate
193  // control point (line, sample, x, y, z) for later use in latlon_to_linesamp.
194  //---------------------------------------------------------------------
195  p_camera->IgnoreProjection(true);
196  for (int line = 0; line < p_camera->ParentLines(); line++) {
197 
198  // VIS exposure is for a single line. According to SIS,
199  // NATIVE_START_TIME is for the first pixel of the IR exposure.
200  // "The offset from IR start to VIS start is calculated by
201  // IrExposMsec - VisExposMsec)/2".
202  // This needs to be moved to forward routine
203 
204  if (p_channel == "VIS") {
205  double et = ((double)p_etStart + (((p_irExp * p_swathWidth) - p_visExp) / 2.)) +
206  ((line + 0.5) * p_visExp);
207  p_camera->setTime(et);
208  }
209 
210  for (int samp = 0; samp < p_camera->ParentSamples(); samp++) {
211  if (p_channel == "IR") {
212  double et = (double)p_etStart +
213  (line * p_camera->ParentSamples() * p_irExp) +
214  (line * p_interlineDelay) + ((samp + 0.5) * p_irExp);
215  p_camera->setTime(et);
216  }
217 
218  if (p_camera->SetImage((double) samp + 1, (double)line + 1)) {
219 
220  double xyz[3];
221  p_camera->Coordinate(xyz);
222 
223  if (xyz[0] != Null && xyz[1] != Null && xyz[2] != Null) {
224  p_xyzMap[line][samp].setX(xyz[0]);
225  p_xyzMap[line][samp].setY(xyz[1]);
226  p_xyzMap[line][samp].setZ(xyz[2]);
227 
228 // if (samp !=0 ) {
229 // QVector3D deltaXyz = p_xyzMap[line][samp-1] - p_xyzMap[line][samp];
230 // qDebug()<<"samp:line = "<<samp<<" : "<<line<<" xyzMap[line][samp-1] = "<<p_xyzMap[line][samp-1]<<" xyzMap[line][samp] = "<<p_xyzMap[line][samp]<<" delta = "<<deltaXyz.length();
231 // }
232 
233  // Find min/max x,y,z for use in SetGround method to make sure incoming lat/lon falls
234  // within image.
235  if (xyz[0] < p_minX) p_minX = xyz[0];
236  if (xyz[0] > p_maxX) p_maxX = xyz[0];
237  if (xyz[1] < p_minY) p_minY = xyz[1];
238  if (xyz[1] > p_maxY) p_maxY = xyz[1];
239  if (xyz[2] < p_minZ) p_minZ = xyz[2];
240  if (xyz[2] > p_maxZ) p_maxZ = xyz[2];
241  }
242  }
243  }
244  }
245 
246  // Fine tune min/max Z so that if the pole is actually in the image, it will be found in
247  // the SetGround method. If the min/max values found for pixels centers is used, the pole
248  // will not be found even if it is actually in the image. if the min/max z values are within
249  // 1 km of the radius, set to the radius.
250 
251  // NOTE: IF THERE ARE PROBLEMS FOUND IN THE CAMERA MODEL, THIS WOULD BE THE FIRST PLACE
252  // I WOULD LOOK.
253  Distance radii[3];
254  p_camera->radii(radii);
255  if (abs(abs(p_minZ) - radii[2].kilometers()) < 1.0) {
256  p_minZ = radii[2].kilometers() * (int(abs(p_minZ) / p_minZ));
257  }
258  if (abs(abs(p_maxZ) - radii[2].kilometers()) < 1.0) {
259  p_maxZ = radii[2].kilometers() * (int(abs(p_maxZ) / p_maxZ));
260  }
261 
262  p_camera->IgnoreProjection(false);
263  }
264 
265 
287  bool VimsGroundMap::SetFocalPlane(const double ux, const double uy,
288  const double uz) {
289 
290  p_ux = ux;
291  p_uy = uy;
292  p_uz = uz;
293 
294  double imgSamp = ux;
295  double imgLine = uy;
296 
297  if ((imgLine < 0.5) || (imgLine > p_camera->ParentLines() + 0.5) ||
298  (imgSamp < 0.5) || (imgSamp > p_camera->ParentSamples() + 0.5)) {
299  return false;
300  }
301  imgLine--;
302  imgSamp--;
303 
304  // does interline_delay & exposure-duration account for summing modes?
305  // if not, won't use p_parentLine/p_parentSample
306  double et = 0.;
307  if (p_channel == "VIS") {
308  et = (p_etStart + ((p_irExp * p_swathWidth) - p_visExp) / 2.) +
309  ((imgLine + 0.5) * p_visExp);
310  }
311  else if (p_channel == "IR") {
312  et = (double)p_etStart +
313  (imgLine * p_camera->ParentSamples() * p_irExp) +
314  (imgLine * p_interlineDelay) + ((imgSamp + 0.5) * p_irExp);
315  }
316  p_camera->setTime(et);
317 
318  // get Look Direction
319  SpiceDouble lookC[3];
320  LookDirection(lookC);
321 
322  SpiceDouble unitLookC[3];
323  vhat_c(lookC, unitLookC);
324  return p_camera->SetLookDirection(unitLookC);
325  }
326 
327 
359  bool VimsGroundMap::SetGround(const Latitude &lat, const Longitude &lon) {
360 
361 
362  // Make sure at least 1 pixel in image has projected onto surface
363  if (p_minX == DBL_MAX || p_maxX == -DBL_MAX ||
364  p_minY == DBL_MAX || p_maxY == -DBL_MAX ||
365  p_minZ == DBL_MAX || p_maxZ == -DBL_MAX) return false;
366 
367  QVector3D xyz;
368  if (p_camera->target()->shape()->name() == "Plane") {
369  double radius = lat.degrees();
370  if(radius <= 0.0)
371  return false;
372 
373  double xCheck = radius * 0.001 * cos(lon.radians());
374  double yCheck = radius * 0.001 * sin(lon.radians());
375 
376  xyz.setX(xCheck);
377  xyz.setY(yCheck);
378  xyz.setZ(0.);
379  }
380  else {
381  // Convert lat/lon to x/y/z
382  Distance radius = p_camera->LocalRadius(lat, lon);
383  SpiceDouble pB[3];
384  latrec_c(radius.kilometers(), lon.radians(), lat.radians(), pB);
385 
386  // Make sure this point falls within range of image
387  if (pB[0] < p_minX || pB[0] > p_maxX ||
388  pB[1] < p_minY || pB[1] > p_maxY ||
389  pB[2] < p_minZ || pB[2] > p_maxZ) return false;
390 
391  xyz.setX(pB[0]);
392  xyz.setY(pB[1]);
393  xyz.setZ(pB[2]);
394  }
395 
396  double minDist = DBL_MAX;
397  int minSamp = -1;
398  int minLine = -1;
399 
400  // Find closest points ??? what tolerance ???
401  for (int line = 0; line < p_camera->ParentLines(); line++) {
402  for (int samp = 0; samp < p_camera->ParentSamples(); samp++) {
403 
404  if (p_xyzMap[line][samp].isNull()) continue;
405 
406  // Subtract map from coordinate then get length
407  QVector3D deltaXyz = xyz - p_xyzMap[line][samp];
408  if (deltaXyz.length() < minDist) {
409  minDist = deltaXyz.length();
410  minSamp = samp;
411  minLine = line;
412  }
413  }
414  }
415 
416  //-----------------------------------------------------------------
417  // If dist is less than some ??? tolerance ??? this is the
418  // closest point. Use this point and surrounding 8 pts as
419  // control pts.
420  //----------------------------------------------------------------
421  if (minDist >= DBL_MAX) return false;
422 
423  //-------------------------------------------------------------
424  // Set-up for LU decomposition (least2 fit).
425  // Assume we will have 9 control points, this may not be true
426  // and will need to be adjusted before the final solution.
427  //-------------------------------------------------------------
428  BasisFunction sampXyzBasis("Sample", 4, 4);
429  BasisFunction lineXyzBasis("Line", 4, 4);
430  LeastSquares sampXyzLsq(sampXyzBasis);
431  LeastSquares lineXyzLsq(lineXyzBasis);
432  vector<double> knownXyz(4);
433 
434  // Solve using x/y/z
435  for (int line = minLine - 1; line < minLine + 2; line++) {
436  if (line < 0 || line > p_camera->ParentLines() - 1) continue;
437  for (int samp = minSamp - 1; samp < minSamp + 2; samp++) {
438  // Check for edges
439  if (samp < 0 || samp > p_camera->ParentSamples() - 1) continue;
440  if (p_xyzMap[line][samp].isNull()) continue;
441 
442  knownXyz[0] = p_xyzMap[line][samp].x();
443  knownXyz[1] = p_xyzMap[line][samp].y();
444  knownXyz[2] = p_xyzMap[line][samp].z();
445  knownXyz[3] = 1;
446  sampXyzLsq.AddKnown(knownXyz, samp + 1);
447  lineXyzLsq.AddKnown(knownXyz, line + 1);
448  }
449  }
450 
451  if (sampXyzLsq.Knowns() < 4) return false;
452 
453  sampXyzLsq.Solve();
454  lineXyzLsq.Solve();
455 
456  // Solve for sample, line position corresponding to input lat, lon
457  knownXyz[0] = xyz.x();
458  knownXyz[1] = xyz.y();
459  knownXyz[2] = xyz.z();
460  knownXyz[3] = 1;
461  double inSamp = sampXyzLsq.Evaluate(knownXyz);
462  double inLine = lineXyzLsq.Evaluate(knownXyz);
463 
464 
465  if (inSamp < 0.5 || inSamp > p_camera->ParentSamples() + 0.5 ||
466  inLine < 0.5 || inLine > p_camera->ParentLines() + 0.5) {
467  return false;
468  }
469 
470  // Sanity check
471  p_camera->IgnoreProjection(true);
472  p_camera->SetImage(inSamp, inLine);
473  p_camera->IgnoreProjection(false);
474  if (!p_camera->HasSurfaceIntersection()) return false;
475 
476  p_focalPlaneX = inSamp;
477  p_focalPlaneY = inLine;
478 
479  return true;
480  }
481 
482 
492  bool VimsGroundMap::SetGround(const SurfacePoint &surfacePoint) {
493  return SetGround(surfacePoint.GetLatitude(), surfacePoint.GetLongitude());
494 // return SetGroundwithLatitudeLongitude(surfacePoint.GetLatitude(), surfacePoint.GetLongitude());
495  }
496 
497 
511  void VimsGroundMap::LookDirection(double v[3]) {
512 
513  double x = p_ux - 1. + p_camSampOffset;
514  double y = p_uy - 1. + p_camLineOffset;
515 
516  // Compute pointing angles based on pixel size separation
517  double theta = Isis::HALFPI - (y - p_yBore) * p_yPixSize;
518  double phi = (-1. * Isis::HALFPI) + (x - p_xBore) * p_xPixSize;
519 
520  v[0] = sin(theta) * cos(phi);
521  v[1] = cos(theta);
522  v[2] = sin(theta) * sin(phi) / -1.;
523  }
524 }
Isis::Distance::kilometers
double kilometers() const
Get the distance in kilometers.
Definition: Distance.cpp:106
Isis::Spice::radii
void radii(Distance r[3]) const
Returns the radii of the body in km.
Definition: Spice.cpp:930
Isis::VimsGroundMap::p_uy
double p_uy
Distorted focal plane y, in millimeters.
Definition: VimsGroundMap.h:102
Isis::Camera::IgnoreProjection
void IgnoreProjection(bool ignore)
Set whether or not the camera should ignore the Projection.
Definition: Camera.cpp:2925
Isis::HALFPI
const double HALFPI
The mathematical constant PI/2.
Definition: Constants.h:41
Isis::Target::shape
ShapeModel * shape() const
Return the shape.
Definition: Target.cpp:655
Isis::PvlObject::findGroup
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:129
Isis::LeastSquares::Solve
int Solve(Isis::LeastSquares::SolveMethod method=SVD)
After all the data has been registered through AddKnown, invoke this method to solve the system of eq...
Definition: LeastSquares.cpp:205
Isis::CameraGroundMap::p_focalPlaneY
double p_focalPlaneY
Camera's y focal plane coordinate.
Definition: CameraGroundMap.h:136
Isis::VimsGroundMap::p_irExp
double p_irExp
IR exposure duration, divided by 1000.
Definition: VimsGroundMap.h:113
Isis::Camera::ParentLines
int ParentLines() const
Returns the number of lines in the parent alphacube.
Definition: Camera.cpp:2806
Isis::VimsGroundMap::SetGround
virtual bool SetGround(const Latitude &lat, const Longitude &lon)
Compute undistorted focal plane coordinate from ground position.
Definition: VimsGroundMap.cpp:359
Isis::Latitude
This class is designed to encapsulate the concept of a Latitude.
Definition: Latitude.h:51
Isis::Sensor::HasSurfaceIntersection
bool HasSurfaceIntersection() const
Returns if the last call to either SetLookDirection or SetUniversalGround had a valid intersection wi...
Definition: Sensor.cpp:186
Isis::VimsGroundMap::p_camLineOffset
int p_camLineOffset
Line offset.
Definition: VimsGroundMap.h:119
Isis::Camera::SetImage
virtual bool SetImage(const double sample, const double line)
Sets the sample/line values of the image to get the lat/lon values.
Definition: Camera.cpp:154
Isis::LeastSquares::Knowns
int Knowns() const
The number of knowns (or times AddKnown was invoked) linear combination of the variables.
Definition: LeastSquares.h:129
Isis::VimsGroundMap::SetFocalPlane
virtual bool SetFocalPlane(const double ux, const double uy, const double uz)
Compute ground position from focal plane coordinate.
Definition: VimsGroundMap.cpp:287
Isis::BasisFunction
Generic linear equation class.
Definition: BasisFunction.h:48
Isis::VimsGroundMap::p_etStart
SpiceDouble p_etStart
Start ephemeris time.
Definition: VimsGroundMap.h:96
Isis::Spice::getClockTime
virtual iTime getClockTime(QString clockValue, int sclkCode=-1, bool clockTicks=false)
This converts the spacecraft clock ticks value (clockValue) to an iTime.
Definition: Spice.cpp:1053
Isis::VimsGroundMap::p_swathLength
int p_swathLength
SwathLength keyword value from the instrument group of the labels.
Definition: VimsGroundMap.h:116
Isis::VimsGroundMap::p_yPixSize
double p_yPixSize
Y pixel size.
Definition: VimsGroundMap.h:106
Isis::ShapeModel::name
QString name() const
Gets the shape name.
Definition: ShapeModel.cpp:543
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::SurfacePoint::GetLatitude
Latitude GetLatitude() const
Return the body-fixed latitude for the surface point.
Definition: SurfacePoint.cpp:1665
Isis::LeastSquares::Evaluate
double Evaluate(const std::vector< double > &input)
Invokes the BasisFunction Evaluate method.
Definition: LeastSquares.cpp:553
Isis::Camera
Definition: Camera.h:236
Isis::VimsGroundMap::Init
void Init(Pvl &lab)
Initialize vims camera model.
Definition: VimsGroundMap.cpp:116
Isis::CameraGroundMap::p_focalPlaneX
double p_focalPlaneX
Camera's x focal plane coordinate.
Definition: CameraGroundMap.h:135
Isis::VimsGroundMap::~VimsGroundMap
virtual ~VimsGroundMap()
Destroys the VimsGroundMap object.
Definition: VimsGroundMap.cpp:64
Isis::Distance
Distance measurement, usually in meters.
Definition: Distance.h:34
Isis::Longitude
This class is designed to encapsulate the concept of a Longitude.
Definition: Longitude.h:40
Isis::CameraGroundMap
Convert between undistorted focal plane and ground coordinates.
Definition: CameraGroundMap.h:73
Isis::Spice::target
virtual Target * target() const
Returns a pointer to the target object.
Definition: Spice.cpp:1368
Isis::PvlObject::Traverse
@ Traverse
Search child objects.
Definition: PvlObject.h:158
Isis::Camera::ParentSamples
int ParentSamples() const
Returns the number of samples in the parent alphacube.
Definition: Camera.cpp:2816
Isis::Sensor::setTime
void setTime(const iTime &time)
By setting the time you essential set the position of the spacecraft and body as indicated in the cla...
Definition: Sensor.cpp:97
Isis::iTime::Et
double Et() const
Returns the ephemeris time (TDB) representation of the time as a double.
Definition: iTime.h:126
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::LeastSquares
Generic least square fitting class.
Definition: LeastSquares.h:99
Isis::VimsGroundMap::p_visExp
double p_visExp
VIS exposure duration, divided by 1000.
Definition: VimsGroundMap.h:112
Isis::VimsGroundMap::p_swathWidth
int p_swathWidth
SwathWidth keyword value from the instrument group of the labels.
Definition: VimsGroundMap.h:114
Isis::VimsGroundMap::p_interlineDelay
double p_interlineDelay
InterlineDelayDuration keyword value from the instrument group of the labels, divided by 1000.
Definition: VimsGroundMap.h:98
Isis::CameraGroundMap::p_camera
Camera * p_camera
Camera.
Definition: CameraGroundMap.h:131
Isis::VimsGroundMap::p_xPixSize
double p_xPixSize
X pixel size.
Definition: VimsGroundMap.h:105
Isis::VimsGroundMap::p_uz
double p_uz
Distorted focal plane z, in millimeters.
Definition: VimsGroundMap.h:103
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::VimsGroundMap::LookDirection
void LookDirection(double v[3])
Determines the look direction in the camera coordinate system.
Definition: VimsGroundMap.cpp:511
Isis::SurfacePoint::GetLongitude
Longitude GetLongitude() const
Return the body-fixed longitude for the surface point.
Definition: SurfacePoint.cpp:1685
Isis::Null
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:95
Isis::VimsGroundMap::p_xBore
double p_xBore
X boresight.
Definition: VimsGroundMap.h:107
Isis::toDouble
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition: IString.cpp:149
Isis::IException::Programmer
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:146
std
Namespace for the standard library.
Isis::Sensor::SetLookDirection
bool SetLookDirection(const double v[3])
Sets the look direction of the spacecraft.
Definition: Sensor.cpp:141
Isis::VimsGroundMap::p_channel
QString p_channel
Channel keyword value from the instrument group of the labels.
Definition: VimsGroundMap.h:110
Isis::Angle::degrees
double degrees() const
Get the angle in units of Degrees.
Definition: Angle.h:232
Isis::VimsGroundMap::p_yBore
double p_yBore
Y boresight.
Definition: VimsGroundMap.h:108
Isis::Sensor::Coordinate
void Coordinate(double p[3]) const
Returns the x,y,z of the surface intersection in BodyFixed km.
Definition: Sensor.cpp:196
Isis::IString
Adds specific functionality to C++ strings.
Definition: IString.h:165
Isis::LeastSquares::AddKnown
void AddKnown(const std::vector< double > &input, double expected, double weight=1.0)
Invoke this method for each set of knowns.
Definition: LeastSquares.cpp:96
Isis::VimsGroundMap::p_ux
double p_ux
Distorted focal plane x, in millimeters.
Definition: VimsGroundMap.h:101
Isis::VimsGroundMap::p_camSampOffset
int p_camSampOffset
Sample offset.
Definition: VimsGroundMap.h:118
Isis::SurfacePoint
This class defines a body-fixed surface point.
Definition: SurfacePoint.h:132
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::Sensor::LocalRadius
Distance LocalRadius() const
Returns the local radius at the intersection point.
Definition: Sensor.cpp:267
Isis::Angle::radians
double radians() const
Convert an angle to a double.
Definition: Angle.h:226