Skip to content

Commit

Permalink
implement spherical rotation for Vector3
Browse files Browse the repository at this point in the history
  • Loading branch information
Erwan de Lépinau committed Apr 17, 2020
1 parent 92dc2e6 commit 130b7ef
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/vectors.cpp
Expand Up @@ -34,6 +34,7 @@ Vector3 &Vector3::operator/=(float f) {
z /= f;
return *this;
}

Vector3 Vector3::operator-() const { return Vector3(-x, -y, -z); }

bool Vector3::operator==(const Vector3 &other) const {
Expand Down Expand Up @@ -97,6 +98,17 @@ Vector3 Vector3::reflected(const Vector3 &normal) const {
return *this - 2 * dot(normalizedNormal) * normalizedNormal;
}

Vector3 Vector3::sphericallyRotated(const Vector3 &normalizedDirection,
float theta, float phi) {
float originalTheta =
std::atan2(normalizedDirection.getY(), normalizedDirection.getX());
float originalPhi = std::acos(normalizedDirection.getZ());
float newX = std::sin(originalPhi + phi) * std::cos(originalTheta + theta);
float newY = std::sin(originalPhi + phi) * std::sin(originalTheta + theta);
float newZ = std::cos(originalPhi + phi);
return {newX, newY, newZ};
}

float Vector3::getX() const { return x; }
float Vector3::getY() const { return y; }
float Vector3::getZ() const { return z; }
Expand Down
2 changes: 2 additions & 0 deletions src/vectors.hpp
Expand Up @@ -18,6 +18,8 @@ class Vector3 {
float dot(const Vector3 &other) const;
Vector3 cross(const Vector3 &other) const;
Vector3 reflected(const Vector3 &normal) const;
static Vector3 sphericallyRotated(const Vector3 &normalizedDirection,
float theta, float phi);

Vector3 &operator+=(const Vector3 &other);
Vector3 &operator-=(const Vector3 &other);
Expand Down
18 changes: 18 additions & 0 deletions tests/test_vectors.cpp
@@ -1,6 +1,7 @@
#include <catch2/catch.hpp>
#include <cmath>

#include "../src/utils.hpp"
#include "../src/vectors.hpp"

TEST_CASE("Vector2") {
Expand Down Expand Up @@ -93,4 +94,21 @@ TEST_CASE("Vector3") {

REQUIRE(reflected == Vector3(1.0f, 1.0f, 1.0f));
}

SECTION("sphericallyRotated returns correct results") {
const Vector3 v1{1.0f, 1.0f, std::sqrt(2.0f)};

const Vector3 rotated1 = Vector3::sphericallyRotated(
v1.normalized(), -Math::PI / 4.0f, Math::PI / 4.0f);

REQUIRE(rotated1 == Vector3(1.0f, 0.0f, 0.0f).normalized());

const Vector3 v3{-1.0f, 0.0f, 0.0f};

const Vector3 rotated2 = Vector3::sphericallyRotated(
v3.normalized(), Math::PI / 2.0f, Math::PI / 6.0f);

REQUIRE(rotated2 ==
Vector3(0.0f, -std::sqrt(3.0f) / 2.0f, -0.5f).normalized());
}
}

0 comments on commit 130b7ef

Please sign in to comment.