USGS

Isis 3.0 Object Programmers' Reference

Home

NaifDskShape.cpp
Go to the documentation of this file.
1 
25 #include "NaifDskShape.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 "NaifDskApi.h"
38 #include "NaifDskPlateModel.h"
39 #include "NaifStatus.h"
40 #include "Pvl.h"
41 #include "ShapeModel.h"
42 #include "SpecialPixel.h"
43 #include "Statistics.h"
44 #include "SurfacePoint.h"
45 #include "Target.h"
46 
47 
48 using namespace std;
49 
50 namespace Isis {
51 
53  NaifDskShape::NaifDskShape() : ShapeModel(), m_intercept(NULL) {
54  // defaults for ShapeModel parent class include:
55  // name = empty string
56  // surfacePoint = null sp
57  // hasIntersection = false
58  // hasNormal = false
59  // normal = (0,0,0)
60  // hasEllipsoidIntersection = false
61  setName("DSK");
62  }
63 
77  NaifDskShape::NaifDskShape(Target *target, Pvl &pvl) : ShapeModel(target, pvl),
78  m_intercept(NULL) {
79 
80  // defaults for ShapeModel parent class include:
81  // name = empty string
82  // surfacePoint = null sp
83  // hasIntersection = false
84  // hasNormal = false
85  // normal = (0,0,0)
86  // hasEllipsoidIntersection = false
87 
88  setName("DSK"); // Really is used as type in the system at present!
89 
90  PvlGroup &kernels = pvl.findGroup("Kernels", Pvl::Traverse);
91 
92  QString dskFile;
93  if (kernels.hasKeyword("ElevationModel")) {
94  dskFile = (QString) kernels["ElevationModel"];
95  }
96  else { // if (kernels.hasKeyword("ShapeModel")) {
97  dskFile = (QString) kernels["ShapeModel"];
98  }
99 
100  // Attempt to initialize the DSK file - exception ensues if errors occur
101  // error thrown if ShapeModel=Null (i.e. Ellipsoid)
102  m_model = NaifDskPlateModel(dskFile);
103 
104  }
105 
120  m_model(model), m_intercept(NULL) {
121 
122  // TODO create valid Target
123  // Using this constructor, ellipsoidNormal(),
124  // calculateSurfaceNormal(), and setLocalNormalFromIntercept()
125  // methods can not be called
126  }
127 
128 
131 
132 
151  bool NaifDskShape::intersectSurface(std::vector<double> observerPos,
152  std::vector<double> lookDirection) {
153  NaifVertex obs(3, &observerPos[0]);
154  NaifVector raydir(3, &lookDirection[0]);
155  m_intercept.reset(m_model.intercept(obs, raydir));
156 
157  bool success = !m_intercept.isNull();
158  if (success) {
159  SurfacePoint point = m_intercept->location();
160  setSurfacePoint(point); // sets ShapeModel::m_hasIntersection=t, ShapeModel::m_hasNormal=f
161  }
162  return ( success );
163  }
164 
182  const Longitude &lon) {
183  QScopedPointer<SurfacePoint> pnt(m_model.point(lat, lon));
184  if ( !pnt.isNull() ) return (pnt->GetLocalRadius());
185  return (Distance());
186  }
187 
198 
199  // Sanity check
200  if ( !hasIntersection() ) { // hasIntersection() <==> !m_intercept.isNull()
201  QString mess = "Intercept point does not exist - cannot provide normal vector";
203  }
204 
205  // Got it, use the existing intercept point (plate) normal
206  NaifVector norm(m_intercept->normal());
207  setNormal(norm[0], norm[1], norm[2]); // this also takes care of setHasNormal(true);
208  return;
209  }
210 
211 
219  bool NaifDskShape::isDEM() const {
220  return false;
221  }
222 
223 
249  void NaifDskShape::calculateLocalNormal(QVector<double *> neighborPoints) {
250 
251  // Sanity check
252  if ( !hasIntersection() ) { // hasIntersection() <==> !m_intercept.isNull()
253  QString mess = "Intercept point does not exist - cannot provide normal vector";
255  }
256 
258  return;
259  }
260 
261 
264  // ShapeModel (parent class) throws error if no intersection
266  }
267 
270  // ShapeModel (parent class) throws error if no intersection
271  setNormal(ellipsoidNormal().toStdVector());// this takes care of setHasNormal(true);
272  return;
273  }
274 
289  QVector<double> NaifDskShape::ellipsoidNormal() {
290 
291  // Sanity check on state
292  if ( !hasIntersection() ) {
293  QString msg = "An intersection must be defined before computing the surface normal.";
295  }
296  if ( !surfaceIntersection()->Valid() ) {
297  QString msg = "The surface point intersection must be valid to compute the surface normal.";
299  }
300  if (!hasValidTarget()) {
301  QString msg = "A valid target must be defined before computing the surface normal.";
303  }
304 
305  // Get the coordinates of the current surface point
306  SpiceDouble pB[3];
308 
309  // Get the body radii and compute the true normal of the ellipsoid
310  QVector<double> norm(3);
311  // need a case for target == NULL
312  QVector<Distance> radii = QVector<Distance>::fromStdVector(targetRadii());
314  surfnm_c(radii[0].kilometers(), radii[1].kilometers(), radii[2].kilometers(),
315  pB, &norm[0]);
317 
318  return (norm);
319  }
320 
323  return (m_model);
324  }
325 
339  return ( m_intercept.data() );
340  }
341 
342 }; // namespace Isis