mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-04 23:56:40 -05:00
Vector method pointers (#621)
* All Vector methods which operate on the vector return pointers to it. * All Vector methods which take vectors take Vector pointers.
This commit is contained in:
parent
89b031d2b7
commit
259c6e7e76
@ -1,5 +1,5 @@
|
|||||||
// Package d2vector provides an implementation of a 2D Euclidean vector using float64 to store the two values.
|
// Package d2vector provides an implementation of a 2D Euclidean vector using float64 to store the two values.
|
||||||
/*
|
/*
|
||||||
Vector uses d2math.Epsilon for approximate equality and comparison. Note: SetLength and Rotate do not (per the unit
|
Vector uses d2math.Epsilon for approximate equality and comparison. Note: SetLength, Reflect, ReflectSurface and Rotate
|
||||||
tests) return exact values but ones within Epsilon range of the expected value.*/
|
do not (per their unit tests) return exact values but ones within Epsilon range of the expected value.*/
|
||||||
package d2vector
|
package d2vector
|
||||||
|
@ -22,15 +22,15 @@ type Position struct {
|
|||||||
// NewPosition returns a Position struct with the given sub tile coordinates where 1 = 1 sub tile, with a fractional
|
// NewPosition returns a Position struct with the given sub tile coordinates where 1 = 1 sub tile, with a fractional
|
||||||
// offset.
|
// offset.
|
||||||
func NewPosition(x, y float64) Position {
|
func NewPosition(x, y float64) Position {
|
||||||
p := Position{NewVector(x, y)}
|
p := Position{*NewVector(x, y)}
|
||||||
p.checkValues()
|
p.checkValues()
|
||||||
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPosition returns a Position struct with the given tile coordinates where 1 = 1 tile, with a fractional offset.
|
// NewPositionTile returns a Position struct with the given tile coordinates where 1 = 1 tile, with a fractional offset.
|
||||||
func NewPositionTile(x, y float64) Position {
|
func NewPositionTile(x, y float64) Position {
|
||||||
p := Position{NewVector(x*subTilesPerTile, y*subTilesPerTile)}
|
p := Position{*NewVector(x*subTilesPerTile, y*subTilesPerTile)}
|
||||||
p.checkValues()
|
p.checkValues()
|
||||||
|
|
||||||
return p
|
return p
|
||||||
|
@ -42,11 +42,11 @@ func TestNewPosition(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func validate(description string, t *testing.T, original, got, want, unchanged Vector) {
|
func validate(description string, t *testing.T, original, got, want, unchanged Vector) {
|
||||||
if !got.EqualsApprox(want) {
|
if !got.EqualsApprox(&want) {
|
||||||
t.Errorf("%s: want %s: got %s", description, want, got)
|
t.Errorf("%s: want %s: got %s", description, want, got)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !original.EqualsApprox(unchanged) {
|
if !original.EqualsApprox(&unchanged) {
|
||||||
t.Errorf("Position value %s was incorrectly changed to %s when calling this method", unchanged, original)
|
t.Errorf("Position value %s was incorrectly changed to %s when calling this method", unchanged, original)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ func TestPosition_World(t *testing.T) {
|
|||||||
got := p.World()
|
got := p.World()
|
||||||
want := NewVector(1, 2)
|
want := NewVector(1, 2)
|
||||||
|
|
||||||
validate("world position", t, p.Vector, *got, want, unchanged)
|
validate("world position", t, p.Vector, *got, *want, *unchanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPosition_Tile(t *testing.T) {
|
func TestPosition_Tile(t *testing.T) {
|
||||||
@ -66,7 +66,7 @@ func TestPosition_Tile(t *testing.T) {
|
|||||||
got := p.Tile()
|
got := p.Tile()
|
||||||
want := NewVector(4, 4)
|
want := NewVector(4, 4)
|
||||||
|
|
||||||
validate("tile position", t, p.Vector, *got, want, unchanged)
|
validate("tile position", t, p.Vector, *got, *want, *unchanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPosition_RenderOffset(t *testing.T) {
|
func TestPosition_RenderOffset(t *testing.T) {
|
||||||
@ -75,5 +75,5 @@ func TestPosition_RenderOffset(t *testing.T) {
|
|||||||
got := p.RenderOffset()
|
got := p.RenderOffset()
|
||||||
want := NewVector(3.1, 5.2)
|
want := NewVector(3.1, 5.2)
|
||||||
|
|
||||||
validate("offset from sub tile", t, p.Vector, *got, want, unchanged)
|
validate("offset from sub tile", t, p.Vector, *got, *want, *unchanged)
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@ type Vector struct {
|
|||||||
const two float64 = 2
|
const two float64 = 2
|
||||||
|
|
||||||
// NewVector creates a new Vector with the given x and y values.
|
// NewVector creates a new Vector with the given x and y values.
|
||||||
func NewVector(x, y float64) Vector {
|
func NewVector(x, y float64) *Vector {
|
||||||
return Vector{x, y}
|
return &Vector{x, y}
|
||||||
}
|
}
|
||||||
|
|
||||||
// X returns the x value of this vector.
|
// X returns the x value of this vector.
|
||||||
@ -30,19 +30,19 @@ func (v *Vector) Y() float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Equals returns true if the float64 values of this vector are exactly equal to the given Vector.
|
// Equals returns true if the float64 values of this vector are exactly equal to the given Vector.
|
||||||
func (v *Vector) Equals(o Vector) bool {
|
func (v *Vector) Equals(o *Vector) bool {
|
||||||
return v.x == o.x && v.y == o.y
|
return v.x == o.x && v.y == o.y
|
||||||
}
|
}
|
||||||
|
|
||||||
// EqualsApprox returns true if the values of this Vector are approximately equal to those of the given Vector. If the
|
// EqualsApprox returns true if the values of this Vector are approximately equal to those of the given Vector. If the
|
||||||
// difference between either of the value pairs is smaller than d2math.Epsilon, they will be considered equal.
|
// difference between either of the value pairs is smaller than d2math.Epsilon, they will be considered equal.
|
||||||
func (v *Vector) EqualsApprox(o Vector) bool {
|
func (v *Vector) EqualsApprox(o *Vector) bool {
|
||||||
return d2math.EqualsApprox(v.x, o.x) && d2math.EqualsApprox(v.y, o.y)
|
return d2math.EqualsApprox(v.x, o.x) && d2math.EqualsApprox(v.y, o.y)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CompareApprox returns 2 ints describing the difference between the vectors. If the difference between either of the
|
// CompareApprox returns 2 ints describing the difference between the vectors. If the difference between either of the
|
||||||
// value pairs is smaller than d2math.Epsilon, they will be considered equal.
|
// value pairs is smaller than d2math.Epsilon, they will be considered equal.
|
||||||
func (v *Vector) CompareApprox(o Vector) (x, y int) {
|
func (v *Vector) CompareApprox(o *Vector) (x, y int) {
|
||||||
return d2math.CompareApprox(v.x, o.x),
|
return d2math.CompareApprox(v.x, o.x),
|
||||||
d2math.CompareApprox(v.y, o.y)
|
d2math.CompareApprox(v.y, o.y)
|
||||||
}
|
}
|
||||||
@ -61,7 +61,7 @@ func (v *Vector) Set(x, y float64) *Vector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clone returns a new a copy of this Vector.
|
// Clone returns a new a copy of this Vector.
|
||||||
func (v *Vector) Clone() Vector {
|
func (v *Vector) Clone() *Vector {
|
||||||
return NewVector(v.x, v.y)
|
return NewVector(v.x, v.y)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ func (v *Vector) Negate() *Vector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Distance between this Vector's position and that of the given Vector.
|
// Distance between this Vector's position and that of the given Vector.
|
||||||
func (v *Vector) Distance(o Vector) float64 {
|
func (v *Vector) Distance(o *Vector) float64 {
|
||||||
delta := o.Clone()
|
delta := o.Clone()
|
||||||
delta.Subtract(v)
|
delta.Subtract(v)
|
||||||
|
|
||||||
@ -178,7 +178,7 @@ func (v *Vector) Length() float64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetLength sets the length of this Vector without changing the direction. The length will be exact within
|
// SetLength sets the length of this Vector without changing the direction. The length will be exact within
|
||||||
// d2math.Epsilon. See d2math.EqualsApprox.
|
// d2math.Epsilon.
|
||||||
func (v *Vector) SetLength(length float64) *Vector {
|
func (v *Vector) SetLength(length float64) *Vector {
|
||||||
v.Normalize()
|
v.Normalize()
|
||||||
v.Scale(length)
|
v.Scale(length)
|
||||||
@ -212,26 +212,25 @@ func (v *Vector) Dot(o *Vector) float64 {
|
|||||||
// Negative = clockwise
|
// Negative = clockwise
|
||||||
// Positive = anti-clockwise
|
// Positive = anti-clockwise
|
||||||
// 0 = vectors are identical.
|
// 0 = vectors are identical.
|
||||||
func (v *Vector) Cross(o Vector) float64 {
|
func (v *Vector) Cross(o *Vector) float64 {
|
||||||
return v.x*o.y - v.y*o.x
|
return v.x*o.y - v.y*o.x
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize sets the vector length to 1 without changing the direction. The normalized vector may be scaled by the
|
// Normalize sets the vector length to 1 without changing the direction. The normalized vector may be scaled by the
|
||||||
// float64 return value to restore it's original length.
|
// float64 return value to restore it's original length.
|
||||||
func (v *Vector) Normalize() float64 {
|
func (v *Vector) Normalize() *Vector {
|
||||||
if v.IsZero() {
|
if v.IsZero() {
|
||||||
return 0
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
multiplier := 1 / v.Length()
|
v.Scale(1 / v.Length())
|
||||||
v.Scale(multiplier)
|
|
||||||
|
|
||||||
return 1 / multiplier
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
// Angle computes the unsigned angle in radians from this vector to the given vector. This angle will never exceed half
|
// Angle computes the unsigned angle in radians from this vector to the given vector. This angle will never exceed half
|
||||||
// a full circle. For angles describing a full circumference use SignedAngle.
|
// a full circle. For angles describing a full circumference use SignedAngle.
|
||||||
func (v *Vector) Angle(o Vector) float64 {
|
func (v *Vector) Angle(o *Vector) float64 {
|
||||||
if v.IsZero() || o.IsZero() {
|
if v.IsZero() || o.IsZero() {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@ -243,13 +242,13 @@ func (v *Vector) Angle(o Vector) float64 {
|
|||||||
to.Normalize()
|
to.Normalize()
|
||||||
|
|
||||||
denominator := math.Sqrt(from.Length() * to.Length())
|
denominator := math.Sqrt(from.Length() * to.Length())
|
||||||
dotClamped := d2math.Clamp(from.Dot(&to)/denominator, -1, 1)
|
dotClamped := d2math.Clamp(from.Dot(to)/denominator, -1, 1)
|
||||||
|
|
||||||
return math.Acos(dotClamped)
|
return math.Acos(dotClamped)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignedAngle computes the signed (clockwise) angle in radians from this vector to the given vector.
|
// SignedAngle computes the signed (clockwise) angle in radians from this vector to the given vector.
|
||||||
func (v *Vector) SignedAngle(o Vector) float64 {
|
func (v *Vector) SignedAngle(o *Vector) float64 {
|
||||||
unsigned := v.Angle(o)
|
unsigned := v.Angle(o)
|
||||||
sign := d2math.Sign(v.x*o.y - v.y*o.x)
|
sign := d2math.Sign(v.x*o.y - v.y*o.x)
|
||||||
|
|
||||||
@ -260,22 +259,22 @@ func (v *Vector) SignedAngle(o Vector) float64 {
|
|||||||
return unsigned
|
return unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reflect sets this Vector to it's reflection off a line defined by the given normal.
|
// Reflect sets this Vector to it's reflection off a line defined by the given normal. The result will be exact within
|
||||||
func (v *Vector) Reflect(normal Vector) *Vector {
|
// d2math.Epsilon.
|
||||||
|
func (v *Vector) Reflect(normal *Vector) *Vector {
|
||||||
normal.Normalize()
|
normal.Normalize()
|
||||||
undo := v.Normalize()
|
v.Normalize()
|
||||||
|
|
||||||
// 1*Dot is the directional (ignoring length) difference between the vector and the normal. Therefore 2*Dot takes
|
// 1*Dot is the directional (ignoring length) difference between the vector and the normal. Therefore 2*Dot takes
|
||||||
// us beyond the normal to the angle with the equivalent distance in the other direction i.e. the reflection.
|
// us beyond the normal to the angle with the equivalent distance in the other direction i.e. the reflection.
|
||||||
normal.Scale(two * v.Dot(&normal))
|
normal.Scale(two * v.Dot(normal))
|
||||||
v.Subtract(&normal)
|
v.Subtract(normal)
|
||||||
v.Scale(undo)
|
|
||||||
|
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReflectSurface does the same thing as Reflect, except the given vector describes the surface line, not it's normal.
|
// ReflectSurface does the same thing as Reflect, except the given vector describes the surface line, not it's normal.
|
||||||
func (v *Vector) ReflectSurface(surface Vector) *Vector {
|
func (v *Vector) ReflectSurface(surface *Vector) *Vector {
|
||||||
v.Reflect(surface).Negate()
|
v.Reflect(surface).Negate()
|
||||||
|
|
||||||
return v
|
return v
|
||||||
@ -316,31 +315,31 @@ func (v Vector) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VectorUp returns a new vector (0, 1)
|
// VectorUp returns a new vector (0, 1)
|
||||||
func VectorUp() Vector {
|
func VectorUp() *Vector {
|
||||||
return NewVector(0, 1)
|
return NewVector(0, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VectorDown returns a new vector (0, -1)
|
// VectorDown returns a new vector (0, -1)
|
||||||
func VectorDown() Vector {
|
func VectorDown() *Vector {
|
||||||
return NewVector(0, -1)
|
return NewVector(0, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VectorRight returns a new vector (1, 0)
|
// VectorRight returns a new vector (1, 0)
|
||||||
func VectorRight() Vector {
|
func VectorRight() *Vector {
|
||||||
return NewVector(1, 0)
|
return NewVector(1, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VectorLeft returns a new vector (-1, 0)
|
// VectorLeft returns a new vector (-1, 0)
|
||||||
func VectorLeft() Vector {
|
func VectorLeft() *Vector {
|
||||||
return NewVector(-1, 0)
|
return NewVector(-1, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VectorOne returns a new vector (1, 1)
|
// VectorOne returns a new vector (1, 1)
|
||||||
func VectorOne() Vector {
|
func VectorOne() *Vector {
|
||||||
return NewVector(1, 1)
|
return NewVector(1, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VectorZero returns a new vector (0, 0)
|
// VectorZero returns a new vector (0, 0)
|
||||||
func VectorZero() Vector {
|
func VectorZero() *Vector {
|
||||||
return NewVector(0, 0)
|
return NewVector(0, 0)
|
||||||
}
|
}
|
||||||
|
@ -116,10 +116,10 @@ func BenchmarkVector_CompareApprox(b *testing.B) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestVector_IsZero(t *testing.T) {
|
func TestVector_IsZero(t *testing.T) {
|
||||||
testIsZero(NewVector(0, 0), true, t)
|
testIsZero(*NewVector(0, 0), true, t)
|
||||||
testIsZero(NewVector(1, 0), false, t)
|
testIsZero(*NewVector(1, 0), false, t)
|
||||||
testIsZero(NewVector(0, 1), false, t)
|
testIsZero(*NewVector(0, 1), false, t)
|
||||||
testIsZero(NewVector(1, 1), false, t)
|
testIsZero(*NewVector(1, 1), false, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testIsZero(v Vector, want bool, t *testing.T) {
|
func testIsZero(v Vector, want bool, t *testing.T) {
|
||||||
@ -169,14 +169,14 @@ func BenchmarkVector_Clone(b *testing.B) {
|
|||||||
v := NewVector(1, 1)
|
v := NewVector(1, 1)
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
outVector = v.Clone()
|
outVector = *v.Clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVector_Copy(t *testing.T) {
|
func TestVector_Copy(t *testing.T) {
|
||||||
want := NewVector(1, 2)
|
want := NewVector(1, 2)
|
||||||
got := NewVector(0, 0)
|
got := NewVector(0, 0)
|
||||||
got.Copy(&want)
|
got.Copy(want)
|
||||||
|
|
||||||
if !got.Equals(want) {
|
if !got.Equals(want) {
|
||||||
t.Errorf("copy %s to %s: want %s: got %s", got, want, want, got)
|
t.Errorf("copy %s to %s: want %s: got %s", got, want, want, got)
|
||||||
@ -188,7 +188,7 @@ func BenchmarkVector_Copy(b *testing.B) {
|
|||||||
o := NewVector(2, 2)
|
o := NewVector(2, 2)
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
v.Copy(&o)
|
v.Copy(o)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ func TestVector_Clamp(t *testing.T) {
|
|||||||
b := NewVector(7, 7)
|
b := NewVector(7, 7)
|
||||||
|
|
||||||
want := NewVector(2, 7)
|
want := NewVector(2, 7)
|
||||||
got := v.Clamp(&a, &b)
|
got := v.Clamp(a, b)
|
||||||
|
|
||||||
if !got.Equals(want) {
|
if !got.Equals(want) {
|
||||||
t.Errorf("clamp %s between %s and %s: want %s: got %s", c, a, b, want, *got)
|
t.Errorf("clamp %s between %s and %s: want %s: got %s", c, a, b, want, *got)
|
||||||
@ -231,7 +231,7 @@ func BenchmarkVector_Clamp(b *testing.B) {
|
|||||||
max := NewVector(1, 1)
|
max := NewVector(1, 1)
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
v.Clamp(&min, &max)
|
v.Clamp(min, max)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +240,7 @@ func TestVector_Add(t *testing.T) {
|
|||||||
add := NewVector(0.5, 3)
|
add := NewVector(0.5, 3)
|
||||||
want := NewVector(1.5, 5)
|
want := NewVector(1.5, 5)
|
||||||
got := v.Clone()
|
got := v.Clone()
|
||||||
got.Add(&add)
|
got.Add(add)
|
||||||
|
|
||||||
if !got.Equals(want) {
|
if !got.Equals(want) {
|
||||||
t.Errorf("add %s to %s: want %s: got %s", add, v, want, got)
|
t.Errorf("add %s to %s: want %s: got %s", add, v, want, got)
|
||||||
@ -252,7 +252,7 @@ func BenchmarkVector_Add(b *testing.B) {
|
|||||||
o := NewVector(0.01, 0.01)
|
o := NewVector(0.01, 0.01)
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
v.Add(&o)
|
v.Add(o)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,7 +281,7 @@ func TestVector_Subtract(t *testing.T) {
|
|||||||
subtract := NewVector(0.6, 0.6)
|
subtract := NewVector(0.6, 0.6)
|
||||||
want := NewVector(0.4, 0.4)
|
want := NewVector(0.4, 0.4)
|
||||||
got := v.Clone()
|
got := v.Clone()
|
||||||
got.Subtract(&subtract)
|
got.Subtract(subtract)
|
||||||
|
|
||||||
if !got.Equals(want) {
|
if !got.Equals(want) {
|
||||||
t.Errorf("subtract %s from %s: want %s: got %s", subtract, v, want, got)
|
t.Errorf("subtract %s from %s: want %s: got %s", subtract, v, want, got)
|
||||||
@ -293,7 +293,7 @@ func BenchmarkVector_Subtract(b *testing.B) {
|
|||||||
o := NewVector(0.01, 0.01)
|
o := NewVector(0.01, 0.01)
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
v.Subtract(&o)
|
v.Subtract(o)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,7 +302,7 @@ func TestVector_Multiply(t *testing.T) {
|
|||||||
multiply := NewVector(2, 2)
|
multiply := NewVector(2, 2)
|
||||||
want := NewVector(2, 2)
|
want := NewVector(2, 2)
|
||||||
got := v.Clone()
|
got := v.Clone()
|
||||||
got.Multiply(&multiply)
|
got.Multiply(multiply)
|
||||||
|
|
||||||
if !got.Equals(want) {
|
if !got.Equals(want) {
|
||||||
t.Errorf("multiply %s by %s: want %s: got %s", v, multiply, want, got)
|
t.Errorf("multiply %s by %s: want %s: got %s", v, multiply, want, got)
|
||||||
@ -314,7 +314,7 @@ func BenchmarkVector_Multiply(b *testing.B) {
|
|||||||
o := NewVector(0.01, 0.01)
|
o := NewVector(0.01, 0.01)
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
v.Multiply(&o)
|
v.Multiply(o)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,7 +323,7 @@ func TestVector_Divide(t *testing.T) {
|
|||||||
divide := NewVector(2, 4)
|
divide := NewVector(2, 4)
|
||||||
want := NewVector(0.5, 2)
|
want := NewVector(0.5, 2)
|
||||||
got := v.Clone()
|
got := v.Clone()
|
||||||
got.Divide(÷)
|
got.Divide(divide)
|
||||||
|
|
||||||
if !got.Equals(want) {
|
if !got.Equals(want) {
|
||||||
t.Errorf("divide %s by %s: want %s: got %s", v, divide, want, got)
|
t.Errorf("divide %s by %s: want %s: got %s", v, divide, want, got)
|
||||||
@ -335,7 +335,7 @@ func BenchmarkVector_Divide(b *testing.B) {
|
|||||||
o := NewVector(3, 3)
|
o := NewVector(3, 3)
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
v.Divide(&o)
|
v.Divide(o)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,7 +488,7 @@ func TestVector_Lerp(t *testing.T) {
|
|||||||
interp := 0.3
|
interp := 0.3
|
||||||
|
|
||||||
want := NewVector(-6, 3)
|
want := NewVector(-6, 3)
|
||||||
got := a.Lerp(&b, interp)
|
got := a.Lerp(b, interp)
|
||||||
|
|
||||||
if !got.Equals(want) {
|
if !got.Equals(want) {
|
||||||
t.Errorf("linear interpolation between %s and %s by %.2f: want %s: got %s", a, b, interp, want, got)
|
t.Errorf("linear interpolation between %s and %s by %.2f: want %s: got %s", a, b, interp, want, got)
|
||||||
@ -500,7 +500,7 @@ func BenchmarkVector_Lerp(b *testing.B) {
|
|||||||
t := NewVector(1000, 1000)
|
t := NewVector(1000, 1000)
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
v.Lerp(&t, 1.01)
|
v.Lerp(t, 1.01)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,7 +508,7 @@ func TestVector_Dot(t *testing.T) {
|
|||||||
v := NewVector(1, 1)
|
v := NewVector(1, 1)
|
||||||
c := v.Clone()
|
c := v.Clone()
|
||||||
want := 2.0
|
want := 2.0
|
||||||
got := c.Dot(&c)
|
got := c.Dot(c)
|
||||||
|
|
||||||
d := fmt.Sprintf("dot product of %s", v)
|
d := fmt.Sprintf("dot product of %s", v)
|
||||||
|
|
||||||
@ -525,7 +525,7 @@ func BenchmarkVector_Dot(b *testing.B) {
|
|||||||
v := NewVector(1, 1)
|
v := NewVector(1, 1)
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
outFloat = v.Dot(&v)
|
outFloat = v.Dot(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,20 +573,12 @@ func TestVector_Normalize(t *testing.T) {
|
|||||||
v = NewVector(0, 10)
|
v = NewVector(0, 10)
|
||||||
c = v.Clone()
|
c = v.Clone()
|
||||||
want = NewVector(0, 1)
|
want = NewVector(0, 1)
|
||||||
reverse := c.Normalize()
|
c.Normalize()
|
||||||
|
|
||||||
if !want.Equals(c) {
|
if !want.Equals(c) {
|
||||||
t.Errorf("normalize %s: want %s: got %s", v, want, c)
|
t.Errorf("normalize %s: want %s: got %s", v, want, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
want = NewVector(0, 10)
|
|
||||||
|
|
||||||
c.Scale(reverse)
|
|
||||||
|
|
||||||
if !want.Equals(c) {
|
|
||||||
t.Errorf("reverse normalizing of %s: want %s: got %s", v, want, c)
|
|
||||||
}
|
|
||||||
|
|
||||||
v = NewVector(0, 0)
|
v = NewVector(0, 0)
|
||||||
c = v.Clone()
|
c = v.Clone()
|
||||||
want = NewVector(0, 0)
|
want = NewVector(0, 0)
|
||||||
@ -602,7 +594,7 @@ func BenchmarkVector_Normalize(b *testing.B) {
|
|||||||
v := NewVector(1, 1)
|
v := NewVector(1, 1)
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
outFloat = v.Normalize()
|
outVector = *v.Normalize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,6 +688,7 @@ func TestVector_Reflect(t *testing.T) {
|
|||||||
up := NewVector(0, 1)
|
up := NewVector(0, 1)
|
||||||
|
|
||||||
want := NewVector(1, 1)
|
want := NewVector(1, 1)
|
||||||
|
want.Normalize()
|
||||||
|
|
||||||
v.Reflect(up)
|
v.Reflect(up)
|
||||||
|
|
||||||
@ -719,6 +712,7 @@ func TestVector_ReflectSurface(t *testing.T) {
|
|||||||
up := NewVector(0, 1)
|
up := NewVector(0, 1)
|
||||||
|
|
||||||
want := NewVector(-1, -1)
|
want := NewVector(-1, -1)
|
||||||
|
want.Normalize()
|
||||||
|
|
||||||
v.ReflectSurface(up)
|
v.ReflectSurface(up)
|
||||||
|
|
||||||
@ -745,7 +739,7 @@ func TestVector_Rotate(t *testing.T) {
|
|||||||
want := NewVector(0, 1)
|
want := NewVector(0, 1)
|
||||||
got := right.Rotate(angle)
|
got := right.Rotate(angle)
|
||||||
|
|
||||||
if !want.EqualsApprox(*got) {
|
if !want.EqualsApprox(got) {
|
||||||
t.Errorf("rotated %s by %.1f: want %s: got %s", c, angle*d2math.RadToDeg, want, got)
|
t.Errorf("rotated %s by %.1f: want %s: got %s", c, angle*d2math.RadToDeg, want, got)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -754,7 +748,7 @@ func TestVector_Rotate(t *testing.T) {
|
|||||||
want = NewVector(-1, 0)
|
want = NewVector(-1, 0)
|
||||||
got = up.Rotate(angle)
|
got = up.Rotate(angle)
|
||||||
|
|
||||||
if !want.EqualsApprox(*got) {
|
if !want.EqualsApprox(got) {
|
||||||
t.Errorf("rotated %s by %.1f: want %s: got %s", c, angle*d2math.RadToDeg, want, got)
|
t.Errorf("rotated %s by %.1f: want %s: got %s", c, angle*d2math.RadToDeg, want, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -775,7 +769,7 @@ func TestVector_NinetyAnti(t *testing.T) {
|
|||||||
want := NewVector(-1, 0)
|
want := NewVector(-1, 0)
|
||||||
got := v.NinetyAnti()
|
got := v.NinetyAnti()
|
||||||
|
|
||||||
if !want.Equals(*got) {
|
if !want.Equals(got) {
|
||||||
t.Errorf("rotated %s by 90 degrees clockwise: want %s: got %s", c, want, *got)
|
t.Errorf("rotated %s by 90 degrees clockwise: want %s: got %s", c, want, *got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -796,7 +790,7 @@ func TestVector_NinetyClock(t *testing.T) {
|
|||||||
v = c.Clone()
|
v = c.Clone()
|
||||||
got := v.NinetyClock()
|
got := v.NinetyClock()
|
||||||
|
|
||||||
if !want.Equals(*got) {
|
if !want.Equals(got) {
|
||||||
t.Errorf("rotated %s by 90 degrees anti-clockwise: want %s: got %s", c, want, *got)
|
t.Errorf("rotated %s by 90 degrees anti-clockwise: want %s: got %s", c, want, *got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ func (m *MapEngine) PathFind(start, dest d2vector.Position) []d2vector.Position
|
|||||||
|
|
||||||
// checkLos finds out if there is a clear line of sight between two points
|
// checkLos finds out if there is a clear line of sight between two points
|
||||||
func (m *MapEngine) checkLos(start, end d2vector.Position) (bool, d2vector.Position) {
|
func (m *MapEngine) checkLos(start, end d2vector.Position) (bool, d2vector.Position) {
|
||||||
dv := d2vector.Position{Vector: end.Clone()}
|
dv := d2vector.Position{Vector: *end.Clone()}
|
||||||
dv.Subtract(&start.Vector)
|
dv.Subtract(&start.Vector)
|
||||||
dx := dv.X()
|
dx := dv.X()
|
||||||
dy := dv.Y()
|
dy := dv.Y()
|
||||||
|
@ -25,7 +25,7 @@ func newMapEntity(x, y int) mapEntity {
|
|||||||
return mapEntity{
|
return mapEntity{
|
||||||
Position: pos,
|
Position: pos,
|
||||||
Target: pos,
|
Target: pos,
|
||||||
velocity: d2vector.NewVector(0, 0),
|
velocity: *d2vector.VectorZero(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ func (m *mapEntity) Step(tickTime float64) {
|
|||||||
v := m.velocity.Clone() // Create a new vector
|
v := m.velocity.Clone() // Create a new vector
|
||||||
|
|
||||||
for {
|
for {
|
||||||
applyVelocity(&m.Position.Vector, &v, &m.Target.Vector) // Pass the new vector to the function which alters it
|
applyVelocity(&m.Position.Vector, v, &m.Target.Vector) // Pass the new vector to the function which alters it
|
||||||
|
|
||||||
if m.atTarget() {
|
if m.atTarget() {
|
||||||
m.nextPath()
|
m.nextPath()
|
||||||
@ -89,7 +89,7 @@ func (m *mapEntity) Step(tickTime float64) {
|
|||||||
|
|
||||||
// atTarget returns true if the distance between entity and target is almost zero.
|
// atTarget returns true if the distance between entity and target is almost zero.
|
||||||
func (m *mapEntity) atTarget() bool {
|
func (m *mapEntity) atTarget() bool {
|
||||||
return m.Position.EqualsApprox(m.Target.Vector)
|
return m.Position.EqualsApprox(&m.Target.Vector)
|
||||||
}
|
}
|
||||||
|
|
||||||
// setVelocity returns a vector describing the given length and the direction to the current target.
|
// setVelocity returns a vector describing the given length and the direction to the current target.
|
||||||
@ -104,7 +104,7 @@ func (m *mapEntity) setVelocity(length float64) {
|
|||||||
// next node.
|
// next node.
|
||||||
func applyVelocity(position, velocity, target *d2vector.Vector) {
|
func applyVelocity(position, velocity, target *d2vector.Vector) {
|
||||||
// Set velocity values to zero if almost zero
|
// Set velocity values to zero if almost zero
|
||||||
x, y := position.CompareApprox(*target)
|
x, y := position.CompareApprox(target)
|
||||||
vx, vy := velocity.X(), velocity.Y()
|
vx, vy := velocity.X(), velocity.Y()
|
||||||
|
|
||||||
if x == 0 {
|
if x == 0 {
|
||||||
@ -121,7 +121,7 @@ func applyVelocity(position, velocity, target *d2vector.Vector) {
|
|||||||
dest.Add(velocity)
|
dest.Add(velocity)
|
||||||
|
|
||||||
destDistance := position.Distance(dest)
|
destDistance := position.Distance(dest)
|
||||||
targetDistance := position.Distance(*target)
|
targetDistance := position.Distance(target)
|
||||||
|
|
||||||
if destDistance > targetDistance {
|
if destDistance > targetDistance {
|
||||||
// Destination overshot target. Set position to target and velocity to overshot amount.
|
// Destination overshot target. Set position to target and velocity to overshot amount.
|
||||||
@ -129,7 +129,7 @@ func applyVelocity(position, velocity, target *d2vector.Vector) {
|
|||||||
velocity.Copy(dest.Subtract(target))
|
velocity.Copy(dest.Subtract(target))
|
||||||
} else {
|
} else {
|
||||||
// At or before target, set position to destination and velocity to zero.
|
// At or before target, set position to destination and velocity to zero.
|
||||||
position.Copy(&dest)
|
position.Copy(dest)
|
||||||
velocity.Set(0, 0)
|
velocity.Set(0, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,9 +68,9 @@ func TestMapEntity_Step(t *testing.T) {
|
|||||||
// change in position
|
// change in position
|
||||||
change.Scale(float64(stepCount))
|
change.Scale(float64(stepCount))
|
||||||
|
|
||||||
want := change.Add(&start)
|
want := change.Add(start)
|
||||||
|
|
||||||
if !e.Position.EqualsApprox(*want) {
|
if !e.Position.EqualsApprox(want) {
|
||||||
t.Errorf("entity position after %d steps: want %s: got %s", stepCount, want, e.Position.Vector)
|
t.Errorf("entity position after %d steps: want %s: got %s", stepCount, want, e.Position.Vector)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ func (c *Camera) SetTarget(target *d2vector.Position) {
|
|||||||
func (c *Camera) MoveTargetBy(vector *d2vector.Vector) {
|
func (c *Camera) MoveTargetBy(vector *d2vector.Vector) {
|
||||||
if c.target == nil {
|
if c.target == nil {
|
||||||
v := c.position.Clone()
|
v := c.position.Clone()
|
||||||
c.target = &d2vector.Position{Vector: v}
|
c.target = &d2vector.Position{Vector: *v}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.target.Add(vector)
|
c.target.Add(vector)
|
||||||
|
@ -349,7 +349,7 @@ func (mr *MapRenderer) renderEntityDebug(target d2interface.Surface) {
|
|||||||
world := pos
|
world := pos
|
||||||
x, y := world.X()/5, world.Y()/5
|
x, y := world.X()/5, world.Y()/5
|
||||||
velocity := e.GetVelocity()
|
velocity := e.GetVelocity()
|
||||||
velocity = velocity.Clone()
|
velocity = *velocity.Clone()
|
||||||
vx, vy := mr.viewport.WorldToOrtho(velocity.X(), velocity.Y())
|
vx, vy := mr.viewport.WorldToOrtho(velocity.X(), velocity.Y())
|
||||||
screenX, screenY := mr.viewport.WorldToScreen(x, y)
|
screenX, screenY := mr.viewport.WorldToScreen(x, y)
|
||||||
|
|
||||||
|
@ -140,5 +140,5 @@ func (ob *Object) GetPosition() d2vector.Position {
|
|||||||
|
|
||||||
// GetVelocity returns the object's velocity vector
|
// GetVelocity returns the object's velocity vector
|
||||||
func (ob *Object) GetVelocity() d2vector.Vector {
|
func (ob *Object) GetVelocity() d2vector.Vector {
|
||||||
return d2vector.NewVector(0, 0)
|
return *d2vector.VectorZero()
|
||||||
}
|
}
|
||||||
|
@ -379,28 +379,28 @@ func (met *MapEngineTest) OnKeyRepeat(event d2interface.KeyEvent) bool {
|
|||||||
|
|
||||||
if event.Key() == d2enum.KeyDown {
|
if event.Key() == d2enum.KeyDown {
|
||||||
v := d2vector.NewVector(0, moveSpeed)
|
v := d2vector.NewVector(0, moveSpeed)
|
||||||
met.mapRenderer.MoveCameraTargetBy(&v)
|
met.mapRenderer.MoveCameraTargetBy(v)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if event.Key() == d2enum.KeyUp {
|
if event.Key() == d2enum.KeyUp {
|
||||||
v := d2vector.NewVector(0, -moveSpeed)
|
v := d2vector.NewVector(0, -moveSpeed)
|
||||||
met.mapRenderer.MoveCameraTargetBy(&v)
|
met.mapRenderer.MoveCameraTargetBy(v)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if event.Key() == d2enum.KeyRight {
|
if event.Key() == d2enum.KeyRight {
|
||||||
v := d2vector.NewVector(moveSpeed, 0)
|
v := d2vector.NewVector(moveSpeed, 0)
|
||||||
met.mapRenderer.MoveCameraTargetBy(&v)
|
met.mapRenderer.MoveCameraTargetBy(v)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if event.Key() == d2enum.KeyLeft {
|
if event.Key() == d2enum.KeyLeft {
|
||||||
v := d2vector.NewVector(-moveSpeed, 0)
|
v := d2vector.NewVector(-moveSpeed, 0)
|
||||||
met.mapRenderer.MoveCameraTargetBy(&v)
|
met.mapRenderer.MoveCameraTargetBy(v)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -164,28 +164,28 @@ func (g *GameControls) OnKeyRepeat(event d2interface.KeyEvent) bool {
|
|||||||
|
|
||||||
if event.Key() == d2enum.KeyDown {
|
if event.Key() == d2enum.KeyDown {
|
||||||
v := d2vector.NewVector(0, moveSpeed)
|
v := d2vector.NewVector(0, moveSpeed)
|
||||||
g.mapRenderer.MoveCameraTargetBy(&v)
|
g.mapRenderer.MoveCameraTargetBy(v)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if event.Key() == d2enum.KeyUp {
|
if event.Key() == d2enum.KeyUp {
|
||||||
v := d2vector.NewVector(0, -moveSpeed)
|
v := d2vector.NewVector(0, -moveSpeed)
|
||||||
g.mapRenderer.MoveCameraTargetBy(&v)
|
g.mapRenderer.MoveCameraTargetBy(v)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if event.Key() == d2enum.KeyRight {
|
if event.Key() == d2enum.KeyRight {
|
||||||
v := d2vector.NewVector(moveSpeed, 0)
|
v := d2vector.NewVector(moveSpeed, 0)
|
||||||
g.mapRenderer.MoveCameraTargetBy(&v)
|
g.mapRenderer.MoveCameraTargetBy(v)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if event.Key() == d2enum.KeyLeft {
|
if event.Key() == d2enum.KeyLeft {
|
||||||
v := d2vector.NewVector(-moveSpeed, 0)
|
v := d2vector.NewVector(-moveSpeed, 0)
|
||||||
g.mapRenderer.MoveCameraTargetBy(&v)
|
g.mapRenderer.MoveCameraTargetBy(v)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user