1313
1414 Author: Adrian Baddeley 2018-2021
1515
16- Copyright (C) Adrian Baddeley, Ege Rubak and Rolf Turner 2001-2021
16+ Copyright (C) Adrian Baddeley, Ege Rubak and Rolf Turner 2001-2026
1717 Licence: GNU Public Licence >= 2
1818
19- $Revision: 1.3 $ $Date: 2022/10/19 02:58:46 $
19+ $Revision: 1.5 $ $Date: 2026/05/02 07:03:14 $
2020
2121*/
2222
2323void
2424FNAME (
2525 /* input */
2626 double * xp ,
27- double * yp , /* point/ pixel coordinates */
27+ double * yp , /* point (or pixel) coordinates */
2828 int * npoints ,
2929 double * x0 ,
3030 double * y0 ,
3333 int * nsegments ,
3434 double * epsilon , /* tolerance for short segments */
3535 /* output */
36- double * dist2 /* squared distance from pixel
36+ double * dist2 /* squared distance from point
3737 to nearest line segment
3838 INITIALISED TO LARGE VALUE */
3939#ifdef WANT_INDEX
@@ -42,9 +42,15 @@ FNAME(
4242) {
4343 int i ,j , np , nseg , maxchunk ;
4444 double dx ,dy ,leng ,co ,si ; /* parameters of segment */
45+ double xpi , ypi , x0j , y0j , x1j , y1j ; /* coordinates */
4546 double xdif0 ,ydif0 ,xdif1 ,ydif1 ,xpr ,ypr ; /* vectors */
4647 double dsq0 ,dsq1 ,dsq ,dsqperp ; /* squared distances */
4748 double eps ;
49+ double * xpp , * ypp ; /* pointers into data xp[], yp[] */
50+ double * dist2p ; /* pointer into dist2[] */
51+ #ifdef WANT_INDEX
52+ int * indexp ; /* pointer into index[] */
53+ #endif
4854
4955 np = * npoints ;
5056 nseg = * nsegments ;
@@ -53,55 +59,90 @@ FNAME(
5359 OUTERCHUNKLOOP (j , nseg , maxchunk , 16384 ) {
5460 R_CheckUserInterrupt ();
5561 INNERCHUNKLOOP (j , nseg , maxchunk , 16384 ) {
56- dx = x1 [j ] - x0 [j ];
57- dy = y1 [j ] - y0 [j ];
62+ /* segment j coordinates */
63+ x0j = x0 [j ];
64+ y0j = y0 [j ];
65+ x1j = x1 [j ];
66+ y1j = y1 [j ];
67+ /* segment j geometry */
68+ dx = x1j - x0j ;
69+ dy = y1j - y0j ;
5870 leng = hypot (dx , dy );
71+ /* loop over points */
5972 if (leng > eps ) {
6073 /* normal case */
6174 co = dx /leng ;
6275 si = dy /leng ;
63- for (i = 0 ; i < np ; i ++ ) {
64- /* vectors from pixel to segment endpoints */
65- xdif0 = xp [i ] - x0 [j ];
66- ydif0 = yp [i ] - y0 [j ];
67- xdif1 = xp [i ] - x1 [j ];
68- ydif1 = yp [i ] - y1 [j ];
76+ for (
77+ #ifdef WANT_INDEX
78+ i = np , xpp = xp , ypp = yp , dist2p = dist2 , indexp = index ;
79+ i > 0 ;
80+ i -- , xpp ++ , ypp ++ , dist2p ++ , indexp ++
81+ #else
82+ i = np , xpp = xp , ypp = yp , dist2p = dist2 ;
83+ i > 0 ;
84+ i -- , xpp ++ , ypp ++ , dist2p ++
85+ #endif
86+ ) {
87+ /* point i coordinates */
88+ xpi = * xpp ;
89+ ypi = * ypp ;
90+ /* vectors from point i to endpoints of segment j */
91+ xdif0 = xpi - x0j ;
92+ ydif0 = ypi - y0j ;
93+ xdif1 = xpi - x1j ;
94+ ydif1 = ypi - y1j ;
6995 /* squared distances to segment endpoints */
7096 dsq0 = xdif0 * xdif0 + ydif0 * ydif0 ;
7197 dsq1 = xdif1 * xdif1 + ydif1 * ydif1 ;
7298 dsq = (dsq0 < dsq1 ) ? dsq0 : dsq1 ;
7399 /* rotate pixel around 1st endpoint of segment
74100 so that line segment lies in x axis */
75101 xpr = xdif0 * co + ydif0 * si ;
76- ypr = - xdif0 * si + ydif0 * co ;
77102 /* perpendicular distance applies only in perpendicular region */
78103 if (xpr >= 0.0 && xpr <= leng ) {
104+ ypr = - xdif0 * si + ydif0 * co ;
79105 dsqperp = ypr * ypr ;
80106 if (dsqperp < dsq ) dsq = dsqperp ;
81107 }
82- if (dist2 [i ] > dsq ) {
83- dist2 [i ] = dsq ;
108+ /* update minimum distance for pixel i */
109+ if (* dist2p > dsq ) {
110+ * dist2p = dsq ;
84111#ifdef WANT_INDEX
85- index [ i ] = j ;
112+ * indexp = j ;
86113#endif
87114 }
88115 }
89116 } else {
90117 /* short segment - use endpoints only */
91- for (i = 0 ; i < np ; i ++ ) {
92- /* vectors from pixel to segment endpoints */
93- xdif0 = xp [i ] - x0 [j ];
94- ydif0 = yp [i ] - y0 [j ];
95- xdif1 = xp [i ] - x1 [j ];
96- ydif1 = yp [i ] - y1 [j ];
118+ for (
119+ #ifdef WANT_INDEX
120+ i = np , xpp = xp , ypp = yp , dist2p = dist2 , indexp = index ;
121+ i > 0 ;
122+ i -- , xpp ++ , ypp ++ , dist2p ++ , indexp ++
123+ #else
124+ i = np , xpp = xp , ypp = yp , dist2p = dist2 ;
125+ i > 0 ;
126+ i -- , xpp ++ , ypp ++ , dist2p ++
127+ #endif
128+ ) {
129+ /* point i coordinates */
130+ xpi = * xpp ;
131+ ypi = * ypp ;
132+ /* vectors from point i to endpoints of segment j */
133+ xdif0 = xpi - x0j ;
134+ ydif0 = ypi - y0j ;
135+ xdif1 = xpi - x1j ;
136+ ydif1 = ypi - y1j ;
97137 /* squared distances to segment endpoints */
98138 dsq0 = xdif0 * xdif0 + ydif0 * ydif0 ;
99139 dsq1 = xdif1 * xdif1 + ydif1 * ydif1 ;
100140 dsq = (dsq0 < dsq1 ) ? dsq0 : dsq1 ;
101- if (dist2 [i ] > dsq ) {
102- dist2 [i ] = dsq ;
141+ /* update minimum distance for pixel i */
142+ if (* dist2p > dsq ) {
143+ * dist2p = dsq ;
103144#ifdef WANT_INDEX
104- index [ i ] = j ;
145+ * indexp = j ;
105146#endif
106147 }
107148 }
0 commit comments