1 /*
2 
3 -Procedure vsep_c  ( Angular separation of vectors, 3 dimensions )
4 
5 -Abstract
6 
7    Find the separation angle in radians between two double
8    precision, 3-dimensional vectors.  This angle is defined as zero
9    if either vector is zero.
10 
11 -Disclaimer
12 
13    THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE
14    CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S.
15    GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE
16    ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE
17    PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS"
18    TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY
19    WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A
20    PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC
21    SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
22    SOFTWARE AND RELATED MATERIALS, HOWEVER USED.
23 
24    IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA
25    BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT
26    LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND,
27    INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS,
28    REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE
29    REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY.
30 
31    RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF
32    THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY
33    CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE
34    ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE.
35 
36 -Required_Reading
37 
38    None.
39 
40 -Keywords
41 
42    ANGLE,  VECTOR
43 
44 */
45 
46    #include <math.h>
47    #include "SpiceUsr.h"
48    #undef    vsep_c
49 
50 
vsep_c(ConstSpiceDouble v1[3],ConstSpiceDouble v2[3])51    SpiceDouble vsep_c ( ConstSpiceDouble v1[3], ConstSpiceDouble v2[3] )
52 
53 /*
54 
55 -Brief_I/O
56 
57    VARIABLE  I/O  DESCRIPTION
58    --------  ---  --------------------------------------------------
59     v1        I     First vector.
60     v2        I     Second vector.
61 
62 
63 -Detailed_Input
64 
65    v1      is an arbitrary double precision, 3-dimensional vector.
66    v2      is also an arbitrary double precision, 3-dimensional
67             vector.  v1 or v2 or both may be the zero vector.
68 
69 -Detailed_Output
70 
71    vsep_c    is the angle between v1 and v2 expressed in radians.
72             vsep_c is strictly non-negative.  If either v1 or v2 is
73             the zero vector, then vsep_c is defined to be 0 radians.
74 
75 -Parameters
76 
77    None.
78 
79 -Particulars
80 
81    In the plane, it is a simple matter to calculate the angle
82    between two vectors once the two vectors have been made to be
83    unit length.  Then, since the two vectors form the two equal
84    sides of an isosceles triangle, the length of the third side
85    is given by the expression
86 
87           length = 2.0 * sin ( vsep /2.0 )
88 
89    The length is given by the magnitude of the difference of the
90    two unit vectors
91 
92           length = norm_c ( u1 - u2 )
93 
94    Once the length is found, the value of vsep_c may be calculated
95    by inverting the first expression given above as
96 
97           vsep  = 2.0 * arcsin ( length/2.0 )
98 
99    This expression becomes increasingly unstable when vsep_c gets
100    larger than PI/2 or 90 degrees.  In this situation (which is
101    easily detected by determining the sign of the dot product of
102    v1 and v2) the supplementary angle is calculated first and
103    then vsep_c is given by
104 
105           vsep  = pi - supplementary_angle
106 
107 -Examples
108 
109    The following table gives sample values for v1, v2 and vsep_c
110    implied by the inputs.
111 
112    v1                        v2                      vsep_c
113    -----------------------------------------------------------------
114    (1, 0, 0)                (1, 0, 0)                0.0
115    (1, 0, 0)                (0, 1, 0)                PI/2 (=1.571...)
116 
117 
118 -Restrictions
119 
120    The user is required to insure that the input vectors will not
121    cause floating point overflow upon calculation of the vector
122    dot product since no error detection or correction code is
123    implemented.  In practice, this is not a significant
124    restriction.
125 
126 -Exceptions
127 
128    Error free.
129 
130 -Files
131 
132    None
133 
134 -Author_and_Institution
135 
136    K.R. Gehringer  (JPL)
137    W.M. Owen       (JPL)
138    W.L. Taber      (JPL)
139 
140 -Literature_References
141 
142    None
143 
144 -Version
145 
146    -CSPICE Version 1.1.1, 17-APR-2006 (EDW)
147 
148       Typo correction to the value of PI/2 in the Examples
149       section, 1.571 instead of 1.71.
150 
151    -CSPICE Version 1.1.0, 22-OCT-1998 (NJB)
152 
153       Made input vectors const.
154 
155    -CSPICE Version 1.0.0, 08-FEB-1998   (EDW)
156 
157 -Index_Entries
158 
159    angular separation of 3-dimensional vectors
160 
161 -&
162 */
163 
164 { /* Begin vsep_c */
165 
166 
167    /*
168    Local variables
169 
170    The following declarations represent, respectively:
171 
172    Magnitudes of v1, v2
173    Either of the difference vectors: v1-v2 or v1-(-v2)
174    Unit vectors parallel to v1 and v2
175    */
176 
177    SpiceDouble     dmag1;
178    SpiceDouble     dmag2;
179    SpiceDouble     vtemp[3];
180    SpiceDouble     u1[3];
181    SpiceDouble     u2[3];
182    SpiceDouble     vsep;
183 
184 
185    /*
186    Calculate the magnitudes of v1 and v2; if either is 0, vsep = 0
187    */
188 
189    unorm_c ( v1, u1, &dmag1 );
190 
191    if ( dmag1 == 0.0 )
192       {
193       vsep = 0.0;
194       return vsep;
195       }
196 
197       unorm_c ( v2, u2, &dmag2 );
198 
199    if ( dmag2 == 0.0 )
200       {
201       vsep = 0.0;
202       return vsep;
203       }
204 
205    if ( vdot_c(u1,u2) > 0. )
206       {
207       vtemp[0] = u1[0] - u2[0];
208       vtemp[1] = u1[1] - u2[1];
209       vtemp[2] = u1[2] - u2[2];
210 
211       vsep = 2.00 * asin (0.50 * vnorm_c(vtemp));
212       }
213 
214    else if ( vdot_c(u1,u2) < 0. )
215       {
216       vtemp[0] = u1[0] + u2[0];
217       vtemp[1] = u1[1] + u2[1];
218       vtemp[2] = u1[2] + u2[2];
219 
220       vsep = pi_c() - 2.00 * asin (0.50 * vnorm_c(vtemp));
221       }
222 
223    else
224       {
225       vsep = halfpi_c();
226       }
227 
228 
229    return vsep;
230 
231 } /* End vsep_c */
232