func TestVectorNormalize(t *testing.T) {
	t.Parallel()
	testprecision := 4
	cases := []struct {
		v        *Vector2D
		expected *Vector2D
	}{
		{NewVector2D(0, 1), NewVector2D(0, 1)},
		{NewVector2D(4, 3), NewVector2D(0.8, 0.6)},
		{NewVector2D(8, -6), NewVector2D(0.8, -0.6)},
		{NewVector2D(0.5, 1.2), NewVector2D(0.3846, 0.9231)},
	}

	for _, c := range cases {
		normv := c.v.Normalize()
		if utils.RoundPrecision(normv.X, testprecision) != c.expected.X || utils.RoundPrecision(normv.Y, testprecision) != c.expected.Y {
			t.Errorf("Computing norm(%v) = %v - expected %v", c.v, normv, c.expected)
		}
	}
}
func TestVectorRotate(t *testing.T) {
	t.Parallel()
	testprecision := 4
	cases := []struct {
		v        *Vector2D
		radians  float64
		expected *Vector2D
	}{
		{NewVector2D(0, 1), 0, NewVector2D(0, 1)},
		{NewVector2D(0, 1), math.Pi / 2, NewVector2D(-1, 0)},
		{NewVector2D(3, 0), math.Pi, NewVector2D(-3, 0)},
		{NewVector2D(2, 2), math.Pi / 4, NewVector2D(0, 2.8284)},
		{NewVector2D(0.5, 1.2), -math.Pi / 3, NewVector2D(1.2892, 0.1670)},
	}

	for _, c := range cases {
		rotv := c.v.Rotate(c.radians)
		if utils.RoundPrecision(rotv.X, testprecision) != c.expected.X || utils.RoundPrecision(rotv.Y, testprecision) != c.expected.Y {
			t.Errorf("Computing rot(%v, %v) = %v - expected %v", c.v, c.radians, rotv, c.expected)
		}
	}
}
func TestEntityDistance(t *testing.T) {
	t.Parallel()
	testprecision := 4
	cases := []struct {
		e1       *Entity
		e2       *Entity
		expected float64
	}{
		{NewEntity(1, 0, 0, 0, 0, 0, 0), NewEntity(1, 1, 0, 0, 0, 0, 0), 1},
		{NewEntity(10, 0, 0, 0, 0, 0, 0), NewEntity(1, 3, 4, 0, 0, 0, 0), 5},
		{NewEntity(25, 15, 16, 19, 12, 31, 31), NewEntity(12, -10, -44, -1, -44, 33, -1), 65},
		{NewEntity(1.3, 2.55, 1.22, 5.32, 233, 3.154, 43.1245), NewEntity(1.5467, 2.356, 2.15123, 0.33, 0.23, 1.2, 2.5), 0.9512},
	}

	for _, c := range cases {
		distance := utils.RoundPrecision(c.e1.Distance(c.e2), testprecision)
		if distance != c.expected {
			t.Errorf("Computing distance from %v to %v: got %v - expected %v", c.e1, c.e2, distance, c.expected)
		}
	}
}
func TestEntityGravitationalForce(t *testing.T) {
	t.Parallel()
	testprecision := 3
	cases := []struct {
		e1       *Entity
		e2       *Entity
		expected float64
	}{
		{NewEntity(1, 0, 0, 0, 0, 0, 0), NewEntity(1, 1, 0, 0, 0, 0, 0), 667.834},
		{NewEntity(2, 0, 0, 0, 0, 0, 0), NewEntity(2, 2, 0, 0, 0, 0, 0), 667.834},
		{NewEntity(3, 0, 0, 0, 0, 0, 0), NewEntity(6, 5, 0, 0, 0, 0, 0), 480.840},
		{NewEntity(4.2, 0, 0, 0, 0, 0, 0), NewEntity(13.13, 6.841, 0, 0, 0, 0, 0), 786.943},
	}

	for _, c := range cases {
		force := c.e1.GravitationalForce(c.e2)
		if utils.RoundPrecision(force, testprecision) != c.expected {
			t.Errorf("Computing %v.GravitationalForce(%v) = %v - expected %v", c.e1, c.e2, force, c.expected)
		}
	}
}
func accelerationsinequal(e1 *Entity, e2 *Entity, testprecision int) bool {
	xinequal := utils.RoundPrecision(e1.Acceleration.X, testprecision) != e2.Acceleration.X
	yinequal := utils.RoundPrecision(e1.Acceleration.Y, testprecision) != e2.Acceleration.Y
	return xinequal || yinequal
}