%% scale_length_4.ldf
%% Created by Laurence D. Finston (LDF) Sat 16 Jul 2022 04:51:35 AM CEST

%% * (1) Copyright and License.

%%%% Copyright (C) 2022 Laurence Finston

%%%% You can redistribute this file and/or modify 
%%%% it under the terms of the GNU General Public License as published by 
%%%% the Free Software Foundation; either version 3 of the License, or 
%%%% (at your option) any later version.  

%%%% This file is distributed in the hope that it will be useful, 
%%%% but WITHOUT ANY WARRANTY; without even the implied warranty of 
%%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
%%%% GNU General Public License for more details.  

%%%% You should have received a copy of the GNU General Public License 
%%%% along with this file; if not, write to the Free Software 
%%%% Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 

%%%% The author can be contacted at: 

%%%% Laurence Finston 
%%%% Laurence.Finston@gmx.de


%% * (1) Top

verbatim_metapost "prologues := 3;\noutputtemplate := \"%j_%3c.eps\";";

input "plainldf.lmc";

pen medium_pen;
medium_pen := pencircle scaled (.5mm, .5mm, .5mm);

pen small_pen;
small_pen := pencircle scaled (.333mm, .333mm, .333mm);

pen dot_pen;
dot_pen := pencircle scaled (2.5mm, 2.5mm, 2.5mm);

pen tiny_pen;
tiny_pen := pencircle scaled (.175mm, .175mm, .175mm);

pickup medium_pen;

numeric wd;
numeric n[];

picture v[];

numeric alpha;
alpha := 2 root 12;

numeric ref_fret;
ref_fret := 24;

%% With float, there are only 23 places to the right
%% of the decimal point.
%% LDF 2022.07.10.
%%
% message "alpha:";
% show alpha fixed 23;

%% * (1)

macro werckmeister_three;

point_vector pv;

def werckmeister_three {numeric sscale_length} =

  begingroup;

    numeric uunit_size;

    uunit_size := sscale_length / (2 * 8.4430);

    boolean do_labels;

    do_labels := false; % true
    
    point p[];
    path  q[];
    
    message "Entering `werkmeister_three'.";

    message "sscale_length = " & decimal sscale_length;
    message "uunit_size    = " & decimal uunit_size;

    numeric a[];

    a0  := 1;
    a1  := 256/243;
    a2  := (64/81);
    a2  *= (sqrt 2);
    a3  := 32/27;
    a4  := 256/243;
    a4  *= 2 root 4;
    a5  := 4/3;
    a6  := 1024/729;

    a7  := 8 root 4; %% 8 == 2 pow 3;
    a7  *= 8/9;

    a8 := 128/81;

    a9 := 1024/729;
    a9 *= 2 root 4;

    a10 := 16/9;

    a11 := 2 root 4;
    a11 *= 128/81;

    a12 := 2;

    p0 := origin;

    if do_labels:
      dotlabel.lft("$p_0$", p0);
    fi

    label.top("Nut", p0) shifted (0, .25cm);
    draw (p0 shifted (-.25cm, 0)) -- (p0 shifted (.25cm, 0));
    label.lft("\setbox0=\hbox{\quad 0}Unison\hbox to \wd0{\hss}", p0) shifted (-.25cm, 0);
    
    
    q0 += --;
    q0 += p0;

    a_inverse0 := 1;

    numeric shift_val;
    shift_val := .25cm;
    
    for i = 1 upto 12:
      message "a" & decimal i & " = " & decimal a[i];
      a_inverse[i] := 1/a[i];
      message "a_inverse" & decimal i & " = " & decimal a_inverse[i];
      p[i] := p[i-1] shifted (0, -uunit_size * a_inverse[i]);
      q0 += p[i];
      if do_labels:
	dotlabel.lft("$p_{" & decimal i & "}$", p[i]);
      fi
    endfor;



    


    p13 := p12 shifted (0, -2cm);
    

    label.bot("Saddle, " & decimal sscale_length & "\Thinspace cm", p13) shifted (0, -.5cm);

    
    label.lft("Minor $2^{\rm{nd}}$\quad 1", 	 p1  shifted (-shift_val, 0));
    label.lft("Major $2^{\rm{nd}}$\quad 2", 	 p2  shifted (-shift_val, 0));
    label.lft("Minor $3^{\rm{rd}}$\quad 3", 	 p3  shifted (-shift_val, 0));
    label.lft("Major $3^{\rm{rd}}$\quad 4", 	 p4  shifted (-shift_val, 0));
    label.lft("$4^{\rm{th}}$\quad 5",       	 p5  shifted (-shift_val, 0));
    label.lft("Diminished $5^{\rm{th}}$\quad 6", p6  shifted (-shift_val, 0));
    label.lft("$5^{\rm{th}}$\quad 7",            p7  shifted (-shift_val, 0));
    label.lft("Minor $6^{\rm{th}}$\quad 8",      p8  shifted (-shift_val, 0));
    label.lft("Major $6^{\rm{th}}$\quad 9",      p9  shifted (-shift_val, 0));
    label.lft("Minor $7^{\rm{th}}$\quad 10",     p10 shifted (-shift_val, 0));
    label.lft("Major $7^{\rm{th}}$\quad 11",     p11 shifted (-shift_val, 0));
    label.lft("Octave\quad 12",                  p12 shifted (-shift_val, 0));


    label.rt("$1/1 = " & decimal a0 & " = " & decimal magnitude(ypart p0) 
	& "\Thinspace\rm{cm}$", p0) shifted (shift_val, 0);
    label.rt("$256/243 = " & decimal a1 & " = " & decimal magnitude(ypart p1) 
	& "\Thinspace\rm{cm}$", p1) shifted (shift_val, 0);
    label.rt("$64/81\sqrt 2 = " & decimal a2 & " = " & decimal magnitude(ypart p2) 
	& "\Thinspace\rm{cm}$", p2) shifted (shift_val, 0);
    label.rt("$32/27 = " & decimal a3 & " = " & decimal magnitude(ypart p3) 
	& "\Thinspace\rm{cm}$", p3) shifted (shift_val, 0);
    label.rt("$256/243\root 4 \of 2 = " & decimal a4 & " = " & decimal magnitude(ypart p4) 
	& "\Thinspace\rm{cm}$", p4) shifted (shift_val, 0);
    label.rt("$4/3 = " & decimal a5 & " = " & decimal magnitude(ypart p5) 
	& "\Thinspace\rm{cm}$", p5) shifted (shift_val, 0);
    label.rt("$1024/729 = " & decimal a6 & " = " & decimal magnitude(ypart p6) 
	& "\Thinspace\rm{cm}$", p6) shifted (shift_val, 0);
    label.rt("$8/9\root 4 \of {2^3} = " & decimal a7 & " = " & decimal magnitude(ypart p7) 
	& "\Thinspace\rm{cm}$", p7) shifted (shift_val, 0);
    label.rt("$128/81 = " & decimal a8 & " = " & decimal magnitude(ypart p8) 
	& "\Thinspace\rm{cm}$", p8) shifted (shift_val, 0);
    label.rt("$1024/729\root 4 \of 2 = " & decimal a9 & " = " & decimal magnitude(ypart p9)
	& "\Thinspace\rm{cm}$", p9) shifted (shift_val, 0);
    label.rt("$16/9 = " & decimal a10 & " = " & decimal magnitude(ypart p10) 
	& "\Thinspace\rm{cm}$", p10) shifted (shift_val, 0);
    label.rt("$128/81\root 4 \of 2 = " & decimal a11 & " = " & decimal magnitude(ypart p11) 
	& "\Thinspace\rm{cm}$", p11) shifted (shift_val, 0);
    label.rt("$2/1 = " & decimal a12 & " = " & decimal magnitude(ypart p12) 
	& "\Thinspace\rm{cm}$", p12) shifted (shift_val, 0);


%% ** (2) Scale (Ruler)

    
    p14 := p0 shifted (9cm, 0);
    p15 := p14 shifted (0, -ceil(scale_length / 2));

    draw p14 -- p15 with_pen small_pen;
    
    for i = 0 upto ceil(sscale_length / 2):
      draw (p14 shifted (-1cm, 0) -- p14) shifted (0, -i) with_pen small_pen;
      label.rt(decimal i & "cm", p14 shifted (0, -i)) shifted (.5shift_val, 0);
    endfor;

    for i = -.5 step -.5 until floor((-sscale_length / 2)):
      draw (p14 shifted (-.5cm, 0) -- p14) shifted (0, i) with_pen small_pen;
    endfor;

    for i = -.1 step -.1 until floor((-sscale_length / 2)):
      draw (p14 shifted (-.25cm, 0) -- p14) shifted (0, i) with_pen small_pen;
    endfor;

%% ** (2) Pure intervals (harmonics)

    p16 := p0 shifted (0, -sscale_length);
    
    p212 := mediate(p0, p16, 1/2); %% Octave
    p207 := mediate(p0, p16, 1/3);  %% Perfect 5th
    p204 := mediate(p0, p16, 1/5);  %% Maj. 3rd
    p205 := mediate(p0, p16, 1/4);  %% 4th
    p202 := mediate(p0, p16, 1/9);  %% 2nd
    p209 := mediate(p0, p16, 2/5);  %% 6th
    p211 := mediate(p0, p16, 7/15); %% Maj. 7th

    numeric u;

    %% 5th

    u := ((magnitude(magnitude(ypart p207) - magnitude(ypart p7))) * 100) / (magnitude(ypart p207));
    
    drawdot p207 with_color green with_pen dot_pen;
    label.lrt("$ 5^{\rm{th}}$\hskip-.25ex, $3/2$, $"
    	& decimal -ypart p207 & "\Thinspace\rm{cm}$, $"
	& "\Delta " & decimal magnitude(ypart p207 - ypart p7)	& "\Thinspace\rm{cm}"
	& "="
	& "\Delta" &  decimal u & "\%"
	& "$", p207) shifted (.25cm, -6pt)
      with_color dark_green;

    draw p207 shifted (-1.25mm, 0) -- p207 shifted (1.25mm, 0) with_pen tiny_pen with_color magenta;


    %% Maj. 3rd

    u := ((magnitude(magnitude(ypart p204) - magnitude(ypart p4))) * 100) / (magnitude(ypart p204));
    
    drawdot p204 with_color green with_pen dot_pen;
    label.urt("$ 3^{\rm{rd}}$\hskip-.25ex, $5/4$, $"
    	& decimal -ypart p204 & "\Thinspace\rm{cm}$, "
	& "$\Delta " & decimal magnitude(ypart p204 - ypart p4)
	& "\Thinspace\rm{cm} =\Thinspace \Delta" &  decimal u & "\%$"
	, p204) shifted (.25cm, 0pt)
      with_color dark_green;

    draw p204 shifted (-1.25mm, 0) -- p204 shifted (1.25mm, 0) with_pen tiny_pen with_color magenta;

    %% 4th

    u := ((magnitude(magnitude(ypart p205) - magnitude(ypart p5))) * 100) / (magnitude(ypart p205));
    
    drawdot p205 with_color green with_pen dot_pen;
    label.lrt("$ 4^{\rm{th}}$\hskip-.25ex, $3/2$, $"
    	& decimal -ypart p205 & "\Thinspace\rm{cm}$, $"
	& "\Delta " & decimal magnitude(ypart p205 - ypart p5)	& "\Thinspace\rm{cm}"
	& "="
	& "\Delta" &  decimal u & "\%"
	& "$", p205) shifted (.25cm, -6pt)
      with_color dark_green;

    draw p205 shifted (-1.25mm, 0) -- p205 shifted (1.25mm, 0) with_pen tiny_pen with_color magenta;

    %% 2nd

    u := ((magnitude(magnitude(ypart p202) - magnitude(ypart p2))) * 100) / (magnitude(ypart p202));
    
    drawdot p202 with_color green with_pen dot_pen;
    label.lrt("$ 2^{\rm{nd}}$\hskip-.25ex, $9/8$, $"
    	& decimal -ypart p202 & "\Thinspace\rm{cm}$, $"
	& "\Delta " & decimal magnitude(ypart p202 - ypart p2)	& "\Thinspace\rm{cm}"
	& "="
	& "\Delta" &  decimal u & "\%"
	& "$", p202) shifted (.25cm, -6pt)
      with_color dark_green;

    draw p202 shifted (-1.25mm, 0) -- p202 shifted (1.25mm, 0) with_pen tiny_pen with_color magenta;

    %% 6th

    u := ((magnitude(magnitude(ypart p209) - magnitude(ypart p9))) * 100) / (magnitude(ypart p209));
    
    drawdot p209 with_color green with_pen dot_pen;
    label.urt("$6^{\rm{th}}$\hskip-.25ex, $5/3$, $"
    	& decimal -ypart p209 & "\Thinspace\rm{cm}$, $"
	& "\Delta " & decimal magnitude(ypart p209 - ypart p9)	& "\Thinspace\rm{cm}"
	& "="
	& "\Delta" &  decimal u & "\%"
	& "$", p209) shifted (.25cm, 0pt)
      with_color dark_green;

    draw p209 shifted (-1.25mm, 0) -- p209 shifted (1.25mm, 0) with_pen tiny_pen with_color magenta;


    %% Maj. 7th

    u := ((magnitude(magnitude(ypart p211) - magnitude(ypart p11))) * 100) / (magnitude(ypart p211));
    
    drawdot p211 with_color green with_pen dot_pen;
    label.urt("Maj.~$7^{\rm{th}}$\hskip-.25ex, $5/3$, $"
    	& decimal -ypart p211 & "\Thinspace\rm{cm}$, $"
	& "\Delta " & decimal magnitude(ypart p211 - ypart p11)	& "\Thinspace\rm{cm}"
	& "="
	& "\Delta" &  decimal u & "\%"
	& "$", p211) shifted (.25cm, 1pt)
      with_color dark_green;

    draw p211 shifted (-1.25mm, 0) -- p211 shifted (1.25mm, 0) with_pen tiny_pen with_color magenta;


%% Octave    
    
    drawdot p212 with_color green with_pen dot_pen;
    label.lrt("Octave", p212) shifted (.25cm, -6pt) with_color dark_green;
 

%% ** (2)     
    
    draw q0;
    drawarrow p12 -- p13;

    for i = 1 upto 12:
      if not do_labels:
	draw (p[i] shifted (-.25cm, 0)) -- (p[i] shifted (.25cm, 0))
	  with_pen small_pen;
      fi
    endfor;

%% ** (2)    

    message "Exiting `werkmeister_three'.";

  endgroup;
  
enddef;


%% * (1) Fig. 0.  Dummy figure.

beginfig(0);
  drawdot origin;
endfig with_projection parallel_x_y;

%% * (1)


point p[];

beginfig(1); 
  numeric scale_length;

  scale_length := 45cm;
  
  werckmeister_three {scale_length};

  
endfig with_projection parallel_x_y;



end_mp;
end;

  
%% ** (2) End of 3DLDF code.

%% * (1) Emacs-Lisp code for use in indirect buffers when using the          
%%       GNU Emacs editor.  The local variable list is not evaluated when an 
%%       indirect buffer is visited, %% %% so it's necessary to evaluate the       
%%       following s-expression in order to use the facilities normally      
%%       accessed via the local variables list.                              
%%       \initials{LDF 2004.02.12}.                                          


%% (progn (metapost-mode) (outline-minor-mode t) (setq fill-column 80))    

%% * (1) Local variables for Emacs.

%% Local Variables:
%% mode:MetaPost
%% eval:(outline-minor-mode t)
%% eval:(read-abbrev-file abbrev-file-name)
%% outline-regexp:"%% [*\f]+"
%% End:
