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

Last change on this file since 226 was 226, checked in by pinsard, 17 years ago

corrections of some misspellings in some *.pro

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