我正在尝试根据面积和角度计算三角形。如果角度 B 为 90°,则公式有效,但在我的情况下,角度可以从 0.1° 到 179.8°。该公式假设角度为 90,所以我在想可能有一些隐藏的东西可以用于非常角度的工作。这是公式:
代码中的公式为:
Height = sqrt((2 * Area) / (tan(Angle-A)));
我正在寻找公式的后半部分。公式的下一部分会是这样的:
cos(sin(AngleB))
我正在尝试根据面积和角度计算三角形。如果角度 B 为 90°,则公式有效,但在我的情况下,角度可以从 0.1° 到 179.8°。该公式假设角度为 90,所以我在想可能有一些隐藏的东西可以用于非常角度的工作。这是公式:
代码中的公式为:
Height = sqrt((2 * Area) / (tan(Angle-A)));
我正在寻找公式的后半部分。公式的下一部分会是这样的:
cos(sin(AngleB))
好的,新的尝试:如果我的计算是正确的,B 面等于 sqrt(2*area*sin(angle-B)/(sin(angle-A)*sin(angle-C))
由于面积 = 1/2 * A * B * sin(c) = 1/2 * C * B * sin(a) = 1/2 * A * C * sin(b) 我们得到:
A = 2 * area / (B * sin(c)) 并使用它我们得到:
C = sin(c) * B / sin(b) 当我们把它放回面积方程时,我们得到:
B = sqrt(2*面积*sin(角度-B)/(sin(角度-A)*sin(角度-C))
当您知道一侧和所有角度时,使用普通三角法计算另一侧应该很容易。
tziki 的回答是正确的,但我想详细说明它是如何得出的。
我们从已知的角度和面积开始。我将使用 OP 图表中的标签进行解释。
首先,我们有一个基本事实,即三角形的面积是其底和高的乘积的一半:Area = base * height / 2
。我们希望能够确定底数和高度之间的关系,以便我们可以将这个方程简化为一个未知数并求解底数。
另一个重要的事情是三角形的高度与 A 侧成正比:height = Side-A * sin(Angle-B)
。所以知道A面会给我们带来高度。
现在我们需要在 Side-A 和 Side-C(基础)之间建立关系。这里最合适的规则是正弦定律:Side-A/sin(A) = Side-C/sin(C)
. 我们重新排列这个方程以根据 Side-C 找到 Side-A:Side-A = Side-C * sin(A)/sin(C)
。
我们现在可以将此结果插入高度方程,以仅根据 Side-C 获得高度公式:height = Side-C * sin(A) * sin(B) / sin(C)
使用 Side-C 作为面积方程的基础,我们现在可以仅根据 Side-C 找到面积:Area = Side-C^2 * sin(A) * sin(B) / 2sin(C)
然后重新排列这个方程以根据面积找到 Side-C:
Side-C = SQRT(2 * Area * sin(C) / (sin(B) * (sin(A)))
这给了你一方面。这可以重复以找到另一方,或者您可以使用不同的方法来找到知道这一方的另一方。
你已经有了答案,但我前段时间在面试时不得不解决这种练习。这并不难,而且我很快就得出了以下解决方案。
通读一遍,它应该是不言自明的。
创建一个 Python 模块,通过应用 sin 和 cosin 定理来求解三角形。
该模块接收三角形的一些值作为参数,如果可能,返回它的所有角度和边长的值。
参数作为 a 接收,
dict
并且应该能够从命令行独立调用。
from __future__ import division
import sys, logging
from math import radians, degrees, acos, cos, sin, sqrt, asin
class InconsistentDataError(TypeError):
pass
class InsufficientDataError(TypeError):
pass
class NonUpdatable(dict):
"""Dictionary whose items can be set only once."""
def __setitem__(self, i, y):
if self.get(i, None):
raise InconsistentDataError()
super(NonUpdatable, self).__setitem__(i, y)
def get_known_sides(**kwarg):
"""Filter from the input elements the Side elements."""
return dict([i for i in kwarg.iteritems() if i[0].isupper()])
def get_known_angles(**kwarg):
"""Filter from the input elements the Angle elements."""
return dict([i for i in kwarg.iteritems() if i[0].islower()])
def get_opposite_angle(C, B, A):
"""
Get the angle corresponding to C.
Keyword arguments:
A -- right side of the angle (real number > 0)
B -- left side of the angle (real number > 0)
C -- side opposite to the angle (real number > 0)
Returns:
angle opposite to C
"""
return degrees(acos((A**2 + B**2 - C**2) / (2 * A * B)))
def get_side(A, B, c):
"""
Calculate the Side corresponding to the Angle c.
Keyword arguments:
A -- left side of C (real number > 0)
B -- right side of C (real number > 0)
c -- angle opposite to side C (real number)
Returns:
side C, opposite to c
"""
return sqrt(A**2 + B**2 - 2*A*B*cos(radians(c)))
def get_overlapping_angle(known_angles, known_sides):
"""
Calculate the Angle of a known side, knowing the angle to another known side.
Keyword arguments:
known_angles -- (dict of angles)
known_sides -- (dict of sides)
Returns:
angle of the known side, to which there is no known angle
"""
a = (set([i.lower() for i in known_sides.iterkeys()]) -
set([i.lower() for i in known_angles.iterkeys()])).pop()
b = (set([i.lower() for i in known_sides.iterkeys()]) &
set([i.lower() for i in known_angles.iterkeys()])).pop()
y = (known_sides[a.upper()]/known_sides[b.upper()]) * sin(radians(known_angles[b.lower()]))
if y > 1: y = 1 #Rounding error fix --- y = 1.000000000001; asin(y) -> Exception
return {a.lower(): degrees(asin(y))}
def get_angles(A, B, C):
"""
Calculate all the angles, given the length of all the sides.
Keyword arguments:
A -- side A (real number > 0)
B -- side B (real number > 0)
C -- side C (real number > 0)
Returns:
dict of angles
"""
sides = {"A":A,"B":B,"C":C}
_sides = sides.keys()
angles = {}
for side in sides.keys():
angles[side.lower()] = get_opposite_angle(
sides[_sides[0]],
sides[_sides[1]],
sides[_sides[2]])
_sides.append(_sides.pop(0))
return angles
def get_triangle_values(**kwargs):
"""Calculate the missing values of a triangle based on the known values."""
known_params = kwargs
angles = NonUpdatable({
"a":0,
"b":0,
"c":0,
})
sides = NonUpdatable({
"A":0,
"B":0,
"C":0,
})
if len(known_params) < 3:
raise InsufficientDataError("Three parameters are needed to calculate triangle's values.")
if str(known_params.keys()).islower():
raise TypeError("At least one length needed.")
known_sides = NonUpdatable(get_known_sides(**known_params))
sides.update(known_sides)
known_angles = NonUpdatable(get_known_angles(**known_params))
angles.update(known_angles)
if len(known_angles) == 3 and sum(known_angles.itervalues()) != 180:
raise InconsistentDataError("One of the sides is too long.")
if len(known_sides) == 3:
x=[side for side in known_sides.itervalues() if (sum(known_sides.itervalues()) - side) < side]
if len(x):
raise InconsistentDataError("One of the sides is too long.")
for angle, value in get_angles(**known_sides).iteritems():
# Done this way to force exception when overwriting a
# user input angle, otherwise it would be a simple assignment.
# >>> angles = get_angles(**known_sides)
# This means inconsistent input data.
angles[angle] = value
else: # There are angles given and not enough sides.
if len(known_angles) > 1:
#2 angles given. Get last angle and calculate missing sides
for angle, val in angles.iteritems():
if val == 0:
angles[angle] = 180. - sum(angles.itervalues())
known_sides = known_sides.items()
for side, length in sides.iteritems():
if length == 0:
sides[side] = known_sides[0][1] / \
sin(radians(angles[known_sides[0][0].lower()])) * \
sin(radians(angles[side.lower()]))
else:
unknown_side = (set(sides.keys()) - set(known_sides.keys())).pop()
chars = [ord(i.lower()) for i in known_params.iterkeys()]
chars.sort()
if chars[0] < chars[1] < chars[2]:
sides[unknown_side] = get_side(known_sides.values()[0], known_sides.values()[1], known_angles[unknown_side.lower()])
angles = get_angles(**sides)
else:
known_angles.update(get_overlapping_angle(known_angles, known_sides))
angles.update(known_angles)
for angle, val in angles.iteritems():
if val == 0:
angles[angle] = 180. - sum(angles.itervalues())
sides[unknown_side] = get_side(known_sides.values()[0], known_sides.values()[1], angles[unknown_side.lower()])
angles.update(sides)
return angles
if __name__ == "__main__":
try:
values = get_triangle_values( **eval(sys.argv[1], {}, {}) )
except IndexError, e:
values = get_triangle_values(A=10,B=10,C=10)
except InsufficientDataError, e:
print "Not enough data!"
exit(1)
except InconsistentDataError, e:
print "Data is inconsistent!"
exit(1)
print values
A、B 和 C 是边长,a、b 和 c 是角度,因此 c 是与边 C 相对的角度。
如果三角形是等腰三角形,则您为 A 面提供的公式似乎是正确的,即角度-B = 角度-C(您可以使用正弦定律和面积的正弦公式得到这个)。如果不是等腰,你似乎需要知道其他角度;一般公式为:
Side-A = sqrt(2*Area*sin(Angle-A)/(sin(Angle-B)*sin(Angle-C)))
当然,我是在脑海中做到这一点的,所以请检查数学;)
编辑:好的,在纸上签到后修正了公式。
如果我没记错的话,两个角度 a 和 b 之间的边 x 的长度应该如下所示。
________________
/ 2A 2A
x = / ------ + ------
\/ tan(a) tan(b)
因此,要计算边 C,您需要使用角度 A 和角度 B。
(现在仔细检查 - 似乎是正确的。)
如何计算三角形的两条边的长度,其中第三个尺寸的长度为 1(使用角度上的正弦定律,该边的长度为 1),然后缩放三角形直到其面积匹配你有地区吗?然后你可以很容易地计算出高度。http://en.wikipedia.org/wiki/Triangle_area#Using_trigonometry