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/06/02 23:35] – [Symbol Sizing and Positioning] clarify symbol parameter indicator brucemuttonmetapost [2019/11/12 16:15] – Changes the customizable blocks code andrew.atkinson
Line 166: Line 166:
  
 I'm going to suggest that the best values for U: components are between [U/u=1.0] to [U/u=1.2] I'm going to suggest that the best values for U: components are between [U/u=1.0] to [U/u=1.2]
 +
 +An here are some examples with a slightly improved U: variable, with the symbol aligned top-left and oriented 30 degrees, and the output rotated 15, 105, 195, 285 degrees.
 +
 +{{:metapost:symbolparameterindicatorsamples.png?400|}}
 +
 +And one last example, using ''point water'', with the above code added, that demonstrates how align is related to scrap coordinates rather than the output coordinates.
 +
 +{{:metapost:symbolscrapaligntooutputalignexplained.png?400|}}
  
 Bruce Bruce
Line 358: Line 366:
  
   text en "point u:warning" "warning/danger"   text en "point u:warning" "warning/danger"
-      + 
 +===Magnetic effects=== 
 + 
 +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: 
 + 
 +<code> 
 +code metapost 
 +  % a spinning compass 
 +  def p_u_magnetism (expr P,R,S,A)= 
 +    scale:=0.5u; 
 +    halfline:=(0.5u/20S); %half thickness of PenC - pen thicknesses do not scale with S 
 +    pointheight:=scale*.9; 
 +    pointwidth:=scale*.4; 
 +    U:=(scale,scale); 
 +    T:=identity aligned A rotated (R-20) scaled S shifted P; 
 +    % a circle 
 +    thdraw fullcircle scaled 2scale withpen PenC withcolor black; 
 +    % filled triangle 
 +    thfill (0,pointheight)--(pointwidth,0)--(-pointwidth,0)--cycle withcolor black; 
 +    % black triangle outline 
 +    thdraw (0,-pointheight+halfline)--(pointwidth-halfline,0) withpen PenC withcolor black; 
 +    thdraw (0,-pointheight+halfline)--(-pointwidth+halfline,0) withpen PenC withcolor black; 
 +    % 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 withcolor black; 
 +    thdraw subpath (6.4,7.5) of fullcircle scaled 1.5scale withpen PenC withcolor black; 
 +  enddef; 
 +  initsymbol("p_u_magnetism"); 
 +endcode 
 +</code> 
 + 
 +{{ ::magnetism.png?nolink |}} 
 + 
 +Select this as point type "u" with "-subtype magnetism" in its options. Use it with this line in your layout: 
 + 
 +  text en "point u:magnetism" "magnetism"
 ====Line Symbols==== ====Line Symbols====
 ===View whole centerline for underground=== ===View whole centerline for underground===
Line 1008: Line 1050:
 Blocks shown as produced by default settings, at about half scale. Blocks shown as produced by default settings, at about half scale.
  
-Various things could be improved, the drawing of the different sided boulders, and calling of thclean qq; three times to stop transparency cannot be the best way.+The grid is made of horizontal and vertical grids, but due to the way the starting regular polygon is derived the starting point is always top middle, this makes no randomness makes the squares come out at 45°
  
-**Code for blocks, Variables can be amended at the start** +Various things could be improved. 
-    initsymbol("a_blocks_BCA"); + 
-     +The settings can no be overridden by using <code>-attr</code> 
-    def a_blocks_BCA (expr p) = +on each area, therefore having different types and density of blocks in different areas. 
-  T:=identity; + 
-  symbol_distance:=0.7; % Distance between the blocks as set out in a rectangular grid +overlap <''true|false''> 
-  block_randomisation:=0.7; % Max each point of the base block can be moved. Too big and they can intersect themselves +Do the blocks overlap the borderif false an attempt is made to shink the block until it is inside or out 
-  base_rotation:= 0; % Rotation from 0 of base block, can be used to set all blocks to the same angle + 
-  random_rotation:= 360; % Rotation either side of base rotation eg 20 will be plus or minus 10 each side +separation <''number''> 
-  min_scale_factor:=0.7; % Minimum multiplier used for the base shape + 
-  add_scale_factor:= 0.6; % Added to the minimum multiplier to get the maximum scale +Proportion to the size of separation of centres of the blocks as set out in a rectangular grid 
-  block_rectangle:=1.5; % How much longer the block is than it is wide, before randomising + 
-  shift_randomisation:=0.75; % Max random amount block can be moved from the original grid +Default 0.7 
-  %Now set the proportions of different sided block + 
-  b_tri:=1; +block_random <''number''> 
-  b_quad:=3; +Max each point of the base block can be moved. Too big and they can intersect themselves 
-  b_pent:=4; +Default 0.7 
-  b_hex:=2; + 
-  pickup PenC; +base_rotation <''number''> 
- path q, regular, qq; q = bbox p; +Rotation from 0 of base block, can be used to set all blocks to the same angle, not relavant if random rotation is set to 360 
- pair outside; +Default 0 
- outside:= ulcorner q + up; + 
- picture tmp_pic;  +random_rotation <''number''> 
- uu := max(u, (xpart urcorner q - xpart llcorner q)/100, (ypart urcorner q - ypart     llcorner q)/100); +Rotation either side of base rotation eg 20 will be plus or minus 10 each side 
- iu := uu * block_rectangle+Default 360 
- blocks := b_tri+b_quad + b_pent + b_hex; + 
- tmp_pic := image( +min_scale <''number''> 
-    for i = xpart llcorner q step symbol_distance block_rectangle * uu until xpart urcorner q: +Minimum multiplier used for the base shape 
-       for j = ypart llcorner q step symbol_distance*uu until ypart urcorner q: +Default 0.7 
-         pick_sides := uniformdeviate(blocks); + 
-         if pick_sides < b_tri: + 
-         sides:=3; +max_scale <''number''> 
-         elseif pick_sides < b_tri + b_quad: +Added to the minimum multiplier to get the maximum scale 
-         sides:=4+Default 0.6 
-         elseif pick_sides < b_tri + b_quad +b_pent: + 
-         sides:=5; +aspect <''number''> 
-         else: +How much longer the block is than it is wide, before randomising 
-         sides:=6 +Default  
-         fi; + 
-   +shift_random <''number''> 
-           qq :=  for n:=0 upto sides-1: +Max random amount block can be moved from the original grid 
-                   ((cosd(360*n/sides))*iu/2,(sind(360*n/sides))*uu/2) --  +Deafult 0.75 
-                             endfor cycle%radius is 0.5 divide by 2 + 
-           qq := punked ((qq)  +shapes <''number,number,number,number''> 
-           randomized (block_randomisation * uu)) +Set the ratio of different sided block, triangle, square, pentagon, hexagon. Must be single digits  
-           scaled (uniformdeviate(add_scale_factor)+min_scale_factor) +Default 1,3,4,2 
-           rotated (base_rotation + random_rotation / 2 - uniformdeviate(random_rotation) ) + 
-           shifted ((i,j) randomized (shift_randomisation * uu)); + 
-           +**Code for blocks** 
-           +<code> 
-           forever: % Repeatedly reduces the size of the image, as this is done round zero it also moves it to the zero location, until it fits in the area +initsymbol ("a_blocks_BCA"); 
-            exitif xpart (p intersectiontimes qq) < 0; + 
-            qq:= qq scaled (0.99 ); +def a_blocks_BCA (expr p) = 
-           endfor; + T:=identity; 
-             if pointinside((i,j),p,outside): % Cleans lines on border, assumably ones outside with jut an edge touching + 
-                thclean qq; +%Derived from one of the built in blocks symbols 
-                thclean qq; +%No error checking on the attr so can break badly 
-                thclean qq; +% Andrew Atkinson 2019 
-                thclean qq; + 
-                thdraw qq; +%Do the blocks overlap the border, if false an attempt is made to shink the block until it is inside or out 
-             fi; +boolean overlap; 
-       endfor;   +overlap:= 
-    endfor; +if known ATTR_overlap: scantokens(ATTR_overlap) 
- ); +else: false fi; 
-  clip tmp_pic to p; + 
-  drawoptions(); +Proportion to the size of separation of centres of the blocks as set out in a rectangular grid 
-  draw tmp_pic; +%FIXME: Really need to check if it is number and not zero in for some cases 
- enddef;+separation:=  
 +if known ATTR_separation: scantokens(ATTR_separation) 
 +else: 0.7 fi; 
 + 
 +% Max each point of the base block can be moved. Too big and they can intersect themselves 
 +block_random:= 
 +if known ATTR_block_random: scantokens(ATTR_block_random); 
 +else: 0.7 
 +fi; 
 + 
 +% Rotation from 0 of base block, can be used to set all blocks to the same angle 
 +base_rotation:= 
 +if known ATTR_base_rotation: scantokens(ATTR_base_rotation) 
 +else: 0 
 +fi; 
 + 
 +% Rotation either side of base rotation eg 20 will be plus or minus 10 each side 
 + 
 +random_rotation:= 
 +if known ATTR_random_rotation: scantokens(ATTR_random_rotation) 
 +else: 360 
 +fi; 
 + 
 +% Minimum multiplier used for the base shape 
 + 
 +min_scale_factor:= 
 +if known ATTR_min_size: scantokens(ATTR_min_size) 
 +else: 0.
 +fi; 
 + 
 +% Added to the minimum multiplier to get the maximum scale 
 +add_scale_factor:= 
 +if known ATTR_max_size: scantokens(ATTR_max_size) 
 +else: 0.
 +fi; 
 + 
 +% How much longer the block is than it is wide, before randomising 
 +aspect:= 
 +if known ATTR_aspect: scantokens(ATTR_aspect) 
 +else: 1.
 +fi; 
 + 
 +% Max random amount block can be moved from the original grid 
 +shift_random:
 +if known ATTR_shift_random: scantokens(ATTR_shift_random) 
 +else: 0.75 
 +fi; 
 + 
 +Set the propotions of different sided block 
 +if known ATTR_shapes: 
 +b_tri:=scantokens substring (0,1) of ATTR_shapes; 
 +b_quad:=scantokens substring (2,3) of ATTR_shapes; 
 +b_pent:=scantokens substring (4,5) of ATTR_shapes; 
 +b_hex:=scantokens substring (6,7) of ATTR_shapes; 
 +else: 
 +b_tri:=1; 
 +b_quad:=3; 
 +b_pent:=4; 
 +b_hex:=2; 
 +fi; 
 + 
 +pickup PenC; 
 +path q, qq; q = bbox p; 
 +pair outside; 
 +outside:= ulcorner q + up; 
 +picture tmp_pic;  
 +uu := max(u, (xpart urcorner q - xpart llcorner q)/100, (ypart urcorner q - ypart     llcorner q)/100); 
 +iu := uu * aspect
 +blocks := b_tri+b_quad + b_pent + b_hex; 
 +tmp_pic := image( 
 +   for i = xpart llcorner q step separation aspect * uu until xpart urcorner q: 
 +      for j = ypart llcorner q step separation*uu until ypart urcorner q: 
 +        pick_sides := uniformdeviate(blocks); 
 + 
 +% This is probably a better way to impliment the different sided blocks calculates the vertices of polygons 
 +%for (i = 0; i < n; i++) { 
 +% printf("%f %f\n",x + r * Math.cos(2 * Math.PI * i / n), y + r * Math.sin(2 * Math.PI * i / n)); 
 +%} 
 + 
 +        if pick_sides < b_tri: 
 +          qq := punked (((.5iu,0)--(-0.25iu,.43uu)--(-.25iu,-0.43uu)--cycle)  
 +          randomized (block_random * uu)) 
 +          scaled (uniformdeviate(add_scale_factor)+min_scale_factor) 
 +         rotated (base_rotation + random_rotation / 2 - uniformdeviate(random_rotation) ) 
 +          shifted ((i,j) randomized (shift_random * uu)); 
 +        elseif pick_sides < b_tri + b_quad: 
 +                    qq := punked (((0.5iu,0)--(0,0.5uu)--(-0.5iu,0)--(0,-0.5uu)--cycle)  
 +          randomized (block_random * uu)) 
 +          scaled (uniformdeviate(add_scale_factor)+min_scale_factor) 
 +         rotated (base_rotation + random_rotation / 2 - uniformdeviate(random_rotation) ) 
 +          shifted ((i,j) randomized (shift_random * uu))
 +         elseif pick_sides < b_tri + b_quad + b_pent: 
 +                    qq := punked (((0.5iu,0)--(.15iu,0.48uu)--(-0.4iu,0.29uu)--(-0.4iu,-0.29uu)--(0.15iu,-0.48uu)--cycle 
 +          randomized (block_random * uu)) 
 +          scaled (uniformdeviate(add_scale_factor)+min_scale_factor) 
 +         rotated (base_rotation + random_rotation / 2 - uniformdeviate(random_rotation) ) 
 +          shifted ((i,j) randomized (shift_random * uu))
 +          else: 
 +          qq := punked (((0.5iu,0)--(0.25iu,0.43uu)--(-0.25iu,0.43uu)--(-0.5iu,0)--(-0.25iu,-0.43uu)--(0.25iu,-0.43uu)--cycle)  
 +          randomized (block_random * uu)) 
 +          scaled (uniformdeviate(add_scale_factor)+min_scale_factor) 
 +          rotated (base_rotation + random_rotation / 2 - uniformdeviate(random_rotation) ) 
 +          shifted ((i,j) randomized (shift_random * uu)); 
 +         fi; 
 +       if not overlap:  
 +          forever: % Repeatedly reduces the size of the image, as this is done round zero it also moves it to the zero location, until it fits in the area 
 +           exitif xpart (p intersectiontimes qq) < 0; 
 +           qq:= qq scaled (0.99 ); 
 +          endfor; 
 +        fi 
 +            if pointinside((i,j),p,outside): 
 +               thclean qq; 
 +               thdraw qq; 
 +             fi; 
 +      endfor;   
 +   endfor; 
 +); 
 + clip tmp_pic to p; %this appears not to be needed as the pointinside removes any outside the area 
 + drawoptions(); % no idea what this does! 
 + draw tmp_pic; 
 +enddef; 
 +</code>
  
 The base_rotation is an attempt to produce bedding plane breakdown, it could do with more time but this is possible The base_rotation is an attempt to produce bedding plane breakdown, it could do with more time but this is possible
Line 1084: Line 1247:
  
 using the settings using the settings
- +<code> 
-  symbol_distance:=0.5; % Distance between the blocks as set out in a rectangular grid +area blocks -attr shapes 1,2,4,7 -attr seperation 0.5 -attr block_random 0.7  -attr base_rotation 20 -attr random_rotation 5 -attr min_scale 0.5 -attr aspect 
-  block_randomisation:=0.7; % Max each point of the base block can be moved. Too big and they can intersect themselves +</code>
-  base_rotation:= 20; % Rotation from 0 of base block, can be used to set all blocks to the same angle +
-  random_rotation:= 5; % Rotation either side of base rotation eg 20 will be plus or minus 10 each side +
-  min_scale_factor:=0.5; % Minimum multiplier used for the base shape +
-  add_scale_factor:= 0.6; % Added to the minimum multiplier to get the maximum scale +
-  block_rectangle:=7; % How much longer the block is than it is wide, before randomising +
-  shift_randomisation:=0.75; % Max random amount block can be moved from the original grid +
-  %Now set the propotions of different sided block +
-  b_tri:=1; +
-  b_quad:=2; +
-  b_pent:=4; +
-  b_hex:=7;+
  
  
Line 1555: Line 1707:
     draw (tmpl-0.25*u/10,-tmph)--(-tmpl+0.25*u/10,-tmph);     draw (tmpl-0.25*u/10,-tmph)--(-tmpl+0.25*u/10,-tmph);
  
 +===Scalebar 3===
 +{{:metapost:scalebar3.png?=400}}  by Chris Hayes
 +
 +  layout LayoutScalebar3 # Scalebar by Chris Hayes
 + code metapost
 + def s_scalebar (expr l, units, txt) =
 +   begingroup
 + interim warningcheck:=0;
 + tmp05:=5 * (l / Scale * cm * units / 100);
 + tmp10:=10 * (l / Scale * cm * units / 100);
 + tmp20:=20 * (l / Scale * cm * units / 100);
 + tmp40:=40 * (l / Scale * cm * units / 100);
 + tmp60:=60 * (l / Scale * cm * units / 100);
 + tmp80:=80 * (l / Scale * cm * units / 100);
 + tmp100:=100 * (l / Scale * cm * units / 100);
 + scal05:=5 * l / 100;
 + scal10:=10 * l / 100;
 + scal20:=20 * l / 100;
 + scal40:=40 * l / 100;
 + scal60:=60 * l / 100;
 + scal80:=80 * l / 100;
 + brht:= 5bp;
 + lblht:= 8bp;
 +   endgroup;
 +   pickup PenC;
 +   draw (0,0)--(0,brht)--(tmp100,brht)--(tmp100,0)--(0,0);
 +   draw (tmp05,0)--(tmp05,brht);
 +   draw (tmp10,0)--(tmp10,brht);
 +   draw (tmp20,0)--(tmp20,brht);
 +   draw (tmp40,0)--(tmp40,brht);
 +   draw (tmp60,0)--(tmp60,brht);
 +   draw (tmp80,0)--(tmp80,brht);
 +   fill (tmp05,0)--(tmp10,0)--(tmp10,brht)--(tmp05,brht)--cycle;
 +   fill (tmp20,0)--(tmp40,0)--(tmp40,brht)--(tmp20,brht)--cycle;
 +   fill (tmp60,0)--(tmp80,0)--(tmp80,brht)--(tmp60,brht)--cycle;
 +   begingroup
 + label.top(thTEX(decimal (l) & "\thinspace" & txt),origin+(tmp100,lblht));
 + label.top(thTEX(decimal (scal80)),origin+(tmp80,lblht));
 + label.top(thTEX(decimal (scal60)),origin+(tmp60,lblht));
 + label.top(thTEX(decimal (scal40)),origin+(tmp40,lblht));
 + label.top(thTEX(decimal (scal20)),origin+(tmp20,lblht));
 + label.top(thTEX(decimal (scal10)),origin+(tmp10,lblht));
 + label.top(thTEX(decimal (scal05)),origin+(tmp05,lblht));
 + label.top(thTEX(decimal (0)),origin+(0,lblht));
 +   endgroup
 + enddef;    
 + endcode
 +  endlayout LayoutScalebar3
 ====Gridlines==== ====Gridlines====
 ===Change grid symbols from cross hairs to continuous lines=== ===Change grid symbols from cross hairs to continuous lines===
  • metapost.txt
  • Last modified: 22 months ago
  • by tarquinwj