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/09 09:25] – [Scalebars] Add Scalebar 3 brucemutton | metapost [2019/11/30 08:05] – Better anchor point tarquinwj | ||
---|---|---|---|
Line 297: | Line 297: | ||
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 1050: | Line 1110: | ||
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 1126: | Line 1305: | ||
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; | + | |