找到多边形的面积


9

给定s1, s2, s3... s_n圆内接的n角的连续边长,请找到其面积。您可以假设该多边形存在。另外,多边形将是凸的并且不会自相交,这足以保证唯一性。禁止专门解决此挑战的内置函数以及用于计算外接圆或外接中心的内置函数(这与该挑战的先前版本不同)。

输入:循环多边形的边长;可以作为函数,stdin等的参数。

输出:多边形的面积。

答案应精确到小数点后六位,并且必须在合理的笔记本电脑上运行20秒。

这是代码高尔夫球,所以最短的代码获胜!

具体测试案例:

[3, 4, 5] --> 6
[3, 4, 6] --> 5.332682251925386
[3, 4, 6, 7] --> 22.44994432064365
[5, 5, 5, 5] --> 25
[6, 6, 6, 6, 6] --> 61.93718642120281
[6.974973020933265, 2.2393294197257387, 5.158285083300981, 1.4845682771595603, 3.5957940796134173] --> 21.958390804292847
[7.353566082457831, 12.271766915518073, 8.453884922273897, 9.879017670784675, 9.493366404245332, 1.2050010402321778] --> 162.27641678140589

测试用例生成器:


7
我知道找到外围的简单方法。
mIllIbyte

1
我知道找到边数的简单方法
Luis Mendo

考虑到半径,这个问题很容易实现,但是如果没有它,这将是非常困难的。
poi830 '16

如果少于五个面,也很容易,这在代码高尔夫中并不重要。
尼尔

Answers:


5

Python 2,191字节

from math import*
C=sorted(input());l,h=C[-1]/2,sum(C)
while h-l>1e-9:m=l+h;a=[asin(c/m)for c in C[:-1]];f=pi-sum(a);l,h=[l,m/2,h][m*sin(f)<C[-1]:][:2]
print sum(l*l*sin(2*t)for t in a+[f])/2

使用二分查找法找到半径,然后通过角度/半径计算每个线段的面积。

它通过首先求和除最大和弦角之外的所有和弦,然后检查与剩余和弦的剩余角来找到半径。然后,这些角度也用于计算每个线段的面积。如果段的角度大于180度,则该段的面积可以为负。

可读的实现:

import math

def segment_angles(line_segments, r):
    return [2*math.asin(c/(2*r)) for c in line_segments]

def cyclic_ngon_area(line_segments):
    line_segments = list(sorted(line_segments))
    lo, hi = max(line_segments) / 2, sum(line_segments)
    while hi - lo > 1e-9:
        mid = (lo + hi) / 2
        angles = segment_angles(line_segments[:-1], mid)
        angles.append(2*math.pi - sum(angles))
        if 2 * mid * math.sin(angles[-1]/2) < line_segments[-1]:
            lo = mid
        else:
            hi = mid
    return sum([lo*lo * math.sin(a) / 2 for a in angles])

如果中心在多边形之外,这行得通吗?(例如,边长为6、7、12的三角形)。sqrt(4**2 - c**2/4)当角度大于时,有时需要为负pi
soktinpk

@soktinpk我固定了我的答案。
orlp

0

八度,89字节

r=sum(s=input(''));while sum(a=asin(s/2/r))<pi r*=1-1e-4;b=a;end;disp(sum(cos(b).*s/2*r))

说明

给定一定的半径,a一段长度s所跨越的角度为。它的面积是。2*asin(s/2/r)rcos(a)*s/2*r

算法

  1. 设置r为太大的东西,例如周长。
  2. 如果累积角度小于2pi,请减小r并重复步骤2。
  3. 计算面积。

平均而言,需要设置多少次迭代r?(出于好奇)
soktinpk

这不可能达到要求的精度。重复将半径乘以0.9999可以减小半径,这很容易使所需的6位小数精度不足。
orlp

@soktinpk大约为15000,最大为r*=1-1e-4150000 r*=1-1e-5
Rainer P.

@RainerP。这两个值是相同的。
Fund Monica的诉讼

1
@soktinpk通常不建议对特定答案作例外处理。
Cyoce '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.