metapost

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revisionBoth sides next revision
metapost [2019/12/24 14:23] – typo tarquinwjmetapost [2020/09/22 13:43] – Added scalebar 2b beni
Line 200: Line 200:
 This function simplifies it all. Add it once, and then any of your custom points can call it to add a label. This function simplifies it all. Add it once, and then any of your custom points can call it to add a label.
  
-[[user:tarquinwj|Tarquin 2019]]+[[user:tarquinwj|Tarquin 2019-2020]]
  
 <code> <code>
 code metapost code metapost
   vardef create_styled_label (expr plaintext,P,R,S,A,defaultstyle)=   vardef create_styled_label (expr plaintext,P,R,S,A,defaultstyle)=
-    save textsize, style;+    save textsize, style, thetext;
     string textsize;     string textsize;
     if S = 0.5:     if S = 0.5:
Line 271: Line 271:
 For an example of code making use of this function, see [[#Rope lengths]] below. For an example of code making use of this function, see [[#Rope lengths]] below.
  
 +If you want to add custom label styles, you need to call "thelabel.suffix(thetext,position)" with the right alignment suffix, save the return value in a variable called "lab", then call "process_label(position,rotation)". After that, you can check "bbox lab" to get the bounding box of the text label as a path which can be used to draw the decoration. You can temporarily ("interim") set the internal "bboxmargin" variable to make the bounding box larger than the text, to create some padding between the text and your ornamentation. You should use "begingroup+endroup" within a "def" when using the "interim" operator to make sure it gets reset correctly afterwards, or use a vardef instead of a def.
 +
 +Use "rotatedaround (position,rotation)" when drawing the ornamentation to make sure it gets rotated and aligned the same as the label. Note that this applies the rotation around the point position, so alignment and rotation at the same time is weird. This is the same with regular labels though - known Therion bug - so at least this is consistent with Therion itself.
 +
 +Since this will require setting the suffix correctly for both the regular label styles and the custom label styles, there ends up being a lot of duplicated code. It is easier to store the suffix name as a string which can then be extracted with scantokens when calling the appropriate macro, which is what the example code below does. The custom decorations are specified using a style number starting from 100, so as not to clash with the numbers used for Therion's internal label styles.
 +
 +<code>
 +code metapost
 +  vardef create_styled_label (expr plaintext,P,R,S,A,defaultstyle)=
 +    save textsize, style, thetext, sufx, athick;
 +    string textsize;
 +    if S = 0.5:
 +      textsize:="\thtinysize";
 +    elseif S = 0.7:
 +      textsize:="\thsmallsize";
 +    elseif S = 1.4:
 +      textsize:="\thlargesize";
 +    elseif S = 2:
 +      textsize:="\thhugesize";
 +    else: % normal is 1
 +      textsize:="\thnormalsize";
 +    fi;
 +    if known ATTR_labelstyle:
 +      style:=scantokens(ATTR_labelstyle);
 +    else:
 +      style:=defaultstyle;
 +    fi;
 +    picture thetext;
 +    thetext:=thTEX("\thframed {" & textsize & plaintext & "}");
 +    % store the alignment suffix as a string, it will be turned back into a suffix with scantokens
 +    string sufx;
 +    if A = (-1,1):
 +      sufx:="ulft";
 +    elseif A = (0,1):
 +      sufx:="top";
 +    elseif A = (1,1):
 +      sufx:="urt";
 +    elseif A = (-1,0):
 +      sufx:="lft";
 +    elseif A = (1,0):
 +      sufx:="rt";
 +    elseif A = (-1,-1):
 +      sufx:="llft";
 +    elseif A = (0,-1):
 +      sufx:="bot";
 +    elseif A = (1,-1):
 +      sufx:="lrt";
 +    else:
 +      sufx:="";
 +    fi;
 +    if style >= 100:
 +      % create the label, passing the alignment as a suffix
 +      lab:=thelabel.scantokens(sufx)(thetext,P);
 +      % process_label looks for a variable called "lab"
 +      process_label(P,R);
 +      % define all the different ornamentations that you want
 +      if style = 100:
 +        pickup PenA;
 +        athick:=(xpart (lrcorner PenA)) - (xpart (llcorner PenA));
 +        % make bounding box measurements temporarily be larger than the object being measured
 +        % "interim" modifies internal variable, must be inside vardef or def+begingroup to make
 +        % sure it gets reset to default correctly afterwards
 +        interim bboxmargin:=5athick;
 +        % rounded rectangle
 +        % rotating around P is undesirable when alignment is also used, but this is what regular labels do
 +        draw ((bbox lab) smoothed 5athick) rotatedaround (P,R) dashed evenly;
 +      fi;
 +    else:
 +      % create the label, passing the alignment as a suffix
 +      p_label.scantokens(sufx)(thetext,P,R,style);
 +    fi;
 +  enddef;
 +endcode
 +</code>
 =====Replacing legend drawings for existing symbols===== =====Replacing legend drawings for existing symbols=====
  
Line 572: Line 646:
 ===Magnetic effects=== ===Magnetic effects===
  
-[[user:tarquinwj|Tarquin 2019]]+[[user:tarquinwj|Tarquin 2019-2020]]
  
 Certain rocks can cause a compass to give the wrong reading. This icon can be used to show areas where this happens (ie. where the survey may be unreliable as a result); a spinning compass: Certain rocks can cause a compass to give the wrong reading. This icon can be used to show areas where this happens (ie. where the survey may be unreliable as a result); a spinning compass:
Line 580: Line 654:
   % a spinning compass   % a spinning compass
   def p_u_magnetism (expr P,R,S,A)=   def p_u_magnetism (expr P,R,S,A)=
-    scale:=0.5u; +    begingroup; 
-    halfline:=(0.5u/20S); %half thickness of PenC - pen thicknesses do not scale with S +      save scale, cthick, pointheight, pointwidth, cutheight, cutwidth; 
-    pointheight:=scale*.9; +      scale:=0.5u; 
-    pointwidth:=scale*.4; +      cthick:=(xpart (lrcorner PenC)) (xpart (llcorner PenC)); 
-    U:=(scale,scale); +      pointheight:=scale*.9; 
-    T:=identity aligned A rotated (R-20) scaled S shifted P; +      pointwidth:=scale*.4; 
-    % a circle +      cutheight:=pointheight - (cthick / sind(angle(pointheight,pointwidth))); 
-    thdraw fullcircle scaled 2scale withpen PenC withcolor black+      cutwidth:=pointwidth - (cthick / sind(angle(pointwidth,pointheight))); 
-    % filled triangle +      U:=(scale,scale); 
-    thfill (0,pointheight)--(pointwidth,0)--(-pointwidth,0)--cycle withcolor black+      T:=identity aligned A rotated (R-20) scaled S shifted P; 
-    % black triangle outline +      % a circle 
-    thdraw (0,-pointheight+halfline)--(pointwidth-halfline,0) withpen PenC withcolor black; +      thdraw fullcircle scaled 2scale withpen PenC; 
-    thdraw (0,-pointheight+halfline)--(-pointwidth+halfline,0) withpen PenC withcolor black+      % filled triangle 
-    % spin arcs, a full circle is path 0-8, anticlockwise, starting from the right +      thfill (0,pointheight)--(pointwidth,0)--(-pointwidth,0)--cycle; 
-    thdraw subpath (2.4,3.5) of fullcircle scaled 1.5scale withpen PenC withcolor black+      % black triangle outline 
-    thdraw subpath (6.4,7.5) of fullcircle scaled 1.5scale withpen PenC withcolor black;+      % this can be drawn with mitred pens, but it still ends up needing calculations to get the centre position of the pen thickness 
 +      % therefore it is easier to just use a filled path 
 +      % pointheight/2 is used to stop the thin unpainted gap between shapes 
 +      thfill (0,-pointheight)--(pointwidth,0)--(0,pointheight/2)--(cutwidth,0)--(0,-cutheight)--(-cutwidth,0)--(0,pointheight/2)--(-pointwidth,0)--cycle
 +      % spin arcs, a full circle is path 0-8, anticlockwise, starting from the right 
 +      thdraw subpath (2.4,3.5) of fullcircle scaled 1.5scale withpen PenC; 
 +      thdraw subpath (6.4,7.5) of fullcircle scaled 1.5scale withpen PenC
 +    endgroup;
   enddef;   enddef;
   initsymbol("p_u_magnetism");   initsymbol("p_u_magnetism");
Line 1046: Line 1127:
       fi;       fi;
     else:     else:
-      thdraw P;+      begingroup; 
 +        save type; 
 +        string type; 
 +        if known ATTR_type: 
 +          type:=ATTR_type; 
 +        else: 
 +          type:="primary"; 
 +        fi; 
 +        if type = "secondary": 
 +          thdraw P withcolor (0.7, 0.7, 0.7); 
 +        else: 
 +          thdraw P; 
 +        fi; 
 +      endgroup;
     fi;     fi;
   enddef;   enddef;
 endcode endcode
 </code> </code>
 +
 +Rope lines default to using the standard colour (black, unless you change it with "symbol-color"). Optionally use it with the following -attr setting "value" options on the line:
 +
 +  * -attr type primary   = (default) use the default colour (black)
 +  * -attr type secondary = draws in grey
 +
 +This allows you to have ropes with two different colours, useful if ropes are optional or follow an uncommon optional route.
  
 ===Deviations=== ===Deviations===
Line 2336: Line 2437:
               thdraw tmp_pic scaled valscal rotatedaround(origin, -rot);               thdraw tmp_pic scaled valscal rotatedaround(origin, -rot);
   enddef;   enddef;
 +  
 +  
 +===Northarrow 5===
 +from Benedikt Hallinger for version 5.4.
 +This arrow is borrowed from an older wiki entry and was enhanced with the label box.
 +
 +It will display the north reference based on the `north <grid|true>` layout option ("ge.N" for true north and "gi.N" for grid-north).
 +It can also optionally display the meridian grid convergence, to enable just define the metapost variable `northArrowShowGridConvergence` in your layout.
 +
 +{{:metapost:northarrows-5.jpg|}}
 +
 +  // distributed under the GNU General Public License.//
 +  code metapost
 +    def s_northarrow (expr rot) =
 +      T:=identity scaled 1.0 rotated -rot;  % scale your north arrow here
 +      begingroup  % Arrow
 +        thdraw (-.5cm, -1cm)--(0, 1.5cm)--(.5cm, -1cm)--(0, -.5cm)--cycle;
 +        thfill (-.5cm, -1cm)--(0, 1.5cm)--(0, -.5cm)--cycle;
 +      endgroup;
 +      
 +      begingroup  % Text Label with box
 +        thfill ((-.6cm, -.35cm)--(-.6cm, .35cm)--(.6cm, .35cm)--(.6cm,-.35cm)--cycle) withcolor (1.0, 1.0, 1.0);
 +        thdraw  (-.6cm, -.35cm)--(-.6cm, .35cm)--(.6cm, .35cm)--(.6cm,-.35cm)--cycle;
 +        interim defaultscale:=1;
 +        newinternal string dirText; dirText:="ge.N";  if NorthDir="grid": dirText:="gi.N"; fi
 +        
 +        if known northArrowShowGridConvergence:
 +            label(dirText, (0, 0.12cm)) scaled 1.0 rotated -rot;
 +            label("GC=" & decimal GridConv & "°", (0, -0.30cm)) scaled 0.7 rotated -rot;
 +        else:
 +             label("ge.N", (0, 0)) scaled 1.0 rotated -rot;
 +        fi
 +      endgroup;
 +      
 +    enddef;
 +  endcode
 +
  
 ====Scalebars==== ====Scalebars====
Line 2397: Line 2535:
       endgroup;       endgroup;
     enddef;     enddef;
 +
 +===Scalebar 2b===
 +By B. Hallinger; This is the same scalebar from above, except that it subdivides the first block.
 +
 +{{:metapost:s_scalebar-2b.png}}
 +
 +  code metapost
 +    def s_scalebar (expr l, units, txt) =
 +    % l = value of scale-bar length
 +    % units = ??
 +    % txt = string representing units
 +      begingroup
 +        interim warningcheck:=0;
 +        tmpl:=l / Scale * cm * units / 2;
 +        % tmpl = half plotted length of scale bar from central top insertion point  
 +        tmpx:=l / Scale * cm * units / 5;
 +        tmph:=5bp; % bar height
 +      endgroup;
 +      pickup PenC;
 +      draw (-tmpl,0)--(tmpl,0)--(tmpl,-tmph)--(-tmpl,-tmph)--cycle;
 +      p:=(0,0)--(tmpx,0)--(tmpx,-tmph)--(0,-tmph)--cycle;
 +      for i:=-0.5 step 2 until 2:   % start drawing at the third block (leave space for smaller divisions)
 +        fill p shifted (i * tmpx,0);
 +      endfor;
 +      
 +      % Draw first part with subdivided blocks
 +      p:=(0,0)--(tmpx/5,0)--(tmpx/5,-tmph)--(0,-tmph)--cycle;  % define width of segment (tmpx is length of a normal bar segment)
 +      for i:=-2.5 step 2/5 until -0.75:                        % Startpos, segments, count-index
 +        fill p shifted (i * tmpx,0) withcolor black;
 +      endfor;
 +      
 +      % Label of scale: Scalebar top, values below
 +      begingroup
 +        interim labeloffset:=3.5bp;
 +        for i:=0 step (l/5) until (l-1):
 +          tmpx:=tmpl * (i * 2 / l - 1);
 +          label.bot(thTEX(decimal (i)),(tmpx,-tmph));
 +        endfor;
 +        label.bot(thTEX(decimal (l) & "\thinspace" & txt),(tmpl,-tmph));
 +        label.top(thTEX("Ma\char25 stab 1 : " & decimal round(Scale*100)),(0,0));
 +      endgroup;
 +      
 +    enddef;
 +  endcode
 +
  
 ===Scalebar Bar length adjustment=== ===Scalebar Bar length adjustment===
  • metapost.txt
  • Last modified: 22 months ago
  • by tarquinwj