Download Java source from study.zip
| Opening screen | After pressing next button once | After pressing next button again |
![]() | ![]() |
|
Use mouse to locate new starting point and direction.
Also see Ball.java
study.javaimport java.awt.*;
import java.awt.geom.Rectangle2D;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
public class study extends JPanel
{
int qx = 220;
int qy = 80;
Ball circ1 = new Ball(qx,qy,0,0,new Color(0,190,0));
//Circle circ1 = new Circle(qx*s,qy*s,radius1*s);
int px = 100;
int py = 130;
//Circle circ2 = new Circle(px*s,py*s,radius2*s);
int vx = 80;
int vy = -40;
Ball circ2 = new Ball(px,py,vx,vy,Color.BLUE);
//Line vec;
double t1, t2;
double wd,ht;
JTextArea area;
boolean flag = true;
JButton button = new JButton("next");
int ns;
study() {
circ1.set_radius(15);
circ2.set_radius(10);
area = new JTextArea(6,20);
//area.setPrefRowCount(6);
area.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
area.setLineWrap(true);
area.setEditable(false);
area.append("Ball study");
solve();
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
int n = (ns+1)%3;
move(n);
repaint();
}
});
addMouseListener( new MouseClickHandler() );
}
// inner class to handle mouse events
private class MouseClickHandler extends MouseAdapter {
public void mouseClicked( MouseEvent e )
{
int x = e.getX();
int y = e.getY();
ns = 0;
if (flag) {
px = x;
py = y;
circ2.px = px;
circ2.py = py;
vx = 0;
vy = 0;
flag= false;
}
else {
vx = x - px;
vy = y - py;
flag = true;
}
solve();
repaint();
}
}
public Dimension getPreferredSize() {
return new Dimension(300,200);
}
public void solve() {
double scl = 10.0;
t1 = t2 = -1;
// relative velocity
double rx = vx/scl;
double ry = vy/scl;
// relative position
double dx = (px - qx)/scl;
double dy = (py - qy)/scl;
// test radius
double r = (circ1.radius + circ2.radius)/scl;
double A = rx*rx+ry*ry;
double B = rx*dx+ry*dy;
double C = dx*dx + dy*dy - r*r;
area.setText("");
area.append(String.format("A %g B %g C %g%n",A,B,C));
double radical = B*B-A*C;
area.append(String.format("radical B*B - A*C = %g%n",radical));
if (C<0) {
area.append(String.format("C<0, balls overlap at start%n"));
}
if (A<=0.0) {
area.append(String.format("A==0, No motion%n"));
return;
}
if (radical<0) {
area.append(String.format("radical < 0, No solution%n"));
return;
}
if (B>0) {
area.append(String.format("B>0, balls moving away from one another%n"));
return;
}
double R = Math.sqrt(radical);
t1 = (-B-R)/A;
t2 = (-B+R)/A;
area.append(String.format("t1 = %g t2 = %g%n",t1,t2));
}
public void move(int pos) {
ns = pos;
if (pos==0) {
circ2.px = px;
circ2.py = py;
}
if (pos==1 && t1>0) {
circ2.px = px+vx*t1;
circ2.py = py+vy*t1;
}
if (pos==2 && t2>0) {
circ2.px = px+vx*t2;
circ2.py = py+vy*t2;
}
}
public void paintComponent(Graphics g)
{
super.paintComponent( g );
circ1.draw(g);
circ2.draw(g);
g.setColor(Color.BLACK);
g.drawLine(px,py,px+vx,py+vy);
}
public static void main( String args[] )
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
study panel = new study();
JFrame application = new JFrame("Ball Study");
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(panel);
application.add(panel.area,BorderLayout.SOUTH);
JPanel top = new JPanel();
top.add(panel.button);
application.add(top,BorderLayout.NORTH);
application.pack();
application.setVisible(true);
}
});
}
}
Maintained by John Loomis, updated Sat Feb 23 15:59:20 2019