Isis 3 Programmer Reference
Stereo.cpp
Go to the documentation of this file.
1 
24 #include <cmath>
25 #include <cstdlib>
26 #include <sstream>
27 #include <iostream>
28 #include <iomanip>
29 
30 #include <SpiceUsr.h>
31 #include <SpiceZfc.h>
32 #include <SpiceZmc.h>
33 
34 #include "Camera.h"
35 #include "TProjection.h"
36 #include "SpecialPixel.h"
37 #include "Stereo.h"
38 
39 namespace Isis {
40 
41  bool Stereo::elevation(Camera &cam1, Camera &cam2, double &radius,
42  double &latitude, double &longitude,
43  double &sepang, double &error) {
44 
45  // Gut check on input Camera points
46  radius = latitude = longitude = Isis::Null;
47  if ( !cam1.HasSurfaceIntersection() ) return (false);
48  if ( !cam2.HasSurfaceIntersection() ) return (false);
49 
50  // Get spacecraft position from target
51  double TC1[3], TC2[3];
52  targetToSpacecraft(cam1, TC1);
53  targetToSpacecraft(cam2, TC2);
54 
55 
56  // Get surface vectors from center of body to surface
57  double TP1[3], TP2[3];
58  targetToSurface(cam1, TP1);
59  targetToSurface(cam2, TP2);
60 
61  // Stereo angle
62  sepang = vsep_c(TC1, TC2) * dpr_c();
63 
64  SpiceDouble CP1[3], CP2[3];
65  vsub_c(TC1, TP1, CP1);
66  vsub_c(TC2, TP2, CP2);
67 
68  sepang = vsep_c(CP1, CP2) * dpr_c();
69 
70  double DR1, DR2;
71  DR1 = vnorm_c(CP1);
72  DR2 = vnorm_c(CP2);
73 
74  vscl_c(1.0/DR1, CP1, CP1);
75  vscl_c(1.0/DR2, CP2, CP2);
76 
77  // Do stereo intersections
78  double aa = CP2[0];
79  double bb = CP2[1];
80  double cc = CP2[2];
81  double xx = CP1[0];
82  double yy = CP1[1];
83  double zz = CP1[2];
84 
85  // Vector between both spacecraft
86  double dd = TC2[0] - TC1[0];
87  double ee = TC2[1] - TC1[1];
88  double ff = TC2[2] - TC1[2];
89 
90  // Do the stereo intersection
91  double bzcy = bb*zz - cc*yy;
92  double cebf = cc*ee - bb*ff;
93  double cxaz = cc*xx - aa*zz;
94  double afcd = aa*ff - cc*dd;
95  double aybx = aa*yy - bb*xx;
96  double bdae = bb*dd - aa*ee;
97 
98  // Get fraction `T' along left vector to "intersection point"
99  double T=-(bzcy*cebf+cxaz*afcd+aybx*bdae)/
100  (bzcy*bzcy+cxaz*cxaz+aybx*aybx);
101  double lx=TC1[0] + T * CP1[0];
102  double ly=TC1[1] + T * CP1[1];
103  double lz=TC1[2] + T * CP1[2];
104 
105  // Find the Perp. vector between both lines (at shortest sep.)
106  double x = TC2[0] - lx;
107  double y = TC2[1] - ly;
108  double z = TC2[2] - lz;
109 
110  // Find the separation distance - useful later
111  double rx = y * CP2[2] - CP2[1] * z;
112  double ry = CP2[0] * z - x * CP2[2];
113  double rz = x * CP2[1] - CP2[0] * y;
114  double dr = std::sqrt(rx*rx+ry*ry+rz*rz);
115 
116  // Find position of intersection on lower line
117  rx = CP1[1] * CP2[2] - CP2[1] * CP1[2];
118  ry = CP2[0] * CP1[2] - CP1[0] * CP2[2];
119  rz = CP1[0] * CP2[1] - CP2[0] * CP1[1];
120  double raa = std::sqrt(rx*rx+ry*ry+rz*rz);
121 
122  // Normalize our new Perpendicular vector
123  rx = rx/raa;
124  ry = ry/raa;
125  rz = rz/raa;
126 
127  // Get the other intersection position
128  rx = lx - rx*dr;
129  ry = ly - ry*dr;
130  rz = lz - rz*dr;
131 
132  // Compute the mid point of the intersection on the planets
133  // surface
134  double mx = (lx+rx)/2.0;
135  double my = (ly+ry)/2.0;
136  double mz = (lz+rz)/2.0;
137  rectangular(mx, my, mz, latitude, longitude, radius);
138  radius *= 1000.0 ; // convert to meters
139  error = dr * 1000.0;
140  return (true);
141  }
142 
143 
144  void Stereo::spherical(const double latitude, const double longitude,
145  const double radius,
146  double &x, double &y, double &z) {
147  SpiceDouble rec[3];
148  latrec_c(radius/1000.0, longitude*rpd_c(), latitude*rpd_c(), &rec[0]);
149  x = rec[0];
150  y = rec[1];
151  z = rec[2];
152  return;
153  }
154 
155  void Stereo::rectangular(const double x, const double y, const double z,
156  double &latitude, double &longitude,
157  double &radius) {
158  SpiceDouble rec[3];
159  rec[0] = x;
160  rec[1] = y;
161  rec[2] = z;
162  reclat_c(&rec[0], &radius, &longitude, &latitude);
163  longitude *= dpr_c();
164  latitude *= dpr_c();
165  longitude = TProjection::To360Domain(longitude);
166  return;
167  return;
168  }
169 
170  std::vector<double> Stereo::array2StdVec(const double d[3]) {
171  std::vector<double> v;
172  for ( int i = 0 ; i < 3 ; i++ ) {
173  v.push_back(d[i]);
174  }
175  return (v);
176  }
177 
178  double *Stereo::stdVec2Array(const std::vector<double> &v, double *d) {
179  if ( d == NULL ) {
180  d = new double[v.size()];
181  }
182 
183  for ( unsigned int i = 0 ; i < v.size() ; i++ ) {
184  d[i] = v[i];
185  }
186  return (d);
187  }
188 
189  void Stereo::targetToSpacecraft(Camera &camera, double TP[3]) {
190  camera.instrumentPosition(TP);
191  return;
192  }
193 
194  void Stereo::targetToSurface(Camera &camera, double TC[3]) {
195  camera.Coordinate(TC);
196  return;
197  }
198 
199 }
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:110
static double To360Domain(const double lon)
This method converts a longitude into the 0 to 360 domain.
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31