Circle-Rectangle collision detection (intersection)

前端 未结 24 1409
无人共我
无人共我 2020-11-22 02:55

How can I tell whether a circle and a rectangle intersect in 2D Euclidean space? (i.e. classic 2D geometry)

24条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-22 03:10

    I've a method which avoids the expensive pythagoras if not necessary - ie. when bounding boxes of the rectangle and the circle do not intersect.

    And it'll work for non-euclidean too:

    class Circle {
     // create the bounding box of the circle only once
     BBox bbox;
    
     public boolean intersect(BBox b) {
        // test top intersect
        if (lat > b.maxLat) {
            if (lon < b.minLon)
                return normDist(b.maxLat, b.minLon) <= normedDist;
            if (lon > b.maxLon)
                return normDist(b.maxLat, b.maxLon) <= normedDist;
            return b.maxLat - bbox.minLat > 0;
        }
    
        // test bottom intersect
        if (lat < b.minLat) {
            if (lon < b.minLon)
                return normDist(b.minLat, b.minLon) <= normedDist;
            if (lon > b.maxLon)
                return normDist(b.minLat, b.maxLon) <= normedDist;
            return bbox.maxLat - b.minLat > 0;
        }
    
        // test middle intersect
        if (lon < b.minLon)
            return bbox.maxLon - b.minLon > 0;
        if (lon > b.maxLon)
            return b.maxLon - bbox.minLon > 0;
        return true;
      }
    }
    
    • minLat,maxLat can be replaced with minY,maxY and the same for minLon, maxLon: replace it with minX, maxX
    • normDist ist just a bit faster method then the full distance calculation. E.g. without the square-root in euclidean space (or without a lot of other stuff for haversine): dLat=(lat-circleY); dLon=(lon-circleX); normed=dLat*dLat+dLon*dLon. Of course if you use that normDist method you'll need to do create a normedDist = dist*dist; for the circle

    See the full BBox and Circle code of my GraphHopper project.

提交回复
热议问题