File:TonnetzTorus.gif

Page contents not supported in other languages.
This is a file from the Wikimedia Commons
From Wikipedia, the free encyclopedia

Original file(900 × 490 pixels, file size: 3.21 MB, MIME type: image/gif, looped, 23 frames, 2.8 s)

Summary

Description Illustration of a en:Tonnetz torus
Date
Source Own work
Author Davidwbulger

Licensing

Public domain I, the copyright holder of this work, release this work into the public domain. This applies worldwide.
In some countries this may not be legally possible; if so:
I grant anyone the right to use this work for any purpose, without any conditions, unless such conditions are required by law.
MATLAB source code

Thanks to Oleg Alexandrov, whose code at File:Plane_wave.gif I imitated.

% The idea here is to produce an animation of a "Tonnetz" torus (see
% http://en.wikipedia.org/wiki/Neo-Riemannian_theory), possibly for upload
% to Wikimedia.

% FIRSTLY CREATE THE TEXTURE.
% Regrettably, no screen to which I have access is anywhere near large
% enough to contain the whole texture (at sufficient resolution to look
% good after texture-mapping the torus' surface). I'm not certain it's
% impossible to draw the whole figure to a larger-than-screen invisible
% buffer & getframe from there, but I don't know how to do it. Instead I'll
% build the texture out of sections of the plot, using xlim & ylim to
% scroll in between. Gawd help me.

% First determine texture's pixel dimensions:
TextureWidth=2702;  %  A spike in this plot: n=1:5000; h=abs(round(n/sqrt(27))./n-1/sqrt(27)); plot(n, 1./h);
TextureHeight=round(TextureWidth/sqrt(27));

ScreenSize = get(0, 'ScreenSize');
PatternRect = [9*sqrt(3)/2, 1/2, 12*sqrt(3), 4];  %  left, bottom, width, height
notes = {'C', 'C$\sharp$', 'D', 'D$\sharp$', 'E', 'F', 'F$\sharp$', 'G', 'G$\sharp$', 'A', 'A$\sharp$', 'B'};
gap = .3;
xoffset = [0,0,0;sqrt(3)/2,0,-sqrt(3)/2];
yoffset = [0,0,0;.5,1,.5];
xoffset=(1-gap)*xoffset+gap*flipud(xoffset);
yoffset=(1-gap)*yoffset+gap*flipud(yoffset);
FontPts = round(TextureWidth/92);

close all
figure(1);
set(1, 'Position', [64, 64, ScreenSize(3:4)-128], 'Color', 'w');
FigureRect = get(1, 'Position');  %  should be the same but who knows
TilesAcross = ceil(TextureWidth/FigureRect(3));
TilesDown = ceil(TextureHeight/FigureRect(4));

hold on
%rectangle('Position', PatternRect, 'EdgeColor', 'none', 'FaceColor', [.2,.2,.2]);%[1,.5,0]);%[.65, .6, .55]);
for j=0:9,
    for k=0:16,
        x = sqrt(3)*(k+j/2);
        y = j/2;
        text(x, y, notes(1+mod(7*j-k, 12)), 'Interpreter', 'latex', 'HorizontalAlignment', 'center', 'fontsize', FontPts);
        plot(x+xoffset, y+yoffset, 'LineWidth', TextureWidth/600);
    end
end
axis equal
axis off
set(gca, 'Position', [0, 0, 1, 1]);

texture = zeros(FigureRect(4)*TilesDown, FigureRect(3)*TilesAcross, 3);
for j=1:TilesDown,
    for k=1:TilesAcross,
        xlim(PatternRect(1)+[k-1,k]*FigureRect(3)/TextureWidth*PatternRect(3));
        ylim(PatternRect(2)+[j-1,j]*FigureRect(4)/TextureHeight*PatternRect(4));
        [tile, map] = frame2im(getframe(gcf));
        texture(1+(TilesDown-j)*FigureRect(4):(TilesDown-j+1)*FigureRect(4), 1+(k-1)*FigureRect(3):k*FigureRect(3), :) = tile;
    end
end
texture = texture(1+end-TextureHeight:end, 1:TextureWidth, :);
background = 220+floor(35*rand(size(texture)));  %  mottle the surface a little
isblank = repmat(min(texture, [], 3)==255, [1,1,3]);
texture = isblank.*background + (1-isblank).*texture;
close(1);

% NOW CREATE THE TORUS:
sx = size(texture, 2)-1;
sy = size(texture, 1)-1;
close all
figure(1);
set(1, 'Position', [1, 31, 1366, 662]);
[phi, theta] = meshgrid(2*pi*(0:sx)/sx, 2*pi*(0:sy)/sy);
h=surf(cos(phi).*(100-20*sin(theta)), sin(phi).*(100-20*sin(theta)), -20*cos(theta), texture);
set(h, 'CDataMapping', 'direct', 'EdgeColor' ,'none', 'FaceColor', 'interp', 'AmbientStrength', 0.003, 'DiffuseStrength', 0.003, 'SpecularStrength', 0.9, 'SpecularExponent', 25);
light('Position', [2000, -2000, 1000], 'Color', [1, 1, .7]);
light('Position', [-2000, 2000, 1000], 'Color', [.7, .7, 1]);
set(gca, 'AmbientLightColor', [1, .9, .9]);
axis equal
axis off
campos([-870, -1266, 749]);
lighting gouraud

% NOW SPIN IT, SAVING THE FRAMES:
NumFrames = 23;
delete('MovieFrames/Frame*.eps');
delete('MovieFrames/Frame*.bmp');
for t=1:NumFrames;
    twist = t*pi/4/NumFrames;
    set(h, 'XData', cos(phi+twist).*(100-20*sin(theta+3*twist)));
    set(h, 'YData', sin(phi+twist).*(100-20*sin(theta+3*twist)));
    set(h, 'ZData', -20*cos(theta+3*twist));
    drawnow;
    fprintf('Writing frame number %d to disk.\n', t);
    FileName = sprintf('MovieFrames/Frame%03d.bmp', t);
    print(gcf, '-dbmp', FileName, '-r200')
    system(sprintf('convert %s -crop 900x490+378+333 %s', FileName, FileName));  %   This relies on having installed "ImageMagick," but it's free
end

% NOW MAKE THE GIF (ImageMagick needed again)
fprintf('Compiling frames into a gif ...');
system('convert -antialias -loop 0 -delay 12 -compress LZW MovieFrames/Frame* TonnetzTorus.gif');
fprintf(' complete.\n');
 
This diagram was created with MATLAB.

Captions

Add a one-line explanation of what this file represents

Items portrayed in this file

depicts

15 September 2010

image/gif

File history

Click on a date/time to view the file as it appeared at that time.

Date/TimeThumbnailDimensionsUserComment
current05:24, 15 September 2010Thumbnail for version as of 05:24, 15 September 2010900 × 490 (3.21 MB)Davidwbulger{{Information |Description=Illustration of a Tonnetz torus |Source={{own}} |Date=15 September 2010 |Author= Davidwbulger |Permission= |other_versions= }}
The following pages on the English Wikipedia use this file (pages on other projects are not listed):

Global file usage

The following other wikis use this file: