void inrypl_c ( ConstSpiceDouble vertex [3],
ConstSpiceDouble dir [3],
ConstSpicePlane * plane,
SpiceInt * nxpts,
SpiceDouble xpt [3] )
Find the intersection of a ray and a plane.
PLANES
GEOMETRY
Variable I/O Description
-------- --- --------------------------------------------------
vertex,
dir I Vertex and direction vector of ray.
plane I A CSPICE plane.
nxpts O Number of intersection points of ray and plane.
xpt O Intersection point, if nxpts = 1.
vertex,
dir are a point and direction vector that define a
ray in three-dimensional space.
plane is a CSPICE plane.
nxpts is the number of points of intersection of the
input ray and plane. Values and meanings of
nxpts are:
0 No intersection.
1 One point of intersection. Note that
this case may occur when the ray's
vertex is in the plane.
-1 An infinite number of points of
intersection; the ray lies in the plane.
xpt is the point of intersection of the input ray
and plane, when there is exactly one point of
intersection.
If the ray lies in the plane, xpt is set equal to
vertex.
If there is no intersection, xpt is the zero vector.
None.
1) If the ray's direction vector is the zero vector, the error
SPICE(ZEROVECTOR) is signaled. nxpts and xpt are not
modified.
2) If the ray's vertex is further than dpmax_c() / 3 from the
origin, the error SPICE(VECTORTOOBIG) is signaled. nxpts
and xpt are not modified.
3) If the input plane is s further than dpmax_c() / 3 from the
origin, the error SPICE(VECTORTOOBIG) is signaled. nxpts
and xpt are not modified.
4) The input plane should be created by one of the CSPICE
routines
nvc2pl_c
nvp2pl_c
psv2pl_c
Invalid input planes will cause unpredictable results.
5) In the interest of good numerical behavior, in the case
where the ray's vertex is not in the plane, this routine
considers that an intersection of the ray and plane occurs
only if the distance between the ray's vertex and the
intersection point is less than dpmax_c() / 3.
If vertex is not in the plane and this condition is not
met, then nxpts is set to 0 and xpt is set to the zero
vector.
None.
The intersection of a ray and plane in three-dimensional space
can be a the empty set, a single point, or the ray itself.
1) Find the camera projection of the center of an extended
body. For simplicity, we assume:
-- The camera has no distortion; the image of a point
is determined by the intersection of the focal plane
and the line determined by the point and the camera's
focal point.
-- The camera's pointing matrix (C-matrix) is available
in a C-kernel.
/.
Load Leapseconds and SCLK kernels to support time
conversion.
./
furnsh_c ( "leap.ker" );
furnsh_c ( "sclk.ker" );
/.
Load an SPK file containing ephemeris data for
observer (a spacecraft, whose NAIF integer code
is sc) and target at the UTC epoch of observation.
./
furnsh_c ( "spk.bsp" );
/.
Load a C-kernel containing camera pointing for
the UTC epoch of observation.
./
furnsh_c ( "ck.bc" ) ;
/.
Find the ephemeris time (barycentric dynamical time)
and encoded spacecraft clock times corresponding to
the UTC epoch of observation.
./
utc2et_c ( utc, &et );
sce2c_c ( sc, et, &sclkdp );
/.
Encode the pointing lookup tolerance.
./
sctiks_c ( sc, tolch, &toldp );
/.
Find the observer-target vector at the observation
epoch. In this example, we'll use a light-time and stellar
aberration corrected state vector.
./
spkez_c ( target, et, "J2000", "LT+S", sc, state, < );
/.
Look up camera pointing.
./
ckgp_c ( camera, sclkdp, toldp, "J2000", cmat, &clkout,
&found );
if ( !found )
{
/.
No pointing was available.
./
[Handle this case...]
return;
}
/.
Negate the spacecraft-to-target body vector and
convert it to camera coordinates.
./
vminus_c ( state, dir );
mxv_c ( cmat, dir, dir );
/.
If FL is the camera's focal length, the effective
focal point is
FL * ( 0, 0, 1 )
./
vscl_c ( FL, zvec, focus );
/.
The camera's focal plane contains the origin in
camera coordinates, and the z-vector is orthogonal
to the plane. Make a CSPICE plane representing
the focal plane.
./
nvc2pl_c ( zvec, 0., &fplane );
/.
The image of the target body's center in the focal
plane is defined by the intersection with the focal
plane of the ray whose vertex is the focal point and
whose direction is dir.
./
inrypl_c ( focus, dir, fplane, &nxpts, image );
if ( nxpts == 1 )
{
/.
The body center does project to the focal plane.
Check whether the image is actually in the
camera's field of view...
./
[Handle this case...]
}
else
{
/.
The body center does not map to the focal plane.
./
[Handle this case...]
}
2) Find the Saturn ring plane intercept of a spacecraft-mounted
instrument's boresight vector. We want the find the point
in the ring plane that will be observed by an instrument
with a give boresight direction at a specified time. We
must account for light time and stellar aberration in order
to find this point. The intercept point will be expressed
in Saturn body-fixed coordinates.
-- The ring plane is equatorial.
-- Light travels in a straight line.
-- The light time correction for the ring plane intercept
can be obtained by performing three light-time
correction iterations. If this assumption does not
lead to a sufficiently accurate result, additional
iterations can be performed.
-- A Newtonian approximation of stellar aberration
suffices.
-- The boresight vector is given in J2000 coordinates.
-- The observation epoch is et ephemeris seconds past
J2000.
-- The boresight vector, spacecraft and planetary
ephemerides, and ring plane orientation are all known
with sufficient accuracy for the application.
-- All necessary kernels are loaded by the caller of
this example routine.
(A similar technique could be used to obtain low-accuracy
predictions of radio occultations. In that case, the
instrument boresight ray's direction vector would be replaced
by the vector from the observer to the light-time corrected
radio source position.)
We omit display of the portion of the code that loads SPICE
kernels.
#include "SpiceUsr.h"
#include "SpiceZfc.h"
void ring_xpt ( ConstSpiceChar * sc,
SpiceDouble et,
ConstSpiceDouble borvec[3],
SpiceDouble * sbfxpt,
SpiceBoolean * found )
{
/.
Local constants
./
#define SATURN 699
/.
Local variables
./
SpiceBoolean fnd;
SpiceDouble borv2 [3];
SpiceDouble corvec [3];
SpiceDouble lt;
SpiceDouble satssb [6];
SpiceDouble scpos [3];
SpiceDouble scssb [6];
SpiceDouble state [6];
SpiceDouble stcorr [3];
SpiceDouble tau;
SpiceDouble tipm [3][3];
SpiceDouble xpt [3];
SpiceDouble zvec [3];
SpiceInt i;
SpiceInt nxpts;
SpiceInt scid;
SpicePlane plane;
/.
First step: account for stellar aberration. Since the
instrument pointing is given, we need to find the intercept
point such that, when the stellar aberration correction is
applied to the vector from the spacecraft to that point,
the resulting vector is parallel to borvec. An easy solution
is to apply the inverse of the normal stellar aberration
correction to borvec, and then solve the intercept problem
with this corrected boresight vector.
Find the position of the observer relative
to the solar system barycenter at et.
./
bodn2c_c ( sc, &scid, &fnd );
if ( !fnd )
{
setmsg_c ( "ID code for body # was not found." );
errch_c ( "#", sc );
sigerr_c ( "SPICE(NOTRANSLATION" );
return;
}
spkssb_c ( scid, et, "j2000", scssb );
/.
We now wish to find the vector corvec that, when corrected for
stellar aberration, yields borvec. A good first approximation is
obtained by applying the stellar aberration correction for
transmission to borvec. Note that the routine called is not
a wrapper, so there is no letter 'c' at the end of its name.
The prototype for this routine is declared in SpiceZfc.h.
./
stlabx_ ( (doublereal *) borvec, scssb+3, corvec );
/.
The inverse of the stellar aberration correction
applicable to corvec should be a very good estimate of
the correction we need to apply to borvec. Apply
this correction to borvec to obtain an improved estimate
of corvec.
./
stelab_c ( corvec, scssb+3, borv2 );
vsub_c ( borv2, corvec, stcorr );
vsub_c ( borvec, stcorr, corvec );
/.
Because the ring plane intercept may be quite far from
Saturn's center, we cannot assume light time from the intercept
to the observer is well approximated by light time from
Saturn's center to the observer. We compute the light time
explicitly using an iterative approach.
We can however use the light time from Saturn's center to
the observer to obtain a first estimate of the actual light
time.
./
spkezr_c ( "SATURN", et, "J2000", "LT", sc, state, < );
tau = lt;
/.
Find the ring plane intercept and calculate the
light time from it to the spacecraft.
Perform three iterations.
./
i = 0;
*found = SPICETRUE;
while ( ( i < 3 ) && ( *found ) )
{
/.
Find the position of Saturn relative
to the solar system barycenter at et-tau.
./
spkssb_c ( SATURN, et-tau, "J2000", satssb );
/.
Find the Saturn-to-observer vector defined by these
two position vectors.
./
vsub_c ( scssb, satssb, scpos );
/.
Look up Saturn's pole at et-tau; this is the third
row of the matrix that transforms J2000
coordinates to Saturn body-fixed coordinates.
./
pxform_c ( "J2000", "IAU_SATURN", et-tau, tipm );
vequ_c ( tipm[2], zvec );
/.
Make a CSPICE plane representing the ring plane.
We're treating Saturn's center as the origin, so
the plane constant is 0.
./
nvc2pl_c ( zvec, 0.0, &plane );
/.
Find the intersection of the ring plane and the
ray having vertex scpos and direction vector
corvec.
./
inrypl_c ( scpos, corvec, &plane, &nxpts, xpt );
/.
If the number of intersection points is 1,
find the next light time estimate.
./
if ( nxpts == 1 )
{
/.
Find the light time (zero-order) from the
intercept point to the spacecraft.
./
tau = vdist_c ( scpos, xpt ) / clight_c();
i++;
}
else
{
*found = SPICEFALSE;
}
}
/.
At this point, if found is SPICETRUE, we iterated
three times, and xpt is our estimate of the
position of the ring plane intercept point
relative to Saturn in the J2000 frame. This is the
point observed by an instrument pointed in direction
borvec at et at mounted on the spacecraft sc.
If found is SPICEFALSE, the boresight ray does not
intersect the ring plane.
As a final step, tranform xpt to Saturn body-fixed
coordinates.
./
if ( *found )
{
mxv_c ( tipm, xpt, sbfxpt );
}
}
None.
None.
N.J. Bachman (JPL)
B.V. Semenov (JPL)
W.L. Taber (JPL)
-CSPICE Version 1.0.2, 01-FEB-2017 (BVS)
Typo fix: pnv2pl_c -> nvp2pl_c.
-CSPICE Version 1.0.1, 12-DEC-2002 (NJB)
Header fix: ring plane intercept algorithm was corrected.
Now light time is computed accurately, and stellar aberration
is accounted for. Example was turned into a complete
subroutine.
-CSPICE Version 1.0.0, 26-JUN-1999 (NJB)
intersection of ray and plane
Link to routine inrypl_c source file inrypl_c.c
|