diff --git a/README.md b/README.md index b861235..3d2c8cb 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,12 @@ Collection of **generic, immutable** vector math functions I've written overtime | Y | ✅ | ✅ | ✅ | Returns the y component of the vector | | Z | | ✅ | ✅ | Returns the z component of the vector | | W | | | ✅ | Returns the w component of the vector | +| XY | | ✅ | ✅ | Equivalent to vector2.New[T](v.x, v.y) | +| YZ | | ✅ | ✅ | Equivalent to vector2.New[T](v.y, v.z) | +| XZ | | ✅ | ✅ | Equivalent to vector2.New[T](v.x, v.z) | +| YX | | ✅ | ✅ | Equivalent to vector2.New[T](v.y, v.x) | +| ZY | | ✅ | ✅ | Equivalent to vector2.New[T](v.z, v.y) | +| ZX | | ✅ | ✅ | Equivalent to vector2.New[T](v.z, v.x) | ## Example diff --git a/vector3/vector3.go b/vector3/vector3.go index c64206e..9dddbe7 100644 --- a/vector3/vector3.go +++ b/vector3/vector3.go @@ -345,6 +345,21 @@ func (v Vector[T]) YZ() vector2.Vector[T] { return vector2.New(v.y, v.z) } +// YX returns vector2 with the y and x components +func (v Vector[T]) YX() vector2.Vector[T] { + return vector2.New(v.y, v.x) +} + +// ZX returns vector2 with the z and x components +func (v Vector[T]) ZX() vector2.Vector[T] { + return vector2.New(v.z, v.x) +} + +// ZY returns vector2 with the z and y components +func (v Vector[T]) ZY() vector2.Vector[T] { + return vector2.New(v.z, v.y) +} + // Midpoint returns the midpoint between this vector and the vector passed in. func (v Vector[T]) Midpoint(o Vector[T]) Vector[T] { return o.Add(v).Scale(0.5) diff --git a/vector3/vector3_test.go b/vector3/vector3_test.go index 67001e3..c7223e0 100644 --- a/vector3/vector3_test.go +++ b/vector3/vector3_test.go @@ -76,6 +76,9 @@ func TestToVector2(t *testing.T) { "xy": {got: start.XY(), want: vector2.New(1.2, -2.4)}, "yz": {got: start.YZ(), want: vector2.New(-2.4, 3.7)}, "xz": {got: start.XZ(), want: vector2.New(1.2, 3.7)}, + "yx": {got: start.YX(), want: vector2.New(-2.4, 1.2)}, + "zy": {got: start.ZY(), want: vector2.New(3.7, -2.4)}, + "zx": {got: start.ZX(), want: vector2.New(3.7, 1.2)}, } for name, tc := range tests { diff --git a/vector4/vector4.go b/vector4/vector4.go index 49442f4..75e7e1d 100644 --- a/vector4/vector4.go +++ b/vector4/vector4.go @@ -7,6 +7,8 @@ import ( "math" "github.com/EliCDavis/vector" + "github.com/EliCDavis/vector/vector2" + "github.com/EliCDavis/vector/vector3" ) // Vector contains 4 components @@ -495,3 +497,37 @@ func (v Vector[T]) FlipW() Vector[T] { w: v.w * -1, } } + +func (v Vector[T]) XYZ() vector3.Vector[T] { + return vector3.New[T](v.x, v.y, v.z) +} + +// XY returns vector2 with the x and y components +func (v Vector[T]) XY() vector2.Vector[T] { + return vector2.New(v.x, v.y) +} + +// XZ returns vector2 with the x and z components +func (v Vector[T]) XZ() vector2.Vector[T] { + return vector2.New(v.x, v.z) +} + +// YZ returns vector2 with the y and z components +func (v Vector[T]) YZ() vector2.Vector[T] { + return vector2.New(v.y, v.z) +} + +// YX returns vector2 with the y and x components +func (v Vector[T]) YX() vector2.Vector[T] { + return vector2.New(v.y, v.x) +} + +// ZX returns vector2 with the z and x components +func (v Vector[T]) ZX() vector2.Vector[T] { + return vector2.New(v.z, v.x) +} + +// ZY returns vector2 with the z and y components +func (v Vector[T]) ZY() vector2.Vector[T] { + return vector2.New(v.z, v.y) +} diff --git a/vector4/vector4_test.go b/vector4/vector4_test.go index cb6c4b8..3dff5fc 100644 --- a/vector4/vector4_test.go +++ b/vector4/vector4_test.go @@ -6,6 +6,8 @@ import ( "math" "testing" + "github.com/EliCDavis/vector/vector2" + "github.com/EliCDavis/vector/vector3" "github.com/EliCDavis/vector/vector4" "github.com/stretchr/testify/assert" ) @@ -117,6 +119,48 @@ func TestScaleVecFloat(t *testing.T) { } } +func TestSwizzle_Vector3(t *testing.T) { + in := vector4.New(1., 2., 3., 4.) + + tests := map[string]struct { + expected vector3.Float64 + got vector3.Float64 + }{ + "XYZ": {expected: vector3.New(1., 2., 3.), got: in.XYZ()}, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + assert.Equal(t, tc.expected.X(), tc.got.X()) + assert.Equal(t, tc.expected.Y(), tc.got.Y()) + assert.Equal(t, tc.expected.Z(), tc.got.Z()) + }) + } +} + +func TestSwizzle_Vector2(t *testing.T) { + start := vector3.New(1.2, -2.4, 3.7) + + tests := map[string]struct { + got vector2.Float64 + want vector2.Float64 + }{ + "xy": {got: start.XY(), want: vector2.New(1.2, -2.4)}, + "yz": {got: start.YZ(), want: vector2.New(-2.4, 3.7)}, + "xz": {got: start.XZ(), want: vector2.New(1.2, 3.7)}, + "yx": {got: start.YX(), want: vector2.New(-2.4, 1.2)}, + "zy": {got: start.ZY(), want: vector2.New(3.7, -2.4)}, + "zx": {got: start.ZX(), want: vector2.New(3.7, 1.2)}, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + assert.Equal(t, tc.want.X(), tc.got.X()) + assert.Equal(t, tc.want.Y(), tc.got.Y()) + }) + } +} + func TestJSON(t *testing.T) { in := vector4.New(1.2, 2.3, 3.4, 5.6) out := vector4.New(0., 0., 0., 0.)