source: trunk/SRC/ToBeReviewed/TRIANGULATION/triangule_c.pro @ 325

Last change on this file since 325 was 325, checked in by pinsard, 17 years ago

modification of some headers (+some corrections) to prepare usage of the new idldoc

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 12.2 KB
Line 
1;+
2;
3; @file_comments
4; Construct the triangulation array.
5;
6; The idea is: construct a list of triangle which link points between them.
7; This is automatically done by the function TRIANGULATE
8;  Here:
9; we consider the fact that points are disposed on a grid (regular or not,
10; but not unstructured, that is to say that points are written following a
11; rectangular matrix). A easy way to do triangles between all points is then:
12;
13;     for each point (i,j) of the matrix -except those of the last line and of
14;     the last column- we call rectangle (i,j) the rectangle made of the four
15;     points (i,j), (i+1,j), (i,j+1), (i+1,j+1). To trace all triangle, we just
16;     have to trace the 2 triangles contained in rectangles (i,j)
17;
18; We notice that each rectangle (i,j) have 2 diagonals (it is true... Make a
19; drawing to make sure!!), so there are two possible choice for each rectangle
20; we want to cut in 2 triangles...
21;
22; It is thanks to this choice that we will be able to trace coast with right
23; angles. At each angle of coast remarkable by the existence of an unique land
24; point or of an unique ocean point on one of the four summit of a rectangle (i,j),
25; we have to cut the rectangle following the diagonal passing by this point.
26;
27; @categories
28; Graphics
29;
30; @param MASKENTREE {in}{optional}{type=2d array}
31; It is a 2d array which will serve to mask the field we will trace after with CONTOUR,
32; ...TRIANGULATION=triangule(mask)
33; If this argument is not specified, the function use tmask
34;
35; @keyword BASIC
36; Specify that the mask is on a basic grid (use the triangulation for vertical cuts and hovmoellers)
37;
38; @keyword KEEP_CONT
39; To keep the triangulation even on the continents
40;
41; @keyword COINMONTE {type=array}
42; To obtain the array of "ascending land corner" to be treated with
43; completecointerre.pro in the variable array instead of make it pass by the global
44; variable twin_corners_up.
45;
46; @keyword COINDESCEND {type=array}
47; See COINMONTE
48;
49; @returns
50; res: tableau 2d (3,nbre de triangles).
51; Each line of res represent indexes of points constituting summits of a triangle.
52; See how we trace triangles in definetri.pro
53;
54; @uses
55; common.pro
56; different.pro
57; definetri.pro
58;
59; @restrictions
60; Data whose we want to do the contour must be disposed in a matrix.
61; On the other hand, in the matrix, the points's arrangement can not be
62; irregular. If it is, use TRIANGULE.
63;
64; @history
65; Sebastien Masson (smasson\@lodyc.jussieu.fr)
66;                       26/4/1999
67;
68; @version
69; $Id$
70;
71; @todo
72; seb L.267->268 je ne pense pas que ce soit ce que tu voulais dire mais
73; c'est la traduction de ce qu'il y avait écrit. Correction si besoin.
74;-
75FUNCTION triangule_c, maskentree, COINMONTE = coinmonte, COINDESCEND = coindescend, BASIC = basic, KEEP_CONT = keep_cont
76;
77compile_opt idl2, strictarrsubs
78;
79tempsun = systime(1)            ; For key_performance
80;---------------------------------------------------------
81@cm_4mesh
82IF NOT keyword_set(key_forgetold) THEN BEGIN
83@updatenew
84ENDIF
85;------------------------------------------------------------
86; Is the mask given or do we have to take tmask?
87;------------------------------------------------------------
88;
89msk = maskentree
90taille = size(msk)
91nx = taille[1]
92ny = taille[2]
93;
94IF n_elements(keep_cont) EQ 0 THEN keep_cont = 1-key_irregular
95;------------------------------------------------------------
96if keyword_set(key_periodic)*(nx EQ jpi) $
97  AND NOT keyword_set(basic) then BEGIN
98    msk = [msk, msk[0, *]]
99    nx = nx+1
100ENDIF
101;------------------------------------------------------------
102; We will find the list of rectangles (i,j)(located by their left
103; bottom corner) we have to cut following a descendant diagonal.
104; We will call this list : pts_downward
105;
106pts_downward = 0
107
108; We construct the test which allow to find this triangle :
109;
110;
111;       shift(msk,  0, -1)------------shift(msk, -1, -1)
112;              |                             |
113;              |                             |
114;              |                             |
115;              |                             |
116;             msk---------------------shift(msk, -1,  0)
117;
118sum1 = msk+shift(msk, -1, 0)+shift(msk, -1, -1)    ;points which surround the left top point.
119sum2 = msk+shift(msk, 0, -1)+shift(msk, -1, -1)    ;points which surround the right bottom point.
120
121
122tempdeux = systime(1)           ; For key_performance =2
123; The left top land point surrounded by ocean points
124liste = where( (4-sum1)*(1-shift(msk, 0, -1)) EQ 1 )
125if liste[0] NE -1 THEN pts_downward = [pts_downward,liste ]
126; The left top ocean point surrounded by land points
127liste = where( (1-sum1)*shift(msk, 0, -1) EQ 1)
128if liste[0] NE -1 THEN pts_downward = [pts_downward,liste ]
129; The right bottom land point surrounded by ocean points
130liste = where( (4-sum2)*(1-shift(msk, -1,  0)) EQ 1)
131if liste[0] NE -1 THEN pts_downward = [pts_downward,liste ]
132; The right bottom ocean point surrounded by land points
133liste = where( (1-sum2)*shift(msk, -1,  0) EQ 1)
134if liste[0] NE -1 THEN pts_downward = [pts_downward,liste ]
135undefine, liste
136;
137IF testvar(var = key_performance) EQ 2 THEN $
138  print, 'temps triangule: trouver pts_downward', systime(1)-tempdeux
139;
140if (NOT keyword_set(basic)) OR keyword_set(coinmonte) OR keyword_set(coindescend) then begin
141    tempdeux = systime(1)       ; For key_performance =2
142;2 land points in ascendant diagonal with 2 ocean points in descendant diagonal.
143    coinmont = where( (1-msk)*(1-shift(msk, -1, -1)) $
144                      *(shift(msk, 0, -1)*shift(msk, -1,  0) EQ 1) )
145    if coinmont[0] NE -1 THEN pts_downward = [pts_downward, coinmont]
146;
147    IF testvar(var = key_performance) EQ 2 THEN $
148      print, 'temps triangule: trouver coinmont', systime(1)-tempdeux
149    tempdeux = systime(1)       ; pour key_performance =2
150;
151    coindesc = where( ((1-shift(msk,  0, -1))*(1-shift(msk, -1, 0)) $
152                       *msk*shift(msk, -1, -1) EQ 1) )
153;
154;2 land points in descendant diagonal with 2 ocean points in ascendant diagonal.
155    IF testvar(var = key_performance) EQ 2 THEN $
156      print, 'temps triangule: trouver coindesc', systime(1)-tempdeux
157;
158ENDIF
159;
160if n_elements(pts_downward) EQ 1 then BEGIN
161    tempdeux = systime(1)       ; For key_performance =2
162;
163    triang = definetri(nx, ny)
164;
165    IF testvar(var = key_performance) EQ 2 THEN $
166      print, 'temps triangule: definetri', systime(1)-tempdeux
167    coinmont = -1
168    coindesc = -1
169ENDIF ELSE BEGIN
170    tempdeux = systime(1)       ; For key_performance =2
171    pts_downward = pts_downward[1:n_elements(pts_downward)-1]
172    pts_downward = pts_downward[uniq(pts_downward, sort(pts_downward))]
173; None rectangle can have an element of the last column or of the
174; last line as left bottom corner.
175; so we have to remove these points if they has been selected in pts_downward.
176    derniere_colonne = (lindgen(ny)+1)*nx-1
177    derniere_ligne = lindgen(nx)+(ny-1)*nx
178    pts_downward =different(pts_downward,derniere_colonne )
179    pts_downward =different(pts_downward,derniere_ligne )
180    if (NOT keyword_set(basic)) OR keyword_set(coinmonte) OR keyword_set(coindescend) then begin
181        if coinmont[0] NE -1 then begin
182            coinmont =different(coinmont,derniere_colonne )
183            coinmont =different(coinmont,derniere_ligne )
184        endif
185        if coindesc[0] NE -1 then begin
186            coindesc =different(coindesc,derniere_colonne )
187            coindesc =different(coindesc,derniere_ligne )
188        endif
189    ENDIF ELSE BEGIN
190        coinmont = -1
191        coindesc = -1
192    ENDELSE
193    IF testvar(var = key_performance) EQ 2 THEN $
194      print, 'temps triangule: menage ds pts_downward coinmont et coindesc', systime(1)-tempdeux
195;
196    tempdeux = systime(1)       ; For key_performance =2
197    if  pts_downward[0] EQ -1 then triang = definetri(nx, ny) $
198    ELSE triang = definetri(nx, ny, pts_downward)
199    IF testvar(var = key_performance) EQ 2 THEN $
200      print, 'temps triangule: definetri', systime(1)-tempdeux
201ENDELSE
202;------------------------------------------------------------
203; We delete land points which only contain land points.
204;------------------------------------------------------------
205;
206;
207if (NOT keyword_set(basic)) AND (NOT keyword_set(keep_cont)) then begin
208    tempdeux = systime(1)       ; For key_performance =2
209; We delete rectangles which are entirely in the land.
210    recdsterre = where((1-msk)*(1-shift(msk, -1, 0))*(1-shift(msk, 0, -1))*(1-shift(msk, -1, -1)) EQ 1)
211    IF testvar(var = key_performance) EQ 2 THEN $
212      print, 'temps triangule: tous les recdsterre', systime(1)-tempdeux
213
214; We do an other sort :
215; We have to do not remove rectangles which only have one common summit.
216; t1 = systime(1)
217    indice = intarr(nx, ny)
218    trimask = intarr(nx, ny)
219    trimask[0:nx-2, 0:ny-2] = 1
220    IF recdsterre[0] NE -1 then BEGIN
221        tempdeux = systime(1)   ; For key_performance =2
222        indice[recdsterre] = 1
223        if NOT keyword_set(basic) then begin
224            vire1 = 0
225            vire2 = 0
226            while (vire1[0] NE -1 OR vire2[0] NE -1) ne 0 do begin
227; Delete rectangles we have to remove from recsterre (in fact those we have
228; to keep although they are entirely in the land).
229                vire1 = where( (indice*shift(indice, -1, -1) $
230                                *(1-shift(indice, 0, -1))*(1-shift(indice, -1, 0))*trimask) EQ 1)
231                if vire1[0] NE -1 THEN BEGIN
232                    indice[vire1] = 0
233;               indice[vire1+nx+1] = 0
234                endif
235
236                vire2 = where( ((1-indice)*(1-shift(indice, -1, -1)) $
237                                *shift(indice, 0, -1)*shift(indice, -1, 0)*trimask) EQ 1)
238                if vire2[0] NE -1 THEN BEGIN
239                    indice[vire2+1] = 0
240;               indice[vire2+nx] = 0
241                endif
242            endwhile
243            IF testvar(var = key_performance) EQ 2 THEN $
244              print, 'temps triangule: trier les recdsterre', systime(1)-tempdeux
245        endif
246        indice[*, ny-1] = 1     ; The last column and the last line
247        indice[nx-1, *] = 1     ; can not define any rectangle.
248;
249        tempdeux = systime(1)   ; For key_performance =2
250        recgarde = where(indice EQ 0)
251; We recuperate numbers of triangles we will keep.
252        trigarde = 2*[recgarde-recgarde/nx]
253        trigarde = transpose(temporary(trigarde))
254        trigarde = [trigarde, trigarde+1]
255;
256        triang = triang[*, temporary(trigarde[*])]
257        IF testvar(var = key_performance) EQ 2 THEN $
258          print, 'temps triangule: virer les triangle de la liste', systime(1)-tempdeux
259    endif
260endif
261; print, 'temps tri triangles', systime(1)-t1
262;------------------------------------------------------------
263; When key_periodic equal 1, triang is a list of indexes's array which
264; have a surplus column.
265; We have to put it back to the initial matrix by putting indexes of
266; the last column equal to these of the last column...
267;------------------------------------------------------------
268tempdeux = systime(1)           ; For key_performance =2
269if keyword_set(key_periodic)*(nx-1 EQ jpi) $
270  AND NOT keyword_set(basic) then BEGIN
271    indicey = triang/nx
272    indicex = triang-indicey*nx
273    nx = nx-1
274    liste = where(indicex EQ nx)
275    if liste[0] NE -1 then indicex[liste] = 0
276    triang = indicex+nx*indicey
277    nx = nx+1
278    if coinmont[0] NE -1 then begin
279        indicey = coinmont/nx
280        indicex = coinmont-indicey*nx
281        nx = nx-1
282        liste = where(indicex EQ nx)
283        if liste[0] NE -1 THEN indicex[liste] = 0
284        coinmont = indicex+nx*indicey
285        nx = nx+1
286    endif
287    if coindesc[0] NE -1 then begin
288        indicey = coindesc/nx
289        indicex = coindesc-indicey*nx
290        nx = nx-1
291        liste = where(indicex EQ nx)
292        if liste[0] NE -1 THEN indicex[liste] = 0
293        coindesc = indicex+nx*indicey
294        nx = nx+1
295    endif
296endif
297IF testvar(var = key_performance) EQ 2 THEN $
298  print, 'temps triangule: finitions', systime(1)-tempdeux
299
300;------------------------------------------------------------
301if keyword_set(coinmonte) THEN coinmonte = coinmont ELSE twin_corners_up = coinmont
302if keyword_set(coindescend) THEN coindescend = coindesc ELSE twin_corners_dn = coindesc
303;------------------------------------------------------------
304IF NOT keyword_set(key_forgetold) THEN BEGIN
305   @updateold
306ENDIF
307
308IF keyword_set(key_performance) THEN print, 'temps triangule', systime(1)-tempsun
309
310return, triang
311
312END
Note: See TracBrowser for help on using the repository browser.