34 ShapeModel::ShapeModel() {
50 ShapeModel::ShapeModel(
Target *target) {
59 void ShapeModel::Initialize() {
60 m_name =
new QString();
62 m_hasIntersection =
false;
64 m_normal.resize(3,0.);
65 m_hasEllipsoidIntersection =
false;
70 ShapeModel::~ShapeModel() {
75 delete m_surfacePoint;
76 m_surfacePoint = NULL;
98 const std::vector<double> &observerPos,
99 const bool &backCheck) {
101 return (intersectSurface(
SurfacePoint(lat, lon, localRadius(lat, lon)), observerPos, backCheck));
122 const std::vector<double> &observerPos,
123 const bool &backCheck) {
127 setSurfacePoint(surfpt);
134 void ShapeModel::calculateEllipsoidalSurfaceNormal() {
140 if (!m_hasIntersection || !surfaceIntersection()->Valid()) {
141 QString msg =
"A valid intersection must be defined before computing the surface normal";
147 pB[0] = surfaceIntersection()->GetX().kilometers();
148 pB[1] = surfaceIntersection()->GetY().kilometers();
149 pB[2] = surfaceIntersection()->GetZ().kilometers();
154 unorm_c(pB, upB, &dist);
155 memcpy(&m_normal[0], upB,
sizeof(
double) * 3);
179 double ShapeModel::emissionAngle(
const std::vector<double> &observerBodyFixedPosition) {
182 if (!hasNormal()) calculateDefaultNormal();
186 pB[0] = surfaceIntersection()->GetX().kilometers();
187 pB[1] = surfaceIntersection()->GetY().kilometers();
188 pB[2] = surfaceIntersection()->GetZ().kilometers();
191 SpiceDouble psB[3], upsB[3], dist;
192 vsub_c((ConstSpiceDouble *) &observerBodyFixedPosition[0], pB, psB);
193 unorm_c(psB, upsB, &dist);
195 double angle = vdot_c((SpiceDouble *) &m_normal[0], upsB);
196 if(angle > 1.0)
return 0.0;
197 if(angle < -1.0)
return 180.0;
207 bool ShapeModel::hasEllipsoidIntersection() {
208 return m_hasEllipsoidIntersection;
226 double ShapeModel::incidenceAngle(
const std::vector<double> &illuminatorBodyFixedPosition) {
229 if (!m_hasNormal) calculateDefaultNormal();
233 pB[0] = surfaceIntersection()->GetX().kilometers();
234 pB[1] = surfaceIntersection()->GetY().kilometers();
235 pB[2] = surfaceIntersection()->GetZ().kilometers();
238 SpiceDouble puB[3], upuB[3], dist;
239 vsub_c((SpiceDouble *) &illuminatorBodyFixedPosition[0], pB, puB);
240 unorm_c(puB, upuB, &dist);
242 double angle = vdot_c((SpiceDouble *) &m_normal[0], upuB);
243 if(angle > 1.0)
return 0.0;
244 if(angle < -1.0)
return 180.0;
261 bool ShapeModel::intersectEllipsoid(
const std::vector<double> observerBodyFixedPosition,
262 const std::vector<double> &observerLookVectorToTarget) {
267 SpiceDouble lookB[3];
273 memcpy(lookB,&observerLookVectorToTarget[0], 3*
sizeof(
double));
276 std::vector<Distance> radii = targetRadii();
277 SpiceDouble a = radii[0].kilometers();
278 SpiceDouble b = radii[1].kilometers();
279 SpiceDouble c = radii[2].kilometers();
282 SpiceDouble intersectionPoint[3];
283 SpiceBoolean intersected =
false;
285 NaifStatus::CheckErrors();
286 surfpt_c((SpiceDouble *) &observerBodyFixedPosition[0], lookB, a, b, c,
287 intersectionPoint, &intersected);
288 NaifStatus::CheckErrors();
291 m_surfacePoint->FromNaifArray(intersectionPoint);
292 m_hasIntersection =
true;
295 m_hasIntersection =
false;
298 m_hasEllipsoidIntersection = m_hasIntersection;
299 return m_hasIntersection;
318 double ShapeModel::phaseAngle(
const std::vector<double> &observerBodyFixedPosition,
319 const std::vector<double> &illuminatorBodyFixedPosition) {
323 pB[0] = surfaceIntersection()->GetX().kilometers();
324 pB[1] = surfaceIntersection()->GetY().kilometers();
325 pB[2] = surfaceIntersection()->GetZ().kilometers();
328 SpiceDouble psB[3], upsB[3], dist;
329 vsub_c((SpiceDouble *) &observerBodyFixedPosition[0], pB, psB);
330 unorm_c(psB, upsB, &dist);
333 SpiceDouble puB[3], upuB[3];
334 vsub_c((SpiceDouble *) &illuminatorBodyFixedPosition[0], pB, puB);
335 unorm_c(puB, upuB, &dist);
337 double angle = vdot_c(upsB, upuB);
340 if(angle > 1.0)
return 0.0;
341 if(angle < -1.0)
return 180.0;
353 return m_surfacePoint;
362 bool ShapeModel::hasIntersection() {
363 return m_hasIntersection;
372 bool ShapeModel::hasNormal()
const {
380 void ShapeModel::clearSurfacePoint() {
381 setHasIntersection(
false);
382 m_hasEllipsoidIntersection =
false;
395 std::vector<double> ShapeModel::normal() {
400 QString message =
"The local normal has not been computed.";
425 bool ShapeModel::isVisibleFrom(
const std::vector<double> observerPos,
426 const std::vector<double> lookDirection) {
427 if ( hasIntersection() ) {
428 if ( fabs(emissionAngle(observerPos)) <= 90.0 ) {
443 bool ShapeModel::hasValidTarget()
const {
444 return (m_target != NULL);
459 std::vector<Distance> ShapeModel::targetRadii()
const {
460 if (hasValidTarget()) {
461 return m_target->radii();
464 QString message =
"Unable to find target radii for ShapeModel. Target is NULL. ";
481 void ShapeModel::setNormal(
const std::vector<double> normal) {
482 if (m_hasIntersection) {
487 QString message =
"No intersection point in known. A normal can not be set.";
506 void ShapeModel::setNormal(
const double a,
const double b,
const double c) {
507 if (m_hasIntersection) {
514 QString message =
"No intersection point in known. A normal can not be set.";
526 void ShapeModel::setName(QString name) {
537 QString ShapeModel::name()
const{
548 void ShapeModel::setHasIntersection(
bool b) {
549 m_hasIntersection = b;
560 *m_surfacePoint = surfacePoint;
563 m_hasIntersection =
true;
575 void ShapeModel::setHasNormal(
bool status) {
576 m_hasNormal = status;
586 double ShapeModel::resolution() {
587 if (hasValidTarget() && m_hasIntersection) {
588 return m_target->spice()->resolution();
591 QString message =
"No valid intersection point for computing resolution.";
This class defines a body-fixed surface point.
Namespace for the standard library.
This class is designed to encapsulate the concept of a Latitude.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
This class is designed to encapsulate the concept of a Longitude.
#define _FILEINFO_
Macro for the filename and line number.
This class is used to create and store valid Isis3 targets.
Namespace for ISIS/Bullet specific routines.
const double RAD2DEG
Multiplier for converting from radians to degrees.