三角形内部只有一些点被认为在三角形“内部”

时间:2019-12-11 16:15:47

标签: python pygame trigonometry

我一直在尝试制作一个简单的pygame程序,以检查光标是否在三角形的内部或外部。为此,我先找到较大三角形的面积,然后从鼠标位置到所有三个点制作三个内部三角形,然后找到它们的面积。

根据我的理解,如果三个内部三角形的面积之和等于总面积之和,则该点位于三角形内部。但是,我的代码只返回它在三角形内部特定像素上的三角形内部,而不是整个区域。

我不确定这是数学错误还是编程错误,但这是下面的代码:

import pygame
from math import sqrt

pygame.init()
DISPLAY = pygame.display.set_mode((400, 400))

def drawTriangle(pointA, pointB, pointC, color):
    pygame.draw.polygon(DISPLAY, color, [pointA, pointB, pointC], 5)

def getLine(pointA, pointB):
    return sqrt((pointB[0] - pointA[0])**2 + (pointB[1]-pointA[1])**2)

def getArea(pointA, pointB, pointC):

    AB = getLine(pointA, pointB)
    BC = getLine(pointB, pointC)
    CA = getLine(pointC, pointA)

    s = (AB + BC + CA) / 2

    return sqrt(s*(s-AB) * (s-BC) * (s-CA))

A = [100, 100]
B = [200, 100]
C = [150, 200]
Color = (255, 255, 255)

while(True):

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            break

    mpx, mpy = pygame.mouse.get_pos()
    posArray = [mpx, mpy]

    drawTriangle(A, B, C, Color)

    Area = getArea(A, B, C)

    trigA = getArea(A, B, posArray)
    trigB = getArea(posArray, B, C)
    trigC = getArea(A, posArray, C)

    if(trigA + trigB + trigC == Area):
        Color = (0, 255, 0)

    else:
        Color = (255, 255, 255)

    pygame.display.update()

到目前为止,我最好的猜测是这是一个四舍五入的问题,但我不确定如何解决。我认为通过将第一个if语句设为<=可以解决舍入错误,并且确实可以改善结果,但是仍然不够完美。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:2)

我建议使用更高效的算法来计算三角形的面积。可以在Check whether a given point lies inside a triangle or not处找到算法:

def getArea(pointA, pointB, pointC): 
    x1, y1 = pointA
    x2, y2 = pointB
    x3, y3 = pointC
    return abs((x1*(y2-y3) + x2*(y3-y1)+ x3*(y1-y2))/2.0)

注意,您仍然可以使用自己的算法。但是

  
if(trigA + trigB + trigC == Area):

比较浮点数。由于浮点数的准确性有限,因此该测试失败(请参见Floating-point arithmetic - Accuracy problems)。
您必须考虑 epsilon 。执行abs(a - b) < epsilon而不是a == b。它不是在比较两个对象的值,而是在将差异与足够低的值进行比较,以实际上保证这些值是相同的。例如:

if abs(trigA + trigB + trigC - Area) < 0.001:
    Color = (0, 255, 0)
else:
    Color = (255, 255, 255)

相关问题