source: trunk/SRC/ToBeReviewed/PLOTS/VECTEUR/vecteur.pro @ 134

Last change on this file since 134 was 134, checked in by navarro, 18 years ago

change *.pro file properties (del eof-style, del executable, set keywords Id

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 14.8 KB
Line 
1;------------------------------------------------------------
2;------------------------------------------------------------
3;------------------------------------------------------------
4;+
5; NAME:vecteur
6;
7; PURPOSE: trace des vecteurs (meme situees sur une grille tordue) sur
8; n''importe quelle projection, de telle sorte que tous les vecteurs
9; aient une norme comparable sur le dessin (en clair, un vecteur qui
10; doit faire 1cm le fait quelque soit la projection et sa position sur
11; la sphere)
12;
13; CATEGORY:trace de vecteur
14;
15; CALLING SEQUENCE:vecteur, composanteu, composantev, normevecteur, indice2d, reduitindice2d
16;
17; INPUTS: COMPOSANTEU et COMPOSANTEV: ce sont les composantes des
18; vecteurs a tracer. Ces tableaux 2d ont la meme dimension que
19; reduitindice2d (cf apres).
20;       INDICE2D: indice permettant de passer d''un tableau jpi,jpj au
21;       zoom surlequel on fait le dessin.
22;       REDUITINDICE2D: indice permettant de passer d''un tableau
23;       definit par indice2d au tableau pourlequel on a reelement des
24;       vecteurs a tracer (en clair: c''est par ex qd on ne trace par exemple
25;       que un vecteur sur 2)
26;
27; KEYWORD PARAMETERS:
28;
29;      CMREF: la longeur en cm sur le papier que diot faire la fleche
30;      de norme normeref. par defaut ajuste au dessin et compris entre
31;      .5 et 1.5 cm
32;
33;      MISSING: la valeur d''une missing value. ne pas utilisder ce
34;      mot cle. fixe a 1e5 par ajoutvect.pro
35;     
36;      NORMEREF: la norme de la fleche de reference. par defaut on
37;      essaie de faire qqch qui colle pas trop mal!
38;
39;      VECTCOLOR: la couleur de la fleche. Par defaut noir (couleur 0)
40;
41;      VECTTHICK; l''epaissuer de la fleche. par defaut 1.
42;
43;      VECTREFPOS: vecteur de 2 elements specifiant la position en
44;      coordonnees DATA du debut du vecteur de reference. Par defaut
45;      en bas a droite du dessin.
46;
47;      VECTREFFORMAT: format a utiliser pour specifier la norme du
48;      vecteur de reference.
49;
50;      /NOVECTREF: pour supprimer l'affichage du vecteur de reference.
51;
52; OUTPUTS:
53;
54; COMMON BLOCKS:common.pro
55;
56; SIDE EFFECTS:
57;
58; RESTRICTIONS:
59;
60; EXAMPLE:
61;
62; MODIFICATION HISTORY:
63;  Creation : 13/02/98 G. Roullet (grlod@lodyc.jussieu.fr)
64;  Modification : 14/01/99 realise la transformation
65;  spherique<->cartesien G. Roullet
66;                 12/03/99 verification de la routine G. Roullet
67;  8/11/1999:
68;  G. Roullet et Sebastien Masson (smasson@lodyc.jussieu.fr)
69;  adaptation pour les zoom. reverification...traitement separe de la
70;  direction et de la norme des vecteurs. mots cles NORMEREF et CMREF.
71;-
72;------------------------------------------------------------
73;------------------------------------------------------------
74;------------------------------------------------------------
75
76FUNCTION cv_cm2normal, angle
77;
78; donne la longeur en coordonnes normales d''un trait ortiente de
79; angle par rapport a l''axe des x et qui doit faire 1 cm sur le
80; dessin.
81; angle peut etre un tableau.
82;
83;
84  compile_opt idl2, strictarrsubs
85;
86@common
87; quelle est la longeur en coordonnees normales d''un trait qui fera 1
88; cm sur le parier et qui est parallele a x?
89  mipgsz = min(page_size, max = mapgsz)
90   sizexfeuille = mipgsz*key_portrait+mapgsz*(1-key_portrait)
91   sizeyfeuille = mapgsz*key_portrait+mipgsz*(1-key_portrait)
92   cm_en_normal = 1./sizexfeuille
93;
94;  si le rapport d''aspect de la fenetre n''est pas egale a 1, la
95;  longeur en coordonees normalise d''un trait de 1cm varie suivant
96;  l''angle polaire de ce trait.
97;
98   aspect = sizexfeuille/sizeyfeuille
99   cm_en_normal = cm_en_normal*sqrt( 1 +(aspect^2-1)*sin(angle)^2 )
100;
101   return, cm_en_normal
102END
103;
104PRO normalise, u, v, w
105;
106; normalise le vecteur
107;
108;
109  compile_opt idl2, strictarrsubs
110;
111   IF n_elements(w) NE 0 THEN BEGIN
112      norme = sqrt(u^2.+v^2.+w^2.)
113      ind = where(norme NE 0)
114      u[ind] = u[ind]/norme[ind]
115      v[ind] = v[ind]/norme[ind]
116      w[ind] = w[ind]/norme[ind]
117   ENDIF ELSE BEGIN
118      norme = sqrt(u^2.+v^2.)
119      ind = where(norme NE 0)
120      u[ind] = u[ind]/norme[ind]
121      v[ind] = v[ind]/norme[ind]
122   ENDELSE
123END
124PRO vecteur, composanteu, composantev, normevecteur, indice2d, reduitindice2d $
125             , CMREF = cmref, MISSING = missing, NORMEREF = normeref $
126             , VECTCOLOR = vectcolor, VECTTHICK = vectthick, VECTREFPOS = vectrefpos $
127             , VECTREFFORMAT = vectrefformat, NOVECTREF = novectref, _extra = extra
128;
129  compile_opt idl2, strictarrsubs
130;
131@common
132   tempsun = systime(1)         ; pour key_performance
133;
134;
135   taille = size(composanteu)
136   nx = taille[1]
137   ny = taille[2]
138   if n_elements(reduitindice2d) EQ 0 then reduitindice2d = lindgen(nx, ny)
139   zu = composanteu
140   zv = composantev
141   norme = normevecteur
142   taille = size(indice2d)
143   nxgd = taille[1]
144   nygd = taille[2]
145;
146   msk = replicate(1, nx, ny)
147   if keyword_set(missing) then terre = where(abs(zu) GE missing/10) ELSE terre = -1
148   if terre[0] NE -1  then BEGIN
149      msk[terre] = 0
150      zu[terre] = 0
151      zv[terre] = 0
152      norme[terre] = 0
153   ENDIF
154;
155; Etape 1:
156;
157; etant donne la direction et le sens que le vecteur a sur la
158; sphere, il faut se debrouiller pour determiner cette direction et le
159; sens qu'aura le vecteur sur l''ecran ou la feuille une fois qu''il
160; aura ete projete.
161;
162; En theorie: sur la sphere, un vecteur en un point donne a pour
163; direction la tangente au cercle qui passe par le centre de la terre
164; et par le vecteur. Donc trouver la direction une fois la projection
165; faite ds le plan 2d, c''est trouver la tangente a la courbe
166; representant la projection du cercle sur le plan 2d au point
167; representant la projection du point de depart de la shere sur le
168; plan 2d!!!
169;
170; En pratique on ne connait pas la definition de la courbe que donne
171; la projection d''un cercle alors trouver sa tangente en un point...
172;
173; Ce que l''on fait:
174; Ds un repere cartesien 3d,
175;       a) on trouve les coordonnees du point T (debut de la fleche)
176;       situe sur la shere.
177;       b) pour chaque point T on determine les directions locales
178;       definies par la grille en ce point et auxquelles se rapportent
179;       les coordonnes (u,v) du vecteur. Ces directions locales sont
180;       definies par les gradiants des glam et gphi. Une fois ces
181;       directions obtenues, on les considere comme orthogonales et en
182;       les normant on construit un repere orthonormal (nu,nv) auquel se
183;       rapporte les coordonnes (u,v) du vecteur. Ds le repere
184;       cartesien 3d de depart, le vecteur est definit par:
185;       V=u*nu+v*nv (ou V, nu et nv sont des vecteurs 3d et u et v des
186;       scalaires)
187;       c) pour approximer la tangente au cercle par la corde definie
188;       par le debut et la fin de la fleche, on va normaliser V puis
189;       le diviser par 100.
190;       d) ceci nous permet de determiner les coordonnees ds le repere
191;       cartesien 3d des extremites de la corde, on les passe en
192;       coordonnes sphereriques de facon a recuperer les positions en
193;       latitude longitude de ces points sur la sphere.
194;       e) on passe les coordonnees de ces points en coordonnees
195;       normalise puis en corrdonnes polaire de facon a trouver
196;       l''angle et la direction qu''ils determinent sur le dessin...
197;
198;
199; etape 1, a)
200;
201;
202; coordonnes du point T (debut de la fleche) en coordonnes sheriques
203   glam = glamt[indice2d[reduitindice2d]]
204   gphi = gphit[indice2d[reduitindice2d]]
205;
206; coordonnes du point T (debut de la fleche) dans le repere cartesien
207; on utilise comme shere, une shere de rayon 1.
208;
209   radius = replicate(1,nx*ny)
210   coord_sphe = transpose([ [glam[*]], [gphi[*]], [radius[*]] ])
211   r = cv_coord(from_sphere=coord_sphe,/to_rect,/degrees)
212;
213   x0 = reform(r[0, *], nx, ny)
214   y0 = reform(r[1, *], nx, ny)
215   z0 = reform(r[2, *], nx, ny)
216;
217; etape 1, b)
218;
219; Construction du vecteur nu (resp. nv), vecteur norme porte par
220; l''axe des points u[i,j] et u[i-1,j] (resp v[i,j] et v[i,j-1])
221; qui definissent pour chaque point sur la shere les directions locales
222; associee a u et v. ces vecteurs definissent un repere orthonorme
223; local.
224; ces vecteurs sont construits dans un repere cartesien (cv_coord)
225; on a choisit un rayon de la terre unite (unit).
226;
227; definition de nu
228   radius = replicate(1,nxgd*nygd)
229   IF finite(glamu[0]*gphiu[0]) NE 0 THEN $
230     coord_sphe = transpose([ [(glamu[indice2d])[*]], [(gphiu[indice2d])[*]], [radius[*]] ]) $
231   ELSE coord_sphe = transpose([ [(glamf[indice2d])[*]], [(gphit[indice2d])[*]], [radius[*]] ])
232   r = cv_coord(from_sphere=coord_sphe,/to_rect,/degrees)
233; coordonnes de points de la grille u en cartesien
234   ux = reform(r[0, *], nxgd, nygd)
235   uy = reform(r[1, *], nxgd, nygd)
236   uz = reform(r[2, *], nxgd, nygd)
237; calcul de nu
238   nux = ux-shift(ux, 1, 0)
239   nuy = uy-shift(uy, 1, 0)
240   nuz = uz-shift(uz, 1, 0)
241; conditions aux limites
242   if NOT keyword_set(key_periodic) OR nxgd NE jpi then begin
243      nux[0, *] = nux[1, *]
244      nuy[0, *] = nuy[1, *]
245      nuz[0, *] = nuz[1, *]
246   ENDIF
247; reduction de la grille
248   nux = nux[reduitindice2d]
249   nuy = nuy[reduitindice2d]
250   nuz = nuz[reduitindice2d]
251; definition de nv
252   IF finite(glamv[0]*gphiv[0]) NE 0 THEN $
253   coord_sphe = transpose([ [(glamv[indice2d])[*]], [(gphiv[indice2d])[*]], [radius[*]] ]) $
254   ELSE coord_sphe = transpose([ [(glamt[indice2d])[*]], [(gphif[indice2d])[*]], [radius[*]] ])               
255   r = cv_coord(from_sphere=coord_sphe,/to_rect,/degrees)
256; coordonnes de points de la grille v en cartesien
257   vx = reform(r[0, *], nxgd, nygd)
258   vy = reform(r[1, *], nxgd, nygd)
259   vz = reform(r[2, *], nxgd, nygd)
260; calcul de nv
261   nvx = vx-shift(vx, 0, 1)
262   nvy = vy-shift(vy, 0, 1)
263   nvz = vz-shift(vz, 0, 1)
264; conditions aux limites
265   nvx[*, 0] = nvx[*, 1]
266   nvy[*, 0] = nvy[*, 1]
267   nvz[*, 0] = nvz[*, 1]
268; reduction de la grille
269   nvx = nvx[reduitindice2d]
270   nvy = nvy[reduitindice2d]
271   nvz = nvz[reduitindice2d]
272;
273; normalisation
274;
275   normalise, nux, nuy, nuz
276   normalise, nvx, nvy, nvz
277;
278; etape 1, c)
279;
280; coordonnes du vecteur V ds le repere cartesion
281;
282   direcx = zu*nux + zv*nvx
283   direcy = zu*nuy + zv*nvy
284   direcz = zu*nuz + zv*nvz
285; normalisation du vecteur v
286   normalise, direcx, direcy, direcz
287; on divise par 100.
288   direcx = direcx/100.
289   direcy = direcy/100.
290   direcz = direcz/100.
291;
292; etape 1, d)
293; coordonnees de la pointe de la fleche dans le repere cartesien
294
295   x1 = x0 + direcx
296   y1 = y0 + direcy
297   z1 = z0 + direcz
298
299; coordonnees de la pointe en spherique
300
301   coord_rect = transpose([ [x1[*]], [y1[*]], [z1[*]] ])
302   r = cv_coord(from_rect=coord_rect,/to_sphere,/degrees)
303   glam1 = reform(r[0, *], nx, ny)
304   gphi1 = reform(r[1, *], nx, ny)
305
306;
307; modif des glam tout se passe bien au niveau de la ligne de
308; changement de date...attention, il ne faut pas couper les fleches
309; qui sortent de la fenetre!
310; test: si il sort du cadre mais qu''avec un +/- 360 il y rentre on le
311; modifie...
312;
313   ind = where(glam1 LT !x.range[0] AND glam1+360. LE !x.range[1])
314   if ind[0] NE -1 then glam1[ind] = glam1[ind]+360.
315   ind = where(glam1 GT !x.range[1] AND glam1-360. GE !x.range[0])
316   if ind[0] NE -1 then glam1[ind] = glam1[ind]-360.
317
318   ind = where(glam LT !x.range[0] AND glam+360. LE !x.range[1])
319   if ind[0] NE -1 then glam[ind] = glam[ind]+360.
320   ind = where(glam  GT !x.range[1] AND glam-360. GE !x.range[0])
321   if ind[0] NE -1 then glam[ind] = glam[ind]-360.
322;
323;
324; etape 1, e)
325;
326   r = convert_coord(glam,gphi,/data,/to_normal)
327   x0 = r[0, *]                 ; coordonnes normales du debut de la fleche
328   y0 = r[1, *]                 ;
329   
330   r = convert_coord(glam1,gphi1,/data,/to_normal)
331   x1 = r[0, *]                 ; coordonnes normales de la fin de la fleche (avant scaling)
332   y1 = r[1, *]                 ;
333;
334; tests pour eviter que des fleches soient dessineees hors du domaine
335;
336   out = where(x0 LT !p.position[0] OR x0 GT !p.position[2]  $
337               OR y0 LT !p.position[1] OR y0 GT !p.position[3])
338   if out[0] NE -1 THEN x0[out] = !values.f_nan
339;
340; suivant les projections, il peu y a voir des points a nan qd on
341; passe en coordonnes normales. on supprime ces points.
342;
343   nan = finite(x0*y0*x1*y1)
344   number = where(nan EQ 1)
345   x0 = x0[number] & x1 = x1[number]
346   y0 = y0[number] & y1 = y1[number]
347   msk = msk[number]
348   norme = norme[number]
349;
350; on definit le vecteur direction dans le repere normalise
351;
352   dirx = x1-x0
353   diry = y1-y0
354;
355; on passe en polaire pour recuperer l''angle qui etait le but de
356; toute la partie 1!!!
357;
358
359   dirpol = cv_coord(from_rect = transpose([ [dirx[*]], [diry[*]] ]), /to_polar)
360   dirpol = msk*dirpol[0, *]
361;
362; 2eme etape....
363;
364; maintenant on s''occupe de la norme...
365;
366; Mise a l''echelle automatique
367;
368   if NOT keyword_set(cmref) then BEGIN
369      mipgsz = min(page_size, max = mapgsz)
370      sizexfeuille = mipgsz*key_portrait+mapgsz*(1-key_portrait)
371      sizexfeuille = 10.*sizexfeuille
372      cmref = 5 > floor(sizexfeuille/10.) < 15
373      cmref = cmref/10.
374   ENDIF
375   if NOT keyword_set(normeref) then BEGIN
376      value = max(norme)
377      puissance10 = 10.^floor(alog10(value))
378      normeref = puissance10*floor(value/puissance10)
379   endif
380   cm = 1.*normeref/cmref
381;
382; on modifie le tableau norme de facon a ce que un element qui a la
383; valeur cm soit represente par un trait de longueur 1cm sur le
384; papier.
385; norme contient la norme des vecteur que l''on veut dessiner
386;
387   norme = 1/(1.*cm)*norme*cv_cm2normal(dirpol)
388;
389;
390; 3eme etape....
391; maintenant qu''on a l''angle et la norme, et bien on recupere les
392; coordonnes en rectangulaire et on dessine les fleches.
393;
394   r = cv_coord(from_polar = transpose([ [dirpol[*]], [norme[*]] ]), /to_rect)
395   composantex = r[0, *]
396   composantey = r[1, *]
397;
398   x1 = x0+composantex
399   y1 = y0+composantey
400;
401; c''est parti pour le trace !
402;
403   if NOT KEYWORD_SET(vectcolor) then vectcolor = 0
404
405   points = where(msk EQ 1)
406   IF points[0] NE -1 THEN arrow, x0[points], y0[points], x1[points], y1[points], /norm $
407    , hsize = -.2, COLOR = vectcolor, THICK = vectthick
408;
409;  Dessine une fleche en bas a droite de la figure en guise de legende
410;
411   if NOT keyword_set(novectref) then BEGIN
412      dx = cmref*cv_cm2normal(0) ; longuer du vecteur de reference en coordonnes normalisees.
413      if keyword_set(vectrefformat) then $
414       normelegende = strtrim(string(normeref, format = vectrefformat), 1)+' ' $
415      ELSE normelegende = strtrim(normeref, 1)+' '
416;
417      if keyword_set(vectrefpos) then begin
418         r = convert_coord(vectrefpos,/data, /to_normal)
419         x0 = r[0]
420         y0 = r[1]
421      ENDIF ELSE BEGIN
422         x0 = !x.window[1]-dx
423         r = convert_coord(!d.x_ch_size, !d.y_ch_size, /device, /to_normal)
424         dy = 3*r[1]*!p.charsize
425         y0 = !y.window[0]-dy
426      ENDELSE
427
428      arrow, x0, y0, x0+dx, y0, /norm, hsize = -.2, color = 0
429      xyouts, x0, y0, normelegende, /norm, align = 1, charsize = !p.charsize, color = 0
430
431   endif
432;
433;
434
435   if keyword_set(key_performance) NE 0 THEN print, 'temps vecteur', systime(1)-tempsun
436;------------------------------------------------------------
437;------------------------------------------------------------
438   return
439END
440
441
442
443
Note: See TracBrowser for help on using the repository browser.