[alt.sources] [comp.sys.next] Superquadric .top file generator for TopologyLab

flynn@pixel.cps.msu.edu (Patrick J. Flynn) (02/07/90)

Archive-name: next-shaded-superquartic/06-Feb-90
Original-posting-by: flynn@pixel.cps.msu.edu (Patrick J. Flynn)
Original-subject: Superquadric .top file generator for TopologyLab
Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)

[This is an experimental alt.sources re-posting from the newsgroup(s)
comp.sys.next. Comments on this service to emv@math.lsa.umich.edu 
(Edward Vielmetti).]


I recently had the need to generate some shaded images of
superquadrics.  I was all ready to fire up Suntools and hack out
something quick and dirty, when I remembered the TopologyLab demo's
ability to read custom data files.  So I wrote a little ditty which
generates the mesh points from the superquad parameters.  To make
things more interesting, I added a twist operator, which does
differential rotation as a linear function of the z-coordinate of the
data point.  Then I added a tapering operator, which linearly tapers
the shape along the Z axis.  You get to set the scale for the twist and
taper operations.  In order to prevent reflections through the origin,
I translated the data points (prior to tapering) so that their
z-coordinates are positive.

The calling syntax is

sq grain e1 e2 twist taper >foo.top

where grain is the grain parameter (10 <= grain <= 100 according to the
TopologyLab help window), e1 and e2 govern the shape of the superquad,
twist is the twist scaling factor (i.e. the twist 'speed'), and taper
is the taper scaling factor.  Twist and taper default to 0, which mean
no twisting or tapering.

After generating a .top file, load it by hitting Custom in the
TopologyLab program.

Interesting (e1,e2) values are:
(1,1) sphere, (0.1,1) cylinder, (0.1,0.1) box, (2,1) double cone,
(2,2) double pyramid.

I particularly liked the look produced by
'sq 20 2 2 1 0 >foo.tmp'   (a Salvador Dali double pyramid).

Twisting and tapering may cause strange-looking shaded images.
If you crank up the twist & taper, you'll also have to crank up
the grain in order for the sampling to capture the deformations.

No guarantees, etc. [hey, it's free].  If anyone tacks new goodies
onto the program, I'd like to see them.

------------ snip snip
#include <math.h>
#include <stdio.h>

/* sq.c: generate data for a .top file (NeXT TopologyLab data) from
   a superquadric

   By P. Flynn, MSU CPS Dept., 2/90

   See Bajcsy & Solina, Proc. 1st Int Conf on Computer Vision (ICCV 87)
   for notation.
   See Alan Barr, SIGGRAPH '84, for global deformations.
*/

#define SIGN(x) (x<0.0)?-1.0:1.0

main(argc,argv)
  int argc;
  char *argv[];
  {

    /* usage: sq grain e1 e2 [twist taper]*/
    float e1,e2,twist=0.0,taper=0.0;
    int i,j,grain;

    if (argc < 4) {
      fprintf(stderr,"usage: sq grain e1 e2 [twist]>foo.top\n");
      exit(-1);
      };
    grain=atoi(argv[1]);
    e1=atof(argv[2]);
    e2=atof(argv[3]);
    if (argc>=5) twist=atof(argv[4]);
    if (argc>=6) taper=atof(argv[5]);
    fwrite(&grain,sizeof(int),1,stdout);
    for(i=0;i<grain;i++)
      for(j=0;j<grain;j++) {
        float eta=(i/(float)(grain-1)-0.5)*3.1416; /* eta, -pi/2 <= eta <= pi/2 */
        float omega=(j/(float)(grain-1)-0.5)*6.2832; /* omega, -pi <= omega <= pi */
        float seta=sin(eta),aseta=fabs(seta),sseta=SIGN(seta);
        float somega=sin(omega),asomega=fabs(somega),ssomega=SIGN(somega);
        float ceta=cos(eta),aceta=fabs(ceta),sceta=SIGN(ceta);
        float comega=cos(omega),acomega=fabs(comega),scomega=SIGN(comega);
        float w=sceta*pow(aceta,e1);
        float x=w*scomega*pow(acomega,e2);
        float y=w*ssomega*pow(asomega,e2);
        float z=sseta*pow(aseta,e1)+1.0;
        if (twist) {
          float tz=twist*z;
          float xx=x*cos(tz)-y*sin(tz);
          float yy=x*sin(tz)+y*cos(tz);
          x=xx;
          y=yy;
          };
        if (taper) {
          x *= taper*z;
          y *= taper*z;
          };
        fwrite(&x,sizeof(float),1,stdout);
        fwrite(&y,sizeof(float),1,stdout);
        fwrite(&z,sizeof(float),1,stdout);
        }
  }
---------snip snip
--
Patrick Flynn, CS, Michigan State University, flynn@cps.msu.edu

Remember Tiananmen Square.