USGS

Isis 3.0 Object Programmers' Reference

Home

PlaneShape.cpp
1 #include <algorithm>
2 #include <cfloat>
3 #include <string>
4 #include <vector>
5 
6 #include <cmath>
7 #include <iomanip>
8 
9 #include "PlaneShape.h"
10 
11 #include "Distance.h"
12 #include "IException.h"
13 #include "Latitude.h"
14 #include "Longitude.h"
15 #include "NaifStatus.h"
16 #include "ShapeModel.h"
17 #include "SurfacePoint.h"
18 
19 namespace Isis {
25  PlaneShape::PlaneShape(Target *target, Pvl &pvl) : ShapeModel (target, pvl) {
26  setName("Plane");
27 
28  // set surface normal
29 // setNormal(0.0, 0.0, 1.0);
30  }
31 
32 
39  setName("Plane");
40 
41  // set normal vector
42 // setNormal(0.0, 0.0, 1.0);
43  }
44 
45 
52  setName("Plane");
53  }
54 
55 
64  bool PlaneShape::intersectSurface (std::vector<double> observerPos,
65  std::vector<double> lookDirection) {
66  SpiceDouble zvec[3];
67  SpicePlane plane;
68  SpiceInt nxpts;
69  SpiceDouble xpt[3];
70 
71 // std::vector<double> n = normal();
72 
73 // zvec[0] = n[0];
74 // zvec[1] = n[1];
75 // zvec[2] = n[2];
76  zvec[0] = 0.0;
77  zvec[1] = 0.0;
78  zvec[2] = 1.0;
79 
80  if (observerPos[2] < 0.0)
81  zvec[2] = -zvec[2];
82 
83  // NAIF routine to "Make a CSPICE plane from a normal vector and a constant"
84  // see http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/nvc2pl_c.html
85  nvc2pl_c(zvec, 0.0, &plane);
86 
87  SpiceDouble position[3];
88  SpiceDouble lookvector[3];
89 
90  position[0] = observerPos[0];
91  position[1] = observerPos[1];
92  position[2] = observerPos[2];
93 
94  lookvector[0] = lookDirection[0];
95  lookvector[1] = lookDirection[1];
96  lookvector[2] = lookDirection[2];
97 
98  // NAIF routine to "find the intersection of a ray and a plane"
99  // see http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/inrypl_c.html
100  inrypl_c(&position, &lookvector, &plane, &nxpts, xpt);
101 
102  if (nxpts != 1 ) {
103  setHasIntersection(false);
104  return false;
105  }
106 
107  setHasIntersection(true);
108  setNormal(0.0,0.0,1.0);
110 
111  return true;
112  }
113 
114 
130  double PlaneShape::emissionAngle(const std::vector<double> & sB) {
131 
132  SpiceDouble pB[3]; // surface intersection in body-fixed coordinates
133  SpiceDouble psB[3]; // vector from spacecraft to surface intersection
134  SpiceDouble upsB[3]; // unit vector from spacecraft to surface intersection
135  SpiceDouble dist; // vector magnitude
136 
137  // Get vector from center of body to surface point
138  pB[0] = surfaceIntersection()->GetX().kilometers();
139  pB[1] = surfaceIntersection()->GetY().kilometers();
140  pB[2] = surfaceIntersection()->GetZ().kilometers();
141 
142  // Get vector from surface intersect point to observer and normalize it
143  vsub_c((ConstSpiceDouble *) &sB[0], pB, psB);
144  unorm_c(psB, upsB, &dist);
145 
146  // temporary normal vector
147  SpiceDouble n[3];
148  n[0] = 0.0;
149  n[1] = 0.0;
150  n[2] = 1.0;
151 
152  // flip normal if observer is "below" the plane, assuming that the target
153  // body north pole defines the "up" direction
154  if (sB[2] < 0.0)
155  n[2] = -n[2];
156 
157  // dot product of surface normal and observer-surface intersection vector
158  double angle = vdot_c(n, upsB);
159 
160  if (angle > 1.0)
161  return 0.0;
162 
163  if (angle < -1.0)
164  return 180.0;
165 
166  return acos(angle) * RAD2DEG;
167  }
168 
169 
187  double PlaneShape::incidenceAngle(const std::vector<double> &uB) {
188 
189  SpiceDouble pB[3]; // surface intersection in body-fixed coordinates
190  SpiceDouble puB[3]; // vector from sun to surface intersection
191  SpiceDouble upuB[3]; // unit vector from sun to surface intersection
192  SpiceDouble dist; // vector magnitude
193 
194  // Get vector from center of body to surface point
195  pB[0] = surfaceIntersection()->GetX().kilometers();
196  pB[1] = surfaceIntersection()->GetY().kilometers();
197  pB[2] = surfaceIntersection()->GetZ().kilometers();
198 
199  // Get vector from surface intersect point to sun and normalize it
200  vsub_c((SpiceDouble *) &uB[0], pB, puB);
201  unorm_c(puB, upuB, &dist);
202 
203  // temporary normal vector
204  SpiceDouble n[3];
205  n[0] = 0.0;
206  n[1] = 0.0;
207  n[2] = 1.0;
208 
209  // flip normal if sun is "below" the plane, assuming that the target
210  // body north pole defines the "up" direction
211  if (uB[2] < 0.0)
212  n[2] = -n[2];
213 
214  double angle = vdot_c((SpiceDouble *) &n[0], upuB);
215 
216  if (angle > 1.0)
217  return 0.0;
218 
219  if(angle < -1.0)
220  return 180.0;
221 
222  return acos(angle) * RAD2DEG;
223  }
224 
225 
229  // TODO: what should this do in the case of a ring plane (or any other plane
230  // for that matter)?
232 
233  SpiceDouble pB[3]; // surface intersection in body-fixed coordinates
234 
235  // Get vector from center of body to surface point
236  pB[0] = surfaceIntersection()->GetX().kilometers();
237  pB[1] = surfaceIntersection()->GetY().kilometers();
238  pB[2] = surfaceIntersection()->GetZ().kilometers();
239 
240  double radius = sqrt(pB[0]*pB[0] + pB[1]*pB[1] + pB[2]*pB[2]);
241 
242  return Distance(radius, Distance::Kilometers);
243  }
244 }