Dear knights,
I spent a few hours today with MetaPost and MetaFun, my first serious stab at Meta in many years, so I'm a virtual newbie (used PSTricks back in the LaTeX days). I am trying to basically duplicate the attached pdf graphic and need help with the following:
1. This code is pretty naive; how can I make it more efficient? Eg, can I make a global "scaled 1cm" declaration instead of repeating it so many times?
2. ConTeXt's alignment mechanism apparently does not work in MetaPost (alignment is commented); is there a workaround? ragged left needed for some labels.
3. What is the most efficient way to get labels to follow the diagonals as in the attached pdf?
Any tips/trick will be appreciated!
Best Idris ==================================== % output=pdf interface=en
\setupcolors[state=start]
\starttext
\noheaderandfooterlines
\startuseMPgraphic{square}
picture p ; p := dashpattern(on 1mm off 1mm) ;
label bot(btex %\hbox to 1.5cm {%\startalignment[left] \vbox{\hsize=1.2cm \ssxx\setupinterlinespace (0,0,0,0) \crlf Light \crlf Condensed Small \crlf Sans~Serif} %\stopalignment } etex, (-1.2cm,0)) ;
draw (origin -- (0,5) -- (5,5) -- (5,0) -- cycle) scaled 1cm withcolor .625red ;
%draw ((2,1) -- (2,6) -- (7,6) -- (7,1) -- cycle) %scaled 1cm withcolor .625red ;
draw ((2,6) -- (7,6)) scaled 1cm withcolor .625red ;
draw ((7,6) -- (7,1)) scaled 1cm withcolor .625red ;
draw ((2,6) -- (2,5)) scaled 1cm withcolor .625red ;
draw ((2,5) -- (2,1)) scaled 1cm withcolor .625red dashed p withpen pencircle scaled 0.4pt;
draw ((2,1) -- (5,1)) scaled 1cm withcolor .625red dashed p withpen pencircle scaled 0.4pt;
draw ((5,1) -- (7,1)) scaled 1cm withcolor .625red ;
draw ((0,5) -- (2,6)) scaled 1cm withcolor .625red ;
draw ((5,5) -- (7,6)) scaled 1cm withcolor .625red ;
draw ((5,0) -- (7,1)) scaled 1cm withcolor .625red ;
draw (origin -- (2,1 )) scaled 1cm withcolor .625red dashed p withpen pencircle scaled 0.4pt;
\stopuseMPgraphic
\startuseMPgraphic{2squares}
draw (origin -- (0,5) -- (5,5) -- (5,0) -- cycle) scaled 1cm withcolor .625red ;
draw ((2,1) -- (2,6) -- (7,6) -- (7,1) -- cycle) scaled 1cm withcolor .625red ;
draw ((0,5) -- (2,6)) scaled 1cm withcolor .625red ;
draw ((5,5) -- (7,6)) scaled 1cm withcolor .625red ;
draw ((5,0) -- (7,1)) scaled 1cm withcolor .625red ;
draw (origin -- (2,1 )) scaled 1cm withcolor .625red ;
draw ((10,0) -- (10,-5) -- (15,-5) -- (15,0) -- cycle) scaled 1cm withcolor .625red ;
draw ((12,1) -- (12,-4) -- (17,-4) -- (17,1) -- cycle) scaled 1cm withcolor .625red ;
draw ((10,0) -- (12,1)) scaled 1cm withcolor .625red ;
draw ((10,-5) -- (12,-4)) scaled 1cm withcolor .625red ;
draw ((15,-5) -- (17,-4)) scaled 1cm withcolor .625red ;
draw ((15,0) -- (17,1 )) scaled 1cm withcolor .625red ;
% map square to square
picture p ; p := dashpattern(on 1mm off 1mm) ;
draw ((0,5) -- (10,0)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
draw ((2,6) -- (12,1)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
draw ((0,0) -- (10,-5)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
draw ((2,1) -- (12,-4)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
draw ((5,5) -- (15,0)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
draw ((7,6) -- (17,1)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
draw ((5,0) -- (15,-5)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
draw ((7,1) -- (17,-4)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
\stopuseMPgraphic
\midaligned{\useMPgraphic{square}}
\hbox{}\blank[5*big]
\useMPgraphic{2squares}
\stoptext ====================================
On Thu, 29 Jun 2006, Idris Samawi Hamid wrote:
Dear knights,
I spent a few hours today with MetaPost and MetaFun, my first serious stab at Meta in many years, so I'm a virtual newbie (used PSTricks back in the LaTeX days). I am trying to basically duplicate the attached pdf graphic and need help with the following:
- This code is pretty naive; how can I make it more efficient? Eg, can I
make a global "scaled 1cm" declaration instead of repeating it so many times?
drawoptions(scaled 1cm) ; , see below.
- ConTeXt's alignment mechanism apparently does not work in MetaPost
(alignment is commented); is there a workaround? ragged left needed for some labels.
Use \framed for multiline labels. Infact, what I ususally do is
\forceMPTEXcheck{LABEL}
\startMPinclusions vardef LABEL@#(expr s, p)= label@#(textext("\framed[width=3cm,align=middle,frame=off,autowidth=force, strut=on]{" & s & "}"),p) enddef ; \stopMPinclusions
and then I can simply use
LABEL.bot("A big huge label that spans multiple lines", origin)
or
LABEL.bot("short",center)
It can be made more efficient using the new sometxt feature. But I do not understand the sometxt interaction completely.
- What is the most efficient way to get labels to follow the diagonals as in
the attached pdf?
remember, anything inside btex...etex or textext() is just a picture. So, you can do
picture p; p := textext("some label"); p := p rotatedaround (center, angle) ;
label.llft(p,center) ;
etc..
Any tips/trick will be appreciated!
Best Idris ==================================== % output=pdf interface=en
\setupcolors[state=start]
\starttext
\noheaderandfooterlines
\startuseMPgraphic{square}
picture p ; p := dashpattern(on 1mm off 1mm) ;
label bot(btex %\hbox to 1.5cm {%\startalignment[left] \vbox{\hsize=1.2cm \ssxx\setupinterlinespace (0,0,0,0) \crlf Light \crlf Condensed Small \crlf Sans~Serif} %\stopalignment } etex, (-1.2cm,0)) ;
Firstly use \textext("string") instead of btex ... etex (assuming you have a uptodate context).
For alignment, I find it easiest to use \framed. So in your case \framed[align=normal,width=1,5cm,font(forgot the switch)=\ssxx]{etc}
draw (origin -- (0,5) -- (5,5) -- (5,0) -- cycle) scaled 1cm withcolor .625red ;
%draw ((2,1) -- (2,6) -- (7,6) -- (7,1) -- cycle) %scaled 1cm withcolor .625red ;
draw ((2,6) -- (7,6)) scaled 1cm withcolor .625red ;
draw ((7,6) -- (7,1)) scaled 1cm withcolor .625red ;
draw ((2,6) -- (2,5)) scaled 1cm withcolor .625red ;
you can use
drawoptions(scaled 1cm withcolor .625red) ;
draw(...) ; draw(...) ; draw(...) ;
draw ((2,5) -- (2,1)) scaled 1cm withcolor .625red dashed p withpen pencircle scaled 0.4pt;
draw ((2,1) -- (5,1)) scaled 1cm withcolor .625red dashed p withpen pencircle scaled 0.4pt;
same here. Use drawoptions.
draw ((5,1) -- (7,1)) scaled 1cm withcolor .625red ;
draw ((0,5) -- (2,6)) scaled 1cm withcolor .625red ;
draw ((5,5) -- (7,6)) scaled 1cm withcolor .625red ;
draw ((5,0) -- (7,1)) scaled 1cm withcolor .625red ;
draw (origin -- (2,1 )) scaled 1cm withcolor .625red dashed p withpen pencircle scaled 0.4pt;
\stopuseMPgraphic
\startuseMPgraphic{2squares}
draw (origin -- (0,5) -- (5,5) -- (5,0) -- cycle) scaled 1cm withcolor .625red ;
draw ((2,1) -- (2,6) -- (7,6) -- (7,1) -- cycle) scaled 1cm withcolor .625red ;
draw ((0,5) -- (2,6)) scaled 1cm withcolor .625red ;
draw ((5,5) -- (7,6)) scaled 1cm withcolor .625red ;
draw ((5,0) -- (7,1)) scaled 1cm withcolor .625red ;
draw (origin -- (2,1 )) scaled 1cm withcolor .625red ;
draw ((10,0) -- (10,-5) -- (15,-5) -- (15,0) -- cycle) scaled 1cm withcolor .625red ;
draw ((12,1) -- (12,-4) -- (17,-4) -- (17,1) -- cycle) scaled 1cm withcolor .625red ;
draw ((10,0) -- (12,1)) scaled 1cm withcolor .625red ;
draw ((10,-5) -- (12,-4)) scaled 1cm withcolor .625red ;
draw ((15,-5) -- (17,-4)) scaled 1cm withcolor .625red ;
draw ((15,0) -- (17,1 )) scaled 1cm withcolor .625red ;
% map square to square
picture p ; p := dashpattern(on 1mm off 1mm) ;
draw ((0,5) -- (10,0)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
draw ((2,6) -- (12,1)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
draw ((0,0) -- (10,-5)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
draw ((2,1) -- (12,-4)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
draw ((5,5) -- (15,0)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
draw ((7,6) -- (17,1)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
draw ((5,0) -- (15,-5)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
draw ((7,1) -- (17,-4)) scaled 1cm dashed p withpen pencircle scaled 0.4pt withcolor .625red ;
\stopuseMPgraphic
I would also probably number the points, so that they are easier to refer to
pair z[];
z[1] := (0,0) ; z[2] := (0,5) ; z[3] := (5,0) ; z[4] := (5,5) ;
etc.
and then
draw (z[1]--z[2]--z[3]--z[4]--cycle) ;
etc.
\midaligned{\useMPgraphic{square}}
\hbox{}\blank[5*big]
\useMPgraphic{2squares}
\stoptext
If the graphic is to be used a figure in the document (and not an a background graphic of some overlay), you may also want to consider the new staticMPgraphic feature. See http://wiki.contextgarden.net/Mpgraphic for details. The advantage is that an external pdf containing the graphic is created once, and is simply included in subsequent runs. It is regenerated only if you make some change in the metapost code. So usually the compilation is faster.
Aditya
Thank you very much Aditya for your guidance:-) I am working through your suggestions and may have more questions soon...
On Thu, 29 Jun 2006 23:42:16 -0600, Aditya Mahajan adityam@umich.edu wrote:
For alignment, I find it easiest to use \framed. So in your case \framed[align=normal,width=1,5cm,font(forgot the switch)=\ssxx]{etc}
\framed and \setupframed do not seem to have font switching options, although \setupframedtexts and \start-\stopframedtexts do ([style=\ssxx,before=\setupinterlinespace]).
Indeed, \setupinterlinespace does not even work inside the argument to framed, e.g,
\framed[width=1.2cm,align=left,frame=off,autowidth=force,strut=on] {\ssxx\setupinterlinespace This is a test of interlinespace}
does not adjust the interlinespace (Is this a bug, Hans?)
What works so far is
\startMPenvironment \ssxx\setupinterlinespace \stopMPenvironment
in the preamble.
Thnx again for your help, still working through things so i may be back;-)
Best Idris
On Thu, 29 Jun 2006 23:42:16 -0600, Aditya Mahajan adityam@umich.edu wrote:
draw ((2,6) -- (2,5)) scaled 1cm withcolor .625red ;
you can use
drawoptions(scaled 1cm withcolor .625red) ;
draw(...) ; draw(...) ; draw(...) ;
"drawoptions(scaled 1cm withcolor .625red)"
does not apply the
"scaled 1cm"
part. Is there another macro that handles the global scaling?
Best Idris
Idris Samawi Hamid wrote:
On Thu, 29 Jun 2006 23:42:16 -0600, Aditya Mahajan adityam@umich.edu wrote:
draw ((2,6) -- (2,5)) scaled 1cm withcolor .625red ;
you can use
drawoptions(scaled 1cm withcolor .625red) ;
draw(...) ; draw(...) ; draw(...) ;
"drawoptions(scaled 1cm withcolor .625red)"
does not apply the
"scaled 1cm"
part. Is there another macro that handles the global scaling?
no, at the end say:
currentpicture := currentpicture scaled 1.2 ;
----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | fax: 038 477 53 74 | www.pragma-ade.com | www.pragma-pod.nl -----------------------------------------------------------------
On Fri, 30 Jun 2006 15:41:15 -0600, Hans Hagen pragma@wxs.nl wrote:
Idris Samawi Hamid wrote:
On Thu, 29 Jun 2006 23:42:16 -0600, Aditya Mahajan adityam@umich.edu wrote:
draw ((2,6) -- (2,5)) scaled 1cm withcolor .625red ;
you can use
drawoptions(scaled 1cm withcolor .625red) ;
draw(...) ; draw(...) ; draw(...) ;
"drawoptions(scaled 1cm withcolor .625red)"
does not apply the
"scaled 1cm"
part. Is there another macro that handles the global scaling?
no, at the end say:
currentpicture := currentpicture scaled 1.2 ;
Ok, but that enlarges everything the pen, the labels etc. i.e.,
draw ((2,6) -- (2,5)) scaled 1cm withcolor .625red ;
is not the same as
draw ((2,6) -- (2,5)) withcolor .625red ;
currentpicture := currentpicture scaled 1 cm ;
I did find the
u := 1cm; z[1] = (2u,6u) ;
method; is there another way, a macro perhaps?
Thnx and Best Idris
On 7/1/06, Idris Samawi Hamid wrote:
draw ((2,6) -- (2,5)) scaled 1cm withcolor .625red ;
is not the same as
draw ((2,6) -- (2,5)) withcolor .625red ;
currentpicture := currentpicture scaled 1 cm ;
I did find the
u := 1cm; z[1] = (2u,6u) ;
method; is there another way, a macro perhaps?
What about this one?
save u; numeric u; u = 1cm;
% point[x][y][z] x,y,z are coordinates (each one can be 1 or 2) % put one point to a fix location z111 = origin;
% same y coordinate y111 = y211; y121 = y221; y112 = y212; y122 = y222;
% same x coordinate x111 = x121; x112 = x122; x211 = x221; x212 = x222;
% face x211 - x111 = y121 - y111 = 5u;
% define the diagonals (you could define other relations instead) z112 - z111 = z122 - z121 = z212 - z211 = z222 - z221 = (2u,1u);
But you could also define them using something like
for i=0 upto 1: for j=0 upto 1: for k=0 upto 1: z[i][j][k] = (i+k*something,j+k*somethingelse) scaled u; endfor; endfor; endfor;
I guess that you could draw the dashed lines by only clipping the path.
Metapost is a magician. You almost never need to manually calculate anything!
Mojca
Hi, Mojca, Aditya, Hans, and all the MP gurus,
Thank you for all the help and advice.
On Fri, 30 Jun 2006 18:17:23 -0600, Mojca Miklavec mojca.miklavec.lists@gmail.com wrote:
I did find the
u := 1cm; z[1] = (2u,6u) ;
method; is there another way, a macro perhaps?
What about this one?
save u; numeric u; u = 1cm;
% point[x][y][z] x,y,z are coordinates (each one can be 1 or 2) % put one point to a fix location z111 = origin;
% same y coordinate y111 = y211; y121 = y221; y112 = y212; y122 = y222;
% same x coordinate x111 = x121; x112 = x122; x211 = x221; x212 = x222;
% face x211 - x111 = y121 - y111 = 5u;
% define the diagonals (you could define other relations instead) z112 - z111 = z122 - z121 = z212 - z211 = z222 - z221 = (2u,1u);
But you could also define them using something like
for i=0 upto 1: for j=0 upto 1: for k=0 upto 1: z[i][j][k] = (i+k*something,j+k*somethingelse) scaled u; endfor; endfor; endfor;
I guess that you could draw the dashed lines by only clipping the path.
Metapost is a magician. You almost never need to manually calculate anything!
Wow... Ok, following is my present, still naive code. What I would like to be able to do is
1) In the first figure [square], control the relation of the front and back face of the cube by a single parameter. So if I use z for the front face coordinates, I can use z' for the rear face and define z' as a function of z. Then the angle of the z111--z'111 diagonal wrt the x-axis will change, and the label for that axis will have to change as well. I've been manually calculating inverse tangents to do this but can it be done automatically?
2. In the second figure, to in addition control the distance between the 2 cubes by a single parameter without recalculating the dashed lines mapping the two.
I only started yesterday but i can see that MetaPost is going to turn me into a junkie if I'm not careful :-)
Any other suggestions for improving/streamlining this is greatly appreciated: I think it will make a nice example case for beginners/on the wiki when done!
Best Idris
=============meta-test.tex=========== % output=pdf interface=en \setuppapersize[letter][letter] \setupcolors[state=start] \setuppagenumbering[state=stop]
\def\AXIS#1#2#3{(#1) Axis #2: {\bf #3}}
\forceMPTEXcheck{LABELL} \forceMPTEXcheck{LABELR} \forceMPTEXcheck{LABELM}
\startMPenvironment \ssxx\setupinterlinespace \stopMPenvironment
\startMPinclusions vardef LABELL@#(expr s, p)= label@#(textext("% \framed[width=1.5cm,align=left,frame=off,autowidth=force,strut=on]{" & s & "}"),p) enddef ;
vardef LABELR@#(expr s, p)= label@#(textext("% \framed[width=1.5cm,align=right,frame=off,autowidth=force,strut=on]{" & s & "}"),p) enddef ;
vardef LABELM@#(expr s, p)= label@#(textext("% \framed[align=middle,frame=off,autowidth=force,strut=on]{" & s & "}"),p) enddef ;
picture p ; p := dashpattern(on 1mm off 1mm) ;
\stopMPinclusions
\startstaticMPfigure{square}
u := 1.4cm;
z[1] = origin ; z[2] = (0,5u) ; z[3] = (5u,5u) ; z[4] = (5u,0) ; z[5] = (2u,1.25u) ; z[6] = (2u,6.25u) ; z[7] = (7u,6.25u) ; z[8] = (7u,1.25u) ; z[9] = (2u,5u) ; z[10] = (5u,1.25u) ; z[11] = (2.5u,0) ; z[12] = (-.17u,1.2u) ; z[13] = (1u,0.15u) ;
drawoptions(withcolor .625red withpen pencircle scaled 0.4pt) ;
draw (z[1] -- z[2] -- z[3] -- z[4] -- cycle) ; draw (z[6] -- z[7]) ; draw (z[7] -- z[8]) ; draw (z[6] -- z[9]) ; draw (z[10] -- z[8]) ; draw (z[2] -- z[6]) ; draw (z[3] -- z[7]) ; draw (z[4] -- z[8]) ;
drawoptions(withcolor .625red dashed p withpen pencircle scaled 0.4pt) ;
draw (z[1] -- z[5]) ; draw (z[9] -- z[5]) ; draw (z[5] -- z[10]) ;
drawoptions(withcolor black) ;
LABELL.llft("(0,0,0,0) Light Condensed Small Sans~Serif", z[1]) ; LABELL.llft("(0,1,0,0) Light Extended Small Sans~Serif", z[2]) ; LABELR.lrt ("(1,1,0,0) Bold Extended Small Sans~Serif", z[3]) ; LABELR.lrt ("(1,0,0,0) Bold Condensed Small Sans~Serif", z[4]) ;
LABELR.urt("(0,0,1,0) Light Condensed Large Sans~Serif", z[5]) ; LABELR.urt("(0,1,1,0) Light Extended Large Sans~Serif", z[6]) ; LABELR.urt("(1,1,1,0) Bold Extended Large Sans~Serif", z[7]) ; LABELR.urt("(1,0,1,0) Bold Condensed Large Sans~Serif", z[8]) ;
LABELM.bot ("\AXIS{x}{1}{Weight}", z[11]);
picture p; p := textext("\framed[align=middle,frame=off,autowidth=force,strut=on]% {\AXIS{y}{2}{Width}}"); p := p rotatedaround (z[12], 90) ;
label.top(p,z[12]);
picture p; p := textext("\AXIS{z}{3}{Optical Size}"); p := p rotatedaround (z[13], 32.005) ; % inv tan(1.5/2)
label.top(p,z[13]);
currentpicture := currentpicture scaled 0.9 ;
\stopstaticMPfigure
\startstaticMPfigure{2squares}
u := 0.7cm;
z[1] = origin ; z[2] = (0,5u) ; z[3] = (5u,5u) ; z[4] = (5u,0) ; z[5] = (2u,1.25u) ; z[6] = (2u,6.25u) ; z[7] = (7u,6.25u) ; z[8] = (7u,1.25u) ;
z[11] = (10u,-2.5u) ; z[12] = (10u,2.5u) ; z[13] = (15u,2.5u) ; z[14] = (15u,-2.5u) ; z[15] = (12u,-1.25u) ; z[16] = (12u,3.75u) ; z[17] = (17u,3.75u) ; z[18] = (17u,-1.25u) ;
z[19] = (3.125u,3.125u) ; z[20] = (13.125u,0.625u) ; z[21] = (5u,-1.25u) ;
drawoptions(withcolor .625red withpen pencircle scaled 0.4pt) ;
draw (z[1] -- z[2] -- z[3] -- z[4] -- cycle) ; draw (z[5] -- z[6] -- z[7] -- z[8] -- cycle) ; draw (z[1] -- z[5]) ; draw (z[2] -- z[6]) ; draw (z[3] -- z[7]) ; draw (z[4] -- z[8]) ;
draw (z[11] -- z[12] -- z[13] -- z[14] -- cycle) ; draw (z[15] -- z[16] -- z[17] -- z[18] -- cycle) ; draw (z[11] -- z[15]) ; draw (z[12] -- z[16]) ; draw (z[13] -- z[17]) ; draw (z[14] -- z[18]) ;
% map square to square
drawoptions(withcolor .625red dashed p withpen pencircle scaled 0.4pt) ;
draw (z[1] -- z[11]) ; draw (z[2] -- z[12]) ; draw (z[3] -- z[13]) ; draw (z[4] -- z[14]) ; draw (z[5] -- z[15]) ; draw (z[6] -- z[16]) ; draw (z[7] -- z[17]) ; draw (z[8] -- z[18]) ;
% labels
drawoptions(withcolor black) ;
label (textext("Sans Serif"),z[19]) ; label (textext("Serif"),z[20]) ;
picture p; p := textext("\AXIS{a}{4}{Serif}"); p := p rotatedaround (z[21], -14.036) ;
label.bot(p,z[21]);
currentpicture := currentpicture scaled 0.9 ;
\stopstaticMPfigure
\starttext
\midaligned{\usestaticMPfigure[square]}
\blank[2*big]
\midaligned{\usestaticMPfigure[2squares]}
\stoptext =====================================
On 7/1/06, Idris Samawi Hamid wrote:
A question for Hans first: how can something similar be used for \sometxt?
\startMPenvironment \ssxx\setupinterlinespace \stopMPenvironment
(\setupsometxt[before=,after=] ?)
Wow... Ok, following is my present, still naive code. What I would like to be able to do is
- In the first figure [square], control the relation of the front and
back face of the cube by a single parameter. So if I use z for the front face coordinates, I can use z' for the rear face and define z' as a function of z. Then the angle of the z111--z'111 diagonal wrt the x-axis will change, and the label for that axis will have to change as well. I've been manually calculating inverse tangents to do this but can it be done automatically?
- In the second figure, to in addition control the distance between the 2
cubes by a single parameter without recalculating the dashed lines mapping the two.
See the example. You only have to change diag1 and diag2.
I only started yesterday but i can see that MetaPost is going to turn me into a junkie if I'm not careful :-)
I can only warn you!
Here's the second square as an example without calculating the coordinates.
=============meta-test2.tex=========== % output=pdf interface=en \setupcolors[state=start] \setuppagenumbering[state=stop]
\def\AXIS#1#2#3{(#1) Axis #2: {\bf #3}}
\forceMPTEXcheck{LABELL} \forceMPTEXcheck{LABELR} \forceMPTEXcheck{LABELM}
\startMPenvironment \ssxx\setupinterlinespace \stopMPenvironment
\startMPinclusions vardef LABELL@#(expr s, p)= label@#(textext("% \framed[width=1.5cm,align=left,frame=off,autowidth=force,strut=on]{" & s & "}"),p) enddef ;
vardef LABELR@#(expr s, p)= label@#(textext("% \framed[width=1.5cm,align=right,frame=off,autowidth=force,strut=on]{" & s & "}"),p) enddef ;
vardef LABELM@#(expr s, p)= label@#(textext("% \framed[align=middle,frame=off,autowidth=force,strut=on]{" & s & "}"),p) enddef ;
picture p ; p := dashpattern(on 1mm off 1mm) ; color mycolor; mycolor = .625red;
\stopMPinclusions
\startstaticMPfigure{2squares} u := 0.7cm; a := 5; pair diag[]; diag1 = (2,1.25); diag2=(10,-2.5);
for i=0 upto 1: for j=0 upto 1: for k=0 upto 1: for l=0 upto 1: z[i+2j+4k+8l] = (((i,j) scaled a) shifted (diag1 scaled k) shifted (diag2 scaled l)) scaled u; endfor; endfor; endfor; endfor;
for i=0 upto 3: drawoptions(withcolor mycolor withpen pencircle scaled 0.4pt) ; % four squares draw z[4i]--z[4i+1]--z[4i+3]--z[4i+2]--cycle; % small diagonals draw z[i]--z[i+4]; draw z[i+8]--z[i+12];
drawoptions(withcolor mycolor dashed p withpen pencircle scaled 0.4pt); % dashed lines draw z[i]--z[i+8]; draw z[i+4]--z[i+12]; endfor;
drawoptions(withcolor black);
label (textext("Sans Serif"),.5[z[3],z[4]]) ; label (textext("Serif"),.5[z[11],z[12]]) ;
picture p; p := textext("\AXIS{a}{4}{Serif}") rotated angle(diag2); label.bot(p,.5[z[0],z[8]]);
\stopstaticMPfigure
\starttext \midaligned{\usestaticMPfigure[2squares]} \stoptext =====================================
Hi Mojca,
On Fri, 30 Jun 2006 22:33:41 -0600, Mojca Miklavec mojca.miklavec.lists@gmail.com wrote:
Here's the second square as an example without calculating the coordinates.
=============meta-test2.tex===========
Thank you very much; I will study this example very carefully.
Thnx again for the lesson in MP and all the
Best Idris
On Fri, 30 Jun 2006, Idris Samawi Hamid wrote:
Hi, Mojca, Aditya, Hans, and all the MP gurus,
Thank you for all the help and advice.
On Fri, 30 Jun 2006 18:17:23 -0600, Mojca Miklavec mojca.miklavec.lists@gmail.com wrote:
Wow... Ok, following is my present, still naive code. What I would like to be able to do is
- In the first figure [square], control the relation of the front and
back face of the cube by a single parameter. So if I use z for the front face coordinates, I can use z' for the rear face and define z' as a function of z. Then the angle of the z111--z'111 diagonal wrt the x-axis will change, and the label for that axis will have to change as well. I've been manually calculating inverse tangents to do this but can it be done automatically?
angle(...).
- In the second figure, to in addition control the distance between the 2
cubes by a single parameter without recalculating the dashed lines mapping the two.
See code below.
I only started yesterday but i can see that MetaPost is going to turn me into a junkie if I'm not careful :-)
Any other suggestions for improving/streamlining this is greatly appreciated: I think it will make a nice example case for beginners/on the wiki when done!
I do not have an ingeneous solution like Mojca. I will do this in a brute force way like you, but using loops for repetitive tasks and allowing metapost to do all the calculations for me.
\setuppapersize[letter][letter] \setupcolors[state=start] \setuppagenumbering[state=stop]
\def\AXIS#1#2#3{(#1) Axis #2: {\bf #3}}
\forceMPTEXcheck{LABELL} \forceMPTEXcheck{LABELR} \forceMPTEXcheck{LABELM}
\startMPenvironment \ssxx\setupinterlinespace \stopMPenvironment
\startMPinclusions vardef LABELL@#(expr s, p)= label@#(textext("% \framed[width=1.5cm,align=left,frame=off,autowidth=force,strut=on]{" & s & "}"),p) enddef ;
vardef LABELR@#(expr s, p)= label@#(textext("% \framed[width=1.5cm,align=right,frame=off,autowidth=force,strut=on]{" & s & "}"),p) enddef ;
vardef LABELM@#(expr s, p)= label@#(textext("% \framed[align=middle,frame=off,autowidth=force,strut=on]{" & s & "}"),p) enddef ;
picture my_dash ; my_dash := dashpattern(on 1mm off 1mm) ;
% my_dash is more verbose than p.
\stopMPinclusions
\startstaticMPfigure{square} numeric u ; u := 1.4cm; % Always declare the type of a variable. Helps in debugging.
path p; p := unitsquare scaled 5u ; % Identify the corners z[1] = llcorner p ; z[2] = ulcorner p ; z[3] = urcorner p ; z[4] = lrcorner p ; % Identify the corners of the shifted rectangle for i = 5 upto 8: z[i] = z[i-4] shifted (2u, 1.25u) ; endfor ; % Find the intersection points z[9] = whatever[z[5],z[6]] = whatever[z[2],z[3]] ; z[10] = whatever[z[5],z[8]] = whatever[z[3],z[4]] ; % Axis location % No need to calculate these explicitly, you can as well use % label(p, 0.5[...]) ; z[11] = 0.5[z[1],z[4]] ; z[12] = 0.5[z[1],z[2]] ; z[13] = 0.5[z[1],z[5]] ; % z[13] = (1u,0.15u) ; Not sure which point you had calculated.
drawoptions(withcolor .625red withpen pencircle scaled 0.4pt) ;
draw p ; draw (z[6] -- z[7]) ; draw (z[7] -- z[8]) ; draw (z[6] -- z[9]) ; draw (z[10] -- z[8]) ; % draw (z[2] -- z[6]) ; % draw (z[3] -- z[7]) ; % draw (z[4] -- z[8]) ; for i = 2 upto 4 : draw(z[i] -- z[i+4]) ; endfor ; drawoptions(withcolor .625red dashed my_dash withpen pencircle scaled 0.4pt) ;
% draw (z[1] -- z[5]) ; % draw (z[9] -- z[5]) ; % draw (z[5] -- z[10]) ; for i = 1,9,10 : draw(z[5] -- z[i] ) ; endfor ;
drawoptions(withcolor black) ; LABELL.llft("(0,0,0,0) Light Condensed Small Sans~Serif", z[1]) ; LABELL.llft("(0,1,0,0) Light Extended Small Sans~Serif", z[2]) ; LABELR.lrt ("(1,1,0,0) Bold Extended Small Sans~Serif", z[3]) ; LABELR.lrt ("(1,0,0,0) Bold Condensed Small Sans~Serif", z[4]) ;
LABELR.urt("(0,0,1,0) Light Condensed Large Sans~Serif", z[5]) ; LABELR.urt("(0,1,1,0) Light Extended Large Sans~Serif", z[6]) ; LABELR.urt("(1,1,1,0) Bold Extended Large Sans~Serif", z[7]) ; LABELR.urt("(1,0,1,0) Bold Condensed Large Sans~Serif", z[8]) ;
LABELM.bot ("\AXIS{x}{1}{Weight}", z[11]);
picture p; p := textext("\framed[align=middle,frame=off,autowidth=force,strut=on]% {\AXIS{y}{2}{Width}}"); p := p rotatedaround (z[12], 90) ;
label.lft(p,z[12]);
p := textext("\AXIS{z}{3}{Optical Size}"); p := p rotatedaround (z[13], angle(z[5]-z[1])) ; % inv tan(1.5/2) % Let metapost calculate it for you
% Ugly kludge label(p,z[13]+(0,2labeloffset));
% currentpicture := currentpicture scaled 0.9 ; % Why? Either change u, or use scaled= option in \usestaticMPfigure
\stopstaticMPfigure
\startstaticMPfigure{2squares}
numeric u ; u := 0.7cm; path p; p := unitsquare scaled 5u ; % Identify the corners z[1] = llcorner p ; z[2] = ulcorner p ; z[3] = urcorner p ; z[4] = lrcorner p ; % Identify the corners of the shifted rectangle for i = 5 upto 8: z[i] = z[i-4] shifted (2u, 1.25u) ; endfor ;
for i = 11 upto 18: z[i] = z[i-10] shifted (10u,-2.5u) ; endfor ;
z[19] = (3.125u,3.125u) ; z[20] = (13.125u,0.625u) ; z[21] = (5u,-1.25u) ;
drawoptions(withcolor .625red withpen pencircle scaled 0.4pt) ;
for i = 0,10: draw (z[i+1] -- z[i+2] -- z[i+3] -- z[i+4] -- cycle) ; draw (z[i+5] -- z[i+6] -- z[i+7] -- z[i+8] -- cycle) ; draw (z[i+1] -- z[i+5]) ; draw (z[i+2] -- z[i+6]) ; draw (z[i+3] -- z[i+7]) ; draw (z[i+4] -- z[i+8]) ; endfor ;
% Remove repetitions % draw (z[11] -- z[12] -- z[13] -- z[14] -- cycle) ; % draw (z[15] -- z[16] -- z[17] -- z[18] -- cycle) ; % draw (z[11] -- z[15]) ; % draw (z[12] -- z[16]) ; % draw (z[13] -- z[17]) ; % draw (z[14] -- z[18]) ;
% map square to square
drawoptions(withcolor .625red dashed my_dash withpen pencircle scaled 0.4pt) ; for i = 1 upto 8 : draw z[i] -- z[i+10] ; endfor ;
% draw (z[1] -- z[11]) ; % draw (z[2] -- z[12]) ; % draw (z[3] -- z[13]) ; % draw (z[4] -- z[14]) ; % draw (z[5] -- z[15]) ; % draw (z[6] -- z[16]) ; % draw (z[7] -- z[17]) ; % draw (z[8] -- z[18]) ;
% labels
drawoptions(withcolor black) ;
label (textext("Sans Serif"),z[19]) ; label (textext("Serif"),z[20]) ;
picture p; p := textext("\AXIS{a}{4}{Serif}"); % p := p rotatedaround (z[21], -14.036) ; p := p rotatedaround (z[21], angle(z[11]-z[1])) ;
label.bot(p,z[21]);
% currentpicture := currentpicture scaled 0.9 ;
\stopstaticMPfigure
\starttext
\midaligned{\usestaticMPfigure[square]}
\blank[2*big]
\midaligned{\usestaticMPfigure[2squares]}
\stoptext
Aditya
Hi, Aditya,
Wow, Thanks for your suggestions; I will most certainly study both yours and Mojca's approaches (I must admit I'm still struggling with mastering Mojca's approach ;-). This is a real contribtion: once I'm done studying yours and Mojca's examples and am sure I understand them I intend to post all three solutions on the wiki with some explanations (a self-pedagogical exercise as well).
Thank you again. Take care and all the
Best Idris
On Wed, 05 Jul 2006 16:27:04 -0600, Aditya Mahajan adityam@umich.edu wrote:
I do not have an ingeneous solution like Mojca. I will do this in a brute force way like you, but using loops for repetitive tasks and allowing metapost to do all the calculations for me.
On 7/6/06, Idris Samawi Hamid wrote:
Hi, Aditya,
(I must admit I'm still struggling with mastering Mojca's approach ;-).
I guess that I should read this as "please comment your code better next time"
pair diag[]; diag1 = (2,1.25); diag2=(10,-2.5);
I used diag1 to define the translation between the front and the back face and diag2 to define the translation between the first and the second cube.
for i=0 upto 1: for j=0 upto 1: for k=0 upto 1: for l=0 upto 1: z[i+2j+4k+8l] = (((i,j) scaled a) shifted (diag1 scaled k) shifted (diag2 scaled l)) scaled u; endfor; endfor; endfor; endfor;
i is the counter for x axes: i=0 means left, i=1 means the right point j is the counter for y axes: j=0 means bottom, j=2 means the upper point
Original point will thus have coordinates (i,j) and we create 4 points (sorry, I'm leaving out the braces):
z2---z3 | | z0---z1
k is the counter for z axes: z=0 means the front face, z=1 means the back face
The original point(s) are translated for diag1: shifted (diag1 scaled k): if k=0, no translation is present, if k=1 it's translated to the back.
You then get additional 4 poins, namely
z6---z7 | | z4---z5
traslated for vector diag1 to form the back face.
Finally, you use the counter l for the first and the second cube. shifted (diag2 scaled l) doesn't do anything if l=0 ("shifted (diag scaled 0)" is same as "shifted (0,0)" which is identity) and translates the first cube into the second one when l=1.
z[...+8l] will number the points from 0 to 7 (depending on i,j,k) when l=1 and from 8 to 15 when l=1, so you get the same points with index of z increased for 8 if you're in the second cube.
for i=0 upto 3: draw z[4i]--z[4i+1]--z[4i+3]--z[4i+2]--cycle;
this will draw: - z0--z1--z3--z2--cycle (first cube, the front face) - z4--z5--z7--z6--cycle (first cube, the front face) - z8--z9--z11--z10--cycle (second cube, the front face) - z12--z13--z15--z14--cycle (second cube, the front face)
% small diagonals draw z[i]--z[i+4]; draw z[i+8]--z[i+12];
this will draw z0--z4, z1--z5, z2--z6, z3--z7: "diagonals" connecting the front face with back face and same for the second cube, only for z[index+8]
draw z[i]--z[i+8];
this will connect the fron face of the first cube with the fron face of the second cube (+8)
draw z[i+4]--z[i+12];
same, bu for the back face; this could be done with the first definition already if 'i' went from 0 to 7 instead from 0 to 3.
label (textext("Sans Serif"),.5[z[3],z[4]]) ;
z3 is the upper right point in the front face and z4 the lower left point in the back face, .5 is the point in the middle then.
label (textext("Serif"),.5[z[11],z[12]]) ;
z11 and z12 are the same points (3+8 and 4+8) on the second cube.
Hope that helps, Mojca
(Asymptote does some conversions directly since it supports 3D, but I never worked with it, most probably because it's not integrated so well with ConTeXt, although it seems a bit more optimistic in the last time.)
On Thu, 06 Jul 2006 08:39:04 -0600, Mojca Miklavec mojca.miklavec.lists@gmail.com wrote:
On 7/6/06, Idris Samawi Hamid wrote:
Hi, Aditya,
(I must admit I'm still struggling with mastering Mojca's approach ;-).
I guess that I should read this as "please comment your code better next time"
Thank you so much, Mojca, for your detailed explanations. It really helps me (and others for sure) get a handle on things!
All the Best Idris
On Wed, 5 Jul 2006, Aditya Mahajan wrote:
p := textext("\AXIS{z}{3}{Optical Size}"); p := p rotatedaround (z[13], angle(z[5]-z[1])) ; % inv tan(1.5/2) % Let metapost calculate it for you
% Ugly kludge label(p,z[13]+(0,2labeloffset));
This can be done neatly if one remembers that label is equivalent to draw thelabel. Hence,
p := textext("\AXIS{z}{3}{Optical Size}"); label.top(p,z[13]) rotatedaround (z[13], angle(z[5]-z[1]) ) ;
Aditya
On Thu, 29 Jun 2006 23:42:16 -0600, Aditya Mahajan adityam@umich.edu wrote:
I would also probably number the points, so that they are easier to refer to
pair z[];
z[1] := (0,0) ; z[2] := (0,5) ; z[3] := (5,0) ; z[4] := (5,5) ;
etc.
and then
draw (z[1]--z[2]--z[3]--z[4]--cycle) ;
etc.
Here I get the following error: ======================= ! Declared variable conflicts with previous vardef. <to be read again> ; l.153 pair z[];
? =======================
and also
======================= ! Improper `:=' will be changed to `='. <recently read> :=
l.155 z[1] := origin ; ? =======================
z[1] = origin ;
etc. works though. Is there any advantage to keeping the brackets instead of just z1 etc.?
Thnx again Idris
Dear syndicate,
Ok, here is a challenge: The following works (I thank Aditya for his help)
============================== \forceMPTEXcheck{LABEL} \startMPenvironment \ssxx\setupinterlinespace \stopMPenvironment
\startMPinclusions vardef LABEL@#(expr s, p)= label@#(textext("% \framed[width=1.5cm,align=left,frame=off,autowidth=force,strut=on]{" & s & "}"),p) enddef ;
LABEL.llft("(0,0,0,0) Light Condensed Small Sans~Serif", origin) ; ==============================
Suppose I want to define LABEL so that for
LABEL.llft LABEL.ulft
I get \framed[align=left], and for
LABEL.lrt LABEL.urt
I get \framed[align=right].
How do I adjust the definition of LABEL above?
Thank you Idris