Casey
Casey

Reputation: 10946

Clamping degree values to 0 <= x < 360 algebraically

Given the function:

void Arc::SetAngles(double startAngle, double endAngle) {
    while(endAngle > (startAngle + 359.0)) endAngle -= 1.0;
    while(startAngle > 360.0) startAngle -= 360.0;
    while(startAngle < -360.0) startAngle += 360.0;
    while(endAngle > 360.0) endAngle -= 360.0;
    while(endAngle < -360.0) endAngle += 360.0;
    _startAngle = DegreeToRadian(startAngle);
    _endAngle = DegreeToRadian(endAngle);
}

Is there an algebraic solution to those while loops? It just looks...ugly. (Not to mention...slow.)

Upvotes: 3

Views: 8212

Answers (4)

mu is too short
mu is too short

Reputation: 434795

In C or C++ you'd use fmod to get rid of some of your loops. Instead of this:

while(startAngle > 360.0) startAngle -= 360.0;
while(startAngle < -360.0) startAngle += 360.0;

Do this:

startAngle = fmod(startAngle, 360.0);
if(startAngle < 0)
    startAngle += 360.0;

Don't use the normal modulus operator (%) as that's for integers and won't do the right thing with floating point values.

Your first loop:

while(endAngle > (startAngle + 359.0)) endAngle -= 1.0;

Can be replaced with just this:

if(endAngle > startAngle + 359.0)
    endAngle = startAngle + 359.0;

But I think you should rethink that part of your algorithm: there's no point in comparing the angles before you normalize them to the [0,360) interval.

Upvotes: 6

djna
djna

Reputation: 55937

Does your language have a modulus operator that works for floating point? The % in Java. This gives the remainder when dividing by a number.

startAngle = startAngle % 360.0

(Yes the concept of a remainder is weird when applied to floating point numbers, but Java at least does give a useful definition.)

Contrary to the comments below, in Java % is explictly defined in the language specification:

15.17.3 Remainder Operator %

In C and C++, the remainder operator accepts only integral operands, but in the Java programming language, it also accepts floating-point operands.

See http://java.sun.com/docs/books/jls/third_edition/html/expressions.html for the full details. Bottom line I believe that this can be used to implement the required algorithms.

Upvotes: 0

C.Evenhuis
C.Evenhuis

Reputation: 26446

You could use modulus, which divides by 360 but returns the remainder instead of the result of the division: 380 mod 360 = 20. Do note that -380 mod 360 = -20

Upvotes: 2

Beno&#238;t
Beno&#238;t

Reputation: 7427

with modulus ?

angle = mod(angle,360.0)

Upvotes: 2

Related Questions