27 ShapeModel::ShapeModel() {
49 ShapeModel::ShapeModel(
Target *target) {
58 void ShapeModel::Initialize() {
59 m_name =
new QString();
61 m_hasIntersection =
false;
63 m_normal.resize(3,0.);
64 m_hasEllipsoidIntersection =
false;
68 ShapeModel::~ShapeModel() {
73 delete m_surfacePoint;
74 m_surfacePoint = NULL;
81 void ShapeModel::calculateEllipsoidalSurfaceNormal() {
87 if (!surfaceIntersection()->Valid() || !m_hasIntersection) {
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);
123 double ShapeModel::emissionAngle(
const std::vector<double> & sB) {
126 if (!hasNormal()) calculateDefaultNormal();
130 pB[0] = surfaceIntersection()->GetX().kilometers();
131 pB[1] = surfaceIntersection()->GetY().kilometers();
132 pB[2] = surfaceIntersection()->GetZ().kilometers();
135 SpiceDouble psB[3], upsB[3], dist;
136 vsub_c((ConstSpiceDouble *) &sB[0], pB, psB);
137 unorm_c(psB, upsB, &dist);
139 double angle = vdot_c((SpiceDouble *) &m_normal[0], upsB);
140 if(angle > 1.0)
return 0.0;
141 if(angle < -1.0)
return 180.0;
150 bool ShapeModel::hasEllipsoidIntersection() {
151 return m_hasEllipsoidIntersection;
160 double ShapeModel::incidenceAngle(
const std::vector<double> &uB) {
163 if (!m_hasNormal) calculateDefaultNormal();
167 pB[0] = surfaceIntersection()->GetX().kilometers();
168 pB[1] = surfaceIntersection()->GetY().kilometers();
169 pB[2] = surfaceIntersection()->GetZ().kilometers();
172 SpiceDouble puB[3], upuB[3], dist;
173 vsub_c((SpiceDouble *) &uB[0], pB, puB);
174 unorm_c(puB, upuB, &dist);
176 double angle = vdot_c((SpiceDouble *) &m_normal[0], upuB);
177 if(angle > 1.0)
return 0.0;
178 if(angle < -1.0)
return 180.0;
186 bool ShapeModel::intersectEllipsoid(
const std::vector<double> observerBodyFixedPosition,
187 const std::vector<double> &observerLookVectorToTarget) {
192 SpiceDouble lookB[3];
198 memcpy(lookB,&observerLookVectorToTarget[0], 3*
sizeof(
double));
201 std::vector<Distance> radii = targetRadii();
202 SpiceDouble a = radii[0].kilometers();
203 SpiceDouble b = radii[1].kilometers();
204 SpiceDouble c = radii[2].kilometers();
207 SpiceDouble intersectionPoint[3];
208 SpiceBoolean intersected =
false;
209 surfpt_c((SpiceDouble *) &observerBodyFixedPosition[0], lookB, a, b, c,
210 intersectionPoint, &intersected);
212 NaifStatus::CheckErrors();
215 m_surfacePoint->FromNaifArray(intersectionPoint);
216 m_hasIntersection =
true;
219 m_hasIntersection =
false;
222 m_hasEllipsoidIntersection = m_hasIntersection;
223 return m_hasIntersection;
232 double ShapeModel::phaseAngle(
const std::vector<double> & sB,
const std::vector<double> &uB) {
236 pB[0] = surfaceIntersection()->GetX().kilometers();
237 pB[1] = surfaceIntersection()->GetY().kilometers();
238 pB[2] = surfaceIntersection()->GetZ().kilometers();
241 SpiceDouble psB[3], upsB[3], dist;
242 vsub_c((SpiceDouble *) &sB[0], pB, psB);
243 unorm_c(psB, upsB, &dist);
246 SpiceDouble puB[3], upuB[3];
247 vsub_c((SpiceDouble *) &uB[0], pB, puB);
248 unorm_c(puB, upuB, &dist);
250 double angle = vdot_c(upsB, upuB);
253 if(angle > 1.0)
return 0.0;
254 if(angle < -1.0)
return 180.0;
263 return m_surfacePoint;
270 bool ShapeModel::hasIntersection() {
271 return m_hasIntersection;
278 bool ShapeModel::hasNormal()
const {
286 void ShapeModel::clearSurfacePoint() {
287 setHasIntersection(
false);
288 m_hasEllipsoidIntersection =
false;
297 std::vector<double> ShapeModel::normal() {
302 QString message =
"The local normal has not been computed.";
309 bool ShapeModel::hasValidTarget()
const {
310 return (m_target != NULL);
317 std::vector<Distance> ShapeModel::targetRadii()
const {
318 if (hasValidTarget()) {
319 return m_target->radii();
322 QString message =
"Unable to find target radii for ShapeModel. Target is NULL. ";
331 void ShapeModel::setNormal(
const std::vector<double> normal) {
332 if (m_hasIntersection) {
337 QString message =
"No intersection point in known. A normal can not be set.";
346 void ShapeModel::setNormal(
const double a,
const double b,
const double c) {
347 if (m_hasIntersection) {
354 QString message =
"No intersection point in known. A normal can not be set.";
363 void ShapeModel::setName(QString name) {
371 QString ShapeModel::name()
const{
379 void ShapeModel::setHasIntersection(
bool b) {
380 m_hasIntersection = b;
389 *m_surfacePoint = surfacePoint;
392 m_hasIntersection =
true;
401 void ShapeModel::setHasNormal(
bool status) {
402 m_hasNormal = status;
409 double ShapeModel::resolution() {
410 if (m_hasIntersection && hasValidTarget()) {
411 return m_target->spice()->resolution();
414 QString message =
"No valid intersection point for computing resolution.";