32   ShapeModel::ShapeModel() {
 
   48   ShapeModel::ShapeModel(
Target *target) {
 
   57   void ShapeModel::Initialize() {
 
   58     m_name = 
new QString();
 
   60     m_hasIntersection = 
false;
 
   62     m_normal.resize(3,0.);
 
   63     m_hasEllipsoidIntersection = 
false;
 
   68   ShapeModel::~ShapeModel() {
 
   73     delete m_surfacePoint;
 
   74     m_surfacePoint = NULL;
 
   81   void ShapeModel::calculateEllipsoidalSurfaceNormal()  {
 
   87     if (!m_hasIntersection || !surfaceIntersection()->Valid()) {
 
   88      QString msg = 
"A valid intersection must be defined before computing the surface normal";
 
   94     pB[0] = surfaceIntersection()->GetX().kilometers();
 
   95     pB[1] = surfaceIntersection()->GetY().kilometers();
 
   96     pB[2] = surfaceIntersection()->GetZ().kilometers();
 
  101     unorm_c(pB, upB, &dist);
 
  102     memcpy(&m_normal[0], upB, 
sizeof(
double) * 3);
 
  126   double ShapeModel::emissionAngle(
const std::vector<double> &observerBodyFixedPosition) {
 
  129     if (!hasNormal()) calculateDefaultNormal();
 
  133     pB[0] = surfaceIntersection()->GetX().kilometers();
 
  134     pB[1] = surfaceIntersection()->GetY().kilometers();
 
  135     pB[2] = surfaceIntersection()->GetZ().kilometers();
 
  138     SpiceDouble psB[3], upsB[3], dist;
 
  139     vsub_c((ConstSpiceDouble *) &observerBodyFixedPosition[0], pB, psB);
 
  140     unorm_c(psB, upsB, &dist);
 
  142     double angle = vdot_c((SpiceDouble *) &m_normal[0], upsB);
 
  143     if(angle > 1.0) 
return 0.0;
 
  144     if(angle < -1.0) 
return 180.0;
 
  154   bool ShapeModel::hasEllipsoidIntersection() {
 
  155     return m_hasEllipsoidIntersection;
 
  173   double ShapeModel::incidenceAngle(
const std::vector<double> &illuminatorBodyFixedPosition) {
 
  176     if (!m_hasNormal) calculateDefaultNormal();
 
  180     pB[0] = surfaceIntersection()->GetX().kilometers();
 
  181     pB[1] = surfaceIntersection()->GetY().kilometers();
 
  182     pB[2] = surfaceIntersection()->GetZ().kilometers();
 
  185     SpiceDouble puB[3], upuB[3], dist;
 
  186     vsub_c((SpiceDouble *) &illuminatorBodyFixedPosition[0], pB, puB);
 
  187     unorm_c(puB, upuB, &dist);
 
  189     double angle = vdot_c((SpiceDouble *) &m_normal[0], upuB);
 
  190     if(angle > 1.0) 
return 0.0;
 
  191     if(angle < -1.0) 
return 180.0;
 
  208   bool ShapeModel::intersectEllipsoid(
const std::vector<double> observerBodyFixedPosition,
 
  209                                       const std::vector<double> &observerLookVectorToTarget) {
 
  214     SpiceDouble lookB[3];
 
  220     memcpy(lookB,&observerLookVectorToTarget[0], 3*
sizeof(
double));
 
  223     std::vector<Distance> radii = targetRadii();
 
  224     SpiceDouble a = radii[0].kilometers();
 
  225     SpiceDouble b = radii[1].kilometers();
 
  226     SpiceDouble c = radii[2].kilometers();
 
  229     SpiceDouble intersectionPoint[3];
 
  230     SpiceBoolean intersected = 
false;
 
  232     NaifStatus::CheckErrors();
 
  233     surfpt_c((SpiceDouble *) &observerBodyFixedPosition[0], lookB, a, b, c,
 
  234              intersectionPoint, &intersected);
 
  235     NaifStatus::CheckErrors();
 
  238       m_surfacePoint->FromNaifArray(intersectionPoint);
 
  239       m_hasIntersection = 
true;
 
  242       m_hasIntersection = 
false;
 
  245     m_hasEllipsoidIntersection = m_hasIntersection;
 
  246     return m_hasIntersection;
 
  265   double ShapeModel::phaseAngle(
const std::vector<double> &observerBodyFixedPosition,
 
  266                                 const std::vector<double> &illuminatorBodyFixedPosition) {
 
  270     pB[0] = surfaceIntersection()->GetX().kilometers();
 
  271     pB[1] = surfaceIntersection()->GetY().kilometers();
 
  272     pB[2] = surfaceIntersection()->GetZ().kilometers();
 
  275     SpiceDouble psB[3], upsB[3], dist;
 
  276     vsub_c((SpiceDouble *) &observerBodyFixedPosition[0], pB, psB);
 
  277     unorm_c(psB, upsB, &dist);
 
  280     SpiceDouble puB[3], upuB[3];
 
  281     vsub_c((SpiceDouble *) &illuminatorBodyFixedPosition[0], pB, puB);
 
  282     unorm_c(puB, upuB, &dist);
 
  284     double angle = vdot_c(upsB, upuB);
 
  287     if(angle > 1.0) 
return 0.0;
 
  288     if(angle < -1.0) 
return 180.0;
 
  300     return m_surfacePoint;
 
  309   bool ShapeModel::hasIntersection() {
 
  310     return m_hasIntersection;
 
  319   bool ShapeModel::hasNormal()
 const {
 
  327   void ShapeModel::clearSurfacePoint() {
 
  328     setHasIntersection(
false);
 
  329     m_hasEllipsoidIntersection = 
false;
 
  342   std::vector<double> ShapeModel::normal() {
 
  347       QString message = 
"The local normal has not been computed.";
 
  360   bool ShapeModel::hasValidTarget()
 const {
 
  361     return (m_target != NULL);
 
  376   std::vector<Distance> ShapeModel::targetRadii()
 const {
 
  377     if (hasValidTarget()) {
 
  378       return m_target->radii();
 
  381       QString message = 
"Unable to find target radii for ShapeModel. Target is NULL. ";
 
  398   void ShapeModel::setNormal(
const std::vector<double> normal) {
 
  399     if (m_hasIntersection) {
 
  404       QString message = 
"No intersection point in known.  A normal can not be set.";
 
  423   void ShapeModel::setNormal(
const double a, 
const double b, 
const double c) {
 
  424     if (m_hasIntersection) {
 
  431       QString message = 
"No intersection point in known.  A normal can not be set.";
 
  443   void ShapeModel::setName(QString name) {
 
  454   QString ShapeModel::name()
 const{
 
  465   void ShapeModel::setHasIntersection(
bool b) {
 
  466     m_hasIntersection  = b;
 
  477     *m_surfacePoint  = surfacePoint;
 
  480     m_hasIntersection  = 
true;
 
  492   void ShapeModel::setHasNormal(
bool status) {
 
  493     m_hasNormal = status;
 
  503   double ShapeModel::resolution() {
 
  504     if (hasValidTarget() && m_hasIntersection) {
 
  505       return m_target->spice()->resolution();
 
  508       QString message = 
"No valid intersection point for computing resolution.";
 
This class defines a body-fixed surface point. 
 
Unless noted otherwise, the portions of Isis written by the USGS are public domain. 
 
#define _FILEINFO_
Macro for the filename and line number. 
 
This class is used to create and store valid Isis3 targets. 
 
const double RAD2DEG(57.29577951308232087679815481)
Multiplier for converting from radians to degrees.