Skip to content

Commit

Permalink
Fix inaccuracy in Vector3 getLength()/getLengthSquared()
Browse files Browse the repository at this point in the history
Although our Vector3 is double precision, for some reason getLength() and
getLengthSquared() were forcing everything to float precision.

getLengthSquared() now operates in the native T type (this will work even for a
hypothetical BasicVector3<int>, since it's just multiplication and addition),
and is implemented as the dot product of the vector with itself for simplicity.

getLength() now returns double, since std::sqrt() always returns a double
anyway so there is no point in converting it at this point.

This allows the VectorLength unit test to compare for exact equality rather
than using an epsilon (the same calculation on the same compiler with the same
FPU should give consistent results).
  • Loading branch information
Matthew Mott committed Apr 4, 2021
1 parent 5762253 commit cda42e9
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 11 deletions.
14 changes: 6 additions & 8 deletions libs/math/Vector3.h
Expand Up @@ -158,17 +158,15 @@ class BasicVector3
}

/// Return the Pythagorean length of this vector.
float getLength() const {
float lenSquared = getLengthSquared();
return sqrt(lenSquared);
double getLength() const
{
return sqrt(getLengthSquared());
}

/// Return the squared length of this vector.
float getLengthSquared() const {
float lenSquared = float(_v[0]) * float(_v[0]) +
float(_v[1]) * float(_v[1]) +
float(_v[2]) * float(_v[2]);
return lenSquared;
T getLengthSquared() const
{
return dot(*this);
}

/**
Expand Down
10 changes: 7 additions & 3 deletions test/math/Vector.cpp
Expand Up @@ -66,9 +66,13 @@ TEST(MathTest, NegateVector3)

TEST(MathTest, VectorLength)
{
Vector3 v3(3, 4, 5);
EXPECT_EQ(v3.getLengthSquared(), 3*3 + 4*4 + 5*5);
EXPECT_NEAR(v3.getLength(), sqrt(3*3 + 4*4 + 5*5), 1E-6);
const Vector3 vA(3, 4, 5);
EXPECT_EQ(vA.getLengthSquared(), 3*3 + 4*4 + 5*5);
EXPECT_EQ(vA.getLength(), sqrt(3*3 + 4*4 + 5*5));

const Vector3 vB(-2, 0.5, 16);
EXPECT_EQ(vB.getLengthSquared(), 4 + 0.25 + 256);
EXPECT_EQ(vB.getLength(), sqrt(4 + 0.25 + 256));
}

TEST(MathTest, NormaliseVector3)
Expand Down

0 comments on commit cda42e9

Please sign in to comment.