mirror of
https://github.com/gonum/gonum.git
synced 2025-10-05 23:26:52 +08:00
84 lines
1.8 KiB
Go
84 lines
1.8 KiB
Go
// Copyright ©2019 The Gonum Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package barneshut_test
|
|
|
|
import (
|
|
"log"
|
|
|
|
"golang.org/x/exp/rand"
|
|
|
|
"gonum.org/v1/gonum/spatial/barneshut"
|
|
"gonum.org/v1/gonum/spatial/r2"
|
|
)
|
|
|
|
type mass struct {
|
|
d r2.Vec
|
|
v r2.Vec
|
|
m float64
|
|
}
|
|
|
|
func (m *mass) Coord2() r2.Vec { return m.d }
|
|
func (m *mass) Mass() float64 { return m.m }
|
|
func (m *mass) move(f r2.Vec) {
|
|
m.v = m.v.Add(f.Scale(1 / m.m))
|
|
m.d = m.d.Add(m.v)
|
|
}
|
|
|
|
func Example_galaxy() {
|
|
rnd := rand.New(rand.NewSource(1))
|
|
|
|
// Make 1000 stars in random locations.
|
|
stars := make([]*mass, 1000)
|
|
p := make([]barneshut.Particle2, len(stars))
|
|
for i := range stars {
|
|
s := &mass{
|
|
d: r2.Vec{
|
|
X: 100 * rnd.Float64(),
|
|
Y: 100 * rnd.Float64(),
|
|
},
|
|
v: r2.Vec{
|
|
X: rnd.NormFloat64(),
|
|
Y: rnd.NormFloat64(),
|
|
},
|
|
m: 10 * rnd.Float64(),
|
|
}
|
|
stars[i] = s
|
|
p[i] = s
|
|
}
|
|
vectors := make([]r2.Vec, len(stars))
|
|
|
|
// Make a plane to calculate approximate forces
|
|
plane := barneshut.Plane{Particles: p}
|
|
|
|
// Run a simulation for 100 updates.
|
|
for i := 0; i < 1000; i++ {
|
|
// Build the data structure. For small systems
|
|
// this step may be omitted and ForceOn will
|
|
// perform the naive quadratic calculation
|
|
// without building the data structure.
|
|
err := plane.Reset()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// Calculate the force vectors using the theta
|
|
// parameter...
|
|
const theta = 0.5
|
|
// and an imaginary gravitational constant.
|
|
const G = 10
|
|
for j, s := range stars {
|
|
vectors[j] = plane.ForceOn(s, theta, barneshut.Gravity2).Scale(G)
|
|
}
|
|
|
|
// Update positions.
|
|
for j, s := range stars {
|
|
s.move(vectors[j])
|
|
}
|
|
|
|
// Rendering stars is left as an exercise for
|
|
// the reader.
|
|
}
|
|
}
|