如何使用 Python 和 DLib 找到线的左侧或右侧的点?
how to find a point is on left or right side of line using Python and DLib?
我正在尝试在 Dlib/OpenCV/Numpy/Scipy 中找到现有的 API 以找出线的左侧或右侧的点。
import dlib
a = dlib.point(0, 0)
b = dlib.point(20, 20)
line = dlib.line(a, b)
dlib.distance_to_line(line, dlib.point((-50, 4))) # provides absolute distance.
正在搜索解决方案
一个简单的 API 告诉它是一条线的 left/right 侧。
example
dlib.where_is_the_point(line, dlib.point((-50, 4)) # if returns negative means left side.
我目前的解决方案
我写了一个数学来找到一个点是左边还是右边。所以下面的函数 returns a d
,根据 d
的符号我可以判断它是左还是右。一种硬编码方式,不喜欢下面的解决方案。
def where_it_is(self, target: Point):
d = (target.x - self.p1[0]) * (self.p2[1] - self.p1[1]) - (target.y - self.p1[1]) * (self.p2[0] - self.p1[0])
return d
我希望您参考 Math StackExchange 上的这一点:https://math.stackexchange.com/questions/274712/calculate-on-which-side-of-a-straight-line-is-a-given-point-located. Simply put, given that you have three points: A point that denotes the beginning of the line, a point that denotes the end of the line and a query point, you can calculate the cross product between these three points and check the sign of the result. In fact, this answer on Stack Overflow uses this to determine if a point is on the left of a line: How to tell whether a point is to the right or left side of a line。
我们可以使用此行为来帮助定义一个点是向左还是向右,并且可以根据您使用 Python 和 DLib 的事实进行调整。因此,如果叉积的符号为正,则该点位于直线的左侧。如果符号为负,则该点位于直线的右侧。如果叉积为 0,则该点在线上共线。由于数值不精确,与 0 进行精确比较是非常危险的,因为在大多数情况下,精确到 0 的情况很少见,因此与 0 进行比较可能会得到错误的结果。因此,您需要查看该值是否小于一个小阈值,比如 1e-9
用于共线检查。
对于您的示例线,请注意它本质上是 y = x
因此我们绝对可以定义应该出现在线的左侧和右侧的众所周知的点。
因此:
def where_it_is(line, point):
aX = line.p1.x
aY = line.p1.y
bX = line.p2.x
bY = line.p2.y
cX = point.x
cY = point.y
val = ((bX - aX)*(cY - aY) - (bY - aY)*(cX - aX))
thresh = 1e-9
if val >= thresh:
return "left"
elif val <= -thresh:
return "right"
else:
return "point is on the line"
要对此进行测试:
import dlib
a = dlib.point(0, 0)
b = dlib.point(20, 20)
line = dlib.line(a, b)
pt1 = dlib.point(2, -2) # Should appear on the right
pt2 = dlib.point(5, 10) # Should appear on the left
pt3 = dlib.point(2, 2) # Point should be collinear
print(where_it_is(line, pt1))
print(where_it_is(line, pt2))
print(where_it_is(line, pt3))
我已经将点定义为在线的左侧、右侧和共线。我们得到:
In [40]: %paste
print(where_it_is(line, pt1))
print(where_it_is(line, pt2))
print(where_it_is(line, pt3))
## -- End pasted text --
right
left
point is on the line
我正在尝试在 Dlib/OpenCV/Numpy/Scipy 中找到现有的 API 以找出线的左侧或右侧的点。
import dlib
a = dlib.point(0, 0)
b = dlib.point(20, 20)
line = dlib.line(a, b)
dlib.distance_to_line(line, dlib.point((-50, 4))) # provides absolute distance.
正在搜索解决方案
一个简单的 API 告诉它是一条线的 left/right 侧。
example
dlib.where_is_the_point(line, dlib.point((-50, 4)) # if returns negative means left side.
我目前的解决方案
我写了一个数学来找到一个点是左边还是右边。所以下面的函数 returns a d
,根据 d
的符号我可以判断它是左还是右。一种硬编码方式,不喜欢下面的解决方案。
def where_it_is(self, target: Point):
d = (target.x - self.p1[0]) * (self.p2[1] - self.p1[1]) - (target.y - self.p1[1]) * (self.p2[0] - self.p1[0])
return d
我希望您参考 Math StackExchange 上的这一点:https://math.stackexchange.com/questions/274712/calculate-on-which-side-of-a-straight-line-is-a-given-point-located. Simply put, given that you have three points: A point that denotes the beginning of the line, a point that denotes the end of the line and a query point, you can calculate the cross product between these three points and check the sign of the result. In fact, this answer on Stack Overflow uses this to determine if a point is on the left of a line: How to tell whether a point is to the right or left side of a line。
我们可以使用此行为来帮助定义一个点是向左还是向右,并且可以根据您使用 Python 和 DLib 的事实进行调整。因此,如果叉积的符号为正,则该点位于直线的左侧。如果符号为负,则该点位于直线的右侧。如果叉积为 0,则该点在线上共线。由于数值不精确,与 0 进行精确比较是非常危险的,因为在大多数情况下,精确到 0 的情况很少见,因此与 0 进行比较可能会得到错误的结果。因此,您需要查看该值是否小于一个小阈值,比如 1e-9
用于共线检查。
对于您的示例线,请注意它本质上是 y = x
因此我们绝对可以定义应该出现在线的左侧和右侧的众所周知的点。
因此:
def where_it_is(line, point):
aX = line.p1.x
aY = line.p1.y
bX = line.p2.x
bY = line.p2.y
cX = point.x
cY = point.y
val = ((bX - aX)*(cY - aY) - (bY - aY)*(cX - aX))
thresh = 1e-9
if val >= thresh:
return "left"
elif val <= -thresh:
return "right"
else:
return "point is on the line"
要对此进行测试:
import dlib
a = dlib.point(0, 0)
b = dlib.point(20, 20)
line = dlib.line(a, b)
pt1 = dlib.point(2, -2) # Should appear on the right
pt2 = dlib.point(5, 10) # Should appear on the left
pt3 = dlib.point(2, 2) # Point should be collinear
print(where_it_is(line, pt1))
print(where_it_is(line, pt2))
print(where_it_is(line, pt3))
我已经将点定义为在线的左侧、右侧和共线。我们得到:
In [40]: %paste
print(where_it_is(line, pt1))
print(where_it_is(line, pt2))
print(where_it_is(line, pt3))
## -- End pasted text --
right
left
point is on the line