Am 22.02.24 um 18:35 schrieb Hans Hagen via ntg-context:
On 2/21/2024 7:47 PM, Henning Hraban Ramm wrote:
(I’m sure I already used that somewhere… Must document…)
ok, new feature dedicated to Hraban ... who then of course has to document it.

This is nice.
Thank you, will do.

(Actually I’m not much interested in dashed borders but to have lines affected by my sketchy style - courtesy of Aditya et al., see below)

Taco, will the syntax pages in the wiki update automatically to a newer version?


"""
\startuseMPgraphic{mp:sketchy}
input mp-sketch.mp;
sketchypaths;

sketch_amount := 1 + (uniformdeviate 2);
sketch_passes := 3;
sketch_segments := 2 + (uniformdeviate 3);
sketch_length := OverlayWidth / 3;

draw topboundary withpen pensquare withcolor lightgray;
naturalizepaths;
\stopuseMPgraphic

\defineoverlay[sketchylines][\useMPgraphic{mp:sketchy}]

\setupTABLE[r][first][style=bold]
\setupTABLE[r][each][
        topoffset=1em,bottomoffset=0.5em,
        background=sketchylines,
        % would be nice if the background wouldn’t start at each column
]
\setupTABLE[c][each][frame=off]
\bTABLE[]
\bTR
\bTD{Stadt}\eTD
\bTD{Land}\eTD
\bTD{Fluss}\eTD
\eTR
\dorecurse{10}{
\bTR
\bTD\strut \eTD\bTD \eTD\bTD \eTD
\eTR
}
\eTABLE
"""


Hraban
%D \module
%D   [       file=mp-sketch.mp
%D        version=2021.05.13
%D          title=\CONTEXT\ \METAPOST\ graphics,
%D       subtitle=Sketch drawing,
%D         author=Aditya Mahajan,
%D           date=\currentdate,
%D      copyright={Aditya Mahajan}]

%D This metapost module is inspired by a TeX.SE question:
%D http://tex.stackexchange.com/q/39296/323
%D
%D I thought that it would be fun to implement a similar feature in MetaPost.
%D
%D To use this package in MetaPost:
%D
%D \starttyping
%D    input mp-sketch;
%D
%D    beginfig(1)
%D      sketchypaths; % Make draw and fill sketchy
%D      ...
%D      naturalizepaths; % Restore the value of draw and fill
%D      ...
%D    endfig
%D \stoptyping
%D
%D The code is heavily inspired by Hans Hagen's Metafun macros.
%D
%D The macro \type{sketchypaths} is modeled after \type{visualizepaths} from
%D \filename{mp-tool}.

def sketchypaths =
    let draw = sketchdraw ;
    let fill = sketchfill ;
enddef ;

%D Check if \filename{mp-tool} is loaded
if not known context_tool :
  let normaldraw = draw;
  let normalfill = fill;

  def naturalizepaths =
      let fill = normalfill ;
      let draw = normaldraw ;
  enddef ;
fi

%D The variable \type{sketch_amount} determines the amount of randomness in the
%D drawing
numeric sketch_amount; sketch_amount := 0.75bp;

%D The variable \type{sketch_passes} determines the number of times the path
%D is drawn
numeric sketch_passes; sketch_passes := 1;

%D Based on \type{randomized}. Assumes p is path:
numeric sketch_segments; sketch_segments := 20;

%D Length (time) of line segments:
numeric sketch_length; sketch_length := 5mm;

primarydef p sketchrandomized s = (
    if path p :
        for t = 0 step 1/sketch_segments until 1-1/sketch_segments :
            ((point       (t*arclength(p))                     on p) 
randomshifted s) .. controls
            ((postcontrol (t*arclength(p))                     on p) 
randomshifted s) and
            ((precontrol  ((t+1/sketch_segments)*arclength(p)) on p) 
randomshifted s) ..
        endfor
        % TODO: beide Ansätze kombinieren. Eckpunkte erhalten!

%        for t = 0 step sketch_length until arclength p:
%          (point (arctime t of p) of p) randomshifted s ..
%        endfor
        if cycle p : % funktioniert nicht
          cycle
        else :
          ((point       (arclength(p))                     on p) randomshifted 
s)
          %(point (arctime t of p) of p) randomshifted s
        fi
    else :
        p
    fi
) enddef ;



%D The macro \type{sketchdraw} draws the randomized path. The
%D \type{expr} ... \type{text} trick is copied from the definition of
%D \type{drawarrow}
def sketchdraw expr p =
   do_sketchdraw(p)
enddef;

def do_sketchdraw(expr p) text t =
  if (path p) :
      for i = 1 upto max(1,sketch_passes) :
        normaldraw p
                   sketchrandomized sketch_amount
                   withtransparency ("multiply", 1/max(1,sketch_passes))
                   t ;
      endfor;
  else :
      normaldraw p t;
  fi
enddef;

%D The macro \type{sketchfill} randomizes the path before filling it.
def sketchfill expr p =
  do_sketchfill(p)
enddef ;

def do_sketchfill(expr p) text t =
  if (path p) :
      for i = 1 upto max(1,sketch_passes) :
        normalfill p
                   sketchrandomized sketch_amount
                   withtransparency ("multiply", 1/max(1,sketch_passes))
                   t ;
      endfor;
  else :
      normalfill p t;
  fi
enddef;

picture NoisePattern;
NoisePattern := image(
  pickup pencircle xyscaled 0.5bp;
  numeric pmax ; pmax := 7 ;
  numeric x ; numeric y ;
        for i = 1 upto pmax:
                for j = 1 upto pmax:
      % try to get more dots in the center
      x := (i - (pmax/2) * (uniformdeviate 2.5)); % we use a wide pen
      y := (j - (pmax/2)) * (uniformdeviate 1.25);
      draw (x, y) withcolor "LineColor" withtransparency ("normal", 
(uniformdeviate 0.33));
                endfor
        endfor
);

numeric brush_length ; brush_length := 20 ;
%numeric brush_width ; brush_width := 0.5 ;

picture BrushPattern;

def makeBrush(expr brush_width) =
  BrushPattern := image(
    naturalizepaths;
    pickup pensquare xyscaled 0.25bp;
    numeric xmax, ymax, dev ;
    ymax := 7 ;
    xmax := round(ymax/2 * brush_width);
    numeric x ; numeric y ;
        for i = 1 upto xmax:
                for j = 1 upto ymax:
        x := (i - (xmax/2));
        y := (j - (ymax/2)); % * (uniformdeviate 1.25);
        dev := (uniformdeviate 1)-0.5;
        draw (x-dev, y-(uniformdeviate brush_length))--(x+dev, 
y+(uniformdeviate brush_length)) withcolor "LineColor" withtransparency 
("normal", (uniformdeviate 0.25));
                endfor
        endfor
  );
enddef;

numeric noise_steps ; noise_steps := 150;
numeric nrush_steps ; brush_steps := 30;

def noisify(expr p) =
  for i = 0 step 1/noise_steps until length p:
        draw NoisePattern randomized 1 shifted point i of p ;
  endfor
enddef;

def brushify(expr p, w) =
  makeBrush(w);
  for i = 0 step 1/brush_steps until length p:
        draw BrushPattern randomized 1 rotated (90 + angle direction i of p) 
shifted point i of p ;
  endfor
enddef;

endinput;

% Modified example from
% http://tex.loria.fr/prod-graph/zoonekynd/metapost/metapost.html

beginfig(1)
  pair A,B,C,O;
  A=(0,0); B=(3cm,0); C=(1cm,2cm);

  O - 1/2[B,C] = whatever * (B-C) rotated 90;
  O - 1/2[A,B] = whatever * (A-B) rotated 90;

  sketchypaths;
  sketch_amount := 5bp;
  draw A--B--C--cycle;

  draw O withpen pencircle scaled 4bp;

  sketch_amount := 2bp;
  draw fullcircle scaled 2abs(O-A) shifted O;
endfig
___________________________________________________________________________________
If your question is of interest to others as well, please add an entry to the 
Wiki!

maillist : ntg-context@ntg.nl / 
https://mailman.ntg.nl/mailman3/lists/ntg-context.ntg.nl
webpage  : https://www.pragma-ade.nl / https://context.aanhet.net (mirror)
archive  : https://github.com/contextgarden/context
wiki     : https://wiki.contextgarden.net
___________________________________________________________________________________

Reply via email to