about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.idea/inspectionProfiles/Project_Default.xml20
-rw-r--r--config.json2
-rw-r--r--csv/csv.go22
-rw-r--r--draw/draw.go10
-rw-r--r--main.go55
-rw-r--r--structs/boundingBox.go27
-rw-r--r--structs/quadtree.go84
-rw-r--r--structs/star.go56
8 files changed, 251 insertions, 25 deletions
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..e62755d
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,20 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="GoUnhandledErrorResult" enabled="true" level="WARNING" enabled_by_default="true">
+      <methods>
+        <method importPath="hash" receiver="Hash" name="Write" />
+        <method importPath="strings" receiver="*Builder" name="Write" />
+        <method importPath="strings" receiver="*Builder" name="WriteByte" />
+        <method importPath="bytes" receiver="*Buffer" name="WriteRune" />
+        <method importPath="bytes" receiver="*Buffer" name="Write" />
+        <method importPath="bytes" receiver="*Buffer" name="WriteString" />
+        <method importPath="strings" receiver="*Builder" name="WriteString" />
+        <method importPath="bytes" receiver="*Buffer" name="WriteByte" />
+        <method importPath="strings" receiver="*Builder" name="WriteRune" />
+        <method importPath="math/rand" receiver="*Rand" name="Read" />
+        <method importPath="os" receiver="*File" name="Close" />
+      </methods>
+    </inspection_tool>
+  </profile>
+</component>
\ No newline at end of file
diff --git a/config.json b/config.json
index 0fd8122..5b77619 100644
--- a/config.json
+++ b/config.json
@@ -2,7 +2,7 @@
   "Frames": 1,
   "Threads": 8,
   "RangeStart": 0,
-  "RangeEnd": 5000,
+  "RangeEnd": 50000,
   "LoadPath": "data/U_ALL.csv",
   "OutPath": "out_%d.csv"
 }
diff --git a/csv/csv.go b/csv/csv.go
index 1b3c0bc..01c3743 100644
--- a/csv/csv.go
+++ b/csv/csv.go
@@ -40,3 +40,25 @@ func Import(path string, start int, end int, slice []structs.Star2D) []structs.S
 
 	return slice
 }
+
+// Generate a homogeneous Grid
+func GenerateHomogeneousGrid(slice []structs.Star2D, left int, right int, step int) []structs.Star2D {
+
+	// Iterate over a grid
+	for i := left; i < right; i += step {
+		for j := left; j < right; j += step {
+
+			// generate a new star with the coordinates
+			tempStar := structs.Star2D{
+				C: structs.Vec2{X: float64(i) + float64(rand.Intn(step)), Y: float64(j) + float64(rand.Intn(step))},
+				M: float64(rand.Intn(500000)),
+			}
+
+			// add the star to the slice
+			slice = append(slice, tempStar)
+		}
+	}
+
+	// return the new slice containing a homogeneous grid of stars
+	return slice
+}
diff --git a/draw/draw.go b/draw/draw.go
index 8b66c90..de58191 100644
--- a/draw/draw.go
+++ b/draw/draw.go
@@ -1,7 +1,6 @@
 package draw
 
 import (
-	"fmt"
 	"git.darknebu.la/GalaxySimulator/Source/structs"
 	"github.com/fogleman/gg"
 	"math"
@@ -10,8 +9,8 @@ import (
 // initializePlot generates a new plot and returns the plot context
 func initializePlot() *gg.Context {
 	// Define the image size
-	const imageWidth = 8192
-	const imageHeight = 8192
+	const imageWidth = 8192 * 2
+	const imageHeight = 8192 * 2
 
 	// Initialize the new context
 	dc := gg.NewContext(imageWidth, imageHeight)
@@ -68,8 +67,7 @@ func drawVelocity(dc *gg.Context, star structs.Star2D) {
 
 	// Use a sigmoid function to generate useful values for coloring the vectors according to their
 	// strength
-	var val = 1.0 / (1.0 + math.Exp(-vecLength*scalingFactor/2 * 1e8))
-	fmt.Println(val)
+	var val = 1.0 / (1.0 + math.Exp(-vecLength*scalingFactor/2*1e8))
 
 	// Set the color to a blue / red
 	dc.SetRGB(val, 0, 1-val)
@@ -81,7 +79,7 @@ func drawVelocity(dc *gg.Context, star structs.Star2D) {
 	dc.LineTo(star.C.X/50+(FUnit.X*scalingFactor), star.C.Y/50+(FUnit.Y*scalingFactor))
 
 	// set line width
-	dc.SetLineWidth(3)
+	dc.SetLineWidth(5)
 
 	// And finally: DRAW (stroke) the vector
 	dc.Stroke()
diff --git a/main.go b/main.go
index 4a3dcad..1126af2 100644
--- a/main.go
+++ b/main.go
@@ -4,10 +4,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"git.darknebu.la/GalaxySimulator/Source/csv"
-	"git.darknebu.la/GalaxySimulator/Source/draw"
-	"git.darknebu.la/GalaxySimulator/Source/forces"
 	"git.darknebu.la/GalaxySimulator/Source/structs"
-	"math"
 	"os"
 )
 
@@ -24,11 +21,11 @@ func main() {
 	// Load the config
 	var config Config = LoadConfiguration("config.json")
 
-	fmt.Printf("[+] Utilizing %d threads ", config.Threads)
+	fmt.Printf("[ ] Utilizing %d threads ", config.Threads)
 	fmt.Printf("for drawing %d Frames, ", config.Frames)
 	fmt.Printf("each containing %d Stars.\n", config.RangeEnd)
 
-	fmt.Printf("[+] Getting previously existing Stars from %s ", config.LoadPath)
+	fmt.Printf("[ ] Getting previously existing Stars from %s ", config.LoadPath)
 	fmt.Printf("and writing the results to %s.\n", config.OutPath)
 
 	// the slice starsSlice stores the star structures
@@ -67,23 +64,46 @@ func main() {
 			M: 1e10,
 		},
 	}
-	starsSlice = csv.Import(config.LoadPath, config.RangeStart, config.RangeEnd, starsSlice)
 
-	fmt.Println("Done loading the data")
+	// import existing stars from a csv
+	// generate new stars in a homogeneous grid
 
-	// Simulate frames
+	starsSlice = csv.GenerateHomogeneousGrid(starsSlice, -5e5, 5e5, 1e5)
+	fmt.Printf("Amount of Stars: %d\n", len(starsSlice))
+	//starsSlice = csv.Import(config.LoadPath, config.RangeStart, config.RangeEnd, starsSlice)
+
+	fmt.Println("[+] Done loading the data.")
+
+	// Iterate over all the frames
 	for i := 0; i < config.Frames; i++ {
-		fmt.Println("Calculating the frame")
+		fmt.Printf("[ ] Frame %d\n", i)
+
+		// Create a new quadtree
+		boundary := *structs.NewBoundingBox(structs.Vec2{0, 0}, 1e8)
+		starsQuadtree := *structs.NewQuadtree(boundary)
 
-		starsSlice = forces.NextTimestep(starsSlice, 25*math.Pow(10, 4+7))
-		starsSlice = forces.CalcAllAccelerations(starsSlice, config.Threads)
+		// Print all the elements in the stars Slice
+		for _, element := range starsSlice {
+			fmt.Println(element)
+		}
 
-		fmt.Println("Done Calculating")
+		// Insert all the stars from the starsSlice into the Quadtree
+		//starQuadtree := quadtree.InsertSlice(starsSlice)
+
+		//starsSlice = forces.NextTimestep(starsSlice, 25*math.Pow(10, 4+7))
+		//starsSlice = forces.CalcAllAccelerations(starsSlice, config.Threads)
+		//var starsQuadtree quadtree.Quadtree = quadtree.CreateWithSlice(starsSlice)
+		//quadtree.Print(&starsQuadtree)
+		//quadtree.Draw(&starsQuadtree)
+		//quadtree.DrawQuadtree(starsQuadtree)
+
+		fmt.Println("[+] Done Calculating the forces acting.")
 
 		// draw the galaxy
-		outputName := fmt.Sprintf("out_%d.png", i+4)
-		draw.Slice(starsSlice, outputName)
-		fmt.Println("Done drawing all the stars")
+		//fmt.Println("[ ] Drawing the Stars")
+		//outputName := fmt.Sprintf("out_%d.png", i+4)
+		//draw.Slice(starsSlice, outputName)
+		//fmt.Println("[+] Done drawing all the stars")
 	}
 }
 
@@ -106,7 +126,10 @@ func LoadConfiguration(file string) Config {
 
 	// Parsing the content and adding it to the config struct
 	jsonParser := json.NewDecoder(configFile)
-	jsonParser.Decode(&config)
+	err := jsonParser.Decode(&config)
+	if err != nil {
+		panic(err)
+	}
 
 	// Returning the config for further use
 	return config
diff --git a/structs/boundingBox.go b/structs/boundingBox.go
new file mode 100644
index 0000000..ad02eab
--- /dev/null
+++ b/structs/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/structs/quadtree.go b/structs/quadtree.go
new file mode 100644
index 0000000..7f82a2a
--- /dev/null
+++ b/structs/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/structs/star.go b/structs/star.go
index f495d99..d2bb124 100644
--- a/structs/star.go
+++ b/structs/star.go
@@ -1,7 +1,5 @@
 package structs
 
-import "C"
-
 // Define a struct storing essential star information such as it's coordinate, velocity and mass
 type Star2D struct {
 	C Vec2    // coordinates of the star
@@ -9,6 +7,60 @@ type Star2D struct {
 	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}