// Last edited on 2019-05-08 06:15:12 by stolfilocal #macro fplot_movie_frame(kind,ck) // Parameters of the function {F} #local tper = 120; // Period of function. #local torg = 1.2*tper; // Function argument for start of one period. // Parameters of function domain and range to plot: #local ncyc = 4; // Total cycles in plot area. #local tmin = 0.0; // Min argument {t} value in plot area. #local tmax = ncyc*tper; // Max argument {t} value in plot area. #local fmax = 1.0; // Max abs value of {F} to assume for plot scaling. #local fmin = -fmax; // Min abs value of {F} to assume for plot scaling. #local flab = sphere{ <0,0,0>, 10 matte_tx(<1,0.5,0>) } // Label for function value axis. #local pmin = 0.0; // Min phase value to assume for plot scaling. #local pmax = 2*pi; // Max phase value to assume for plot scaling. #local plab = sphere{ <0,0,0>, 10 matte_tx(<1,0.5,0>) } // Label for phase value axis. // Parameters of the whole plot #local ytot = 1600; // Width of plot with axes, axis labels, etc.. #local ztot_f = 700; // Height of function plot with axes, axis labels, etc.. #local ztot_p = 500; // Height of phase plot with axes, axis labels, etc.. // Parameters of the movie: #local ncmv = 2; // Whole cycles in movie. #local tini = torg - 0.1*tper; // Argument {t} at start of movie. #local tfin = torg + (ncmv + 0.1)*tper; // Argument {t} at end of movie. #local pini = 2*pi*(tini - torg)/tper; // Phase at start of movie (radians, unreduced). #local pfin = 2*pi*(tfin - torg)/tper; // Phase at end of movie (radians, unreduced). // Plot parameters for this frame: #local tcur = (1-ck)*tini + ck*tfin; // Argument. #local f_graph = object{ fplot_graph(ytot,ztot_f, tmin,tmax, fmin,fmax, torg,tper,tcur, kind, 0, flab) } #local p_graph = object{ fplot_graph(ytot,ztot_p, tmin,tmax, pmin,pmax, torg,tper,tcur, kind, 1, plab) } // #local p_spinner = object{ fplot_phase_spinner(kind,ncyc,ck) } // Testing labels // #local lb1 = mklab_make("foo") #local frame = union{ // sphere{ < 0, ytot/2, ztot_f/2 >, ytot/5 matte_tx( <1.0,0.7,0.2> ) } #local pht = max_extent(p_graph).z - min_extent(p_graph).z; object{ f_graph translate pht*z } object{ p_graph } // object{ p_spinner translate 0.5*pht*z } } #declare fplot_movie_frame_ctr = < 0, ytot/2, (max_extent(frame).z + min_extent(frame).z)/2 >; #declare fplot_movie_frame_rad = vlength(max_extent(frame) - min_extent(frame))/2; frame #end #macro fplot_graph(ytot,ztot, tmin,tmax, fmin,fmax, torg,tper,tcur, kind,what,vlab) // Parameters of the whole plot #local tminp = tmin; // Min {t} value on horizontal axis. #local tmaxp = tmax; // Max {t} value on horizontal axis. #local ftad = 0.1*(fmax-fmin); // Extra space to leave above and below graph. #local fminp = fmin-ftad; // Min {f} value on vertical axis. #local fmaxp = fmax+ftad; // Max {f} value on vertical axis. #local ymrg = 100; // Left/Rite margin between edge and plot area. #local ymin = ymrg; // Min Y coordinate of plot area (for {t = tminp}). #local ymax = ytot-ymrg; // Max Y coordinate of plot area (for {t = tmaxp}). #local zmrg = 100; // Top/Bot margin between edge and plot area. #local zmin = zmrg; // Min Z coordinate of plot area (for {f = fminp}). #local zmax = ztot-zmrg; // Max Z coordinate of plot area (for {f = fmaxp}). #local nsteps = 2000; #local raxes = 0.0015*ytot; // Radius of axis lines. #local caxes = < 0.000, 0.000, 0.000 >; // Color of axes. #local rdots = 0.002*ytot; // Radius of plot dots. #local cdots_o = < 0.000, 0.000, 0.800 >; // Color of plot dots outside ref cycle. #local cdots_r = < 0.300, 0.800, 0.500 >; // Color of plot dots in ref cycle. #local rvbar = raxes; // Radius of vertical bar. #local cvbar = < 1.000, 0.000, 0.800 >; // Color of vertical var. #local rampl = 0.75*raxes; // Radius of amplitude lines. #local campl = < 1.000, 0.750, 0.500 >; // Color of amplitude lines. #local rdoth = 1.2*rdots; // Radius of highlighted dot. union{ box{ < 0,0,0 >, < -2,ytot,ztot> matte_tx( < 1.000, 1.000, 1.000 > ) } // Argument {t} axis: #local po = fplot_graph_scale(tminp, 0.0, tminp,tmaxp, ymin,ymax, fminp,fmaxp, zmin,zmax); // Plot origin. object{ axis_arrow( po, <0, ymax + 0.5*ymrg, po.z >, raxes, 15, caxes, "t") } // Lines at {fmin,fmax}: #local plo = fplot_graph_scale(tminp, fmin, tminp,tmaxp, ymin,ymax, fminp,fmaxp, zmin,zmax); // Pt {fmin} on vert axis. object{ axis_line( plo, <0, ymax, plo.z >, rampl, campl, "fmin") } #local phi = fplot_graph_scale(tminp, fmax, tminp,tmaxp, ymin,ymax, fminp,fmaxp, zmin,zmax); // Pt {fnax} on vert axis. object{ axis_line( phi, <0, ymax, phi.z >, rampl, campl, "fmax") } // Function value {f} axis: object{ axis_arrow( < 0, po.y, zmin >, <0, po.y, zmax + 0.5*zmrg > , raxes, 15, caxes, "f") } #local qq = <0,0,0>; // Previous point, if any. #for (ii,0,nsteps-1) #local rr = (ii + 0.5)/nsteps; // Relative position of dot in {tminp _ tmaxp}. #local tt = (1-rr)*tminp + rr*tmaxp; // Corresponding argument {t}. // Decide dot color: #if ((tt < torg) | (tt > torg+tper)) #local cdots = cdots_o; #else #local cdots = cdots_r; #end // Compute plot coordinates: #local pp = fplot_graph_point(tt, tminp,tmaxp, ymin,ymax, fminp,fmaxp, zmin,zmax, torg,tper, kind,what); sphere{ pp, rdots matte_tx( cdots ) } #if (ii > 0) #if (vlength(pp-qq) > 0.05*(zmax-zmin)) // Seems to be a jump: cylinder{ qq, pp, 0.33*rdots matte_tx(caxes) } #else // Seems to be a smooth change: cylinder{ qq, pp, rdots matte_tx(cdots) } #end #end #local qq = pp; #end // Vertical line at current agument {tcur}: #local tt = tcur; #local pp = fplot_graph_point(tt, tminp,tmaxp, ymin,ymax, fminp,fmaxp, zmin,zmax, torg,tper, kind,what); sphere{ pp, 1.5*rdoth matte_tx( cvbar ) } cylinder{ < 0, pp.y, 0 >, < 0, pp.y, ztot >, rvbar matte_tx( cvbar ) } } #end #macro fplot_graph_point(tt, tminp,tmaxp, ymin,ymax, fminp,fmaxp, zmin,zmax, torg,tper, kind,what) // Return graph point { < 0, yy, zz >} for arg value {tt}. #local ff = fplot_func(kind,what, (tt-torg)/tper); #local pp = fplot_graph_scale(tt, ff, tminp,tmaxp, ymin,ymax, fminp,fmaxp, zmin,zmax); pp #end #macro fplot_graph_scale(tt, ff, tminp,tmaxp, ymin,ymax, fminp,fmaxp, zmin,zmax) // Return graph point { < 0, yy, zz >} for plot coord pair {tt,ff}. #local rr = (tt - tminp)/(tmaxp - tminp); #local ss = (ff - fminp)/(fmaxp - fminp); #local yy = (1-rr)*ymin + rr*ymax; #local zz = (1-ss)*zmin + ss*zmax; < 0, yy, zz > #end #macro fplot_func(kind,what,tfrac) #if (what = 0) // Function value: #local vv = sin(2*pi*tfrac); #else // Phase: #local vv = 2*pi*((tfrac+1000)-int(tfrac+1000)); #end vv #end