OrbitSystem -> Barycenter
This commit is contained in:
parent
5ad70b3f9c
commit
70c4cd8a92
|
@ -0,0 +1,18 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://scripts/orbits/Barycenter.cs" type="Script" id=1]
|
||||
[ext_resource path="res://scenes/orbits/Planet.tscn" type="PackedScene" id=2]
|
||||
|
||||
[node name="Barycenter" type="Spatial"]
|
||||
script = ExtResource( 1 )
|
||||
SemiMajorAxis = 7.0
|
||||
Eccentricity = 0.752
|
||||
_pointMassPaths = [ NodePath("Planet A"), NodePath("Planet B") ]
|
||||
_speed = 1.0
|
||||
|
||||
[node name="Planet A" parent="." instance=ExtResource( 2 )]
|
||||
transform = Transform( 0.999977, 0.00603502, 0.00319089, -0.00604282, 0.999979, 0.0024369, -0.00317609, -0.00245615, 0.999992, -2.55711, 0, -4.25519 )
|
||||
|
||||
[node name="Planet B" parent="." instance=ExtResource( 2 )]
|
||||
transform = Transform( 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, -11.9998, 0, 1.25565 )
|
||||
Mass = 0.125
|
|
@ -1,22 +0,0 @@
|
|||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://scripts/orbits/OrbitSystem.cs" type="Script" id=1]
|
||||
[ext_resource path="res://scenes/orbits/Planet.tscn" type="PackedScene" id=2]
|
||||
|
||||
[node name="Orbit System" type="Spatial"]
|
||||
script = ExtResource( 1 )
|
||||
SemiMajorAxis = 6.881
|
||||
Eccentricity = 0.399
|
||||
Period = 10.0
|
||||
_a = NodePath("Planet A")
|
||||
_b = NodePath("Planet B")
|
||||
_barycenter = NodePath("Barycenter")
|
||||
|
||||
[node name="Barycenter" type="Spatial" parent="."]
|
||||
|
||||
[node name="Planet A" parent="." instance=ExtResource( 2 )]
|
||||
transform = Transform( 0.999977, 0.00603502, 0.00319089, -0.00604282, 0.999979, 0.0024369, -0.00317609, -0.00245615, 0.999992, 0, 0, 0 )
|
||||
|
||||
[node name="Planet B" parent="." instance=ExtResource( 2 )]
|
||||
transform = Transform( 0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, -8.44634, 0, -3.53339 )
|
||||
Mass = 0.125
|
|
@ -1,13 +1,13 @@
|
|||
using Godot;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Vim.Math3d;
|
||||
|
||||
[Tool]
|
||||
public class OrbitSystem : Node, IMassive, ILocation
|
||||
public class Barycenter : Node, IPointMass
|
||||
{
|
||||
[Export] private NodePath _a;
|
||||
[Export] private NodePath _b;
|
||||
[Export] private NodePath _barycenter;
|
||||
[Export]
|
||||
private NodePath[] _pointMassPaths;
|
||||
|
||||
private double _semiMajorAxis;
|
||||
[Export]
|
||||
|
@ -40,79 +40,19 @@ public class OrbitSystem : Node, IMassive, ILocation
|
|||
}
|
||||
}
|
||||
|
||||
#region Point Masses
|
||||
private IPointMass Primary
|
||||
public double Mass
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_pointMasses[0] == null)
|
||||
double mass = 0;
|
||||
foreach (var orbiter in Orbiters)
|
||||
{
|
||||
InitPointMasses();
|
||||
mass += orbiter.PointMass.Mass;
|
||||
}
|
||||
return _pointMasses[0];
|
||||
}
|
||||
}
|
||||
private IPointMass Secondary
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_pointMasses[1] == null)
|
||||
{
|
||||
InitPointMasses();
|
||||
}
|
||||
return _pointMasses[1];
|
||||
}
|
||||
}
|
||||
private readonly IPointMass[] _pointMasses = new IPointMass[2];
|
||||
private void InitPointMasses()
|
||||
{
|
||||
var a = GetNode<IPointMass>(_a);
|
||||
var b = GetNode<IPointMass>(_b);
|
||||
|
||||
if (a.Mass > b.Mass)
|
||||
{
|
||||
_pointMasses[0] = a;
|
||||
_pointMasses[1] = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
_pointMasses[0] = b;
|
||||
_pointMasses[1] = a;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public float Mass => Primary.Mass + Secondary.Mass;
|
||||
public DVector3 Position
|
||||
{
|
||||
get => Barycenter;
|
||||
set => Barycenter = value;
|
||||
}
|
||||
|
||||
public DVector3 Barycenter
|
||||
{
|
||||
get
|
||||
{
|
||||
var p0 = Primary.Position;
|
||||
var p1 = Secondary.Position;
|
||||
return p0.Lerp(p1, .5f);
|
||||
}
|
||||
// TODO - make setting the berycenter do something sensible?
|
||||
set => _ = value;
|
||||
}
|
||||
|
||||
private Orbit _orbit = null;
|
||||
private Orbit Orbit
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_orbit == null)
|
||||
{
|
||||
_orbit = new Orbit();
|
||||
}
|
||||
return _orbit;
|
||||
return mass;
|
||||
}
|
||||
}
|
||||
public DVector3 Position { get; set; }
|
||||
|
||||
private ImmediateGeometry _orbitGeometry = null;
|
||||
public ImmediateGeometry OrbitGeometry
|
||||
|
@ -132,6 +72,50 @@ public class OrbitSystem : Node, IMassive, ILocation
|
|||
}
|
||||
}
|
||||
|
||||
private struct Orbiter
|
||||
{
|
||||
public IPointMass PointMass { get; set; }
|
||||
public IOrbit Orbit { get; set; }
|
||||
}
|
||||
private Orbiter[] _orbiters = null;
|
||||
private Orbiter[] Orbiters
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_orbiters == null)
|
||||
{
|
||||
var length = _pointMassPaths.Length;
|
||||
_orbiters = new Orbiter[length];
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
var pointMass = GetNode<IPointMass>(_pointMassPaths[i]);
|
||||
var orbit = new Orbit(this, pointMass);
|
||||
|
||||
var orbiter = new Orbiter
|
||||
{
|
||||
PointMass = pointMass,
|
||||
Orbit = orbit
|
||||
};
|
||||
_orbiters[i] = orbiter;
|
||||
}
|
||||
}
|
||||
return _orbiters;
|
||||
}
|
||||
}
|
||||
|
||||
private IOrbit[] _orbits;
|
||||
private IOrbit[] Orbits
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_orbits == null)
|
||||
{
|
||||
|
||||
}
|
||||
return _orbits;
|
||||
}
|
||||
}
|
||||
|
||||
private float _time = 0;
|
||||
|
||||
[Export]
|
||||
|
@ -145,9 +129,15 @@ public class OrbitSystem : Node, IMassive, ILocation
|
|||
|
||||
private void InvalidateGeometry()
|
||||
{
|
||||
Orbit.Ellipse = new Ellipse(SemiMajorAxis, Eccentricity);
|
||||
Orbit.Draw(OrbitGeometry);
|
||||
for (int i = 0; i < Orbiters.Length; i++)
|
||||
{
|
||||
var orbiter = Orbiters[i];
|
||||
var orbit = orbiter.Orbit;
|
||||
orbit.Ellipse = new Ellipse(SemiMajorAxis, Eccentricity);
|
||||
orbit.Draw(OrbitGeometry);
|
||||
|
||||
Secondary.Position = Orbit.GetPosition(_time);
|
||||
var t = _time + i * Math.PI;
|
||||
orbiter.PointMass.Position = orbit.GetPosition(t);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue