Point inside a polygon

Asked

Viewed 1,242 times

1

I need to create a function that checks if a point is inside a polygon. For this, I researched on the Internet some solutions that can help me. I found one that seems to be of great help, but in one of the functions necessary for the functioning of the main function, there was an error. The function is as follows:

// A função checa se o ponto Q está no segmento PR.
bool NoSegmento(Ponto P, Ponto Q, Ponto R)
{
    if (Q.x <= max(P.x, R.x) && Q.x >= min(P.x, R.x) && Q.y <= max(P.y, R.y) 
&& Q.y >= min(P.y, R.y))
        return true;
    return false;
}

However, when compiling, I get some warnings and errors, for example:

implicit declaration of function 'max' [-Wimplicit-function-declaration]|
implicit declaration of function 'min' [-Wimplicit-function-declaration]|
undefined reference to `max'|
undefined reference to `min'|

I wonder if the MAX and MIN functions are functions of some library and what is the purpose of sweating bool type for the function.

  • I’m talking about point-to-polygon belonging in that reply.

  • 1

    About the max/min, that answer says you need to declare these functions/macros.

  • And its function NoSegmento checks whether the point Q is within the rectangle defined by the points P and R, which therefore does not fit into general polygon membership (only rectangles parallel to the axes). It also doesn’t detect if it really belongs to the segment, so the comment is also misleading

3 answers

2


This function checks whether a Ponto is contained within the area occupied by a Rectangle. Points P and R are the coordinates of two opposite vertices of this Rectangle:

retangulo

Assuming Ponto be something like that:

typedef struct _Ponto
{
    int x;
    int y;
} Ponto;

To compile your code in C++:

#include <algorithm>

bool NoRetangulo( Ponto P, Ponto Q, Ponto R )
{
    return( (Q.x <= std::max(P.x, R.x)) && (Q.x >= std::min(P.x, R.x)) &&
            (Q.y <= std::max(P.y, R.y)) && (Q.y >= std::min(P.y, R.y)) );
}

To compile your code in C:

#define max(a,b)  ( (a > b) ? a : b )
#define min(a,b)  ( (a < b) ? a : b )

int NoRetangulo( Ponto P, Ponto Q, Ponto R )
{
    return( (Q.x <= max(P.x, R.x)) && (Q.x >= min(P.x, R.x)) &&
            (Q.y <= max(P.y, R.y)) && (Q.y >= min(P.y, R.y)) );
}

Improving the idea (in C++):

#include <algorithm>


typedef struct Retangulo_
{
    Ponto a;
    Ponto b;
} Retangulo;


int NoRetangulo( Retangulo R, Ponto X )
{
    return( (X.x <= std::max(R.a.x, R.b.x)) && (X.x >= std::min(R.a.x, R.b.x)) &&
            (X.y <= std::max(R.a.y, R.b.y)) && (X.y >= std::min(R.a.y, R.b.y)) );
}
  • I find it strange that the question speaks of generalized polygons, but the rest of the context points to rectangle parallel to the axes

1

Imagem de ponto e vertices

 private void teste()
    {
        double xMax = 0;
        double yMax = 0;
        double xMin = 9999999999999999999;
        double yMin = 9999999999999999999;

        System.Collections.Generic.List<System.Drawing.PointF> listaDePontos = new System.Collections.Generic.List<System.Drawing.PointF>();
        var p1 = new System.Drawing.PointF(2, 8);
        var p2 = new System.Drawing.PointF(6, 2);
        listaDePontos.Add(p1);
        listaDePontos.Add(p2);


        //Cria uma lista de vertices
        System.Collections.Generic.List<System.Drawing.PointF> listaDeVertices = new System.Collections.Generic.List<System.Drawing.PointF>();
        var v1 = new System.Drawing.PointF(5, 8);
        var v2 = new System.Drawing.PointF(9, 1);
        var v3 = new System.Drawing.PointF(1, 1);

        listaDeVertices.Add(v1);
        listaDeVertices.Add(v2);
        listaDeVertices.Add(v3);

        //Calcula o mínimo e máximo de X e Y
        for (int i = 0; i < listaDeVertices.Count; i++)
        {
            xMax = Math.Max(xMax, listaDeVertices[i].X);
            yMax = Math.Max(yMax, listaDeVertices[i].Y);

            xMin = Math.Min(xMin, listaDeVertices[i].X);
            yMin = Math.Max(yMin, listaDeVertices[i].Y);
        }



        foreach (PointF p in listaDePontos)
        {
            if (PontoDentroDoPoligono(p, listaDeVertices))
            {
                //to do 
            }
        }
  }

     private bool PontoDentroDoPoligono(System.Drawing.PointF p,
        System.Collections.Generic.List<System.Drawing.PointF> vertices)
    {
        if (!(p.X >= vertices.Min().X && p.X <= vertices.Max().X && p.Y >= vertices.Min().Y && p.Y <= vertices.Max().Y))
        {
            return false;
        }
        bool result = false;
        int j = vertices.Count - 1;
        for (int i = 0; i < vertices.Count; i++)
        {
            if ((vertices[i].Y < p.Y && vertices[j].Y >= p.Y) || (vertices[j].Y < p.Y && vertices[i].Y >= p.Y))
            {
                if (vertices[i].X + (p.Y - vertices[i].Y) / (vertices[j].Y - vertices[i].Y) * (vertices[j].X - vertices[i].X) < p.X)
                {
                    result = !result;
                }
            }
            j = i;
        }
        return result;
    }

0

The min and max functions are from the library Algorithm of C++ see the reference in the documentation

Add to your code:

#import <algorithm>

and change its function to use the Std namespace:

std::min() e std::max()

Browser other questions tagged

You are not signed in. Login or sign up in order to post.