Ball Study

Download Java source from study.zip

Opening screenAfter pressing next button once

After pressing next button again

Use mouse to locate new starting point and direction.

   

Also see Ball.java


study.java

import 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