A.I, Data and Software Engineering

Basic shapes collision detection without complicated maths

B

This article demonstrates the collision between square, circle, and points using Android Kotlin. We will focus on the programming aspect rather than using complicated mathematical equations. A video tutorial is at the end of the article.

Two rectangle collision

Collision Detection - game development

Using complicated math for rectangle collision is not always necessary. Java and Kotlin offer a convenient way to detect the collision with intersect method.

var r1: Rect = Rect(0, 0, 200, 300)
var r2: Rect = Rect(0, 0, 100, 100)
if(r2.intersect(r1)) {
    //collision detected
} else {
    //not collide
}

The approach is useful for game development where objects bounds are rectangles.

Two circle collision

Collision Detection - Happy Coding
Two circle collsion

To detect the collision of two circles, we need to check whether the Euclidean distance between two center points is smaller than the sum of the two radii. In Java and Kotlin, there is no circle class, so we can create one.

class Circle {
   var center = PointF()
   var radius = 50f
}
var c1 = Circle()
var c2 = Circle()
val deltaX = c1.center.x - c2.center.x
val deltaY = c1.center.y - c2.center.y
distance = Math.sqrt(deltaX*deltaX - deltaY*deltaY)
if(distance < c1.radius + c2.radius) {
 //Collision detected
}

Rectangle and Circle collision detection

XNA/Monogame Detecting collision between Circle and Rectangle not working - Stack Overflow

This one is a little bit more complicated. We will divide it into 2 main cases:

  1. The center of the circle is inside the rectangle (very easy and always collide)
  2. The center of the circle is outside the rectangle: we consider the distance of the center to the nearest edge of the rectangle (left, right, top, bottom)

In the following code, we use the same definition for the Circle class. For the first case, we use contains method to verify whether the center of circle c1 is inside the rectangle r1.

private fun collisionDectection() {
        var collided = false
        //case 1: the center of the circle c1 is inside the rect 1
        if(r1.contains(c1.center.x.toInt(), c1.center.y.toInt())){
            collided = true
        } else {
          //case 2: the center is outside the rect1 r1
            var pEdge = PointF()
            //Update x coordinate of pEdge
            if(c1.center.x < r1.left) {
                pEdge.x = r1.left.toFloat()
            } else if(c1.center.x > r1.right) {
                pEdge.x = r1.right.toFloat()
            } else {
                pEdge.x = c1.center.x
            }
            //Update x coordinate of pEdge
            if(c1.center.y < r1.top) {
                pEdge.y = r1.top.toFloat()
            } else if(c1.center.y > r1.bottom) {
                pEdge.y = r1.bottom.toFloat()
            } else{
                pEdge.y = c1.center.y
            }
            val deltaX = c1.center.x - pEdge.x
            val deltaY = c1.center.y - pEdge.y
            val distance = Math.sqrt((deltaX*deltaX + deltaY*deltaY).toDouble())
            collided = (distance <= c1.radius)
        }
        if(collided) {
            //Collision detected here
        } else {
            //do sth else
        }
    }

Point inside/outside Rectangle or Circle

The detection is useful if you want to detect the touch location is inside a certain area. For rectangle, the solution is a one-liner. The following code detects touch in the onTouchEvent method.

 override fun onTouchEvent(event: MotionEvent?): Boolean {
        if(r1.contains(event!!.x.toInt(), event!!.y.toInt())) {
           //touch is inside the rect r1
        } else {
            //outside
        }
        postInvalidate()//redraw
        return true
    }

For the circle, the same technique with two circle collision detection is applied. We need to check the distance of clicked point and the center point is smaller than the radius.

val deltaX = c1.center.x - p.x
val deltaY = c1.center.y - p.y
val distance = Math.sqrt((deltaX*deltaX + deltaY*deltaY).toDouble())
collided = (distance <= c1.radius)

Video tutorial (Kotlin)

Enjoy 10 min exclusive video to create custom views and collision detection.

Useful links

Add comment

A.I, Data and Software Engineering

PetaMinds focuses on developing the coolest topics in data science, A.I, and programming, and make them so digestible for everyone to learn and create amazing applications in a short time.

Categories