next up previous contents
Next: Tcl source for Up: Evolution of Facial Previous: Glossary

PostScript source for the 2-D facial model

%!PS-Adobe-3.0
%%Title: (Face)
%%
%%Creator: Andrew C. Bulhak <acb@cs.monash.edu.au>

% The basic code for drawing a face.
% Note: this is not a complete program; only the functions for drawing faces.
% To use, run this in the PostScript interpreter and then use the face operator
% to draw faces.

%% (theta) (r) (closedness) eye -- draws an eye centered at the origin, with a
%% specified degree of closedness

/eye {
  % draw lower, invariant half of eye
  % draw upper, variant half
  4 dict begin
    % top of stack contains degree of closedness
    dup /closedness exch def
    /makeeyepath {
      -1 0 moveto -1 -0.55 -0.55 -1 0 -1 curveto
      0.55 -1 1 -0.55 1 0 curveto
      1 cpy 0.55 ceny 0 ceny curveto -0.55 ceny -1 cpy -1 0 curveto 
    } def
    dup /cpy exch 2 mul 1 sub -0.55 mul def % y of control pts of upward curve
    /ceny exch 2 mul 1 sub neg def % 
    % here, the stack contains (theta) (r). We need to convert these
    % into (x) (y)
    % r is from 0 to 1. Convert to degrees.
    360 mul
    dup sin 2 index mul 3 1 roll cos mul
    makeeyepath stroke
    makeeyepath clip
    newpath 1 index 
    closedness neg 2 index add
    0.25 0 360 arc fill
    pop pop
  end
} def

%% sf co mouth -- draw a mouth with parameters as specified.
%% the mouth is drawn centered at the origin, with a bounding box of (-1,-1)..(1,1).

/mouth {
  16 dict begin
    /co exch def /sf exch def 
    0 sf -0.5 mul translate
    /ucpy co 45 mul sin 0.5 mul def        % upper spline control point y value
    /cnrx 1 co 0.15 mul sub def             % mouth corner x value
    /ctrllen 1 co sub 0.5 mul 0.25 add def % control line length
    /cp1x cnrx neg co 45 mul cos ctrllen mul add def  
    /cp2x cnrx co 45 mul cos ctrllen mul sub def
    /lcpy co 45 mul sin -0.5 mul def 
    /vy sf 2 mul 1 sub 0.5 mul def

    cnrx neg vy moveto cp1x ucpy cp2x ucpy cnrx vy curveto
    cp2x lcpy cp1x lcpy cnrx neg vy curveto closepath stroke
  end
} def


%% code for drawing an eyebrow, on the left side of the face.
%% (raiselower) eyebrow
%%
%% The way this code works is to handle the eyebrow as a spline. The
%% spline is always curved upwards, but the polarity of the parameter
%% determines which control point has the most magnitude.

/eyebrow {
  9 dict begin
    dup 45 mul /aparam exch def
    0 lt { % eyebrow raised
      /outmagn 0.5 def
      /inmagn 0 def
    } { %eyebrow lowered
      /outmagn 0 def
      /inmagn 0.5 def
    } ifelse
    /outx aparam cos outmagn mul -1 add def
    /inx aparam cos inmagn mul 1 exch sub def
    /outy aparam sin outmagn mul def
    /iny aparam sin inmagn mul def
    -1 0 moveto outx outy inx iny 1 0 curveto stroke
  end
} def


%%  face
%%  (brow) (brow) (eyetheta) (eyerad) (iclose) (eyetheta) (eyerad) (iclose) 
%%  (mthsf) (mthco) (mthsc) 
%%  (xrot) (yrot) (zrot) face

/face {
  8 dict begin
    /zrot exch 22.5 mul def 
    /yrot exch 22.5 mul def 
    /xrot exch 22.5 mul def
    % draw the outline
    /outline {newpath 0 0 1 0 360 arc} bind def
    outline stroke outline clip
%% handle mouth
    /mouthheight xrot 63 add sin 30 xrot sub sin add 2 div def
    gsave
      yrot sin xrot 15 sub sin translate 
      dup 0.625 mul mouthheight 2 index mul scale pop 
      mouth
    grestore
%% handle eyes
    /leyewidth -33 yrot add sin -4 yrot add sin sub abs 2 div def
    /reyewidth 33 yrot add sin 4 yrot add sin sub abs 2 div def
    /eyeheight 30 xrot add sin xrot sin sub 2 div def
    gsave
      leyewidth eyeheight scale yrot 18 sub sin 0.25 div xrot 15 
      add sin 0.25 div translate eye
    grestore
    gsave
      reyewidth eyeheight scale yrot 18 add sin 0.25 div xrot 15 
      add sin 0.25 div translate eye
    grestore
%% handle eyebrows
    gsave
      0.25 0.25 scale yrot 18 sub sin 0.25 div xrot 34 add sin 0.25 div 
      translate eyebrow
    grestore
    gsave
      -0.25 0.25 scale 18 yrot add sin -0.25 div xrot 34 add sin 0.25 div 
      translate eyebrow
    grestore
  end
} def


% rescale uniformly and set the line width to be equal to one unit beforehand

/rescale { dup dup scale 1 exch div setlinewidth } def

%% face definitions are defined as arrays, each containing a name and
%% a chromosome

/genename 
  [(brow) (itheta) (irad) (icl) (msf) (mco) (mscl) (xrot) (yrot) (zrot)] def



Andrew C Bulhak
Tue Nov 7 11:44:11 EST 1995