For 2: I think Metafont makes more sense if you don't think of a macro
as a function that does some work in its own context and returns a
value, but as something that expands textually in place. So there
isn't any concept of "return" as there aren't separate stack frames to
return "from" or "to".
So you could try something like this (completely untested, and I am a
Metafont beginner. This is from memory, so check the book for the
right syntax, especially for the semicolons.)
def myPath(<args>) =
begingroup
save tr, tl, bl, br;
pair tr, tl, bl, br;
I've come up with a crude function that's doing more like what I want. I have two problems with it:
1. The most important: I need to differentiate the equations that generate a superellipse, in order to find the tangent at the defined vertices. I have failed to do this and so use a crude arbitrary power function. 2. Less important: what is the equivalent in METAFONT of the 'return' keyword? I just want superellipse() to return the shape, rather than draw it.
James
def superellipse(expr r,t,l,b,s)= pair tr, tl, bl, br; tr = (s[xpart t,xpart r],s[ypart r,ypart t]); tl = (s[xpart t,xpart l],s[ypart l,ypart t]); bl = (s[xpart b,xpart l],s[ypart l,ypart b]); br = (s[xpart b,xpart r],s[ypart r,ypart b]);
numeric theta;
if s > 0.5: % Behave as in the normal superellipse function theta = 0; else: % This is a crude mockup of the kind of function that is required % to generate shapes with s<0.5 (apparently called astroids). % This satisfies: % % s = 0.5, theta = 0.5 % s = 0, theta = 90 % % But to find the actual function, % we need to differentiate, at an endpoint, % the equation that would produce one quadrant of the shape.
theta = 90 - (s*s*s*7.11378661); fi
fill r{dir(90+theta)} ... tr{t-r} ... {dir(180-theta)}t & t{dir(180+theta)} ... tl{l-t} ... {dir(270-theta)}l & l{dir(270+theta)} ... bl{b-l} ... {dir(-theta)}b & b{dir(theta)} ... br{r-b} ... {dir(90-theta)}r & cycle; enddef;
beginfig(0); superellipse( ( 100, 50 ), ( 50, 100 ), ( 0, 50 ), ( 50, 0 ), 0.6 ); endfig;
end;
On Mon, Mar 1, 2010 at 4:20 PM, Rory Molinari
wrote: James's explanation appears to be right.
On p 126 of the METAFONTbook Knuth says that the "superness should be between 0.5 (when you get a diamond) and 1.0 (when you get a square)".
Exercise 14.6 asks the reader to "Try superellimpse with superness values less than 0.5 or greater than 1.0; explain why you get weird shapes in such cases." The answer is "There are inflection points, because there are no bounding triangles for the '...' operations in the superellipse macro ... unless 0.5 \leq s \leq 1."
Cheers, Rory
On Mon, Mar 1, 2010 at 8:04 AM, James Fisher
wrote: I should say that the vertices of the superellipse are calculated correctly. The problem, it seems, is that for the vertices at right, top, left, and bottom, the angles of entry and exit need to be explicitly defined, rather than just relying on the '...' which coincidentally works for s>=0.5.
I should say at this point that I am no maths whiz. But, sticking with the 'right ... topright ... top' line, the angle calculation needs to satisfy, for the exit angle of the first vertex:
For s=0, angle = 180 degrees (vector to the left) For s = 0.5, angle = 135 degrees (45 degrees to the top left, producing a straight line to create the diamond shape) For s>0.5, angle = 90 degrees (vector vertically upwards)
Suffice to say that I don't know how to produce that elegantly.
James
On Mon, Mar 1, 2010 at 3:54 PM, James Fisher
wrote: Hi again,
Another METAPOST problem. For the sake of curiosity, I've been looking at and playing with the superellipse() function in plain METAPOST. This is all fine and dandy until I try values of 'superness' less than 0.5, in which case it generates shapes that are seemingly not superellipses. At s=0.5, the function generates a diamond shape -- which, AFAIK, is correct. However, s<0.5, the points of the diamond immediately turn to curves. (My knowledge of superellipses here is just from http://en.wikipedia.org/wiki/Superellipse -- try the image at http://en.wikipedia.org/wiki/File:Lame_anima.gif to see how I expect the shape to change with varying values of superness).
Some code follows -- perhaps someone could run it and tell me if, for starters, they get the same as me. (See http://i49.tinypic.com/2ijqatl.jpg for superellipse() with s=0.3).
Best,
James
% The following is a superellipse function at
http://lists.foundry.supelec.fr/pipermail/metapost-commits/2008-June/000340....; % I think it's the superellipse function in my copy of METAPOST; it at least has the same behaviour. % It seems to calculate the vertices correctly, but not the way they join (try changing all ... to --). % %def superellipse(expr r,t,l,b,s)= % r ... (s[xpart t,xpart r],s[ypart r,ypart t]){t-r} ... % t ... (s[xpart t,xpart l],s[ypart l,ypart t]){l-t} ... % l ... (s[xpart b,xpart l],s[ypart l,ypart b]){b-l} ... % b ... (s[xpart b,xpart r],s[ypart r,ypart b]){r-b} ... cycle %enddef;
def supertest expr s = superellipse( ( 100, 50 ), ( 50, 100 ), ( 0, 50 ), ( 50, 0 ), s ); enddef;
% These >0 supernesses are fine, I think ...
beginfig(0); draw supertest 2; endfig;
beginfig(1); draw supertest 1.01; endfig;
% The following, 0.5>=superness<=1, % are from visual reference definitely right
beginfig(2); draw supertest 1; endfig;
beginfig(3); draw supertest 0.99; endfig;
beginfig(4); draw supertest 0.7; endfig;
beginfig(5); draw supertest 0.51; endfig;
beginfig(6); draw supertest 0.5; endfig;
% Now, for <0.5, % things get problematic -- % the points in the shape generated by s=0.5 % should stay 'pointy'
beginfig(7); draw supertest 0.49; endfig;
beginfig(8); draw supertest 0.3; endfig;
beginfig(9); draw supertest 0.01; endfig;
beginfig(10); draw supertest 0; endfig;
end;
___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context webpage : http://www.pragma-ade.nl / http://tex.aanhet.net archive : http://foundry.supelec.fr/projects/contextrev/ wiki : http://contextgarden.net
___________________________________________________________________________________
___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context webpage : http://www.pragma-ade.nl / http://tex.aanhet.net archive : http://foundry.supelec.fr/projects/contextrev/ wiki : http://contextgarden.net
___________________________________________________________________________________
___________________________________________________________________________________ If your question is of interest to others as well, please add an entry to the Wiki!
maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context webpage : http://www.pragma-ade.nl / http://tex.aanhet.net archive : http://foundry.supelec.fr/projects/contextrev/ wiki : http://contextgarden.net ___________________________________________________________________________________