Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package collision;
- import java.awt.Dimension;
- import java.awt.Graphics;
- import java.awt.Point;
- import java.awt.event.MouseEvent;
- import java.awt.event.MouseListener;
- import java.awt.event.MouseMotionListener;
- import javax.swing.JFrame;
- import javax.swing.JPanel;
- /** Efficient circle / circle collision detection.
- * (c) Keldon Alleyne 2007
- */
- public class CircleCircleCollision {
- public static void main ( String argv [] ) {
- Circle A = new Circle ( 1d, 0,0, new Vector (10d, -1d));
- Circle B = new Circle ( 2d, 20d, 0d, null );
- System.out.println( collisionDistance ( A, B ) );
- JFrame frame = new JFrame ();
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- frame.getContentPane().add( new CircleFrame ());
- frame.pack();
- frame.setVisible(true);
- }
- static double collisionDistance ( Circle A, Circle B ) {
- double x = B.x - A.x;
- double y = B.y - A.y;
- if ( A.velocity == null ) return Double.NaN;
- Vector velocity = A.velocity.normalized();
- double nx = x * velocity.x + y * velocity.y;
- double ny = x * velocity.cross().x + y * velocity.cross().y;
- System.out.println ( "Double nx, ny: " + nx + "," + ny);
- if ( nx <= 0d ) return Double.NaN;
- if ( Math.abs(ny) > (A.radius + B.radius )) return Double.NaN;
- double distance = nx - Math.sqrt( (A.radius+B.radius)*(A.radius+B.radius) - (ny * ny));
- return distance;
- }
- static class Circle {
- double radius;
- double x,y;
- Vector velocity;
- Circle ( double _radius, double _x, double _y, Vector _velocity ) {
- radius = _radius;
- x = _x;
- y = _y;
- velocity = _velocity;
- }
- }
- static class Vector {
- double x,y;
- Vector ( double _x, double _y ) {
- x = _x;
- y = _y;
- }
- Vector cross (){
- return new Vector ( -y, x);
- }
- double length (){
- return Math.sqrt(x*x + y*y);
- }
- Vector normalized (){
- return new Vector ( x / length(), y / length () );
- }
- }
- static class CircleFrame extends JPanel implements MouseListener, MouseMotionListener{
- private static final long serialVersionUID = -7074661778734564087L;
- Circle c1=null,c2=null;
- CircleFrame (){
- setPreferredSize(new Dimension ( 640,480));
- addMouseListener(this);
- addMouseMotionListener(this);
- }
- public void paintComponent ( Graphics g ) {
- super.paintComponent(g);
- int x1,y1,x2,y2;
- if ( c1 != null ) {
- // draw circle
- x1 = (int)(c1.x - c1.radius);
- y1 = (int)(c1.y - c1.radius);
- x2 = (int)(c1.radius*2);
- y2 = (int)(c1.radius*2);
- g.drawOval(x1, y1, x2, y2);
- // draw velocity
- if ( c1.velocity != null ) {
- x1 = (int)c1.x;
- y1 = (int)c1.y;
- x2 = x1 + (int)c1.velocity.x;
- y2 = y1 + (int)c1.velocity.y;
- g.drawLine(x1,y1,x2,y2);
- }
- }
- if ( c2 != null ) {
- // draw circle
- x1 = (int)(c2.x - c2.radius);
- y1 = (int)(c2.y - c2.radius);
- x2 = (int)(c2.radius*2);
- y2 = (int)(c2.radius*2);
- g.drawOval(x1, y1, x2, y2);
- }
- if ( c1 != null & c2 != null ) {
- double distance = collisionDistance (c1, c2 );
- System.out.println(distance);
- if ( ! (Double.isNaN(distance) | Double.isInfinite(distance)) ) {
- x1 = (int)((c1.x - c1.radius) + c1.velocity.normalized().x*distance);
- y1 = (int)((c1.y - c1.radius) + c1.velocity.normalized().y*distance);
- x2 = (int)(c1.radius*2);
- y2 = (int)(c1.radius*2);
- g.drawOval(x1, y1, x2, y2);
- if ( distance <= c1.velocity.length() ){
- g.fillOval(x1, y1, x2, y2);
- }
- }
- }
- }
- Point lDown = null, rDown = null, clDown = null;
- public void mousePressed(MouseEvent e) {
- button = e.getButton();
- switch ( e.getButton ()){
- case MouseEvent.BUTTON1:
- if ( (e.getModifiers() & MouseEvent.CTRL_MASK) != 0 & c1 != null ) {
- int dx = e.getPoint().x - (int)c1.x;
- int dy = e.getPoint().y - (int)c1.y;
- if ( c1!= null ) c1.velocity = new Vector ( (double) dx, (double) dy );
- repaint();
- }
- else lDown = e.getPoint();
- break;
- case MouseEvent.BUTTON3:
- rDown = e.getPoint();
- break;
- }
- }
- int button = -1;
- public void mouseDragged(MouseEvent e) {
- switch ( button){
- case MouseEvent.BUTTON1:
- if ( (e.getModifiers() & MouseEvent.CTRL_MASK ) > 0 ){
- int dx = e.getPoint().x - (int)c1.x;
- int dy = e.getPoint().y - (int)c1.y;
- if ( c1!= null ) c1.velocity = new Vector ( (double) dx, (double) dy );
- repaint();
- } else {
- if ( lDown != null ) {
- int dx = e.getPoint().x - lDown.x;
- int dy = e.getPoint().y - lDown.y;
- double radius = (double)((dx > dy ? dx : dy) >> 1 );
- if ( radius < 0 ) radius = -radius;
- if ( radius != 0 ){
- c1 = new Circle (radius,(double)(lDown.x + radius), (double)(lDown.y+ radius), null);
- if ( dx < 0 ) c1.x -= radius*2;
- if ( dy < 0 ) c1.y -= radius*2;
- }
- repaint();
- }
- }
- break;
- case MouseEvent.BUTTON3:
- if ( rDown != null ) {
- int dx = e.getPoint().x - rDown.x;
- int dy = e.getPoint().y - rDown.y;
- double radius = (double)((dx > dy ? dx : dy) >> 1 );
- if ( radius < 0 ) radius = -radius;
- if ( radius != 0 ){
- c2 = new Circle (radius,(double)(rDown.x + radius), (double)(rDown.y+ radius), null);
- if ( dx < 0 ) c2.x -= radius*2;
- if ( dy < 0 ) c2.y -= radius*2;
- }
- repaint();
- }
- break;
- }
- }
- public void mouseReleased(MouseEvent e) {
- button = -1;
- switch ( e.getButton ()){
- case MouseEvent.BUTTON1:
- if ( (e.getModifiers() & MouseEvent.CTRL_MASK ) > 0 ){
- int dx = e.getPoint().x - (int)c1.x;
- int dy = e.getPoint().y - (int)c1.y;
- if ( c1!= null ) c1.velocity = new Vector ( (double) dx, (double) dy );
- repaint();
- } else {
- if ( lDown != null ) {
- int dx = e.getPoint().x - lDown.x;
- int dy = e.getPoint().y - lDown.y;
- double radius = (double)((dx > dy ? dx : dy) >> 1 );
- if ( radius < 0 ) radius = -radius;
- if ( radius != 0 ){
- c1 = new Circle (radius,(double)(lDown.x + radius), (double)(lDown.y+ radius), null);
- if ( dx < 0 ) c1.x -= radius*2;
- if ( dy < 0 ) c1.y -= radius*2;
- }
- repaint();
- lDown = null;
- }
- }
- break;
- case MouseEvent.BUTTON3:
- if ( rDown != null ) {
- int dx = e.getPoint().x - rDown.x;
- int dy = e.getPoint().y - rDown.y;
- double radius = (double)((dx > dy ? dx : dy) >> 1 );
- if ( radius < 0 ) radius = -radius;
- if ( radius != 0 ){
- c2 = new Circle (radius,(double)(rDown.x + radius), (double)(rDown.y+ radius), null);
- if ( dx < 0 ) c2.x -= radius*2;
- if ( dy < 0 ) c2.y -= radius*2;
- }
- repaint();
- rDown = null;
- }
- break;
- }
- }
- public void mouseClicked(MouseEvent arg0) { }
- public void mouseEntered(MouseEvent arg0) { }
- public void mouseExited(MouseEvent arg0) { }
- public void mouseMoved(MouseEvent arg0) {
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment