Skip to content

Commit

Permalink
zzre: Add ToZZRotationVector as roundtrip to ToZZRotation
Browse files Browse the repository at this point in the history
  • Loading branch information
Helco committed Jul 16, 2024
1 parent 23cba61 commit 79a4862
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
53 changes: 53 additions & 0 deletions zzre.core.tests/math/TestMath.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Numerics;
using NUnit.Framework;

namespace zzre.core.tests.math;

[TestFixture]
public class TestMath
{
[Test]
public void TestRoundtrip()
{
foreach (var dir in GenerateUniformPoints())
{
var dirQuat = dir.ToZZRotation();
var roundtripDir = dirQuat.ToZZRotationVector();
var dirLength = dir.Length();
var roundtripDirLength = roundtripDir.Length();
var acosAngle = Vector3.Dot(dir, roundtripDir) / (dirLength * roundtripDirLength);
// We still occasionally get values slightly outside -1 to 1. Is this a problem in game too?
acosAngle = Math.Clamp(acosAngle, -1, 1);
var roundtripAngle = Math.Acos(acosAngle) * MathEx.RadToDeg;

Assert.That(dir.Length(), Is.EqualTo(1.0f).Within(1).Percent);
Assert.That(roundtripDir.Length(), Is.EqualTo(1.0f).Within(1).Percent);
Assert.That(roundtripAngle, Is.EqualTo(0).Within(0.1), $"For {dir}");
}
}

private const int PointCount = 10000;
public static IEnumerable<Vector3> GenerateUniformPoints()
{
// TODO: Move uniform sphere point generator to NumericsExtensions
// (and test that everything still works after that change)

var random = new Random(42);
for (int i = 0; i < PointCount; i++)
{
// from https://corysimon.github.io/articles/uniformdistn-on-sphere/
double theta = 2 * Math.PI * random.NextDouble();
double phi = Math.Acos(1 - 2 * random.NextDouble());
double sinTheta = Math.Sin(theta), cosTheta = Math.Cos(theta);
double sinPhi = Math.Sin(phi), cosPhi = Math.Cos(phi);
var vec = new Vector3(
(float)(sinPhi * cosTheta),
(float)(sinPhi * sinTheta),
(float)(cosPhi));
yield return vec;
}
}
}
3 changes: 3 additions & 0 deletions zzre.core/math/ZZIOExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ public static void CopyFromNumerics(this ref FColor c, Vector4 v)
public static Quaternion ToZZRotation(this Vector3 v) =>
Quaternion.Conjugate(Quaternion.CreateFromRotationMatrix(Matrix4x4.CreateLookAt(Vector3.Zero, v * -1f, Vector3.UnitY)));

public static Vector3 ToZZRotationVector(this Quaternion rotation) =>
Vector3.Transform(-Vector3.UnitZ, rotation) * -1f;

public static RgbaByte ToVeldrid(this IColor c) => new(c.r, c.g, c.b, c.a);
public static RgbaFloat ToVeldrid(this FColor c) => new(c.r, c.g, c.b, c.a);
public static FColor ToFColor(this Vector4 v) => new(v.X, v.Y, v.Z, v.W);
Expand Down

0 comments on commit 79a4862

Please sign in to comment.