Resolved Unit test result differ in angle calculation between two vectors

proxyprochy

New member
Joined
Aug 25, 2023
Messages
4
Programming Experience
1-3
Hello, so I've got some code that works normally in production, but whenever i run test (MSTest), the result differs by 3.2034 degrees, thus the test fails. Based on my calculations, the test calculates wrongly. Any suggestions what might be wrong?

For testing purposes, I've hard-coded the point values and moved everything to a separate solution.

Main method:
static void Main(string[] args)
{
     // Results in 178.898293884794
     Console.WriteLine(Angle.NormalizeAngle(Angle.GetAngleByVectors(),0));
     Console.ReadLine();
}

Unit testing:
[TestMethod]
 public void TestMethod1()
 {
     // Act
     double angle = Angle.NormalizeAngle(Angle.GetAngleByVectors(), 0);
     // Results in 181.10170611520635
     double normalizedAngle = Angle.NormalizeAngle(angle, 0);

     // Assert
     double expectedAngle = 177.8983;
     Assert.AreEqual(expectedAngle, normalizedAngle, Tolerance);
}

Methods used:
public static double GetAngleByVectors()
{
     var pt1 = new Point(757, 473);
     var pt2 = new Point(705, 472);

     const double Rad2Deg = 180.0 / Math.PI;
     double result = Math.Atan2(pt2.Y - pt1.Y, pt2.X - pt1.X);
     double resultInDegrees = result * Rad2Deg;
     return resultInDegrees;
}

public static double NormalizeAngle(double angle, double offset)
{
     angle += offset;
     angle %= 360.0;
     if (angle < 0)
     {
         angle += 360.0;
     }

     return 360 - angle;
}
 
Last edited:
Don't use doubles if you want calculations to produce exact decimal numbers. Either use decimal or accept double values inability to exactly represent certain values by accepting a range rather than an equality; don't AreEqual on 10.0/2.0 = 5.0, instead consider eg Assert.That(10.0/2.0, Is.EqualTo(5.0).Within(0.1))
 
Don't use doubles if you want calculations to produce exact decimal numbers. Either use decimal or accept double values inability to exactly represent certain values by accepting a range rather than an equality; don't AreEqual on 10.0/2.0 = 5.0, instead consider eg Assert.That(10.0/2.0, Is.EqualTo(5.0).Within(0.1))

I have tolerance set to 0.1.
Anyways, 3 degrees seems to me to be too big a difference to be caused by decimals.
 
my bad, accidentally duplicated statements

should've looked like this:
   // Act
            double angle = Angle.NormalizeAngle(Angle.GetAngleByVectors(), 0);

            // Assert
            double expectedAngle = 178.8983;
            Assert.AreEqual(expectedAngle, angle, Tolerance);

So it now differs by 1 degree exactly.
 
Last edited:
Last edited:
Ah. I swapped pt1 and pt2 when I was using the online calculator.

Anyway, here what .NET Fiddle says:
Code:
-3.122364254490086
-178.89829388479365
178.89829388479365

C#:
using System;
using System.Drawing;
                    
public class Program
{
    public static void Main()
    {
        var pt1 = new Point(757, 473);
        var pt2 = new Point(705, 472);
        const double Rad2Deg = 180.0 / Math.PI;
        double result = Math.Atan2(pt2.Y - pt1.Y, pt2.X - pt1.X);
        Console.WriteLine(result);
        double resultInDegrees = result * Rad2Deg;        
        Console.WriteLine(resultInDegrees);

        double angle = resultInDegrees;
        double offset = 0;
        angle += offset;
        angle %= 360.0;
        if (angle < 0)
        {
            angle += 360.0;
        }

        double normalizedAngle = 360 - angle;
        Console.WriteLine(normalizedAngle);
    }
}
 
And the same numbers match up using the Windows calculator:
1693089224579.png
 
The tests fail because your expected value is not withing tolerance of the value computed by the code.
 

Latest posts

Back
Top Bottom