source: trunk/ToBeReviewed/TRIANGULATION/triangule_c.pro @ 29

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

upgrade of TRIANGULATION according to cerbere.lodyc.jussieu.fr: /usr/home/smasson/SAXO_RD/ : files

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 13.2 KB
Line 
1;------------------------------------------------------------
2;------------------------------------------------------------
3;------------------------------------------------------------
4;+
5; NAME:triangule_c
6;
7; PURPOSE:construit le tableau de triangulation.
8;
9; L''idee est de
10; construire une liste de triangles qui relient les points entre
11; eux. Ceci est fait automatiquement avec la fonction TRIANGULATE.
12;  ICI:
13; on tient compte du fait que les points sont disposes sur une grille
14; (reguliere ou pas, mais pas destructuree, cad que les points sont
15; ecrits suivant une matrice rectangulaire). Un moyen tres simple de
16; faire des triangles entre tous les points est alors:
17;
18;     pour chaque point (i,j) de la matrice -sauf ceux de la derniere
19;     ligne et de la derniere colonne- on on appelle le rectangle
20;     (i,j) le rectangle forme par les 4 points (i,j), (i+1,j),
21;     (i,j+1), (i+1,j+1). Pour tracer tous les triangles, il suffit de
22;     tracer les 2 triangles contenus ds les rectangles (i,j)
23;
24; au passage on remarque que chaque rectangle (i,j) possede 2 diagonales (si
25; si faites un dessin c''est vrai), il y a donc 2 choix possibles pour
26; chaque rectangles qd on veut le couper en 2 triangles...
27;
28; C''est grace a ce choix que l''on va pouvoir tracer les cotes avec
29; des angles droits. A chaque angle de cote remarquable par
30; l''existance d''un unique point terre ou d''un unique point mer sur
31; les 4 cotes d''un rectangle (i,j), il faut couper le rectangle
32; suivant la diagonale qui qui passe par le point singulier.
33;
34; CATEGORY:pour faire de beaux graphiques masques
35;
36; CALLING SEQUENCE:res=triangule([mask])
37;
38; INPUTS:optionnel:mask c''est le tableau 2d qui sevira a masquer le
39; champ que l''on tracera apres avec CONTOUR,
40; ...TRIANGULATION=triangule(mask)
41; si cet argument n''est pas specifie, la function utilise tmask.
42;
43; KEYWORD PARAMETERS:
44;
45;       /BASIC: specifie que le masque est sur une grille basice
46;       (utiliser pour la triangulation ds les coupes verticales et
47;       des hovmoellers)
48;
49;       /KEEP_CONT: to keep the triangulation even on the continents
50;
51;       COINMONTE=tableau, pour obtenir le tableau de "coins de terre
52;       montant" a traiter avec completecointerre.pro ds la variable
53;       tableau plutot que de la faire passer par la variable globale
54;       twin_corners_up.
55;
56;       COINDESCEND=tableau cf COINMONTE
57;
58; OUTPUTS:
59;       res: tableau 2d (3,nbre de triangles).
60;    chaque ligne de res represente les indices des points
61;    constituants les sommets d''un triangle.
62;    cf. comment on trace les triangles ds dessinetri.pro
63;
64; COMMON BLOCKS:
65;       common.pro different.pro definetri.pro
66;
67; SIDE EFFECTS:
68;
69; RESTRICTIONS:les donnees dont un veut ensuite faire le contour
70; doivent etre disposees dans une matrice. Par contre dans la matrice,
71; la disposition des points peut ne pas etre irreguliere. Si les
72; donnees sont disposees completement de facon irreguliere, utiliser
73; TRIANGULE.
74;
75; EXAMPLE:
76;
77; MODIFICATION HISTORY: Sebastien Masson (smasson@lodyc.jussieu.fr)
78;                       26/4/1999
79;-
80;------------------------------------------------------------
81;------------------------------------------------------------
82;------------------------------------------------------------
83FUNCTION triangule_c, maskentree, COINMONTE = coinmonte, COINDESCEND = coindescend, BASIC = basic, KEEP_CONT = keep_cont
84   tempsun = systime(1)         ; pour key_performance
85;---------------------------------------------------------
86@cm_4mesh
87  IF NOT keyword_set(key_forgetold) THEN BEGIN
88@updatenew
89  ENDIF
90;------------------------------------------------------------
91; le masque est donne ou il faut prendre tmask?
92;------------------------------------------------------------
93;
94   msk = maskentree
95   taille = size(msk)
96   nx = taille[1]
97   ny = taille[2]
98;
99   IF n_elements(keep_cont) EQ 0 THEN keep_cont = 1-key_irregular
100;------------------------------------------------------------
101   if keyword_set(key_periodic)*(nx EQ jpi) $
102    AND NOT keyword_set(basic) then BEGIN
103      msk = [msk, msk[0, *]]
104      nx = nx+1
105   ENDIF
106;------------------------------------------------------------
107; on va trouver la liste des rectangles (i,j) (reperes par leur coin
108; en bas a gauche) qu''il faut couper suivant une diagonale descendante
109; on appellera cette liste : pts_downward
110;
111   pts_downward = 0
112
113; on construit le test qui permet de trouver un tel triangle:
114;
115;
116;       shift(msk,  0, -1)------------shift(msk, -1, -1)
117;              |                             |
118;              |                             |
119;              |                             |
120;              |                             |
121;             msk---------------------shift(msk, -1,  0)
122;
123   sum1 = msk+shift(msk, -1, 0)+shift(msk, -1, -1) ;pts qui entourrent le pt en haut a gauche
124   sum2 = msk+shift(msk, 0, -1)+shift(msk, -1, -1) ;pts qui entourrent le pt en bas a droite
125
126
127   tempdeux = systime(1)        ; pour key_performance =2
128; pt terre en haut a gauche entoure de pts mer
129   liste = where( (4-sum1)*(1-shift(msk, 0, -1)) EQ 1 )
130   if liste[0] NE -1 THEN pts_downward = [pts_downward,liste ]
131; pt mer en haut a gauche entoure de pts terre
132   liste = where( (1-sum1)*shift(msk, 0, -1) EQ 1)
133   if liste[0] NE -1 THEN pts_downward = [pts_downward,liste ]
134; pt terre en bas a droite entoure de pts mer
135   liste = where( (4-sum2)*(1-shift(msk, -1,  0)) EQ 1)
136   if liste[0] NE -1 THEN pts_downward = [pts_downward,liste ]
137; pt mer en bas a droite entoure de pts terre
138   liste = where( (1-sum2)*shift(msk, -1,  0) EQ 1)
139   if liste[0] NE -1 THEN pts_downward = [pts_downward,liste ]
140   undefine, liste
141;
142   IF testvar(var = key_performance) EQ 2 THEN $
143    print, 'temps triangule: trouver pts_downward', systime(1)-tempdeux
144;
145   if (NOT keyword_set(basic)) OR keyword_set(coinmonte) OR keyword_set(coindescend) then begin
146      tempdeux = systime(1)     ; pour key_performance =2
147;2 points terre en diagonale montante avec 2 points mer sur la diagonale descendante
148      coinmont = where( (1-msk)*(1-shift(msk, -1, -1)) $
149                        *(shift(msk, 0, -1)*shift(msk, -1,  0) EQ 1) )
150      if coinmont[0] NE -1 THEN pts_downward = [pts_downward, coinmont]
151;
152      IF testvar(var = key_performance) EQ 2 THEN $
153       print, 'temps triangule: trouver coinmont', systime(1)-tempdeux
154      tempdeux = systime(1)     ; pour key_performance =2
155;
156;2 points terre en diagonale descendante avec 2 points mer sur la diagonale montante
157      coindesc = where( ((1-shift(msk,  0, -1))*(1-shift(msk, -1, 0)) $
158                         *msk*shift(msk, -1, -1) EQ 1) )
159;
160      IF testvar(var = key_performance) EQ 2 THEN $
161       print, 'temps triangule: trouver coindesc', systime(1)-tempdeux
162;
163    ENDIF
164;
165   if n_elements(pts_downward) EQ 1 then BEGIN
166      tempdeux = systime(1)     ; pour key_performance =2
167;
168      triang = definetri(nx, ny)
169;
170      IF testvar(var = key_performance) EQ 2 THEN $
171       print, 'temps triangule: definetri', systime(1)-tempdeux
172      coinmont = -1
173      coindesc = -1
174   ENDIF ELSE BEGIN
175      tempdeux = systime(1)     ; pour key_performance =2
176      pts_downward = pts_downward[1:n_elements(pts_downward)-1]
177      pts_downward = pts_downward(uniq(pts_downward, sort(pts_downward)))
178; aucun rectangle ne peut avoir comme coin en bas a gauche un element
179; de la derniere colonne ou de la derniere ligne.
180; il faut donc enlever ces points si ils ont ete selectionnes dans
181; pts_downward.
182      derniere_colonne = (lindgen(ny)+1)*nx-1
183      derniere_ligne = lindgen(nx)+(ny-1)*nx
184      pts_downward =different(pts_downward,derniere_colonne )
185      pts_downward =different(pts_downward,derniere_ligne )
186      if (NOT keyword_set(basic)) OR keyword_set(coinmonte) OR keyword_set(coindescend) then begin
187         if coinmont[0] NE -1 then begin
188            coinmont =different(coinmont,derniere_colonne )
189            coinmont =different(coinmont,derniere_ligne )
190         endif
191         if coindesc[0] NE -1 then begin
192            coindesc =different(coindesc,derniere_colonne )
193            coindesc =different(coindesc,derniere_ligne )
194         endif
195      ENDIF ELSE BEGIN
196         coinmont = -1
197         coindesc = -1
198      ENDELSE
199      IF testvar(var = key_performance) EQ 2 THEN $
200       print, 'temps triangule: menage ds pts_downward coinmont et coindesc', systime(1)-tempdeux
201;
202      tempdeux = systime(1)     ; pour key_performance =2
203      if  pts_downward[0] EQ -1 then triang = definetri(nx, ny) $
204      ELSE triang = definetri(nx, ny, pts_downward)
205      IF testvar(var = key_performance) EQ 2 THEN $
206       print, 'temps triangule: definetri', systime(1)-tempdeux
207   ENDELSE
208;------------------------------------------------------------
209; on vire les triangles qui ne contiennent que des points terre
210;------------------------------------------------------------
211;
212;  tres bonne idee qui ne marche pas encore a 200% avec IDL 5.2
213;  ca devrait aller mieux dans les prochaines versions d''IDL...
214;
215   if (NOT keyword_set(basic)) AND (NOT keyword_set(keep_cont)) then begin
216      tempdeux = systime(1)     ; pour key_performance =2
217; on enleve les rectangles qui sont entierement dans la terre
218      recdsterre = where((1-msk)*(1-shift(msk, -1, 0))*(1-shift(msk, 0, -1))*(1-shift(msk, -1, -1)) EQ 1)
219      IF testvar(var = key_performance) EQ 2 THEN $
220       print, 'temps triangule: tous les recdsterre', systime(1)-tempdeux
221
222; en attendant une version qui marche parfaitement, on est contraint
223; de faire un nouveau tri:
224; il ne faut pas enlever les rectangles qui n''ont qu''un sommet en
225; commun.
226; t1 = systime(1)
227      indice = intarr(nx, ny)
228      trimask = intarr(nx, ny)
229      trimask[0:nx-2, 0:ny-2] = 1
230      IF recdsterre[0] NE -1 then BEGIN
231         tempdeux = systime(1)  ; pour key_performance =2
232         indice[recdsterre] = 1
233;      if NOT keyword_set(basic) then begin
234         vire1 = 0
235         vire2 = 0
236         while (vire1[0] NE -1 OR vire2[0] NE -1) ne 0 do begin
237; vire sont les rectangles qu''il faut retirer de recsterre (en fait
238; qu''il faut garder bien qu''ils soient entirement dans la terre) 
239            vire1 = where( (indice*shift(indice, -1, -1) $
240                            *(1-shift(indice, 0, -1))*(1-shift(indice, -1, 0))*trimask) EQ 1)
241            if vire1[0] NE -1 THEN BEGIN
242               indice[vire1] = 0
243;               indice[vire1+nx+1] = 0
244            endif
245           
246            vire2 = where( ((1-indice)*(1-shift(indice, -1, -1)) $
247                            *shift(indice, 0, -1)*shift(indice, -1, 0)*trimask) EQ 1)
248            if vire2[0] NE -1 THEN BEGIN
249               indice[vire2+1] = 0
250;               indice[vire2+nx] = 0
251            endif
252         endwhile
253         IF testvar(var = key_performance) EQ 2 THEN $
254          print, 'temps triangule: trier les recdsterre', systime(1)-tempdeux
255;      endif
256         indice[*, ny-1] = 1    ; la deriere colonne te la derniere ligne
257         indice[nx-1, *] = 1    ; ne peuvent definir de rectangle.
258;
259         tempdeux = systime(1)  ; pour key_performance =2
260         recgarde = where(indice EQ 0)
261; on recupere les numeros des triangles que l'' on va garder
262         trigarde = 2*[recgarde-recgarde/nx]
263         trigarde = transpose(temporary(trigarde))
264         trigarde = [trigarde, trigarde+1]
265;
266         triang = triang[*, temporary(trigarde[*])]
267         IF testvar(var = key_performance) EQ 2 THEN $
268          print, 'temps triangule: virer les triangle de la liste', systime(1)-tempdeux
269      endif
270   endif
271; print, 'temps tri triangles', systime(1)-t1
272;------------------------------------------------------------
273; quand key_periodic eq 1, triang est une liste d''indice d'un
274; tableau qui a une colonne de trop.
275; il faut ramener ca a la matrice initiale en mettant les indivces de
276; la derniere colonne egaux a ceux de la derniere colonne...
277;------------------------------------------------------------
278   tempdeux = systime(1)        ; pour key_performance =2
279   if keyword_set(key_periodic)*(nx-1 EQ jpi) $
280    AND NOT keyword_set(basic) then BEGIN
281      indicey = triang/nx
282      indicex = triang-indicey*nx
283      nx = nx-1
284      liste = where(indicex EQ nx)
285      if liste[0] NE -1 then indicex[liste] = 0
286      triang = indicex+nx*indicey
287      nx = nx+1
288      if coinmont[0] NE -1 then begin
289         indicey = coinmont/nx
290         indicex = coinmont-indicey*nx
291         nx = nx-1
292         liste = where(indicex EQ nx)
293         if liste[0] NE -1 THEN indicex[liste] = 0
294         coinmont = indicex+nx*indicey
295         nx = nx+1
296      endif
297      if coindesc[0] NE -1 then begin
298         indicey = coindesc/nx
299         indicex = coindesc-indicey*nx
300         nx = nx-1
301         liste = where(indicex EQ nx)
302         if liste[0] NE -1 THEN indicex[liste] = 0
303         coindesc = indicex+nx*indicey
304         nx = nx+1
305      endif
306   endif
307   IF testvar(var = key_performance) EQ 2 THEN $
308    print, 'temps triangule: finitions', systime(1)-tempdeux
309
310;------------------------------------------------------------
311   if keyword_set(coinmonte) THEN coinmonte = coinmont ELSE twin_corners_up = coinmont
312   if keyword_set(coindescend) THEN coindescend = coindesc ELSE twin_corners_dn = coindesc
313;------------------------------------------------------------
314  IF NOT keyword_set(key_forgetold) THEN BEGIN
315   @updateold
316 ENDIF
317
318   IF keyword_set(key_performance) THEN print, 'temps triangule', systime(1)-tempsun
319
320   return, triang
321
322END
Note: See TracBrowser for help on using the repository browser.