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

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

header improvements + xxx doc

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 15.1 KB
Line 
1;+
2; @file_comments
3;
4;
5; @categories
6;
7;
8; @param ANGLE
9;
10;
11; @returns
12;
13;
14; @restrictions
15;
16;
17; @examples
18;
19;
20; @history
21;
22;
23; @version
24; $Id$
25;-
26FUNCTION cv_cm2normal, angle
27;
28; Give the lenth in normal coordinates of a trait oriented of an angle
29; by rapport at the x axis and which must do 1 cm on the drawing.
30; Angle can be an array.
31;
32;
33;
34  compile_opt idl2, strictarrsubs
35;
36@common
37; What is the lenth in normal coordinates of a trait which will do 1 cm
38; on the paper an which is parallel to x?
39  mipgsz = min(page_size, max = mapgsz)
40   sizexfeuille = mipgsz*key_portrait+mapgsz*(1-key_portrait)
41   sizeyfeuille = mapgsz*key_portrait+mipgsz*(1-key_portrait)
42   cm_en_normal = 1./sizexfeuille
43;
44; If the aspect rapport of the window is not equal to 1, the lenth in
45; normalized coordinates of  a trait of 1 cm vary following the polar
46; angle of this trait.
47;
48   aspect = sizexfeuille/sizeyfeuille
49   cm_en_normal = cm_en_normal*sqrt( 1 +(aspect^2-1)*sin(angle)^2 )
50;
51   return, cm_en_normal
52END
53;
54;+
55; @file_comments
56;
57;
58; @categories
59;
60;
61; @param U
62;
63;
64; @param V
65;
66;
67; @param W
68;
69;
70; @restrictions
71;
72;
73; @examples
74;
75;
76; @history
77;
78;
79; @version
80; $Id$
81;-
82PRO normalise, u, v, w
83;
84; normalize the vector
85;
86;
87  compile_opt idl2, strictarrsubs
88;
89   IF n_elements(w) NE 0 THEN BEGIN
90      norme = sqrt(u^2.+v^2.+w^2.)
91      ind = where(norme NE 0)
92      u[ind] = u[ind]/norme[ind]
93      v[ind] = v[ind]/norme[ind]
94      w[ind] = w[ind]/norme[ind]
95   ENDIF ELSE BEGIN
96      norme = sqrt(u^2.+v^2.)
97      ind = where(norme NE 0)
98      u[ind] = u[ind]/norme[ind]
99      v[ind] = v[ind]/norme[ind]
100   ENDELSE
101END
102;------------------------------------------------------------
103;------------------------------------------------------------
104;------------------------------------------------------------
105;+
106;
107; @file_comments
108; Trace vectors (even if they are on a deformed grid) on any projection.
109; In this way, all vectors have a comparable norme on the drawing (to be
110; clear, a vector which measure 1 cm measure it, no matter the projection
111; and is position on the sphere).
112;
113; @categories
114; Graphics
115;
116; @param COMPOSANTEU {in}{required}
117; It is the u component of the vector to be traced. This 2d array has the
118; same dimension that reduitindice2d (see further)
119;
120; @param COMPOSANTEV {in}{required}
121; It is the v component of the vector to be traced. This 2d array has the
122; same dimension that reduitindice2d (see further)
123;
124; @param NORMEVECTEUR
125;
126;
127; @param INDICE2D  {in}{required}
128; It in an index allowing to to pass from an jpi or jpj array to the zoom
129; on which we do the drawing
130;
131; @param REDUITINDICE2D {in}{required}
132; It is an index allowing to pass from an array defined by indice2d to the
133; array for which we really have vectors to be traced (to be clear, it is
134; for example when we trace only one vector on two).
135;
136; @keyword CMREF
137; The lenth in cm that must measure the arrow normed normeref. By default,
138; it is ajusted t othe drawing and included between .5 and 1.5 cm.
139;
140; @keyword MISSING
141; The value of a missing value. Do not use this keyword. Fixed at 1e5 by
142; ajoutvect.pro
143;     
144; @keyword NORMEREF
145; The norme of the reference arrow.
146;
147; @keyword VECTCOLOR
148; The color of the arrow. Black by default (color 0)
149;
150; @keyword VECTTHICK
151; The thick of the arrow. 1 by default
152;
153; @keyword VECTREFPOS
154; Vector composed of 2 elements specifing the position on DATA coordinates
155; from de begining of the reference vector. By default at the right bottom
156; of the drawing.
157;
158; @keyword VECTREFFORMAT
159; The format to be used to specify the norme of the reference vector.
160;
161; @keyword NOVECTREF
162; To delete the display of the reference vector.
163;
164; @keyword _EXTRA
165; Used to pass your keywords
166;
167; @uses
168; common.pro
169;
170; @history
171;  Creation : 13/02/98 G. Roullet (grlod\@lodyc.jussieu.fr)
172;  Modification : 14/01/99 realise la transformation
173;  spherique<->cartesien G. Roullet
174;                 12/03/99 verification de la routine G. Roullet
175;  8/11/1999:
176;  G. Roullet et Sebastien Masson (smasson\@lodyc.jussieu.fr)
177;  adaptation pour les zoom. reverification...traitement separe de la
178;  direction et de la norme des vecteurs. mots cles NORMEREF et CMREF.
179;
180; @version
181; $Id$
182;
183;-
184;------------------------------------------------------------
185;------------------------------------------------------------
186;------------------------------------------------------------
187PRO vecteur, composanteu, composantev, normevecteur, indice2d, reduitindice2d $
188             , CMREF = cmref, MISSING = missing, NORMEREF = normeref $
189             , VECTCOLOR = vectcolor, VECTTHICK = vectthick, VECTREFPOS = vectrefpos $
190             , VECTREFFORMAT = vectrefformat, NOVECTREF = novectref, _extra = extra
191;
192  compile_opt idl2, strictarrsubs
193;
194@common
195   tempsun = systime(1)         ; For key_performance
196;
197;
198   taille = size(composanteu)
199   nx = taille[1]
200   ny = taille[2]
201   if n_elements(reduitindice2d) EQ 0 then reduitindice2d = lindgen(nx, ny)
202   zu = composanteu
203   zv = composantev
204   norme = normevecteur
205   taille = size(indice2d)
206   nxgd = taille[1]
207   nygd = taille[2]
208;
209   msk = replicate(1, nx, ny)
210   if keyword_set(missing) then terre = where(abs(zu) GE missing/10) ELSE terre = -1
211   if terre[0] NE -1  then BEGIN
212      msk[terre] = 0
213      zu[terre] = 0
214      zv[terre] = 0
215      norme[terre] = 0
216   ENDIF
217;
218; Stage 1:
219;
220; Given that the directions and the sense that the vector has on the sphere,
221; we have to try to determinate this direction and the sense that the vector
222; will have on the screen once it will have been projected.
223;
224; In theory: on the sphere, a vector in a given point has for direction the
225; tangent at the circle passing by the center of the Earth and by the vector.
226; So, find the direction once the projection is done, it is find the tangent
227; to the curve representing the projection of the circle on the 2d plan at the
228; point representing the projection of the starting point of the shere on the
229; 2d plan.
230;
231; In practice we do no know the definition of the curve given by the projection
232; of a circle so find its tangente in a point...
233;
234; What we do:
235; In a 3d cartesian reference,
236;       a) We find coorinates of the point T (starting of the arrow) situed
237;       on the sphere.
238;       b) To each point T, we determine local directions defined by the grid
239;       on this point and on which coordinates (u,v) of the vector refer to.
240;       These local directions are defined by gradients of glam and gphi. Once
241;       we have obtain these directions, we considare them like orthogonal and
242;       by norming them, we build an orthonormal reference (nu,nv) on which
243;       coordinates (u,v) of the vector refer to. In the starting 3d cartesian
244;       reference, the vector is defined by:
245;       V=u*nu+v*nv
246;       (where V, nu and nv are 3d vectors and u and v are scalars).
247;       c) To approximate the tangente to the circle by the chord defined by
248;       the beginning and the ending of the arrow, we will normalize V, and
249;       then divide it by 100.
250;       d) This allows us to determine coordinates of extremities of the chord
251;       in the 3d cartesian reference. We pass them in spherical coordinates in
252;       order to recuperate latitude and longitude position of these points on
253;       the sphere.
254;       e) We pass coordinates of these points in normalized coordinates, then
255;       in polar coordinates in order to find the angle and the direction they
256;       dertermine on the drawing.
257;
258;
259; Stage 1, a)
260;
261;
262; coordinates of the point T (beginning of the arrow) in spherical coordinates.
263   glam = glamt[indice2d[reduitindice2d]]
264   gphi = gphit[indice2d[reduitindice2d]]
265;
266; Coordinates of the point T (beginning of the arrow) in the cartesian reference.
267; For the sphere, we use a sphere with a radius of 1.
268;
269   radius = replicate(1,nx*ny)
270   coord_sphe = transpose([ [glam[*]], [gphi[*]], [radius[*]] ])
271   r = cv_coord(from_sphere=coord_sphe,/to_rect,/degrees)
272;
273   x0 = reform(r[0, *], nx, ny)
274   y0 = reform(r[1, *], nx, ny)
275   z0 = reform(r[2, *], nx, ny)
276;
277; Stage 1, b)
278;
279; Construction of a vector nu (resp. nv), vectr normed carried by the axis of
280; points u[i,j] and u[i-1,j] (resp v[i,j] and v[i,j-1]) which define, for each
281; point on the sphere, local directions associated with u and v. These vectors
282; define a local orthonormal reference.
283; These vectors are built in a cartesian reference (cv_coord). We have choose a
284; unity radius of the Earth (unit).
285;
286; definition of nu
287   radius = replicate(1,nxgd*nygd)
288   IF finite(glamu[0]*gphiu[0]) NE 0 THEN $
289     coord_sphe = transpose([ [(glamu[indice2d])[*]], [(gphiu[indice2d])[*]], [radius[*]] ]) $
290   ELSE coord_sphe = transpose([ [(glamf[indice2d])[*]], [(gphit[indice2d])[*]], [radius[*]] ])
291   r = cv_coord(from_sphere=coord_sphe,/to_rect,/degrees)
292; coordinates of points of the grid u in cartesian.
293   ux = reform(r[0, *], nxgd, nygd)
294   uy = reform(r[1, *], nxgd, nygd)
295   uz = reform(r[2, *], nxgd, nygd)
296; calculation of nu
297   nux = ux-shift(ux, 1, 0)
298   nuy = uy-shift(uy, 1, 0)
299   nuz = uz-shift(uz, 1, 0)
300; conditions at extremities.
301   if NOT keyword_set(key_periodic) OR nxgd NE jpi then begin
302      nux[0, *] = nux[1, *]
303      nuy[0, *] = nuy[1, *]
304      nuz[0, *] = nuz[1, *]
305   ENDIF
306; reduction of the grid
307   nux = nux[reduitindice2d]
308   nuy = nuy[reduitindice2d]
309   nuz = nuz[reduitindice2d]
310; definition of nv
311   IF finite(glamv[0]*gphiv[0]) NE 0 THEN $
312   coord_sphe = transpose([ [(glamv[indice2d])[*]], [(gphiv[indice2d])[*]], [radius[*]] ]) $
313   ELSE coord_sphe = transpose([ [(glamt[indice2d])[*]], [(gphif[indice2d])[*]], [radius[*]] ])               
314   r = cv_coord(from_sphere=coord_sphe,/to_rect,/degrees)
315; coordinates of points of the grid in cartesian.
316   vx = reform(r[0, *], nxgd, nygd)
317   vy = reform(r[1, *], nxgd, nygd)
318   vz = reform(r[2, *], nxgd, nygd)
319; calcul of nv
320   nvx = vx-shift(vx, 0, 1)
321   nvy = vy-shift(vy, 0, 1)
322   nvz = vz-shift(vz, 0, 1)
323; conditions at extremities
324   nvx[*, 0] = nvx[*, 1]
325   nvy[*, 0] = nvy[*, 1]
326   nvz[*, 0] = nvz[*, 1]
327; reduction of the grid
328   nvx = nvx[reduitindice2d]
329   nvy = nvy[reduitindice2d]
330   nvz = nvz[reduitindice2d]
331;
332; normalization
333;
334   normalise, nux, nuy, nuz
335   normalise, nvx, nvy, nvz
336;
337; Stage 1, c)
338;
339; coordinates of the vector V in the cartesian reference
340;
341   direcx = zu*nux + zv*nvx
342   direcy = zu*nuy + zv*nvy
343   direcz = zu*nuz + zv*nvz
344; normalization of the vector V
345   normalise, direcx, direcy, direcz
346; on divide by 100
347   direcx = direcx/100.
348   direcy = direcy/100.
349   direcz = direcz/100.
350;
351; Stege 1, d)
352; coordinates of the point of the arrow in the cartesian reference.
353
354   x1 = x0 + direcx
355   y1 = y0 + direcy
356   z1 = z0 + direcz
357
358; coordinates of the point of the arrow in spherical coordinates.
359
360   coord_rect = transpose([ [x1[*]], [y1[*]], [z1[*]] ])
361   r = cv_coord(from_rect=coord_rect,/to_sphere,/degrees)
362   glam1 = reform(r[0, *], nx, ny)
363   gphi1 = reform(r[1, *], nx, ny)
364
365;
366; modification of glams. Everything take place at the level of the line
367; of changing of date... BEWARE, do not cut arrow which goes out of the
368; window!
369; test: If it goes out of the frame, but, thanks to +/- 360° it come in,
370; we modify it
371;
372   ind = where(glam1 LT !x.range[0] AND glam1+360. LE !x.range[1])
373   if ind[0] NE -1 then glam1[ind] = glam1[ind]+360.
374   ind = where(glam1 GT !x.range[1] AND glam1-360. GE !x.range[0])
375   if ind[0] NE -1 then glam1[ind] = glam1[ind]-360.
376
377   ind = where(glam LT !x.range[0] AND glam+360. LE !x.range[1])
378   if ind[0] NE -1 then glam[ind] = glam[ind]+360.
379   ind = where(glam  GT !x.range[1] AND glam-360. GE !x.range[0])
380   if ind[0] NE -1 then glam[ind] = glam[ind]-360.
381;
382;
383; Stage 1, e)
384;
385   r = convert_coord(glam,gphi,/data,/to_normal)
386   x0 = r[0, *]                 ; normal coordinates of the beginning of the array.
387   y0 = r[1, *]                 ;
388   
389   r = convert_coord(glam1,gphi1,/data,/to_normal)
390   x1 = r[0, *]                 ; normal coordinates of the ending of the array (Before scaling).
391   y1 = r[1, *]                 ;
392;
393; tests to avoid that arrows be drawing out of the domain.
394;
395   out = where(x0 LT !p.position[0] OR x0 GT !p.position[2]  $
396               OR y0 LT !p.position[1] OR y0 GT !p.position[3])
397   if out[0] NE -1 THEN x0[out] = !values.f_nan
398;
399; Following projections, there may are points at NaN when we pass in normal coordinates.
400; We delete these points.
401;
402   nan = finite(x0*y0*x1*y1)
403   number = where(nan EQ 1)
404   x0 = x0[number] & x1 = x1[number]
405   y0 = y0[number] & y1 = y1[number]
406   msk = msk[number]
407   norme = norme[number]
408;
409; We define the vector direction in the normalize reference.
410;
411   dirx = x1-x0
412   diry = y1-y0
413;
414;We pass in polar coordinates to recuperate the angle which wasb the goal of all the first stage!!!
415;
416
417   dirpol = cv_coord(from_rect = transpose([ [dirx[*]], [diry[*]] ]), /to_polar)
418   dirpol = msk*dirpol[0, *]
419;
420; Stage 2
421;
422; Now we take care of the norme...
423;
424; Automatic putting at the scale
425;
426   if NOT keyword_set(cmref) then BEGIN
427      mipgsz = min(page_size, max = mapgsz)
428      sizexfeuille = mipgsz*key_portrait+mapgsz*(1-key_portrait)
429      sizexfeuille = 10.*sizexfeuille
430      cmref = 5 > floor(sizexfeuille/10.) < 15
431      cmref = cmref/10.
432   ENDIF
433   if NOT keyword_set(normeref) then BEGIN
434      value = max(norme)
435      puissance10 = 10.^floor(alog10(value))
436      normeref = puissance10*floor(value/puissance10)
437   endif
438   cm = 1.*normeref/cmref
439;
440; We modify the array norme to an element having the value cm be represented
441; by a trait of lenght 1 cm on the paper. Norme contain the norme of vectors
442; we want to draw.
443;
444   norme = 1/(1.*cm)*norme*cv_cm2normal(dirpol)
445;
446;
447; Stage 3
448; Now that we have the angle and the norme, we recuperate coordinates in
449; rectangular and we draw arrows.
450;
451   r = cv_coord(from_polar = transpose([ [dirpol[*]], [norme[*]] ]), /to_rect)
452   composantex = r[0, *]
453   composantey = r[1, *]
454;
455   x1 = x0+composantex
456   y1 = y0+composantey
457;
458; Drawing
459;
460   if NOT KEYWORD_SET(vectcolor) then vectcolor = 0
461
462   points = where(msk EQ 1)
463   IF points[0] NE -1 THEN arrow, x0[points], y0[points], x1[points], y1[points], /norm $
464    , hsize = -.2, COLOR = vectcolor, THICK = vectthick
465;
466;  Draw an arrow at the right bottom of the drawing as a caption.
467;
468   if NOT keyword_set(novectref) then BEGIN
469      dx = cmref*cv_cm2normal(0) ; Lenght of the vector of reference in normalzed coordinates.
470      if keyword_set(vectrefformat) then $
471       normelegende = strtrim(string(normeref, format = vectrefformat), 1)+' ' $
472      ELSE normelegende = strtrim(normeref, 1)+' '
473;
474      if keyword_set(vectrefpos) then begin
475         r = convert_coord(vectrefpos,/data, /to_normal)
476         x0 = r[0]
477         y0 = r[1]
478      ENDIF ELSE BEGIN
479         x0 = !x.window[1]-dx
480         r = convert_coord(!d.x_ch_size, !d.y_ch_size, /device, /to_normal)
481         dy = 3*r[1]*!p.charsize
482         y0 = !y.window[0]-dy
483      ENDELSE
484
485      arrow, x0, y0, x0+dx, y0, /norm, hsize = -.2, color = 0
486      xyouts, x0, y0, normelegende, /norm, align = 1, charsize = !p.charsize, color = 0
487
488   endif
489;
490;
491
492   if keyword_set(key_performance) NE 0 THEN print, 'temps vecteur', systime(1)-tempsun
493;------------------------------------------------------------
494;------------------------------------------------------------
495   return
496END
497
498
499
500
Note: See TracBrowser for help on using the repository browser.