59e05e301c37067a21d27fbdf325359e19493699
[scilab.git] / scilab / modules / graphics / macros / comet3d.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2011 - INRIA - Serge Steer <serge.steer@inria.fr>
3 //
4 // Copyright (C) 2012 - 2016 - Scilab Enterprises
5 //
6 // This file is hereby licensed under the terms of the GNU GPL v2.0,
7 // pursuant to article 5.3.4 of the CeCILL v.2.1.
8 // This file was originally licensed under the terms of the CeCILL v2.1,
9 // and continues to be available under such terms.
10 // For more information, see the COPYING file which you should have received
11 // along with this program.
12
13 function comet3d(varargin)
14     //Comet-like trajectory.
15     //   comet(y) displays an animated comet plot of the vector y.
16     //   comet(x,y) displays an animated comet plot of vector y vs. x.
17     //   comet(x,y,p) uses a comet of length p*size(y,'*').  Default is p = 0.1.
18
19     //   Example:
20     //       t = linspace(-%pi,%pi,500);
21     //       clf();comet3d(sin(5*t),sin(t),t^2)
22     //
23     //       function z=traj(x,y),z=1.5*sin(x^2)*cos(y),endfunction
24     //       clf();comet3d(cos(t),sin(t),traj)
25     //
26     nv=size(varargin)
27     if nv>=3&varargin(nv-1)=="colors" then
28         c=round(varargin(nv))
29         if type(c)<>1|~isreal(c) then
30             error(msprintf(_("%s: Wrong type for argument #%d: Real vector expected.\n"),"comet3d",nv))
31         end
32         varargin=list(varargin(1:$-2))
33     else
34         c=[]
35     end
36     select size(varargin)
37
38     case 1 then //z
39         z=varargin(1)
40         if or(size(z)==1) then
41             x=1:size(z,"*")
42         else
43             x=1:size(z,1)
44         end
45         y=x
46         p=0.1
47     case 3 then  //x,y,z
48         [x,y,z]=varargin(1:3)
49         p=0.1
50     case 4 then  //x,y,z,p
51         [x,y,z,p]=varargin(1:4)
52     else
53         error(msprintf(_("%s: Wrong number of input arguments: %d or %d to %d expected.\n"),"comet3d",1,3,4))
54     end
55
56
57     if type(x)<>1|~isreal(x) then
58         error(msprintf(_("%s: Wrong type for argument #%d: Real vector expected.\n"),"comet3d",1))
59     end
60     if type(y)<>1|~isreal(x) then
61         error(msprintf(_("%s: Wrong type for argument #%d: Real vector expected.\n"),"comet3d",1))
62     end
63
64     if (type(z)<>1|~isreal(z))&type(z)<>13 then
65         error(msprintf(_("%s: Wrong type for argument #%d: Real vector expected.\n"),"comet3d",3))
66     end
67
68
69     if type(z)==13 then
70         x=x(:);y=y(:)
71         n=size(x,"*")
72         m=1
73         if n<>size(y,"*") then
74             error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same sizes expected.\n"),"comet3d",1,2))
75         end
76         prot=funcprot();funcprot(0)
77         zz=z;
78         z=zeros(n,1);
79         for i=1:n
80             z(i)=zz(x(i),y(i))
81         end
82         funcprot(prot)
83     else
84         if or(size(z)==1) then
85             m=1
86             z=z(:)
87             n=size(z,"*")
88         else
89             [n,m]=size(z)
90         end
91         if or(size(x)==1) then
92             x=x(:)
93             if size(x,"*")<>n then
94                 error(msprintf(_("%s: Wrong size for argument #%d: %d expected.\n"),"comet3d",1,n))
95             end
96             x=x*ones(1,m)
97         else
98             if or(size(x)<>size(z)) then
99                 error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same sizes expected.\n"),"comet3d",1,3))
100             end
101         end
102         if or(size(y)==1) then
103             y=y(:)
104             if size(y,"*")<>n then
105                 error(msprintf(_("%s: Wrong size for argument #%d: %d expected.\n"),"comet3d",2,n))
106             end
107             y=y*ones(1,m)
108         else
109             if or(size(y)<>size(z)) then
110                 error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same sizes expected.\n"),"comet3d",2,3))
111             end
112
113         end
114     end
115
116
117     if type(p)<>1|~isreal(p)|size(p,"*")>1 then
118         error(msprintf(_("%s: Wrong type for argument #%d: Real scalar expected.\n"),"comet3d",3))
119     end
120     if p<0|p>=1 then
121         error(msprintf(_("%s: Wrong value for input argument #%d: Must be in the interval %s.\n"),"comet3d",3,"[0 1["))
122     end
123     fig=gcf();
124     if c==[] then
125         c=1:m
126     else
127         if size(c,"*")<>m then
128             error(msprintf(_("%s: Wrong size for argument #%d: %d expected.\n"),"comet",nv,m))
129         end
130         if min(c)<1|max(c)>size(fig.color_map,1) then
131             error(msprintf(_( "%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"),"comet",nv,"1,...,"+string(size(fig.color_map,1))))
132         end
133     end
134     axes=gca();
135     axes.view="3d"
136
137
138     if axes.children==[] then
139         axes.data_bounds=[min(x) min(y) min(z);max(x) max(y) max(z)];
140         axes.axes_visible="on";
141         axes.box="on";
142     else
143         axes.data_bounds=[min(axes.data_bounds(1,:), [min(x) min(y) min(z)]);
144         max(axes.data_bounds(2,:), [max(x) max(y) max(z)])];
145     end
146     //create the head, body and tail polylines
147     drawlater()
148     for l=1:m
149         xpoly([],[]);tail(l)=gce();
150         tail(l).foreground=c(l);
151
152         xpoly([],[]);body(l)=gce();
153         body(l).foreground=c(l); body(l).thickness=2;
154         xpoly([],[],"marks");head(l)=gce();
155         head(l).mark_size_unit="point";
156         head(l).mark_size=6;
157         head(l).mark_style=9;
158         head(l).mark_foreground=c(l);
159     end
160     show_window();
161
162     function anim()
163         //animation loop
164         k = round(p*n);
165         step=ceil(n/200); //used to speed up the drawing
166
167         for i=1:n
168             for l=1:m
169                 head(l).data=[x(i,l),y(i,l),z(i,l)];
170                 if i<=k then
171                     body(l).data= [body(l).data;[x(i,l),y(i,l),z(i,l)]];
172                 else
173                     body(l).data= [body(l).data(2:$,:);[x(i,l),y(i,l),z(i,l)]];
174                     tail(l).data=[ tail(l).data;[x(i-k,l),y(i-k,l),z(i-k,l)]];
175                 end
176             end
177             if modulo(i,step)==0 then
178                 fig.immediate_drawing = "on"
179                 fig.immediate_drawing = "off"
180             end
181         end
182         drawnow(),drawlater()
183
184         for i=n:n+k
185             for l=1:m
186                 body(l).data= body(l).data(2:$,:);
187                 tail(l).data=[ tail(l).data;[x(i-k,l),y(i-k,l),z(i-k,l)]];
188             end
189             if modulo(i,step)==0 then
190                 fig.immediate_drawing = "on"
191                 fig.immediate_drawing = "off"
192             end
193         end
194         delete(body)
195         drawnow()
196     endfunction
197     //not to generate an error message if the window is closed
198     exec(anim, "errcatch", -1)
199     //exec(anim,-1)
200 endfunction