从面积和角度计算三角形

发布于 2024-09-11 06:48:36 字数 547 浏览 5 评论 0原文

我正在尝试根据面积和角度计算三角形。如果角度 B 为 90°,则该公式有效,但在我的例子中,角度可以为 0.1° 到 179.8°。该公式假设角度为 90 度,所以我在想可能有一些隐藏的东西可以适用于任何角度。公式如下:

替代文字替代文本

代码中的公式是:

Height = sqrt((2 * Area) / (tan(Angle-A)));

我正在寻找公式的后半部分。公式的下一部分是这样的吗:

cos(sin(AngleB))

I'm trying to calculate triangles base on the Area and the angles. If Angle-B is 90° then the formula works, but in my case, the angle can be from 0.1° to 179.8°. The formula assumes that the angle is 90, so I was thinking that there might be something that is hidden that could work for very angle. Here is the formula:

alt text

alt text

The formula in code would be:

Height = sqrt((2 * Area) / (tan(Angle-A)));

I'm looking for the second half of the formula. Would the next part of the formula be something like this:

cos(sin(AngleB))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

沧桑㈠ 2024-09-18 06:48:36

好的,新尝试:如果我的计算正确,B 边等于 sqrt(2*area*sin(angle-B)/(sin(angle-A)*sin(angle-C))

因为 Area = 1/2 * A * B * sin(c) = 1/2 * C * B * sin(a) = 1/2 * A * C * sin(b) 我们得到:

A = 2 * 面积 / (B * sin(c))使用这个我们得到:

C = sin(c) * B / sin(b) 当我们将其放回面积方程时,我们得到:

B = sqrt(2*面积*sin(角度-B)/( sin(angle-A)*sin(angle-C))

当您知道一侧和所有角度时,使用普通三角函数计算另一侧应该很容易。

Okay, new try: If my calculations are correct, side B equals sqrt(2*area*sin(angle-B)/(sin(angle-A)*sin(angle-C))

Since Area = 1/2 * A * B * sin(c) = 1/2 * C * B * sin(a) = 1/2 * A * C * sin(b) we get:

A = 2 * area / (B * sin(c)) and using this we get:

C = sin(c) * B / sin(b) and when we place that back into the equation of area, we get:

B = sqrt(2*area*sin(angle-B)/(sin(angle-A)*sin(angle-C))

When you know one side and all the angles, calculating the other sides should be easy using normal trigonometry.

醉南桥 2024-09-18 06:48:36

tziki的答案是正确的,但我想详细说明它是如何得出的。

我们从已知的角度和面积开始。我将使用 OP 图中的标签来进行解释。

首先,我们有一个基本事实:三角形的面积是其底边和高度的乘积的一半:面积 = 底边 * 高度 / 2。我们希望能够确定底数和高度之间的关系,以便我们可以将该方程简化为一个未知数并求解底数。

另一件需要知道的重要事情是,三角形的高度与 A 边成正比:高度 = A 边 * sin(B 角)。所以知道 A 面就可以得到高度。

现在我们需要在A方和C方(基础)之间建立关系。这里最合适的规则是正弦定律:Side-A/sin(A) = Side-C/sin(C)。我们重新排列此方程,以根据 C 面求出 A 面:A 面 = C 面 * sin(A)/sin(C)

现在,我们可以将此结果代入高度方程,以获得仅以 Side-C 表示的高度公式:height = Side-C * sin(A) * sin(B) / sin(C)

使用 Side-C 作为面积方程的基础,我们现在可以仅根据 Side-C 求面积: 面积 = Side-C^2 * sin(A) * sin(B) / 2sin( C)

然后重新排列这个方程,根据面积找到 C 边:

Side-C = SQRT(2 * Area * sin(C) / (sin(B) * (sin(A)))

这样就得到了一侧。可以重复此操作来找到另一方,或者您可以使用不同的方法来找到了解这一方的另一方。

tziki's answer is correct, but I'd like to elaborate on how it's derived.

We start with angles and area as knowns. I'm going to use the labels in the OP's diagram for this explanation.

First we have the basic truth that the area of a triangle is half the product of its base and height: Area = base * height / 2. We want to be able to determine the relationship between base and height so that we can reduce this equation to one unknown and solve for base.

Another important thing to know is that the height of the triangle is proportional to Side-A: height = Side-A * sin(Angle-B). So knowing Side-A will give us the height.

Now we need to establish a relationship between Side-A and Side-C (the base). The most appropriate rule here is the sine law: Side-A/sin(A) = Side-C/sin(C). We re-arrange this equation to find Side-A in terms of Side-C: Side-A = Side-C * sin(A)/sin(C).

We can now insert this result into the height equation to get the formula for height in terms of Side-C only: height = Side-C * sin(A) * sin(B) / sin(C)

Using Side-C as the base in the area equation, we can now find the area in terms of Side-C only: Area = Side-C^2 * sin(A) * sin(B) / 2sin(C)

Then re-arrange this equation to find Side-C in terms of Area:

Side-C = SQRT(2 * Area * sin(C) / (sin(B) * (sin(A)))

And that gives you one side. This can be repeated to find the other sides, or you can use a different approach to find the other sides knowing this one.

七度光 2024-09-18 06:48:36

你已经有了答案,但前段时间我必须为面试做这样的练习。这并不难,而且我没有花太多时间就得到了以下解决方案。

通读一遍,它应该是不言自明的。

创建一个 Python 模块,通过应用正弦和余弦定理来求解三角形。

该模块接收一些三角形值作为参数,如果可能,返回其所有角度和边长的值。

参数以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 边相反的角度。

测试

You already have your answer, but I had to solve this kind of exercise for a job interview some time ago. It's not hard, and it didn't took me much time to arrive to the following solution.

Read it through and it should be self explanatory.

Create a Python module that solves triangles by aplying the sin and cosin theorems.

The module receives as parameters some of a triangle's values and, if possible, returns the values of all it's angles and side lengths.

The parameters are received as a dict and it should be able to be called stand-alone from the command line.

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 and C are the side lengths and a, b and c are the angles, so c is the angle opposite to the side C.

Tests

那伤。 2024-09-18 06:48:36

如何计算第三个尺寸的长度为 1 的三角形两条边的长度(使用 角度上的正弦定律,该边指定长度 1),然后缩放三角形,直到其面积与您拥有的面积匹配?然后你就可以很容易地计算出高度。 http://en.wikipedia.org/wiki/Triangle_area#Using_trigonometry

How about calculating the lengths of two of the sides of a triangle where the third size is assigned a length of 1 (using the law of sines on the angles, with that side assigned length 1), then scale the triangle until its area matches the area you have? Then you can calculate the height fairly easily. http://en.wikipedia.org/wiki/Triangle_area#Using_trigonometry

阳光下慵懒的猫 2024-09-18 06:48:36

如果我没记错的话,两个角 a 和 b 之间的边 x 的长度应该如下。

         ________________
        /  2A       2A
x =    / ------ + ------
     \/  tan(a)   tan(b)

因此,要计算 C 面,请计算 A 角和 B 角。

(现在仔细检查了它 - 似乎是正确的。)

If I made no mistake the length of a side x between two angles a and b should be the following.

         ________________
        /  2A       2A
x =    / ------ + ------
     \/  tan(a)   tan(b)

So to calculate side-C you but in angle-A and angle-B.

(Now double checked it - seems to be correct.)

金兰素衣 2024-09-18 06:48:36

如果三角形是等腰三角形,则您为 A 边给出的公式似乎是正确的,即角度 B = 角度 C(您可以使用正弦定律和面积的正弦公式得到此公式)。如果不是等腰,你似乎需要知道其他角度;一般公式是:

Side-A = sqrt(2*Area*sin(Angle-A)/(sin(Angle-B)*sin(Angle-C)))

当然,我在脑子里做了这个,所以检查数学;)

编辑:好的,在纸上签入后修复了公式。

The formula you give for Side-A seems to be correct IF the triangle is isosceles, i.e., Angle-B = Angle-C (you get this using the law of sines and the sine formula for the area). If it is not isosceles, you seem to need to know the other angles; the general formula is:

Side-A = sqrt(2*Area*sin(Angle-A)/(sin(Angle-B)*sin(Angle-C)))

Of course, I did this in my head, so check the math ;)

Edit: Ok, fixed the formula after checkin on paper.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文