function modfun(m,n,detail,gif) % modfun(m,n,detail) connects n points, z(j), equally spaced % around the complex unit circle, by n+1 straight lines. % The j-th line connects z(j+1) to z(mod(j*m,n)+1). % % detail = 0 displays the final result. % detail = 1 displays each line. % detail = 2 pauses briefly after displaying each line. % Copyright 2022 Cleve Moler if nargin < 2 m = 102; n = 300; end if nargin < 3 detail = 0; end if nargin < 4 gif = []; end init_fig(detail,gif) z = exp(2i*pi*(0:n)/n); for j = 0:n zj = [z(j+1) z(mod(j*m,n)+1)]; line(real(zj),imag(zj)) paws(detail) if ~isempty(gif) && mod(j,5) == 0 gif_frame end end if ~isempty(gif) gif_frame(3) gif_frame('wrap') end % ------------------------------------------- function init_fig(detail,gif) clf shg axis([-1 1 -1 1]) axis square axis off if isempty(gif) pbutton(1,'-','m') ebutton(2,int2str(m),'m') pbutton(3,'+','m') wbutton(4,detail) pbutton(6,'-','n') ebutton(7,int2str(n),'n') pbutton(8,'+','n') else gif_frame(gif) end end function ebutton(p,s,t) uicontrol(Style = "edit", ... Units = 'normalized', ... Position = [p/10+(p>5)/20,0.03,0.08,0.05], ... String = s, ... Tag = t, ... FontSize = 12, ... FontWeight = 'Bold', ... Callback = @cb) end function pbutton(p,s,u) uicontrol(Style = "pushbutton", ... Units = 'normalized', ... Position = [p/10+(p>5)/20,0.03,0.08,0.05], ... String = s, ... UserData = u, ... FontSize = 12, ... FontWeight = 'Bold', ... Callback = @cb) end function wbutton(~,s) uicontrol(Style = "pushbutton", ... Units = 'normalized', ... Position = [0.475,0.03,0.08,0.05], ... String = s, ... FontSize = 12, ... FontWeight = 'Bold', ... Callback = @paws) end function cb(arg,~) mo = findobj('tag','m'); m = str2double(mo.String); no = findobj('tag','n'); n = str2double(no.String); as = arg.String; au = arg.UserData; minus = (length(as) == 1) && (as == '-'); plus = (length(as) == 1) && (as == '+'); if minus && au == 'm' m = m-1; elseif minus && au == 'n' n = n-1; elseif plus && au == 'm' m = m+1; elseif plus && au == 'n' n = n+1; end mo.String = num2str(m); no.String = num2str(n); detail = get(findobj('callback',@paws),'string'); modfun(m,n,detail) end function paws(arg,~) if nargin == 1 switch arg case '0' case '1', drawnow case '2', pause(0.05) end else switch arg.String case '0', arg.String = '1'; case '1', arg.String = '2'; case '2', arg.String = '0'; end end end end