-1

I have to write an algorithm in C and Python to know if a point belongs to a polygon or not (all entered by the user). My algorithm works in python but the C one doesn't work and I can't find my errors since my debugger code blocks refuse to work. So if someone could tell me where my error is, I would be very grateful...

The user is asked for the number of vertices of the polygon n≥3 (while). We ask for their coordinates (For) which we store in 2 arrays (CoordX/CoordY). The coordinates of the point to be tested are requested (TestX/TestY). We find the equations of lines connecting the points that follow each other (For). General case: we look for a and b of y = ax + b.

a= (y(i+1) - y(i))/(x(i+1) -x(i)); b=y-ax

Special case: if the point at x, (i+1) - i = 0 then we have a line of equation y = x = k (constant) with b = 0; Line = True. if the point at y, (i+1) - i = 0 then we have a line with equation y = b with a = 0.

We determine if the point is between the bounds y(i) and y(i+1) (For) in order to know which line will cross the point to be tested: Bound = True/False, which we store in an array of Booleans, TabBorne.

We count the number of lines that the point to be tested will cross if we tend x towards infinity (For); we increment k (we take care to use only the lines that we will cross (If)).

y=ax+b<=>x= (y-b)/a,a≠0

Special case: if a point lies on a vertex, Vertex = True and the point lies in the figure.

We count the number of lines touched % 2 : If = 1, it is inside the polygon; Otherwise, it is outside.

In Python:

n=0
NbCroise = 0
k = 0
CoordX = [0]*100
CoordY = [0]*100
TabA=[0]*100
TabB=[0]*100
Ligne=[0]*100
TabBorne = [0]*100
Droite = [0]*100


while n<3:
    n = int(input("Entrer le nombre de sommets >=3 : "))


for i in range (n):
    CoordX[i] = float(input("Valeur de x : "))
    CoordY[i] = float(input("Valeur de y : "))


TestX = float (input("Valeur x du point à tester : "))
TestY = float (input("Valeur y du point à tester : "))


for i in range (n-1):
    if CoordX[i+1]-CoordX[i]==0 or CoordY[i+1]-CoordY[i]==0:
        if CoordX[i+1]-CoordX[i]==0 :
            TabA[i] = CoordX[i]
            TabB[i] = 0
            Ligne[i] = True
        else :
            TabA[i] = 0
            TabB[i] = CoordY[i]
            Ligne[i] = False
    else :
        TabA[i] = (CoordY[i+1]-CoordY[i])/(CoordX[i+1]-CoordX[i])
        TabB[i] = (CoordY[i]-TabA[i]*CoordX[i])
        Ligne[i] = False
         
if CoordX[n-1]-CoordX[0]==0 or CoordY[n-1]-CoordY[0]==0:
    if CoordX[n-1]-CoordX[0]==0 :
            TabA[n-1] = CoordX[0]
            TabB[n-1] = 0
            Ligne[n-1] = True
    else :
            TabA[n-1] = 0
            TabB[n-1] = CoordY[0]
            Ligne[n-1] = False
else :
        TabA[n-1] = (CoordY[n-1]-CoordY[0])/(CoordX[n-1]-CoordX[0])
        TabB[n-1] = (CoordY[0]-TabA[n-1]*CoordX[0])
        Ligne[n-1] = False 
        
        
for i in range (n-1) :
    Borne = False
    if (CoordY[i]<=TestY and CoordY[i+1]>=TestY) or (CoordY[i]>=TestY and CoordY[i+1]<=TestY):
        Borne = True
    TabBorne[i] = Borne
       
Borne = False
if (CoordY[n-1]<=TestY and CoordY[0]>=TestY) or (CoordY[n-1]>=TestY and CoordY[0]<=TestY):
        Borne = True
TabBorne[n-1] = Borne


for i in range (n):
    if TabBorne[i] == True:
        if Ligne[i] == True:
            Droite[k] = TabA[i]
        elif TabA[i] != 0 :
            Droite[k] = ((TestY-TabB[i])/TabA[i])
        k = k + 1
     
               
for i in range (k):
    if TestX<=Droite[i]:
               NbCroise = NbCroise+1
     

Sommet = False
for i in range(n):
    if TestX == CoordX[i] and TestY == CoordY[i]:
        Sommet = True
        

if Sommet == True:     
    print ("Le point est dans la figure.")
elif NbCroise % 2 == 0:
    print ("Le point n'est pas dans la figure.")
else:
    print ("Le point est dans la figure.")

In C:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i, n, k, NbCroise, Borne, Sommet, TabBorne[100], Ligne[100];
    float TestX, TestY, CoordX[100], CoordY[100], TabA[100], TabB[100], Droite[100];

    Sommet = 0;
    NbCroise = 0;
    k = 0;
    n = 0;

    while (n<3)
        {printf("Entrer le nombre de sommets >=3 \n");
        scanf ("%d", &n) ;}

    for (i=0;i<n;i=i+1)
        {printf("Valeur de x :\n");
        scanf ("%f", &CoordX[i]);
        printf("Valeur de y :\n");
        scanf ("%f", &CoordY[i]);}

    printf("Valeur x du point a tester :\n");
    scanf ("%f", &TestX);
    printf("Valeur y du point a tester :\n");
    scanf ("%f", &TestY);

    for (i=0;i<(n-1);i=i+1)
        {if (((CoordX[i+1]-CoordX[i])==0) || ((CoordY[i+1]-CoordY[i])==0))
            {if ((CoordX[i+1]-CoordX[i])==0)
                {TabA[i] = CoordX[i];
                TabB[i] = 0;
                Ligne[i] = 1;}
            else
                {TabA[i] = 0;
                TabB[i] = CoordY[i];
                Ligne[i] = 0;}}
        else
            {TabA[i] = ((CoordY[i+1]-CoordY[i])/(CoordX[i+1]-CoordX[i]));
            TabB[i] = (CoordY[i]-(TabA[i]*CoordX[i]));
            Ligne[i] = 0;}
        }

    if (((CoordX[n-1]-CoordX[0])==0) || ((CoordY[n-1]-CoordY[0])==0))
            {if ((CoordX[n-1]-CoordX[0])==0)
                {TabA[n-1] = CoordX[0];
                TabB[n-1] = 0;
                Ligne[n-1] = 1;}
            else
                {TabA[n-1] = 0;
                TabB[n-1] = CoordY[0];
                Ligne[n-1] = 0;}}
    else
        {TabA[n-1] = ((CoordY[n-1]-CoordY[0])/(CoordX[n-1]-CoordX[0]));
        TabB[n-1] = (CoordY[0]-(TabA[n-1]*CoordX[0]));
        Ligne[n-1] = 0;}


    for (i=0;i<(n-1);i=i+1)
        {Borne = 0;
        if (((CoordY[i]<=TestY) && (CoordY[i+1]>=TestY)) || ((CoordY[i]>=TestY) && (CoordY[i+1]<=TestY)))
            {Borne = 1;
            TabBorne[i] = Borne;}}

    Borne = 0;
        if (((CoordY[n-1]<=TestY) && (CoordY[0]>=TestY)) || ((CoordY[n-1]>=TestY) && (CoordY[0]<=TestY)))
            {Borne = 1;
            TabBorne[n-1] = Borne;}

    for (i=0;i<n;i=i+1)
        {if (TabBorne[i] == 1)
            {if (Ligne[i] == 1)
                {Droite[k] = TabA[i];}
                k = (k+1);}
            else if (TabA[i] != 0)
                {Droite[k] = ((TestY-TabB[i])/TabA[i]);
                k = (k+1);}}

    for (i=0;i<k;i=i+1)
        {if (TestX <= Droite[i])
            NbCroise = (NbCroise + 1);}


    for (i=0;i<n;i=i+1)
        {if ((TestX == CoordX[i]) && (TestY == CoordY[i]))
            Sommet = 1;}


    if (Sommet == 1)
        {printf("Le point est dans la figure.\n");}
    else if (NbCroise % 2 == 0)
        {printf("Le point n'est pas dans la figure.\n");}
    else
        {printf("Le point est dans la figure.\n");}

    return 0;
}
Carlo Prato
  • 326
  • 4
  • 21
Bnj_euw
  • 3
  • 2
  • 1
    Can you please specify what does "belong to a polygon" mean? Should it be in the inside area of the polygon? Or on one of the edges? – Stef May 28 '21 at 12:05
  • 1
    Besides, it would help if you provide a simple input example where the program fails. – Damien May 28 '21 at 12:10
  • 1
    Simply take your failing example and debug it in python and c and compare the debugging information, – MrSmith42 May 28 '21 at 12:11
  • 1
    The nesting of `TabBorne[i] = Borne;` and `TabBorne[n-1] = Borne;` is different in the C and Python code. Also, the conditions for setting `k = (k + 1);` are different in the C and Python code. – Ian Abbott May 28 '21 at 12:19
  • if the point belongs to the polygon or if it lies on a point of the polygon – Bnj_euw May 28 '21 at 12:28
  • the technique used is to count the number of edges touched by the point if we tend x to +infinity – Bnj_euw May 28 '21 at 12:29
  • I used a randomly created polygon: A(-6;-1) B(-4;-4) C(-4;3) D(-3;4) E(-2;-5) F(-6;-6) And I test the following points: G(-5;-4) supposed to be inside, H(-1;-2) supposed to be outside, I(-3;-3) supposed to be inside, J(-8;-8) supposed to be outside – Bnj_euw May 28 '21 at 12:39
  • Can you provide sample inputs, for both false and true answers? And then, can you provide sample inputs that work in your Python code but not in your C code? – joanis May 28 '21 at 12:40
  • You posted as I was writing. :) That's helpful, but can you provide these as cut-and-pastable program input? – joanis May 28 '21 at 12:42
  • I would really like to do it but being still very young at programming, I don't really know how I can do it – Bnj_euw May 28 '21 at 12:44

1 Answers1

0
  1. The first problem is in this part of the code:
    for (i=0;i<(n-1);i=i+1)
        {Borne = 0;
        if (((CoordY[i]<=TestY) && (CoordY[i+1]>=TestY)) || ((CoordY[i]>=TestY) && (CoordY[i+1]<=TestY)))
            {Borne = 1;
            TabBorne[i] = Borne;}}

    Borne = 0;
        if (((CoordY[n-1]<=TestY) && (CoordY[0]>=TestY)) || ((CoordY[n-1]>=TestY) && (CoordY[0]<=TestY)))
            {Borne = 1;
            TabBorne[n-1] = Borne;}

Comparing it to the Python code, it should be like this:

    for (i=0;i<(n-1);i=i+1)
        {Borne = 0;
        if (((CoordY[i]<=TestY) && (CoordY[i+1]>=TestY)) || ((CoordY[i]>=TestY) && (CoordY[i+1]<=TestY)))
            {Borne = 1;}
        TabBorne[i] = Borne;}

    Borne = 0;
        if (((CoordY[n-1]<=TestY) && (CoordY[0]>=TestY)) || ((CoordY[n-1]>=TestY) && (CoordY[0]<=TestY)))
            {Borne = 1;}
        TabBorne[n-1] = Borne;

The indentation on the second if statement is wrong, but C does not care about indentation.

  1. The second problem is here:
    for (i=0;i<n;i=i+1)
        {if (TabBorne[i] == 1)
            {if (Ligne[i] == 1)
                {Droite[k] = TabA[i];}
                k = (k+1);}
            else if (TabA[i] != 0)
                {Droite[k] = ((TestY-TabB[i])/TabA[i]);
                k = (k+1);}}

If the above code was indented to match to the placement of the { } braces, it would look like this:

    for (i=0;i<n;i=i+1)
        {if (TabBorne[i] == 1)
            {if (Ligne[i] == 1)
                {Droite[k] = TabA[i];}
            k = (k+1);}
        else if (TabA[i] != 0)
            {Droite[k] = ((TestY-TabB[i])/TabA[i]);
        k = (k+1);}}

Comparing to the Python code, it should be like this:

    for (i=0;i<n;i=i+1)
        {if (TabBorne[i] == 1)
            {if (Ligne[i] == 1)
                {Droite[k] = TabA[i];}
            else if (TabA[i] != 0)
                {Droite[k] = ((TestY-TabB[i])/TabA[i]);}
            k = (k+1);}}

C does not care about indentation, but it does care where you put the braces!

  1. The brace ({ }) placement style in your code is very unconventional and hard to read. I would recommend switching to one of the more popular styles such as K&R style, Allman style, One True Brace style, Whitesmiths style, or (horror of horrors) GNU style.
Ian Abbott
  • 15,083
  • 19
  • 33