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 fixed point Circle/Circle collision detection.
- */
- public class FCircleCircleCollision {
- public static void main ( String argv [] ) {
- Circle A = new Circle ( 0,0, 1);
- Circle B = new Circle ( 20, 0, 2 );
- A.velocity = new Vector (10, -1);
- System.out.println( collisionDistance ( A, B ) );
- JFrame frame = new JFrame ("Fixed-point Moving circle/circle collision");
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- frame.getContentPane().add( new CircleFrame ());
- frame.pack();
- frame.setVisible(true);
- }
- static int collisionDistance ( Circle A, Circle B ) {
- if ( A.velocity == null ) return Integer.MAX_VALUE;
- Vector v = new FVector ( A.velocity ).transform(new Vector(B.x - A.x,B.y - A.y));
- int nx = v.x;
- int ny = v.y;
- System.out.println ( "Integer nx,ny: " + nx + "," + ny );
- if ( nx <= 0 ) return Integer.MAX_VALUE;
- if ( Math.abs(ny) > (A.radius+B.radius)) return Integer.MAX_VALUE;
- int distance = nx - (int)(Math.sqrt((double)((A.radius+B.radius)*(A.radius+B.radius) - (ny * ny))));
- return distance;
- }
- static class Circle {
- int x, y, radius;
- Vector velocity = null;
- Circle(int _x, int _y, int _radius) {
- x = _x;
- y = _y;
- radius = _radius;
- }
- /** return whether this point is contained within the circle) */
- boolean contains(int px, int py) {
- int r = radius * radius;
- px -= x;
- py -= y;
- px *= px;
- py *= py;
- return (px + py) <= r;
- }
- public String toString (){
- return "("+x+","+y+",r="+radius+")";
- }
- }
- /**
- * Fixed point vector
- * @author Keldon
- *
- */
- static class FVector {
- int x, y;
- public FVector(Vector v) {
- x = v.x << 16;
- y = v.y << 16;
- }
- public FVector ( int _x, int _y ) {
- x = _x;
- y = _y;
- }
- public FVector copy (){
- return new FVector ( x,y);
- }
- public void cross() {
- int nx, ny;
- nx = -y;
- ny = x;
- x = nx;
- y = ny;
- }
- public int getLength() {
- long lx = (long)x;
- long ly = (long)y;
- return (int)Math.sqrt((lx*lx) + (ly*ly));
- }
- /**
- * will transform v to a position relative to the plane where this vector is the x axis;
- * for example if this vector were (1,0) then the returned vector would be the same. But if this
- * vector were (0,1) then the returned vector would appear to have been rotated 90 degrees!
- * @param v
- * @return
- */
- public Vector transform ( Vector v ) {
- int nx,ny;
- FVector x,y;
- x = copy();
- x.normalize();
- y = x.copy();
- y.cross();
- nx = x.x * v.x + x.y * v.y;
- ny = y.x * v.x + y.y * v.y;
- nx = nx >> 16;
- ny = ny >> 16;
- return new Vector (nx,ny);
- }
- public void normalize() {
- int length = getLength();
- if (length == 0)
- length = 1;
- x = (int)(((long)x << 16 ) / (long)length);
- y = (int)(((long)y << 16 ) / (long)length);
- }
- public String toString() {
- return x + ",\t" + y;
- }
- }
- static class Vector {
- int x, y;
- public Vector(int _x, int _y) {
- x = _x;
- y = _y;
- }
- public void cross() {
- int nx, ny;
- nx = -y;
- ny = x;
- x = nx;
- y = ny;
- }
- public int getLength() {
- return (int) Math.sqrt((x * x) + (y * y));
- }
- Vector copy() {
- return new Vector(x, y);
- }
- public String toString() {
- return x + ",\t" + y;
- }
- }
- 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 ) {
- int distance = collisionDistance (c1, c2 );
- System.out.println(distance);
- if ( distance != Integer.MAX_VALUE ) {
- int vx = (c1.velocity.x*distance) / c1.velocity.getLength();
- int vy = (c1.velocity.y*distance) / c1.velocity.getLength();
- x1 = (int)((c1.x - c1.radius) + vx);
- y1 = (int)((c1.y - c1.radius) + vy);
- x2 = (int)(c1.radius*2);
- y2 = (int)(c1.radius*2);
- g.drawOval(x1, y1, x2, y2);
- if ( distance <= c1.velocity.getLength() ){
- 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 ( dx, 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 ( dx, dy );
- repaint();
- } else {
- if ( lDown != null ) {
- int dx = e.getPoint().x - lDown.x;
- int dy = e.getPoint().y - lDown.y;
- int radius = (dx > dy ? dx : dy) >> 1;
- if ( radius < 0 ) radius = -radius;
- if ( radius != 0 ){
- c1 = new Circle (lDown.x + radius, lDown.y+ radius, radius);
- 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;
- int radius = (dx > dy ? dx : dy) >> 1;
- if ( radius < 0 ) radius = -radius;
- if ( radius != 0 ){
- c2 = new Circle (rDown.x + radius, rDown.y+ radius,radius);
- 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 (dx, dy );
- repaint();
- } else {
- if ( lDown != null ) {
- int dx = e.getPoint().x - lDown.x;
- int dy = e.getPoint().y - lDown.y;
- int radius = (dx > dy ? dx : dy) >> 1 ;
- if ( radius < 0 ) radius = -radius;
- if ( radius != 0 ){
- c1 = new Circle (lDown.x + radius, lDown.y+ radius,radius);
- 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;
- int radius = (dx > dy ? dx : dy) >> 1;
- if ( radius < 0 ) radius = -radius;
- if ( radius != 0 ){
- c2 = new Circle (rDown.x + radius, rDown.y+ radius,radius);
- 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