Rect与Circle重叠有三种情况:
1. Rect至少有一个角在Circle里面
2. Circle与Rect的左边或右边相交,或者Circle在Rect内
3. Circle与Rect的顶边或底边相交,或者Circle在Rect内
判断代码:
1 public static boolean IsInside( float x, float y, Circle circle ){ 2 float disX = x - circle.x; 3 float disY = y - circle.y; 4 return disX*disX + disY*disY <= circle.radius*circle.radius; 5 } 6 7 public static float Distance( float x1, float y1, float x2, float y2 ){ 8 return (float)Math.sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) ); 9 } 10 11 public static boolean IsOverlap( Rectangle rect0, Circle circle0 ){ 12 float x1 = rect0.x, y1 = rect0.y, w = rect0.width, h = rect0.height; 13 float cx1 = x1+w/2, cy1 = y1+h/2; 14 float x2 = circle0.x, y2 = circle0.y, r = circle0.radius; 15 /////overlap with the corners 16 if( IsInside(x1,y1,circle0) || IsInside(x1+w,y1,circle0) || IsInside(x1,y1+h,circle0) || IsInside(x1+w,y1+h,circle0) ){ 17 return true; 18 } 19 ////overlap with the left or the right edge or s inside of the rect 20 if( Distance( cx1, cy1, x2, y2 )<w/2+r && Math.abs( cy1-y2 )<h/2 ){ 21 return true; 22 } 23 ////overlap with the top or the bottom edge or s inside of the rect 24 if( Distance( cx1, cy1, x2, y2 )<h/2+r && Math.abs( cx1-x2 )<w/2 ){ 25 return true; 26 } 27 28 return false; 29 }
完整实例代码:
1 package com.fxb.newtest; 2 3 import com.badlogic.gdx.ApplicationAdapter; 4 import com.badlogic.gdx.Gdx; 5 import com.badlogic.gdx.Input; 6 import com.badlogic.gdx.graphics.Color; 7 import com.badlogic.gdx.graphics.GL10; 8 import com.badlogic.gdx.graphics.g2d.BitmapFont; 9 import com.badlogic.gdx.graphics.g2d.SpriteBatch; 10 import com.badlogic.gdx.graphics.glutils.ShapeRenderer; 11 import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; 12 import com.badlogic.gdx.math.Circle; 13 import com.badlogic.gdx.math.Rectangle; 14 15 public class Lib032_CircleRect extends ApplicationAdapter{ 16 17 Rectangle rect; 18 Circle circle; 19 ShapeRenderer rend; 20 SpriteBatch batch; 21 BitmapFont font; 22 23 public static boolean IsInside( float x, float y, Circle circle ){ 24 float disX = x - circle.x; 25 float disY = y - circle.y; 26 return disX*disX + disY*disY <= circle.radius*circle.radius; 27 } 28 29 public static float Distance( float x1, float y1, float x2, float y2 ){ 30 return (float)Math.sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) ); 31 } 32 33 public static boolean IsOverlap( Rectangle rect0, Circle circle0 ){ 34 float x1 = rect0.x, y1 = rect0.y, w = rect0.width, h = rect0.height; 35 float cx1 = x1+w/2, cy1 = y1+h/2; 36 float x2 = circle0.x, y2 = circle0.y, r = circle0.radius; 37 /////overlap with the corners 38 if( IsInside(x1,y1,circle0) || IsInside(x1+w,y1,circle0) || IsInside(x1,y1+h,circle0) || IsInside(x1+w,y1+h,circle0) ){ 39 return true; 40 } 41 ////overlap with the left or the right edge or s inside of the rect 42 if( Distance( cx1, cy1, x2, y2 )<w/2+r && Math.abs( cy1-y2 )<h/2 ){ 43 return true; 44 } 45 ////overlap with the top or the bottom edge or s inside of the rect 46 if( Distance( cx1, cy1, x2, y2 )<h/2+r && Math.abs( cx1-x2 )<w/2 ){ 47 return true; 48 } 49 50 return false; 51 } 52 53 @Override 54 public void create() { 55 // TODO Auto-generated method stub 56 super.create(); 57 58 rect = new Rectangle( 10, 10, 100, 50 ); 59 circle = new Circle( 400, 240, 100 ); 60 61 rend = new ShapeRenderer(); 62 batch = new SpriteBatch(); 63 font = new BitmapFont(); 64 font.setColor( Color.BLACK ); 65 66 } 67 68 @Override 69 public void render() { 70 // TODO Auto-generated method stub 71 super.render(); 72 73 Gdx.gl.glClearColor( 1, 1, 1, 1 ); 74 Gdx.gl.glClear( GL10.GL_COLOR_BUFFER_BIT ); 75 76 float step = 1.5f; 77 if( Gdx.input.isKeyPressed( Input.Keys.LEFT ) ){ 78 rect.x -= step; 79 } 80 else if( Gdx.input.isKeyPressed( Input.Keys.RIGHT ) ){ 81 rect.x += step; 82 } 83 else if( Gdx.input.isKeyPressed( Input.Keys.UP ) ){ 84 rect.y +=step; 85 } 86 else if( Gdx.input.isKeyPressed( Input.Keys.DOWN ) ){ 87 rect.y -= step; 88 } 89 90 if( Gdx.input.isKeyPressed( Input.Keys.A ) ){ 91 rect.width -= step; 92 } 93 else if( Gdx.input.isKeyPressed( Input.Keys.D ) ){ 94 rect.width += step; 95 } 96 else if( Gdx.input.isKeyPressed( Input.Keys.W ) ){ 97 rect.height +=step; 98 } 99 else if( Gdx.input.isKeyPressed( Input.Keys.S ) ){ 100 rect.height -= step; 101 } 102 103 rend.begin( ShapeType.Line ); 104 rend.setColor( Color.BLUE ); 105 rend.rect( rect.x, rect.y, rect.width, rect.height ); 106 rend.circle( circle.x, circle.y, circle.radius ); 107 rend.end(); 108 109 String str; 110 if( IsOverlap( rect, circle ) ){ 111 str = "true"; 112 } 113 else{ 114 str = "false"; 115 } 116 117 batch.begin(); 118 font.draw( batch, str, 750, 20 ); 119 batch.end(); 120 121 } 122 123 @Override 124 public void dispose() { 125 // TODO Auto-generated method stub 126 super.dispose(); 127 } 128 129 }
运行结果:
演示了四种相交的情形,其他右下角显示为false