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

Last change on this file since 378 was 370, checked in by pinsard, 16 years ago

improvemnts of headers (typo, links)

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