function trio(d) % trio http://www.clevertoys.cz/index_eng.php?page=eng % trio(0) initialize. % trio(d) d = 1, 2, 3, rotate d-th outer disc one-tenth of a full revoltion. % trio(4) rotatate inner disc one-third of a full revoltion. % Change sign, right-click or command-click for reverse direction. % '28-Sep-2022 7:11pm' % Copyright 2022 Cleve Moler if nargin == 0 || d == 0 [C,P,PO,PI,B] = trio_init; set(gcf,'userdata',{C,P,PO,PI,B}); return else gcfud = get(gcf,'userdata'); [C,P,PO,PI,B] = deal(gcfud{:}); end z0 = exp(pi*2i*(-31.5:32.5)/64); FC = [1.00 .80 .25 .90 .88 .81 1.00 .60 .00]; r1 = .43; r2 = .75; rm = (r2+r1)/2; r3 = 0.9*(r2-r1)/2; if abs(d) == 4 delta = 1/6; else delta = 1/3; end for f = 0:delta:1 for k = 1:3 zk = exp(pi*2i*(k-2)/3); z1 = r1*zk*z0; z2 = r2*zk*z0; ps = polyshape(real([z1 z2]+zk),imag([z1 z2]+zk)); z2 = z2(abs(z2+zk) > 1); z1 = flip(z1(abs(z1+zk) > 1)); zo = [z1 z2]+zk; pso = polyshape(real(zo),imag(zo)); psi = subtract(ps,pso); if abs(d) == 4 psi = rotate(psi,sign(d)*f*120); end PI(k).Shape = psi; w = exp(pi*2i*(-4.5:4.5)/10)*zk; if k == abs(d) w = w*exp(sign(d)*f*pi*2i/10); end for j = 1:10 wj = rm*w(j) + r3*z0; ps = polyshape(real(wj+zk),imag(wj+zk)); if abs(d) == 4 && (j <= 2 || j >= 9) ps = rotate(ps,sign(d)*f*120); end B(j,k).Shape = ps; B(j,k).FaceColor = FC(C(j,k),:); B(j,k).FaceAlpha = 1; end end %gif_frame drawnow end k = [1 2 9 10]; if d == 4 C(k,:) = C(k,[3 1 2]); elseif d == -4 C(k,:) = C(k,[2 3 1]); elseif 1 <= d && d <= 3 C(:,d) = C([10 1:9],d); elseif -3 <= d && d <= -1 C(:,-d) = C([2:10 1],-d); end set(gcf,'userdata',{C,P,PO,PI,B}); % ------------------------------------------------------------- function [C,P,PO,PI,B] = trio_init % % http://www.clevertoys.cz/index_eng.php?page=eng % z0 = exp(pi*2i*(-31.5:32.5)/64); FC = [1.00 .80 .25 .90 .88 .81 1.00 .60 .00]; maple = [.90 .72 .50]; initialize_fig warning off hold on C = [ones(10,1) 2*ones(10,1) 3*ones(10,1)]; cla for k = 1:4 zk = (k < 4)*exp(pi*2i*(k-2)/3); ps = polyshape(real(z0+zk),imag(z0+zk)); plot(ps,'linewidth',2, ... 'facealpha',1, ... 'facecolor', maple); end r1 = .43; r2 = .75; rm = (r2+r1)/2; r3 = 0.9*(r2-r1)/2; ps = polyshape(real(z0),imag(z0)); P = plot(ps,'linewidth',3, ... 'facealpha',1, ... 'facecolor', maple); for k = 1:3 zk = exp(pi*2i*(k-2)/3); z1 = r1*zk*z0; z2 = r2*zk*z0; ps = polyshape(real([z1 z2]+zk),imag([z1 z2]+zk)); z2 = z2(abs(z2+zk) > 1); z1 = flip(z1(abs(z1+zk) > 1)); zo = [z1 z2]+zk; pso = polyshape(real(zo),imag(zo)); PO(k) = plot(pso,'linewidth',3, ... 'facealpha',1, ... 'facecolor','k'); psi = subtract(ps,pso); PI(k) = plot(psi,'linewidth',3, ... 'facealpha',1, ... 'facecolor','k'); w = exp(pi*2i*(-4.5:4.5)/10)*zk; for j = 1:10 wj = rm*w(j) + r3*z0; ps = polyshape(real(wj+zk),imag(wj+zk)); B(j,k) = plot(ps, ... 'facealpha',1, ... 'facecolor',FC(C(j,k),:)); end drawnow end set(gcf,'userdata',{C,P,PO,PI,B}); % ------------------------------------------------------------- function initialize_fig set(gcf, ... 'name','Trio', ... 'menu','none', ... 'numbertitle','off', ... 'menubar','none', ... 'numbertitle','off', ... 'windowbuttondownfcn',@wbdown) axis(2.25*[-1 1 -1 1]) axis square set(gca,'xtick',[],'ytick',[]) box on shg end % initialize fig function wbdown(~,~) % WindowsButtonDownFunction cp = get(gca,'currentpoint'); z = complex(cp(1,1),cp(1,2)); % Counter-clockwise or clockwise. s = 1 - 2*isequal(get(gcf,'selectiontype'),'alt'); if abs(z) < 1 trio(4*s) elseif abs(z - 1) < 1 trio(2*s) elseif abs(z - exp(pi*2i/3)) < 1 trio(3*s) elseif abs(z - exp(-pi*2i/3)) < 1 trio(s) else trio(0) end end end end