[Therion] metapost help - line Blocks

Andrew Atkinson andrew at wotcc.org.uk
Wed Sep 23 15:28:16 CEST 2015



On 23/09/15 13:59, Georg Pacher wrote:
> Hi Andrew,
> 
> First of all, i would suggest to use:
> st:= arctime (laenge+cur/2) of P; instead of
> st:= arctime (laenge+cur)/2 of P;
> for the direction of the last block. Otherwise this will use the
> direction near the middle of the path, and not at the location of the
> last block. But I am not sure if this is related to your issue.

Hmm that does not seem your suggestion if beyond the end of the path;
laenge is the total length of the path. But as you say this is not
affecting it.
> 
> I remember having this issue also back then, when generating the AUT
> symbol-set. Though I don't remember the details anymore, I believe it
> always had something to do with determining the scale_factor for the
> last block, or the calculated location for the last block.
> You can check that by adding the line "scale_factor" before "  if
> scale_factor > 0:", to print out the value of scale factor (when
> omitting the ';', it will print out the stated value). Then you should
> see if this value gets <=0 sometimes.
> But note that it is not feasible to do this on a big dataset, as there
> will be an enormous amount of output then.
> 
Fixed it and sent it to the printers just before lunch

The problem was that in

   # find next position where the block fits in without intersecting
the previous one
    forever:
      exitif xpart ( ((block--cycle) rotated angle(direction t of P)
shifted point t of P) intersectiontimes old_block) < 0;
      cur:=cur+0.01u;
      t:= arctime cur of P;
      st:= arctime (cur+block_width/2) of P;
      exitif cur > (laenge- 3*block_width/2);
    endfor;

If the newly generated block did not intersect the previous block on the
first attempt, the variables t and st did not get updated, moving them
up before the test fixed that. Thanks to Julian for helping me with
this. The final code is now (will try to add it to the wiki later)


def l_wall_blocks_CHED (expr P) =

  T:=identity;
  pickup PenC;
  laenge := arclength P;

  path block;
  path old_block;

  cur := 0;


  #draw first block
  old_block := punked ((
(.65u,-.15u)--(.72u,0.05u)--(.55u,.15u)--(.23u,.17u)--(.0u,.03u)--(.05u,-.1u))randomized
(0.1u))
             scaled (uniformdeviate(0.3)+.65);
  block_width := (xpart urcorner old_block - xpart ulcorner old_block);
  t:= arctime (cur+block_width/2) of P;
  old_block:=old_block rotated angle( direction t of P) shifted point 0
of P;
  thclean (old_block--cycle);
  thdraw old_block;


  cur := cur + block_width + 0.04u;

  forever:
    # generate random block
    block := punked(
((.65u,-.15u)--(.72u,0.05u)--(.55u,.15u)--(.2u,.17u)--(.0u,.03u)--(.05u,-.1u)randomized
(0.1u) ))
          scaled (uniformdeviate(0.3)+.65)
          rotated (uniformdeviate(20)-10);
    # check width of block
    block_width := (xpart urcorner block - xpart ulcorner block);

    exitif cur > (laenge- 3*block_width/2);
    # find next position where the block fits in without intersecting
the previous one
    forever:
      cur:=cur+0.01u;
      t:= arctime cur of P;
      st:= arctime (cur+block_width/2) of P;
      exitif cur > (laenge- 3*block_width/2);
      exitif xpart ( ((block--cycle) rotated angle(direction st of P)
shifted point t of P) intersectiontimes old_block) < 0;
    endfor;
    exitif cur > (laenge- 3*block_width/2);

    old_block:= block rotated angle(direction st of P) shifted point t of P;
    thclean (old_block--cycle);
    thdraw old_block;

  cur := cur + block_width + 0.04u;

  endfor;

    # generate last block

    block :=
(((.65u,-.15u)--(.72u,0.05u)--(.55u,.15u)--(.2u,.17u)--(.0u,.03u)--(.05u,-.1u))
);
    block_width := (xpart urcorner block - xpart ulcorner block);

    # scale last block to fit in the remaining gap
    scale_factor:=(laenge-cur)/block_width;
      t:= arctime cur of P;
      st:= arctime (laenge+cur)/2 of P;
    forever:
    exitif scale_factor < 0;
      exitif xpart ( ( (block) rotated angle (direction st of P) scaled
scale_factor shifted (point t of P) ) intersectiontimes old_block) < 0;
      scale_factor:=scale_factor-0.001;
    endfor;
    if scale_factor > 0:
      thclean (block--cycle) rotated angle (direction st of P) scaled
scale_factor shifted (point t of P);
      thdraw (block) rotated angle (direction st of P) scaled
scale_factor shifted (point t of P);
    fi;
enddef;



More information about the Therion mailing list