2023-11-13 22:40:23 +03:00
|
|
|
namespace MindBox.Lib;
|
|
|
|
|
|
|
|
public class Triangle : FlatShape
|
|
|
|
{
|
2023-11-16 15:48:44 +03:00
|
|
|
// Может потребоваться хранить разные стороны в разных полях, но для нашей задачи это избыточно
|
2023-11-13 22:40:23 +03:00
|
|
|
private readonly double[] _sides;
|
|
|
|
|
|
|
|
public Triangle(double a, double b, double c)
|
|
|
|
{
|
|
|
|
_sides = new[] { a, b, c };
|
|
|
|
if (_sides.Any(side => side <= 0))
|
|
|
|
{
|
|
|
|
throw new ArgumentException($"Side(s) cannot be non-positive: {string.Join(" ;", _sides.Where(side => side <= 0))}");
|
|
|
|
}
|
|
|
|
if (a >= b + c || b >= c + a || c >= a + b)
|
|
|
|
{
|
|
|
|
throw new ArgumentException($"Sides lengths are not valid: {a}, {b}, {c}");
|
|
|
|
}
|
|
|
|
}
|
2023-11-16 15:48:44 +03:00
|
|
|
/// <summary>
|
|
|
|
/// Вычисление площади реугольника по формуле Герона
|
|
|
|
/// </summary>
|
2023-11-13 22:40:23 +03:00
|
|
|
public override double GetArea()
|
|
|
|
{
|
|
|
|
if (_area != null)
|
|
|
|
{
|
|
|
|
return _area.Value;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
double semiPerimeter = _sides.Sum() / 2;
|
|
|
|
_area = Math.Sqrt(semiPerimeter *
|
|
|
|
(semiPerimeter - _sides[0]) *
|
|
|
|
(semiPerimeter - _sides[1]) *
|
|
|
|
(semiPerimeter - _sides[2]));
|
|
|
|
return _area.Value;
|
|
|
|
}
|
2023-11-16 15:48:44 +03:00
|
|
|
}
|
2023-11-13 22:40:23 +03:00
|
|
|
public bool IsRight()
|
|
|
|
{
|
|
|
|
var sorted = _sides.OrderByDescending(x => x);
|
|
|
|
|
2023-11-16 15:48:44 +03:00
|
|
|
// Самая длинная сторона: гипотенуза
|
2023-11-13 22:40:23 +03:00
|
|
|
double hypotenuse = sorted.First();
|
2023-11-16 15:48:44 +03:00
|
|
|
// Две другие - катеты
|
2023-11-13 22:40:23 +03:00
|
|
|
var catheti = sorted.Skip(1);
|
|
|
|
|
|
|
|
return hypotenuse * hypotenuse == catheti.Sum(x => x * x);
|
2023-11-16 15:48:44 +03:00
|
|
|
}
|
2023-11-13 22:40:23 +03:00
|
|
|
}
|