鉴于以下系统:
其中:
A
:存在于xz平面上半径为r
的圆边上任意位置的点。θ
:正x轴与从原点到点A
的矢量之间的角度。这应该从-PI / 2到PI / 2。B1
:圆圈与正x轴交叉点的高度为h1
。B2
:圆圈与正z轴交叉点的高度为h2
。d1
:B1
和A
之间的距离。d2
:B2
和A
之间的距离。假设:
h1
,h2
和r
是已知的常量。d1
和d2
是已知变量。 如何找到θ
?
这最终将在嵌入式系统中以C语言实现,其中arctan2
,sine
和cosine
具有相当快的功能。因此,性能绝对是一个优先事项,如果它们正确到大约3个小数位(这是我的trig函数的准确度),则可以使用估计。
然而,即使给出了数学算法,我确信我可以计算出具体的实现方法。
对于它的价值,我得到了:
(d1^2 - h1^2) / r = (sin(θ))^2 + (cos(θ))^2
(d2^2 - h2^2) / r = (sin(PI/4 - θ))^2 + (cos(PI/4 - θ))^2
在我意识到这一点之前,在数学上,这是方式在我的联盟之外。
答案 0 :(得分:3)
这不是一个完整的答案,而是一个开头。
您可以进行两种简单的简化。
让H1和H2成为B1和B2下方平面中的点。 既然知道了h1和d1,h2和d2,就可以计算出2个距离A-H1和A-H2(用毕达哥拉斯)。 现在你已经把拼图缩小到了一架飞机。
此外,您不需要同时查看H1和H2。给定距离A-H1,A只有2个可能的位置,它们在x轴上镜像。然后你可以通过查看A-H2距离是否高于或低于阈值距离H2-H1来找到它们中的哪一个。
这似乎是一个好的开始: - )
答案 1 :(得分:1)
使用@Rhialto,对角落案例进行额外的简化和测试:
// c1 is the signed chord distance A to (B1 projected to the xz plane)
// c1*c1 + h1*h1 = d1*d1
// c1 = +/- sqrt(d1*d1 - h1*h1) (choose sign later)
// c1 = Cord(r, theta) = fabs(r*2*sin(theta/2))
// theta = asin(c1/(r*2))*2
//
// theta is < 0 when d2 > sqrt(h2*h2 + sqrt(2)*r*sqrt(2)*r)
// theta is < 0 when d2 > sqrt(h2*h2 + 2*r*r)
// theta is < 0 when d2*d2 > h2*h2 + 2*r*r
#define h1 (0.1)
#define h2 (0.25)
#define r (1.333)
#define h1Squared (h1*h1)
#define rSquared (r*r)
#define rSquaredTimes2 (r*r*2)
#define rTimes2 (r*2)
#define d2Big (h2*h2 + 2*r*r)
// Various steps to avoid issues with d1 < 0, d2 < 0, d1 ~= h1 and theta near pi
double zashu(double d1, double d2) {
double c1Squared = d1*d1 - h1Squared;
if (c1Squared < 0.0)
c1Squared = 0.0; // _May_ be needed when in select times |d1| ~= |h1|
double a = sqrt(c1Squared) / rTimes2;
double theta = (a <= 1.0) ? asin(a)*2.0 : asin(1.0)*2.0; // Possible a is _just_ greater than 1.0
if (d2*d2 > d2Big) // this could be done with fabs(d2) > pre_computed_sqrt(d2Big)
theta = -theta;
return theta;
}