Вычислить XY координаты вершины треугольника, зная длинны всех сторон
есть упрошенная формула определения координаты вершины треугольника, если основание треугольника расположено на оси X. (нужно для определения положения при навигации, используя всего 2 точки привязки, вместо 3)
/// <summary>
/// Определение координат вершины треугольника C.
/// по закону косинусов и теореме пифагора можно вычислить позицию тега.
/// Треугольник задан вершинами ABC
/// A находится в начале координат (0,0)
/// B вдоль оси X, (var, 0)
/// </summary>
/// <param name="a">длина стороны CB - расстояние от тега C до якоря B</param>
/// <param name="b">длина стороны CA - расстояние от тега C до якоря A (ОТРЕЗОК ВЫХОДЯЩИЙ ИЗ НАЧАЛА КООРДИНАТ - A (0,0))</param>
/// <param name="c">длина стороны AB - расстояние между якорями A и B</param>
///
/// <returns></returns>
public static (double x, double y) CalculatePosition(double a, double b, double c)
{
var cosA= (b*b + c*c - a*a)/(2*b*c);
var x = b * cosA;
var y = b * Math.Sqrt(1 - cosA * cosA);
return (Math.Round(x, 1, MidpointRounding.AwayFromZero), Math.Round(y, 1, MidpointRounding.AwayFromZero));
}
A (0,0)
B (70,0)
C (x,y)
c= 70
b=58
a= 37
C (x,y) = 50,30
А если вершина B находится не на оси Х? Входные данные для формулы все те же, это длинны сторон (abc), но точка B теперь имеет координаты B (65,25). Точку A (0,0) оставим в начале координат И нужно все также определить координаты точки С.
Ответы (3 шт):
Если вершина A лежит в начале координат, вершина B в точке (x_b,y_b), а расстояния |CA| = b и |CB| = a, то, если Wolfram не врет, координаты двух точек C следующие:
Если есть координаты двух точек, то расстояние между ними вычисляется :) А дальше - два уравнения на расстояние от (x,y) до А и до В - и все, решаемо на уровне квадратных уравнений. Громоздко, да, но - решаемо.
x^2+y^2==b^2
(x-x_b)^2+(y-y_b)^2==a^2
Собственно, вот и все. Ответ - см. выше.
А вот что делать, если
x_b^2 + y_b^2 != c^2
(расстояние |AB| не равно c) — тут уж думайте сами...
Ещё один способ:
-раз уж у вас есть функция для нахождения координат, когда B на оси - грешно её не использовать ещё раз. Найдите координаты сx,сy, как и ранее, как если бы B была на оси, используя длины сторон, а затем поверните их на угол между AB и осью OX. Для поворота нужны косинус и синус этого угла, их выразить из заданных величин нетрудно:
cosa = B.x / c
sina = B.y / c
//а теперь повернём:
C.x = cx * cosa - cy * sina
C.y = cx * sina + cy * cosa
Раз уж вы нашли косинус и синус угла в треугольнике - дальше вы можете просто повернуть на этот угол вектор одной из сторон и получить направление второй стороны, а дальше нужно лишь изменить длину вектора.
Но есть и решение в векторах, вообще без тригонометрии.
Рассмотрим задачу в общем виде: у нас заданы вершины A и B, нам надо найти третью вершину треугольника С зная прилежащие к ней стороны - AC=a и BC=b соответственно. Построим окружности нужных радиусов с центрами в точках A и B, и тогда точка C как раз будет на их пересечении:

Обозначим через rA, rB и rC радиус-векторы точек. Тогда получаем следующую систему уравнений:
(rC-rA)² = a²
(rC-rB)² = b²
Решив её относительно rC можно получить ответ. Для решения первым делом вычтем одно уравнение из другого, чтобы избавиться от квадрата rC:
(rC-rA)² - (rC-rB)² = a² - b²
(rC² - 2rCrA + rA²) - (rC² - 2rCrB + rB²) = a² - b²
2rC(rB-rA) + rA² - rB² = a² - b²
2rC(rB-rA) = a² - b² - (rA² - rB²)
У нас получилось, внезапно или не очень, уравнение прямой в одном из своих форм. Этой прямой по построению принадлежат точки C и C' - значит, это уравнение прямой CC'. Кстати, разности rB - rA будет в дальнейшем встречаться часто, поэтому обозначим её как AB (потому что это и есть вектор стороны AB).
В принципе, на этом этапе можно перейти от векторного вида к координатному, выразить через это уравнение переменную y через x или наоборот, подставить в любое уравнение окружности и решить обыкновенное квадратное уравнение. Однако, любого кто так попытается сделать, ожидает засада под названием "сингулярность": если прямая CC' вертикальная, то при попытке выразить y через x в формуле будет деление на ноль, а если она горизонтальная - деление на ноль будет при попытке выразить x через y.
Можно было бы просто разобрать два случая, но есть вариант лучше. Для этого надо перейти к параметрическому виду уравнения прямой СС'. Напомню, что параметрический вид уравнения прямой выглядит вот так:
r = r0 + t u
Чтобы получить параметрическое уравнение прямой, нужно знать направляющий вектор и любую точку на этой прямой. Точки C и С' мы узнать не можем (точнее можем, но если узнаем - задача будет уже решена), поэтому попытаемся найти точку пересечения прямых CC' и AB.
Это сделать не так сложно как кажется, потому что у нас есть уравнение прямой CC' и мы можем составить параметрическое уравнение прямой AB:
r = rA + tAB
2r·AB = a² - b² - (rA² - rB²)
Подставим первое уравнение во второе и решим его относительно переменной t:
2(rA + tAB)·AB = a² - b² - (rA² - rB²)
2rA·AB + 2t AB² = a² - b² - (rA² - rB²)
t = (a² - b² - rA² + rB² - 2rA·AB) / 2AB²
t = (a² - b² - rA² + rB² + 2rA² - 2rA·rB) / 2AB²
t = (a² - b² + rA² + rB² - 2rA·rB) / 2AB²
t = (a² - b² + (rA - rB)²) / 2AB²
t = (a² - b² + AB²) / 2AB²
Осталось подставить эту переменную обратно в параметрическое уравнение:
t = (a² - b² + AB²) / 2AB²
r0 = rA + tAB
Формула выглядит страшно, но не имеет сингулярностей пока A и B - разные точки. Даже в случае некорректных начальных данных у тут будет какое-то решение.
Кстати, для проверки корректности формулы можно подставить сюда вырожденные треугольники: при a=0, b=AB точка r0 окажется равна rA; а при a=AB, b=0 точка r0 окажется равна rB. Пока всё нормально.
И так, у нас есть точка r0, осталось найти направляющий вектор прямой CC'. Ну, это тоже просто: надо лишь взять вектор AB и повернуть его на прямой угол в любую сторону. Это делается тоже просто, если вектор AB был с координатами (xB - xA, yB - yA) - то повёрнутый будет с координатами (-yB + yA, xB - xA). Почему так - объясняется по ссылке, которую я уже приводил ранее. Обозначим его через AB^.
Ну, теперь у нас есть параметрическое уравнение прямой CC' и уравнение одной из окружностей, осталось их пересечь и мы найдём точки C и C'.
rC = r0 + k AB^
(rC-rA)² = a²
И снова мы можем просто подставить одно уравнение в другое (вот почему я так люблю параметрические уравнения прямых в задачах на геометрию!):
(r0-rA + k AB^)² = a²
k² AB^² + 2k AB^ (r0-rA) + (r0-rA)² - a² = 0
Тут есть и дальнейшие упрощения: вектор r0-rA сонаправлен AB, а потому при умножении на AB^ будет чистый ноль, можно и не считать. Кстати, длина вектора AB^ равна длине вектора AB, что тоже позволяет чуть упростить формулу.
Суммируя всё что написано выше, получаем следующую систему уравнений:
t = (a² - b² + AB²) / 2AB²
k² AB² = a² - t² AB²
r0 = rA + t AB
rC = r0 + k AB^
Осталось решить примитивное квадратное уравнение:
t = (a² - b² + AB²) / 2AB²
k = ± sqrt(a² / AB² - t²)
rC = rA + t AB + k AB^
Дальше осталось перейти от векторов к координатам и решение готово.


