File failed to load: https://isis.astrogeology.usgs.gov/6.0.0/Object/assets/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
TriangularPlate.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include "TriangularPlate.h"
8 
9 #include <string>
10 #include <vector>
11 #include <numeric>
12 
13 #include <QtGlobal>
14 
15 #include "AbstractPlate.h"
16 #include "Angle.h"
17 #include "Distance.h"
18 #include "Intercept.h"
19 #include "IException.h"
20 #include "IString.h"
21 #include "Latitude.h"
22 #include "Longitude.h"
23 #include "NaifDskApi.h"
24 #include "SurfacePoint.h"
25 
26 using namespace std;
27 
28 namespace Isis {
29 
31  // no need to implement this method since it is private and never called
32  // within this class
33  // TriangularPlate::TriangularPlate() : AbstractPlate(), m_plate(3, 3, 0.0) { }
34 
36  TriangularPlate::TriangularPlate(const NaifTriangle &plate, const int &plateId) :
37  AbstractPlate(), m_plate(plate.copy()),
38  m_plateId(plateId) { }
39 
40  TriangularPlate::~TriangularPlate() { }
41 
42  int TriangularPlate::id() const {
43  return m_plateId;
44  }
45 
46  QString TriangularPlate::name() const {
47  return "TriangularPlate";
48  }
49 
65  double radius = qMax(qMax(vnorm_c(m_plate[0]), vnorm_c(m_plate[1])),
66  vnorm_c(m_plate[2]));
67  return ( Distance(radius, Distance::Kilometers) );
68  }
69 
71  double radius = qMin(qMin(vnorm_c(m_plate[0]), vnorm_c(m_plate[1])),
72  vnorm_c(m_plate[2]));
73  return ( Distance(radius, Distance::Kilometers) );
74  }
75 
85  double TriangularPlate::area() const {
86 
87  // Get the lengths of each side
88  NaifVector edge(3);
89  vsub_c(m_plate[1], m_plate[0], &edge[0]);
90  double s1 = vnorm_c(&edge[0]);
91 
92  vsub_c(m_plate[2], m_plate[0], &edge[0]);
93  double s2 = vnorm_c(&edge[0]);
94 
95  vsub_c(m_plate[2], m_plate[1], &edge[0]);
96  double s3 = vnorm_c(&edge[0]);
97 
98  // Heron's formula for area
99  double S = (s1 + s2 + s3) / 2.0;
100  double p_area = std::sqrt(S * (S - s1) * (S - s2) * (S - s3));
101 
102  return (p_area);
103  }
104 
116 
117  // Get the lengths of each side
118  NaifVector edge1(3);
119  vsub_c(m_plate[1], m_plate[0], &edge1[0]);
120 
121  NaifVector edge2(3);
122  vsub_c(m_plate[2], m_plate[0], &edge2[0]);
123 
124  NaifVector norm(3);
125  ucrss_c(&edge1[0], &edge2[0], &norm[0]);
126 
127  return (norm);
128  }
129 
130  NaifVector TriangularPlate::center() const {
131  double third(0.33333333333333331);
132  NaifVector midPt(3);
133  vlcom3_c(third, m_plate[0], third, m_plate[1], third, m_plate[2], &midPt[0]);
134  return (midPt);
135  }
136 
154  // Get two sides
155  NaifVector norm(normal());
156  double sepang = vsep_c(&norm[0], &raydir[0]);
157  return ( Angle(sepang, Angle::Radians) );
158  }
159 
177  const NaifVector &raydir) const {
179  return (findPlateIntercept(vertex, raydir, point));
180  }
181 
199  const Longitude &lon) const {
200 
201  // Extend the maximum height of the plate to a resonable distance
202  double maxrad = maxRadius().kilometers() * 1.5;
203 
204  // Create a surface point above the highest plate vertex
205  SurfacePoint point(lat, lon, Distance(maxrad, Distance::Kilometers));
206  NaifVertex obs(3);
207  point.ToNaifArray(&obs[0]);
208 
209  // Set the ray direction back toward the center of the body
210  NaifVector raydir(3);
211  vminus_c(&obs[0], &raydir[0]);
212 
213  // Determine where the point/ray intercepts the plate
214  NaifVertex xpt;
215  return (findPlateIntercept(obs, raydir, xpt));
216  }
217 
238  const Longitude &lon) const {
239  // Extend the maximum height of the plate
240  double maxrad = maxRadius().kilometers() * 1.5;
241 
242  // Create a surface point 1.5 times above the highest plate vertex
243  SurfacePoint point(lat, lon, Distance(maxrad, Distance::Kilometers));
244  NaifVertex obs(3);
245  point.ToNaifArray(&obs[0]);
246 
247  // Set the ray direction back toward the center of the body
248  NaifVector raydir(3);
249  vminus_c(&obs[0], &raydir[0]);
250 
251  // Determine if the point/ray intercepts the plate
252  NaifVertex xpt;
253  if ( !findPlateIntercept(obs, raydir, xpt) ) return (0);
254 
255  // Construct the intercept point and return it
256  SurfacePoint *ipoint(new SurfacePoint());
257  ipoint->FromNaifArray(&xpt[0]);
258  return (ipoint);
259  }
260 
261 
281  const NaifVector &raydir) const {
283  if ( !findPlateIntercept(vertex, raydir, point) ) return (0);
284 
285  // Got a valid intercept. Construct it and return
286  SurfacePoint *xpt = new SurfacePoint();
287  xpt->FromNaifArray(&point[0]);
288  return (new Intercept(vertex, raydir, xpt, clone()));
289  }
290 
291 
307  NaifVertex vec(3);
308  if ( (v < 0) || (v > 2) ) {
309  QString msg = "Unable to get TriangularPlate vertex for index ["
310  + toString(v) + "]. Valid index range is 0-2.";
311  throw IException(IException::Programmer, msg, _FILEINFO_);
312  }
313  for ( int i = 0 ; i < 3 ; i++ ) {
314  vec[i] = m_plate[v][i];
315  }
316  return (vec);
317  }
318 
319 
334  return (new TriangularPlate(m_plate, m_plateId));
335  }
336 
358  const NaifVector &raydir,
359  NaifVertex &point) const {
360 
361  // Construct three edges of the solid tehtrahderal between plate and observer
362  NaifVector e1(3), e2(3), e3(3);
363  vsub_c(m_plate[0], &obs[0], &e1[0]);
364  vsub_c(m_plate[1], &obs[0], &e2[0]);
365  vsub_c(m_plate[2], &obs[0], &e3[0]);
366 
367  // Test to see if the ray direction and plate normal are perpendicular
368  NaifVector tnorm12(3);
369  vcrss_c(&e1[0], &e2[0], &tnorm12[0]);
370  double tdot12 = vdot_c(&raydir[0], &tnorm12[0]);
371  double en = vdot_c(&e3[0], &tnorm12[0]);
372 
373  // Check for e3 perpendicular to plate normal. If true, e3 is a linear
374  // combination of e1 and e2.
375  if ( qFuzzyCompare(en+1.0, 1.0) ) return (false);
376 
377  // Check if raydir and e3 are in same half space
378  if ( (en > 0.0) && (tdot12 < 0.0) ) return (false);
379  if ( (en < 0.0) && (tdot12 > 0.0) ) return (false);
380 
381  // Check that raydir and e1 are on the same side of the plane spanned by e2
382  // and e3.
383  NaifVector tnorm23(3);
384  vcrss_c(&e2[0], &e3[0], &tnorm23[0]);
385  double tdot23 = vdot_c(&raydir[0], &tnorm23[0]);
386 
387  // Check if raydir and e3 are in same halfspace
388  if ( (en > 0.0) && (tdot23 < 0.0) ) return (false);
389  if ( (en < 0.0) && (tdot23 > 0.0) ) return (false);
390 
391  // Finally check that raydir and e2 are in the same half space bounded by e3
392  // and e2.
393  NaifVector tnorm31(3);
394  vcrss_c(&e3[0], &e1[0], &tnorm31[0]);
395  double tdot31 = vdot_c(&raydir[0], &tnorm31[0]);
396 
397  // Check if raydir and e2 are in same halfspace
398  if ( (en > 0.0) && (tdot31 < 0.0) ) return (false);
399  if ( (en < 0.0) && (tdot31 > 0.0) ) return (false);
400 
401  // Ok, we know raydir intersects the plate. Compute the intercept point if
402  // the denominator is not 0.
403  double denom = tdot12 + tdot23 + tdot31;
404 
405  // NOTE: If we have gotten this far in the method,
406  // we have checked that en != 0
407  // if en < 0, then tdot12 <= 0, tdot23 <= 0 and tdot31 <= 0
408  // if en > 0, then tdot12 >= 0, tdot23 >= 0 and tdot31 >= 0
409  // So, in order for the denominator to be 0, then it must be that
410  // tdot12 == tdot23 == tdot31 == 0
411  if ( qFuzzyCompare(denom+1.0, 1.0) ) return (false);
412 
413  double scale = en / denom;
414  NaifVertex xpt(3);
415  vlcom_c(1.0, &obs[0], scale, &raydir[0], &xpt[0]);
416  point = xpt;
417  return (true);
418  }
419 
420 } // namespace Isis
Isis::TriangularPlate::separationAngle
Angle separationAngle(const NaifVector &raydir) const
Computes the separation angle from the plate normal of a given vector.
Definition: TriangularPlate.cpp:153
Isis::Distance::kilometers
double kilometers() const
Get the distance in kilometers.
Definition: Distance.cpp:106
Isis::NaifVertex
TNT::Array1D< SpiceDouble > NaifVertex
1-D Buffer[3]
Definition: NaifDskApi.h:47
Isis::Latitude
This class is designed to encapsulate the concept of a Latitude.
Definition: Latitude.h:51
Isis::TriangularPlate::vertex
NaifVertex vertex(int v) const
Returns the vth point of the triangle.
Definition: TriangularPlate.cpp:306
Isis::TriangularPlate::intercept
Intercept * intercept(const NaifVertex &vertex, const NaifVector &raydir) const
Conpute the intercept point on a triangular plate.
Definition: TriangularPlate.cpp:280
Isis::AbstractPlate
Abstract interface to a TIN plate.
Definition: AbstractPlate.h:46
Isis::TriangularPlate::point
SurfacePoint * point(const Latitude &lat, const Longitude &lon) const
Determine the intercept point of a lat/lon location for the plate.
Definition: TriangularPlate.cpp:237
Isis::toString
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:211
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::Distance::Kilometers
@ Kilometers
The distance is being specified in kilometers.
Definition: Distance.h:45
Isis::TriangularPlate::maxRadius
Distance maxRadius() const
Determines the maximum radius from all the vertices of the plate.
Definition: TriangularPlate.cpp:64
Isis::TriangularPlate::hasPoint
bool hasPoint(const Latitude &lat, const Longitude &lon) const
Determines the give lat/lon point intercept the triangular plate.
Definition: TriangularPlate.cpp:198
Isis::TriangularPlate::clone
AbstractPlate * clone() const
Retrns a clone of the current plate.
Definition: TriangularPlate.cpp:333
Isis::NaifTriangle
TNT::Array2D< SpiceDouble > NaifTriangle
3-D triangle[3][3]
Definition: NaifDskApi.h:48
Isis::TriangularPlate::name
QString name() const
Gets the name of this Plate type.
Definition: TriangularPlate.cpp:46
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::TriangularPlate::m_plate
NaifTriangle m_plate
Tetrahedron, defined by the coordinate system origin and 3 vertices, used to represent the Triangular...
Definition: TriangularPlate.h:67
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::TriangularPlate::normal
NaifVector normal() const
Compute the surface normal of the plate.
Definition: TriangularPlate.cpp:115
Isis::Angle
Defines an angle and provides unit conversions.
Definition: Angle.h:45
Isis::TriangularPlate::findPlateIntercept
bool findPlateIntercept(const NaifVertex &obs, const NaifVector &raydir, NaifVertex &point) const
Determines of if given a vertex and look direction intercepts the plate.
Definition: TriangularPlate.cpp:357
Isis::TriangularPlate::area
double area() const
Returns the area of the plate in km.
Definition: TriangularPlate.cpp:85
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::Intercept
Container for a intercept condition.
Definition: Intercept.h:36
Isis::TriangularPlate::m_plateId
int m_plateId
ID for this plate on the ShapeModel.
Definition: TriangularPlate.h:69
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::TriangularPlate::minRadius
Distance minRadius() const
Gets the minimum radius.
Definition: TriangularPlate.cpp:70
Isis::NaifVector
TNT::Array1D< SpiceDouble > NaifVector
Namespace to contain type definitions of NAIF DSK fundamentals.
Definition: NaifDskApi.h:46
Isis::SurfacePoint
This class defines a body-fixed surface point.
Definition: SurfacePoint.h:132
Isis::TriangularPlate
Specification for an abstract triangular plate.
Definition: TriangularPlate.h:34
Isis::Angle::Radians
@ Radians
Radians are generally used in mathematical equations, 0-2*PI is one circle, however these are more di...
Definition: Angle.h:63
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::TriangularPlate::hasIntercept
bool hasIntercept(const NaifVertex &vertex, const NaifVector &raydir) const
Determines if a look direction from a point intercepts the plate.
Definition: TriangularPlate.cpp:176

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the USGS Astrogeology Discussion Board
To report a bug, or suggest a feature go to: ISIS Github
File Modified: 07/13/2023 15:17:25