Ball.javaimport javafx.geometry.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import java.util.Random;
public class Ball
{
Circle circle = new Circle();
double px, py;
double vx, vy;
double mass;
double radius;
Color color;
String name;
static int count = 0;
Ball()
{
color = Color.rgb(255,180,0);
vx = 8;
vy = 9;
name = "default";
set_radius(17);
setPosition(50,60);
circle.setFill(color);
}
Ball(double px, double py, double vx, double vy, Color color)
{
this.vx = vx;
this.vy = vy;
this.color = color;
name = "ball" + (++count);
set_radius(17);
setPosition(px,py);
circle.setFill(color);
}
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, double wd, double ht)
{
Random r = new Random();
double x = wd*r.nextDouble();
double y = ht*r.nextDouble();
setPosition(x,y);
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(double r)
{
radius = r;
mass = r*r;
circle.setRadius(radius);
}
public void setColor(Color c) {
color = c;
circle.setFill(color);
}
public void setPosition(double x, double y)
{
px = x;
py = y;
circle.setCenterX(px);
circle.setCenterY(py);
}
public String toString()
{
if (name!=null) return String.format(" %s (%.1f, %.1f)",name,px,py);
else return String.format(" pos (%.1f, %.1f) ",px,py);
}
public String info()
{
return String.format(" %s pos (%.1f, %.1f) vel (%.1f %.1f) ",name,px,py,vx,vy);
}
public void move(double delta)
{
px += vx*delta;
py += vy*delta;
circle.setCenterX(px);
circle.setCenterY(py);
}
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;
double epsilon = -1e-6;
// 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 - 1;
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 tx; // balls moving apart
if (C<epsilon) System.out.println("already intersecting " + this + " " + b + " C " + C);
if (C<epsilon) 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 Sat Mar 03 12:45:57 2018