about summary refs log tree commit diff
path: root/quadtree.go
diff options
context:
space:
mode:
authorhanemile <hanemile@protonmail.com>2018-12-01 00:52:33 +0100
committerhanemile <hanemile@protonmail.com>2018-12-01 00:52:33 +0100
commita65c7dd191b9fdcbbcc7741111c50b4d09ac3c3d (patch)
tree6c45d2fd23d1392c13f346cf144d844d8fde7cf4 /quadtree.go
parente26f2bde45d6dbc0f2110605b2d117e36c2a20fd (diff)
last commit, manually merging into the GalaxySimulator
Diffstat (limited to 'quadtree.go')
-rw-r--r--quadtree.go146
1 files changed, 119 insertions, 27 deletions
diff --git a/quadtree.go b/quadtree.go
index c799df7..24aedb6 100644
--- a/quadtree.go
+++ b/quadtree.go
@@ -1,6 +1,12 @@
 package quadtree
 
-import "fmt"
+import (
+	"fmt"
+	"git.darknebu.la/GalaxySimulator/Source/structs"
+
+	//"git.darknebu.la/GalaxySimulator/Source/structs"
+	"github.com/fogleman/gg"
+)
 
 type Coord struct {
 	X float64
@@ -132,46 +138,132 @@ func (quadtree *Quadtree) Insert(point Coord) {
 	// subdivide the Quadtree into four new cells
 	quadtree.subdivide()
 
-	// if the maxDepth is not reached...
-	if quadtree.depth < 4 {
-		// ... test if the given point is inside the one of the cells
-		// and add Insert it to that specific cell
-
-		if point.InsideOf(quadtree.northWest) {
-			quadtree.northWest.Insert(point)
-		}
-		if point.InsideOf(quadtree.northEast) {
-			quadtree.northEast.Insert(point)
-		}
-		if point.InsideOf(quadtree.southWest) {
-			quadtree.southWest.Insert(point)
-		}
-		if point.InsideOf(quadtree.southEast) {
-			quadtree.southEast.Insert(point)
-		}
+	if point.InsideOf(quadtree.northWest) {
+		quadtree.northWest.Insert(point)
+	}
+	if point.InsideOf(quadtree.northEast) {
+		quadtree.northEast.Insert(point)
+	}
+	if point.InsideOf(quadtree.southWest) {
+		quadtree.southWest.Insert(point)
+	}
+	if point.InsideOf(quadtree.southEast) {
+		quadtree.southEast.Insert(point)
 	}
 
 	// if the maximal depth of the tree has been reached:
 	// Insert the point into the slice
 	quadtree.pointsSlice = append(quadtree.pointsSlice, NewCoord(point.X, point.Y))
+	fmt.Printf("Inserted (%f, %f) in layer %d\n", point.X, point.Y, quadtree.depth)
 }
 
-// Print() is a method that can be used on a quadtree.
-// It prints all the root nodes of the quadtree recursively
-// The tree is printed from the bottom up in the following order: NW, NE, SW, SE
-func (quadtree *Quadtree) Print() {
+func Print(quadtree *Quadtree) {
 	// Define an end condition: if the quadtree-leaf is nil, the root does not continue
 	if quadtree.northWest != nil {
-		quadtree.northWest.Print()
+		Print(quadtree.northWest)
 	}
 	if quadtree.northEast != nil {
-		quadtree.northEast.Print()
+		Print(quadtree.northEast)
 	}
 	if quadtree.southWest != nil {
-		quadtree.southWest.Print()
+		Print(quadtree.southWest)
 	}
 	if quadtree.southEast != nil {
-		quadtree.southEast.Print()
+		Print(quadtree.southEast)
 	}
-	fmt.Println(quadtree)
+	fmt.Printf("%d\t", quadtree.depth)
+	fmt.Printf("%v\t", quadtree.boundary)
+	fmt.Printf("%d\n", len(quadtree.pointsSlice))
+}
+
+func CreateWithSlice(slice []structs.Star2D) Quadtree {
+	// Create a new bounding box at the center of the Galaxy containing the whole galaxy
+	var newCenter structs.Vec2 = structs.Vec2{0, 0}
+	var newHalfDimension float64 = 5e5
+
+	// Create a Quadtree containing the whole galaxy
+	var boundary BoundingBox = NewBoundingBox(Coord(newCenter), newHalfDimension)
+	var depth int = 0
+	var newQuadtree *Quadtree = NewQuadtree(boundary, depth)
+
+	fmt.Printf("Inserting %d Elements into the Quadtree\n", len(slice))
+
+	// Insert all the stars from the slice into the quadtree step for step
+	for i := 0; i < len(slice); i++ {
+		newQuadtree.Insert(Coord(slice[i].C))
+	}
+
+	return *newQuadtree
+}
+
+func InitializeCanvas() *gg.Context {
+	const imageWidth = 8192
+	const imageHeight = 8192
+
+	// Initialize the new Context
+	dc := gg.NewContext(imageWidth, imageHeight)
+
+	// Set the Background to black
+	dc.SetRGB(0, 0, 0)
+	dc.Clear()
+
+	// Invert the Y axis
+	dc.InvertY()
+
+	// Translate the Coordinate System to the middle of the image
+	dc.TransformPoint(imageWidth/4, imageHeight/4)
+
+	return dc
 }
+
+// recursively iterate over a quadtree and draw all the nodes
+func drawQuadTree(dc *gg.Context, quadtree Quadtree) {
+
+	// find filled quadtrees
+	if quadtree.northWest != nil {
+		drawQuadTree(dc, *quadtree.northWest)
+	}
+	if quadtree.northEast != nil {
+		drawQuadTree(dc, *quadtree.northEast)
+	}
+	if quadtree.southWest != nil {
+		drawQuadTree(dc, *quadtree.southWest)
+	}
+	if quadtree.southEast != nil {
+		drawQuadTree(dc, *quadtree.southEast)
+	}
+
+	// don't draw the root node
+	if quadtree.depth != 0 {
+
+		// calculate the position of the new rectangle
+		origx := quadtree.boundary.center.X
+		origy := quadtree.boundary.center.X
+		x := (origx - quadtree.boundary.halfDimension) / 1000
+		y := (origy - quadtree.boundary.halfDimension) / 1000
+		w := quadtree.boundary.halfDimension
+		h := quadtree.boundary.halfDimension
+		//fmt.Printf("(%f, %f), (%f, %f, %f, %f)\n", origx, origy, x, y, w, h)
+
+		// draw the rectangle
+		dc.DrawRectangle(x, y, w, h)
+		dc.Stroke()
+	}
+}
+
+// save the given gg.Context to the given path
+func saveImage(dc *gg.Context, path string) {
+	err := dc.SavePNG(path)
+	if err != nil {
+		panic(err)
+	}
+}
+
+func DrawQuadtree(quadtree Quadtree) {
+	dc := InitializeCanvas()
+
+	dc.SetRGB(1, 1, 1)
+	drawQuadTree(dc, quadtree)
+	saveImage(dc, "quadtree.png")
+}
+