about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--boundingBox.go27
-rw-r--r--quadtree.go84
-rw-r--r--star.go86
-rw-r--r--vector2D.go71
4 files changed, 268 insertions, 0 deletions
diff --git a/boundingBox.go b/boundingBox.go
new file mode 100644
index 0000000..ad02eab
--- /dev/null
+++ b/boundingBox.go
@@ -0,0 +1,27 @@
+package structs
+
+// BoundingBox is a struct defining the spatial outreach of a box
+type BoundingBox struct {
+	center Vec2    // Center of the box
+	width  float64 // width of the box
+}
+
+func (b *BoundingBox) Width() float64 {
+	return b.width
+}
+
+func (b *BoundingBox) SetWidth(width float64) {
+	b.width = width
+}
+
+func (b *BoundingBox) Center() Vec2 {
+	return b.center
+}
+
+func (b *BoundingBox) SetCenter(center Vec2) {
+	b.center = center
+}
+
+func NewBoundingBox(center Vec2, halfDim float64) *BoundingBox {
+	return &BoundingBox{center: center, width: halfDim}
+}
diff --git a/quadtree.go b/quadtree.go
new file mode 100644
index 0000000..103a666
--- /dev/null
+++ b/quadtree.go
@@ -0,0 +1,84 @@
+package structs
+
+// Definition of a quadtree and it's nodes recursively
+type Quadtree struct {
+	boundary     BoundingBox // Spatial outreach of the quadtree
+	centerOfMass Vec2        // Center of mass of the cell
+	totalMass    float64     // Total mass of the cell
+	depth        int         // Depth of the cell in the quadtree
+	star         Star2D      // Star inside the cell
+
+	// NW, NE, SW, SE
+	quadrants []*Quadtree // List of quadtrees representing individual quadrants
+
+	// Quadrants
+	//northWest *Quadtree
+	//northEast *Quadtree
+	//southWest *Quadtree
+	//southEast *Quadtree
+}
+
+// CenterOfMass is a getter method for quadtrees.
+// It returns the Center of mass of the quadtree it is applied on
+func (q *Quadtree) CenterOfMass() Vec2 {
+	return q.centerOfMass
+}
+
+// SetCenterOfMass is a setter method for quadtrees.
+// It sets the centerOfMass of the quadtree to the given value
+func (q *Quadtree) SetCenterOfMass(centerOfMass Vec2) {
+	q.centerOfMass = centerOfMass
+}
+
+// CalcCenterOfMass is a calculator method for quadtrees.
+// It recursively walks through the quadtree and calculates it's center of mass.
+// The calculated center of mass is then inserted into the centerOfMass variable.
+func (q *Quadtree) CalcCenterOfMass() (Vec2, float64) {
+	var totalMass float64 = 0
+	var x float64 = 0
+	var y float64 = 0
+
+	// If the Node is a leaf
+	if q.IsLeaf() == true {
+
+		// update the values needed to calculate the center of mass
+		totalMass += q.star.M
+		x += q.star.C.X * q.star.M
+		y += q.star.C.X * q.star.M
+
+		return Vec2{x, y}, totalMass
+
+	} else {
+
+		// Iterate over all the quadrants
+		for _, element := range q.quadrants {
+
+			// Calculate the center of mass for each quadrant
+			centerOfMass, totalMass := element.CalcCenterOfMass()
+
+			// Update the overall centerOfMass for the individual quadtree
+			q.centerOfMass.X += centerOfMass.X
+			q.centerOfMass.Y += centerOfMass.Y
+			q.totalMass += totalMass
+		}
+	}
+
+	// Return the original centerOfMass and totalMass
+	return q.centerOfMass, q.totalMass
+}
+
+// IsLeaf is a method for quadtrees returning true if the node is a leaf (has no children)
+// or returning false if the node is nor a leaf (has children).
+func (q *Quadtree) IsLeaf() bool {
+	for _, element := range q.quadrants {
+		if element == nil {
+			return true
+		}
+	}
+	return false
+}
+
+// NewQuadtree generates a new root node.
+//func NewQuadtree(boundary BoundingBox) *Quadtree {
+//	return &Quadtree{boundary: boundary}
+//}
diff --git a/star.go b/star.go
new file mode 100644
index 0000000..d2bb124
--- /dev/null
+++ b/star.go
@@ -0,0 +1,86 @@
+package structs
+
+// Define a struct storing essential star information such as it's coordinate, velocity and mass
+type Star2D struct {
+	C Vec2    // coordinates of the star
+	V Vec2    // velocity    of the star
+	M float64 // mass        of the star
+}
+
+// InsideOf is a method that tests if the star it is applied on is in or outside of the given
+// BoundingBox. It returns true if the star is inside of the BoundingBox and false if it isn't.
+func (s Star2D) InsideOf(boundary BoundingBox) bool {
+
+	// Test if the star is inside or outside of the bounding box.
+	// Abort testing if one of the conditions is not met
+	if s.C.X < boundary.center.X+boundary.width/2 {
+		if s.C.X > boundary.center.X-boundary.width/2 {
+			if s.C.Y < boundary.center.Y+boundary.width/2 {
+				if s.C.Y > boundary.center.Y-boundary.width/2 {
+					return true
+				} else {
+					return false
+				}
+			} else {
+				return false
+			}
+		} else {
+			return false
+		}
+	} else {
+		return false
+	}
+}
+
+// Quadrant returns a string indicating in which quadrant of the given quadtree the point the method
+// is applied on is.
+// This methods presumes that the point is inside of the boundingBox
+func (s Star2D) Quadrant(starsQuadtree *Quadtree) string {
+	centerX := starsQuadtree.boundary.center.X
+	centerY := starsQuadtree.boundary.center.Y
+
+	// test if the point is left the the center or not
+	if s.C.X < centerX {
+
+		// Test if the point is above or below of the center
+		if s.C.Y > centerY {
+			return "northwest"
+		} else {
+			return "southwest"
+		}
+
+		// The point is right of the center
+	} else {
+
+		// Test if the point is above or below of the center
+		if s.C.Y > centerY {
+			return "northeast"
+		} else {
+			return "southeast"
+		}
+	}
+}
+
+// Return a copy of the star by returning a star struct with the same values.
+func (s *Star2D) Copy() Star2D {
+	return Star2D{s.C.Copy(), s.V.Copy(), s.M}
+}
+
+// Accelerate the star with the acceleration a for the time t.
+// This changes the velocity of the star.
+func (s *Star2D) AccelerateVelocity(a Vec2, t float64) {
+	s.V = s.V.Add(a.Multiply(t))
+}
+
+// Move the star with it's velocity for the time t.
+// This changes the Position of the star.
+func (s *Star2D) Move(t float64) {
+	s.C = s.C.Add(s.V.Multiply(t))
+}
+
+// Accelerate and move the star with it's velocity and the acceleration a for the time t
+// This changes the position and the velocity of the star.
+func (s *Star2D) Accelerate(a Vec2, t float64) {
+	s.AccelerateVelocity(a, t)
+	s.Move(t)
+}
diff --git a/vector2D.go b/vector2D.go
new file mode 100644
index 0000000..6beedb2
--- /dev/null
+++ b/vector2D.go
@@ -0,0 +1,71 @@
+package structs
+
+import (
+	"math"
+)
+
+type Vec2 struct {
+	X, Y float64
+}
+
+// newVec2 returns a new Vec2 using the given coordinates
+func newVec2(x float64, y float64) *Vec2 {
+	return &Vec2{
+		X: x,
+		Y: y,
+	}
+}
+
+// creates a copy of the vector
+func (v *Vec2) Copy() Vec2 {
+	return Vec2{v.X, v.Y}
+}
+
+func (v *Vec2) Split() (x float64, y float64) {
+	return v.X, v.Y
+}
+
+// changes the length of the vector to the length l
+func (v *Vec2) SetLength(l float64) {
+	var k = l / v.GetLength()
+	var newV = v.Multiply(k)
+	//	v = newV
+	v.X, v.Y = newV.Split()
+}
+
+// changes the length of the vector to the length 1
+func (v *Vec2) SetLengthOne() {
+	v.SetLength(1)
+}
+
+// returns the direction Vector of this vector. This means a copy of this vector with a length of 1
+func (v *Vec2) GetDirVector() Vec2 {
+	var dirV = v.Copy()
+	dirV.SetLengthOne()
+	return dirV
+}
+
+// returns the length of the vector
+func (v *Vec2) GetLength() float64 {
+	return math.Sqrt(math.Pow(v.X, 2) + math.Pow(v.Y, 2))
+}
+
+// returns the product of the vector and a scalar s
+func (v *Vec2) Multiply(s float64) Vec2 {
+	return Vec2{v.X * s, v.Y * s}
+}
+
+// returns the quotient of the vector and a scalar s
+func (v *Vec2) Divide(s float64) Vec2 {
+	return Vec2{v.X / s, v.Y / s}
+}
+
+// returns the sum of this vector and the vector v2
+func (v1 *Vec2) Add(v2 Vec2) Vec2 {
+	return Vec2{v1.X + v2.X, v1.Y + v2.Y}
+}
+
+// returns the difference of this vector minus the vector v2
+func (v1 *Vec2) Subtract(v2 Vec2) Vec2 {
+	return Vec2{v1.X - v2.X, v1.Y - v2.Y}
+}