/* * Created on Feb 8, 2005 * */ import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Composite; import java.awt.Graphics2D; import java.awt.Image; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; /** * @author knorton */ public class Ball { private Vector2D position; private Vector2D velocity; private float angularVel; private float orientation; private float r; private Image dyImage = null; private Image stImage = null; private GeneralPath cxPath = null; private GeneralPath rxPath = null; public Ball() { this.position = new Vector2D(0f,0f); this.velocity = new Vector2D(0f,0f); this.angularVel = 0f; this.orientation = 0f; this.r = 5f; } public Ball(float x, float y, float r) { this(); this.position.set(x,y); this.r = r; } public Ball(float x, float y, float r, float vx, float vy) { this(x,y,r); this.velocity.set(vx,vy); } public void draw(Graphics2D g) { if (stImage == null || dyImage == null) return; Composite c = g.getComposite(); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.5f)); if (cxPath != null) { g.setColor(Color.RED); g.draw(cxPath); } if (rxPath != null) { g.setColor(Color.GREEN); g.draw(rxPath); } g.setComposite(c); AffineTransform dxt = AffineTransform.getTranslateInstance(position.i,position.j); g.transform(dxt); g.transform(AffineTransform.getRotateInstance(orientation)); g.drawImage(dyImage,(int)-r,(int)-r,null); g.setTransform(dxt); if (stImage != null) g.drawImage(stImage,(int)-r,(int)-r,null); g.setTransform(new AffineTransform()); } public float getX() { return position.i; } public void setX(float x) { position.i = x; } public float getY() { return position.j; } public void setY(float y) { position.j = y; } public float getVx() { return velocity.i; } public void setVx(float vx) { velocity.i = vx; } public float getVy() { return velocity.j; } public void setVy(float vy) { velocity.j = vy; } public void setAngularVelocity(float av) { angularVel = av; } public float getRadius() { return r; } public void setRadius(float r) { this.r = r; } public Image getStaticImage() { return this.stImage; } public void setStaticImage(Image stImage) { this.stImage = stImage; } public Image getDynamicImage() { return this.dyImage; } public void setDynamicImage(Image dyImage) { this.dyImage = dyImage; this.setRadius(this.dyImage.getWidth(null)>>1); } public void computeFrictionlessCollisions(int width, int height) { // Collisions if ((position.j+r) >= height) { //collide with floor velocity.j = -Constants.DAMPENING * velocity.j; position.j = height-r; } else if ((position.j+r) < 0) { //collide with ceiling velocity.j = -Constants.DAMPENING * velocity.j; position.j = r; } if ((position.i+r) >= width) { //collide with right wall velocity.i = -Constants.DAMPENING * velocity.i; position.i = width-r; } else if ((position.i+r) <= 0) { //collide with left wall velocity.i = -Constants.DAMPENING * velocity.i; position.i = r; } } public static float computeVxGarwin(float vx, float av, float r) { return ((1-Constants.GARWIN_ALPHA*Constants.Ex)*vx + Constants.GARWIN_ALPHA*(1+Constants.Ex)*r*av) / (1+Constants.GARWIN_ALPHA); } public static float computeVyGarwin(float vy) { return -Constants.Ey*vy; } public static float computeAVGarwin(float vx,float av, float r) { return ((1+Constants.Ex) * vx + (Constants.GARWIN_ALPHA - Constants.Ex)*r*av) /(r*(1+Constants.GARWIN_ALPHA)); } public void computeGarwinCollisions(int width, int height) { if ((position.j+r) >= height) { velocity.i = computeVxGarwin(velocity.i,this.angularVel,r); angularVel = computeAVGarwin(velocity.i,this.angularVel,r); velocity.j = computeVyGarwin(velocity.j); position.j = height-r; } if ((position.i+r) >= width) { velocity.i = computeVyGarwin(velocity.i); velocity.j = computeVxGarwin(velocity.j,angularVel,r); angularVel = computeAVGarwin(velocity.j,angularVel,r); position.i = width-r; } else if ((position.i-r) <= 0) { velocity.i = computeVyGarwin(velocity.i); velocity.j = computeVxGarwin(velocity.j,angularVel,r); angularVel = computeAVGarwin(velocity.j,angularVel,r); position.i = r; } } public void reset() { cxPath = rxPath = null; this.orientation = 0f; this.angularVel = 0f; this.velocity.set(0f,0f); } public void update(float dt, int width, int height) { velocity.j = velocity.j + Constants.G * dt; position.i += velocity.i*dt; position.j += velocity.j*dt; orientation += angularVel*dt; this.computeGarwinCollisions(width,height); if (cxPath == null) { cxPath = new GeneralPath(); cxPath.moveTo(position.i,position.j); } else { cxPath.lineTo(position.i,position.j); } if (rxPath == null) { rxPath = new GeneralPath(); rxPath.moveTo( position.i+r*(float)Math.cos(orientation), position.j+r*(float)Math.sin(orientation)); } else { rxPath.lineTo( position.i+r*(float)Math.cos(orientation), position.j+r*(float)Math.sin(orientation)); } } }