Research: orbit probe (rails vs gravity terrain, slope-squared and potential readings, implied density)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
ab42214329
commit
1746e8bdc8
23 changed files with 1106 additions and 0 deletions
165
docs/research/2026-10-13-orbit-probe/OrbitProbeScratch.cs.txt
Normal file
165
docs/research/2026-10-13-orbit-probe/OrbitProbeScratch.cs.txt
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using CultMath;
|
||||
using GameCult.Caching;
|
||||
using Xunit;
|
||||
using static CultMath.math;
|
||||
using float2 = CultMath.float2;
|
||||
using Random = CultMath.Random;
|
||||
|
||||
// SCRATCH orbit probe (Imagination, agent imagination-aeth-orbit-probe). Never merged.
|
||||
public sealed class OrbitProbeScratch : IDisposable
|
||||
{
|
||||
private readonly string _root = Path.Combine(Path.GetTempPath(), "orbitprobe-" + Guid.NewGuid().ToString("N"));
|
||||
private readonly string _out = "/tmp/probe";
|
||||
private readonly List<CultCache> _caches = new List<CultCache>();
|
||||
|
||||
public OrbitProbeScratch() { Directory.CreateDirectory(_root); Directory.CreateDirectory(_out); }
|
||||
public void Dispose() { foreach (var c in _caches) c.Dispose(); Directory.Delete(_root, true); }
|
||||
|
||||
private static string F(float v) => v.ToString("R", CultureInfo.InvariantCulture);
|
||||
|
||||
// Settings/Assets/Resources/Settings.asset PlanetSettings block, transcribed.
|
||||
private static PlanetSettings Real(bool waves = true, bool bowl = true) => new PlanetSettings
|
||||
{
|
||||
ZoneDepthExponent = 2, ZoneDepth = bowl ? 64 : 0, ZoneBoundaryFog = 0,
|
||||
GravityDepth = new ExponentialCurve { Exponent = .175f, Multiplier = 30, Constant = 0 },
|
||||
GravityRadius = new ExponentialCurve { Exponent = .25f, Multiplier = 500, Constant = 0 },
|
||||
WaveDepth = new ExponentialCurve { Exponent = .3f, Multiplier = waves ? .5f : 0f, Constant = 0 },
|
||||
WaveRadius = new ExponentialCurve { Exponent = .25f, Multiplier = 500, Constant = 0 },
|
||||
WaveFrequency = new ExponentialCurve { Exponent = .45f, Multiplier = .2f, Constant = 0 },
|
||||
WaveSpeed = new ExponentialCurve { Exponent = 0, Multiplier = 0, Constant = .025f },
|
||||
LightRadius = new ExponentialCurve { Exponent = .25f, Multiplier = 300, Constant = 0 },
|
||||
BodyRadius = new ExponentialCurve { Exponent = .25f, Multiplier = 3, Constant = 0 },
|
||||
GravityStrength = 2,
|
||||
OrbitPeriod = new ExponentialCurve { Exponent = 1, Multiplier = 1, Constant = 0 },
|
||||
};
|
||||
|
||||
private Zone NewZone(PlanetSettings ps, float packRadius, BodyData body, out CultCache cache)
|
||||
{
|
||||
cache = AetheriaStores.Open(Path.Combine(_root, Guid.NewGuid().ToString("N") + ".cc"), runPath: Path.Combine(_root, Guid.NewGuid().ToString("N") + ".run.cc"), catalogWritable: true);
|
||||
_caches.Add(cache);
|
||||
var gs = new GameplaySettings
|
||||
{
|
||||
DefaultEntitySettings = new EntitySettings(),
|
||||
Tiers = new[] { new RarityTier { Name = "Common", Quality = .5f, Rarity = 0, Color = new float3(1, 1, 1) } },
|
||||
QualityPriceModifier = new ExponentialLerp()
|
||||
};
|
||||
var items = new ItemManager(cache, new ProvenanceLedger(), gs, _ => { });
|
||||
var pack = new ZonePack { Radius = packRadius };
|
||||
if (body != null)
|
||||
{
|
||||
var orbit = new OrbitData { Distance = 0 };
|
||||
cache.Upsert(orbit);
|
||||
body.Orbit = cache.RefOf(orbit);
|
||||
cache.Upsert(body);
|
||||
pack.Orbits.Add(cache.RefOf(orbit));
|
||||
pack.Planets.Add(cache.RefOf(body));
|
||||
}
|
||||
return new Zone(items, ps, pack, new GalaxyZone { Name = "Probe", Owner = null }, null);
|
||||
}
|
||||
|
||||
private static BodyData MakeBody(string type, float mass)
|
||||
{
|
||||
BodyData b = type == "Sun" ? new SunData() : type == "GasGiant" ? new GasGiantData() : (BodyData) new PlanetData();
|
||||
b.Mass = mass;
|
||||
return b;
|
||||
}
|
||||
|
||||
private void Profile(StringBuilder sb, string name, Zone zone, float rMax, int n)
|
||||
{
|
||||
sb.AppendLine("@@CASE " + name);
|
||||
for (var i = 0; i <= n; i++)
|
||||
{
|
||||
var r = rMax * i / n;
|
||||
var p = new float2(r, 0);
|
||||
var h = zone.GetHeight(p);
|
||||
var f = zone.GetForce(p);
|
||||
sb.AppendLine(F(r) + "," + F(h) + "," + F(f.x) + "," + F(f.y));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Probe()
|
||||
{
|
||||
var zs = RestoredHullsTests.TutorialZoneSettings();
|
||||
|
||||
// 1. Where bodies sit: the real generator's trees over the density range.
|
||||
var bodies = new StringBuilder();
|
||||
bodies.AppendLine("density,seed,idx,type,mass,distance,parentIdx,parentType,parentMass,belt,empty,zoneRadius");
|
||||
var massesByType = new Dictionary<string, List<float>>();
|
||||
foreach (var density in new[] { 0f, .25f, .5f, .75f, 1f })
|
||||
{
|
||||
var radius = zs.ZoneRadius.Evaluate(density);
|
||||
var mass = zs.ZoneMass.Evaluate(density);
|
||||
for (uint seed = 1; seed <= 300; seed++)
|
||||
{
|
||||
var random = new Random(seed * 2654435761u ^ (uint) (density * 1000));
|
||||
var planets = ZoneGenerator.GenerateEntities(zs, ref random, mass, radius, float2.zero);
|
||||
string TypeOf(GeneratorPlanet p) => p.Belt ? "Belt" : p.Mass > zs.SunMass ? "Sun" : p.Mass > zs.GasGiantMass ? "GasGiant" : p.Mass > zs.PlanetMass ? "Planet" : "Planetoid";
|
||||
for (var i = 0; i < planets.Length; i++)
|
||||
{
|
||||
var p = planets[i];
|
||||
var pi = p.Parent == null ? -1 : Array.IndexOf(planets, p.Parent);
|
||||
var t = TypeOf(p);
|
||||
bodies.AppendLine(string.Join(",", F(density), seed, i, t, F(p.Mass), F(p.Distance), pi,
|
||||
pi < 0 ? "-" : TypeOf(planets[pi]), pi < 0 ? "0" : F(planets[pi].Mass), p.Belt ? 1 : 0, p.Empty ? 1 : 0, F(radius)));
|
||||
if (!p.Empty && !p.Belt)
|
||||
{
|
||||
if (!massesByType.TryGetValue(t, out var l)) massesByType[t] = l = new List<float>();
|
||||
l.Add(p.Mass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File.WriteAllText(Path.Combine(_out, "bodies.csv"), bodies.ToString());
|
||||
|
||||
// 2. Field profiles through the real Zone: representative masses at p10/p50/p90 of each type.
|
||||
var prof = new StringBuilder();
|
||||
float Q(List<float> l, float q) { l.Sort(); return l[(int) ((l.Count - 1) * q)]; }
|
||||
var meta = new StringBuilder();
|
||||
foreach (var type in new[] { "Planetoid", "Planet", "GasGiant", "Sun" })
|
||||
{
|
||||
if (!massesByType.TryGetValue(type, out var l) || l.Count == 0) continue;
|
||||
foreach (var (tag, q) in new[] { ("p10", .1f), ("p50", .5f), ("p90", .9f) })
|
||||
{
|
||||
var m = Q(l, q);
|
||||
foreach (var waves in type == "GasGiant" || type == "Sun" ? new[] { true, false } : new[] { false })
|
||||
{
|
||||
var body = MakeBody(type, m);
|
||||
var zone = NewZone(Real(waves, bowl: false), 100000f, body, out _);
|
||||
var inst = zone.PlanetInstances.Values.First();
|
||||
var support = inst.GravityWellRadius / 2f;
|
||||
meta.AppendLine(string.Join(",", type, tag, F(m), F(inst.GravityWellRadius), F(inst.GravityWellDepth), F(inst.BodyRadius), waves ? 1 : 0, l.Count));
|
||||
Profile(prof, $"{type}_{tag}_waves{(waves ? 1 : 0)}", zone, support * 1.15f, 460);
|
||||
}
|
||||
}
|
||||
}
|
||||
File.WriteAllText(Path.Combine(_out, "meta.csv"), "type,tag,mass,wellRadius,wellDepth,bodyRadius,waves,n\n" + meta);
|
||||
|
||||
// 3. The zone bowl alone, at the real pack radii.
|
||||
foreach (var R in new[] { 1000f, 2500f, 5000f, 10000f })
|
||||
{
|
||||
var zone = NewZone(Real(false, true), R, null, out _);
|
||||
Profile(prof, $"Bowl_R{(int) R}", zone, R * 1.05f, 460);
|
||||
}
|
||||
File.WriteAllText(Path.Combine(_out, "profiles.csv"), prof.ToString());
|
||||
|
||||
// 4. Ship scale: thrusters, hull masses, speed limits straight from the shipped catalog.
|
||||
var ships = new StringBuilder();
|
||||
var cat = AetheriaStores.Open(TestCatalog.Repo, catalogWritable: false);
|
||||
_caches.Add(cat);
|
||||
foreach (var item in cat.GetAll<EquippableItemData>())
|
||||
{
|
||||
if (item is HullData hull)
|
||||
ships.AppendLine($"hull,{hull.Name},{hull.HullType},{F(hull.Mass)},{string.Join(";", hull.Behaviors.OfType<VelocityLimitData>().Select(v => F(v.TopSpeed.Min) + ":" + F(v.TopSpeed.Max)))},");
|
||||
foreach (var th in item.Behaviors.OfType<ThrusterData>())
|
||||
ships.AppendLine($"thruster,{item.Name},,,{F(th.Thrust.Min)}:{F(th.Thrust.Max)},");
|
||||
}
|
||||
File.WriteAllText(Path.Combine(_out, "ships.csv"), ships.ToString());
|
||||
}
|
||||
}
|
||||
348
docs/research/2026-10-13-orbit-probe/analyze.py
Normal file
348
docs/research/2026-10-13-orbit-probe/analyze.py
Normal file
|
|
@ -0,0 +1,348 @@
|
|||
import csv, json, collections, os, math, sys
|
||||
import numpy as np
|
||||
import matplotlib
|
||||
matplotlib.use('Agg')
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
D = os.path.join(HERE, 'data')
|
||||
S_STR, REF = 2.0, 60.0 # Settings.asset GravityStrength, Zone.GravityReferenceRate
|
||||
SR = S_STR * REF
|
||||
GATE = 0.001 # |n_xz|^2 gate in Zone.GravityAcceleration
|
||||
TP = 2 * math.pi
|
||||
A_SHIP = 30.0 # u/s^2: Longinus (mass 2500) + Small Drive (60k..90k thrust) = 24..36
|
||||
OUT = os.path.join(HERE, 'out'); os.makedirs(OUT, exist_ok=True)
|
||||
md = [] # report fragments
|
||||
def P(s=''): md.append(s)
|
||||
|
||||
# ---------- load ----------
|
||||
def load_profiles():
|
||||
cases, cur = {}, None
|
||||
for line in open(os.path.join(D, 'profiles.csv')):
|
||||
line = line.strip()
|
||||
if line.startswith('@@CASE'):
|
||||
cur = line.split()[1]; cases[cur] = []
|
||||
elif line and cur:
|
||||
p = line.split(',')
|
||||
if len(p) == 4: cases[cur].append([float(x) for x in p])
|
||||
return {k: np.array(v) for k, v in cases.items()}
|
||||
cases = load_profiles()
|
||||
meta = {}
|
||||
for r in csv.DictReader(open(os.path.join(D, 'meta.csv'))):
|
||||
meta[(r['type'], r['tag'], int(r['waves']))] = dict(mass=float(r['mass']), Rg=float(r['wellRadius']), D=float(r['wellDepth']), body=float(r['bodyRadius']), n=int(r['n']))
|
||||
EXP = 16.0
|
||||
|
||||
def well_h(r, Dd, Rg, e=EXP):
|
||||
x = 2 * r / Rg
|
||||
return -Dd * np.clip(1 - x * x, 0, None) ** e
|
||||
def well_dh(r, Dd, Rg, e=EXP):
|
||||
x = 2 * r / Rg; u = np.clip(1 - x * x, 0, None)
|
||||
return np.where(x < 1, 4 * Dd * e * x * u ** (e - 1) / Rg, 0.0)
|
||||
def well_lap(r, Dd, Rg, e=EXP):
|
||||
x = 2 * r / Rg; u = np.clip(1 - x * x, 1e-300, None)
|
||||
h2 = 8 * Dd * e / Rg ** 2 * u ** (e - 2) * (u - 2 * (e - 1) * x * x)
|
||||
return np.where(x < 1, h2 + well_dh(r, Dd, Rg, e) / np.maximum(r, 1e-9), 0.0)
|
||||
def well_h2(r, Dd, Rg, e=EXP):
|
||||
x = 2 * r / Rg; u = np.clip(1 - x * x, 1e-300, None)
|
||||
return np.where(x < 1, 8 * Dd * e / Rg ** 2 * u ** (e - 2) * (u - 2 * (e - 1) * x * x), 0.0)
|
||||
BOWL_E = 2.0; BOWL_D = 64.0
|
||||
def bowl_h(r, Rz): # PowerPulse(r/(2Rz),2)*64 -> x=r/Rz
|
||||
u = np.clip(1 - (r / Rz) ** 2, 0, None); return -BOWL_D * u ** BOWL_E
|
||||
def bowl_dh(r, Rz):
|
||||
x = r / Rz; u = np.clip(1 - x * x, 0, None)
|
||||
return np.where(x < 1, 4 * BOWL_D * BOWL_E * x * u ** (BOWL_E - 1) / (2 * Rz), 0.0) if False else np.where(x < 1, BOWL_D * BOWL_E * u ** (BOWL_E - 1) * 2 * x / Rz, 0.0)
|
||||
def bowl_lap(r, Rz):
|
||||
x = r / Rz; u = np.clip(1 - x * x, 1e-300, None)
|
||||
h2 = BOWL_D * BOWL_E / Rz ** 2 * (2 * u ** (BOWL_E - 1) + 2 * x * (BOWL_E - 1) * u ** (BOWL_E - 2) * (-2 * x))
|
||||
return np.where(x < 1, h2 + bowl_dh(r, Rz) / np.maximum(r, 1e-9), 0.0)
|
||||
|
||||
def accA(s):
|
||||
m = s * s / (1 + s * s)
|
||||
return np.where(m > GATE, SR * s * s, 0.0)
|
||||
def period(r, a):
|
||||
with np.errstate(divide='ignore', invalid='ignore'):
|
||||
return np.where(a > 0, TP * np.sqrt(r / a), np.inf)
|
||||
def stable(r, a): # d(r^3 a)/dr > 0
|
||||
L = r ** 3 * a
|
||||
d = np.gradient(L, r)
|
||||
return d > 0
|
||||
|
||||
# ---------- cross-check of the analytic field vs real code ----------
|
||||
P('## Cross-check: analytic reimplementation vs the real Zone (GetHeight / GetForce)')
|
||||
P()
|
||||
P('| case | max abs err h (units) | max rel err a_A (where a>0.01) | cells where real force is 0 but formula >0.001 | cells where formula is 0 but real >0.001 |')
|
||||
P('|---|---|---|---|---|')
|
||||
for name, arr in cases.items():
|
||||
r, h, fx, fy = arr.T
|
||||
if name.startswith('Bowl'):
|
||||
Rz = float(name.split('_R')[1]); hh = bowl_h(r, Rz); s = bowl_dh(r, Rz)
|
||||
else:
|
||||
t, tag, w = name.split('_'); m = meta[(t, tag, int(w[-1]))]
|
||||
if t in ('GasGiant', 'Sun') and w == 'waves1':
|
||||
continue
|
||||
hh = well_h(r, m['D'], m['Rg']); s = well_dh(r, m['D'], m['Rg'])
|
||||
a_real = np.hypot(fx, fy); a_f = accA(s)
|
||||
sel = a_f > 0.01
|
||||
rel = float(np.max(np.abs(a_real[sel] - a_f[sel]) / a_f[sel])) if sel.any() else float('nan')
|
||||
P(f'| {name} | {np.max(np.abs(h-hh)):.2e} | {rel:.2e} | {int(np.sum((a_real==0)&(a_f>1e-3)))} | {int(np.sum((a_f==0)&(a_real>1e-3)))} |')
|
||||
P()
|
||||
# direction sanity
|
||||
r, h, fx, fy = cases['Planet_p50_waves0'].T
|
||||
P(f'Direction: Planet_p50 force x component is {"negative (inward)" if np.all(fx[(np.hypot(fx,fy)>0)&(r<1000)]<=0) else "mixed"} for r<1000, y component max {np.max(np.abs(fy)):.2e}.')
|
||||
P()
|
||||
|
||||
# ---------- waves contribution ----------
|
||||
P('## Wave term (gas giants and suns)')
|
||||
P()
|
||||
P('| case | peak a with waves | peak a without | max rel diff of a over r<support |')
|
||||
P('|---|---|---|---|')
|
||||
for t in ('GasGiant', 'Sun'):
|
||||
for tag in ('p10', 'p50', 'p90'):
|
||||
a1 = np.hypot(*cases[f'{t}_{tag}_waves1'][:, 2:4].T); a0 = np.hypot(*cases[f'{t}_{tag}_waves0'][:, 2:4].T)
|
||||
rr = cases[f'{t}_{tag}_waves1'][:, 0]; m = meta[(t, tag, 1)]
|
||||
sel = rr < m['Rg'] / 2
|
||||
P(f'| {t} {tag} | {a1.max():.3f} | {a0.max():.3f} | {np.max(np.abs(a1[sel]-a0[sel]))/a0.max():.3f} of peak |')
|
||||
P()
|
||||
|
||||
# ---------- bodies / bands ----------
|
||||
rows = [r for r in csv.DictReader(open(os.path.join(D, 'bodies.csv'))) if r.get('zoneRadius') is not None and r.get('belt') is not None]
|
||||
bands = collections.defaultdict(list) # parentType -> list of (childType, n, p10, p50, p90)
|
||||
tmp = collections.defaultdict(list)
|
||||
for r in rows:
|
||||
if r['empty'] == '1' or r['parentIdx'] == '-1': continue
|
||||
tmp[(r['parentType'], r['type'])].append(float(r['distance']))
|
||||
for (pt, ct), v in tmp.items():
|
||||
v = np.sort(v); q = lambda p: float(v[int((len(v) - 1) * p)])
|
||||
bands[pt].append((ct, len(v), q(.1), q(.5), q(.9)))
|
||||
# stations: middle-upper half of parented, non-empty bodies sorted by distance, per zone
|
||||
zones = collections.defaultdict(list)
|
||||
for r in rows:
|
||||
if r['parentIdx'] != '-1' and r['empty'] != '1':
|
||||
zones[(r['density'], r['seed'])].append((float(r['distance']), r['parentType']))
|
||||
st = collections.defaultdict(list)
|
||||
for z, lst in zones.items():
|
||||
lst.sort(); cand = lst[len(lst) // 2:]
|
||||
for d, pt in cand: st[pt].append(d)
|
||||
stationBands = {}
|
||||
for pt, v in st.items():
|
||||
v = np.sort(v); stationBands[pt] = (len(v), *(float(v[int((len(v) - 1) * p)]) for p in (.1, .5, .9)))
|
||||
P('## Where orbits are in the game (real generator: ZoneGenerator.GenerateEntities, 5 zone densities x 300 seeds, authored ZoneGenerationSettings)')
|
||||
P()
|
||||
P('Distance is OrbitData.Distance, relative to the parent body. Rail speed is 2*pi*d/OrbitPeriod(d) = 2*pi u/s at every d (OrbitPeriod = 1*d^1+0).')
|
||||
P()
|
||||
P('| parent type | child type | n | d p10 | d p50 | d p90 |')
|
||||
P('|---|---|---|---|---|---|')
|
||||
order = {'Sun': 0, 'GasGiant': 1, 'Planet': 2, 'Planetoid': 3}
|
||||
for pt in sorted(bands, key=lambda x: order.get(x, 9)):
|
||||
for ct, n, a, b, c in sorted(bands[pt], key=lambda x: order.get(x[0], 9) if x[0] != 'Belt' else 5):
|
||||
P(f'| {pt} | {ct} | {n} | {a:.0f} | {b:.0f} | {c:.0f} |')
|
||||
P()
|
||||
P('Stations (ZoneGenerator.cs:225-310) sit on the orbit of a selected body (same Distance, phase +-60 deg, parent = that body\'s parent), chosen from the upper half of the distance-sorted bodies. Station distance by parent type, p10/p50/p90 over all candidates (upper-half pool, count unknown from the stationCount draw):')
|
||||
P()
|
||||
P('| parent type | n candidates | d p10 | d p50 | d p90 |')
|
||||
P('|---|---|---|---|---|')
|
||||
for pt in sorted(stationBands, key=lambda x: order.get(x, 9)):
|
||||
n, a, b, c = stationBands[pt]; P(f'| {pt} | {n} | {a:.0f} | {b:.0f} | {c:.0f} |')
|
||||
P()
|
||||
P('Belts are bodies in the table above (type Belt); their rocks sit at belt distance +- AsteroidBeltWidth(d) = 5*d^0.666+50 wide.')
|
||||
P()
|
||||
|
||||
# ---------- per type analysis ----------
|
||||
types = ['Planetoid', 'Planet', 'GasGiant', 'Sun']
|
||||
summary = {}
|
||||
colors = dict(A='#c0392b', B='#2471a3', rail='#1e8449', disc='#8e44ad')
|
||||
GRID = [5, 10, 25, 50, 100, 150, 200, 300, 400, 500, 750, 1000, 1500, 2000, 3000, 4000, 5000]
|
||||
|
||||
def mark_for(parent_type, r):
|
||||
out = []
|
||||
for ct, n, a, b, c in bands.get(parent_type, []):
|
||||
if a <= r <= c: out.append(f'{ct}[{a:.0f}-{c:.0f}]')
|
||||
return ' '.join(out)
|
||||
|
||||
for t in types:
|
||||
for tag in ('p10', 'p50', 'p90'):
|
||||
m = meta[(t, tag, 0)]
|
||||
Rg, Dd = m['Rg'], m['D']; rs = Rg / 2
|
||||
r = np.linspace(rs / 20000, rs, 40000)
|
||||
s = well_dh(r, Dd, Rg); aA = accA(s)
|
||||
k = aA.max() / s.max(); aB = k * s
|
||||
summary[(t, tag)] = dict(mass=m['mass'], Rg=Rg, rs=rs, D=Dd, peakA=aA.max(), peakS=s.max(), k=k,
|
||||
r_gate_lo=float(r[np.argmax(aA > 0)]), r_peak=float(r[np.argmax(s)]))
|
||||
# ---- p50 detail tables
|
||||
tag = 'p50'; m = meta[(t, tag, 0)]; Rg, Dd = m['Rg'], m['D']; rs = Rg / 2
|
||||
sm = summary[(t, tag)]; k = sm['k']
|
||||
r = np.linspace(rs / 40000, rs, 40000)
|
||||
h = well_h(r, Dd, Rg); s = well_dh(r, Dd, Rg); aA = accA(s); aB = k * s
|
||||
TA = period(r, aA); TB = period(r, aB); stA = stable(r, aA); stB = stable(r, aB)
|
||||
lap = well_lap(r, Dd, Rg)
|
||||
P(f'### {t} (representative mass {m["mass"]:.0f} = p50 of {t}s in generated zones; well radius {Rg:.0f}, support radius {rs:.0f}, depth {Dd:.1f}, body radius {m["body"]:.1f}, exponent 16)')
|
||||
P()
|
||||
P(f'Peak slope |h\'| = {sm["peakS"]:.4f} at r = {sm["r_peak"]:.0f}. Peak a_A = S*R*s^2 = {sm["peakA"]:.4f} u/s^2. Gate (|n|^2 > 0.001 <=> s > 0.0316) switches the force on at r = {sm["r_gate_lo"]:.1f}. Reading B: k = {k:.3f} u/s^2 per unit slope (a_B = k*|h\'|, peak-matched).')
|
||||
P()
|
||||
P('| r | h(r) | slope s | a_A | T_A | a_B | T_B | T_rail=r | hold-rail thrust A (u/s^2, frac of 30) | hold-rail thrust B | stable A | stable B | Laplacian (h"+h\'/r) | orbits here |')
|
||||
P('|---|---|---|---|---|---|---|---|---|---|---|---|---|---|')
|
||||
pts = sorted(set([g for g in GRID if g < rs] + [round(rs * f) for f in (0.9, 0.99)] + [round(x) for _, _, a, b, c in bands.get(t, []) for x in (a, b, c) if x < rs]))
|
||||
for rr in pts:
|
||||
i = int(np.searchsorted(r, rr)); i = min(i, len(r) - 1)
|
||||
f = lambda v: ('inf' if not np.isfinite(v) else (f'{v:.3g}'))
|
||||
need = TP ** 2 / rr
|
||||
tA = need - aA[i]; tB = need - aB[i]
|
||||
P(f'| {rr:.0f} | {h[i]:.2f} | {s[i]:.4f} | {aA[i]:.4f} | {f(TA[i])} | {aB[i]:.4f} | {f(TB[i])} | {rr:.0f} | {tA:+.3f} ({abs(tA)/A_SHIP:.3%}) | {tB:+.3f} ({abs(tB)/A_SHIP:.3%}) | {"yes" if stA[i] else "no"} | {"yes" if stB[i] else "no"} | {lap[i]:+.2e} | {mark_for(t, rr)} |')
|
||||
P()
|
||||
# stability spans
|
||||
def spans(mask):
|
||||
out = []; on = False
|
||||
for i in range(len(r)):
|
||||
if mask[i] and not on: lo = r[i]; on = True
|
||||
if (not mask[i]) and on: out.append((lo, r[i - 1])); on = False
|
||||
if on: out.append((lo, r[-1]))
|
||||
return out
|
||||
def fmt(sp): return ', '.join(f'{a:.0f}-{b:.0f}' for a, b in sp if b - a > 1) or 'none'
|
||||
P(f'Stable circular-orbit spans (d(r^3 a)/dr>0, with a>0): A: {fmt(spans(stA & (aA>0)))}; B: {fmt(spans(stB))}. Unstable (outer well, a falls faster than 1/r^3): A: {fmt(spans((~stA)&(aA>0)))}; B: {fmt(spans(~stB))}.')
|
||||
# share of orbit band that is stable
|
||||
for ct, n, a, b, c in bands.get(t, []):
|
||||
sel = (r >= a) & (r <= c)
|
||||
if sel.sum() == 0: continue
|
||||
gA = (aA[sel] > 0).mean(); sA = (stA & (aA > 0))[sel].mean(); sB = stB[sel].mean()
|
||||
medi = int(np.searchsorted(r, b)); medi = min(medi, len(r)-1)
|
||||
P(f'- {ct} orbits of a {t} (d {a:.0f}-{c:.0f}): force on (A) at {gA:.0%} of the band, stable (A) {sA:.0%}, stable (B) {sB:.0%}; at the median d={b:.0f}: T_A/T_rail = {TA[medi]/b if np.isfinite(TA[medi]) else float("inf"):.3g}, T_B/T_rail = {TB[medi]/b:.3g}.')
|
||||
P()
|
||||
# --- implied mass (B)
|
||||
Sigma = k * lap / TP # G=1
|
||||
Mcum = r * aB / 2.0 # 2D Gauss: a = 2 G M(<r)/r
|
||||
dr = np.gradient(r)
|
||||
Mpos = float(np.sum(np.clip(Sigma, 0, None) * TP * r * dr)); Mneg = float(np.sum(np.clip(Sigma, None, 0) * TP * r * dr))
|
||||
sgn = np.where(np.diff(np.sign(lap)) != 0)[0]
|
||||
P(f'Reading B mass: Sigma = k*(h"+h\'/r)/(2*pi) (G=1). Positive mass {Mpos:.2f}, negative (antimass) {Mneg:.2f}, net M(<rim) = {Mpos+Mneg:.3f} (should be 0 because h\'(rim)=0). Laplacian changes sign at r = {", ".join(f"{r[i]:.0f}" for i in sgn)}. Core mass (r<first sign change) fraction of the antimass: {Mpos/abs(Mneg) if Mneg else 0:.2f}.')
|
||||
P()
|
||||
summary[(t, 'p50')].update(Mpos=Mpos, Mneg=Mneg, signs=[float(r[i]) for i in sgn])
|
||||
|
||||
# ---------- figures
|
||||
fig, ax = plt.subplots(figsize=(8, 5))
|
||||
ax.plot(r, np.where(np.isfinite(TA), TA, np.nan), color=colors['A'], label='T_field A (a = S*R*|h\'|^2, gated)')
|
||||
ax.plot(r, TB, color=colors['B'], label='T_field B (a = k*|h\'|)')
|
||||
ax.plot(r, r, color=colors['rail'], lw=2, label='T_rail = OrbitPeriod(r) = r')
|
||||
ax.axvline(rs, color='gray', ls=':'); ax.text(rs, 1.5, ' support', color='gray', rotation=90, va='bottom')
|
||||
unst = (~stA) & (aA > 0)
|
||||
ax.fill_between(r, 1, 1e8, where=unst, color='#c0392b', alpha=.08, label='A unstable (r^3 a falling)')
|
||||
bc = ['#f5b041', '#af7ac5', '#48c9b0', '#aab7b8']
|
||||
for j, (ct, n, a, b, c) in enumerate(bands.get(t, [])):
|
||||
ax.axvspan(a, min(c, rs * 1.0), color=bc[j % 4], alpha=.18, label=f'{ct} orbits p10-p90')
|
||||
ax.set_xscale('log'); ax.set_yscale('log'); ax.set_ylim(1, 1e6); ax.set_xlim(max(1, rs / 400), rs * 1.02)
|
||||
ax.set_xlabel('r (units from body)'); ax.set_ylabel('orbital period T (s)')
|
||||
ax.set_title(f'{t} (mass {m["mass"]:.0f}): field periods vs OrbitPeriod rail'); ax.legend(fontsize=7, loc='upper left')
|
||||
fig.tight_layout(); fig.savefig(os.path.join(HERE, f'fig_T_{t}.png'), dpi=130); plt.close(fig)
|
||||
|
||||
# derived wells (anchored to h(rs)=0)
|
||||
rr_ = np.linspace(rs / 2000, rs, 3000)
|
||||
hA = (TP / math.sqrt(SR)) * 2 * (np.sqrt(rr_) - math.sqrt(rs)) # h' = 2pi/(sqrt(SR) sqrt r)
|
||||
r0 = m['body']
|
||||
hB = (TP ** 2 / k) * (np.log(rr_) - math.log(rs))
|
||||
fig, ax = plt.subplots(figsize=(8, 5))
|
||||
ax.plot(rr_, well_h(rr_, Dd, Rg), color='k', lw=2, label=f'today (PowerPulse e=16, depth {Dd:.0f})')
|
||||
ax.plot(rr_, hA, color=colors['A'], label='derived A: h = 1.147*(sqrt r - sqrt rs)')
|
||||
ax.plot(rr_[rr_ >= r0], hB[rr_ >= r0], color=colors['B'], label=f'derived B: h = (4pi^2/k) ln(r/rs), k={k:.2f}')
|
||||
ax.axvline(r0, color='gray', ls=':'); ax.text(r0, -Dd * .95, ' body radius', color='gray', rotation=90)
|
||||
ax.set_xscale('log'); ax.set_ylim(-Dd * 1.08, Dd * .06); ax.set_xlabel('r'); ax.set_ylabel('h(r)')
|
||||
ax.set_title(f'{t}: today\'s well vs the well that makes the rail exact'); ax.legend(fontsize=7)
|
||||
fig.tight_layout(); fig.savefig(os.path.join(HERE, f'fig_well_{t}.png'), dpi=130); plt.close(fig)
|
||||
summary[(t, 'p50')].update(depthA=float(-hA[0]), depthB=float(-hB[rr_ >= r0][0]), gateA=(0.5735 / 0.0316) ** 2)
|
||||
|
||||
fig, axs = plt.subplots(1, 2, figsize=(11, 4.2))
|
||||
axs[0].plot(r, Sigma, color=colors['B']); axs[0].fill_between(r, 0, Sigma, where=Sigma < 0, color='#c0392b', alpha=.35, label='negative density (antimass)')
|
||||
axs[0].fill_between(r, 0, Sigma, where=Sigma > 0, color=colors['B'], alpha=.2, label='positive')
|
||||
axs[0].axhline(0, color='k', lw=.5); axs[0].set_xlabel('r'); axs[0].set_ylabel('implied surface density (G=1, k peak-matched)')
|
||||
axs[0].set_title(f'{t}: Sigma(r) = k*laplacian(h)/2pi'); axs[0].legend(fontsize=7)
|
||||
axs[1].plot(r, Mcum, color=colors['B']); axs[1].axhline(0, color='k', lw=.5); axs[1].set_xlabel('r'); axs[1].set_ylabel('enclosed mass M(<r) = r*a_B/2')
|
||||
axs[1].set_title('enclosed mass returns to 0 at the rim')
|
||||
fig.tight_layout(); fig.savefig(os.path.join(HERE, f'fig_rho_{t}.png'), dpi=130); plt.close(fig)
|
||||
|
||||
# ---------- summary table over p10/p50/p90 ----------
|
||||
P('## Summary by body type and mass quantile (reading A and B peaks)')
|
||||
P()
|
||||
P('| type | quantile | mass | support r | depth | peak slope at r | peak a_A | force switches on at r | k (B) | rail hold thrust at peak (frac of 30) |')
|
||||
P('|---|---|---|---|---|---|---|---|---|---|')
|
||||
for t in types:
|
||||
for tag in ('p10', 'p50', 'p90'):
|
||||
d = summary[(t, tag)]
|
||||
P(f'| {t} | {tag} | {d["mass"]:.0f} | {d["rs"]:.0f} | {d["D"]:.0f} | {d["peakS"]:.4f} at {d["r_peak"]:.0f} | {d["peakA"]:.3f} | {d["r_gate_lo"]:.1f} | {d["k"]:.2f} | {abs(TP**2/d["r_peak"]-d["peakA"])/A_SHIP:.3%} |')
|
||||
P()
|
||||
P('Ship scale (catalog, tests/ships.csv): thrust is Thruster.Thrust/Entity.Mass per second (Thruster.cs:121). Longinus (mass 2500, TopSpeed 100) with a Small Drive (thrust 60000..90000) = 24..36 u/s^2; Djinni (mass 10000, TopSpeed 50) = 6..9. A_SHIP = 30 used above. Gravity peaks are 0.01-3 u/s^2.')
|
||||
P()
|
||||
|
||||
# ---------- zone bowl ----------
|
||||
P('## Zone bowl')
|
||||
P()
|
||||
P('h_bowl = -64*(1-(r/Rz)^2)^2, slope = 256*u*(1-u^2)/Rz with u = r/Rz, max 98.5/Rz at u = 0.577. Gate needs slope > 0.0316, i.e. Rz < 3117 for the bowl to push at all.')
|
||||
P()
|
||||
P('| pack radius Rz | peak slope | peak a_A (real code) | real code max force | force on over | centre-of-zone T_A at 0.5Rz | note |')
|
||||
P('|---|---|---|---|---|---|---|')
|
||||
for Rz in (1000, 2500, 5000, 10000):
|
||||
arr = cases[f'Bowl_R{Rz}']; rr = arr[:, 0]; a_real = np.hypot(arr[:, 2], arr[:, 3])
|
||||
s = bowl_dh(np.linspace(1, Rz, 20000), Rz); peak = s.max(); aa = accA(s)
|
||||
on = np.linspace(1, Rz, 20000)[aa > 0]
|
||||
ta = period(np.array([0.5 * Rz]), accA(bowl_dh(np.array([0.5 * Rz]), Rz)))[0]
|
||||
P(f'| {Rz} | {peak:.4f} | {aa.max():.4f} | {a_real.max():.4f} | {("%.0f-%.0f" % (on.min(), on.max())) if len(on) else "never"} | {ta:.4g} | {"zone radius range is 1000..10000 (ZoneRadius)" if Rz==1000 else ""} |')
|
||||
P()
|
||||
# combined sun + bowl
|
||||
for Rz in (1000, 2000, 5000):
|
||||
m = meta[('Sun', 'p50', 0)]; Rg, Dd = m['Rg'], m['D']; rs = Rg / 2
|
||||
r = np.linspace(1, rs, 20000)
|
||||
sw = well_dh(r, Dd, Rg); sb = bowl_dh(r, Rz); st_ = sw + sb
|
||||
aW = accA(sw); aC = accA(st_)
|
||||
sel = (r > 300) & (r < 1500)
|
||||
P(f'Sun p50 (support {rs:.0f}) in a zone of radius {Rz}, bowl centred on the sun (the generator puts the root body at the origin): bowl adds {np.mean(aC[sel]-aW[sel]):+.3f} u/s^2 on average over r=300..1500 (well alone {aW[sel].mean():.3f}); T_A at r=1000: well alone {period(np.array([1000.]), accA(well_dh(np.array([1000.]),Dd,Rg)))[0]:.0f} s, with bowl {period(np.array([1000.]), accA(well_dh(np.array([1000.]),Dd,Rg)+bowl_dh(np.array([1000.]),Rz)))[0]:.0f} s (rail 1000 s).')
|
||||
P()
|
||||
P('Bowl as reading B mass: laplacian of -64(1-u^2)^2 = 64*(...) is positive at the centre and negative near the rim, same antimass-ring signature (see fig_bowl.png).')
|
||||
P()
|
||||
fig, axs = plt.subplots(1, 3, figsize=(14, 4))
|
||||
for Rz, c in ((1000, '#c0392b'), (2500, '#d68910'), (5000, '#2471a3'), (10000, '#1e8449')):
|
||||
rr = np.linspace(1, Rz, 4000); s = bowl_dh(rr, Rz)
|
||||
axs[0].plot(rr / Rz, s, color=c, label=f'Rz={Rz}'); axs[1].plot(rr / Rz, accA(s), color=c); axs[2].plot(rr / Rz, bowl_lap(rr, Rz) * Rz ** 2 / BOWL_D, color=c)
|
||||
axs[0].axhline(0.0316, color='k', ls='--', lw=.7); axs[0].text(.02, .034, 'force gate s=0.0316'); axs[0].set_title('bowl slope vs r/Rz'); axs[0].legend(); axs[0].set_xlabel('r/Rz')
|
||||
axs[1].set_title('a_A from bowl (u/s^2)'); axs[1].set_xlabel('r/Rz')
|
||||
axs[2].set_title('bowl laplacian * Rz^2 / 64'); axs[2].axhline(0, color='k', lw=.5); axs[2].set_xlabel('r/Rz')
|
||||
fig.tight_layout(); fig.savefig(os.path.join(HERE, 'fig_bowl.png'), dpi=130); plt.close(fig)
|
||||
|
||||
# ---------- inverse ----------
|
||||
P('## Inverse: the well that makes OrbitPeriod exact (T = r)')
|
||||
P()
|
||||
P(f'A: h\'(r) = 2*pi*sqrt(r)/(sqrt(S*R)*T) = 2*pi/(sqrt({SR:.0f})*sqrt(r)) = {TP/math.sqrt(SR):.4f}/sqrt(r); h = {2*TP/math.sqrt(SR):.4f}*sqrt(r) (cusp at the centre, slope infinite at r=0). a = S*R*h\'^2 = 4*pi^2/r exactly. Stable for any T growing slower than r^2: T=r qualifies everywhere. The force gate zeroes the field once h\' < 0.0316, i.e. beyond r = {(TP/math.sqrt(SR)/math.sqrt(GATE/(1-GATE)))**2:.0f} u, so the exact well cannot be realised past that radius with the gate in place (a rail at 1000 u would need slope {TP/math.sqrt(SR)/math.sqrt(1000):.4f}).')
|
||||
P()
|
||||
P('| type (p50) | rim (support) | today\'s depth | derived A depth (rim to centre) | derived B depth (rim to body radius) | k |')
|
||||
P('|---|---|---|---|---|---|')
|
||||
for t in types:
|
||||
d = summary[(t, 'p50')]; mm = meta[(t, 'p50', 0)]
|
||||
P(f'| {t} | {d["rs"]:.0f} | {d["D"]:.1f} | {d["depthA"]:.1f} | {d["depthB"]:.1f} | {d["k"]:.2f} |')
|
||||
P()
|
||||
P('B: h\'(r) = 4*pi^2*r/(k*T^2) = 4*pi^2/(k*r), h = (4*pi^2/k) ln r, laplacian = 0 everywhere except r=0: a single point mass (2D Newton: a = 2*G*M/r, M = r*a/2 = 2*pi^2 in G=1 units, independent of r).')
|
||||
P()
|
||||
|
||||
# ---------- point mass / disc in B (Planet p50) ----------
|
||||
t = 'Planet'; m = meta[(t, 'p50', 0)]; Rg, Dd = m['Rg'], m['D']; rs = Rg / 2; k = summary[(t, 'p50')]['k']
|
||||
rc = [b for ct, n, a, b, c in bands['Sun'] if ct == 'Planet'][0]
|
||||
r = np.linspace(2, 3 * rs, 4000)
|
||||
Ttar = rc # disc period set to the rail at the median planet-around-sun distance
|
||||
Om = TP / Ttar
|
||||
a_disc = np.where(r < rs, Om ** 2 * r, Om ** 2 * rs ** 2 / r)
|
||||
T_disc = TP * np.sqrt(r / a_disc)
|
||||
s = well_dh(r, Dd, Rg); T_today_B = period(r, k * s); T_today_A = period(r, accA(s))
|
||||
fig, ax = plt.subplots(figsize=(8, 5))
|
||||
ax.plot(r, T_today_A, color=colors['A'], label='today, reading A'); ax.plot(r, T_today_B, color=colors['B'], label='today, reading B')
|
||||
ax.plot(r, r, color=colors['rail'], lw=2, label='rail T=r = 2D point mass in B')
|
||||
ax.plot(r, T_disc, color=colors['disc'], label=f'uniform disc radius {rs:.0f}, T_core={Ttar:.0f}s, point mass outside')
|
||||
ax.set_xscale('log'); ax.set_yscale('log'); ax.set_ylim(1, 1e5); ax.set_xlabel('r'); ax.set_ylabel('T (s)'); ax.legend(fontsize=7)
|
||||
ax.set_title(f'{t} p50, reading B: point mass vs uniform disc vs today'); fig.tight_layout(); fig.savefig(os.path.join(HERE, 'fig_point_disc.png'), dpi=130); plt.close(fig)
|
||||
hpt = (TP ** 2 / k) * np.log(r / rs)
|
||||
hdisc = np.where(r < rs, (Om ** 2 / k) * (r ** 2 - rs ** 2) / 2, (Om ** 2 * rs ** 2 / k) * np.log(r / rs))
|
||||
P('## Reading B comparisons: point mass, uniform disc')
|
||||
P()
|
||||
P(f'2D gravity (Gauss law in the plane): a(r) = 2*G*M(<r)/r. Point mass: a = c/r, v = const = sqrt(c), T = 2*pi*r/v ~ r (flat rotation curve). OrbitPeriod is Exponent=1, Multiplier=1, i.e. T=d^1: exactly the 2D point mass with c = 4*pi^2 (v = 2*pi u/s). Generalising, OrbitPeriod exponent E gives a ~ r^(1-2E): E=1 is the 2D point mass (1/r), E=1.5 would be 3D Kepler (1/r^2), E=0 is a rigid-rotation disc interior (a ~ r, T const).')
|
||||
P()
|
||||
P(f'Uniform disc of radius {rs:.0f} (the {t} p50 support) in B, with core period fixed to the rail at the median planet-around-sun distance ({rc:.0f} u): a = Omega^2*r inside (Omega = 2*pi/{Ttar:.0f}), T constant = {Ttar:.0f} s inside; point-mass tail outside, T = {TP/ Om * 1:.0f}*(r/{rs:.0f}) s beyond r={rs:.0f}. Height: parabola h = (Omega^2/(2k))(r^2 - rs^2) inside, log outside; the potential never returns to flat (log), unlike today\'s wells which are exactly flat beyond the rim (zero net mass). A point mass has an unbounded log well; today\'s well is bounded and mass-neutral.')
|
||||
P()
|
||||
P(f'Today\'s p50 {t} core (r << rim): h ≈ -D + D*e*(2/Rg)^2*r^2 -> h" = {2*Dd*EXP*4/Rg**2:.4g}, h\'/r = h"; so near the centre laplacian = 2h" = {4*Dd*EXP*4/Rg**2:.4g} > 0: positive density, rigid-rotation core in B (T = 2*pi/sqrt(k*h") = {TP/math.sqrt(k*2*Dd*EXP*4/Rg**2):.0f} s), not a point mass.')
|
||||
P()
|
||||
open(os.path.join(HERE, 'report_numbers.md'), 'w', encoding='utf-8').write('\n'.join(md))
|
||||
json.dump({f'{a}_{b}': {kk: (vv if not isinstance(vv, list) else vv) for kk, vv in v.items()} for (a, b), v in summary.items()}, open(os.path.join(HERE, 'summary.json'), 'w'), indent=1)
|
||||
print('ok', len(md))
|
||||
BIN
docs/research/2026-10-13-orbit-probe/data/bodies.csv
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/data/bodies.csv
(Stored with Git LFS)
Normal file
Binary file not shown.
|
BIN
docs/research/2026-10-13-orbit-probe/data/meta.csv
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/data/meta.csv
(Stored with Git LFS)
Normal file
Binary file not shown.
|
BIN
docs/research/2026-10-13-orbit-probe/data/profiles.csv
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/data/profiles.csv
(Stored with Git LFS)
Normal file
Binary file not shown.
|
BIN
docs/research/2026-10-13-orbit-probe/data/ships.csv
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/data/ships.csv
(Stored with Git LFS)
Normal file
Binary file not shown.
|
13
docs/research/2026-10-13-orbit-probe/extract.py
Normal file
13
docs/research/2026-10-13-orbit-probe/extract.py
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import sys,os,re
|
||||
log,outd=sys.argv[1],sys.argv[2]; os.makedirs(outd,exist_ok=True)
|
||||
cur=None;f=None
|
||||
for line in open(log,encoding='utf-8',errors='replace'):
|
||||
line=line.rstrip('\r\n')
|
||||
m=re.match(r'@@FILE (\w+)',line)
|
||||
if m:
|
||||
if f:f.close()
|
||||
cur=m.group(1);f=open(os.path.join(outd,cur+'.csv'),'w',encoding='utf-8');continue
|
||||
if line.startswith('@@END'):
|
||||
if f:f.close()
|
||||
f=None;cur=None;continue
|
||||
if f: f.write(line+'\n')
|
||||
BIN
docs/research/2026-10-13-orbit-probe/fig_T_GasGiant.png
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/fig_T_GasGiant.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
docs/research/2026-10-13-orbit-probe/fig_T_Planet.png
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/fig_T_Planet.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
docs/research/2026-10-13-orbit-probe/fig_T_Planetoid.png
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/fig_T_Planetoid.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
docs/research/2026-10-13-orbit-probe/fig_T_Sun.png
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/fig_T_Sun.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
docs/research/2026-10-13-orbit-probe/fig_bowl.png
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/fig_bowl.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
docs/research/2026-10-13-orbit-probe/fig_point_disc.png
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/fig_point_disc.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
docs/research/2026-10-13-orbit-probe/fig_rho_GasGiant.png
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/fig_rho_GasGiant.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
docs/research/2026-10-13-orbit-probe/fig_rho_Planet.png
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/fig_rho_Planet.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
docs/research/2026-10-13-orbit-probe/fig_rho_Planetoid.png
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/fig_rho_Planetoid.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
docs/research/2026-10-13-orbit-probe/fig_rho_Sun.png
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/fig_rho_Sun.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
docs/research/2026-10-13-orbit-probe/fig_well_GasGiant.png
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/fig_well_GasGiant.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
docs/research/2026-10-13-orbit-probe/fig_well_Planet.png
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/fig_well_Planet.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
docs/research/2026-10-13-orbit-probe/fig_well_Planetoid.png
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/fig_well_Planetoid.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
docs/research/2026-10-13-orbit-probe/fig_well_Sun.png
(Stored with Git LFS)
Normal file
BIN
docs/research/2026-10-13-orbit-probe/fig_well_Sun.png
(Stored with Git LFS)
Normal file
Binary file not shown.
356
docs/research/2026-10-13-orbit-probe/report.md
Normal file
356
docs/research/2026-10-13-orbit-probe/report.md
Normal file
|
|
@ -0,0 +1,356 @@
|
|||
<!-- Research for operator question 2026-10-13: do Aetheria orbits match the gravity terrain; potential/Laplacian reading. Probe imagination-aeth-orbit-probe, session self-2026-10-13-ag2, at master 0898725f. -->
|
||||
# Orbit probe: does following an orbit cost effort, and what do the wells say?
|
||||
|
||||
Imagination probe `imagination-aeth-orbit-probe`, 2026-10-13. A measurement, not a cut: nothing admitted, nothing pushed. Source tree: GameCult/Aetheria origin/master e99cfbed, in a detached worktree (since removed). Real code ran on Yggdrasil (stopgap, dotnet image, one scratch xunit test, job log `run2.log`, 1 passed); the tables below are the analytic reimplementation in `analyze.py`, cross-checked against that run.
|
||||
|
||||
## Short answer
|
||||
|
||||
Self's analysis largely holds. Two things it missed matter more than the rest: the force gate, and magnitude. Today's wells pull 20 to 70 times harder than the OrbitPeriod rail implies, so a field orbit at the same radius takes 0.11 to 0.23 of the rail period, and holding the rail costs a real fraction of a ship's thrust. The wells' shape is not the main hostility; the strength is, plus an unstable outer half and a dead-zone gate.
|
||||
|
||||
## Method and sources
|
||||
|
||||
| number | value | where it came from |
|
||||
|---|---|---|
|
||||
| GravityStrength S | 2 | `Assets/Resources/Settings.asset`, PlanetSettings (read from the checked-out file; a real YAML, not an LFS pointer) |
|
||||
| GravityReferenceRate R | 60 | `Zone.cs:678` constant |
|
||||
| force gate | \|n_xz\|^2 > 0.001 (slope s > 0.0316) | `Zone.GravityAcceleration`, Zone.cs:680-685 |
|
||||
| OrbitPeriod | Exponent 1, Multiplier 1, Constant 0, so T = d seconds | Settings.asset PlanetSettings.OrbitPeriod; `ExponentialCurve.Evaluate = M*pow(v,E)+C` |
|
||||
| well depth / radius | 30*m^0.175 / 500*m^0.25 (times per-body multipliers, default 1) | Settings.asset GravityDepth, GravityRadius; Zone.cs:738-741 |
|
||||
| well exponent | 16 | `BodyData.GravityDepthExponent` default (ZoneData.cs:97); the generator never overrides it |
|
||||
| zone bowl | depth 64, exponent 2, radius Pack.Radius | Settings.asset ZoneDepth, ZoneDepthExponent; Zone.cs:629 |
|
||||
| waves (gas giants, suns) | depth 0.5*m^0.3, radius 500*m^0.25, freq 0.2*m^0.45 | Settings.asset WaveDepth/WaveRadius/WaveFrequency; Zone.cs:643-651 |
|
||||
| zone radius | lerp(1000, 10000, density^1.5) | Settings.asset ZoneSettings.ZoneRadius (same values as RestoredHullsTests.TutorialZoneSettings, which the probe used) |
|
||||
| body masses and orbit distances | generated | real `ZoneGenerator.GenerateEntities`, authored ZoneGenerationSettings, 5 densities x 300 seeds = 31,640 bodies (`data/bodies.csv`). Mass thresholds: sun>5000, gas giant>1000, planet>100, else planetoid. |
|
||||
| ship acceleration | 24 to 36 u/s^2 (Longinus 2500 + Small Drive 60-90k thrust); 6 to 9 (Djinni 10000) | catalog via the probe (`data/ships.csv`); `Thruster.Execute`: `Velocity -= dir*input*thrust/Entity.Mass*dt`. 30 u/s^2 is used as "typical". Approximation: Entity.Mass read as hull mass only. |
|
||||
|
||||
PowerPulse(x,e) doubles x then clamps, so a well's real support radius is Rg/2 (half the "GravityWellRadius"), and the zone bowl's is Pack.Radius. Real code on a grid is in `data/profiles.csv` (22 cases: 4 body types x p10/p50/p90 mass, gas giants and suns with and without waves, and 4 bowls). "p50 body" below means the median mass of that type among generated bodies (planetoid 29, planet 274, gas giant 2260, sun 14152).
|
||||
|
||||
Cross-check (first table in the appendix): the analytic h matches `Zone.GetHeight` to 1e-4 units; a = S*R*s^2 matches `Zone.GetForce` to 0.7% to 8% (worst for suns, from the 0.1-unit finite-difference step and float32 heights over a steep exponent-16 profile); direction is inward; the only gate disagreements are single cells at the on/off edge.
|
||||
|
||||
## Where Self's analysis held or broke
|
||||
|
||||
1. a = S*R*|grad h|^2: held. The step cancels (normal xz = -grad h / sqrt(1+|grad h|^2), m = s^2/(1+s^2), 1/(1-m)-1 = s^2); measured against the real code. Not in Self's version: the gate zeroes the force wherever s <= 0.0316. That kills the inner core (force switches on only at r = 3.6 for a small planetoid up to 123 for a heavy sun), the outer rim tail, every zone bowl with radius above 3117 (zone radius is 1000 to 10000: density above about 0.38), and the inverse well beyond r = 329.
|
||||
2. Waves matter for gas giants and suns: they add 8 to 32 percent of the peak acceleration (2.1x for a 284k-mass rosette sun). Self's analysis ignored them; the tables use the well alone (waves are a time-dependent ripple on top).
|
||||
3. OrbitPeriod is independent of the field: held. T = d exactly, so every rail body moves at the constant speed 2*pi = 6.28 u/s whatever its distance. That is the 2D point-mass flat rotation curve (below).
|
||||
4. T_field(r) = 2*pi*sqrt(r/a): held. Non-monotonic: flat or falling inside, minimum near the slope peak, rising to infinity at the rim.
|
||||
5. Instability where r^3 a falls: held, and it bites. Stable spans under A (B in brackets), p50 body: planetoid out to r = 161 (199), planet 282 (349), gas giant 478 (591), sun 756 (935); beyond that to the rim circular orbits are unstable. About 0.28 rs (A), 0.34 rs (B).
|
||||
6. Inverse: held with a caveat. h'(r) = 2*pi/(sqrt(S*R)*sqrt(r)) = 0.5736/sqrt(r) for T = r; the gate makes it unrealisable past 329 u.
|
||||
|
||||
## Findings
|
||||
|
||||
### F1. The field orbit is 5 to 8 times too fast: gravity is 20 to 70 times the rail's
|
||||
In every orbit band, T_field/T_rail at the median distance is 0.11 to 0.23 (planets of suns 0.12, moons of planets 0.18, belts of gas giants 0.15). The rail needs a = 4*pi^2/r = 39.5/r (0.04 at r=1000, 0.4 at r=100); the wells peak at 3.2 to 16.6 u/s^2 (summary table). Gravity exceeds the centripetal need almost everywhere inside the orbit bands, so holding the rail means thrusting outward against the well.
|
||||
|
||||
### F2. Cost of holding the rail: not free
|
||||
Thrust needed = |4*pi^2/r - a(r)|. A planet's p50 well at its moon/belt orbit distances costs 17 to 30 percent of a 30 u/s^2 ship's acceleration (sun p50: 15 to 17 percent at 487-610 u, 10 percent at 750); the peak over the well is 11 percent (heavy sun) to 53 percent (small planetoid). Near the rim the need drops under 1 percent, but there the A force is gated off anyway. Ship drag (`Ship.cs:131`, `Velocity *= exp(-Drag*dt)`) makes a free orbit impossible regardless; hull Drag values were not measured.
|
||||
|
||||
### F3. Zone bowl: matters in small zones, absent in large
|
||||
Bowl slope peaks at 98.5/Rz. Rz = 1000: push peaks at 1.17 u/s^2 (on for r = 126 to 931); Rz = 2500: 0.19 (on 882 to 1939); Rz >= 3117: never on. With the sun at the zone origin and Rz = 2000 the bowl adds about 1.2 u/s^2 on average over r = 300 to 1500 to the sun's own 2.1, shortening T_A at r=1000 from 230 s to 143 s (rail 1000 s). It is also an ambient push toward zone centre on every body, including those orbiting an off-centre planet. Under A the bowl and wells do not add linearly (the force is a function of the summed slope).
|
||||
|
||||
### F4. Where orbits sit relative to wells
|
||||
Children of a sun: planets d 207-1419 (p50 610), belts 156-1091, planetoids 101-717, gas giants 304-3360, against a p50 sun support radius 2727. A sun's A force is on for 82 percent of the planet band, 37 percent of the gas giant band, 20 percent of the binary-sun band (binaries and rosettes orbit in the dead zone). Moons of a planet: d 57-443 against support 1017; the A-stable span ends at 282, so about 40 percent of moon orbits sit in the unstable outer half. Stations sit on a body's orbit distance (upper half of the distance-sorted bodies): around a sun p50 1053 (inside the A-unstable 756-2727 band), around a gas giant 407, around a planet 411.
|
||||
|
||||
### F5. Inverse: what well would make the rail exact
|
||||
A reading: h = 1.147*sqrt(r), slope infinite at the centre (a cusp), depth rim-to-centre 27 to 59 (today 54 to 160); a = 4*pi^2/r exactly; the gate defeats it past 329 u. B reading with k peak-matched: h = (4*pi^2/k)*ln(r/rs), depth rim to body radius only 4.4 to 7.0 (today 54 to 160), because the rail wants gravity of 0.04 to 0.4 u/s^2, not 5 to 17. Tuned for looks, today's wells are deep, with a flat bottom, a steep mid-radius flank and a flat rim; the rail wants a shallow log (B) or a sqrt cusp (A).
|
||||
|
||||
## Reading B: the heightfield as a potential
|
||||
|
||||
k (u/s^2 per unit slope, peak-matched to A): planetoid 39.3, planet 33.2, gas giant 28.4, sun 24.7 (p50; range 19.7 to 44.7 over p10-p90). T_B, stability and rail mismatch are in each table and in `fig_T_<type>.png`. T_B tracks T_A around the slope peak (peak-matching makes them agree there) and differs at both ends: B has no inner dead zone and keeps force past where A is gated to zero.
|
||||
|
||||
### Laplacian and implied mass (G=1, 2D Poisson: laplacian(phi) = 2*pi*G*Sigma, phi = k*h)
|
||||
Every well profile has the same signature: positive surface density in the core, a sign change at exactly r = rs/sqrt(e) = rs/4 for e=16 (analytic: laplacian ~ u^(e-2)(1-e*x^2), x = 2r/Rg), then a negative-density ring (antimass) out to the rim, then zero. The positive and negative masses are equal (planet p50 +2022 and -2022 in G=1 units; planetoid 1616, gas giant 2497, sun 2999); net M(<rim) = r*a/2 = 0 because the slope is zero at the rim. So the terrain is not a physical potential: it is a mass-neutral object, a core plus its own antimass ring, which is why nothing is felt outside the rim. The zone bowl has the same signature: positive core, negative density from Rz/sqrt(2) outward (`fig_bowl.png`).
|
||||
|
||||
### Point mass, disc, and the OrbitPeriod exponent
|
||||
In 2D, Gauss gives a = 2*G*M(<r)/r. A point mass: a = c/r, v constant, T proportional to r, logarithmic potential. OrbitPeriod (E=1, M=1) is exactly this: c = 4*pi^2, v = 2*pi. The inverse B well is h = (4*pi^2/k)*ln r with laplacian zero except at the origin: a single point mass (M = 2*pi^2 in G=1 units). An OrbitPeriod exponent E gives a ~ r^(1-2E): E=1 is 2D point mass, E=0 is a rigid-rotation uniform disc (T constant), E=1.5 would be 3D Kepler (1/r^2). A uniform disc of radius rs (`fig_point_disc.png`, planet p50): T constant inside, point-mass tail outside, the potential never returns to flat. Today's core is rigid rotation (planet p50: T_B flat at 22 s) but then bends into an antimass ring: neither a point mass nor a disc.
|
||||
Under A, the inverse well h = 1.147*sqrt(r) read as a B potential has laplacian 0.287*r^-1.5: a spread mass with enclosed mass growing as sqrt(r), also not a point mass. A forces are not linear in superposition; B forces are.
|
||||
|
||||
## Files in this folder
|
||||
`fig_T_{Planetoid,Planet,GasGiant,Sun}.png`: T_field(A), T_field(B), T_rail over r, child-orbit bands shaded, A-unstable span shaded. `fig_well_*.png`: today's well vs derived A vs derived B. `fig_rho_*.png`: implied surface density and enclosed mass under B. `fig_bowl.png`, `fig_point_disc.png`. CSVs: `data/bodies.csv` (31,640 generated bodies), `data/profiles.csv` (real-code radial profiles: r, h, force x, force y), `data/meta.csv`, `data/ships.csv`. Scripts: `analyze.py`, `extract.py`, `job.sh`; probe source `OrbitProbeScratch.cs.txt` (it was a throwaway local commit in the worktree, never pushed to GameCult; it was pushed to the Yggdrasil verify mirror as refs/verify/<sha> by the stopgap).
|
||||
|
||||
## Open and unmeasured
|
||||
- Hull Drag values (decide whether any free orbit is possible for ships).
|
||||
- Ship acceleration with items' mass included, and thruster quality (Min/Max range).
|
||||
- Sub-zone circles (smaller radius and mass) are not in the generated distribution.
|
||||
- The bowl is evaluated at the zone origin only, not at a body's actual offset.
|
||||
- Waves are excluded from the T tables.
|
||||
|
||||
---
|
||||
|
||||
# Appendix: generated tables (analyze.py)
|
||||
|
||||
## Cross-check: analytic reimplementation vs the real Zone (GetHeight / GetForce)
|
||||
|
||||
| case | max abs err h (units) | max rel err a_A (where a>0.01) | cells where real force is 0 but formula >0.001 | cells where formula is 0 but real >0.001 |
|
||||
|---|---|---|---|---|
|
||||
| Planetoid_p10_waves0 | 5.67e-05 | 6.55e-03 | 0 | 0 |
|
||||
| Planetoid_p50_waves0 | 7.74e-05 | 8.87e-03 | 0 | 0 |
|
||||
| Planetoid_p90_waves0 | 9.12e-05 | 1.76e-02 | 0 | 0 |
|
||||
| Planet_p10_waves0 | 9.61e-05 | 2.90e-02 | 0 | 0 |
|
||||
| Planet_p50_waves0 | 1.14e-04 | 2.61e-02 | 0 | 1 |
|
||||
| Planet_p90_waves0 | 1.37e-04 | 1.86e-02 | 0 | 0 |
|
||||
| GasGiant_p10_waves0 | 1.43e-04 | 2.38e-02 | 0 | 0 |
|
||||
| GasGiant_p50_waves0 | 1.61e-04 | 1.00e+00 | 1 | 0 |
|
||||
| GasGiant_p90_waves0 | 1.77e-04 | 3.99e-02 | 0 | 0 |
|
||||
| Sun_p10_waves0 | 1.94e-04 | 5.52e-02 | 0 | 0 |
|
||||
| Sun_p50_waves0 | 2.26e-04 | 7.25e-02 | 0 | 0 |
|
||||
| Sun_p90_waves0 | 3.85e-04 | 8.24e-02 | 0 | 0 |
|
||||
| Bowl_R1000 | 1.18e-05 | 4.91e-03 | 0 | 1 |
|
||||
| Bowl_R2500 | 1.18e-05 | 1.00e+00 | 1 | 0 |
|
||||
| Bowl_R5000 | 1.18e-05 | nan | 0 | 0 |
|
||||
| Bowl_R10000 | 1.18e-05 | nan | 0 | 0 |
|
||||
|
||||
Direction: Planet_p50 force x component is negative (inward) for r<1000, y component max 0.00e+00.
|
||||
|
||||
## Wave term (gas giants and suns)
|
||||
|
||||
| case | peak a with waves | peak a without | max rel diff of a over r<support |
|
||||
|---|---|---|---|
|
||||
| GasGiant p10 | 8.048 | 7.429 | 0.084 of peak |
|
||||
| GasGiant p50 | 7.489 | 6.726 | 0.115 of peak |
|
||||
| GasGiant p90 | 7.090 | 6.103 | 0.162 of peak |
|
||||
| Sun p10 | 6.944 | 5.790 | 0.200 of peak |
|
||||
| Sun p50 | 6.687 | 5.111 | 0.321 of peak |
|
||||
| Sun p90 | 10.097 | 3.268 | 2.124 of peak |
|
||||
|
||||
## Where orbits are in the game (real generator: ZoneGenerator.GenerateEntities, 5 zone densities x 300 seeds, authored ZoneGenerationSettings)
|
||||
|
||||
Distance is OrbitData.Distance, relative to the parent body. Rail speed is 2*pi*d/OrbitPeriod(d) = 2*pi u/s at every d (OrbitPeriod = 1*d^1+0).
|
||||
|
||||
| parent type | child type | n | d p10 | d p50 | d p90 |
|
||||
|---|---|---|---|---|---|
|
||||
| Sun | Sun | 2873 | 817 | 3167 | 6367 |
|
||||
| Sun | GasGiant | 3663 | 304 | 1405 | 3360 |
|
||||
| Sun | Planet | 6112 | 207 | 610 | 1419 |
|
||||
| Sun | Planetoid | 3195 | 101 | 266 | 717 |
|
||||
| Sun | Belt | 1133 | 156 | 487 | 1091 |
|
||||
| GasGiant | GasGiant | 316 | 92 | 210 | 407 |
|
||||
| GasGiant | Planet | 1316 | 111 | 288 | 637 |
|
||||
| GasGiant | Planetoid | 4217 | 89 | 214 | 581 |
|
||||
| GasGiant | Belt | 1094 | 104 | 262 | 641 |
|
||||
| Planet | Planet | 693 | 45 | 114 | 299 |
|
||||
| Planet | Planetoid | 3084 | 57 | 145 | 443 |
|
||||
| Planet | Belt | 835 | 72 | 172 | 483 |
|
||||
| Planetoid | Planetoid | 382 | 31 | 79 | 253 |
|
||||
| Planetoid | Belt | 72 | 36 | 93 | 260 |
|
||||
|
||||
Stations (ZoneGenerator.cs:225-310) sit on the orbit of a selected body (same Distance, phase +-60 deg, parent = that body's parent), chosen from the upper half of the distance-sorted bodies. Station distance by parent type, p10/p50/p90 over all candidates (upper-half pool, count unknown from the stationCount draw):
|
||||
|
||||
| parent type | n candidates | d p10 | d p50 | d p90 |
|
||||
|---|---|---|---|---|
|
||||
| Sun | 12454 | 345 | 1053 | 4005 |
|
||||
| GasGiant | 1982 | 215 | 407 | 853 |
|
||||
| Planet | 424 | 122 | 411 | 1021 |
|
||||
| Planetoid | 16 | 255 | 427 | 783 |
|
||||
|
||||
Belts are bodies in the table above (type Belt); their rocks sit at belt distance +- AsteroidBeltWidth(d) = 5*d^0.666+50 wide.
|
||||
|
||||
### Planetoid (representative mass 29 = p50 of Planetoids in generated zones; well radius 1162, support radius 581, depth 54.1, body radius 7.0, exponent 16)
|
||||
|
||||
Peak slope |h'| = 0.3274 at r = 104. Peak a_A = S*R*s^2 = 12.8667 u/s^2. Gate (|n|^2 > 0.001 <=> s > 0.0316) switches the force on at r = 6.2. Reading B: k = 39.294 u/s^2 per unit slope (a_B = k*|h'|, peak-matched).
|
||||
|
||||
| r | h(r) | slope s | a_A | T_A | a_B | T_B | T_rail=r | hold-rail thrust A (u/s^2, frac of 30) | hold-rail thrust B | stable A | stable B | Laplacian (h"+h'/r) | orbits here |
|
||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||
| 5 | -54.08 | 0.0257 | 0.0000 | inf | 1.0093 | 14 | 5 | +7.896 (26.319%) | +6.886 (22.955%) | no | yes | +1.02e-02 | |
|
||||
| 10 | -53.89 | 0.0511 | 0.3137 | 35.5 | 2.0090 | 14 | 10 | +3.634 (12.114%) | +1.939 (6.463%) | yes | yes | +1.02e-02 | |
|
||||
| 25 | -52.56 | 0.1248 | 1.8678 | 23 | 4.9023 | 14.2 | 25 | -0.289 (0.962%) | -3.323 (11.077%) | yes | yes | +9.70e-03 | |
|
||||
| 31 | -51.73 | 0.1524 | 2.7872 | 21 | 5.9885 | 14.3 | 31 | -1.514 (5.046%) | -4.715 (15.717%) | yes | yes | +9.41e-03 | Planetoid[31-253] |
|
||||
| 36 | -50.91 | 0.1743 | 3.6477 | 19.7 | 6.8509 | 14.4 | 36 | -2.551 (8.504%) | -5.754 (19.181%) | yes | yes | +9.13e-03 | Planetoid[31-253] |
|
||||
| 50 | -48.07 | 0.2295 | 6.3199 | 17.7 | 9.0175 | 14.8 | 50 | -5.530 (18.434%) | -8.228 (27.427%) | yes | yes | +8.15e-03 | Planetoid[31-253] Belt[36-260] |
|
||||
| 79 | -40.17 | 0.3064 | 11.2653 | 16.6 | 12.0394 | 16.1 | 79 | -10.766 (35.885%) | -11.540 (38.465%) | yes | yes | +5.57e-03 | Planetoid[31-253] Belt[36-260] |
|
||||
| 93 | -35.75 | 0.3233 | 12.5446 | 17.1 | 12.7046 | 17 | 93 | -12.120 (40.400%) | -12.280 (40.934%) | yes | yes | +4.21e-03 | Planetoid[31-253] Belt[36-260] |
|
||||
| 100 | -33.47 | 0.3269 | 12.8197 | 17.5 | 12.8432 | 17.5 | 100 | -12.425 (41.416%) | -12.448 (41.495%) | yes | yes | +3.54e-03 | Planetoid[31-253] Belt[36-260] |
|
||||
| 150 | -17.97 | 0.2736 | 8.9812 | 25.7 | 10.7498 | 23.5 | 150 | -8.718 (29.060%) | -10.487 (34.955%) | yes | yes | -2.58e-04 | Planetoid[31-253] Belt[36-260] |
|
||||
| 200 | -7.20 | 0.1548 | 2.8768 | 52.4 | 6.0840 | 36 | 200 | -2.679 (8.931%) | -5.887 (19.622%) | no | no | -1.57e-03 | Planetoid[31-253] Belt[36-260] |
|
||||
| 253 | -1.88 | 0.0555 | 0.3694 | 164 | 2.1802 | 67.7 | 253 | -0.213 (0.711%) | -2.024 (6.747%) | no | no | -1.10e-03 | Belt[36-260] |
|
||||
| 260 | -1.52 | 0.0468 | 0.2627 | 198 | 1.8384 | 74.7 | 260 | -0.111 (0.369%) | -1.687 (5.622%) | no | no | -9.91e-04 | |
|
||||
| 300 | -0.38 | 0.0147 | 0.0000 | inf | 0.5787 | 143 | 300 | +0.132 (0.439%) | -0.447 (1.491%) | no | no | -4.37e-04 | |
|
||||
| 400 | -0.00 | 0.0001 | 0.0000 | inf | 0.0053 | 1.73e+03 | 400 | +0.099 (0.329%) | +0.093 (0.311%) | no | no | -8.43e-06 | |
|
||||
| 500 | -0.00 | 0.0000 | 0.0000 | inf | 0.0000 | 3.45e+05 | 500 | +0.079 (0.263%) | +0.079 (0.263%) | no | no | -7.07e-10 | |
|
||||
| 523 | -0.00 | 0.0000 | 0.0000 | inf | 0.0000 | 3.59e+06 | 523 | +0.075 (0.252%) | +0.075 (0.252%) | no | no | -9.84e-12 | |
|
||||
| 575 | -0.00 | 0.0000 | 0.0000 | inf | 0.0000 | 5.38e+13 | 575 | +0.069 (0.229%) | +0.069 (0.229%) | no | no | -4.84e-25 | |
|
||||
|
||||
Stable circular-orbit spans (d(r^3 a)/dr>0, with a>0): A: 6-161; B: 0-199. Unstable (outer well, a falls faster than 1/r^3): A: 161-275; B: 199-581.
|
||||
- Planetoid orbits of a Planetoid (d 31-253): force on (A) at 100% of the band, stable (A) 59%, stable (B) 76%; at the median d=79: T_A/T_rail = 0.21, T_B/T_rail = 0.203.
|
||||
- Belt orbits of a Planetoid (d 36-260): force on (A) at 100% of the band, stable (A) 56%, stable (B) 73%; at the median d=93: T_A/T_rail = 0.184, T_B/T_rail = 0.183.
|
||||
|
||||
Reading B mass: Sigma = k*(h"+h'/r)/(2*pi) (G=1). Positive mass 1616.15, negative (antimass) -1616.15, net M(<rim) = -0.000 (should be 0 because h'(rim)=0). Laplacian changes sign at r = 145, 581. Core mass (r<first sign change) fraction of the antimass: 1.00.
|
||||
|
||||
### Planet (representative mass 274 = p50 of Planets in generated zones; well radius 2034, support radius 1017, depth 80.1, body radius 12.2, exponent 16)
|
||||
|
||||
Peak slope |h'| = 0.2768 at r = 183. Peak a_A = S*R*s^2 = 9.1968 u/s^2. Gate (|n|^2 > 0.001 <=> s > 0.0316) switches the force on at r = 12.8. Reading B: k = 33.221 u/s^2 per unit slope (a_B = k*|h'|, peak-matched).
|
||||
|
||||
| r | h(r) | slope s | a_A | T_A | a_B | T_B | T_rail=r | hold-rail thrust A (u/s^2, frac of 30) | hold-rail thrust B | stable A | stable B | Laplacian (h"+h'/r) | orbits here |
|
||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||
| 5 | -80.08 | 0.0124 | 0.0000 | inf | 0.4123 | 21.9 | 5 | +7.896 (26.319%) | +7.483 (24.945%) | no | yes | +4.95e-03 | |
|
||||
| 10 | -79.99 | 0.0248 | 0.0000 | inf | 0.8236 | 21.9 | 10 | +3.948 (13.159%) | +3.124 (10.414%) | no | yes | +4.94e-03 | |
|
||||
| 25 | -79.34 | 0.0614 | 0.4531 | 46.7 | 2.0413 | 22 | 25 | +1.126 (3.753%) | -0.462 (1.541%) | yes | yes | +4.87e-03 | |
|
||||
| 45 | -77.64 | 0.1083 | 1.4077 | 35.5 | 3.5981 | 22.2 | 45 | -0.530 (1.768%) | -2.721 (9.069%) | yes | yes | +4.67e-03 | |
|
||||
| 50 | -77.07 | 0.1195 | 1.7146 | 33.9 | 3.9710 | 22.3 | 50 | -0.925 (3.083%) | -3.181 (10.605%) | yes | yes | +4.61e-03 | Planet[45-299] |
|
||||
| 57 | -76.18 | 0.1348 | 2.1795 | 32.1 | 4.4771 | 22.4 | 57 | -1.487 (4.956%) | -3.785 (12.615%) | yes | yes | +4.50e-03 | Planet[45-299] |
|
||||
| 72 | -73.92 | 0.1655 | 3.2870 | 29.4 | 5.4982 | 22.7 | 72 | -2.739 (9.129%) | -4.950 (16.500%) | yes | yes | +4.25e-03 | Planetoid[57-443] Planet[45-299] |
|
||||
| 100 | -68.57 | 0.2143 | 5.5096 | 26.8 | 7.1183 | 23.6 | 100 | -5.115 (17.049%) | -6.724 (22.412%) | yes | yes | +3.66e-03 | Belt[72-483] Planetoid[57-443] Planet[45-299] |
|
||||
| 114 | -65.44 | 0.2337 | 6.5563 | 26.2 | 7.7651 | 24.1 | 114 | -6.210 (20.700%) | -7.419 (24.729%) | yes | yes | +3.32e-03 | Belt[72-483] Planetoid[57-443] Planet[45-299] |
|
||||
| 145 | -57.67 | 0.2641 | 8.3700 | 26.2 | 8.7736 | 25.5 | 145 | -8.098 (26.992%) | -8.501 (28.338%) | yes | yes | +2.51e-03 | Belt[72-483] Planetoid[57-443] Planet[45-299] |
|
||||
| 150 | -56.34 | 0.2673 | 8.5745 | 26.3 | 8.8802 | 25.8 | 150 | -8.311 (27.704%) | -8.617 (28.723%) | yes | yes | +2.37e-03 | Belt[72-483] Planetoid[57-443] Planet[45-299] |
|
||||
| 172 | -50.35 | 0.2758 | 9.1312 | 27.3 | 9.1639 | 27.2 | 172 | -8.902 (29.672%) | -8.934 (29.781%) | yes | yes | +1.79e-03 | Belt[72-483] Planetoid[57-443] Planet[45-299] |
|
||||
| 200 | -42.62 | 0.2743 | 9.0310 | 29.6 | 9.1135 | 29.4 | 200 | -8.834 (29.445%) | -8.916 (29.720%) | yes | yes | +1.09e-03 | Belt[72-483] Planetoid[57-443] Planet[45-299] |
|
||||
| 299 | -18.86 | 0.1910 | 4.3760 | 51.9 | 6.3439 | 43.1 | 299 | -4.244 (14.146%) | -6.212 (20.706%) | no | yes | -5.35e-04 | Belt[72-483] Planetoid[57-443] |
|
||||
| 300 | -18.67 | 0.1898 | 4.3214 | 52.4 | 6.3042 | 43.3 | 300 | -4.190 (13.966%) | -6.173 (20.575%) | no | yes | -5.44e-04 | Belt[72-483] Planetoid[57-443] |
|
||||
| 400 | -5.44 | 0.0797 | 0.7620 | 144 | 2.6473 | 77.2 | 400 | -0.663 (2.211%) | -2.549 (8.495%) | no | no | -6.95e-04 | Belt[72-483] Planetoid[57-443] |
|
||||
| 443 | -2.76 | 0.0468 | 0.2624 | 258 | 1.5535 | 106 | 443 | -0.173 (0.578%) | -1.464 (4.881%) | no | no | -5.30e-04 | Belt[72-483] Planetoid[57-443] |
|
||||
| 483 | -1.34 | 0.0259 | 0.0000 | inf | 0.8598 | 149 | 483 | +0.082 (0.272%) | -0.778 (2.594%) | no | no | -3.61e-04 | |
|
||||
| 500 | -0.96 | 0.0195 | 0.0000 | inf | 0.6487 | 174 | 500 | +0.079 (0.263%) | -0.570 (1.899%) | no | no | -2.95e-04 | |
|
||||
| 750 | -0.00 | 0.0000 | 0.0000 | inf | 0.0005 | 7.89e+03 | 750 | +0.053 (0.175%) | +0.052 (0.174%) | no | no | -6.44e-07 | |
|
||||
| 915 | -0.00 | 0.0000 | 0.0000 | inf | 0.0000 | 5.5e+06 | 915 | +0.043 (0.144%) | +0.043 (0.144%) | no | no | -4.93e-12 | |
|
||||
| 1000 | -0.00 | 0.0000 | 0.0000 | inf | 0.0000 | 2.72e+12 | 1000 | +0.039 (0.132%) | +0.039 (0.132%) | no | no | -1.40e-22 | |
|
||||
| 1007 | -0.00 | 0.0000 | 0.0000 | inf | 0.0000 | 1.43e+14 | 1007 | +0.039 (0.131%) | +0.039 (0.131%) | no | no | -8.70e-26 | |
|
||||
|
||||
Stable circular-orbit spans (d(r^3 a)/dr>0, with a>0): A: 13-282; B: 0-349. Unstable (outer well, a falls faster than 1/r^3): A: 282-470; B: 349-1017.
|
||||
- Belt orbits of a Planet (d 72-483): force on (A) at 97% of the band, stable (A) 51%, stable (B) 67%; at the median d=172: T_A/T_rail = 0.158, T_B/T_rail = 0.158.
|
||||
- Planetoid orbits of a Planet (d 57-443): force on (A) at 100% of the band, stable (A) 58%, stable (B) 76%; at the median d=145: T_A/T_rail = 0.18, T_B/T_rail = 0.176.
|
||||
- Planet orbits of a Planet (d 45-299): force on (A) at 100% of the band, stable (A) 93%, stable (B) 100%; at the median d=114: T_A/T_rail = 0.231, T_B/T_rail = 0.212.
|
||||
|
||||
Reading B mass: Sigma = k*(h"+h'/r)/(2*pi) (G=1). Positive mass 2021.62, negative (antimass) -2021.62, net M(<rim) = -0.000 (should be 0 because h'(rim)=0). Laplacian changes sign at r = 254, 1017. Core mass (r<first sign change) fraction of the antimass: 1.00.
|
||||
|
||||
### GasGiant (representative mass 2260 = p50 of GasGiants in generated zones; well radius 3447, support radius 1724, depth 115.9, body radius 20.7, exponent 16)
|
||||
|
||||
Peak slope |h'| = 0.2363 at r = 310. Peak a_A = S*R*s^2 = 6.7013 u/s^2. Gate (|n|^2 > 0.001 <=> s > 0.0316) switches the force on at r = 25.5. Reading B: k = 28.358 u/s^2 per unit slope (a_B = k*|h'|, peak-matched).
|
||||
|
||||
| r | h(r) | slope s | a_A | T_A | a_B | T_B | T_rail=r | hold-rail thrust A (u/s^2, frac of 30) | hold-rail thrust B | stable A | stable B | Laplacian (h"+h'/r) | orbits here |
|
||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||
| 5 | -115.88 | 0.0063 | 0.0000 | inf | 0.1784 | 33.4 | 5 | +7.896 (26.319%) | +7.717 (25.724%) | no | yes | +2.50e-03 | |
|
||||
| 10 | -115.84 | 0.0125 | 0.0000 | inf | 0.3552 | 33.4 | 10 | +3.948 (13.159%) | +3.593 (11.975%) | no | yes | +2.49e-03 | |
|
||||
| 25 | -115.51 | 0.0312 | 0.0000 | inf | 0.8835 | 33.4 | 25 | +1.579 (5.264%) | +0.696 (2.319%) | no | yes | +2.48e-03 | |
|
||||
| 50 | -114.35 | 0.0617 | 0.4563 | 65.8 | 1.7487 | 33.6 | 50 | +0.333 (1.111%) | -0.959 (3.197%) | yes | yes | +2.43e-03 | |
|
||||
| 89 | -111.05 | 0.1068 | 1.3679 | 50.7 | 3.0277 | 34.1 | 89 | -0.924 (3.081%) | -2.584 (8.614%) | yes | yes | +2.30e-03 | Planetoid[89-581] |
|
||||
| 92 | -110.73 | 0.1100 | 1.4529 | 50 | 3.1203 | 34.1 | 92 | -1.024 (3.413%) | -2.691 (8.971%) | yes | yes | +2.29e-03 | Planetoid[89-581] |
|
||||
| 100 | -109.81 | 0.1187 | 1.6905 | 48.3 | 3.3658 | 34.3 | 100 | -1.296 (4.319%) | -2.971 (9.903%) | yes | yes | +2.25e-03 | Planetoid[89-581] GasGiant[92-407] |
|
||||
| 104 | -109.33 | 0.1229 | 1.8136 | 47.6 | 3.4862 | 34.3 | 104 | -1.434 (4.780%) | -3.107 (10.355%) | yes | yes | +2.23e-03 | Planetoid[89-581] GasGiant[92-407] Belt[104-641] |
|
||||
| 111 | -108.44 | 0.1302 | 2.0340 | 46.4 | 3.6920 | 34.5 | 111 | -1.678 (5.595%) | -3.336 (11.121%) | yes | yes | +2.20e-03 | Planet[111-637] Planetoid[89-581] GasGiant[92-407] Belt[104-641] |
|
||||
| 150 | -102.63 | 0.1671 | 3.3494 | 42 | 4.7377 | 35.4 | 150 | -3.086 (10.288%) | -4.474 (14.915%) | yes | yes | +1.97e-03 | Planet[111-637] Planetoid[89-581] GasGiant[92-407] Belt[104-641] |
|
||||
| 200 | -93.30 | 0.2037 | 4.9815 | 39.8 | 5.7778 | 37 | 200 | -4.784 (15.947%) | -5.580 (18.601%) | yes | yes | +1.62e-03 | Planet[111-637] Planetoid[89-581] GasGiant[92-407] Belt[104-641] |
|
||||
| 210 | -91.23 | 0.2095 | 5.2661 | 39.7 | 5.9405 | 37.4 | 210 | -5.078 (16.927%) | -5.753 (19.175%) | yes | yes | +1.54e-03 | Planet[111-637] Planetoid[89-581] GasGiant[92-407] Belt[104-641] |
|
||||
| 214 | -90.39 | 0.2116 | 5.3745 | 39.7 | 6.0013 | 37.5 | 214 | -5.190 (17.300%) | -5.817 (19.390%) | yes | yes | +1.51e-03 | Planet[111-637] Planetoid[89-581] GasGiant[92-407] Belt[104-641] |
|
||||
| 262 | -79.74 | 0.2303 | 6.3660 | 40.3 | 6.5315 | 39.8 | 262 | -6.215 (20.718%) | -6.381 (21.269%) | yes | yes | +1.13e-03 | Planet[111-637] Planetoid[89-581] GasGiant[92-407] Belt[104-641] |
|
||||
| 288 | -73.67 | 0.2351 | 6.6330 | 41.4 | 6.6671 | 41.3 | 288 | -6.496 (21.653%) | -6.530 (21.767%) | yes | yes | +9.29e-04 | Planet[111-637] Planetoid[89-581] GasGiant[92-407] Belt[104-641] |
|
||||
| 300 | -70.85 | 0.2361 | 6.6879 | 42.1 | 6.6946 | 42.1 | 300 | -6.556 (21.854%) | -6.563 (21.877%) | yes | yes | +8.36e-04 | Planet[111-637] Planetoid[89-581] GasGiant[92-407] Belt[104-641] |
|
||||
| 400 | -47.79 | 0.2176 | 5.6842 | 52.7 | 6.1718 | 50.6 | 400 | -5.585 (18.618%) | -6.073 (20.244%) | yes | yes | +1.59e-04 | Planet[111-637] Planetoid[89-581] GasGiant[92-407] Belt[104-641] |
|
||||
| 407 | -46.28 | 0.2149 | 5.5406 | 53.9 | 6.0934 | 51.4 | 407 | -5.444 (18.145%) | -5.996 (19.988%) | yes | yes | +1.21e-04 | Planet[111-637] Planetoid[89-581] GasGiant[92-407] Belt[104-641] |
|
||||
| 500 | -28.39 | 0.1670 | 3.3454 | 76.8 | 4.7348 | 64.6 | 500 | -3.266 (10.888%) | -4.656 (15.519%) | no | yes | -2.53e-04 | Planet[111-637] Planetoid[89-581] Belt[104-641] |
|
||||
| 581 | -16.83 | 0.1188 | 1.6935 | 116 | 3.3688 | 82.5 | 581 | -1.626 (5.419%) | -3.301 (11.003%) | no | yes | -3.77e-04 | Planet[111-637] Planetoid[89-581] Belt[104-641] |
|
||||
| 637 | -11.06 | 0.0879 | 0.9262 | 165 | 2.4914 | 100 | 637 | -0.864 (2.881%) | -2.429 (8.098%) | no | no | -3.79e-04 | Belt[104-641] |
|
||||
| 641 | -10.71 | 0.0858 | 0.8833 | 169 | 2.4330 | 102 | 641 | -0.822 (2.739%) | -2.371 (7.905%) | no | no | -3.77e-04 | |
|
||||
| 750 | -4.03 | 0.0402 | 0.1937 | 391 | 1.1394 | 161 | 750 | -0.141 (0.470%) | -1.087 (3.623%) | no | no | -2.68e-04 | |
|
||||
| 1000 | -0.16 | 0.0026 | 0.0000 | inf | 0.0751 | 725 | 1000 | +0.039 (0.132%) | -0.036 (0.119%) | no | no | -3.50e-05 | |
|
||||
| 1500 | -0.00 | 0.0000 | 0.0000 | inf | 0.0000 | 1.37e+06 | 1500 | +0.026 (0.088%) | +0.026 (0.088%) | no | no | -6.81e-11 | |
|
||||
| 1551 | -0.00 | 0.0000 | 0.0000 | inf | 0.0000 | 8.47e+06 | 1551 | +0.025 (0.085%) | +0.025 (0.085%) | no | no | -2.44e-12 | |
|
||||
| 1706 | -0.00 | 0.0000 | 0.0000 | inf | 0.0000 | 1.59e+14 | 1706 | +0.023 (0.077%) | +0.023 (0.077%) | no | no | -7.89e-26 | |
|
||||
|
||||
Stable circular-orbit spans (d(r^3 a)/dr>0, with a>0): A: 25-478; B: 0-591. Unstable (outer well, a falls faster than 1/r^3): A: 478-779; B: 591-1724.
|
||||
- Planet orbits of a GasGiant (d 111-637): force on (A) at 100% of the band, stable (A) 70%, stable (B) 91%; at the median d=288: T_A/T_rail = 0.144, T_B/T_rail = 0.143.
|
||||
- Planetoid orbits of a GasGiant (d 89-581): force on (A) at 100% of the band, stable (A) 79%, stable (B) 100%; at the median d=214: T_A/T_rail = 0.186, T_B/T_rail = 0.176.
|
||||
- GasGiant orbits of a GasGiant (d 92-407): force on (A) at 100% of the band, stable (A) 100%, stable (B) 100%; at the median d=210: T_A/T_rail = 0.189, T_B/T_rail = 0.178.
|
||||
- Belt orbits of a GasGiant (d 104-641): force on (A) at 100% of the band, stable (A) 70%, stable (B) 91%; at the median d=262: T_A/T_rail = 0.154, T_B/T_rail = 0.152.
|
||||
|
||||
Reading B mass: Sigma = k*(h"+h'/r)/(2*pi) (G=1). Positive mass 2496.62, negative (antimass) -2496.62, net M(<rim) = -0.000 (should be 0 because h'(rim)=0). Laplacian changes sign at r = 431, 1724. Core mass (r<first sign change) fraction of the antimass: 1.00.
|
||||
|
||||
### Sun (representative mass 14152 = p50 of Suns in generated zones; well radius 5454, support radius 2727, depth 159.8, body radius 32.7, exponent 16)
|
||||
|
||||
Peak slope |h'| = 0.2059 at r = 490. Peak a_A = S*R*s^2 = 5.0891 u/s^2. Gate (|n|^2 > 0.001 <=> s > 0.0316) switches the force on at r = 46.2. Reading B: k = 24.712 u/s^2 per unit slope (a_B = k*|h'|, peak-matched).
|
||||
|
||||
| r | h(r) | slope s | a_A | T_A | a_B | T_B | T_rail=r | hold-rail thrust A (u/s^2, frac of 30) | hold-rail thrust B | stable A | stable B | Laplacian (h"+h'/r) | orbits here |
|
||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||
| 5 | -159.77 | 0.0035 | 0.0000 | inf | 0.0857 | 48.2 | 5 | +7.896 (26.319%) | +7.810 (26.033%) | no | yes | +1.38e-03 | |
|
||||
| 10 | -159.74 | 0.0069 | 0.0000 | inf | 0.1703 | 48.2 | 10 | +3.948 (13.159%) | +3.778 (12.592%) | no | yes | +1.37e-03 | |
|
||||
| 25 | -159.56 | 0.0172 | 0.0000 | inf | 0.4246 | 48.2 | 25 | +1.579 (5.264%) | +1.155 (3.848%) | no | yes | +1.37e-03 | |
|
||||
| 50 | -158.92 | 0.0342 | 0.1406 | 119 | 0.8460 | 48.3 | 50 | +0.649 (2.163%) | -0.056 (0.188%) | yes | yes | +1.36e-03 | |
|
||||
| 100 | -156.37 | 0.0674 | 0.5450 | 85.1 | 1.6655 | 48.7 | 100 | -0.150 (0.501%) | -1.271 (4.236%) | yes | yes | +1.32e-03 | |
|
||||
| 101 | -156.30 | 0.0681 | 0.5558 | 84.7 | 1.6818 | 48.7 | 101 | -0.165 (0.550%) | -1.291 (4.303%) | yes | yes | +1.32e-03 | Planetoid[101-717] |
|
||||
| 150 | -152.21 | 0.0986 | 1.1664 | 71.3 | 2.4363 | 49.3 | 150 | -0.903 (3.011%) | -2.173 (7.244%) | yes | yes | +1.25e-03 | Planetoid[101-717] |
|
||||
| 156 | -151.61 | 0.1021 | 1.2521 | 70.1 | 2.5244 | 49.4 | 156 | -0.999 (3.330%) | -2.271 (7.571%) | yes | yes | +1.24e-03 | Planetoid[101-717] |
|
||||
| 200 | -146.56 | 0.1268 | 1.9308 | 63.9 | 3.1346 | 50.2 | 200 | -1.733 (5.778%) | -2.937 (9.791%) | yes | yes | +1.17e-03 | Planetoid[101-717] Belt[156-1091] |
|
||||
| 207 | -145.66 | 0.1305 | 2.0449 | 63.2 | 3.2259 | 50.3 | 207 | -1.854 (6.181%) | -3.035 (10.117%) | yes | yes | +1.15e-03 | Planetoid[101-717] Belt[156-1091] |
|
||||
| 266 | -137.10 | 0.1585 | 3.0148 | 59 | 3.9170 | 51.8 | 266 | -2.866 (9.555%) | -3.769 (12.562%) | yes | yes | +1.02e-03 | Planetoid[101-717] Belt[156-1091] Planet[207-1419] |
|
||||
| 300 | -131.49 | 0.1719 | 3.5442 | 57.8 | 4.2470 | 52.8 | 300 | -3.413 (11.375%) | -4.115 (13.718%) | yes | yes | +9.35e-04 | Planetoid[101-717] Belt[156-1091] Planet[207-1419] |
|
||||
| 304 | -130.79 | 0.1733 | 3.6039 | 57.7 | 4.2826 | 52.9 | 304 | -3.474 (11.580%) | -4.153 (13.843%) | yes | yes | +9.25e-04 | Planetoid[101-717] Belt[156-1091] Planet[207-1419] |
|
||||
| 400 | -112.81 | 0.1985 | 4.7274 | 57.8 | 4.9050 | 56.7 | 400 | -4.629 (15.429%) | -4.806 (16.021%) | yes | yes | +6.65e-04 | Planetoid[101-717] Belt[156-1091] Planet[207-1419] GasGiant[304-3360] |
|
||||
| 487 | -95.12 | 0.2059 | 5.0888 | 61.5 | 5.0890 | 61.5 | 487 | -5.008 (16.692%) | -5.008 (16.693%) | yes | yes | +4.28e-04 | Planetoid[101-717] Belt[156-1091] Planet[207-1419] GasGiant[304-3360] |
|
||||
| 500 | -92.44 | 0.2058 | 5.0845 | 62.3 | 5.0868 | 62.3 | 500 | -5.006 (16.685%) | -5.008 (16.693%) | yes | yes | +3.94e-04 | Planetoid[101-717] Belt[156-1091] Planet[207-1419] GasGiant[304-3360] |
|
||||
| 610 | -70.26 | 0.1942 | 4.5251 | 73 | 4.7989 | 70.8 | 610 | -4.460 (14.868%) | -4.734 (15.780%) | yes | yes | +1.33e-04 | Planetoid[101-717] Belt[156-1091] Planet[207-1419] GasGiant[304-3360] |
|
||||
| 717 | -50.77 | 0.1683 | 3.3998 | 91.2 | 4.1596 | 82.5 | 717 | -3.345 (11.149%) | -4.105 (13.682%) | yes | yes | -5.36e-05 | Belt[156-1091] Planet[207-1419] GasGiant[304-3360] |
|
||||
| 750 | -45.37 | 0.1585 | 3.0129 | 99.1 | 3.9157 | 87 | 750 | -2.960 (9.868%) | -3.863 (12.877%) | yes | yes | -9.63e-05 | Belt[156-1091] Planet[207-1419] GasGiant[304-3360] |
|
||||
| 817 | -35.47 | 0.1370 | 2.2534 | 120 | 3.3864 | 97.6 | 817 | -2.205 (7.350%) | -3.338 (11.127%) | no | yes | -1.61e-04 | Belt[156-1091] Planet[207-1419] GasGiant[304-3360] |
|
||||
| 1000 | -15.84 | 0.0788 | 0.7445 | 230 | 1.9466 | 142 | 1000 | -0.705 (2.350%) | -1.907 (6.357%) | no | no | -2.10e-04 | Belt[156-1091] Planet[207-1419] GasGiant[304-3360] Sun[817-6367] |
|
||||
| 1091 | -9.80 | 0.0548 | 0.3601 | 346 | 1.3538 | 178 | 1091 | -0.324 (1.080%) | -1.318 (4.392%) | no | no | -1.87e-04 | Belt[156-1091] Planet[207-1419] GasGiant[304-3360] Sun[817-6367] |
|
||||
| 1405 | -1.15 | 0.0094 | 0.0000 | inf | 0.2332 | 488 | 1405 | +0.028 (0.094%) | -0.205 (0.684%) | no | no | -5.94e-05 | Planet[207-1419] GasGiant[304-3360] Sun[817-6367] |
|
||||
| 1419 | -1.02 | 0.0085 | 0.0000 | inf | 0.2113 | 515 | 1419 | +0.028 (0.093%) | -0.183 (0.611%) | no | no | -5.51e-05 | GasGiant[304-3360] Sun[817-6367] |
|
||||
| 1500 | -0.50 | 0.0046 | 0.0000 | inf | 0.1144 | 720 | 1500 | +0.026 (0.088%) | -0.088 (0.293%) | no | no | -3.40e-05 | GasGiant[304-3360] Sun[817-6367] |
|
||||
| 2000 | -0.00 | 0.0000 | 0.0000 | inf | 0.0003 | 1.58e+04 | 2000 | +0.020 (0.066%) | +0.019 (0.065%) | no | no | -2.11e-07 | GasGiant[304-3360] Sun[817-6367] |
|
||||
| 2454 | -0.00 | 0.0000 | 0.0000 | inf | 0.0000 | 1.23e+07 | 2454 | +0.016 (0.054%) | +0.016 (0.054%) | no | no | -1.32e-12 | GasGiant[304-3360] Sun[817-6367] |
|
||||
| 2699 | -0.00 | 0.0000 | 0.0000 | inf | 0.0000 | 2.43e+14 | 2699 | +0.015 (0.049%) | +0.015 (0.049%) | no | no | -3.93e-26 | GasGiant[304-3360] Sun[817-6367] |
|
||||
|
||||
Stable circular-orbit spans (d(r^3 a)/dr>0, with a>0): A: 46-756; B: 0-935. Unstable (outer well, a falls faster than 1/r^3): A: 756-1206; B: 935-2727.
|
||||
- Planetoid orbits of a Sun (d 101-717): force on (A) at 100% of the band, stable (A) 100%, stable (B) 100%; at the median d=266: T_A/T_rail = 0.222, T_B/T_rail = 0.195.
|
||||
- Belt orbits of a Sun (d 156-1091): force on (A) at 100% of the band, stable (A) 64%, stable (B) 83%; at the median d=487: T_A/T_rail = 0.126, T_B/T_rail = 0.126.
|
||||
- Planet orbits of a Sun (d 207-1419): force on (A) at 82% of the band, stable (A) 45%, stable (B) 60%; at the median d=610: T_A/T_rail = 0.12, T_B/T_rail = 0.116.
|
||||
- GasGiant orbits of a Sun (d 304-3360): force on (A) at 37% of the band, stable (A) 19%, stable (B) 26%; at the median d=1405: T_A/T_rail = inf, T_B/T_rail = 0.347.
|
||||
- Sun orbits of a Sun (d 817-6367): force on (A) at 20% of the band, stable (A) 0%, stable (B) 6%; at the median d=3167: T_A/T_rail = inf, T_B/T_rail = inf.
|
||||
|
||||
Reading B mass: Sigma = k*(h"+h'/r)/(2*pi) (G=1). Positive mass 2999.36, negative (antimass) -2999.36, net M(<rim) = -0.000 (should be 0 because h'(rim)=0). Laplacian changes sign at r = 682, 2727. Core mass (r<first sign change) fraction of the antimass: 1.00.
|
||||
|
||||
## Summary by body type and mass quantile (reading A and B peaks)
|
||||
|
||||
| type | quantile | mass | support r | depth | peak slope at r | peak a_A | force switches on at r | k (B) | rail hold thrust at peak (frac of 30) |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| Planetoid | p10 | 5 | 380 | 40 | 0.3721 at 68 | 16.613 | 3.6 | 44.65 | 53.446% |
|
||||
| Planetoid | p50 | 29 | 581 | 54 | 0.3274 at 104 | 12.867 | 6.2 | 39.29 | 41.628% |
|
||||
| Planetoid | p90 | 79 | 746 | 64 | 0.3038 at 134 | 11.075 | 8.6 | 36.46 | 35.936% |
|
||||
| Planet | p10 | 120 | 827 | 69 | 0.2946 at 149 | 10.412 | 9.8 | 35.35 | 33.820% |
|
||||
| Planet | p50 | 274 | 1017 | 80 | 0.2768 at 183 | 9.197 | 12.8 | 33.22 | 29.935% |
|
||||
| Planet | p90 | 760 | 1312 | 96 | 0.2564 at 236 | 7.892 | 17.8 | 30.77 | 25.748% |
|
||||
| GasGiant | p10 | 1160 | 1459 | 103 | 0.2484 at 262 | 7.406 | 20.5 | 29.81 | 24.185% |
|
||||
| GasGiant | p50 | 2260 | 1724 | 116 | 0.2363 at 310 | 6.701 | 25.5 | 28.36 | 21.912% |
|
||||
| GasGiant | p90 | 4263 | 2020 | 130 | 0.2253 at 363 | 6.093 | 31.3 | 27.04 | 19.947% |
|
||||
| Sun | p10 | 6163 | 2215 | 138 | 0.2192 at 398 | 5.765 | 35.3 | 26.30 | 18.886% |
|
||||
| Sun | p50 | 14152 | 2727 | 160 | 0.2059 at 490 | 5.089 | 46.2 | 24.71 | 16.695% |
|
||||
| Sun | p90 | 284099 | 5772 | 270 | 0.1644 at 1037 | 3.245 | 122.8 | 19.73 | 10.691% |
|
||||
|
||||
Ship scale (catalog, tests/ships.csv): thrust is Thruster.Thrust/Entity.Mass per second (Thruster.cs:121). Longinus (mass 2500, TopSpeed 100) with a Small Drive (thrust 60000..90000) = 24..36 u/s^2; Djinni (mass 10000, TopSpeed 50) = 6..9. A_SHIP = 30 used above. Gravity peaks are 0.01-3 u/s^2.
|
||||
|
||||
## Zone bowl
|
||||
|
||||
h_bowl = -64*(1-(r/Rz)^2)^2, slope = 256*u*(1-u^2)/Rz with u = r/Rz, max 98.5/Rz at u = 0.577. Gate needs slope > 0.0316, i.e. Rz < 3117 for the bowl to push at all.
|
||||
|
||||
| pack radius Rz | peak slope | peak a_A (real code) | real code max force | force on over | centre-of-zone T_A at 0.5Rz | note |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 1000 | 0.0985 | 1.1651 | 1.1646 | 126-931 | 133.6 | zone radius range is 1000..10000 (ZoneRadius) |
|
||||
| 2500 | 0.0394 | 0.1864 | 0.1866 | 882-1939 | 528.1 | |
|
||||
| 5000 | 0.0197 | 0.0000 | 0.0000 | never | inf | |
|
||||
| 10000 | 0.0099 | 0.0000 | 0.0000 | never | inf | |
|
||||
|
||||
Sun p50 (support 2727) in a zone of radius 1000, bowl centred on the sun (the generator puts the root body at the origin): bowl adds +2.328 u/s^2 on average over r=300..1500 (well alone 2.080); T_A at r=1000: well alone 230 s, with bowl 230 s (rail 1000 s).
|
||||
Sun p50 (support 2727) in a zone of radius 2000, bowl centred on the sun (the generator puts the root body at the origin): bowl adds +1.158 u/s^2 on average over r=300..1500 (well alone 2.080); T_A at r=1000: well alone 230 s, with bowl 143 s (rail 1000 s).
|
||||
Sun p50 (support 2727) in a zone of radius 5000, bowl centred on the sun (the generator puts the root body at the origin): bowl adds +0.182 u/s^2 on average over r=300..1500 (well alone 2.080); T_A at r=1000: well alone 230 s, with bowl 205 s (rail 1000 s).
|
||||
|
||||
Bowl as reading B mass: laplacian of -64(1-u^2)^2 = 64*(...) is positive at the centre and negative near the rim, same antimass-ring signature (see fig_bowl.png).
|
||||
|
||||
## Inverse: the well that makes OrbitPeriod exact (T = r)
|
||||
|
||||
A: h'(r) = 2*pi*sqrt(r)/(sqrt(S*R)*T) = 2*pi/(sqrt(120)*sqrt(r)) = 0.5736/sqrt(r); h = 1.1471*sqrt(r) (cusp at the centre, slope infinite at r=0). a = S*R*h'^2 = 4*pi^2/r exactly. Stable for any T growing slower than r^2: T=r qualifies everywhere. The force gate zeroes the field once h' < 0.0316, i.e. beyond r = 329 u, so the exact well cannot be realised past that radius with the gate in place (a rail at 1000 u would need slope 0.0181).
|
||||
|
||||
| type (p50) | rim (support) | today's depth | derived A depth (rim to centre) | derived B depth (rim to body radius) | k |
|
||||
|---|---|---|---|---|---|
|
||||
| Planetoid | 581 | 54.1 | 27.0 | 4.4 | 39.29 |
|
||||
| Planet | 1017 | 80.1 | 35.8 | 5.2 | 33.22 |
|
||||
| GasGiant | 1724 | 115.9 | 46.6 | 6.1 | 28.36 |
|
||||
| Sun | 2727 | 159.8 | 58.6 | 7.0 | 24.71 |
|
||||
|
||||
B: h'(r) = 4*pi^2*r/(k*T^2) = 4*pi^2/(k*r), h = (4*pi^2/k) ln r, laplacian = 0 everywhere except r=0: a single point mass (2D Newton: a = 2*G*M/r, M = r*a/2 = 2*pi^2 in G=1 units, independent of r).
|
||||
|
||||
## Reading B comparisons: point mass, uniform disc
|
||||
|
||||
2D gravity (Gauss law in the plane): a(r) = 2*G*M(<r)/r. Point mass: a = c/r, v = const = sqrt(c), T = 2*pi*r/v ~ r (flat rotation curve). OrbitPeriod is Exponent=1, Multiplier=1, i.e. T=d^1: exactly the 2D point mass with c = 4*pi^2 (v = 2*pi u/s). Generalising, OrbitPeriod exponent E gives a ~ r^(1-2E): E=1 is the 2D point mass (1/r), E=1.5 would be 3D Kepler (1/r^2), E=0 is a rigid-rotation disc interior (a ~ r, T const).
|
||||
|
||||
Uniform disc of radius 1017 (the Planet p50 support) in B, with core period fixed to the rail at the median planet-around-sun distance (610 u): a = Omega^2*r inside (Omega = 2*pi/610), T constant = 610 s inside; point-mass tail outside, T = 610*(r/1017) s beyond r=1017. Height: parabola h = (Omega^2/(2k))(r^2 - rs^2) inside, log outside; the potential never returns to flat (log), unlike today's wells which are exactly flat beyond the rim (zero net mass). A point mass has an unbounded log well; today's well is bounded and mass-neutral.
|
||||
|
||||
Today's p50 Planet core (r << rim): h ≈ -D + D*e*(2/Rg)^2*r^2 -> h" = 0.002478, h'/r = h"; so near the centre laplacian = 2h" = 0.004957 > 0: positive density, rigid-rotation core in B (T = 2*pi/sqrt(k*h") = 22 s), not a point mass.
|
||||
170
docs/research/2026-10-13-orbit-probe/summary.json
Normal file
170
docs/research/2026-10-13-orbit-probe/summary.json
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
{
|
||||
"Planetoid_p10": {
|
||||
"mass": 5.3146176,
|
||||
"Rg": 759.1682,
|
||||
"rs": 379.5841,
|
||||
"D": 40.18638,
|
||||
"peakA": 16.613000611854176,
|
||||
"peakS": 0.37207750773924975,
|
||||
"k": 44.64930092870997,
|
||||
"r_gate_lo": 3.558512444744369,
|
||||
"r_peak": 68.1716004592736
|
||||
},
|
||||
"Planetoid_p50": {
|
||||
"mass": 29.198189,
|
||||
"Rg": 1162.2751,
|
||||
"rs": 581.13755,
|
||||
"D": 54.145023,
|
||||
"peakA": 12.866651604363554,
|
||||
"peakS": 0.3274478534103249,
|
||||
"k": 39.29374240923899,
|
||||
"r_gate_lo": 6.188960902199118,
|
||||
"r_peak": 104.36969533360629,
|
||||
"Mpos": 1616.1477969176299,
|
||||
"Mneg": -1616.1478040094987,
|
||||
"signs": [
|
||||
145.26985906125003,
|
||||
581.1230215612501
|
||||
],
|
||||
"depthA": 27.035684547300516,
|
||||
"depthB": 4.429937896586987,
|
||||
"gateA": 329.3765522352187
|
||||
},
|
||||
"Planetoid_p90": {
|
||||
"mass": 79.32431,
|
||||
"Rg": 1492.1813,
|
||||
"rs": 746.09065,
|
||||
"D": 64.493706,
|
||||
"peakA": 11.075358805802322,
|
||||
"peakS": 0.30380035667362104,
|
||||
"k": 36.456042800834524,
|
||||
"r_gate_lo": 8.561177101280407,
|
||||
"r_peak": 133.99453164186735
|
||||
},
|
||||
"Planet_p10": {
|
||||
"mass": 119.75782,
|
||||
"Rg": 1654.0399,
|
||||
"rs": 827.01995,
|
||||
"D": 69.31455,
|
||||
"peakA": 10.411736699763738,
|
||||
"peakS": 0.2945580969826346,
|
||||
"k": 35.34697163791615,
|
||||
"r_gate_lo": 9.779267448665717,
|
||||
"r_peak": 148.52907064138995
|
||||
},
|
||||
"Planet_p50": {
|
||||
"mass": 273.8736,
|
||||
"Rg": 2034.0309,
|
||||
"rs": 1017.01545,
|
||||
"D": 80.11107,
|
||||
"peakA": 9.196790562250865,
|
||||
"peakS": 0.27683916152179505,
|
||||
"k": 33.22069938261541,
|
||||
"r_gate_lo": 12.814075573425148,
|
||||
"r_peak": 182.65140957776777,
|
||||
"Mpos": 2021.6242659634618,
|
||||
"Mneg": -2021.6242748346144,
|
||||
"signs": [
|
||||
254.25386249999997,
|
||||
1016.9900246137499
|
||||
],
|
||||
"depthA": 35.76528389155362,
|
||||
"depthB": 5.239770439285403,
|
||||
"gateA": 329.3765522352187
|
||||
},
|
||||
"Planet_p90": {
|
||||
"mass": 759.5583,
|
||||
"Rg": 2624.885,
|
||||
"rs": 1312.4425,
|
||||
"D": 95.767784,
|
||||
"peakA": 7.891955693897595,
|
||||
"peakS": 0.25644940524233356,
|
||||
"k": 30.77392862908003,
|
||||
"r_gate_lo": 17.848773398988104,
|
||||
"r_peak": 235.70878162644382
|
||||
},
|
||||
"GasGiant_p10": {
|
||||
"mass": 1160.0167,
|
||||
"Rg": 2918.0051,
|
||||
"rs": 1459.00255,
|
||||
"D": 103.13415,
|
||||
"peakA": 7.406264502379473,
|
||||
"peakS": 0.24843282966057903,
|
||||
"k": 29.811939559269483,
|
||||
"r_gate_lo": 20.498475163840908,
|
||||
"r_peak": 262.03030871857214
|
||||
},
|
||||
"GasGiant_p50": {
|
||||
"mass": 2259.8394,
|
||||
"Rg": 3447.382,
|
||||
"rs": 1723.691,
|
||||
"D": 115.90037,
|
||||
"peakA": 6.701270510950089,
|
||||
"peakS": 0.23631318398384818,
|
||||
"k": 28.35758207806178,
|
||||
"r_gate_lo": 25.466899975386884,
|
||||
"r_peak": 309.56716618858843,
|
||||
"Mpos": 2496.6240996325446,
|
||||
"Mneg": -2496.624110588059,
|
||||
"signs": [
|
||||
430.92275,
|
||||
1723.6479077249999
|
||||
],
|
||||
"depthA": 46.56156920884126,
|
||||
"depthB": 6.138352632401603,
|
||||
"gateA": 329.3765522352187
|
||||
},
|
||||
"GasGiant_p90": {
|
||||
"mass": 4262.56,
|
||||
"Rg": 4040.058,
|
||||
"rs": 2020.029,
|
||||
"D": 129.51306,
|
||||
"peakA": 6.092818670716137,
|
||||
"peakS": 0.22532973377393956,
|
||||
"k": 27.039568052872745,
|
||||
"r_gate_lo": 31.309669244292355,
|
||||
"r_peak": 362.78814076813546
|
||||
},
|
||||
"Sun_p10": {
|
||||
"mass": 6163.2734,
|
||||
"Rg": 4430.1953,
|
||||
"rs": 2215.09765,
|
||||
"D": 138.14598,
|
||||
"peakA": 5.764970420162093,
|
||||
"peakS": 0.2191835307864563,
|
||||
"k": 26.302023694374757,
|
||||
"r_gate_lo": 35.27455093739169,
|
||||
"r_peak": 397.8215946718419
|
||||
},
|
||||
"Sun_p50": {
|
||||
"mass": 14152.431,
|
||||
"Rg": 5453.531,
|
||||
"rs": 2726.7655,
|
||||
"D": 159.7779,
|
||||
"peakA": 5.089137317417582,
|
||||
"peakS": 0.20593561529066923,
|
||||
"k": 24.712273834880307,
|
||||
"r_gate_lo": 46.217523137774066,
|
||||
"r_peak": 489.71484372535997,
|
||||
"Mpos": 2999.3597195423154,
|
||||
"Mneg": -2999.359732703899,
|
||||
"signs": [
|
||||
681.6232058625001,
|
||||
2726.6973308625
|
||||
],
|
||||
"depthA": 58.56279509678064,
|
||||
"depthB": 7.043821210483852,
|
||||
"gateA": 329.3765522352187
|
||||
},
|
||||
"Sun_p90": {
|
||||
"mass": 284098.97,
|
||||
"Rg": 11543.498,
|
||||
"rs": 5771.749,
|
||||
"D": 270.0713,
|
||||
"peakA": 3.245251279883395,
|
||||
"peakS": 0.16444987280534745,
|
||||
"k": 19.733984736641695,
|
||||
"r_gate_lo": 122.7908972641191,
|
||||
"r_peak": 1036.5802118139616
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue