围绕圆周运动的点的三角剖分算法

时间:2013-07-11 22:41:49

标签: c geometry triangulation

鉴于以下系统:

enter image description here

其中:

  • A:存在于xz平面上半径为r的圆边上任意位置的点。
  • θ:正x轴与从原点到点A的矢量之间的角度。这应该从-PI / 2到PI / 2。
  • B1:圆圈与正x轴交叉点的高度为h1
  • B2:圆圈与正z轴交叉点的高度为h2
  • d1B1A之间的距离。
  • d2B2A之间的距离。

假设:

  • h1h2r是已知的常量。
  • d1d2是已知变量。

如何找到θ

这最终将在嵌入式系统中以C语言实现,其中arctan2sinecosine具有相当快的功能。因此,性能绝对是一个优先事项,如果它们正确到大约3个小数位(这是我的trig函数的准确度),则可以使用估计。

然而,即使给出了数学算法,我确信我可以计算出具体的实现方法。

对于它的价值,我得到了:

(d1^2 - h1^2) / r = (sin(θ))^2        + (cos(θ))^2
(d2^2 - h2^2) / r = (sin(PI/4 - θ))^2 + (cos(PI/4 - θ))^2

在我意识到这一点之前,在数学上,这是方式在我的联盟之外。

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;
}