开发者

Android: optimal way to find shortest distance between Point and Rect?

开发者 https://www.devze.com 2023-02-05 20:15 出处:网络
Seems like there should be some convenient way to do this? I couldn\'t find one, so I threw together the below algorithm.Is it memory/computationally optimal?

Seems like there should be some convenient way to do this?

I couldn't find one, so I threw together the below algorithm. Is it memory/computationally optimal?

Thanks:

Edit: Original algorithm was stupidly wrong, maybe this is better?

public static float minDistance(RectF rect, PointF point)
{
    if(rect.contains(point.x, point.y))
    {
        //North line 
        float distance = point.y - rect.top;

        //East line
        distance = Math.min(distance, point.x - rect.left);

        //South line
        distance = Math.min(distance, rect.bottom - point.y);

        //West line
        distance = Math.min(distance, rect.right - point.x);

        return distance;
    }
    else
    {
        float minX, minY;

        if (point.x < rect.left) 
        {
            minX = rect.left;
        } 
        else if (point.x > rect.right) 
        {
            minX = rect.right;
        } 
        else 
        {
            minX = point.x;
        }

        if (point.y < rect.top) 
        {
            minY = rect.top;
        } 
        else if (point.y > rect.bottom) 
        {
            minY = rect.bottom;
        } 
        else 
        {
            minY = point.y;
        }

        float vectorX = point.x - minX;
        float vectorY = point.y - minY;

        float distance = (float) Math.sqrt((vectorX * vectorX) + (vectorY * vectorY)); 

        return distance;
    }开发者_JS百科
}


Just take the closest point and then get the distance to that. Off the top of my head:

    float closestX, closestY;

    if(point.x >= x1 && point.x <= x2 && point.y >= y1 && point.y <= y2)
    {
         float bestDistance = point.y - y1;
         bestDistance = Math.min(distance, y2 - point.y);
         bestDistance = Math.min(distance, point.x - x1);
         bestDistance = Math.min(distance, x2 - point.x);

         return bestDistance;
    }

    if (point.x < x1) {
        closestX = x1;
    } else if (point.x > x2) {
        closestX = x2;
    } else {
        closestX = point.x;
    }

    if (point.y < x1) {
        closestY = y1;
    } else if (point.y > y2) {
        closestY = y2;
    } else {
        closestY = point.y;
    }

    float vectorY = point.x - closestX;
    float vectorY = point.Y - closestY;

    float distance = sqrtf((vectorX * vectorX) + (vectorY * vectorY));


One optimization is to not use the square root until the end. If you just compare distance squared and then return the sqrt of the smallest distance squared, you only have to do one sqrt.

Edit: Here is a good example of the distance from a point to a line segment (edge of the rect). You can use it, and modify it so that it returns the distance squared instead. Then compare them all and return the sqrt of the min distance squared.

Distance Between Point and Segment


The natural approach is to consider the eight areas outside the square, four corners and four laterals. This gives the shortest distance possible to the border of the square. If the point is inside the square (perhaps a button) then distance is zero, but if a distance is required is the shortest straight to the four borders.

0

精彩评论

暂无评论...
验证码 换一张
取 消