// fasor.sq // Juan Claudio Regidor, 25/2/2004 title "Fasor" help {@ Display a rotating fasor. @} variable phi // phase variable w1 // horizontal frequency variable w2 // vertical frequency variable t // time variable theta // time vector variable hor // horizontal channel amplitude vector variable vert // vertical channel amplitude vector variable x // horizontal channel amplitude value in time t variable y // vertical channel amplitude value in time t variable sc // scale variable an // animation flag variable fh // flag for horizontal function variable fv // flag for vertical function init (phi, w1, w2, t, theta, sc, an, fh, fv) = init // initialization idle (t, _idleamount) = idleAnimate(w1, w2, t, an) // idle handler make (hor, vert) = xy(theta, w1, w2, phi, fh, fv) // calculate horizontal and vertical vectors make (x, y) = xy(t, w1, w2, phi, fh, fv) // calculate horizontal and vertical values figure "Fasor" // Lissajous figure, 'osciloscope' draw sc = drawFasor(hor, vert, x, y, t, phi) figure "Par‡metros" // sliders to set the phase, frequencies and draw drawParameters(phi, an) // checkmark button for animation flag mousedrag (phi, an) = dragParameters(phi, an, _id, _nb, _x1) // _nb is the slider number, or [] if // the click is not on a slider // _x1 is the current value figure "Parte Imaginaria" // vertical channel figure draw drawVertsin(vert, theta, y, t) mousedrag (t, _msg) = drag(t, 1, _x, _x1) mouseover _msg = overT(_id, t) figure "Parte Real" // horizontal channel figure draw drawHorsin(hor, theta, x, t, sc) mousedrag (t, _msg) = drag(t, -1, _y, _y1) mouseover _msg = overT(_id, t) functions {@ function (phi, w1, w2, t, theta, sc, an, fh, fv) = init // initialization phi = pi/6; // phase for vertical function w1 = 1; // unit frequencies on both channels w2 = 1; t = 0; // time theta = 2 * pi * (0:360) / 360; // time vector sc = [0, 0, -1, 1]; an = 0; // don not animate fh = 1; // cos on hor. channel fv = 2; // sin on vert. channel subplots('Fasor\tParte Imaginaria\nParte Real\tPar‡metros'); function sc = drawFasor(hor, vert, x, y, t, phi) // Fasor line([1, 0], 0., 'h(d0d0d0)'); // draw x and y axis, light gray line([0, 1], 0., 'h(d0d0d0)'); scale('equal', [-1,1;-1,1]); plot(hor, vert, 'h(d0d0d0)'); // plot figure plot(x, y, 'xb'); // plot blue 'x' on intersection of plot([0, x], [0, y], 'g'); plot([0, x], [0, 0], 'g'); plot(x, 0, 'og'); plot([0, 0], [0, y], 'g'); plot(0, y, 'og'); tt = (t + phi <= pi)? t+phi : -2*pi+t+phi; u = min(0, tt); v = max(0, tt); plot(0.25*cos(u:0.05:v), 0.25*sin(u:0.05:v), 'r'); line([1, 0], x, 'r-'); // horizontal and line([0, 1], y, 'r-'); // vertical values sc = scale; function drawVertsin(vert, theta, y, t) // vertical channel figure line([1, 0], 0., 'h(d0d0d0)'); // draw x and y axis, light gray line([0, 1], 0., 'h(d0d0d0)'); scale([0, 2*pi, -1, 1]); plot(theta, vert, 'h(00c000)'); // plot figure plot(t, y, 'or', 1); // plot red 'o' on intersection of line([1, 0], t, 'c', 1); // time and line([0, 1], y, 'r-'); // vertical values function drawHorsin(hor, theta, x, t, sc) // horizontal channel figure line([1, 0], 0., 'h(d0d0d0)'); // draw x and y axis, light gray line([0, 1], 0., 'h(d0d0d0)'); scale([sc(1)+0.055, sc(2)-0.055]); plot(hor, -theta, 'h(00c000)'); // plot figure (reversed vertical time axis) plot(x, -t, 'or', 1); // plot red 'o' on intersection of line([0, 1], -t, 'c', 1); // time and line([1, 0], x, 'r-'); // horizontal values function (x, y) = xy(t, w1, w2, phi, fh, fv) // calculate horizontal and vertical values if (fh == 2) x = sin(w1 * t + phi); else x = cos(w1 * t + phi); end if (fv == 2) y = sin(w2 * t + phi); else y = cos(w2 * t + phi); end function drawParameters(phi, an) settabs('Fase = -120 ¼ '); slider(sprintf('Fase = %d ¼', round(180*phi/pi)), [phi], [-pi, pi], '-', '', 1); button(' \tAnimar tiempo', [an], 'checkmark', '', 4); function (phi, an) = dragParameters(phi, an, id, nb, x1) if isempty(id) cancel; elseif (id == 1) switch nb case 1 phi = round(90*x1/pi)*pi/90; end elseif (id == 4) an = x1; end function (t, idleamount) = idleAnimate(w1, w2, t, an) idleamount = 0.9; if (an == 1) a = clock; if (w1 > 4) || (w2 > 4) // k reduces the sweep time as a function of k = 8; // hor. and vert. frequencies elseif (w1 > 8) || (w2 > 8) k = 4; else k = 2; end // t = mod((60*a(5)+a(6))/k,2*pi); // real time is 60*minutes + seconds t = mod(t+0.16/k, 2*pi); msg = sprintf('t = %.2f', t); end function (t, msg) = drag(t, s, y, y1) if isempty(y) cancel; end t = s*round(180*y1/pi)*pi/180; if (t < 0) t = 0; end if (t > 2*pi) t = 2*pi; end msg = sprintf('t = %.2f', t); function msg = overT(id, t) if ~same(id, 1) cancel; end msg = sprintf('t = %.2f', t); @}