如何确定某个点的坐标是否在某个4边形范围内的问题。
在这里使用一个非常简单的方法。matplotlib.path
# -*- coding:utf-8 -*-
from matplotlib.path import Path
import numpy as np
import math
def cos_dist(a, b):
if len(a) != len(b):
return None
part_up = 0.0
a_sq = 0.0
b_sq = 0.0
for a1, b1 in zip(a, b):
part_up += a1*b1
a_sq += a1**2
b_sq += b1**2
part_down = math.sqrt(a_sq*b_sq)
if part_down == 0.0:
return None
else:
return part_up / part_down
def order_points_quadrangle(pts):
# pts: 4x2 np.array
# sort the points based on their x-coordinates
xSorted = pts[np.argsort(pts[:, 0]), :]
# grab the left-most and right-most points from the sorted
# x-roodinate points
leftMost = xSorted[:2, :]
rightMost = xSorted[2:, :]
# now, sort the left-most coordinates according to their
# y-coordinates so we can grab the top-left and bottom-left
# points, respectively
leftMost = leftMost[np.argsort(leftMost[:, 1]), :]
(tl, bl) = leftMost
# now that we have the top-left and bottom-left coordinate, use it as an
# base vector to calculate the angles between the other two vectors
vector_0 = np.array(bl - tl)
vector_1 = np.array(rightMost[0] - tl)
vector_2 = np.array(rightMost[1] - tl)
angle = [np.arccos(cos_dist(vector_0, vector_1)), np.arccos(cos_dist(vector_0, vector_2))]
(br, tr) = rightMost[np.argsort(angle), :]
# return the coordinates in top-left, top-right,
# bottom-right, and bottom-left order
return np.array([tl, tr, br, bl], dtype="float32")
def point_in_quadrilateral(point, quadrilateral):
# quadrilateral: 4x2 list
# point: 1x2 list or nx2 list
# np.random.shuffle(quadrilateral)
# print("shuffled coordinate:", quadrilateral)
quadrilateral = order_points_quadrangle(np.reshape(np.array(quadrilateral), (4, 2))) # 把坐标按照顺时针排列
# print("sorted coordinate: \n", quadrilateral)
p = Path(quadrilateral)
res = p.contains_points(point)
return res
if __name__ == "__main__":
# 设定四个点来限定一个四边形的界限
shape = [(0, 0), (0, 1), (2, 1), (1, 0)]
point = [(0.1, -1), (0.5, 0.5)]
res = point_in_quadrilateral(point, shape)
print(res)
输出:[False True]
这里其实是用(0, 0), (0, 1), (2, 1), (1, 0)四个顶点限定了一个四边形,然后查看新点(0.1, -1)是否在这四个点所围成的矩形内。
运行上面的代码,得到的结果为:array([ True]),说明点(0.1, -1) 在这个矩形内。