Skip to content

Commit

Permalink
Adding swizzling. (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
SolarLune committed Aug 17, 2022
1 parent 3a5b7a8 commit 8b37b46
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 0 deletions.
40 changes: 40 additions & 0 deletions arithmetic.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,3 +364,43 @@ func angle(a, b []float64) float64 {
angle := math.Acos(dot(unit(clone(a)), unit(clone(b))))
return angle
}

func swizzle(a []float64, indices ...int) ([]float64, error) {

for _, i := range indices {
if i < 0 || i >= len(a) {
return nil, ErrNotValidSwizzleIndex
}
}

switch len(indices) {

case 0:
return []float64{}, nil
case 1:
return []float64{a[indices[0]]}, nil
case 2:
return []float64{a[indices[0]], a[indices[1]]}, nil
case 3:
return []float64{a[indices[0]], a[indices[1]], a[indices[2]]}, nil
case 4:
return []float64{a[indices[0]], a[indices[1]], a[indices[2]], a[indices[3]]}, nil
default:

vec := make([]float64, len(indices))

for i := 0; i < len(indices); i++ {

ind := indices[i]
if ind >= len(a) {
return nil, ErrNotValidSwizzleIndex
}
vec[i] = a[ind]

}

return vec, nil

}

}
11 changes: 11 additions & 0 deletions arithmetic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,14 @@ func BenchmarkArithmeticAngle(b *testing.B) {
angle(v1, v2)
}
}

func BenchmarkSwizzling(b *testing.B) {
b.ReportAllocs()

v1 := Vector{1, 2, 19}

for i := 0; i < b.N; i++ {
swizzle(v1, 0, 1, 2)
}

}
4 changes: 4 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ var (
// ErrNotSameDimensions is an error that is returned when functions need both
// Vectors provided to be the same dimensionally
ErrNotSameDimensions = errors.New("the two vectors provided aren't the same dimensional size")

// ErrNotValidSwizzleIndex is an error that is returned when swizzling a vector and passing
// an index that lies outside of the length of the vector
ErrNotValidSwizzleIndex = errors.New("index for swizzling is not valid for the given vector")
)
7 changes: 7 additions & 0 deletions vector.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ func (a Vector) Rotate(angle float64, axis ...Vector) Vector {
return rotate(clone(a), angle, clone(as))
}

// Swizzle returns a clone of the input vector altered using the provided swizzling indices.
// For example, with `vector := {1, 3, 9}`, `vector.Swizzle(2,1,2,0)` will return `Vector{9,3,9,1}`.
// Swizzle will return the swizzled vector, and an error if one of the provided indices is out of bounds.
func (a Vector) Swizzle(swizzleIndices ...int) (Vector, error) {
return swizzle(a, swizzleIndices...)
}

// Angle returns the angle in radians from the first Vector to the second, and an error if the two Vectors
// aren't of equal dimensions (length). For 0-dimension Vectors, the returned angle is 0. For 1-dimension Vectors,
// the angle is Pi if the second Vector's coordinate is less than the first Vector's coordinate, and 0 otherwise.
Expand Down
10 changes: 10 additions & 0 deletions vector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,13 @@ func TestXYZGetters(t *testing.T) {
t.Error("getter methods for x, y, z did not return 0 when expected")
}
}

func TestSwizzling(t *testing.T) {
v1 := vec{1, 12, 73.2, 99}
v2, _ := v1.Swizzle(3, 0, 1, 2)

if v2[0] != 99 || v2[1] != 1 || v2[2] != 12 || v2[3] != 73.2 {
t.Error("swizzling functions did not return values expected")
}

}

0 comments on commit 8b37b46

Please sign in to comment.