找出哪个三角形最接近等边三角形,fastest/simplest 方式

find out which triangle is closest to equilateral triangle, fastest/simplest way

我有大量由三个 3d 点定义的三角形,例如

T1 = ((x1, y1, z1), (x2, y2, z2), (x3, y3, z3))
T2 = ((x1, y1, z1), (x2, y2, z2), (x3, y3, z3))
T3 = ((x1, y1, z1), (x2, y2, z2), (x3, y3, z3))
T4 = ((x1, y1, z1), (x2, y2, z2), (x3, y3, z3))....

我想知道的是,找出这些三角形中哪个最接近等边三角形的最佳方法是什么。 我能想到的最佳策略是,以某种方式计算每个三角形的三个内角,然后得到这三个内角的乘积,然后查看哪个三角形的乘积最大。如果我没有记错的话,三角形越接近等边三角形,三个内角的乘积就越大(当三角形是完全等边三角形时,内角乘积是60乘以60乘以60 = 216000) 但是,我觉得有更好的方法来完成这项任务。 如果您能为我提出更好的解决方案,我将不胜感激。 None 这些三个 3d 点的集合在直线上。 这些三角形中没有长度为0的边。

三角形的面积有一个clever idea due to a math teacher from Brooklyn, New York named Patrick Honner. It is to take the ratio of the area of a triangle to the area of the equilateral triangle which has the same perimeter. This yields a number between 0 and 1, with 1 corresponding to perfectly equilateral. When combined with Heron's formula,你的计算相当简单(尤其是在合并到一个平方根并简化之后)。

这是一个 Python 实现:

import math

#computation given the sides:

def eq(a,b,c):
    p = a+b+c
    s = p/2
    e = p/3
    return math.sqrt((s-a)*(s-b)*(s-c)/(s-e)**3)

def dist(p,q):
    return math.sqrt(sum((x-y)**2 for x,y in zip(p,q)))

#computation given the vertices:
    
def eq_vertices(vertices):
    p,q,r = vertices
    a = dist(p,q)
    b = dist(p,r)
    c = dist(q,r)
    return eq(a,b,c)

def most_equilateral(triangles):
    return max(triangles,key = eq_vertices)

出于测试目的,我写道:

import random

def rand_triangle():
    nums = tuple(random.uniform(0,10) for _ in range(9))
    return nums[:3],nums[3:6],nums[6:]

def rand_triangles(n):
    return [rand_triangle() for _ in range(n)]

p,q,r = most_equilateral(rand_triangles(10**6))
print(p)
print(q)
print(r)
print(dist(p,q),dist(p,r),dist(q,r))

典型输出:

(5.78980790676774, 9.853230008053409, 4.974470485333855)
(8.824990996578379, 4.403159314576518, 3.1039937224539615)
(2.7571861861239597, 5.607135338917225, 1.0725696230700976)
6.512625451616404 6.515438955183434 6.511105693852511

生成 100 万个三角形比找到最等边的三角形花费的时间更长。如果速度是一个问题,您可以考虑从函数 eq 中删除 sqrt,因为这仍然会产生一个取值范围 [0,1].

的函数