简体   繁体   中英

Algorithm for triangulation of point travelling around a circle

Given the following system:

在此处输入图片说明

Where:

  • A : Point that exists anywhere on the edge of a circle with radius r on the xz plane.
  • θ : The angle between the positive-x-axis and a vector from the origin to point A . This should range from -PI/2 to PI/2.
  • B1 : A point at the intersection of the circle and the positive x-axis at a height of h1 .
  • B2 : A point at the intersection of the circle and the positive z-axis at a height of h2 .
  • d1 : Distance between B1 and A .
  • d2 : Distance between B2 and A .

Assuming:

  • h1 , h2 , and r are known constants.
  • d1 and d2 are known variables.

How do I find θ ?

This will eventually be implemented in C in an embedded system where I have reasonably fast functions for arctan2 , sine , and cosine . As such, performance is definitely a priority, and estimations can be used if they are correct to about 3 decimal places (which is how accurate my trig functions are).

However, even given a mathematical algorithm, I'm sure I could work out the specific implementation.

For what it's worth, I got about as far as:

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

Before I realized that, mathematically, this is way out of my league.

This isn't a full answer but a start of one.

There are two easy simplifications you can make.

Let H1 and H2 be the points in your plane below B1 and B2. Since you know h1 and d1, h2 and d2, you can calculate the 2 distances A-H1 and A-H2 (with Pythagoras). Now you have reduced the puzzle to a plane.

Furthermore, you don't really need to look at both H1 and H2. Given the distance A-H1, there are only 2 possible locations for A, which are mirrored in the x-axis. Then you can find which of the two it is by seeing if the A-H2 distance is above or below the threshold distance H2-H1.

That seems to be a good beginning :-)

Employing @Rhialto, additional simplifications and tests for corners cases:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM