source: trunk/ToBeReviewed/PLOTS/VECTEUR/vecteur.pro @ 69

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

upgrade of PLOTS/VECTEUR 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: 14.7 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@common
84; quelle est la longeur en coordonnees normales d''un trait qui fera 1
85; cm sur le parier et qui est parallele a x?
86  mipgsz = min(page_size, max = mapgsz)
87   sizexfeuille = mipgsz*key_portrait+mapgsz*(1-key_portrait)
88   sizeyfeuille = mapgsz*key_portrait+mipgsz*(1-key_portrait)
89   cm_en_normal = 1./sizexfeuille
90;
91;  si le rapport d''aspect de la fenetre n''est pas egale a 1, la
92;  longeur en coordonees normalise d''un trait de 1cm varie suivant
93;  l''angle polaire de ce trait.
94;
95   aspect = sizexfeuille/sizeyfeuille
96   cm_en_normal = cm_en_normal*sqrt( 1 +(aspect^2-1)*sin(angle)^2 )
97;
98   return, cm_en_normal
99END
100;
101PRO normalise, u, v, w
102;
103; normalise le vecteur
104;
105   IF n_elements(w) NE 0 THEN BEGIN
106      norme = sqrt(u^2.+v^2.+w^2.)
107      ind = where(norme NE 0)
108      u(ind) = u(ind)/norme[ind]
109      v(ind) = v(ind)/norme[ind]
110      w(ind) = w(ind)/norme[ind]
111   ENDIF ELSE BEGIN
112      norme = sqrt(u^2.+v^2.)
113      ind = where(norme NE 0)
114      u(ind) = u(ind)/norme[ind]
115      v(ind) = v(ind)/norme[ind]
116   ENDELSE
117END
118PRO vecteur, composanteu, composantev, normevecteur, indice2d, reduitindice2d $
119             , CMREF = cmref, MISSING = missing, NORMEREF = normeref $
120             , VECTCOLOR = vectcolor, VECTTHICK = vectthick, VECTREFPOS = vectrefpos $
121             , VECTREFFORMAT = vectrefformat, NOVECTREF = novectref, _extra = extra
122@common
123   tempsun = systime(1)         ; pour key_performance
124;
125;
126   taille = size(composanteu)
127   nx = taille[1]
128   ny = taille[2]
129   if n_elements(reduitindice2d) EQ 0 then reduitindice2d = lindgen(nx, ny)
130   zu = composanteu
131   zv = composantev
132   norme = normevecteur
133   taille = size(indice2d)
134   nxgd = taille[1]
135   nygd = taille[2]
136;
137   msk = replicate(1, nx, ny)
138   if keyword_set(missing) then terre = where(abs(zu) GE missing/10) ELSE terre = -1
139   if terre[0] NE -1  then BEGIN
140      msk[terre] = 0
141      zu[terre] = 0
142      zv[terre] = 0
143      norme[terre] = 0
144   ENDIF
145;
146; Etape 1:
147;
148; etant donne la direction et le sens que le vecteur a sur la
149; sphere, il faut se debrouiller pour determiner cette direction et le
150; sens qu'aura le vecteur sur l''ecran ou la feuille une fois qu''il
151; aura ete projete.
152;
153; En theorie: sur la sphere, un vecteur en un point donne a pour
154; direction la tangente au cercle qui passe par le centre de la terre
155; et par le vecteur. Donc trouver la direction une fois la projection
156; faite ds le plan 2d, c''est trouver la tangente a la courbe
157; representant la projection du cercle sur le plan 2d au point
158; representant la projection du point de depart de la shere sur le
159; plan 2d!!!
160;
161; En pratique on ne connait pas la definition de la courbe que donne
162; la projection d''un cercle alors trouver sa tangente en un point...
163;
164; Ce que l''on fait:
165; Ds un repere cartesien 3d,
166;       a) on trouve les coordonnees du point T (debut de la fleche)
167;       situe sur la shere.
168;       b) pour chaque point T on determine les directions locales
169;       definies par la grille en ce point et auxquelles se rapportent
170;       les coordonnes (u,v) du vecteur. Ces directions locales sont
171;       definies par les gradiants des glam et gphi. Une fois ces
172;       directions obtenues, on les considere comme orthogonales et en
173;       les normant on construit un repere orthonormal (nu,nv) auquel se
174;       rapporte les coordonnes (u,v) du vecteur. Ds le repere
175;       cartesien 3d de depart, le vecteur est definit par:
176;       V=u*nu+v*nv (ou V, nu et nv sont des vecteurs 3d et u et v des
177;       scalaires)
178;       c) pour approximer la tangente au cercle par la corde definie
179;       par le debut et la fin de la fleche, on va normaliser V puis
180;       le diviser par 100.
181;       d) ceci nous permet de determiner les coordonnees ds le repere
182;       cartesien 3d des extremites de la corde, on les passe en
183;       coordonnes sphereriques de facon a recuperer les positions en
184;       latitude longitude de ces points sur la sphere.
185;       e) on passe les coordonnees de ces points en coordonnees
186;       normalise puis en corrdonnes polaire de facon a trouver
187;       l''angle et la direction qu''ils determinent sur le dessin...
188;
189;
190; etape 1, a)
191;
192;
193; coordonnes du point T (debut de la fleche) en coordonnes sheriques
194   glam = glamt[indice2d[reduitindice2d]]
195   gphi = gphit[indice2d[reduitindice2d]]
196;
197; coordonnes du point T (debut de la fleche) dans le repere cartesien
198; on utilise comme shere, une shere de rayon 1.
199;
200   radius = replicate(1,nx*ny)
201   coord_sphe = transpose([ [glam[*]], [gphi[*]], [radius[*]] ])
202   r = cv_coord(from_sphere=coord_sphe,/to_rect,/degrees)
203;
204   x0 = reform(r(0, *), nx, ny)
205   y0 = reform(r(1, *), nx, ny)
206   z0 = reform(r(2, *), nx, ny)
207;
208; etape 1, b)
209;
210; Construction du vecteur nu (resp. nv), vecteur norme porte par
211; l''axe des points u(i,j) et u(i-1,j) (resp v(i,j) et v(i,j-1))
212; qui definissent pour chaque point sur la shere les directions locales
213; associee a u et v. ces vecteurs definissent un repere orthonorme
214; local.
215; ces vecteurs sont construits dans un repere cartesien (cv_coord)
216; on a choisit un rayon de la terre unite (unit).
217;
218; definition de nu
219   radius = replicate(1,nxgd*nygd)
220   IF finite(glamu[0]*gphiu[0]) NE 0 THEN $
221     coord_sphe = transpose([ [(glamu[indice2d])[*]], [(gphiu[indice2d])[*]], [radius(*)] ]) $
222   ELSE coord_sphe = transpose([ [(glamf[indice2d])[*]], [(gphit[indice2d])[*]], [radius(*)] ])
223   r = cv_coord(from_sphere=coord_sphe,/to_rect,/degrees)
224; coordonnes de points de la grille u en cartesien
225   ux = reform(r(0, *), nxgd, nygd)
226   uy = reform(r(1, *), nxgd, nygd)
227   uz = reform(r(2, *), nxgd, nygd)
228; calcul de nu
229   nux = ux-shift(ux, 1, 0)
230   nuy = uy-shift(uy, 1, 0)
231   nuz = uz-shift(uz, 1, 0)
232; conditions aux limites
233   if NOT keyword_set(key_periodic) OR nxgd NE jpi then begin
234      nux[0, *] = nux[1, *]
235      nuy[0, *] = nuy[1, *]
236      nuz[0, *] = nuz[1, *]
237   ENDIF
238; reduction de la grille
239   nux = nux[reduitindice2d]
240   nuy = nuy[reduitindice2d]
241   nuz = nuz[reduitindice2d]
242; definition de nv
243   IF finite(glamv[0]*gphiv[0]) NE 0 THEN $
244   coord_sphe = transpose([ [(glamv[indice2d])[*]], [(gphiv[indice2d])[*]], [radius(*)] ]) $
245   ELSE coord_sphe = transpose([ [(glamt[indice2d])[*]], [(gphif[indice2d])[*]], [radius(*)] ])               
246   r = cv_coord(from_sphere=coord_sphe,/to_rect,/degrees)
247; coordonnes de points de la grille v en cartesien
248   vx = reform(r(0, *), nxgd, nygd)
249   vy = reform(r(1, *), nxgd, nygd)
250   vz = reform(r(2, *), nxgd, nygd)
251; calcul de nv
252   nvx = vx-shift(vx, 0, 1)
253   nvy = vy-shift(vy, 0, 1)
254   nvz = vz-shift(vz, 0, 1)
255; conditions aux limites
256   nvx[*, 0] = nvx[*, 1]
257   nvy[*, 0] = nvy[*, 1]
258   nvz[*, 0] = nvz[*, 1]
259; reduction de la grille
260   nvx = nvx[reduitindice2d]
261   nvy = nvy[reduitindice2d]
262   nvz = nvz[reduitindice2d]
263;
264; normalisation
265;
266   normalise, nux, nuy, nuz
267   normalise, nvx, nvy, nvz
268;
269; etape 1, c)
270;
271; coordonnes du vecteur V ds le repere cartesion
272;
273   direcx = zu*nux + zv*nvx
274   direcy = zu*nuy + zv*nvy
275   direcz = zu*nuz + zv*nvz
276; normalisation du vecteur v
277   normalise, direcx, direcy, direcz
278; on divise par 100.
279   direcx = direcx/100.
280   direcy = direcy/100.
281   direcz = direcz/100.
282;
283; etape 1, d)
284; coordonnees de la pointe de la fleche dans le repere cartesien
285
286   x1 = x0 + direcx
287   y1 = y0 + direcy
288   z1 = z0 + direcz
289
290; coordonnees de la pointe en spherique
291
292   coord_rect = transpose([ [x1(*)], [y1(*)], [z1(*)] ])
293   r = cv_coord(from_rect=coord_rect,/to_sphere,/degrees)
294   glam1 = reform(r(0, *), nx, ny)
295   gphi1 = reform(r(1, *), nx, ny)
296
297;
298; modif des glam tout se passe bien au niveau de la ligne de
299; changement de date...attention, il ne faut pas couper les fleches
300; qui sortent de la fenetre!
301; test: si il sort du cadre mais qu''avec un +/- 360 il y rentre on le
302; modifie...
303;
304   ind = where(glam1 LT !x.range[0] AND glam1+360. LE !x.range[1])
305   if ind[0] NE -1 then glam1(ind) = glam1(ind)+360.
306   ind = where(glam1 GT !x.range[1] AND glam1-360. GE !x.range[0])
307   if ind[0] NE -1 then glam1(ind) = glam1(ind)-360.
308
309   ind = where(glam LT !x.range[0] AND glam+360. LE !x.range[1])
310   if ind[0] NE -1 then glam(ind) = glam(ind)+360.
311   ind = where(glam  GT !x.range[1] AND glam-360. GE !x.range[0])
312   if ind[0] NE -1 then glam(ind) = glam(ind)-360.
313;
314;
315; etape 1, e)
316;
317   r = convert_coord(glam,gphi,/data,/to_normal)
318   x0 = r(0, *)                 ; coordonnes normales du debut de la fleche
319   y0 = r(1, *)                 ;
320   
321   r = convert_coord(glam1,gphi1,/data,/to_normal)
322   x1 = r(0, *)                 ; coordonnes normales de la fin de la fleche (avant scaling)
323   y1 = r(1, *)                 ;
324;
325; tests pour eviter que des fleches soient dessineees hors du domaine
326;
327   out = where(x0 LT !p.position[0] OR x0 GT !p.position[2]  $
328               OR y0 LT !p.position[1] OR y0 GT !p.position[3])
329   if out[0] NE -1 THEN x0[out] = !values.f_nan
330;
331; suivant les projections, il peu y a voir des points a nan qd on
332; passe en coordonnes normales. on supprime ces points.
333;
334   nan = finite(x0*y0*x1*y1)
335   number = where(nan EQ 1)
336   x0 = x0[number] & x1 = x1[number]
337   y0 = y0[number] & y1 = y1[number]
338   msk = msk[number]
339   norme = norme[number]
340;
341; on definit le vecteur direction dans le repere normalise
342;
343   dirx = x1-x0
344   diry = y1-y0
345;
346; on passe en polaire pour recuperer l''angle qui etait le but de
347; toute la partie 1!!!
348;
349
350   dirpol = cv_coord(from_rect = transpose([ [dirx[*]], [diry[*]] ]), /to_polar)
351   dirpol = msk*dirpol[0, *]
352;
353; 2eme etape....
354;
355; maintenant on s''occupe de la norme...
356;
357; Mise a l''echelle automatique
358;
359   if NOT keyword_set(cmref) then BEGIN
360      mipgsz = min(page_size, max = mapgsz)
361      sizexfeuille = mipgsz*key_portrait+mapgsz*(1-key_portrait)
362      sizexfeuille = 10.*sizexfeuille
363      cmref = 5 > floor(sizexfeuille/10.) < 15
364      cmref = cmref/10.
365   ENDIF
366   if NOT keyword_set(normeref) then BEGIN
367      value = max(norme)
368      puissance10 = 10.^floor(alog10(value))
369      normeref = puissance10*floor(value/puissance10)
370   endif
371   cm = 1.*normeref/cmref
372;
373; on modifie le tableau norme de facon a ce que un element qui a la
374; valeur cm soit represente par un trait de longueur 1cm sur le
375; papier.
376; norme contient la norme des vecteur que l''on veut dessiner
377;
378   norme = 1/(1.*cm)*norme*cv_cm2normal(dirpol)
379;
380;
381; 3eme etape....
382; maintenant qu''on a l''angle et la norme, et bien on recupere les
383; coordonnes en rectangulaire et on dessine les fleches.
384;
385   r = cv_coord(from_polar = transpose([ [dirpol[*]], [norme[*]] ]), /to_rect)
386   composantex = r(0, *)
387   composantey = r(1, *)
388;
389   x1 = x0+composantex
390   y1 = y0+composantey
391;
392; c''est parti pour le trace !
393;
394   if NOT KEYWORD_SET(vectcolor) then vectcolor = 0
395
396   points = where(msk EQ 1)
397   IF points[0] NE -1 THEN arrow, x0(points), y0(points), x1(points), y1(points), /norm $
398    , hsize = -.2, COLOR = vectcolor, THICK = vectthick
399;
400;  Dessine une fleche en bas a droite de la figure en guise de legende
401;
402   if NOT keyword_set(novectref) then BEGIN
403      dx = cmref*cv_cm2normal(0) ; longuer du vecteur de reference en coordonnes normalisees.
404      if keyword_set(vectrefformat) then $
405       normelegende = strtrim(string(normeref, format = vectrefformat), 1)+' ' $
406      ELSE normelegende = strtrim(normeref, 1)+' '
407;
408      if keyword_set(vectrefpos) then begin
409         r = convert_coord(vectrefpos,/data, /to_normal)
410         x0 = r[0]
411         y0 = r[1]
412      ENDIF ELSE BEGIN
413         x0 = !x.window[1]-dx
414         r = convert_coord(!d.x_ch_size, !d.y_ch_size, /device, /to_normal)
415         dy = 3*r[1]*!p.charsize
416         y0 = !y.window[0]-dy
417      ENDELSE
418
419      arrow, x0, y0, x0+dx, y0, /norm, hsize = -.2, color = 0
420      xyouts, x0, y0, normelegende, /norm, align = 1, charsize = !p.charsize, color = 0
421
422   endif
423;
424;
425
426   if keyword_set(key_performance) NE 0 THEN print, 'temps vecteur', systime(1)-tempsun
427;------------------------------------------------------------
428;------------------------------------------------------------
429   return
430END
431
432
433
434
Note: See TracBrowser for help on using the repository browser.