属于多边形的点:C 和 python 中的程序
Point belonging to a polygon : program in C and python
我必须在C
和Python
中编写一个算法来知道一个点是否属于多边形(全部由用户输入)。
我的算法在 python 中有效,但在 C
中无效,而且我找不到我的错误,因为我的调试器代码块拒绝工作。
所以如果有人能告诉我我的错误在哪里,我将不胜感激...
用户被要求提供多边形的顶点数 n≥3
(while
)。
我们询问它们的坐标 (For
),我们将其存储在 2 个数组 (CoordX/CoordY)
) 中。
请求要测试的点的坐标(TestX/TestY
)。
我们找到连接彼此跟随的点的直线方程 (For
)。
一般情况:我们寻找 y = ax + b
.
的 a
和 b
a= (y(i+1) - y(i))/(x(i+1) -x(i)); b=y-ax
特例:
如果 x 处的点 (i+1) - i = 0
那么我们有一条等式线 y = x = k
(常量)和 b = 0; Line = True
。
如果 y 处的点 (i+1) - i = 0
那么我们有一条等式 y = b with a = 0
.
的直线
我们确定该点是否在边界 y(i)
和 y(i+1) (For)
之间,以便知道哪条线将穿过要测试的点:Bound = True/False
,我们将其存储在一个Booleans, TabBorne
.
数组
如果我们将x趋向于无穷大(For),我们计算要测试的点将穿过的线数;我们增加 k(我们注意只使用我们将穿过的线(If))。
y=ax+b<=>x= (y-b)/a,a≠0
特殊情况:如果一个点位于顶点上,则 Vertex = True 并且该点位于图中。
我们计算触摸的行数 % 2 :
如果 = 1,则在多边形内部;
否则就是外面了。
在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.")
在 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;
}
- 第一个问题出在这部分代码中:
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;}
❌
与Python代码相比,应该是这样的:
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;
✅
第二个if
语句的缩进是错误的,但C不关心缩进。
- 第二个问题在这里:
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<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);}}
❌
相对于Python的代码,应该是这样的:
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 不关心缩进,但 关心大括号放在哪里!
- 您代码中的大括号 (
{
}
) 放置样式非常不合常规且难以阅读。我建议切换到一种更流行的样式,例如 K&R style, Allman style, One True Brace style, Whitesmiths style, or (horror of horrors) GNU style.
我必须在C
和Python
中编写一个算法来知道一个点是否属于多边形(全部由用户输入)。
我的算法在 python 中有效,但在 C
中无效,而且我找不到我的错误,因为我的调试器代码块拒绝工作。
所以如果有人能告诉我我的错误在哪里,我将不胜感激...
用户被要求提供多边形的顶点数 n≥3
(while
)。
我们询问它们的坐标 (For
),我们将其存储在 2 个数组 (CoordX/CoordY)
) 中。
请求要测试的点的坐标(TestX/TestY
)。
我们找到连接彼此跟随的点的直线方程 (For
)。
一般情况:我们寻找 y = ax + b
.
a
和 b
a= (y(i+1) - y(i))/(x(i+1) -x(i)); b=y-ax
特例:
如果 x 处的点 (i+1) - i = 0
那么我们有一条等式线 y = x = k
(常量)和 b = 0; Line = True
。
如果 y 处的点 (i+1) - i = 0
那么我们有一条等式 y = b with a = 0
.
我们确定该点是否在边界 y(i)
和 y(i+1) (For)
之间,以便知道哪条线将穿过要测试的点:Bound = True/False
,我们将其存储在一个Booleans, TabBorne
.
如果我们将x趋向于无穷大(For),我们计算要测试的点将穿过的线数;我们增加 k(我们注意只使用我们将穿过的线(If))。
y=ax+b<=>x= (y-b)/a,a≠0
特殊情况:如果一个点位于顶点上,则 Vertex = True 并且该点位于图中。
我们计算触摸的行数 % 2 : 如果 = 1,则在多边形内部; 否则就是外面了。
在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.")
在 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;
}
- 第一个问题出在这部分代码中:
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;}
❌
与Python代码相比,应该是这样的:
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;
✅
第二个if
语句的缩进是错误的,但C不关心缩进。
- 第二个问题在这里:
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<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);}}
❌
相对于Python的代码,应该是这样的:
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 不关心缩进,但 关心大括号放在哪里!
- 您代码中的大括号 (
{
}
) 放置样式非常不合常规且难以阅读。我建议切换到一种更流行的样式,例如 K&R style, Allman style, One True Brace style, Whitesmiths style, or (horror of horrors) GNU style.