source: trunk/SRC/Interpolation/inquad.pro @ 101

Last change on this file since 101 was 101, checked in by pinsard, 18 years ago

start to modify headers of Interpolation *.pro files for better idldoc output

  • Property svn:executable set to *
File size: 9.6 KB
Line 
1;+
2; @file_comments to find if an (x,y) point is in a quadrilateral (x1,x2,x3,x4)
3;
4; @categories grid manipulation
5;
6; @examples
7;
8;     res = inquad(x, y, x1, y1, x2, y2, x3, y3, x4, y4)
9;
10;     @param x y {in}{required}  the coordinates of the point we want to know where it
11;     is. Must be a scalar if /onsphere activated else can be scalar
12;     or array.
13;
14;     @param x1 y1 x2 y2 x3 y3 x4 y4 {in}{required}  the coordinates of the
15;     quadrilateral given in the CLOCKWISE order. Scalar or array.
16;
17;
18; @keyword    /DOUBLE use double precision to perform the computation
19;
20; @keyword    /ONSPHERE to specify that the quadilateral are on a sphere and
21;    that teir coordinates are longitude-latitude coordinates. In this
22;    case, est-west periodicity, poles singularity and other pbs
23;    related to longitude-latitude coordinates are managed
24;    automatically.
25;
26; @keyword    ZOOMRADIUS :the zoom (circle centred on the (x,y) with a radius of
27;    zoomradius degree where we look for the the quadrilateral which;    contains the (x,y) point) used for the satellite projection
28;    when /onsphere is activated. Default is 4 and seems to be the
29;    minimum which can be used. Can be increase if the cell size is
30;    larger than 5 degrees.
31;   
32; @keyword    /NOPRINT to suppress the print messages.
33;
34; @returns
35;    a n element vector. Where n is the number of elements of
36;    x. res[i]=j means that the point number i is located in the
37;    quadrilateral number j with (0 <= j <= n_elements(x0)-1)
38;
39; @restrictions I think degenerated quadrilateral (e.g. flat of
40; twisted) is not work. This has to be tested.
41;
42; @examples
43;
44;       x = 1.*[1, 2, 6, 7, 3]
45;       y = 1.*[1, 3, 3, 4, 7]
46;       x1 = 1.*[0,4,2]
47;       y1 = 1.*[1,4,8]
48;       x2 = 1.*[1,6,4]
49;       y2 = 1.*[5,6,8]
50;       x3 = 1.*[3,8,4]
51;       y3 = 1.*[4,4,6]
52;       x4 = 1.*[2,6,2]
53;       y4 = 1.*[0,2,6]
54;       splot, [0,10], [0,10], xstyle = 1, ystyle = 1,/nodata
55;       for i=0,2 do oplot, [x4[i],x1[i],x2[i],x3[i],x4[i]],[y4[i],y1[i],y2[i],y3[i],y4[i]]
56;       oplot, x, y, color = 20, psym = 1, thick = 2
57;       print, inquad(x, y, x1, y1, x2, y2, x3, y3, x4, y4)
58;
59;      On a sphere see clickincell.pro...
60;
61; @history
62;      Sebastien Masson (smasson\@lodyc.jussieu.fr)
63;      August 2003
64;      Based on Convert_clic_ij.pro written by Gurvan Madec
65;
66;-
67FUNCTION inquad, x, y, x1, y1, x2, y2, x3, y3, x4, y4, ONSPHERE = onsphere,  DOUBLE = double, ZOOMRADIUS = zoomradius, NOPRINT = noprint, NEWCOORD = newcoord
68;
69;
70  ntofind = n_elements(x)
71  nquad = n_elements(x2)
72;
73  IF keyword_set(onsphere) THEN BEGIN
74; save the inputs parameters
75    xin = x
76    yin = y
77    x1in = x1
78    y1in = y1
79    x2in = x2
80    y2in = y2
81    x3in = x3
82    y3in = y3
83    x4in = x4
84    y4in = y4
85; for map_set
86    x = x MOD 360
87    x1 = x1 MOD 360
88    x2 = x2 MOD 360
89    x3 = x3 MOD 360
90    x4 = x4 MOD 360
91; save !map
92    save = {map:!map, x:!x, y:!y, z:!z, p:!p}
93; do a satellite projection
94    IF NOT keyword_set(zoomradius) THEN zoomradius = 4
95    map_set, y[0], x[0], 0, /satellite, sat_p = [1+zoomradius*20/6371.229, 0, 0], /noerase, /iso, /noborder
96; use normal coordinates to reject cells which are out of the projection.
97    tmp  = convert_coord(x, y, /DATA, /TO_NORMAL, DOUBLE = double)
98    tmp1 = convert_coord(x1, y1, /DATA, /TO_NORMAL, DOUBLE = double)
99    tmp2 = convert_coord(x2, y2, /DATA, /TO_NORMAL, DOUBLE = double)
100    tmp3 = convert_coord(x3, y3, /DATA, /TO_NORMAL, DOUBLE = double)
101    tmp4 = convert_coord(x4, y4, /DATA, /TO_NORMAL, DOUBLE = double)
102; remove cell which have one corner with coordinates equal to NaN
103    test = finite(tmp1[0, *]+tmp1[1, *]+tmp2[0, *]+tmp2[1, *] $
104                  +tmp3[0, *]+tmp3[1, *]+tmp4[0, *]+tmp4[1, *])
105    good = where(temporary(test) EQ 1)
106;
107    IF good[0] EQ -1 THEN BEGIN
108      IF NOT keyword_set(noprint) THEN print, 'The point is out of the cells'
109; restore the input parameters
110      x = temporary(xin)
111      y = temporary(yin)
112      x1 = temporary(x1in)
113      y1 = temporary(y1in)
114      x2 = temporary(x2in)
115      y2 = temporary(y2in)
116      x3 = temporary(x3in)
117      y3 = temporary(y3in)
118      x4 = temporary(x4in)
119      y4 = temporary(y4in)
120; restore old !map...
121      !map = save.map
122      !x = save.x
123      !y = save.y
124      !z = save.z
125      !p = save.p
126      RETURN,  -1
127    ENDIF
128;
129    x  = tmp[0]
130    y  = tmp[1]
131    x1 = tmp1[0, good]
132    y1 = tmp1[1, good]
133    x2 = tmp2[0, good]
134    y2 = tmp2[1, good]
135    x3 = tmp3[0, good]
136    y3 = tmp3[1, good]
137    x4 = tmp4[0, good]
138    y4 = tmp4[1, good]
139;
140    tmp1 = -1 & tmp2 = -1 & tmp3 = -1 & tmp4 = -1
141; remove cells which are obviously bad
142    test = (x1 GT x AND x2 GT x AND x3 GT x AND x4 GT x) $
143      OR (x1 LT x AND x2 LT x AND x3 LT x AND x4 LT x) $
144      OR (y1 GT y AND y2 GT y AND y3 GT y AND y4 GT y) $
145      OR (y1 LT y AND y2 LT y AND y3 LT y AND y4 LT y)
146    good2 = where(temporary(test) EQ 0)
147;
148    IF good2[0] EQ -1 THEN BEGIN
149      IF NOT keyword_set(noprint) THEN print, 'The point is out of the cells'
150; restore the input parameters
151      x = temporary(xin)
152      y = temporary(yin)
153      x1 = temporary(x1in)
154      y1 = temporary(y1in)
155      x2 = temporary(x2in)
156      y2 = temporary(y2in)
157      x3 = temporary(x3in)
158      y3 = temporary(y3in)
159      x4 = temporary(x4in)
160      y4 = temporary(y4in)
161; restore old !map...
162      !map = save.map
163      !x = save.x
164      !y = save.y
165      !z = save.z
166      !p = save.p
167      RETURN,  -1
168    ENDIF
169;
170    nquad = n_elements(good2)
171    x1 = x1[good2]
172    y1 = y1[good2]
173    x2 = x2[good2]
174    y2 = y2[good2]
175    x3 = x3[good2]
176    y3 = y3[good2]
177    x4 = x4[good2]
178    y4 = y4[good2]
179  ENDIF
180;
181;
182; the point is inside the quadilateral if test eq 1
183; with test equal to:
184;     test = ((x-x1)*(y2-y1) GE (x2-x1)*(y-y1)) $
185;       *((x-x2)*(y3-y2) GT (x3-x2)*(y-y2)) $
186;       *((x-x3)*(y4-y3) GT (x4-x3)*(y-y3)) $
187;       *((x-x4)*(y1-y4) GE (x1-x4)*(y-y4))
188;
189; computation of test without any do loop for ntofind points (x,y) and
190; nquad quadilateral((x1,x2,x3,x4),(y1,y2,y3,y4))
191; test dimensions are (ntofind, nquad)
192; column i of test corresponds to the intersection of point i with all
193; quadirlateral.
194; row j of test corresponds to all the points localized in cell j
195  test = $
196; (x-x1)
197  ((x[*]#replicate(1, nquad)-replicate(1, ntofind)#x1[*]) $
198; *(y2-y1)
199  *(replicate(1, ntofind)#(y2-y1)[*]) $
200; GE (x2-x1)
201  GE ((replicate(1, ntofind)#(x2-x1)[*]) $
202; *(y-y1)
203  *(y[*]#replicate(1, nquad)-replicate(1, ntofind)#y1[*])))
204;-------
205  test = temporary(test) $
206; *(x-x2)
207  *((x[*]#replicate(1, nquad)-replicate(1, ntofind)#x2[*]) $
208; *(y3-y2)
209  *(replicate(1, ntofind)#(y3-y2)[*]) $
210; GE (x3-x2)
211  GE ((replicate(1, ntofind)#(x3-x2)[*]) $
212; *(y-y2)
213  *(y[*]#replicate(1, nquad)-replicate(1, ntofind)#y2[*])))
214;-------
215  test = temporary(test) $
216; *(x-x3)
217  *((x[*]#replicate(1, nquad)-replicate(1, ntofind)#x3[*]) $
218; *(y4-y3)
219  *(replicate(1, ntofind)#(y4-y3)[*]) $
220; GE (x4-x3)
221  GE ((replicate(1, ntofind)#(x4-x3)[*]) $
222; *(y-y3)
223  *(y[*]#replicate(1, nquad)-replicate(1, ntofind)#y3[*])))
224;-------
225  test = temporary(test) $
226; *(x-x4)
227  *((x[*]#replicate(1, nquad)-replicate(1, ntofind)#x4[*]) $
228; *(y1-y4)
229  *(replicate(1, ntofind)#(y1-y4)[*]) $
230; GE (x1-x4)
231  GE ((replicate(1, ntofind)#(x1-x4)[*]) $
232; *(y-y4)
233  *(y[*]#replicate(1, nquad)-replicate(1, ntofind)#y4[*])))
234;
235; check test if ntofind gt 1
236; if ntofind gt 1, each point must be localised in one uniq cell.
237  IF ntofind GT 1 THEN BEGIN
238; each column of test must have only 1 position equal to one
239    chtest = total(test, 2)
240; points out of the cells
241    IF (where(chtest EQ 0))[0] NE -1 THEN BEGIN
242      IF NOT keyword_set(noprint) THEN print, 'Points number '+strjoin(strtrim(where(chtest EQ 0), 1), ', ')+' are out of the grid'
243      stop
244    ENDIF
245; points in more than one cell
246    IF (where(chtest GT 1))[0] NE -1 THEN BEGIN
247      IF NOT keyword_set(noprint) THEN print, 'Points number '+strjoin(strtrim(where(chtest GT 1), 1), ', ')+' are in more than one cell'
248      stop
249    ENDIF
250  ENDIF
251; find the points for which test eq 1
252  found = where(temporary(test) EQ 1)
253; if ntofind eq 1, the point may be localised in more than one grid
254; cell ou may also be out of the cells
255  IF ntofind EQ 1 THEN BEGIN
256    CASE 1 OF
257      found[0] EQ -1:BEGIN
258        IF NOT keyword_set(noprint) THEN print, 'The point is out of the cells'
259        IF keyword_set(onsphere) THEN BEGIN
260; restore old !map...
261          !map = save.map
262          !x = save.x
263          !y = save.y
264          !z = save.z
265          !p = save.p
266        ENDIF
267        return,  -1
268      END
269      n_elements(found) GT ntofind:BEGIN
270        IF NOT keyword_set(noprint) THEN print, 'The point is in more than one cell'
271      END
272      ELSE:
273    ENDCASE
274  ENDIF ELSE BEGIN
275; if ntofind GT 1, found must be sorted
276; i position of found. this corresponds to one x,y point
277    forsort = found MOD ntofind
278; j position of found. this corresponds to cell in which is one x,y
279; point
280    found = temporary(found)/ntofind
281; found must be sorted accordind to forsort
282    found = found[sort(forsort)]
283  ENDELSE
284;
285  IF keyword_set(onsphere) THEN BEGIN
286    IF arg_present(newcoord) THEN BEGIN
287      newcoord = [[x1[found], y1[found]] $
288                  , [x2[found], y2[found]] $
289                  , [x3[found], y3[found]] $
290                  , [x4[found], y4[found]] $
291                  , [x, y]]
292    ENDIF
293;
294    found = good[good2[found]]
295; restore the input parameters
296    x = temporary(xin)
297    y = temporary(yin)
298    x1 = temporary(x1in)
299    y1 = temporary(y1in)
300    x2 = temporary(x2in)
301    y2 = temporary(y2in)
302    x3 = temporary(x3in)
303    y3 = temporary(y3in)
304    x4 = temporary(x4in)
305    y4 = temporary(y4in)
306; restore old !map...
307    !map = save.map
308    !x = save.x
309    !y = save.y
310    !z = save.z
311    !p = save.p
312  ENDIF
313;;
314  RETURN, found
315END
Note: See TracBrowser for help on using the repository browser.