scaling a line thickness in Metapost
I want to be able to select a different thickness of line for different "scale" values that can be selected in the .th2 file. Lines can have a scale like this, which seems perfect for what I need: -scale xs * Is there a way to access this value from within a custom line definition like this? def l_u_foo (expr P)= if ATTR_scale ... * Assuming it can be seen from some ATTR value, internal variabe or function parameter, what values will it see for the various -scale options (xs, s, m, l, xl) - if it is a number, what are the numeric values for the various scales, or if it is a string, does it just see the literal values "xs", "s" etc.? Cheers! Tarquin
Yes, I have long wanted control of line ornamentation size (as opposed to line thickness), with th2 statements like; line wall -scale xs... line floor-step xs... do not throw an error, but also do not have any effect on what is drawn. They seem not to be parsed to any of the standard line metapost code. I was playing with this idea in 2012 and got nowhere. What if you include the scale in a line definition, like is done with the standard point definitions, and work from there? def p_stalagmite_UIS(expr pos,theta,sc,al) = def l_wall_sand_SKBB (expr P) = So maybe def l_wall_sand_SKBB (expr P, sc) = if unknown sc: sc:=1; fi; %assuming parsing sc can be optional is a good start? Seems like it should not be too hard -:) I deduce that sc has already been converted from xs to 0.5 by something magic in the Therion code by the time it gets to metapost. I think scale m = 1, with the other values each scaled up or down by root 2. Therefore xs = 0.5, xl = 2.0 Good luck I’ll be watching with interest. Bruce
So maybe
def l_wall_sand_SKBB (expr P, sc) =
if unknown sc: sc:=1; fi; %assuming parsing sc can be optional
Right now it doesn't work - it claims that I am asking for non-existent parameters. I guess it would need a change in Therion to make it work. For now, you can make an equivalent like this: -attr scale xs Then in your metapost: string scale; if known ATTR_scale: scale:=ATTR_scale; else: scale:="m"; fi; This is reinventing the wheel since "-scale" is a real parameter that seems to exist but doesn't seem to get put anywhere useful. I would prefer not to reinvent the wheel, when something already exists for that purpose. But at least -attr exists to allow you to pass custom data into functions. The issue I have right now is that every bit of "def" code seems to share its variables with every other bit of "def" code. So each time you say "string scale", you are forcing *every* "scale" variable in all of Therion's Metapost code to be a string, even if some other piece of code is expecting it to be a number or whatever. (I can see that this same issue will creep into other people's Metapost examples on the wiki, and they will end up randomly trampling variables in other pieces of code. For example, Andrew's wonderful boulder code uses "boolean overlap;" without locally scoping that variable.) You can call the variable "string l_u_foo_scale;" which will then be very unlikely to clash with existing variables, but there has to be a way to make variables local within a def. (Apparently you can use "save" within a begingroup section to make variables local, so I am playing with that right now to see if I can work out how to use it. You cannot use vardef instead of def, because Therion relies on you having global variables like "T" and "u" within your def. It would be so much nicer if Metapost had a simple way to say "this variable is the local one, not a higher scoped one" like most other languages I know. It over-complicates this part.)
I think scale m = 1, with the other values each scaled up or down by root 2. Therefore xs = 0.5, xl = 2.0
Thanks for that info :)
Apparently you can use "save" within a begingroup section to make variables local, so I am playing with that right now to see if I can work out how to use it.
Easy enough: def l_u_foo begingroup; %allow local variables to work save scale, bar, baz; %declare local variables string scale; if known ATTR_scale: scale:=ATTR_scale; else: scale:="m"; fi; ... endgroup; enddef; I tried using vardef instead, but couldn't get it to work. "save" actually temporarily saves the existing (global) value of a variable, then restores is after the endgroup. But it has the effect of creating a local variable.
participants (2)
-
Bruce Mutton -
Tarquin Wilton-Jones