Docstoc

walker

Document Sample
walker Powered By Docstoc
					/***********************************************************
/* A program to generate symbolic walkers as dynamic, three dimensional /* color
graphic displays. We, the viewers, move into the seen in a
/* straight line, while our "gaze" is on this walker
/*
/*
/* The basis for this code was a program written by James E. Cutting,
/* published in Behavior Research Methods & Instrumentation (1978, Vol. /* 10
(1), 91-94), under the * title of "A program to generate synthetic /* walkers as *
dynamic point-light displays." The orginal program was * /* written in FORTAN 77
on a 32K Hewlett-Packard HP-100 * L-Series P /* for a Tektronix 604 monitor
display driven by a Data General Nova.
/*
/*      Modifications by J.E.C. beginning 23 Sept 91
/*      latest 18 Mar 92, Laurence Kaplan adaptation
/*
/***********************************************************/


/* attach the code to the 'C' libraries it requires */ #include <stdio.h>
/* standard input & output */
#include <values.h>
#include <gl.h>      /* graphics library */
#include <math.h> /* math functions           */
#include <device.h> /* interactive device */
#include <time.h>
#include <sys/types.h>       /* }     */
#include <sys/times.h>
#include <sys/time.h>        /* } time/timing functions */
#include <sys/param.h> /* }           */
#include <fmclient.h>

/* define the global constants */
/* math */
#define PI 3.1415926
#define RAD 0.017453292 /* degree to radian conversion constant */
#define DEG 57.29577951 /* radian to degree conversion constant */

/* body */
#define TORSO 85.0       /* height or length of torso */
#define SW 25.0  /* shoulder width */
#define HW 15.0  /* hip width */

/* walker object */
#define NUM_STEPS 6        /* number of steps to be taken by walker */
#define Z1 0.0      /* where in z-plane walker is to walk */
/* colors */
#define GROUND 1 /* color of ground plane in bkgnd scenery */
#define FIXTREE 9
#define TREECOLOR 10

/* viewing */
#define VISANG 300            /* cone of vision */
#define EYE_HT 255.0

/* forest */
#define NUMTR 60
#define NTRI 9   /* 8 plus 1 */


/* declare global variables */
/* the coords for cube object from which walker is created */

long side[6][4][3] ={{-1,-1,1}, {1,-1,1}, {1,1,1}, {-1,1,1},
{1,-1,1}, {1,-1,-1}, {1,1,-1}, {1,1,1},
{1,-1,-1}, {-1,-1,-1}, {-1,1,-1}, {1,1,-1},
{-1,-1,-1}, {-1,-1,1}, {-1,1,1}, {-1,1,-1},
{-1,1,1}, {1,1,1}, {1,1,-1}, {-1,1,-1},
{-1,-1,-1}, {1,-1,-1}, {1,-1,1}, {-1,-1,1}};


/* variables used by time functions */
struct tms t1;
long time1,time2;
double tim, starttim;

struct timeval tp;
struct timezone tzp;

float x,y,z,xx,zz,xx1,zz1;
int REDO,TRI,RESP,SDIR,SX,SZ,GRID,TREES,INCR,t,tt,tmod,j,OUT; char
fname[20];
FILE *fp,*fopen();
Coord rno[NUMTR][3];
int afile[NTRI][6];
int tord[NTRI];
int tinfo[NTRI][3] ={0,0,0,

/*     x       z angle        */

-4943, 0, 0,
/* in front and behind */
4943, 0, 180,

0, -4943, 90,
/*on either side*/
0, 4943, 270,

3445, -3445, 135,
/*in front and to the side*/
3445, 3445, 225,

-3445, -3445, 45,
/*behind and to the side*/
-3445, 3445, 315};


/* the graphical objects that make up the walker and scenery */ Object
cube,Groundplane,Floorgrid,Tree1,Cylinder;



/***************************************************************************
* MAIN function/procedure of the program              *
***************************************************************************/ main () {

/* declare functions */
void initialize_variables (),
setup_windows_graphics_devices (),
setup_underdraw(),
make_objects (),
ankle_table (),
get_hips (),
get_ankles (),
get_shoulders (),
get_wrists (),
get_knees (),
get_elbows (),
get_midpoint (),
clear_screen (),
draw_corpse (),
draw_head (),
draw_part (),
draw_torso (),
get_angle (),
locomotion (),
stop_and_wait (),
clean_up ();

/* declare variables */
float humor,ulna,tibia,femur,leg, /* lengths of body parts */
step, hstep, /* length of step, half-step */ hex, hey,      /* hip ellipses, x&y axes */
sex, sey,       /* shoulder ellipses,x&y-axes*/
sher, /* shoulder excursion as multiple of hip */
time, /* cmsec per frame */
bounce,         /* up & down mvt of body */
swf, /* femur swing */
swh, /* humor swing, f(sholder swing&step */
swu, /* ulna swing */
swt, /* tibia swing, 25=atan(foot/tibia) */
femfo, /* forward tilt of femur pendulum */
delay, /* degrees pre- and post-femur swing that tibia
swings due to foot & to compound pendulum */
cosff, /* y correction for hip */
xlean, ylean, /* upper body lean, f(speed), 2 deg modal */ xinit, yinit, /* initial x & y
values in screen units */ falfo,      /* mvt falling forwards w/in overlay period
due to tibia swing and foot */
sia[541];       /* ankle table, broad w-shaped, 0-540 deg. */
int    ip, ist; /* used for SWAPINTERVAL */

char ss[10];
int c,k;

fmfonthandle f;
fmfonthandle fsized;

/*     printf("filename = ");
scanf("%s",fname);
*/
/* main routines */

/* initialize the variables */
initialize_variables (&humor,&ulna,&femur,&tibia,&leg,&step,
&sher,&time,&hex,&hey,&sex,&sey,&swf,&swh,
&swu,&swt,&hstep,&bounce,&delay,&xlean,&ylean,
&xinit,&yinit,&falfo,&femfo,&cosff,&ip,&ist);

/* set up the windows, the graphics configuration, objects, etc. */
setup_windows_graphics_devices ();

/* generate the ankle table */
ankle_table (delay,sia);
rnorder();
/*for (t=1; t<NTRI; t++) printf("%5d",tord[t]);*/ color(BLACK);
clear();
swapbuffers();

for (TRI=1; TRI<NTRI; TRI++){

frontbuffer(TRUE);
color(WHITE);
ortho2 (0,1280,0,1009);
cmov2i(520,530);
sprintf(ss,"%d",TRI);

fminit();
f = fmfindfont("Times-Roman");
fsized = fmscalefont(f,36);
fmsetfont(fsized);
fmprstr("TRIAL");
cmov2i(700,530);
fmprstr(ss);

sleep(1);
frontbuffer(FALSE);

if (REDO == 0)
generatecoords();
qreset();

/* main loop(s) for the walker(s) */

t=tord[TRI];
xx=tinfo[t][0];
zz=tinfo[t][1];
SDIR=tinfo[t][2];

setup_underdraw();
locomotion (humor,ulna,femur,tibia,leg,step,
sher,time,hex,hey,sex,sey,swf,swh,
swu,swt,hstep,bounce,delay,xlean,ylean,
xinit,yinit,falfo,femfo,cosff,sia,ip,ist);

/* clean up the underlay plane so desktop/workspace isn't messed up */

qreset ();
while(qtest()) {}
processinput();
clean_up ();
clearscreen();
swapbuffers();
qreset();
sleep(1);

if (OUT == 1)
break;

afile[t][0]=xx;
afile[t][1]=zz;
afile[t][2]=SDIR;
afile[t][3]=RESP;
afile[t][4]=1;

if(t%2==(RESP-1)) afile[t][4]=0;
/*      printf("%3d %3d     ",TRI,t);
for (j=0; j<5; j++)
printf("%6d",afile[t][j]);
printf("\n");
*/
}

fp=fopen(fname,"w");
for (TRI=1; TRI<NTRI; TRI++){
for (j=0; j<5; j++)
fprintf(fp,"%6d",afile[TRI][j]);
fprintf(fp,"\n");
}
fclose(fp);
clearscreen ();
clear ();
}


/*********************************************************************
/* initialize the variables     *
**********************************************************************void
initialize_variables (humor,ulna,femur,tibia,leg,step,
sher,time,hex,hey,sex,sey,swf,swh,
swu,swt,hstep,bounce,delay,xlean,ylean,
xinit,yinit,falfo,femfo,cosff,ip,ist)
/* all of these values are R/W, and are explained in declarations above */

float *humor,*ulna,*femur,*tibia,*leg,*step,*sher,
*time,*hex,*hey,*sex,*sey,*swf,*swh,*swu,*swt,
*hstep,*bounce,*delay,*xlean,*ylean,*xinit,*yinit, *falfo,*femfo,*cosff;
int *ip,*ist;
{
float a, temp; /* for temporary storage */

*step=TORSO*0.975;
*hex=1.0;
*sher=3.0;
*hex=(*hex)*0.03*(*step);
*hey=(*hex)/1.5;

*sex=(*sher)*(*hex);
*sey=(*sex)/5.0;

*humor=TORSO*0.59;         /* length of upper arm */
*ulna=TORSO*0.56;          /* length of forearm */
*femur=TORSO*0.77;         /* length of upper leg */
*tibia=TORSO*0.77;/* length lower leg */
*leg=(*femur)+(*tibia)+0.3*TORSO; /* adjust for ankle to heel length */

/* half step without torso torque */
*hstep=(*step)/2.0-(*hex);

/* up & down mvt of body due to step size and hip roll */ *bounce=((*leg)-
sqrt((*leg)*(*leg)-(*hstep)*(*hstep))-(*hey))/2.0;

temp=(*hstep)/sqrt((*leg)*(*leg)-(*hstep)*(*hstep)); *swf=atan(temp);
*swh=0.24*((*step)-4.0*(*sex))*RAD;
*swu=1.65*(*swh);
*swt=25.0*RAD+(*swf)+5.0*(*hey)*RAD;

*femfo=RAD*0.04*(*step);
*cosff= (*leg)*(cos((*swf)-(*femfo))-cos((*swf)+(*femfo)))/2.0;

*xlean=TORSO*sin(-.0*RAD); /* no lean */ *ylean=TORSO*cos(-.0*RAD);
*xinit= -1060.0;    /*changed*/
*yinit=130.0; /*changed from Laurence's program*/
*falfo=0.0;

REDO=0; /* to repeat a trial */
OUT=0; /* to break out of system */
}

/*********************************************************************
* create the objects from which the sequence is to be made *
/********************************************************************* void make_objects
()
{
int i,j; /* used in "Floorgrid" object */

makeobj (cube=genobj());

/* 1.05-1.07 s/cyc w/ polygons only
1.06-1.10 s/cyc w/ closedlines only
1.08-1.40 s/cyc w/ both */
color (YELLOW);
for (j=0;j<6;j++)
{
bgnpolygon ();
v3i (side[j][0]);
v3i (side[j][1]);
v3i (side[j][2]);
v3i (side[j][3]);
endpolygon ();
}
color (BLACK);
for (j=0;j<6;j++)
{
bgnclosedline ();
v3i (side[j][0]);
v3i (side[j][1]);
v3i (side[j][2]);
v3i (side[j][3]);
endclosedline ();
}
closeobj ();

makeobj (Groundplane=genobj());
pmv(-20000.0,0.0,-20000.0);
pdr(-20000.0,0.0,20000.0);
pdr(20000.0,0.0,20000.0);
pdr(20000.0,0.0,-20000.0);
pclos();
closeobj ();

makeobj (Floorgrid=genobj());
for (i= -13000;i<=13000;i+=1500)
{
movei (i,0.0,13500);
drawi (i,0.0,-13500);
movei (13500,0.0,i);
drawi (-13500,0.0,i);
}

closeobj ();

makeobj(Cylinder=genobj());
move(0.0,0.0,0.0);
draw(0.0,20.0,0.0);
closeobj();

makeobj(Tree1);
move(0.0,0.0,0.0);
scale(1.6,1.6,1.6);
callobj(Cylinder);
translate(0.0,20.0,0.0);
rotate(250,'z');
scale(0.8,0.8,0.8);
callobj(Cylinder);
rotate(-400,'z');
rotate(250,'x');
scale(0.9,0.9,0.9);
callobj(Cylinder);
translate(0.0,15.0,0.0);
scale(0.8,0.8,0.8);
rotate(-850,'x');
callobj(Cylinder);
translate(0.0,8.0,0.0);
scale(0.8,0.8,0.8);
rotate(500,'z');
callobj(Cylinder);/**/
translate(-10.0,-8.0,-25.0);
rotate(1800,'x');
rotate(1400,'z');
callobj(Cylinder);
translate(0.0,15.0,0.0);
rotate(1200,'z');
scale(0.5,0.5,0.5);
callobj(Cylinder);/**/
translate(21.0,17.0,-46.0);
rotate(-1350,'z');
scale(2.0,2.0,2.0);
callobj(Cylinder);
translate(0.0,18.0,0.0);
rotate(-400,'z');/*b*/
rotate(-600,'x');
scale(0.6,0.6,0.6);
callobj(Cylinder);/*e*/
move(0.0,0.0,0.0);
closeobj();

}


/*********************************************************************
* setup windows, graphical configurations, devices, and call objects *
*********************************************************************/ void
setup_windows_graphics_devices ()
{
prefposition (0,1280,0,1009); /* define window size and placement */ winopen
("walker in a forest"); /* call and name the window */

underlay (2);
doublebuffer ();      /* double buffer mode for animation */
gconfig ();
/*swapinterval (7);*/

backface (TRUE); /* Remove counter-clockwise drawn */
zbuffer (TRUE);    /* backfacing characters & activate */
zclear ();  /* z-buffering for speed & acuracy */

qdevice (ESCKEY); /* queue the ESC key */
qdevice (LEFTMOUSE);
qdevice (MIDDLEMOUSE);
qdevice (RIGHTMOUSE);

make_objects ();       /* generate the graphical objects */

mapcolor (TREECOLOR,227,128,101);
mapcolor (FIXTREE,227,144,67);

drawmode(UNDERDRAW);                  /*added by Peter to fix ground plane*/
mapcolor (GROUND,90,73,47);           /*added by Peter to fix ground plane*/
drawmode(NORMALDRAW);                 /*added by Peter to fix ground plane*/
}

/*********************************************************************
* set up underdraw *
*********************************************************************/ void
setup_underdraw ()
{
drawmode (UNDERDRAW);
perspective (VISANG,1.0,0.1,20000.0);
lookat (0.0,EYE_HT,0.0,0.0,0.0,20000.0,0.0); color(GROUND);
callobj (Groundplane);
drawmode (NORMALDRAW);
}

/*********************************************************************
* generate the ankle table, broad w-shaped, 0-540 degrees *
*********************************************************************/ void ankle_table
(delay,sia)
float delay, /* R/W pre- and post- femur swing of tibia */
sia[]; /* R/W ankle table */
{
int i,j; /* counters */
float n, a, z; /* for temporary storage */

for (i=0;i<=180;i++)
{
sia[i]=0.0;
sia[i+360]=0.0;
}

n=360.0+delay;
i=0;

/* symmetric about 270 degrees */
for (j=270;j<=n;j++)
{
z=(float)i;
a=(2.0*z-2.0*delay*z/(90.0+delay))*RAD;
a=(cos(a)+1.0)/2.0;
sia[j]=a;
sia[j-2*i]=a;
i++;
}

for (i=360;i<=n;i++)
sia[i-360]=sia[i];

n=180.0-delay;

for (i=n;i<=180;i++)
sia[i+360]=sia[i];
}


/*********************************************************************
* determine the right and left hip locations in the x and y axes             *
*********************************************************************/ void get_hips
(x,y,cosa,sina,cosff,hex,hey,xhipr,yhipr,xhipl,yhipl) float
x,y,cosa,sina,cosff,hex,hey,*xhipr,*yhipr,*xhipl,*yhipl; {
float hx,hy;

hx=hex*cosa;
hy=hey*sina-cosff*sina;

*xhipr=x+hx;
*yhipr=y+hy;
*xhipl=x-hx;
*yhipl=y-hy;
}


/*********************************************************************
* determine the right and left knee locations in the x and y axes            *
*********************************************************************/ void get_knees
(swf,cosa,femfo,femur,xhipr,yhipr,xhipl,yhipl,
xkner,ykner,xknel,yknel)
float swf,cosa,femfo,femur,xhipr,yhipr,xhipl,yhipl,
*xkner,*ykner,*xknel,*yknel;
{
float a,z;

a=swf*cosa+femfo;
z=swf*cosa-femfo;

*xkner=xhipr+femur*sin(a);
*ykner=yhipr-femur*cos(a);
*xknel=xhipl-femur*sin(z);
*yknel=yhipl-femur*cos(z);
}


/*********************************************************************
* determine the right and left shoulder locations in the x and y axes *
*********************************************************************/ void get_shoulders
(x,y,sex,sey,cosa,sina,xlean,ylean,
xshor,yshor,xshol,yshol)
float x,y,sex,sey,cosa,sina,xlean,ylean,
*xshor,*yshor,*xshol,*yshol;
{
float hx,hy;
hx=sex*cosa;
hy=sey*sina;

*xshor=x+xlean-hx;
*yshor=y+ylean-hy;
*xshol=x+xlean+hx;
*yshol=y+ylean+hy;
}

/*********************************************************************
* determine the right and left elbows locations in the x and y axes *
*********************************************************************/ void get_elbows
(humor,cosa,swh,xshor,yshor,xshol,yshol,
xelbr,yelbr,xelbl,yelbl)
float humor,cosa,swh,xshor,yshor,xshol,yshol,
*xelbr,*yelbr,*xelbl,*yelbl;
{
float hx,hy;

hx=humor*sin(swh*cosa);
hy=humor*cos(swh*cosa);

*xelbr=xshor-hx;
*yelbr=yshor-hy;
*xelbl=xshol+hx;
*yelbl=yshol-hy;
}


/*********************************************************************
* determine the right and left ankles locations in the x and y axes *
*********************************************************************/ void get_ankles
(swf,swt,cosa,sina1,sina2,femfo,tibia,
xkner,ykner,xknel,yknel,
xankr,yankr,xankl,yankl)
float swf,swt,cosa,sina1,sina2,femfo,tibia,xkner,ykner,xknel,yknel,
*xankr,*yankr,*xankl,*yankl;
{
float a,z;

a=swf*cosa+femfo-swt*sina1;
z= -swf*cosa+femfo-swt*sina2;

*xankr=xkner+tibia*sin(a);
*yankr=ykner-tibia*cos(a);
*xankl=xknel+tibia*sin(z);
*yankl=yknel-tibia*cos(z);
}


/*********************************************************************
* determine the right and left wrists locations in the x and y axes          *
*********************************************************************/ void get_wrists
(swh,swu,cosa,cos2a,ulna,xelbr,yelbr,xelbl,yelbl,
xwrir,ywrir,xwril,ywril)
float swh,swu,cosa,cos2a,ulna,xelbr,yelbr,xelbl,yelbl,
*xwrir,*ywrir,*xwril,*ywril;
{
float hx,hy,a,z;

hx=swh*cosa;
hy=swh*(cos2a+1.0)/2.0;

a=swu*(cosa-1.0)/2.0;
z=swu*(cosa+1.0)/2.0;

*xwrir=xelbr-ulna*sin(hx+a);
*ywrir=yelbr-ulna*cos(hy-a);
*xwril=xelbl+ulna*sin(hx+z);
*ywril=yelbl-ulna*cos(hy+z);
}



/********************************************************************
* render the walker to the buffering being drawn to           *
*********************************************************************/ void draw_corpse
(xhead,yhead,xshor,yshor,xshol,yshol,
xelbr,yelbr,xelbl,yelbl,xwrir,ywrir,
xwril,ywril,xhipr,yhipr,xhipl,yhipl,
xkner,ykner,xknel,yknel,xankr,yankr,
xankl,yankl,
ulna,humor,femur,tibia,
beta,shape,z)
float xhead,yhead,
xshor,yshor,xshol,yshol,
xelbr,yelbr,xelbl,yelbl,
xwrir,ywrir,xwril,ywril,
xhipr,yhipr,xhipl,yhipl,
xkner,ykner,xknel,yknel,
xankr,yankr,xankl,yankl,
ulna,humor,femur,tibia;
Angle beta;
Object shape;
float z;
{
/* bones lengths added --get_part_length omitted */ draw_part
(xshor,yshor,z+SW,xelbr,yelbr,z+SW,ulna,8.0,8.0,beta,shape); draw_part
(xelbr,yelbr,z+SW,xwrir,ywrir,z+SW,humor,7.0,7.0,beta,shape); draw_part
(xshol,yshol,z-SW,xelbl,yelbl,z-SW,ulna,8.0,8.0,beta,shape); draw_part
(xelbl,yelbl,z-SW,xwril,ywril,z-SW,humor,7.0,7.0,beta,shape);
/* legs changed */
draw_part
(xhipr,yhipr,z+HW-4.0,xkner,ykner,z+HW-4.0,femur,12.0,12.0,beta,shape);
draw_part
(xkner,ykner,z+HW-4.0,xankr,yankr,z+HW-4.0,tibia,11.0,11.0,beta,shape);
draw_part
(xhipl,yhipl,z-HW+4.0,xknel,yknel,z-HW+4.0,femur,12.0,12.0,beta,shape);
draw_part
(xknel,yknel,z-HW+4.0,xankl,yankl,z-HW+4.0,tibia,11.0,11.0,beta,shape);
draw_torso ((xshor+xshol)/2.0,(yshor+yshol)/2.0,z,
(xhipr+xhipl)/2.0,(yhipr+yhipl)/2.0,z,beta,shape); draw_head (xhead-5.0,yhead-
19.0,z,10.0,beta,shape); draw_head (xhead-9.0,yhead-40.0,z,5.0,beta,shape); /*
neck added */ }


/*********************************************************************
* This is the main loop, in which the walker walks and the viewer moves * *
through the "scenery"             *
*********************************************************************/ void locomotion
(humor,ulna,femur,tibia,leg,step,
sher,time,hex,hey,sex,sey,swf,swh,
swu,swt,hstep,bounce,delay,xlean,ylean,
xinit,yinit,falfo,femfo,cosff,sia,ip,ist) float humor,ulna,femur,tibia,leg,step,
sher,time,hex,hey,sex,sey,swf,swh,
swu,swt,hstep,bounce,delay,xlean,ylean,
xinit,yinit,falfo,femfo,cosff,sia[];
int     ip,ist;
{
int     i,j,k,it,gridrot,tt,tmod;

float sina, sina1, sina2, cosa, cos2a, cosi, dum,
x, y, xf, zf,
xhead, yhead,          /* }  */
xhipr, yhipr, xhipl, yhipl,  /* }   */
xelbr, yelbr, xelbl, yelbl,  /* }   */
xkner, ykner, xknel, yknel, /* }x&y coords of body parts */
xshor, yshor, xshol, yshol, /* }    */
xankr, yankr, xankl, yankl, /* }       */
xwrir, ywrir, xwril, ywril,     /* }   */
n,      /* a counter */
a1,     /* for temporary storage */
yy,     /* eyeheight of looker */
speed;           /* time in secs. of each step cycle */

/* n is the counter used in the subject walker movement loop.
The subject walker starts walking at xx,zz=0.0 */

gridrot=(float)rand()*3600.0;
time1=times(&t1);
gettimeofday(&tp,&tzp);
tt=0;
tmod=0;
INCR=30;
xx1=xx;
zz1=zz;

/* This is the main loop for both walkers. Each step-cycle (j) is
two steps */

for (j=1;j<=NUM_STEPS;j++)
{
for (k=tmod;k<359;k+=INCR)
{
tim = starttim = ((double)tp.tv_sec) +
((double)tp.tv_usec)*0.000001;
/*n=step*2.0*INCR/360.0;*/

i=k+12.0*sin(2.0*k*RAD); /* surge factor */
sina=sin(i*RAD);
cosa=sin((i+90)*RAD);
cos2a=sin((i*2+90)*RAD);
sina1=sia[i];
sina2=sia[i+180];

if (i <= 180) cosi=cosa;
if (i > 180) cosi=sin((i-90)*RAD);
if ((i >= (180-delay)) && (i <= (180+delay)))
falfo=falfo+step*0.02/12;
if ((i >= (360-delay)) || (i <= delay))
falfo=falfo+step*0.02/12;

/* depends on increment in i */
x=xinit-cosi*step/2.0+falfo;
y=yinit-bounce*cos2a;

/* generate the coords of the walker object */

xhead=x+1.6*xlean+TORSO/15.0;
yhead=y+1.6*ylean;

get_hips (x,y,cosa,sina,cosff,hex,hey,&xhipr,&yhipr,
&xhipl,&yhipl);
get_knees (swf,cosa,femfo,femur,xhipr,yhipr,xhipl,
yhipl,&xkner,&ykner,&xknel,&yknel);
get_shoulders (x,y,sex,sey,cosa,sina,xlean,ylean,
&xshor,&yshor,&xshol,&yshol);
get_elbows (humor,cosa,swh,xshor,yshor,xshol,yshol,
&xelbr,&yelbr,&xelbl,&yelbl);
get_ankles (swf,swt,cosa,sina1,sina2,femfo,tibia,
xkner,ykner,xknel,yknel,
&xankr,&yankr,&xankl,&yankl);
get_wrists (swh,swu,cosa,cos2a,ulna,
xelbr,yelbr,xelbl,yelbl,
&xwrir,&ywrir,&xwril,&ywril);


/* draw the grid, walker object, then trees */

clearscreen ();
perspective (VISANG,1.0,0.1,30000.0);
lookat (xx1,EYE_HT,zz1,0.0,EYE_HT,0.0,0.0);

linewidth(1);
color (WHITE);
pushmatrix();
rotate(gridrot,'y');
callobj(Floorgrid);
popmatrix();

draw_corpse (xhead,yhead,xshor,yshor,xshol,yshol,
xelbr,yelbr,xelbl,yelbl,xwrir,ywrir,
xwril,ywril,xhipr,yhipr,xhipl,yhipl,
xkner,ykner,xknel,yknel,xankr,yankr,
xankl,yankl,
ulna,humor,femur,tibia,
0,cube,Z1);

drawtrees(xx,zz);
swapbuffers ();

gettimeofday(&tp,&tzp);
tim = ((double)tp.tv_sec) +
((double)tp.tv_usec)*0.000001;
tt=(float)(tim-starttim)*100*3;
/*       printf ("frame %d = %d %f\n",k,tt,x);
*/
INCR = tt;
if((k+tt)>359) tmod=(k+tt)%360;

if ((k>=140) && (k<=180)){
xinit=xinit+step+falfo;
xx=xx+(step+falfo)*cos(SDIR*RAD);
zz=zz+(step+falfo)*sin(SDIR*RAD);
falfo=0;
if(k<(181-INCR)) k=181-INCR;}
}
xinit=xinit+step+falfo;
xx=xx+(step+falfo)*cos(SDIR*RAD);
zz=zz+(step+falfo)*sin(SDIR*RAD);
falfo=0;
}
time2=times(&t1);
/*      printf (" duration = %d\n",(time2-time1));
*/
}

/*********************************************************************
* calculate the midpoint between two points in three dimensional space *
*********************************************************************/ void get_midpoint
(x1,y1,z1,x2,y2,z2,xm,ym,zm) float x1,y1,z1,x2,y2,z2,*xm,*ym,*zm;
{
*xm=(x1+x2)/2.0;
*ym=(y1+y2)/2.0;
*zm=(z1+z2)/2.0;
}

/*********************************************************************
* render a single body part *
*********************************************************************/ void draw_part
(x1,y1,z1,x2,y2,z2,length,w,t,beta,shape) float x1,y1,z1,x2,y2,z2, /* R/O
coords of joints of this body part */
w,t, /* R/O width and thickness of this body part */
length;         /* from bone */
Angle beta; /* R/O Angle of walker's change of direction */

Object shape;        /* R/O object used to make this body part */
{
float alpha, /* angle to which the object that the body
part is made freom is rotated */
xm,ym,zm; /* midpoint of the body part (midpoint
between the joints */

get_midpoint (x1,y1,z1,x2,y2,z2,&xm,&ym,&zm); get_angle (x1,y1,x2,y2,&alpha);

pushmatrix ();
rotate (beta*10,'Y'); /* change of direction */
translate (xm,ym,zm);
rotate (alpha*10,'Z');
scale (length/2.0,t/2.0,w/2.0); /* make the part the correct length,
width and thickness */
callobj (shape);
popmatrix ();
}



/*********************************************************************
* calculate the angle that a body part needs to be rotated            *
*********************************************************************/ void get_angle
(x1,y1,x2,y2,a)
float x1,y1,x2,y2, /* R/O endpts of the line (coords of the 2 joints */
*a;     /* W/O the angle of rotation */
{
float temp1,temp2; /* for temporary storage */

/* This function takes the x and y coordinates of two joints
(z coords are unnecessary because connected joints are always in the same z-
plane) projects thet line they form onto the axes, and calculates one of the angles
that is formed. Ths function is used by the DRAWPART procedure, which seeks
to place an object (to be the body part connecting the joints) between them.*/

temp1=y1-y2;
temp2= sqrt ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); *a=asin(temp1/temp2)*DEG;
if (y1 == y2) *a=0.0;
if (x1 == x2) *a=90.0;
if (((x1<x2) && (y1>y2)) || ((x1>x2) && (y1<y2))) *a= -(*a); }


/*********************************************************************
* render the head of the walker *
**********************************************************************/ void draw_head
(x,y,z,w,beta,shape)
float x,y,z,w; /* R/O location of head in 3d space & its radius */ Angle beta; /* R/O
Angle of walker's change of direction */
Object shape; /* R/O object used to make the head */ {
pushmatrix ();
rotate (beta*10,'Y');
translate (x,y,z);
rotate (900,'Z');
scale (w*1.4,w*1.0,w);
callobj (shape);
popmatrix ();
}


/********************************************************************
* render the torso of the walker *
*********************************************************************/ void draw_torso
(xn,yn,zn,xp,yp,zp,beta,shape) float xn,yn,zn,xp,yp,zp;/* R/O coords of midpoint
between shoulders and hips */ Angle beta;             /* R/O Angle of walker's change
of direction */
Object shape;           /* R/O object used to make the three-part torso */
{
float l; /* length or height of the whole torso */

l=TORSO/3.0;
draw_part (xn,yn+l/5.0,zn,xn,yn-l*1.2,zn,l*1.3,41.7,25.0,beta,shape); draw_part
(xn,yn-l,zn,xp,yn-(l*2.0),zp,l,32.0,22.0,beta,shape); draw_part (xp,yn-
(l*2.0),zp,xp,yp,zp,l,28.0,20.0,beta,shape); }


/*********************************************************************
* clear the underlay plane so upon return to the shell, it isn't messy *
*********************************************************************/ void clean_up ()
{
fullscrn ();
drawmode (UNDERDRAW);
mapcolor (BLACK,0,0,0);
color (BLACK);
clear ();
drawmode (NORMALDRAW);
endfullscrn ();
}
/*********************************************************************
* randomize trials *
*********************************************************************/ rnorder() {
int k,j,in,itemp;
long tm_sec;
time(&tm_sec);
srand(tm_sec);

for (k=0; k<NTRI; k++)
tord[k]=k;
for (k=1; k<=(NTRI-1); k++) {
in=k+((NTRI-1-k)*(float)rand()/32767.0); itemp=tord[in];
if (in>tord[k]){
for (j=in; j>k; j=j-1)
tord[j]=tord[j-1];
}
tord[k]=itemp;
}
}

/*********************************************************************
* clear the screen *
*********************************************************************/ clearscreen () {
color (BLACK);
clear ();
zclear();
}
/*********************************************************************
* take care of any window changes or input from mouse and keyboard *
*********************************************************************/ processinput () {
short val;
int dev;
dev=qread (&val);
switch (dev) {
case MIDDLEMOUSE:              /* user wants to repeat */
TRI=TRI-1;
REDO=1;
qreset();
return;
case RIGHTMOUSE:
RESP=1;
REDO=0;
return;
case LEFTMOUSE:
RESP=2;
REDO=0;
return;
case ESCKEY:           /* end program */
OUT=1;
return;
default:
return;
}
}

/*********************************************************************
* draw the trees *
*********************************************************************/

drawtrees (xx,zz)
float xx,zz;
{
int c,r,w;
float x1,z1;
color(TREECOLOR);

for (c=1;c<NUMTR;c++){
translate(rno[c][0]-rno[c-1][0],0.0,
rno[c][1]-rno[c-1][1]);
x1=rno[c][0]-xx;
z1=rno[c][1]-zz;
x1=sqrt(x1*x1+z1*z1);
w=3.0*tan(1.0/x1)/tan(1.0/5000.0);
linewidth((short)w);
r=rno[c][2];
if(c==(NUMTR-1)) color(FIXTREE);
pushmatrix();
rotate(r,'y');
scale(10.0,10.0,10.0);
callobj(Tree1);
popmatrix();
}
}

/*********************************************************************
* generate the random coordinates of each of the 6 randomly placed trees
*********************************************************************/ generatecoords () {
int c;
float angd,angr,angl;
rno[0][0]=0.0;
rno[0][1]=0.0;
for (c=1;c<NUMTR;c++) {
rno[c][0]=20000.0*((float)rand())/32767.0 - 10000.0; rno[c][1]=10000.0 -
200.0*c*(100.0/NUMTR); rno[c][2]=((float)rand()/32767.0)*3600.0;
}
rno[NUMTR-1][0]=0.0;
rno[NUMTR-1][1]=0.0;
}

/*********************************************************************
* stop and wait for the ESC to be queued by the user/viewer *
*********************************************************************/ void stop_and_wait
(){
int i;
while (getbutton (ESCKEY) == FALSE);
}

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:4
posted:12/27/2011
language:English
pages:23