From 088372b31882dd0217d8cc36d7abeac8b6268382 Mon Sep 17 00:00:00 2001 From: emile Date: Mon, 15 Oct 2018 15:32:13 +0200 Subject: refactored the Star type to Star2D --- csv/csv.go | 24 +++++++++------------ draw/draw.go | 19 ++++++++--------- draw/draw3D.go | 58 -------------------------------------------------- forces/forces.go | 62 ++++++++++++++++++++++++------------------------------ main.go | 2 +- structs/structs.go | 6 +++--- 6 files changed, 51 insertions(+), 120 deletions(-) delete mode 100644 draw/draw3D.go diff --git a/csv/csv.go b/csv/csv.go index 5e682a7..7a0fa9f 100644 --- a/csv/csv.go +++ b/csv/csv.go @@ -10,16 +10,16 @@ import ( "time" ) -// openStarCSV opens the file at the given path and reads its content. It then returns the content inform of a slice +// openStar2DCSV opens the file at the given path and reads its content. It then returns the content inform of a slice // of slices -func openStarCSV(path string) [][]string { +func openStar2DCSV(path string) [][]string { // Open the file located at the given path b, err := os.Open(path) // Handle errors if err != nil { - log.Printf("openStarsCSV Panic! (cannot read file from %s)", path) + log.Printf("openStar2DsCSV Panic! (cannot read file from %s)", path) } // Close the file afre reading it's content @@ -30,7 +30,7 @@ func openStarCSV(path string) [][]string { // Handle errors if err != nil { - log.Println("openStarsCSV Panic! (cannot read the files content)") + log.Println("openStar2DsCSV Panic! (cannot read the files content)") } return lines @@ -39,8 +39,8 @@ func openStarCSV(path string) [][]string { // Import gets a file, a starting line, an ending line and a struct. It then adds the content of the file to the struct // For finding the length of the .csv, you can use the following command in linux: // $ cat | wc -l -func Import(path string, start int, end int, slice []structs.Star) []structs.Star { - lines := openStarCSV(path) +func Import(path string, start int, end int, slice []structs.Star2D) []structs.Star2D { + lines := openStar2DCSV(path) // seed the random number generator rand.Seed(time.Now().UTC().UnixNano()) @@ -49,7 +49,6 @@ func Import(path string, start int, end int, slice []structs.Star) []structs.Sta for linenr, line := range lines[start:end] { x, errx := strconv.ParseFloat(line[0], 64) y, erry := strconv.ParseFloat(line[1], 64) - z, errz := strconv.ParseFloat(line[2], 64) // Handle errors if errx != nil { @@ -58,22 +57,19 @@ func Import(path string, start int, end int, slice []structs.Star) []structs.Sta if erry != nil { log.Printf("error reading value from csv in line nr. %d (%s)", linenr, erry) } - if errz != nil { - log.Printf("error reading value from csv in line nr. %d (%s)", linenr, errz) - } // TODO: Export the code below to its own function var mass float64 = float64(10000 + rand.Intn(100000-10000)) // Create a temporary star for assembling the star - tempStar := structs.Star{ - structs.Coord{X: x, Y: y, Z: z}, - structs.Force{X: 0, Y: 0, Z: 0}, + tempStar2D := structs.Star2D{ + structs.Coord{X: x, Y: y}, + structs.Force{X: 0, Y: 0}, mass, } // Add the Temporary star to the slice - slice = append(slice, tempStar) + slice = append(slice, tempStar2D) } diff --git a/draw/draw.go b/draw/draw.go index b66fc7b..1823493 100644 --- a/draw/draw.go +++ b/draw/draw.go @@ -33,8 +33,8 @@ func saveImage(dc *gg.Context, path string) { dc.SavePNG(path) } -// drawStar draws the given stars to the given context -func drawStar(dc *gg.Context, star structs.Star) { +// drawStar2D draws the given stars to the given context +func drawStar2D(dc *gg.Context, star structs.Star2D) { // the radius can be any value inbetween 1e4 and 1e5 // Define the default star radius as 1 and change it according to the stars mass @@ -59,7 +59,7 @@ func vectorLength(force structs.Force) float64 { return math.Sqrt(math.Pow(force.X, 2) + math.Pow(force.Y, 2)) } -func drawForce(dc *gg.Context, star structs.Star) { +func drawForce(dc *gg.Context, star structs.Star2D) { // controll the length of the vector var scalingFactor float64 = 15 @@ -81,8 +81,7 @@ func drawForce(dc *gg.Context, star structs.Star) { FyUnit := star.F.Y / math.Abs(vecLength) dc.LineTo(star.C.X/50+(FxUnit*scalingFactor), star.C.Y/50+(FyUnit*scalingFactor)) - // dc.LineTo(star.C.X/100 + (star.F.X * scalingFactor), star.C.Y/100 + (star.F.Y * scalingFactor)) - // + // css dc.SetLineWidth(3) @@ -90,8 +89,8 @@ func drawForce(dc *gg.Context, star structs.Star) { dc.Stroke() } -// drawStars draws all the stars in the given slice to the given context -func drawStars(dc *gg.Context, slice []structs.Star) { +// drawStar2Ds draws all the stars in the given slice to the given context +func drawStars2D(dc *gg.Context, slice []structs.Star2D) { // draw all the forces in the given slice for _, star := range slice { drawForce(dc, star) @@ -101,18 +100,18 @@ func drawStars(dc *gg.Context, slice []structs.Star) { // draw all the stars in the given slice for _, star := range slice { - drawStar(dc, star) + drawStar2D(dc, star) } } // Slice draws the stars and the forces acting on them and saves the result to the given path -func Slice(slice []structs.Star, path string) { +func Slice(slice []structs.Star2D, path string) { // initialize the plot dc := initializePlot() // draw all the stars in the given slice - drawStars(dc, slice) + drawStars2D(dc, slice) // save the plot to the given path saveImage(dc, path) diff --git a/draw/draw3D.go b/draw/draw3D.go deleted file mode 100644 index 62d0f05..0000000 --- a/draw/draw3D.go +++ /dev/null @@ -1,58 +0,0 @@ -package draw - -import ( - "../llog" - "../structs" - "github.com/fogleman/ln/ln" -) - -func drawStar3D(scene ln.Scene, star structs.Star) ln.Scene { - starSize := 0.1 - oneCorner := ln.Vector{star.C.X - starSize, star.C.Y - starSize, star.C.Z - starSize} - otherCorner := ln.Vector{star.C.X + starSize, star.C.Y + starSize, star.C.Z + starSize} - - scene.Add(ln.NewCube(oneCorner, otherCorner)) - - return scene -} - -func drawStars3D(scene ln.Scene, slice []structs.Star) ln.Scene { - for _, star := range slice { - scene = drawStar3D(scene, star) - } - - return scene -} - -func Slice3D(slice []structs.Star, path string) { - // create a scene and add a single cube - scene := ln.Scene{} - - llog.Good("Drawing the Stars") - scene = drawStars3D(scene, slice) - llog.Good("Done Drawing the Stars") - - // scene.Add(ln.NewCube(ln.Vector{-1, -1, -1}, ln.Vector{1, 1, 1})) - - // define camera parameters - eye := ln.Vector{4, 3, 2} // camera position - center := ln.Vector{0, 0, 0} // camera looks at - up := ln.Vector{0, 0, 1} // up direction - - // define rendering parameters - width := 1024.0 // rendered width - height := 1024.0 // rendered height - fovy := 50.0 // vertical field of view, degrees - znear := 0.1 // near z plane - zfar := 10.0 // far z plane - step := 0.01 // how finely to chop the paths for visibility testing - - llog.Good("Configuring path") - // compute 2D paths that depict the 3D scene - paths := scene.Render(eye, center, up, width, height, fovy, znear, zfar, step) - llog.Good("Done") - - // render the paths in an image - llog.Good("Writing to png") - paths.WriteToPNG(path, width, height) -} diff --git a/forces/forces.go b/forces/forces.go index e3f822d..7763f87 100644 --- a/forces/forces.go +++ b/forces/forces.go @@ -10,15 +10,15 @@ import ( // forces_acting calculates the force inbetween the two given stars s1 and s2 // The function return the force -func forceActing(s1 structs.Star, s2 structs.Star) structs.Force { +func forceActing(s1 structs.Star2D, s2 structs.Star2D) structs.Force { // Gravitational constant var G float64 = 6.674e-11 // Distance between the stars - var r21 = math.Sqrt(math.Pow(s2.C.X-s1.C.X, 2) + math.Pow(s2.C.Y-s1.C.Y, 2) + math.Pow(s2.C.Z-s1.C.Z, 2)) + var r21 = math.Sqrt(math.Pow(s2.C.X-s1.C.X, 2) + math.Pow(s2.C.Y-s1.C.Y, 2)) // Unit vector pointing from s1 to s2 - rhat := structs.Force{s2.C.X - s1.C.X, s2.C.Y - s1.C.Y, s2.C.Z - s1.C.Z} + rhat := structs.Force{s2.C.X - s1.C.X, s2.C.Y - s1.C.Y} // Calculate how strong the star is affected var FScalar = G * (s1.Mass * s2.Mass) / math.Pow(math.Abs(r21), 2) @@ -26,16 +26,15 @@ func forceActing(s1 structs.Star, s2 structs.Star) structs.Force { // Calculate the overall force by combining the scalar and the vector var Fx = FScalar * rhat.X var Fy = FScalar * rhat.Y - var Fz = FScalar * rhat.Z // Pack the forces in a force structur - F := structs.Force{Fx, Fy, Fz} + F := structs.Force{Fx, Fy} return F } // forces calculates the forces acting in between a given star and all the other stars in a given array. -func forces(stars_arr []structs.Star, nr int) structs.Force { +func forces(stars_arr []structs.Star2D, nr int) structs.Force { var force structs.Force // Iterate over all the stars in the stars_arr @@ -48,11 +47,9 @@ func forces(stars_arr []structs.Star, nr int) structs.Force { fa := forceActing(stars_arr[nr], stars_arr[index]) stars_arr[nr].F.X += fa.X stars_arr[nr].F.Y += fa.Y - stars_arr[nr].F.Z += fa.Z force.X += fa.X force.Y += fa.Y - force.Z += fa.Z } } @@ -61,31 +58,31 @@ func forces(stars_arr []structs.Star, nr int) structs.Force { // forcesThread calculates the forces acting on a given amount of stars in a given range for a given slice of stars // as a go-routine -func forcesThread(starSlice []structs.Star, localRangeStart int, localRangeEnd int, channel chan structs.Star) { +func forcesThread(starSlice []structs.Star2D, localRangeStar2Dt int, localRangeEnd int, channel chan structs.Star2D) { // iterate over the given range - for index := localRangeStart; index < localRangeEnd; index++ { + for index := localRangeStar2Dt; index < localRangeEnd; index++ { // Calculate the force acting inbetween the given star and all other stars var force = forces(starSlice, index) // create a new star - newStar := structs.Star{ - structs.Coord{starSlice[index].C.X, starSlice[index].C.Y, starSlice[index].C.Z}, - structs.Force{force.X, force.Y, force.Z}, + newStar2D := structs.Star2D{ + structs.Coord{starSlice[index].C.X, starSlice[index].C.Y}, + structs.Force{force.X, force.Y}, starSlice[index].Mass, } - // push the new Star into the channel - channel <- newStar + // push the new Star2D into the channel + channel <- newStar2D } } // CalcAllForces calculates all the forces acting inbetween all the stars in the given starSlice slice and // returns a "new" slice contaning the forces -func CalcAllForces(starSlice []structs.Star, threads int) []structs.Star { +func CalcAllForces(starSlice []structs.Star2D, threads int) []structs.Star2D { // create a channel for bundling the stars generaten in the go-routines - channel := make(chan structs.Star, 1000) + channel := make(chan structs.Star2D, 1000) sliceLength := len(starSlice) @@ -94,7 +91,7 @@ func CalcAllForces(starSlice []structs.Star, threads int) []structs.Star { localRangeLen := sliceLength / threads // generate a new slice for storing the stars - var newSlice []structs.Star + var newSlice []structs.Star2D llog.Good(fmt.Sprintf("Starting %d workers, each processing %d stars", threads, localRangeLen)) @@ -102,39 +99,37 @@ func CalcAllForces(starSlice []structs.Star, threads int) []structs.Star { for i := 0; i < threads; i++ { // define the local range - localRangeStart := i * localRangeLen + localRangeStar2Dt := i * localRangeLen localRangeEnd := (i * localRangeLen) + localRangeLen // calculate the forces for all the stars in the given slice in the given range and return them using the // given channel - go forcesThread(starSlice, localRangeStart, localRangeEnd, channel) + go forcesThread(starSlice, localRangeStar2Dt, localRangeEnd, channel) } // Handle errors (10004 stars, but 1250 stars per thread, so 4 stars are not calculate and block the queue) if sliceLength > localRangeLen { // Calculate the amount of stars and their range - remainingStars := sliceLength - (localRangeLen * threads) + remainingStar2Ds := sliceLength - (localRangeLen * threads) localRangeEnd := ((threads - 1) * localRangeLen) + localRangeLen // Run the Thread - // go forcesThread(starSlice, localRangeEnd, localRangeEnd+remainingStars, channel) - forcesThread(starSlice, localRangeEnd, localRangeEnd+remainingStars, channel) + // go forcesThread(starSlice, localRangeEnd, localRangeEnd+remainingStar2Ds, channel) + forcesThread(starSlice, localRangeEnd, localRangeEnd+remainingStar2Ds, channel) } // Initialize a new progress bar - bar := pb.New(len(starSlice)).Prefix("Stars: ") - - bar.Start() + bar := pb.New(len(starSlice)).Prefix("Star2Ds: ") // iterate over the amount of stars for i := 0; i < sliceLength; i++ { // block until a star is finisehd - var newStar structs.Star = <-channel + var newStar2D structs.Star2D = <-channel // append the star from the channel to the newSlice for returning in the end - newSlice = append(newSlice, newStar) + newSlice = append(newSlice, newStar2D) // increment the progress bar and the counter bar.Increment() @@ -146,9 +141,9 @@ func CalcAllForces(starSlice []structs.Star, threads int) []structs.Star { } // Calculate the new positions of the stars using the -func NextTimestep(starSlice []structs.Star, deltat int) []structs.Star { +func NextTimestep(starSlice []structs.Star2D, deltat int) []structs.Star2D { // create a new slice for storing the "new" stars - var newSlice []structs.Star + var newSlice []structs.Star2D // iterate over all the stars in the old slice for index := range starSlice { @@ -156,17 +151,16 @@ func NextTimestep(starSlice []structs.Star, deltat int) []structs.Star { // calculate the new position newX := starSlice[index].C.X + starSlice[index].F.X*float64(deltat) newY := starSlice[index].C.Y + starSlice[index].F.Y*float64(deltat) - newZ := starSlice[index].C.Z + starSlice[index].F.Z*float64(deltat) // assemble the new star - newStar := structs.Star{ - C: structs.Coord{X: newX, Y: newY, Z: newZ}, + newStar2D := structs.Star2D{ + C: structs.Coord{X: newX, Y: newY}, F: structs.Force{}, Mass: starSlice[index].Mass, } // append the new star to the newSlice - newSlice = append(newSlice, newStar) + newSlice = append(newSlice, newStar2D) } return newSlice diff --git a/main.go b/main.go index 48ed075..0ad2e69 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,7 @@ func main() { var stars int = 800 // the slice starsSlice stores the star structures - starsSlice := []structs.Star{} + starsSlice := []structs.Star2D{} logplus.LogPositive("Opening the csv") starsSlice = csv.Import("data/U_ALL.csv", 0, stars, starsSlice) diff --git a/structs/structs.go b/structs/structs.go index 5b1c6ea..ed70a84 100644 --- a/structs/structs.go +++ b/structs/structs.go @@ -7,16 +7,16 @@ package structs // Force struct soring a force vector type Force struct { - X, Y, Z float64 + X, Y float64 } // Coord struct storing coordinates type Coord struct { - X, Y, Z float64 + X, Y float64 } // Star struct storing all necessary star information -type Star struct { +type Star2D struct { C Coord F Force Mass float64 -- cgit 1.4.1