判断某个点是不是在某个区域内,用到的一个方法是这个点往右延伸成线段,然后计算这个线段与多边形区域线段交点的个数,交点个数为奇数则该点在内。也可以是这个点往上,往下,往左,自己规定。
代码里用了cv来辅助看看有没有判断对,自行处理。
import cv2
def draw_img(point_list,point,is_in):
# 将点依次连接,并将需要判断的点画出来
img_path = r'C:UsersAdministratorDesktopmytable.jpg'
img = cv2.imread(img_path)
img = cv2.resize(img, (700, 450))
for i in range(len(point_list)-1):
x1 = point_list[i][0]
y1 = point_list[i][1]
x2 = point_list[i+1][0]
y2 = point_list[i+1][1]
cv2.line(img,(x1,y1),(x2,y2),(0,255,255),2)
xb = point_list[0][0]
yb = point_list[0][1]
xe = point_list[-1][0]
ye = point_list[-1][1]
cv2.line(img, (xb, yb), (xe, ye), (0, 255, 255), 2)
if is_in:
cv2.circle(img, point, 3, (0, 0, 0), 4)
else:
cv2.circle(img,point,3,(255,255,255),4)
cv2.imshow('a',img)
cv2.waitKey(2000)
def judge_line(point_line,point):
#判断点往右延伸是否与线段相交,相交返回true,不想交返回false
x = point[0]
y = point[1]
x1 = point_line[0][0]
y1 = point_line[0][1]
x2 = point_line[1][0]
y2 = point_line[1][1]
if y1 > y2: #确认在上方的点,用该点做减数来计算斜率
ymax = y1
xmax = x1
ymin = y2
xmin = x2
else:
ymax = y2
ymin = y1
xmax = x2
xmin = x1
if y >= ymax or y <= ymin: #点不在线段的垂直范围里不可能相交
return False
if x >= max(x1,x2): #点在线段的右侧也不可能相交
return False
k_line = 0
k_point = 0
if x1 == x2: #针对横坐标或纵坐标相等做的一些处理
k_line = 100
if y1 == y2:
k_line = 0.01
if k_line == 0:
k_line = (ymax-ymin)/(xmax-xmin)
if x == xmax:
k_point = 100
if y == ymax:
k_point = 0.01
if k_point == 0:
k_point = (ymax-y)/(xmax-x)
if k_line > 0: #线段斜率可能是正负,点可能在线段的左右侧,分类讨论
if k_point < k_line:
return True
else:
return False
else:
if k_point>0:
return True
else:
if k_line > k_point:
return True
return False
def judge_in(point_list,point):
# 该点向右的射线与多边形的交点数为奇数则在多边形内,偶数则在外
# 遍历线段,比较y值,point的y处于线段y值中间则相交
# 多边形坐标按下笔顺序,因为顺序不同,多边形围合的形状也不同,比如五个点,可以使五角星,也可是五边形
# 在多边形内返回true,不在返回false
num_intersect = 0 # 交点数
num_intersect_vertex = 0 #点与顶点的纵坐标相同的数量,用一下方法纵坐标相同时会计算两次交点数(一个点是两个线段的顶点),最后减去(相当于只计算一次)
for item in point_list:
if item[1] == point[1]:
num_intersect_vertex += 1
x = point[0]
y = point[1]
for i in range(len(point_list)-1):
point_line = [point_list[i],point_list[i+1]]
if judge_line(point_line,point):
num_intersect += 1
xb = point_list[0][0] #首尾坐标的线段
yb = point_list[0][1]
xe = point_list[-1][0]
ye = point_list[-1][1]
point_lines = [(xb,yb),(xe,ye)]
if judge_line(point_lines,point):
num_intersect += 1
print("与多变形交点的个数为:%d"%num_intersect)
num_intersect -= num_intersect_vertex
if num_intersect > 0 and num_intersect%2==1:
return True
else:
return False
#线是黄色的,点在区域里则点是黑色,否则为白色
point_list = [(100,100),(100,300),(200,200)]
point = (150,200)
is_in = judge_in(point_list,point)
draw_img(point_list,point,is_in)
下面是几张效果图



