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