001    /*
002     * Coord.java
003     * part of the Spirograph.java problem set
004     *
005     * Developed for "Rethinking CS101", a project of Lynn Andrea Stein's AP Group.
006     * For more information, see <a href="http://www.ai.mit.edu/projects/cs101/">the
007     * CS101 homepage</a> or email <las@ai.mit.edu>.
008     *
009     * Copyright (C) 1996 Massachusetts Institute of Technology.
010     * Please do not redistribute without obtaining permission.
011     */
012    
013    package spirograph;
014    
015    import java.util.*;
016    import java.awt.*;
017    
018    /** This class holds information regarding one dimension of the ball.
019     * It has methods to update the position of the ball, as well as
020     * methods to get and set certain variables.
021     *
022     * <p>Copyright © 1996 Massachusetts Institute of Technology.<br />
023     * Copyright © 2003 Franklin W. Olin College of Engineering.</p>
024     *
025     * @author Luis Sarmenta, lfgs@cag.lcs.mit.edu
026     * @author Henry Wong, henryw@mit.edu
027     * @author Patrick G. Heck, gus.heck@olin.edu
028     * @version $Id: Coord.java,v 1.4 2004/02/09 20:55:03 gus Exp $
029     * @see AccelHandler
030     * @see Spirograph
031     */
032    public class Coord {
033        
034      private double pos = 0;
035      private double vel = 0;
036      private double accel = 0;
037      private double maxPos = Spirograph.WIDTH;
038    
039      private int accelMode = AccelHandler.POSMODE;
040    
041      /** 
042       * Determines the current mode of operation, either position,
043       *       velocity, or accleration control.
044       *
045       * @return {@link AccelHandler#POSMODE}, {@link AccelHandler#VELMODE}
046       *         or {@link AccelHandler#ACCELMODE}
047       */
048      public int getMode() { return accelMode; }
049    
050      /**
051       * Sets the current mode.  Legal parameter values are
052       *       AccelHandler.POSMODE, AccelHandler.VELMODE, or
053       *       AccelHandler.ACCELMODE.
054       *
055       * @param mode The desired mode
056       */
057      public void setMode(int mode) {
058        switch( mode ) {
059        case AccelHandler.POSMODE: 
060          setVel(0.0D);
061          // fall through
062    
063        case AccelHandler.VELMODE:
064          setAccel(0.0D);
065          // fall through
066    
067        default:
068          accelMode = mode;
069          break;
070        }
071      }
072    
073      /** The maximum position for this coordinate.
074       * @return a positive double indicating the maximum allowable position
075       */  
076      public double getMaxPos() { return maxPos; }
077      /** Set the maximum position for this coordinate
078       * @param pos A positive value indicating the maximum position.
079       * @throws IllegalArgumentException when pos < 0
080       */  
081      public void setMaxPos( double pos ) throws IllegalArgumentException { 
082          if (pos < 0.0) {
083              throw new IllegalArgumentException("Negagive Max Pos!");
084          }
085          maxPos = pos; 
086      }
087            
088    
089      /**
090       * The current position of this coordinate. 
091       *
092       * @return  a double between <code>-(getMaxPos())</code> and 
093       *          <code>getMaxPos()</code>
094       */  
095      public double getPos() { return pos; }
096      /** Modify the current position of this coordinate.
097       *
098       * @param pos the desired new position
099       * @throws IllegalArgumentException If the absolute value of the argument is
100       *                                  greater than {@link #getMaxPos()}
101       */  
102      public void setPos(double pos) throws IllegalArgumentException { 
103          if (Math.abs(pos) > getMaxPos()) {
104              throw new IllegalArgumentException("pos out of bounds");
105          }
106          this.pos = pos; 
107      }
108    
109      /** The current velocity along this coordinate axis.
110       *
111       * @return the magnitude of a velocity vector along this axis
112       */  
113      public double getVel() { return vel; }
114       /** Set the velocity along this axis.
115        *
116        * @param vel The new value for the velocity along this axis
117        */  
118      public void setVel(double vel) { this.vel = vel; }
119    
120      /** The acceleration along this axis.
121       *
122       * @return the magintude of an acceleration vector along this axis
123       */  
124      public double getAccel() { return accel; }
125      /** Set the acceleration along this axis.
126       *
127       * @param accel The new value for the acceleration along this axis
128       */  
129      public void setAccel(double accel) { this.accel = accel; }                
130    
131      /** Sets the position, velocity or acceleration depending on the current mode.
132       *
133       * @param val The new value for the current movement mode.
134       */  
135      public void setValue(double val)
136      {
137        switch( accelMode ) {
138        case AccelHandler.POSMODE: 
139          setPos(val);
140          break;
141        case AccelHandler.VELMODE: 
142          setVel(val);
143          break;
144        case AccelHandler.ACCELMODE: 
145          setAccel(val);
146          break;
147        }
148      }
149    
150      /** Calculates the acceleration of the ball by taking
151       *  the current acceleration and adding it to the combined
152       *  accelerations resulting from each of the different gravitational
153       *  fields.
154       *
155       * @param v A vector denoting the distance on this axis and the total distance from
156       *         every gravitational source.
157       * @param step The size of the step to calculate.
158       */
159      public void nextStep (Vector v, double step) {
160        double finalAccel = accel;
161            
162        for (Enumeration e = v.elements(); e.hasMoreElements();) {
163          Point data  = (Point)e.nextElement();
164    
165          // I just use these to make the math formula a little
166          // easier to follow, they aren't really needed.
167          int dx = data.x;
168          int dr = data.y;
169    
170          // If dr == 0 just ignore it...
171          if (dr != 0) {        
172            finalAccel += Spirograph.GRAV*dx/Math.pow(dr,3);
173          }
174    
175        }
176            
177        vel = vel + (finalAccel * step);
178        pos = pos + (vel * step);
179      }
180    }
181    
182    /*
183     * $Log: Coord.java,v $
184     * Revision 1.4  2004/02/09 20:55:03  gus
185     * javadoc fixes
186     *
187     * Revision 1.3  2003/01/15 17:36:10  gus
188     * adding log keywords to files that don't have them
189     *
190     */