Isis 3 Programmer Reference
BulletShapeModel.cpp
Go to the documentation of this file.
1 
25 #include "BulletShapeModel.h"
26 
27 #include <numeric>
28 
29 #include <QtGlobal>
30 #include <QVector>
31 
32 #include "IException.h"
33 #include "Intercept.h"
34 #include "IString.h"
35 #include "Latitude.h"
36 #include "Longitude.h"
37 #include "NaifStatus.h"
38 #include "Pvl.h"
39 #include "ShapeModel.h"
40 #include "SpecialPixel.h"
41 #include "Statistics.h"
42 #include "SurfacePoint.h"
43 #include "Target.h"
44 
45 
46 using namespace std;
47 
48 namespace Isis {
49 
53  BulletShapeModel::BulletShapeModel() : ShapeModel(), m_model(), m_tolerance(DBL_MAX),
54  m_intercept(btVector3(0,0,0), btVector3(0,0,0)) {
55  // defaults for ShapeModel parent class include:
56  // name = empty string
57  // surfacePoint = null sp
58  // hasIntersection = false
59  // hasNormal = false
60  // normal = (0,0,0)
61  // hasEllipsoidIntersection = false
62  setName("Bullet");
63  }
64 
79  ShapeModel(target), m_model(), m_tolerance(DBL_MAX),
80  m_intercept(btVector3(0,0,0), btVector3(0,0,0)) {
81 
82  // defaults for ShapeModel parent class include:
83  // name = empty string
84  // surfacePoint = null sp
85  // hasIntersection = false
86  // hasNormal = false
87  // normal = (0,0,0)
88  // hasEllipsoidIntersection = false
89 
90  setName("Bullet"); // Really is used as type in the system at present!
91 
92  PvlGroup &kernels = pvl.findGroup("Kernels", Pvl::Traverse);
93 
94  QString shapefile;
95  if (kernels.hasKeyword("ElevationModel")) {
96  shapefile = (QString) kernels["ElevationModel"];
97  }
98  else { // if (kernels.hasKeyword("ShapeModel")) {
99  shapefile = (QString) kernels["ShapeModel"];
100  }
101 
102  QScopedPointer<BulletTargetShape> v_shape( BulletTargetShape::load(shapefile) );
103  if (v_shape.isNull() ) {
104  QString mess = "Cannot create a BulletShape from " + shapefile;
105  throw IException(IException::User, mess, _FILEINFO_);
106  }
107 
108  // Attempt to initialize the DSK file - exception ensues if errors occur
109  // error thrown if ShapeModel=Null (i.e. Ellipsoid)
110  m_model.reset(new BulletWorldManager(shapefile));
111  m_model->addTarget( v_shape.take() );
112  }
113 
114 
125  ShapeModel(target), m_model(), m_tolerance(DBL_MAX),
126  m_intercept(btVector3(0,0,0), btVector3(0,0,0)) {
127  // Attempt to initialize the DSK file - exception ensues if errors occur
128  // error thrown if ShapeModel=Null (i.e. Ellipsoid)
129  btAssert ( shape != 0 );
130  m_model.reset( new BulletWorldManager( shape->name() ) );
131  m_model->addTarget( shape );
132  setName("Bullet"); // Really is used as type in the system at present!
133  }
134 
146  ShapeModel(target), m_model(model), m_tolerance(DBL_MAX),
147  m_intercept(btVector3(0,0,0), btVector3(0,0,0)) {
148 
149  // TODO create valid Target
150  // Using this constructor, ellipsoidNormal(),
151  // calculateSurfaceNormal(), and setLocalNormalFromIntercept()
152  // methods can not be called
153  }
154 
155 
160 
161 
168  return ( m_tolerance );
169  }
170 
171 
177  void BulletShapeModel::setTolerance(const double &tolerance) {
178  m_tolerance = tolerance;
179  }
180 
181 
193  bool BulletShapeModel::intersectSurface(std::vector<double> observerPos,
194  std::vector<double> lookDirection) {
195 
197  btVector3 observer(observerPos[0], observerPos[1], observerPos[2]);
198  btVector3 lookdir(lookDirection[0], lookDirection[1], lookDirection[2]);
199  btVector3 rayEnd = castLookDir(observer, lookdir);
200  BulletClosestRayCallback result(observer, rayEnd);
201  bool success = m_model->raycast(observer, rayEnd, result);
202  updateShapeModel(result);
203  return ( success );
204  }
205 
225  const std::vector<double> &observerPos,
226  const bool &checkOcclusion) {
227 
228  // Set up for finding all rays along origin vector through lat/lon surface point
230  btVector3 origin(0.0, 0.0, 0.0);
231  btVector3 lookdir = latlonToVector(lat, lon);
232  btVector3 rayEnd = castLookDir(origin, lookdir);
233  BulletAllHitsRayCallback results( origin, rayEnd, false);
234 
235  // If no intersections (unlikely for this case), we are done!
236  if ( !m_model->raycast(origin, rayEnd, results) ) {
237  return ( false );
238  }
239 
240  // Sort the intersections based on distance to the observer
241  btVector3 observer(observerPos[0], observerPos[1], observerPos[2]);
242  QVector<BulletClosestRayCallback> points = sortHits(results, observer);
243 
244  // If occlusion is being checked
245  if ( checkOcclusion ) {
246  for (int i = 0 ; i < points.size() ; i++) {
247 
248  // Check for occlusion
249  // If the hit is occluded then move on.
250  // Otherwise, it is the closest non-occluded point so take it.
251  BulletClosestRayCallback &hit = points[i];
252  if ( !isOccluded(hit, observer) ) {
253  updateShapeModel( hit );
254  break;
255  }
256  }
257  }
258 
259  // If occlusion is not being checked, take the intersection closest to the observer
260  else {
261  updateShapeModel( points[0] );
262  }
263 
264  // Is set by the update routine
265  return ( hasIntersection() );
266  }
267 
268 
288  const std::vector<double> &observerPos,
289  const bool &checkOcclusion) {
290 
291  // Set up for finding all rays along origin vector through lat/lon surface point
293  btVector3 origin(0.0, 0.0, 0.0);
294  btVector3 surfPointVec = pointToVector(surfpt);
295  btVector3 rayEnd = castLookDir(origin, surfPointVec);
296  BulletAllHitsRayCallback results(origin, rayEnd, false);
297 
298  // Cast the ray to find all intersections
299  // If no intersections (unlikely for this case), we are done!
300  if ( !m_model->raycast(origin, rayEnd, results) ) {
301  return ( false );
302  }
303 
304  // Sort the intersections based on distance to the surface point
305  QVector<BulletClosestRayCallback> points = sortHits(results, surfPointVec);
306 
307  // If occlusion is being checked
308  if ( checkOcclusion ) {
309  btVector3 observer(observerPos[0], observerPos[1], observerPos[2]);
310  for (int i = 0 ; i < points.size() ; i++) {
311 
312  // Check for occlusion
313  // If the hit is occluded then move on.
314  // Otherwise, it is the closest non-occluded point so take it.
315  BulletClosestRayCallback &hit = points[i];
316  if ( !isOccluded(hit, observer) ) {
317  updateShapeModel( hit );
318  break;
319  }
320  }
321  }
322 
323  // If occlusion is not being checked, take the intersection closest to the observer
324  else {
325  updateShapeModel( points[0] );
326  }
327 
328  // Is set by the update routine
329  return ( hasIntersection() );
330 
331  }
332 
333 
343  const btVector3 &observer) const {
344  // If the callback does not have an intersection return true
345  if ( !hit.isValid() ) {
346  return true;
347  }
348 
349  // Check if the emission angle is greater than 90 degrees
350  // If true, then it is occluded, if false then unknown
351  btVector3 psB = (observer - hit.point()).normalized();
352  btScalar angle = std::acos( hit.normal().dot( psB ) ) * RAD2DEG;
353  if ( std::fabs( angle ) > 90.0 - DBL_MIN) {
354  return true;
355  }
356 
357  // Ray cast from the observer to the intersection
358  // If we have an intersection, test for occlusion
359  BulletClosestRayCallback results( observer, hit.point() );
360  if ( !m_model->raycast(observer, hit.point(), results) ) {
361  return false;
362  }
363 
364  // Is this intersection the same as the previous intersection?
365  if ( results.isVisible( hit, getTolerance() ) ) {
366  return false;
367  }
368 
369  return true;
370  }
371 
372 
380  std::vector<double> fakepos(3, 0.0);
381  (void) intersectSurface(surfacePoint, fakepos, false);
382  }
383 
384 
390  }
391 
392 
411  const Longitude &lon) {
412 
413  // Cast a ray from the origin through the surface point at the input lat/lon
414  btVector3 origin(0.0, 0.0, 0.0);
415  btVector3 lookdir = latlonToVector(lat, lon);
416  btVector3 rayEnd = castLookDir(origin, lookdir);
417 
418  BulletAllHitsRayCallback result(origin, rayEnd, false);
419  if ( m_model->raycast(origin, rayEnd, result) ) {
420  BulletClosestRayCallback hit = result.hit();
421  return ( Distance(hit.point().length(), Distance::Kilometers) );
422  }
423  return ( Distance() );
424  }
425 
426 
437 
438  // Sanity check
439  if ( !hasIntersection() ) { // hasIntersection() <==> !m_intercept.isNull()
440  QString mess = "Intercept point does not exist - cannot provide normal vector";
441  throw IException(IException::Programmer, mess, _FILEINFO_);
442  }
443 
444  btVector3 normal = m_intercept.normal();
445  setNormal(normal[0], normal[1], normal[2]);
446  }
447 
448 
456  bool BulletShapeModel::isDEM() const {
457  return false;
458  }
459 
460 
470  bool BulletShapeModel::isVisibleFrom(const std::vector<double> observerPos,
471  const std::vector<double> lookDirection) {
472 
473  if ( !m_intercept.isValid() ) return (false);
474 
475  // Check if the emission angle is greater than 90 degrees
476  // If true, then it is occluded, if false then unknown
477  btVector3 observer(observerPos[0], observerPos[1], observerPos[2]);
478  btVector3 psB = (observer - m_intercept.point()).normalized();
479  btScalar angle = std::acos( m_intercept.normal().dot( psB ) ) * RAD2DEG;
480  if ( std::fabs( angle ) > 90.0 - DBL_MIN) {
481  return false;
482  }
483 
484  btVector3 rayEnd = castLookDir( observer, btVector3(lookDirection[0], lookDirection[1], lookDirection[2]) );
485  BulletClosestRayCallback results(observer, rayEnd);
486  (void) m_model->raycast(observer, rayEnd, results);
487  return ( m_intercept.isVisible( results, getTolerance() ) );
488  }
489 
490 
517 
518  // Sanity check
519  if ( !hasIntersection() ) { // hasIntersection() <==> !m_intercept.isNull()
520  QString mess = "Intercept point does not exist - cannot provide normal vector";
521  throw IException(IException::Programmer, mess, _FILEINFO_);
522  }
523 
525  }
526 
527 
532  // ShapeModel (parent class) throws error if no intersection
534  }
535 
540  // ShapeModel (parent class) throws error if no intersection
541  setNormal(ellipsoidNormal().toStdVector());// this takes care of setHasNormal(true);
542  }
543 
544 
560 
561  // Sanity check on state
562  if ( !hasIntersection() ) {
563  QString msg = "An intersection must be defined before computing the surface normal.";
564  throw IException(IException::Programmer, msg, _FILEINFO_);
565  }
566 
567  if ( !surfaceIntersection()->Valid() ) {
568  QString msg = "The surface point intersection must be valid to compute the surface normal.";
569  throw IException(IException::Programmer, msg, _FILEINFO_);
570  }
571 
572  if (!hasValidTarget()) {
573  QString msg = "A valid target must be defined before computing the surface normal.";
574  throw IException(IException::Programmer, msg, _FILEINFO_);
575  }
576 
577  // Get the coordinates of the current surface point
578  SpiceDouble pB[3];
580 
581  // Get the body radii and compute the true normal of the ellipsoid
582  QVector<double> norm(3);
583  // need a case for target == NULL
586  surfnm_c(radii[0].kilometers(), radii[1].kilometers(), radii[2].kilometers(),
587  pB, &norm[0]);
589 
590  return (norm);
591  }
592 
593 
599  return (*m_model);
600  }
601 
602 
610  btScalar BulletShapeModel::maxDistance() const {
611  return m_model->getTarget()->maximumDistance();
612  }
613 
614 
626  btVector3 BulletShapeModel::castLookDir(const btVector3 &observer,
627  const btVector3 &lookdir) const {
628  btScalar lookScale = observer.length() + maxDistance();
629  return ( observer + lookdir.normalized() * lookScale );
630  }
631 
632 
644  btVector3 BulletShapeModel::latlonToVector(const Latitude &lat, const Longitude &lon) const {
645  double latAngle = lat.radians();
646  double lonAngle = lon.radians();
647  btVector3 lookDir( cos(latAngle) * cos(lonAngle),
648  cos(latAngle) * sin(lonAngle),
649  sin(latAngle) );
650  return ( lookDir );
651  }
652 
653 
661  btVector3 BulletShapeModel::pointToVector(const SurfacePoint &surfpt) const {
662  btVector3 point;
663  surfpt.ToNaifArray( &point[0] );
664  return ( point );
665  }
666 
667 
675  SurfacePoint BulletShapeModel::makeSurfacePoint(const btVector3 &point) const {
676  SurfacePoint surfpt;
677  surfpt.FromNaifArray( &point[0] );
678  return ( surfpt );
679  }
680 
681 
693  const btVector3 &sortPoint) const {
695  for (int i = 0 ; i < hits.size() ; i++) {
696  BulletClosestRayCallback hit = hits.hit(i);
697  sortMap.insert( hit.distance(sortPoint), hit );
698  }
699  return ( QVector<BulletClosestRayCallback>::fromList( sortMap.values() ) );
700  }
701 
702 
717  m_intercept = result;
718  if ( m_intercept.isValid() ) {
719  ShapeModel::setSurfacePoint( makeSurfacePoint(m_intercept.point()) ); // sets ShapeModel::m_hasIntersection=t, ShapeModel::m_hasNormal=f
720 
721  btVector3 normal = m_intercept.normal();
722  setNormal(normal[0], normal[1], normal[2]);
723  }
724  else {
726  setHasNormal(false);
727  }
728 
729  return;
730  }
731 }; // namespace Isis
Isis::BulletShapeModel::calculateSurfaceNormal
void calculateSurfaceNormal()
compute the ellipsoid surface normal of the target
Definition: BulletShapeModel.cpp:539
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::ShapeModel::clearSurfacePoint
virtual void clearSurfacePoint()
Clears or resets the current surface point.
Definition: ShapeModel.cpp:386
Isis::BulletShapeModel::BulletShapeModel
BulletShapeModel()
Default constructor that creates a shape model without any internal model.
Definition: BulletShapeModel.cpp:53
Isis::BulletClosestRayCallback::normal
btVector3 normal() const
Return the local surface normal at the intersection, if an intersection exists.
Definition: BulletClosestRayCallback.cpp:183
Isis::BulletShapeModel::m_intercept
BulletClosestRayCallback m_intercept
! Tolerance of occlusion check in kilometers.
Definition: BulletShapeModel.h:92
Isis::Latitude
This class is designed to encapsulate the concept of a Latitude.
Definition: Latitude.h:51
Isis::BulletShapeModel::clearSurfacePoint
virtual void clearSurfacePoint()
Clear the saved surface point and reset the saved intersection.
Definition: BulletShapeModel.cpp:388
Isis::BulletShapeModel::~BulletShapeModel
~BulletShapeModel()
Destructor.
Definition: BulletShapeModel.cpp:159
Isis::ShapeModel::surfaceIntersection
SurfacePoint * surfaceIntersection() const
Returns the surface intersection for this ShapeModel.
Definition: ShapeModel.cpp:358
Isis::BulletShapeModel::isOccluded
bool isOccluded(const BulletClosestRayCallback &hit, const btVector3 &observer) const
Check if an intersection is occluded from an observer.
Definition: BulletShapeModel.cpp:342
Isis::BulletShapeModel::updateShapeModel
void updateShapeModel(const BulletClosestRayCallback &result)
Update shape model - carefully!!
Definition: BulletShapeModel.cpp:716
Isis::ShapeModel::setSurfacePoint
virtual void setSurfacePoint(const SurfacePoint &surfacePoint)
Set surface intersection point.
Definition: ShapeModel.cpp:565
Isis::BulletShapeModel::pointToVector
btVector3 pointToVector(const SurfacePoint &point) const
Convert a surface point into a vector.
Definition: BulletShapeModel.cpp:661
Isis::BulletAllHitsRayCallback
Bullet ray tracing callback to return all intersections along a ray's path.
Definition: BulletAllHitsRayCallback.h:30
Isis::ShapeModel::targetRadii
std::vector< Distance > targetRadii() const
Returns the radii of the body in km.
Definition: ShapeModel.cpp:465
Isis::BulletAllHitsRayCallback::size
int size() const
Returns the number of intersections found.
Definition: BulletAllHitsRayCallback.cpp:80
Isis::BulletShapeModel::setLocalNormalFromIntercept
void setLocalNormalFromIntercept()
Set the normal vector to the intercept point normal.
Definition: BulletShapeModel.cpp:436
Isis::PvlContainer::hasKeyword
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Definition: PvlContainer.cpp:159
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::NaifStatus::CheckErrors
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Definition: NaifStatus.cpp:28
Isis::BulletShapeModel::latlonToVector
btVector3 latlonToVector(const Latitude &lat, const Longitude &lon) const
Convert a pair of latitude and longitude values into a unit vector pointing from the origin of the bo...
Definition: BulletShapeModel.cpp:644
Isis::ShapeModel::setNormal
void setNormal(const std::vector< double >)
Sets the normal for the currect intersection point.
Definition: ShapeModel.cpp:487
Isis::BulletWorldManager
Bullet World manager maintains a proper state for target bodies.
Definition: BulletWorldManager.h:41
Isis::BulletTargetShape::load
static BulletTargetShape * load(const QString &dem, const Pvl *conf=0)
Load a DEM file into the target shape.
Definition: BulletTargetShape.cpp:84
Isis::BulletClosestRayCallback::point
btVector3 point() const
Return the intersection point, if one exists.
Definition: BulletClosestRayCallback.cpp:167
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::PvlObject::Traverse
@ Traverse
Search child objects.
Definition: PvlObject.h:158
Isis::Distance::Kilometers
@ Kilometers
The distance is being specified in kilometers.
Definition: Distance.h:45
Isis::BulletShapeModel::setTolerance
void setTolerance(const double &tolerance)
Sets the occlusion tolerance.
Definition: BulletShapeModel.cpp:177
Isis::BulletShapeModel::isVisibleFrom
virtual bool isVisibleFrom(const std::vector< double > observerPos, const std::vector< double > lookDirection)
Check if the saved intercept is visible from a observer with a given look direction.
Definition: BulletShapeModel.cpp:470
Isis::BulletShapeModel::model
const BulletWorldManager & model() const
Returns a direct reference to the Bullet world that contains the target shape and can perform ray cas...
Definition: BulletShapeModel.cpp:598
Isis::ShapeModel::setName
void setName(QString name)
Sets the shape name.
Definition: ShapeModel.cpp:532
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::BulletShapeModel::calculateLocalNormal
void calculateLocalNormal(QVector< double * > cornerNeighborPoints)
Compute the normal for a local region of surface points.
Definition: BulletShapeModel.cpp:516
Isis::BulletAllHitsRayCallback::hit
const BulletClosestRayCallback & hit(const int &index=0) const
Return a callback for the intersection at a given index.
Definition: BulletAllHitsRayCallback.cpp:112
Isis::BulletShapeModel::calculateDefaultNormal
void calculateDefaultNormal()
Calculate the surface normal of the ellipsoid as the default.
Definition: BulletShapeModel.cpp:531
Isis::BulletTargetShape::name
QString name() const
Return name of the target shape.
Definition: BulletTargetShape.cpp:71
Isis::SurfacePoint::FromNaifArray
void FromNaifArray(const double naifValues[3])
A naif array is a c-style array of size 3.
Definition: SurfacePoint.cpp:891
Isis::BulletShapeModel::castLookDir
btVector3 castLookDir(const btVector3 &observer, const btVector3 &lookdir) const
Compute the end point of a ray based on an observer and look direction.
Definition: BulletShapeModel.cpp:626
Isis::BulletShapeModel::ellipsoidNormal
QVector< double > ellipsoidNormal()
Compute the true surface normal vector of an ellipsoid.
Definition: BulletShapeModel.cpp:559
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::BulletShapeModel::localRadius
Distance localRadius(const Latitude &lat, const Longitude &lon)
Compute the radius of the body at a lat/lon point.
Definition: BulletShapeModel.cpp:410
Isis::BulletClosestRayCallback::isValid
bool isValid() const
Checks if the callback is valid/has a valid intersection.
Definition: BulletClosestRayCallback.cpp:120
Isis::BulletShapeModel::isDEM
bool isDEM() const
Indicates that this shape model is not from a DEM.
Definition: BulletShapeModel.cpp:456
Isis::ShapeModel::setHasNormal
void setHasNormal(bool status)
Sets the flag to indicate whether this ShapeModel has a surface normal.
Definition: ShapeModel.cpp:581
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::ShapeModel::hasValidTarget
bool hasValidTarget() const
Returns the status of the target.
Definition: ShapeModel.cpp:449
Isis::ShapeModel
Define shapes and provide utilities for Isis targets.
Definition: ShapeModel.h:62
Isis::BulletShapeModel::makeSurfacePoint
SurfacePoint makeSurfacePoint(const btVector3 &point) const
Convert a vector into a surface point.
Definition: BulletShapeModel.cpp:675
Isis::BulletTargetShape
Bullet Target Shape for planetary bodies.
Definition: BulletTargetShape.h:33
Isis::SurfacePoint::ToNaifArray
void ToNaifArray(double naifOutput[3]) const
A naif array is a c-style array of size 3.
Definition: SurfacePoint.cpp:870
Isis::BulletClosestRayCallback::distance
btScalar distance() const
Returns the distance from the intersection point to the beginning of the ray.
Definition: BulletClosestRayCallback.cpp:221
QMap
This is free and unencumbered software released into the public domain.
Definition: CubeIoHandler.h:22
Isis::BulletClosestRayCallback::isVisible
bool isVisible(const BulletClosestRayCallback &other, const btScalar tolerance=DBL_MAX) const
Check if the intersection in this is visible based on another callback.
Definition: BulletClosestRayCallback.cpp:291
Isis::BulletShapeModel::m_tolerance
double m_tolerance
! Bullet collision world that contains the representation of the body.
Definition: BulletShapeModel.h:90
Isis::ShapeModel::hasIntersection
bool hasIntersection()
Returns intersection status.
Definition: ShapeModel.cpp:368
Isis::BulletShapeModel::intersectSurface
bool intersectSurface(std::vector< double > observerPos, std::vector< double > lookDirection)
This method computes a DEM intercept point given an observer location and look direction using the Bu...
Definition: BulletShapeModel.cpp:193
Isis::BulletShapeModel::maxDistance
btScalar maxDistance() const
! The results of the last ray cast.
Definition: BulletShapeModel.cpp:610
QVector
This is free and unencumbered software released into the public domain.
Definition: Calculator.h:18
Isis::BulletShapeModel::sortHits
QVector< BulletClosestRayCallback > sortHits(const BulletAllHitsRayCallback &hits, const btVector3 &sortPoint) const
Sort the hits in an AllHitsRayCallback based on distance to a point.
Definition: BulletShapeModel.cpp:692
Isis::BulletClosestRayCallback
Bullet ray tracing callback for closest hit on target surface.
Definition: BulletClosestRayCallback.h:33
Isis::BulletShapeModel::getTolerance
double getTolerance() const
Returns the occlusion tolerance in kilometers.
Definition: BulletShapeModel.cpp:167
Isis::Target
This class is used to create and store valid Isis targets.
Definition: Target.h:63
Isis::RAD2DEG
const double RAD2DEG
Multiplier for converting from radians to degrees.
Definition: Constants.h:44
Isis::BulletShapeModel::setSurfacePoint
virtual void setSurfacePoint(const SurfacePoint &surfacePoint)
Set the internal surface point.
Definition: BulletShapeModel.cpp:379
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::IException::User
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition: IException.h:126
Isis::ShapeModel::normal
std::vector< double > normal()
Returns the local surface normal at the current intersection point.
Definition: ShapeModel.cpp:401
Isis::Angle::radians
double radians() const
Convert an angle to a double.
Definition: Angle.h:226