Ball.java


import java.awt.*;
import java.awt.geom.*;
import java.util.Random;

public class Ball
{
    double px, py;
    double vx, vy;
    double mass;
    int radius;
    Color color;
    String name;
    static int count = 0;
    Ball()
    {
	color = new Color(255,180,0);
	px = 50;
	py = 60;
	vx = 8;
	vy = 9;
	name = "default";
	set_radius(17);
    }
    Ball(double px, double py, double vx, double vy, Color color)
    {
	this.px = px;
	this.py = py;
	this.vx = vx;
	this.vy = vy;
	this.color = color;
	name = "ball" + (++count);	
	set_radius(17);
    }
    Ball(int px, int py)
    {
	this.px = px;
	this.py = py;
	vx = vy = 0.0;
	color = Color.BLACK;
	set_radius(1);
    }
    public void randomize(double v, int wd, int ht)
    {
	Random r = new Random();
	px = wd*r.nextDouble();
	py = ht*r.nextDouble();
	double theta = r.nextDouble()*2.0*Math.PI;
	vx = v*Math.cos(theta);
	vy = v*Math.sin(theta);
    }
    public void set_name(String name)
    {
	this.name = name;
    }
    public void set_radius(int r)
    {
	radius = r;
	mass = r*r;
    }
    public void set_point(double x, double y)
    {
	px = x;
	py = y;
    }

    public String toString()
    {
	return String.format(" %s ",name);
    }

    public String info()
    {
	return String.format(" %s  pos (%.1f, %.1f) vel (%.1f %.1f) ",name,px,py,vx,vy);
    }
/*    
    public void move()
    {
	px += vx;
	py += vy;
    }
*/
    public void move(double delta)
    {
	px += vx*delta;
	py += vy*delta;
    }

    public void draw_outline(Graphics g)
    {
	g.drawOval((int)(px-radius), (int) (py-radius), (int)2*radius, (int)2*radius);
    }
    
    public void draw(Graphics g) 
    {
	g.setColor(color);
	//System.out.format("%s radius %g%n",name, radius
	g.fillOval((int)(px-radius), (int) (py-radius), (int)2*radius, (int)2*radius);
    }

    public boolean contains(Point2D pt)
    {
	double dist = Math.hypot(pt.getX()-px,pt.getY()-py);
	return (dist<radius);
    }

    public double dist(Ball b)
    {
	// relative position
	double dx = b.px - px;
	double dy = b.py - py;
	double dist = Math.hypot(dx,dy);
	// test radius
	double r = radius + b.radius;
        return dist-r;
    }

    public double intersect(Ball b)
    {
	double tx = 1000.0;
	// relative velocity
	double rx = b.vx - vx;
	double ry = b.vy - vy;
	// relative position
	double dx = b.px - px;
	double dy = b.py - py;
	// test radius
	double r = radius + b.radius;
	double A = rx*rx+ry*ry;
	double B = rx*dx+ry*dy;
	double C =  dx*dx + dy*dy - r*r;
	if (B>0.0) return -1.0; // balls moving apart
	if (C<0.0) return -1.0; // already intersecting
	if (A<=0.0) return tx; // no relative velocity
	// quadratic At^2 + 2Bt + C = 0
	double radical = B*B-A*C;
	if (radical<=0.0) return tx; // no intersection (balls miss)
	double R = Math.sqrt(radical);
	double t;
	if (B>0) t = (-B + R)/A;
	else t = -(B+R)/A;
	if (t<=0.0) return tx; // no intersection in future
	return t;
    }

    public double intersect_window_vertical(double width)
    {
	if (vx<0) {
	    return (px-radius)/(-vx);
	}
	else if (vx>0) {
	    return (width - px - radius)/(vx);
	}
	return -1.0;
   }

    public double intersect_window_horizontal(double height)
    {
	if (vy<0) {
	    return (py-radius)/(-vy);
	}
	else if (vy>0) {
	    return (height - py - radius)/vy;
	}
	return -1.0;
   }
}


Maintained by John Loomis, updated Sun Jul 13 19:27:43 2014