// 9/30/98 Lab 5 leader script // Compiled using MS SDK Java 3.1 on Windows 98 import java.io.*; import java.util.*; import vrml.*; import vrml.node.*; import vrml.field.*; import java.lang.Math; public class leader extends Script { // fields private SFString nodename; // eventouts private SFRotation rotation_changed; private SFVec3f translation_changed; // local vars private float arotation[]={0,1,0,0}; private float translation[]={0,0,0}; private float curx = 0f, cury = 0f, curz = 0f; private float destx = 30f, desty = 5f, destz = 3f; // initial destination private float xdist = 30f, ydist = 5f, zdist = 3f; // distance between dest and cur private float curAngle = 0f; //(float) Math.PI; // angle fish is pointing private float angleToRotate = 0f, angleDif, lastTime = 0f; private int destQuadrant = 1, curQuadrant = 2; private Random arand = new Random(); public int findQuadrant(float x, float z) { if( (x >= 0) && (z >=0) ) return 1; else if( (x >= 0) && (z < 0) ) return 4; else if( (x < 0) && (z >= 0) ) return 2; else return 3; } public void findAngle() // finds the angle to turn to based on current and dest { // 0 angle means pointing towards positive x direction float anAngle = (float) Math.atan( (double) (destz-curz)/(destx-curx+0.0001f) ); if( (destz >= curz) && (destx >= curx) ) angleToRotate = (float)Math.PI - anAngle; else if( (destz < curz) && (destx >= curx) ) angleToRotate = (float)Math.PI-anAngle; else if( (destz < curz) && (destx < curx) ) angleToRotate = - anAngle; else angleToRotate = - anAngle; angleDif = angleToRotate - curAngle ; // readjust so that we know what angle to rotate to. } public void initialize() { rotation_changed = (SFRotation) getEventOut("rotation_changed"); translation_changed = (SFVec3f) getEventOut("translation_changed"); nodename = (SFString) getField("nodename"); destQuadrant = findQuadrant(destx, destz); findAngle(); setDistances(); } public void processEvent(Event e) { String EventName = e.getName(); if(EventName.equals("set_fraction")) set_fraction((ConstSFFloat)e.getValue()); } private boolean randomNegative() { if(arand.nextFloat() >= .5) return true; else return false; } private void setDistances() { xdist = destx - curx; ydist = desty - cury; zdist = destz - curz; } private void set_fraction(ConstSFFloat temp) { float frac = temp.getValue(); if(frac >= 1.0f) { System.out.println("Something WRONG! Can't have fraction > 1"); return; } if(lastTime <= frac) { if(frac < .4f) // have the fish turn by 0.4 of the whole sequence arotation[3]= (frac/0.4f)*angleDif+curAngle; else { arotation[3]= angleToRotate; curAngle = angleToRotate; } translation[0] = xdist*frac+curx; translation[1] = ydist*frac+cury; translation[2] = zdist*frac+curz; lastTime = frac; rotation_changed.setValue(arotation); translation_changed.setValue(translation); } else // as soon as the timer loops... { // should have arrived at destination now. translation[0] = destx; translation[1] = desty; translation[2] = destz; lastTime = 0f; rotation_changed.setValue(arotation); translation_changed.setValue(translation); curx = destx; cury = desty; curz = destz; // now find new worlds to discover float blah = arand.nextFloat()*5f; if(randomNegative()) blah = -blah*1.05f; desty += blah; curQuadrant = destQuadrant; switch(curQuadrant) { case 1: destx += arand.nextFloat()*7; destz += -arand.nextFloat()*6.2-.2f; break; case 2: destx += arand.nextFloat()*6.2+.2f; destz += arand.nextFloat()*7; break; case 3: destx += -arand.nextFloat()*7.2; destz += arand.nextFloat()*6+.2f; break; case 4: destx += -arand.nextFloat()*6.2-.2f; destz += -arand.nextFloat()*7; break; } if(destx >= 40) destx = 34f; if(destx <= -40) destx = -34f; if(destz >= 40) destz = 34f; if(destz <= -40) destz = -34f; if( ( Math.pow((double)destx, 2) + Math.pow((double)destz, 2) ) >= 1600 ) { if( (destx >= 0) && (destz >= 0) ) { if( destx >= destz) { destz -= 4.5f; destx = (float) Math.sqrt( 1600 - Math.pow( (double)destz, 2)) - 4f; } else { destx -= 4.5f; destz = (float) Math.sqrt( 1600 - Math.pow((double)destx, 2)) - 4f; } } if( (destx >= 0) && (destz < 0) ) { if( destx >= -destz) { destz += 4.5f; destx = (float) Math.sqrt( 1600 - Math.pow((double)destz, 2)) - 4f; } else { destx -= 4.5f; destz = (float) -Math.sqrt( 1600 - Math.pow((double)destx, 2)) + 4f; } } if( (destx < 0) && (destz >= 0) ) { if( destz >= -destx) { destx += 4.5f; destz = (float) Math.sqrt( 1600 - Math.pow((double)destx, 2)) - 4f; } else { destz -= 4.5f; destx= (float) -Math.sqrt( 1600 - Math.pow((double)destz, 2)) + 4f; } } if( (destx < 0) && (destz < 0) ) { if( -destx >= -destz) { destz += 4.5f; destx = (float) -Math.sqrt( 1600 - Math.pow((double)destz, 2)) + 4f; } else { destx += 4.5f; destz = (float) -Math.sqrt( 1600 - Math.pow((double)destx, 2)) + 4f; } } } if(desty >= 15) desty = 11f; if(desty <= -15) desty = -11f; System.out.println("New Destination: "+destx+", "+desty+", "+destx); setDistances(); destQuadrant = findQuadrant(destx, destz); findAngle(); } // end else } // end function } // end class