%% scale_length_3.ldf
%% Created by Laurence D. Finston (LDF) Thu 14 Jul 2022 04:33:00 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";

pickup pencircle scaled (.333mm, .333mm, .333mm);

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)

def layout {point ttop,
            path Q,
            point_vector PV,
            numeric llength,
            numeric ffret_ctr,
            numeric ffret_thickness,
            numeric sstart,
            numeric eend,
            numeric oovershoot_top,
            numeric oovershoot_bot
            } = 

    begingroup;

    message "Entering layout.";

    % message "point ttop:";
    % show ttop;
    % message "llength           == " & decimal llength; 
    % message "ffret_ctr         == " & decimal ffret_ctr; 
    % message "ffret_thickness   == " & decimal ffret_thickness; 
    % message "sstart           == " & decimal sstart;

    %message "oovershoot_top   == " & decimal oovershoot_top;
    %message "oovershoot_bot   == " & decimal oovershoot_bot;
    %pause;

    point p[];
    numeric n[];

    clear pv;

    % message "sstart == " & decimal sstart;
    % message "eend == " & decimal eend;
    % pause;
    
    if eend == 0:
      eend := 1000;
    fi

    % message "sstart == " & decimal sstart;
    % message "eend == " & decimal eend;
    % pause;

    
    p1000   := ttop;
    p0 := ttop shifted (0, -llength);

    
    numeric a;
    a := 1.0/alpha;
    
    n1 := llength*a;
    p1 := p1000 shifted (0, -n1);

    
    numeric k;

    if ffret_ctr > ref_fret:
      k := ffret_ctr;
    else:
      k := ref_fret;
    fi

    for i = 2 upto k:
      n[i] := n[i-1] * a;
      %message "n" & decimal i;
      p[i] := p1000 shifted (0, -n[i]);
    endfor;

    % message "mags:";
    % show magnitude(p12 - p0);
    % show magnitude(p1000 - p12);    
    % pause;
    
    % n2 := n1*a;
    % p2 := p1000 shifted (0, -n2);

    % n3 := n2*a;
    % p3 := p1000 shifted (0, -n3);
    
    % for i = 99 downto 93:
    %   n[i] := a * n[i+1];
    %   p[i] := p0 shifted (0, n[i]);
    % endfor;

    transform t[];
    t0 := identity rotated (0, 0, 180);

    p0 *= p1000 *= t0;

    t1 := identity shifted (-xpart p0, -ypart p0);

    p0 *= p1000 *= t1;

    %t2 := identity scaled (0, m3);
   

    %p0 *= p1000 *= t2;
    
    for i = 1 upto k:
      p[i] *= t0;
      p[i] *= t1;
    endfor;

    
    % show p0;

    % message "p[ref_fret}:";
    % show p[ref_fret];
    %pause;
    
    boolean do_labels;
    do_labels := false; % true;

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

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

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

    % show ypart p1000;
    % show ypart p0;
    % show llength;
    %pause;

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

    p212 := mediate(p0, p1000, 1/2);  %% Octave
    p207 := mediate(p0, p1000, 1/3);  %% Perfect 5th
    p204 := mediate(p0, p1000, 1/5);  %% Maj. 3rd
    p205 := mediate(p0, p1000, 1/4);  %% 4th
    p202 := mediate(p0, p1000, 1/9);  %% 2nd
    p209 := mediate(p0, p1000, 2/5);  %% 6th
    p211 := mediate(p0, p1000, 7/15); %% Maj. 7th
    
   
    % message "p0:";
    % show p0;
    % pause;

    numeric temp_val;




    

%% ** (2)
    
    numeric m[];
    numeric u;
    
    if (sstart > 0) and (sstart < ffret_ctr):
      p300 := p[sstart];
      message "p" & decimal sstart & ":";
      show p[sstart];
      m0 := floor(magnitude(ypart p300));
      m0 -= oovershoot_top;
      m0 := max(m0, 0);
      p302 := (xpart p0, -m0);      
    else:
      m0 := magnitude(ypart p0);
      p302 := p300 := p0;
      sstart := 0;
    fi

    if (eend > 1) and (eend > sstart) and (eend <= ffret_ctr):
      p301 := p[eend];
      message "p" & decimal eend & ":";
      show p[eend];
      m1 := ceil(magnitude(ypart p301));
      m1 += oovershoot_bot;
      p303 := (xpart p0, -m1);
    else:
      m1 := magnitude(ypart p1000);
      p303 := p301 := p1000;
      eend := 1000;
    fi



    
    message "m0 = " & decimal m0;
    message "m1 = " & decimal m1;

    if (magnitude(ypart p212) >= magnitude(ypart p302)) and (magnitude(ypart p212) <= magnitude(ypart p303)):
      drawdot p212 with_color green with_pen dot_pen;
      label.urt("{\Tiny Octave}", p212) shifted (2pt, 4pt) with_color dark_green;
    fi

    %% 2nd
    
    if (magnitude(ypart p202) >= magnitude(ypart p302)) and (magnitude(ypart p202) <= magnitude(ypart p303)):
      drawdot p202 with_color green with_pen dot_pen;
      label.lrt("$\scriptstyle 2^{\rm{nd}}$\hskip-.25ex, $\scriptstyle 9/8$, $\scriptstyle "
          & decimal -ypart p202 & "\Thinspace\rm{cm}$", p202) shifted (2pt, -3pt)
        with_color dark_green;
      draw p202 shifted (-1.25mm, 0) -- p202 shifted (1.25mm, 0) with_pen tiny_pen;
      u := ((magnitude(magnitude(ypart p202) - magnitude(ypart p2))) * 100) / (magnitude(ypart p202));
      label.rt("\setbox0=\hbox{" & decimal (-1 * ypart p2)
          & "\Thinspace cm}\lower10pt\hbox{\hskip\wd0\hskip.75em , "
          & "$\scriptstyle " & decimal (ypart p202 - ypart p2) & "\Thinspace =\Thinspace \Delta"
          & decimal u & "\%$}",
          p2);
    fi

    %% 5th
    
    if (magnitude(ypart p207) >= magnitude(ypart p302)) and (magnitude(ypart p207) <= magnitude(ypart p303)):
      drawdot p207 with_color green with_pen dot_pen;
      label.lrt("$\scriptstyle 5^{\rm{th}}$\hskip-.25ex, $\scriptstyle 3/2$, $\scriptstyle "
          & decimal -ypart p207 & "\Thinspace\rm{cm}$", p207) shifted (2pt, -3pt)
        with_color dark_green;
      draw p207 shifted (-1.25mm, 0) -- p207 shifted (1.25mm, 0) with_pen tiny_pen with_color magenta;
      u := ((magnitude(magnitude(ypart p207) - magnitude(ypart p7))) * 100) / (magnitude(ypart p207));
      label.rt("\setbox0=\hbox{" & decimal (-1 * ypart p7)
          & "\Thinspace cm}\lower10pt\hbox{\hskip\wd0\hskip.75em , "
          & "$\scriptstyle " & decimal (ypart p207 - ypart p7) & "\Thinspace =\Thinspace \Delta"
          & decimal u & "\%$}",
          p7);
    fi

    %% Maj. 3rd
    
    if (magnitude(ypart p204) >= magnitude(ypart p302)) and (magnitude(ypart p204) <= magnitude(ypart p303)):
      drawdot p204 with_color green with_pen dot_pen;
      label.urt("$\scriptstyle 3^{\rm{rd}}$\hskip-.25ex, $\scriptstyle 5/4$, $\scriptstyle "
          & decimal -ypart p204 & "\Thinspace\rm{cm}$", p204) shifted (2pt, 0pt)
        with_color dark_green;
      draw p204 shifted (-1.25mm, 0) -- p204 shifted (1.25mm, 0) with_pen tiny_pen;
      u := ((magnitude(magnitude(ypart p204) - magnitude(ypart p4))) * 100) / (magnitude(ypart p204));
      label.rt("\setbox0=\hbox{" & decimal (-1 * ypart p4)
          & "\Thinspace cm}\lower10pt\hbox{\hskip\wd0\hskip.75em , "
          & "$\scriptstyle +" & decimal (ypart p204 - ypart p4) & "\Thinspace =\Thinspace \Delta"
          & decimal u & "\%$}",
          p4);
    fi

    %% 4th

    if (magnitude(ypart p205) >= magnitude(ypart p302)) and (magnitude(ypart p205) <= magnitude(ypart p303)):
      drawdot p205 with_color green with_pen dot_pen;
      label.urt("$\scriptstyle 4^{\rm{th}}$\hskip-.25ex, $\scriptstyle 4/3$, $\scriptstyle "
          & decimal -ypart p205 & "\Thinspace\rm{cm}$", p205) shifted (2pt, 3pt)
        with_color dark_green;
      draw p205 shifted (-1.25mm, 0) -- p205 shifted (1.25mm, 0) with_pen tiny_pen with_color magenta;
      u := ((magnitude(magnitude(ypart p205) - magnitude(ypart p5))) * 100) / (magnitude(ypart p205));
      label.rt("\setbox0=\hbox{" & decimal (-1 * ypart p5)
          & "\Thinspace cm}\lower10pt\hbox{\hskip\wd0\hskip.75em , "
          & "$\scriptstyle +" & decimal (ypart p205 - ypart p5) & "\Thinspace =\Thinspace \Delta"
          & decimal u & "\%$}",
          p5);
    fi

    %% 6th
    
    if (magnitude(ypart p209) >= magnitude(ypart p302)) and (magnitude(ypart p209) <= magnitude(ypart p303)):
      drawdot p209 with_color green with_pen dot_pen;
      label.urt("$\scriptstyle 6^{\rm{th}}$\hskip-.25ex, $\scriptstyle 5/3$, $\scriptstyle "
          & decimal -ypart p209 & "\Thinspace\rm{cm}$", p209) shifted (2pt, 0pt)
        with_color dark_green;
      draw p209 shifted (-1.25mm, 0) -- p209 shifted (1.25mm, 0) with_pen tiny_pen;
      u := ((magnitude(magnitude(ypart p209) - magnitude(ypart p9))) * 100) / (magnitude(ypart p209));
      label.rt("\setbox0=\hbox{" & decimal (-1 * ypart p9)
          & "\Thinspace cm}\lower10pt\hbox{\hskip\wd0\hskip.75em , "
          & "$\scriptstyle +" & decimal (ypart p209 - ypart p9) & "\Thinspace =\Thinspace \Delta"
          & decimal u & "\%$}",
          p9);
    fi

    %% Maj. 7th
    
    if (magnitude(ypart p211) >= magnitude(ypart p302)) and (magnitude(ypart p211) <= magnitude(ypart p303)):
      drawdot p211 with_color green with_pen dot_pen;
      label.urt("{\Tiny Maj.~}$\scriptstyle  7^{\rm{th}}$\hskip-.25ex, $\scriptstyle  15/8$, $\scriptstyle "
          & decimal -ypart p211 & "\Thinspace\rm{cm}$", p211) shifted (2pt, -.25pt)
        with_color dark_green;
      draw p211 shifted (-1.25mm, 0) -- p211 shifted (1.25mm, 0) with_pen tiny_pen;
      u := ((magnitude(magnitude(ypart p211) - magnitude(ypart p11))) * 100) / (magnitude(ypart p211));
      label.rt("\setbox0=\hbox{" & decimal (-1 * ypart p11)
          & "\Thinspace cm}\lower10pt\hbox{\hskip\wd0\hskip.75em , "
          & "$\scriptstyle +" & decimal (ypart p211 - ypart p11) & "\Thinspace =\Thinspace \Delta"
          & decimal u & "\%$}",
          p11);
    fi
    
    % pause;
    
    message "p0:";
    show p0;

    message "p300:";
    show p300;

    message "p301:";
    show p301;

    %pause;

    if (sstart == 0) and (eend == 1000):
      draw p0 -- p1000;
    else:
      draw p302 -- p303;
    fi

    draw (p302 -- p303) shifted (-2cm, 0) with_pen pencircle scaled (.25mm, .25mm, .25mm);
    
    %draw (p0 -- p1000) shifted (-2cm, 0);
    

    if sstart == 0:
      if do_labels:
        dotlabel.lft("$p_0$", p0);
      else:
        label.top("Nut", p0) shifted (0, 2pt);
        draw (p0 shifted (-.25cm, 0)) -- (p0 shifted (.25cm, 0)) with_pen medium_pen;
      fi
    %dotlabel.lft("$p_{100}$", p1000);
    fi

    

    if eend == 1000:
      draw (p1000 shifted (-.25cm, 0)) -- (p1000 shifted (.25cm, 0)) with_pen medium_pen;
      label.bot("Saddle", p1000) shifted (0, -2pt);
    fi
    
    % message "p[ref_fret]:";
    % show p[ref_fret];
    %pause;

    for i = m0 upto m1:
      draw (p0 shifted (-2cm, 0) -- p0 shifted (-1cm, 0)) shifted (0, -i);
      label.lft(decimal i & "cm", (p0 shifted (-2cm, 0)) shifted (0, -i));
    endfor;

    for i = (m0 + .5) step .5 until (m1 - .5):
      draw (p0 shifted (-2cm, 0) -- p0 shifted (-1.5cm, 0)) shifted (0, -i);
    endfor;

    
    for i = (m0 + .1) step .1 until m1:
      draw (p0 shifted (-2cm, 0) -- p0 shifted (-1.75cm, 0)) shifted (0, -i);
    endfor;

    if eend < 1000:
      k := eend;
    fi
      
    
    for i = sstart upto k:
      pv += p[i];
      if do_labels:%
        dotlabel.lft("$p_{" & decimal i & "}$", p[i]);
      else:
        if i <= ffret_ctr:
          label.lft(decimal i, p[i]) shifted (-.333cm, 0);
          draw (p[i] shifted (-.25cm, 0)) -- (p[i] shifted (.25cm, 0)) with_pen small_pen;
        % elseif i < 25:
        %   dotlabel.lft(decimal i, p[i]) shifted (-2pt, 0) with_color dark_gray;
        fi
        temp_val := -1 * ypart p[i];
        if (i > 0) and (i <= ffret_ctr):
          label.rt(decimal temp_val & "\Thinspace cm", p[i]) shifted (.25cm, 0);
        % elseif i < 25:
        %   label.rt(decimal temp_val & "cm", p[i]) shifted (.125cm, 0)
        %     with_text_color dark_gray;
          fi
        fi
    endfor;


    message "Exiting layout.";

    pickup pencircle scaled (.333mm, .333mm, .333mm);
    
  endgroup;


%% ** (2) End of layout definition
  
enddef;



%% * (1) Fig. 0.  Dummy figure.  It must exist for the sake of the make rules.
%%       LDF 2022.07.13.

beginfig(0);
  drawdot origin;
endfig;

%% * (1)

beginfig(1);

  point p[];
  path q[];         

  p0 := origin;
  q0 := nullpath;
  point_vector pv;

  point_vector pv;

  layout  {p0,  %% ttop
           q0,  %% path Q
           pv,  %% point_vector PV
           87,  %% llength         
           17,  %% ffret_ctr       
           2mm, %% ffret_thickness        
             0, %% sstart
             5, %% eend,
             0, %% oovershoot_top	
             2  %% oovershoot_bot
    };

  clear pv;

endfig with_projection parallel_x_y no_sort;

%% * (1)

beginfig(2);

  point p[];
  path q[];         

  p0 := origin;
  q0 := nullpath;

  point_vector pv;

  layout  {p0,  %% ttop
           q0,  %% path Q
           pv,  %% point_vector PV
           87,  %% llength         
           17,  %% ffret_ctr       
           2mm, %% ffret_thickness        
            5,  %% sstart
            11, %% eend
            2,  %% oovershoot_top
            2   %% oovershoot_bot
    };

  clear pv;

endfig with_projection parallel_x_y no_sort;

%% * (1)

beginfig(3);

  point p[];
  path q[];         

  p0 := origin;
  q0 := nullpath;

  point_vector pv;

  layout  {p0,  %% ttop
           q0,  %% path Q
           pv,  %% point_vector PV
           87,  %% llength         
           17,  %% ffret_ctr       
           2mm, %% ffret_thickness        
            11, %% sstart
            17, %% eend
             2, %% oovershoot_top		
             2  %% oovershoot_bot   
    };

  clear pv;

endfig with_projection parallel_x_y no_sort;


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:
