inrypl_c |
Table of contents
Procedureinrypl_c ( Intersection of ray and plane ) void inrypl_c ( ConstSpiceDouble vertex [3], ConstSpiceDouble dir [3], ConstSpicePlane * plane, SpiceInt * nxpts, SpiceDouble xpt [3] ) AbstractFind the intersection of a ray and a plane. Required_ReadingPLANES KeywordsGEOMETRY Brief_I/OVARIABLE I/O DESCRIPTION -------- --- -------------------------------------------------- vertex, dir I Vertex and direction vector of ray. plane I A SPICE plane. nxpts O Number of intersection points of ray and plane. xpt O Intersection point, if nxpts = 1. Detailed_Inputvertex, dir are a point and direction vector that define a ray in three-dimensional space. plane is a SPICE plane. Detailed_Outputnxpts 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. ParametersNone. Exceptions1) 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 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. FilesNone. ParticularsThe intersection of a ray and plane in three-dimensional space can be a the empty set, a single point, or the ray itself. Examples1) 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 SPICE 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 SPICE 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, transform xpt to Saturn body-fixed coordinates. ./ if ( *found ) { mxv_c ( tipm, xpt, sbfxpt ); } } RestrictionsNone. Literature_ReferencesNone. Author_and_InstitutionN.J. Bachman (JPL) J. Diaz del Rio (ODC Space) B.V. Semenov (JPL) Version-CSPICE Version 1.0.3, 24-AUG-2021 (JDR) Edited the header to comply with NAIF standard. -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) Index_Entriesintersection of ray and plane |
Fri Dec 31 18:41:08 2021