使用列表元素的定义来决定给出最小答案的元素

Using definition on elements of a list to decide which give smallest answer

在下面的代码中,我计算了哪些三角形覆盖了某个点。现在我试图让函数 perimeter 计算可以在 triangle_fit 中找到的左边三角形的周长。当我知道这些三角形的周长时,我想选择最小的三角形。我做了一些尝试,但函数只能识别 x1y1x2....

import itertools
import math

def area(x1, y1, x2, y2, x3, y3):
    return abs((x1 * (y2 - y3) + x2 * (y3 - y1)
                + x3 * (y1 - y2)) / 2.0)


def isInside(x1, y1, x2, y2, x3, y3, x, y):
    A = area (x1, y1, x2, y2, x3, y3)
    A1 = area (x, y, x2, y2, x3, y3)
    A2 = area (x1, y1, x, y, x3, y3)
    A3 = area (x1, y1, x2, y2, x, y)
    if(A == A1 + A2 + A3):
        return True
    else:
        return False


def perimeter (x1, y1, x2, y2, x3, y3):
    return abs(math.sqrt((x1-x2)**2+(y1-y2)**2)+math.sqrt((x2-x3)^2
               +(y2-y3)**2)+math.sqrt((x3-x1)**2+(y3-y1)**2))


points = [(0,10), (0,0), (10,0), (10,10), (5,2), (2,2)]
P = (5,1)
triangle_fit = []

for triangle in itertools.combinations(points, 3):
    p1, p2, p3 = triangle
    if isInside(*p1, *p2, *p3, *P):
       triangle_fit.append(triangle)

print(triangle_fit)

您可以通过按周长对三角形列表进行排序,将较小的三角形移到开头(请注意,如果周长相同,则可能有多个最小的三角形)。

为了使这更容易,我更改了 perimeter() 函数的调用顺序以接受三点的序列以匹配 triangle_fit 列表内容的格式。我还将其更改为使用 math.hypot() 函数来计算每对点之间的 Euclidean-distance。这样做不仅使速度更快,还修复了代码中的错误我注意到您在哪里使用 ^ 而不是 ** 进行求幂。

import itertools
import math

def area(x1, y1, x2, y2, x3, y3):
    return abs((x1 * (y2 - y3) +
                x2 * (y3 - y1) +
                x3 * (y1 - y2)) / 2.0)


def is_inside(x1, y1, x2, y2, x3, y3, x, y):
    A = area(x1, y1, x2, y2, x3, y3)
    A1 = area(x, y, x2, y2, x3, y3)
    A2 = area(x1, y1, x, y, x3, y3)
    A3 = area(x1, y1, x2, y2, x, y)
    return A == A1 + A2 + A3


def perimeter(points):
    (x1, y1), (x2, y2), (x3, y3) = points
    return (math.hypot(x1-x2, y1-y2) +
            math.hypot(x2-x3, y2-y3) +
            math.hypot(x3-x1, y3-y1))


points = [(0,10), (0,0), (10,0), (10,10), (5,2), (2,2)]
P = (5,1)
triangle_fit = []

for triangle in itertools.combinations(points, 3):
    p1, p2, p3 = triangle
    if is_inside(*p1, *p2, *p3, *P):
       triangle_fit.append(triangle)

triangle_fit.sort(key=perimeter)  # Sort by perimeter.

for points in triangle_fit:
    print(f'{points}: area={area(*points[0], *points[1], *points[2]):.2f}')