Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revisionBoth sides next revision | ||
metapost [2019/06/03 01:04] – [Symbol Sizing and Positioning] explain align in scrap versus output brucemutton | metapost [2019/11/30 08:20] – Adding custom styled labels at any point/linepoint tarquinwj | ||
---|---|---|---|
Line 192: | Line 192: | ||
</ | </ | ||
+ | =====Adding custom styled labels at any point/ | ||
+ | |||
+ | Therion does not offer any way to add custom styled labels to inputs - labels are created by various dedicated point symbols. Although you can call some of the internal macros to produce labels, it can be difficult to work out exactly what macro names to call to get it to align correctly, and certain features, such as setting the scaling, require you to modify the TEX rather than the MetaPost. | ||
+ | |||
+ | This function simplifies it all. Add it once, and then any of your custom points can call it to add a label. | ||
+ | |||
+ | < | ||
+ | code metapost | ||
+ | vardef create_styled_label (expr plaintext, | ||
+ | save textsize, style; | ||
+ | string textsize; | ||
+ | if S = 0.5: | ||
+ | textsize: | ||
+ | elseif S = 0.7: | ||
+ | textsize: | ||
+ | elseif S = 1.4: | ||
+ | textsize: | ||
+ | elseif S = 2: | ||
+ | textsize: | ||
+ | else: % normal is 1 | ||
+ | textsize: | ||
+ | fi; | ||
+ | if known ATTR_labelstyle: | ||
+ | style: | ||
+ | else: | ||
+ | style: | ||
+ | fi; | ||
+ | picture thetext; | ||
+ | thetext: | ||
+ | if A = (-1,1): | ||
+ | p_label.ulft(thetext, | ||
+ | elseif A = (0,1): | ||
+ | p_label.top(thetext, | ||
+ | elseif A = (1,1): | ||
+ | p_label.urt(thetext, | ||
+ | elseif A = (-1,0): | ||
+ | p_label.lft(thetext, | ||
+ | elseif A = (1,0): | ||
+ | p_label.rt(thetext, | ||
+ | elseif A = (-1,-1): | ||
+ | p_label.llft(thetext, | ||
+ | elseif A = (0,-1): | ||
+ | p_label.bot(thetext, | ||
+ | elseif A = (1,-1): | ||
+ | p_label.lrt(thetext, | ||
+ | else: | ||
+ | p_label(thetext, | ||
+ | fi; | ||
+ | enddef; | ||
+ | endcode | ||
+ | </ | ||
+ | |||
+ | Call it like this: | ||
+ | |||
+ | < | ||
+ | create_styled_label(text, | ||
+ | </ | ||
+ | |||
+ | Style meanings: | ||
+ | * 0 or = basic label | ||
+ | * 1 = label with a dot marker | ||
+ | * 2 = semi circle up | ||
+ | * 3 = semi circle down | ||
+ | * 4 = semi circle up and semi circle down | ||
+ | * 5 = (default) circle | ||
+ | * 6 = box | ||
+ | * 7 = basic label with extra offset | ||
+ | * 8 = supposed to be a filled label, but doesn' | ||
+ | |||
+ | Each symbol can individually override its label styling by setting the "-attr labelstyle 6" option - the function will check for it, and use that other style if an option is selected. | ||
=====General Symbol Examples===== | =====General Symbol Examples===== | ||
For example; centrelines, | For example; centrelines, | ||
Line 297: | Line 367: | ||
enddef; | enddef; | ||
- | ===P-hangers that face the right way=== | + | ===P-hangers that face the right way, and other anchor designs=== |
The default " | The default " | ||
+ | |||
+ | In elevation view, by default it switches to being a filled circle, a standard symbol for a fixed position hanger, which can be placed on the linepoints of a basic rope line. | ||
+ | |||
+ | By using the "-attr type" option, you can control which type of anchor it will show: | ||
+ | * "-attr type auto" (default) shows a P-hanger (like " | ||
+ | * "-attr type p" shows a P-hanger in either plan or elevation view - the control point is at the place where a P-hanger meets the wall, not where the rope meets the hanger. | ||
+ | * "-attr type ropedp" | ||
+ | * "-attr type fixed" shows a filled circle in either plan or elevation view. | ||
+ | * "-attr type natural" | ||
< | < | ||
code metapost | code metapost | ||
- | | + | |
+ | % store the original clean_legend_box | ||
+ | boolean p_anchor_MY_inlegend; | ||
+ | p_anchor_MY_inlegend: | ||
+ | let p_anchor_MY_legend_box = clean_legend_box; | ||
+ | % redefine clean_legend_box to store the flag, then run the original | ||
+ | def clean_legend_box = | ||
+ | p_anchor_MY_inlegend: | ||
+ | p_anchor_MY_legend_box; | ||
+ | enddef; | ||
+ | |||
+ | | ||
def p_anchor_MY (expr P,R,S,A)= | def p_anchor_MY (expr P,R,S,A)= | ||
- | | + | |
- | T:=identity aligned A rotated R scaled S shifted P; | + | % this is the legend - make sure the function works normally again |
- | % thick part sticking out of the rock | + | p_anchor_MY_inlegend:=false; |
- | | + | % draw a pretty legend - show all possibilities |
- | % thin part in the rock | + | |
- | | + | ATTR_type: |
- | % the loop should hang down the "page", based on the rotation | + | p_anchor_MY((.2,.57) inscale, |
- | | + | |
- | Facing:=-1 | + | |
+ | | ||
+ | | ||
else: | else: | ||
- | | + | |
+ | save type, facing; | ||
+ | T:=identity aligned A rotated R scaled S shifted P; | ||
+ | string type; | ||
+ | if known ATTR_type: | ||
+ | type: | ||
+ | else: | ||
+ | type: | ||
+ | fi; | ||
+ | if (type = " | ||
+ | U: | ||
+ | PenCThick: | ||
+ | % fill with background colour, to remove any rope lines going through the point | ||
+ | % this does not respect opacity, but there is no other way to remove lines from other objects | ||
+ | % clipping currentpicture does not work, since ropes are always drawn last, then layered beneath point symbols | ||
+ | thunfill fullcircle scaled (0.4u-PenCThick); | ||
+ | thdraw fullcircle scaled (0.4u-PenCThick) withpen PenC; | ||
+ | else: | ||
+ | if (type = " | ||
+ | U: | ||
+ | thfill fullcircle scaled 0.4u; | ||
+ | else: | ||
+ | if (R > 0) and (R < 180): | ||
+ | facing:=-1 | ||
+ | else: | ||
+ | facing:=1 | ||
+ | fi; | ||
+ | if (type = " | ||
+ | T:=identity shifted (facing*-0.25u, | ||
+ | fi; | ||
+ | U: | ||
+ | % thick part sticking out of the rock | ||
+ | thdraw (0, | ||
+ | % thin part in the rock | ||
+ | thdraw (0, | ||
+ | % the loop should hang down the " | ||
+ | % stubs to hold the semicircle | ||
+ | thdraw (0, | ||
+ | thdraw (0, | ||
+ | % semicircle | ||
+ | thdraw halfcircle scaled .3u rotated (facing*-90) shifted (facing*.1u, | ||
+ | fi; | ||
+ | fi; | ||
+ | endgroup; | ||
fi; | fi; | ||
- | % stubs to hold the semicircle | ||
- | thdraw (0, | ||
- | thdraw (0, | ||
- | % semicircle | ||
- | thdraw halfcircle scaled .3u rotated (Facing*-90) shifted (Facing*.1u, | ||
enddef; | enddef; | ||
initsymbol(" | initsymbol(" | ||
Line 366: | Line 496: | ||
text en "point u: | text en "point u: | ||
- | | + | |
+ | ===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 metapost | ||
+ | % a spinning compass | ||
+ | def p_u_magnetism (expr P,R,S,A)= | ||
+ | scale: | ||
+ | halfline: | ||
+ | pointheight: | ||
+ | pointwidth: | ||
+ | U: | ||
+ | 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, | ||
+ | % black triangle outline | ||
+ | thdraw (0, | ||
+ | thdraw (0, | ||
+ | % spin arcs, a full circle is path 0-8, anticlockwise, | ||
+ | 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(" | ||
+ | endcode | ||
+ | </ | ||
+ | |||
+ | {{ :: | ||
+ | |||
+ | Select this as point type " | ||
+ | |||
+ | text en "point u: | ||
====Line Symbols==== | ====Line Symbols==== | ||
===View whole centerline for underground=== | ===View whole centerline for underground=== | ||
Line 1016: | Line 1180: | ||
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 | + | The grid is made of horizontal |
- | **Code for blocks, | + | Various things could be improved. |
- | initsymbol(" | + | |
- | + | The settings can no be overridden by using < | |
- | def a_blocks_BCA (expr p) = | + | on each area, therefore having different types and density of blocks |
- | T: | + | |
- | | + | overlap <'' |
- | | + | Do the blocks overlap the border, if false an attempt is made to shink the block until it is inside or out\\ |
- | | + | Default false\\ |
- | | + | |
- | | + | separation <'' |
- | | + | Proportion to the size of separation of centres of the blocks as set out in a rectangular grid\\ |
- | | + | Default 0.7\\ |
- | | + | |
- | %Now set the proportions | + | block_random <'' |
- | b_tri:=1; | + | Max each point of the base block can be moved. Too big and they can intersect themselves\\ |
- | b_quad: | + | Default 0.7\ |
- | b_pent: | + | |
- | b_hex:=2; | + | base_rotation <'' |
- | pickup PenC; | + | 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\\ |
- | path q, regular, qq; q = bbox p; | + | Default 0\\ |
- | pair outside; | + | |
- | outside:= ulcorner q + up; | + | random_rotation <'' |
- | picture tmp_pic; | + | Rotation either side of base rotation eg 20 will be plus or minus 10 each side\\ |
- | uu := max(u, (xpart urcorner q - xpart llcorner q)/100, (ypart urcorner q - ypart | + | Default 360\\ |
- | iu := uu * block_rectangle; | + | |
- | blocks := b_tri+b_quad + b_pent + b_hex; | + | min_scale <'' |
- | tmp_pic := image( | + | Minimum multiplier used for the base shape\\ |
- | for i = xpart llcorner q step symbol_distance | + | Default 0.7\\ |
- | | + | |
- | | + | max_scale <'' |
- | | + | Added to the minimum multiplier to get the maximum scale\\ |
- | sides:=3; | + | Default 0.6\\ |
- | elseif pick_sides < b_tri + b_quad: | + | |
- | sides:=4; | + | aspect <'' |
- | elseif pick_sides < b_tri + b_quad +b_pent: | + | How much longer the block is than it is wide, before randomising\\ |
- | sides:=5; | + | Default 1.5\\ |
- | else: | + | |
- | sides:=6 | + | shift_random <'' |
- | fi; | + | Max random amount block can be moved from the original grid\\ |
- | + | Deafult 0.75\\ | |
- | | + | |
- | | + | shapes <'' |
- | endfor cycle; %radius is 0.5 divide by 2 | + | Set the ratio of different sided block, triangle, square, pentagon, hexagon. Must be single digits\\ |
- | | + | Default 1,3,4,2 |
- | | + | |
- | | + | |
- | | + | **Code for blocks** |
- | | + | < |
- | + | initsymbol (" | |
- | + | ||
- | | + | def a_blocks_BCA (expr p) = |
- | exitif xpart (p intersectiontimes qq) < 0; | + | |
- | qq:= qq scaled (0.99 ); | + | |
- | | + | %Derived from one of the built in blocks symbols |
- | | + | %No error checking on the attr so can break badly |
- | | + | % Andrew Atkinson 2019 |
- | | + | |
- | | + | %Do the blocks overlap the border, if false an attempt is made to shink the block until it is inside or out |
- | thclean qq; | + | boolean overlap; |
- | thdraw qq; | + | overlap:= |
- | fi; | + | if known ATTR_overlap: |
- | | + | else: false fi; |
- | endfor; | + | |
- | ); | + | % Proportion to the size of separation of centres of the blocks as set out in a rectangular grid |
- | clip tmp_pic to p; | + | %FIXME: Really need to check if it is number and not zero in for some cases |
- | drawoptions(); | + | separation:= |
- | draw tmp_pic; | + | if known ATTR_separation: |
- | enddef; | + | 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: | ||
+ | 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: | ||
+ | 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: | ||
+ | else: 360 | ||
+ | fi; | ||
+ | |||
+ | % Minimum multiplier used for the base shape | ||
+ | |||
+ | min_scale_factor:= | ||
+ | if known ATTR_min_size: | ||
+ | else: 0.7 | ||
+ | fi; | ||
+ | |||
+ | % Added to the minimum multiplier to get the maximum scale | ||
+ | add_scale_factor:= | ||
+ | if known ATTR_max_size: | ||
+ | else: 0.6 | ||
+ | fi; | ||
+ | |||
+ | % How much longer the block is than it is wide, before randomising | ||
+ | aspect:= | ||
+ | if known ATTR_aspect: | ||
+ | else: 1.5 | ||
+ | fi; | ||
+ | |||
+ | % Max random amount block can be moved from the original grid | ||
+ | shift_random: | ||
+ | if known ATTR_shift_random: | ||
+ | else: 0.75 | ||
+ | fi; | ||
+ | |||
+ | % Set the propotions | ||
+ | if known ATTR_shapes: | ||
+ | b_tri: | ||
+ | b_quad: | ||
+ | b_pent: | ||
+ | b_hex: | ||
+ | else: | ||
+ | b_tri:=1; | ||
+ | b_quad: | ||
+ | b_pent: | ||
+ | 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 | ||
+ | iu := uu * aspect; | ||
+ | blocks := b_tri+b_quad + b_pent + b_hex; | ||
+ | tmp_pic := image( | ||
+ | | ||
+ | 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(" | ||
+ | %} | ||
+ | |||
+ | | ||
+ | | ||
+ | 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)); | ||
+ | | ||
+ | | ||
+ | randomized (block_random * uu)) | ||
+ | scaled (uniformdeviate(add_scale_factor)+min_scale_factor) | ||
+ | | ||
+ | shifted ((i,j) randomized (shift_random * uu)); | ||
+ | | ||
+ | qq := punked | ||
+ | randomized (block_random | ||
+ | scaled (uniformdeviate(add_scale_factor)+min_scale_factor) | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | randomized (block_random | ||
+ | scaled (uniformdeviate(add_scale_factor)+min_scale_factor) | ||
+ | rotated (base_rotation + random_rotation / 2 - uniformdeviate(random_rotation) ) | ||
+ | shifted ((i,j) randomized (shift_random | ||
+ | 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 | ||
+ | | ||
+ | | ||
+ | endfor; | ||
+ | fi | ||
+ | | ||
+ | | ||
+ | | ||
+ | fi; | ||
+ | endfor; | ||
+ | | ||
+ | ); | ||
+ | % clip tmp_pic to p; %this appears not to be needed as the pointinside removes any outside the area | ||
+ | | ||
+ | draw tmp_pic; | ||
+ | enddef; | ||
+ | </ | ||
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 1092: | Line 1375: | ||
using the settings | using the settings | ||
- | + | < | |
- | | + | area blocks -attr shapes 1,2,4,7 -attr seperation |
- | block_randomisation: | + | </ |
- | | + | |
- | | + | |
- | min_scale_factor: | + | |
- | add_scale_factor: | + | |
- | block_rectangle: | + | |
- | | + | |
- | %Now set the propotions of different sided block | + | |
- | b_tri:=1; | + | |
- | b_quad: | + | |
- | b_pent: | + | |
- | b_hex:=7; | + | |
Line 1563: | Line 1835: | ||
draw (tmpl-0.25*u/ | draw (tmpl-0.25*u/ | ||
+ | ===Scalebar 3=== | ||
+ | {{: | ||
+ | |||
+ | layout LayoutScalebar3 # Scalebar by Chris Hayes | ||
+ | code metapost | ||
+ | def s_scalebar (expr l, units, txt) = | ||
+ | begingroup | ||
+ | interim warningcheck: | ||
+ | tmp05:=5 * (l / Scale * cm * units / 100); | ||
+ | tmp10: | ||
+ | tmp20: | ||
+ | tmp40: | ||
+ | tmp60: | ||
+ | tmp80: | ||
+ | tmp100: | ||
+ | scal05: | ||
+ | scal10: | ||
+ | scal20: | ||
+ | scal40: | ||
+ | scal60: | ||
+ | scal80: | ||
+ | brht:= 5bp; | ||
+ | lblht:= 8bp; | ||
+ | endgroup; | ||
+ | pickup PenC; | ||
+ | draw (0, | ||
+ | draw (tmp05, | ||
+ | draw (tmp10, | ||
+ | draw (tmp20, | ||
+ | draw (tmp40, | ||
+ | draw (tmp60, | ||
+ | draw (tmp80, | ||
+ | fill (tmp05, | ||
+ | fill (tmp20, | ||
+ | fill (tmp60, | ||
+ | begingroup | ||
+ | label.top(thTEX(decimal (l) & " | ||
+ | label.top(thTEX(decimal (scal80)), | ||
+ | label.top(thTEX(decimal (scal60)), | ||
+ | label.top(thTEX(decimal (scal40)), | ||
+ | label.top(thTEX(decimal (scal20)), | ||
+ | label.top(thTEX(decimal (scal10)), | ||
+ | label.top(thTEX(decimal (scal05)), | ||
+ | label.top(thTEX(decimal (0)), | ||
+ | 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=== |