有一个简化的公式来确定三角形顶点的坐标,如果三角形的底位于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 不在 x 轴上怎么办?公式的输入数据仍然是相同的,它是边长 (abc),但点 B 现在有坐标 B (65.25)。让我们将点 A (0,0) 留在坐标原点 我们仍然需要确定点 C 的坐标。
另一种方式:
- 因为你已经有一个当 B 在轴上时查找坐标的功能 - 不再使用它是一种罪过。像以前一样找到坐标
сx,сy
,就像 B 在轴上一样,使用边的长度,然后将它们旋转 AB 和 OX 轴之间的角度。对于旋转,需要这个角度的余弦和正弦,从给定的值不难表达它们:既然你已经在三角形中找到了角度的余弦和正弦,那么你可以简单地将其中一个边的向量旋转这个角度并得到第二个边的方向,然后你只需要改变长度向量。
但是向量中也有一个解,根本没有三角函数。
笼统地考虑这个问题:我们已经给定了顶点 A 和 B,我们需要知道三角形 C 的第三个顶点,知道它的相邻边——分别为 AC=a 和 BC=b。让我们以 A 点和 B 点为中心建立所需半径的圆,然后点 C 将正好在它们的交点处:
用rA、rB和rC表示点的半径向量。然后我们得到以下方程组:
通过解决关于rC的问题,您可以获得答案。为了解决这个问题,我们首先从另一个方程中减去一个方程来去掉平方rC:
无论是否突然,我们都拥有其中一种形式的直线方程。通过构造,点C和C'属于这条线,这意味着这是线CC'的方程。顺便说一句,rB - rA的差值以后会经常出现,所以我们记为AB(因为这是边向量AB)。
原则上,在这个阶段,你可以从向量视图切换到坐标视图,通过这个方程表示变量y到x ,反之亦然,将其代入任何圆方程并求解一个普通的二次方程。然而,任何试图这样做的人都会陷入被称为“奇点”的伏击:如果线 CC' 是垂直的,那么当您尝试通过x表示y时,公式将除以零,如果它是水平的,则除当您尝试通过y表达x时,将为零。
可以只分析两种情况,但有更好的选择。为此,我们必须转到直线 CC' 方程的参数形式。让我提醒您,直线方程的参数形式如下所示:
要得到一条直线的参数方程,你需要知道方向向量和这条直线上的任意一点。我们无法找到点 C 和 C'(更准确地说,我们可以,但如果我们找到了,问题就已经解决了),所以我们将尝试找到线 CC' 和 AB 的交点。
这并不像看起来那么难,因为我们有线 CC' 的方程,我们可以制作线 AB 的参数方程:
将第一个方程代入第二个方程并针对变量t求解:
仍需将此变量代入参数方程:
这个公式看起来很吓人,但只要 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'。
同样,我们可以将一个方程插入另一个方程(这就是为什么我非常喜欢几何问题中的线参数方程!):
这里有进一步的简化:向量r0 - rA共同指向AB,因此,当乘以AB^时,将有一个纯零,你不能数。顺便说一句,向量AB^的长度等于向量AB的长度,这也让我们可以稍微简化公式。
总结上面写的所有内容,我们得到以下方程组:
剩下的就是求解一个原始的二次方程:
然后剩下的就是从向量移动到坐标,解决方案就准备好了。
如果顶点 A 位于原点,则顶点 B 位于 (x_b,y_b),距离 |CA| = b 和 |CB| = a,那么,如果 Wolfram 是对的,那么两点 C 的坐标如下:
如果有两点的坐标,则计算它们之间的距离:) 然后 - 从 (x, y) 到 A 和 B 的距离的两个方程 - 一切都在二次方程的水平上求解。麻烦,是的,但可行。
其实,仅此而已。答案 - 见上文。
以下是如果
(距离 |AB| 不等于 c)——那就自己想想吧……