[Math] Detect when a point belongs to a bounding box with distances

analytic geometrycomputational geometrydifferential-geometrygeometryvector-spaces

I have a box with known bounding coordinates (latitudes and longitudes): latN, latS, lonW, lonE.

I have a mystery point P with unknown coordinates. The only data available is the distance from P to any point p. dist(p,P).`

I need a function that tells me whether this point is inside or outside the box.

Best Answer

Once we know the coordinates of P then the problem revers to a well known answer. To get the coordinates of $P=(x, y)$ we take three measurements. I have moved the coordinate system onto one corner and named the objects accordingly, with $a$ the horizontal side and $b$ the vertical side. In addition, we are going to find the coordinates of P in polar notation, with the distance $r$ and angle $\theta$.

Figure

Measuring $\vec{AP}$ we get the distance $r$. Measuring $\vec{BP}$ gives us the cosine and measuring $\vec{DP}$ gives us the sine, by means of the law of cosines.

$$ \cos\theta = \frac{r^2+a^2-d_{BP}^2}{2 a r} $$ $$ \sin\theta = \frac{r^2+b^2-d_{DP}^2}{2 b r} $$

So the location of P is

$$ x = r \cos\theta = d_{AP} \frac{r^2+a^2-d_{BP}^2}{2 a r} $$ $$ y = r \sin\theta = d_{AP} \frac{r^2+b^2-d_{DP}^2}{2 b r} $$

The point is inside if $x>=0$ and $x<=a$ and $y>=0$ and $y<=b$.

I have checked this with the above C# code

static void Main(string[] args)
{

    double a=2;
    double b=1;

    Point A=new Point(0, 0);
    Point B=new Point(a, 0);
    Point D=new Point(0, b);

    for(double x=-5; x<=5; x+=0.5)
    {
        for(double y=-5; y<=5; y+=0.5) 
        {
            Point P=new Point(x, y);

            double d_AP=A.DistanceTo(P);
            double d_BP=B.DistanceTo(P);
            double d_DP=D.DistanceTo(P);

            double r=d_AP;
            double cos=(a*a+r*r-d_BP*d_BP)/(2*a*r);
            double sin=(b*b+r*r-d_DP*d_DP)/(2*b*r);                    

            double x_P=r*cos;
            double y_P=r*sin;

            P.inside=(x_P>=0&&x_P<=a)&&(y_P>=0&&y_P<=b);

            Point Q=new Point(x_P, y_P);
            if(P.DistanceTo(Q)>1e-6)
            {
                Console.WriteLine("({0},{1}) - ({2},{3})", x, y, x_P, y_P);
            }
        }
    }

}

public struct Point
{
    double x, y;  //private, not visible
    public bool inside;

    public Point(double x, double y)
    {
        this.x=x;
        this.y=y;
        this.inside=false;
    }

    public double DistanceTo(Point p)
    {
        return Math.Sqrt((p.x-x)*(p.x-x)+(p.y-y)*(p.y-y));
    }
}

and it all checks out ok. No need to check for signs and quadrants. It all works out cleanly.