1 /* npsgpt.f -- translated by f2c (version 19980913).
2    You must link the resulting object file with the libraries:
3 	-lf2c -lm   (in that order)
4 */
5 
6 #include "f2c.h"
7 
8 /* $Procedure      NPSGPT ( Nearest point on line segment ) */
npsgpt_(doublereal * ep1,doublereal * ep2,doublereal * point,doublereal * pnear,doublereal * dist)9 /* Subroutine */ int npsgpt_(doublereal *ep1, doublereal *ep2, doublereal *
10 	point, doublereal *pnear, doublereal *dist)
11 {
12     extern doublereal vdot_(doublereal *, doublereal *);
13     extern /* Subroutine */ int vsub_(doublereal *, doublereal *, doublereal *
14 	    ), vequ_(doublereal *, doublereal *);
15     doublereal lnear[3];
16     extern doublereal vdist_(doublereal *, doublereal *);
17     extern logical vzero_(doublereal *), failed_(void);
18     doublereal offdot, segdot, offset[3];
19     extern /* Subroutine */ int nplnpt_(doublereal *, doublereal *,
20 	    doublereal *, doublereal *, doublereal *);
21     extern logical return_(void);
22     doublereal seg[3];
23 
24 /* $ Abstract */
25 
26 /*     Find the nearest point on a line segment to a given point. */
27 
28 /* $ Disclaimer */
29 
30 /*     THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE */
31 /*     CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. */
32 /*     GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE */
33 /*     ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE */
34 /*     PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" */
35 /*     TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY */
36 /*     WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A */
37 /*     PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC */
38 /*     SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE */
39 /*     SOFTWARE AND RELATED MATERIALS, HOWEVER USED. */
40 
41 /*     IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA */
42 /*     BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT */
43 /*     LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, */
44 /*     INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, */
45 /*     REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE */
46 /*     REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. */
47 
48 /*     RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF */
49 /*     THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY */
50 /*     CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE */
51 /*     ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. */
52 
53 /* $ Required_Reading */
54 
55 /*     None. */
56 
57 /* $ Keywords */
58 
59 /*     GEOMETRY */
60 /*     MATH */
61 
62 /* $ Declarations */
63 /* $ Brief_I/O */
64 
65 /*     Variable  I/O  Description */
66 /*     --------  ---  -------------------------------------------------- */
67 /*     EP1, */
68 /*     EP2        I   Endpoints of a line segment. */
69 /*     POINT      I   A point in 3-dimensional space. */
70 /*     PNEAR      O   Nearest point on the line segment to POINT. */
71 /*     DIST       O   Distance between PNEAR and POINT. */
72 
73 /* $ Detailed_Input */
74 
75 /*     EP1, */
76 /*     EP2        are the endpoints of a line segment in 3-dimensional */
77 /*                space. EP1 and EP2 need not be distinct. */
78 
79 /*     POINT      is an arbitrary point in 3-dimensional space. */
80 
81 /* $ Detailed_Output */
82 
83 /*     PNEAR      is the closest point on the line segment to POINT. */
84 
85 /*     DIST       is the distance between POINT and PNEAR. */
86 
87 /* $ Parameters */
88 
89 /*     None. */
90 
91 /* $ Exceptions */
92 
93 /*     1) The input segment is allowed to be degenerate: it may be */
94 /*        a single point. */
95 
96 /* $ Files */
97 
98 /*     None. */
99 
100 /* $ Particulars */
101 
102 /*     None. */
103 
104 /* $ Examples */
105 
106 /*     The numerical results shown for these examples may differ across */
107 /*     platforms. The results depend on the SPICE kernels used as input */
108 /*     (if any), the compiler and supporting libraries, and the machine */
109 /*     specific arithmetic implementation. */
110 
111 /*     1) Compute the nearest point on a line segment to a given */
112 /*        point in a simple case for which the results can easily be */
113 /*        checked. */
114 
115 
116 /*        Example code begins here. */
117 
118 
119 /*              PROGRAM EX1 */
120 /*              IMPLICIT NONE */
121 /*        C */
122 /*        C     Local parameters */
123 /*        C */
124 /*              CHARACTER*(*)         FMT1 */
125 /*              PARAMETER           ( FMT1 = '(A,3F13.8)' ) */
126 /*        C */
127 /*        C     Local variables */
128 /*        C */
129 /*              DOUBLE PRECISION      DIST */
130 /*              DOUBLE PRECISION      ENDPT1 ( 3 ) */
131 /*              DOUBLE PRECISION      ENDPT2 ( 3 ) */
132 /*              DOUBLE PRECISION      PNEAR  ( 3 ) */
133 /*              DOUBLE PRECISION      POINT  ( 3 ) */
134 
135 /*        C */
136 /*        C     Initialize the line segment's endpoints. */
137 /*        C */
138 /*              CALL VPACK ( 1.D0, -2.D0, 3.D0, ENDPT1 ) */
139 /*              CALL VPACK ( 1.D0,  2.D0, 3.D0, ENDPT2 ) */
140 /*        C */
141 /*        C     Set the input point. */
142 /*        C */
143 /*              CALL VPACK ( 1.D0,  0.D0, 0.D0, POINT ) */
144 /*        C */
145 /*        C     Find the near point on the segment. */
146 /*        C */
147 /*              CALL NPSGPT ( ENDPT1, ENDPT2, POINT, PNEAR, DIST ) */
148 
149 /*              WRITE (*,*) ' ' */
150 /*              WRITE (*,FMT1) 'Endpoint 1:  ', ENDPT1 */
151 /*              WRITE (*,FMT1) 'Endpoint 2:  ', ENDPT2 */
152 /*              WRITE (*,FMT1) 'Point:       ', POINT */
153 /*              WRITE (*,*) ' ' */
154 /*              WRITE (*,FMT1) 'Near point:  ', PNEAR */
155 /*              WRITE (*,FMT1) 'Distance:    ', DIST */
156 /*              WRITE (*,*) ' ' */
157 
158 /*              END */
159 
160 
161 /*     When this program was executed on a PC/Linux/gfortran/64-bit */
162 /*     platform, the output was: */
163 
164 
165 /*        Endpoint 1:     1.00000000  -2.00000000   3.00000000 */
166 /*        Endpoint 2:     1.00000000   2.00000000   3.00000000 */
167 /*        Point:          1.00000000   0.00000000   0.00000000 */
168 
169 /*        Near point:     1.00000000   0.00000000   3.00000000 */
170 /*        Distance:       3.00000000 */
171 
172 
173 /* $ Restrictions */
174 
175 /*     None. */
176 
177 /* $ Literature_References */
178 
179 /*     None. */
180 
181 /* $ Author_and_Institution */
182 
183 /*     N.J. Bachman   (JPL) */
184 
185 /* $ Version */
186 
187 /* -    SPICELIB Version 1.0.0, 02-FEB-MAR-2016 (NJB) */
188 
189 /*        Updated from DSKLIB Version 1.0.0, 20-MAR-2015 (NJB) */
190 
191 /* -& */
192 /* $ Index_Entries */
193 
194 /*     nearest point on line segment */
195 
196 /* -& */
197 
198 /*     SPICELIB functions */
199 
200 
201 /*     Local variables */
202 
203 
204 /*     Use discovery check-in. */
205 
206     if (return_()) {
207 	return 0;
208     }
209 
210 /*     Find a direction vector defined by the endpoints. */
211 
212     vsub_(ep2, ep1, seg);
213     if (vzero_(seg)) {
214 
215 /*        The endpoints coincide, and both coincide with the */
216 /*        near point. */
217 
218 	vequ_(ep1, pnear);
219 	*dist = vdist_(ep1, point);
220 	return 0;
221     }
222 
223 /*     Find the nearest point to POINT on the line defined by */
224 /*     EP1 and SEG. */
225 
226     nplnpt_(ep1, seg, point, lnear, dist);
227     if (failed_()) {
228 	return 0;
229     }
230 
231 /*     Determine whether LNEAR is on the segment, "before" EP1, or */
232 /*     "after" EP2, where SEG points in the "increasing" direction. */
233 
234     vsub_(lnear, ep1, offset);
235     offdot = vdot_(offset, seg);
236     if (offdot < 0.) {
237 
238 /*        The nearest point on the line precedes the first endpoint. */
239 /*        The closest point on the segment is the first endpoint. */
240 
241 	vequ_(ep1, pnear);
242 	*dist = vdist_(ep1, point);
243     } else {
244 
245 /*        See whether OFFSET is past the second endpoint. Compare */
246 /*        the dot product of OFFSET with SEG to that of SEG with */
247 /*        itself, since SEG is the offset of EP2 from EP1. */
248 
249 	segdot = vdot_(seg, seg);
250 	if (offdot > segdot) {
251 
252 /*           The nearest point on the line follows the last endpoint. */
253 /*           The closest point on the segment is the last endpoint. */
254 
255 	    vequ_(ep2, pnear);
256 	    *dist = vdist_(ep2, point);
257 	} else {
258 
259 /*           The near point is on the segment. LNEAR is actually the */
260 /*           solution. */
261 
262 	    vequ_(lnear, pnear);
263 
264 /*           DIST was correctly set by the call to NPLNPT. */
265 
266 	}
267     }
268     return 0;
269 } /* npsgpt_ */
270 
271