验证鼠标在三角形内的位置 - Python
Verifying Mouse Position Within Triangle - Python
**这是编程课程的一部分,要求我们使用的模块一般不会用到。我会尽我所能解释我的代码(虽然它很容易解释)
编辑:如果你很好奇,我必须使用 Myro,我用来获取鼠标点击坐标的代码是:mouseX, mouseY = win.getMouse() # "win" refers to a Window object
我正在创建 "buttons" 当点击时执行某种形式的操作。我使用了三种不同的形状:矩形、圆形和三角形。
对于矩形:
# The numbers used in this example are the coordinates on an XY plane
# mouseX refers to the X coord of a recent mouse click; mouseY on the Y axis
if mouseX >= 70 and mouseX <= 120:
if mouseY >= 10 and mouseY <= 35:
print("rectangle button clicked")
对于圈子,我得到了this question的帮助,最后得到了这个代码:
# mouseX and mouseY, same as rectangle example
if sqrt((mouseX-660)**2 + (mouseY-270)**2) <= 30:
print("circle button clicked")
我尝试使用的最后一个形状是三角形。我不确定如何确保 mouseX
和 mouseY
在形状的坐标范围内。我在数学方面相当糟糕,但我假设有一些可以使用的公式(例如圆圈示例)。非常感谢。
定义你的三角形和鼠标坐标:
并定义两个向量u
和v
的二维叉积:
如果向量 u
位于 v
的 右侧 ,则为正,如果位于左侧,则为负。
所以你要找的四个条件是:
...鼠标点击。
(可以使用涉及点积的替代方法,但它涉及效率相当低的平方根)
抱歉缺少代码 - 我讨厌 Python(是的,我说过)。但这应该提供您实现它所需的数学知识。
使用叉积 - 必须全部为正或全部为负。
def line_point_pos(start, end, point):
"""right: negative, left: positive, onedge: zero"""
A = end[0]-start[0], end[1]-start[1]
B = point[0]-start[0], point[1]-start[1]
# return z-component of cross product
return A[0]*B[1] - A[1]*B[0]
def in_polygon(vertices, point, onedges=True):
"""find out if the point is inside the polygon"""
edges = zip(vertices, vertices[1:] + [vertices[0]])
zs = [line_point_pos(s, e, point) for s,e in edges]
if 0 in zs:
return onedges
return all(z>0 for z in zs) or all(z<0 for z in zs)
triangle = [(1, 1), (10, 1), (5, 10)]
a = 5, 10
print(in_polygon(triangle, a)) # True
我在 this 问题中找到了答案,是用 C 语言编写的(我相信)。我已将代码重写为 Python,并将留在这里供其他人使用。
代码:
def sign(p1, p2, p3): #all Points
return (p1.getX() - p3.getX()) * (p2.getY() - p3.getY()) - (p2.getX() - p3.getX()) * (p1.getY() - p3.getY())
def inTriangle(pt, v1, v2, v3): #all Points, pt = mouse, v = triangle vertex
b1 = sign(pt, v1, v2) < 0.0
b2 = sign(pt, v2, v3) < 0.0
b3 = sign(pt, v3, v1) < 0.0
return ((b1 == b2) and (b2 == b3))
测试:
mouseX, mouseY = win.getMouse() #Myro module, win = Window object
a = Point(662,200)
b = Point(1,1)
print(inTriangle(a, Point(661,156), Point(633,217), Point(688,218))) #TRUE!
print(inTriangle(b, Point(661,156), Point(633,217), Point(688,218))) #FALSE!
triangle = [Point(661, 156), Point(633, 217), Point(688, 218)]
if inTriangle(Point(mouseX, mouseY), triangle[0], triangle[1], triangle[2]):
print("clicked up")
**这是编程课程的一部分,要求我们使用的模块一般不会用到。我会尽我所能解释我的代码(虽然它很容易解释)
编辑:如果你很好奇,我必须使用 Myro,我用来获取鼠标点击坐标的代码是:mouseX, mouseY = win.getMouse() # "win" refers to a Window object
我正在创建 "buttons" 当点击时执行某种形式的操作。我使用了三种不同的形状:矩形、圆形和三角形。
对于矩形:
# The numbers used in this example are the coordinates on an XY plane
# mouseX refers to the X coord of a recent mouse click; mouseY on the Y axis
if mouseX >= 70 and mouseX <= 120:
if mouseY >= 10 and mouseY <= 35:
print("rectangle button clicked")
对于圈子,我得到了this question的帮助,最后得到了这个代码:
# mouseX and mouseY, same as rectangle example
if sqrt((mouseX-660)**2 + (mouseY-270)**2) <= 30:
print("circle button clicked")
我尝试使用的最后一个形状是三角形。我不确定如何确保 mouseX
和 mouseY
在形状的坐标范围内。我在数学方面相当糟糕,但我假设有一些可以使用的公式(例如圆圈示例)。非常感谢。
定义你的三角形和鼠标坐标:
并定义两个向量u
和v
的二维叉积:
如果向量 u
位于 v
的 右侧 ,则为正,如果位于左侧,则为负。
所以你要找的四个条件是:
...鼠标点击。
(可以使用涉及点积的替代方法,但它涉及效率相当低的平方根)
抱歉缺少代码 - 我讨厌 Python(是的,我说过)。但这应该提供您实现它所需的数学知识。
使用叉积 - 必须全部为正或全部为负。
def line_point_pos(start, end, point):
"""right: negative, left: positive, onedge: zero"""
A = end[0]-start[0], end[1]-start[1]
B = point[0]-start[0], point[1]-start[1]
# return z-component of cross product
return A[0]*B[1] - A[1]*B[0]
def in_polygon(vertices, point, onedges=True):
"""find out if the point is inside the polygon"""
edges = zip(vertices, vertices[1:] + [vertices[0]])
zs = [line_point_pos(s, e, point) for s,e in edges]
if 0 in zs:
return onedges
return all(z>0 for z in zs) or all(z<0 for z in zs)
triangle = [(1, 1), (10, 1), (5, 10)]
a = 5, 10
print(in_polygon(triangle, a)) # True
我在 this 问题中找到了答案,是用 C 语言编写的(我相信)。我已将代码重写为 Python,并将留在这里供其他人使用。
代码:
def sign(p1, p2, p3): #all Points
return (p1.getX() - p3.getX()) * (p2.getY() - p3.getY()) - (p2.getX() - p3.getX()) * (p1.getY() - p3.getY())
def inTriangle(pt, v1, v2, v3): #all Points, pt = mouse, v = triangle vertex
b1 = sign(pt, v1, v2) < 0.0
b2 = sign(pt, v2, v3) < 0.0
b3 = sign(pt, v3, v1) < 0.0
return ((b1 == b2) and (b2 == b3))
测试:
mouseX, mouseY = win.getMouse() #Myro module, win = Window object
a = Point(662,200)
b = Point(1,1)
print(inTriangle(a, Point(661,156), Point(633,217), Point(688,218))) #TRUE!
print(inTriangle(b, Point(661,156), Point(633,217), Point(688,218))) #FALSE!
triangle = [Point(661, 156), Point(633, 217), Point(688, 218)]
if inTriangle(Point(mouseX, mouseY), triangle[0], triangle[1], triangle[2]):
print("clicked up")