Reputation: 97
I want to draw a circe with given curvature k.
I just need to know the y-coordinate for a given x-coordinate. So i.e. z = 1/k + sqrt(1/k^2 - x^2) is what I would normally use.
The problem is that my k is allowed to become zero. Which means that my circle becomes a line. For a mathematican thats no problem. But for my computer it is. For example when k is minimum double value, y will be infinity, for k == 0 I receive nan for y.
Are there any ways to get this done?
Upvotes: 1
Views: 305
Reputation: 539935
You gave the formula
y1 = 1/k + sqrt(1/k^2 - x^2) // (1)
which describes the upper half of the circle with radius 1/k
and center (0, 1/k)
. Now for small k
these values become very large and will eventually be outside of your drawing are.
The lower half of the circle is given by
y2 = 1/k - sqrt(1/k^2 - x^2) // (2)
For k approaching zero, these values "approach" the line y = 0
. But for small values of k
, (2) computes the difference of two large numbers. This causes a loss of precision and possible overflow.
But you can rewrite the formula (2) into the equivalent form
y2 = k * x^2 / (1 + sqrt(1 - k^2 * x^2)) // (2a)
Now you can compute the lower half of the circle for small values of k
and even for k = 0
without any overflow or precision loss.
For the upper half you always have y1 >= 1/k
. So if 1/k
is larger than the boundary of your drawing area, you can ignore the upper value. Otherwise you can compute y1
via
y1 = 2/k - y2
Upvotes: 1
Reputation: 150138
Given such border cases, I would just test the input parameters to see if one of them applies and use separate logic to just draw a horizontal or vertical line as appropriate if a border case applies.
That is a fairly common approach and computationally quite efficient.
When testing for border cases, test k to ensure that: - k^2 will not overflow the data type in use - k is not so small that 1/k^2 will underflow the data type in use
In either case, use the appropriate border case logic. Thanks @Godeke for pointing that out.
Upvotes: 2