Deriving the major and minor axis of an ellipse

Click For Summary

Homework Help Overview

The discussion revolves around deriving the major and minor axes of an ellipse using conjugate diameters. Participants are examining a mathematical approach involving trigonometric functions and potential pitfalls related to division by zero in specific angle scenarios.

Discussion Character

  • Exploratory, Assumption checking, Mathematical reasoning

Approaches and Questions Raised

  • Participants discuss a current solution involving calculations based on the coordinates of conjugate diameters and the center of the ellipse. They raise concerns about the function returning NaN for certain angles, particularly when sine of the angle is zero, leading to division by zero issues. There are suggestions to avoid using problematic angles and to explore alternative methods for determining the axes.

Discussion Status

The conversation is ongoing, with participants providing insights on how to handle specific cases that lead to mathematical errors. Some suggest enhancing the robustness of the code to prevent division by zero, while others are exploring geometric interpretations that could simplify the problem.

Contextual Notes

Participants note that the angles causing issues are multiples of π, which lead to undefined behavior in the calculations. There is a shared understanding that the current approach may not be sufficient, and alternative strategies are being considered.

frankinstein
Messages
74
Reaction score
0
1. Deriving the major and minor axis of an ellipse from conjugate diameters pointsCurrent solution:
Code:
double x1 = Diameter1.X - Center.X;
double y1 = Diameter1.Y - Center.Y;
double x2 = Diameter2.X - Center.X;
double y2 = Diameter2.Y - Center.Y;
double xc = (x2 + y1) / 2;
double yc = (y2 - x1) / 2;
double theta = Math.Atan2(yc - y2, x2 - xc);
double phi = Math.Atan2(yc, xc);
double d = xc / Math.Cos(phi);
double yu = yc + d * Math.Sin(theta);
double xv = xc + d * Math.Cos(theta);
double yv = yc - d * Math.Sin(theta);
double alpha = Math.Atan2(yv, xv);
a = (yu - y2) / Math.Sin(theta);
b = 0;
double SemiDiag1 = GraphicTools.GetRadius(Center, Diameter1);
double SemiDiag2 = GraphicTools.GetRadius(Center, Diameter2);
if (a != 0 && !double.IsNaN(a))
{
      b = Math.Sqrt((Math.Pow(SemiDiag1, 2) + Math.Pow(SemiDiag2, 2)) - Math.Pow(a, 2));
}
else
{
       b = d;
       a = Math.Sqrt((Math.Pow(SemiDiag1, 2) + Math.Pow(SemiDiag2, 2)) - Math.Pow(b, 2));
}

The above function where a = (yu - y2) / Math.Sin(theta) can be NaN when the conjugate radii's angles are: 0, 1.57, 3.14, 4.71, 6.28

All other angles the function works perfectly. The alternative process where a = 0 or a = NaN is inaccurate or completely dysfunctional. How does one treat the angles that don't work?
 
Last edited by a moderator:
Physics news on Phys.org
frankinstein said:
1. Deriving the major and minor axis of an ellipse from conjugate diameters points


Current solution:
Code:
double x1 = Diameter1.X - Center.X;
double y1 = Diameter1.Y - Center.Y;
double x2 = Diameter2.X - Center.X;
double y2 = Diameter2.Y - Center.Y;
double xc = (x2 + y1) / 2;
double yc = (y2 - x1) / 2;
double theta = Math.Atan2(yc - y2, x2 - xc);
double phi = Math.Atan2(yc, xc);
double d = xc / Math.Cos(phi);
double yu = yc + d * Math.Sin(theta);
double xv = xc + d * Math.Cos(theta);
double yv = yc - d * Math.Sin(theta);
double alpha = Math.Atan2(yv, xv);
a = (yu - y2) / Math.Sin(theta);
b = 0;
double SemiDiag1 = GraphicTools.GetRadius(Center, Diameter1);
double SemiDiag2 = GraphicTools.GetRadius(Center, Diameter2);
if (a != 0 && !double.IsNaN(a))
{
      b = Math.Sqrt((Math.Pow(SemiDiag1, 2) + Math.Pow(SemiDiag2, 2)) - Math.Pow(a, 2));
}
else
{
       b = d;
       a = Math.Sqrt((Math.Pow(SemiDiag1, 2) + Math.Pow(SemiDiag2, 2)) - Math.Pow(b, 2));
}

The above function where a = (yu - y2) / Math.Sin(theta) can be NaN when the conjugate radii's angles are: 0, 1.57, 3.14, 4.71, 6.28
Whenever theta is ##k\pi##, sin(theta) will be zero, so you'll have a division by zero problem at these values. You shouldn't have problems at ##\pi/2## (which you show above as 1.57) or ##3\pi/2## (which you show as 4.71), or at any odd multiple of ##\pi/2##.
frankinstein said:
All other angles the function works perfectly. The alternative process where a = 0 or a = NaN is inaccurate or completely dysfunctional. How does one treat the angles that don't work?

The short answer is - don't use those angles. It would help if you explained what you were doing.
 
Mark44 said:
Whenever theta is ##k\pi##, sin(theta) will be zero, so you'll have a division by zero problem at these values. You shouldn't have problems at ##\pi/2## (which you show above as 1.57) or ##3\pi/2## (which you show as 4.71), or at any odd multiple of ##\pi/2##.


The short answer is - don't use those angles. It would help if you explained what you were doing.

Actually its the angle between the radii that's the problem and that's when theta is zero and if any of the x or y components zero out, like when the angle between the radii are ∏/2 or some multiple, causes the product of "a" to be zero or division by zero.

The function is used to generate an arc using the parametric equations for an ellipse, why the need for finding the major and minor axis from the conjugate diameter points. The parameters given to the function will have angles that result in products of "a" becoming unusable.

I was hoping that there was a better approach to extracting the major and minor axis from conjugate diameter points that didn't have the problems that my current solution has or a work around for those angles that produce an unusable "a".
 
I don't know if you can work around the problem, but you can make your code more robust, by guarding against division by zero.

You'll potentially have problems with these lines of code:
Code:
double theta = Math.Atan2(yc - y2, x2 - xc);
double phi = Math.Atan2(yc, xc);
double d = xc / Math.Cos(phi);
// <snip>

double alpha = Math.Atan2(yv, xv);
a = (yu - y2) / Math.Sin(theta);
In the first line above, you should make sure that x2 - xc ≠ 0 or close to zero (say 10-7 or so).
In the second line, you don't want xc to be zero or very close to zero.
In the third line, you don't want phi to be an odd multiple of pi/2.
In the last line, you don't want theta to be any multiple of pi.

For these special cases, I would see if there is some geometry I could exploit, like maybe one point is directly above the other, or on the same horizontal line or what-have-you, and take that into consideration.

BTW, I always avoided using Pow when I was just squaring a number. Rather than use Math.Pow(x, 2), I would just have x * x. I'm not sure the compiler is smart enough to convert a Pow() function call to a simple multiplication, which would be much faster.
 

Similar threads

  • · Replies 3 ·
Replies
3
Views
3K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 4 ·
Replies
4
Views
8K