worldorbit 2.5.12 → 2.5.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "worldorbit",
3
- "version": "2.5.12",
3
+ "version": "2.5.13",
4
4
  "description": "A text-based DSL and parser pipeline for orbital worldbuilding",
5
5
  "type": "module",
6
6
  "main": "./dist/unpkg/worldorbit.esm.js",
@@ -837,8 +837,9 @@ function placeOrbitingChildren(object, positions, orbitDrafts, leaderDrafts, con
837
837
  }
838
838
  const orbiting = [...(context.orbitChildren.get(object.id) ?? [])].sort(compareOrbiting);
839
839
  const orbitMetricContext = computeOrbitMetricContext(orbiting, parent.radius, context.spacingFactor, context.scaleModel);
840
+ const orbitRadiiPx = resolveOrbitRadiiPx(orbiting, orbitMetricContext);
840
841
  orbiting.forEach((child, index) => {
841
- const orbitGeometry = resolveOrbitGeometry(child, index, orbiting.length, parent, orbitMetricContext, context);
842
+ const orbitGeometry = resolveOrbitGeometry(child, index, orbiting.length, parent, orbitMetricContext, orbitRadiiPx[index] ?? orbitMetricContext.innerPx, context);
842
843
  orbitDrafts.push({
843
844
  object: child,
844
845
  parentId: object.id,
@@ -913,6 +914,7 @@ function computeOrbitMetricContext(objects, parentRadius, spacingFactor, scaleMo
913
914
  innerPx,
914
915
  stepPx,
915
916
  pixelSpread: Math.max(stepPx * Math.max(objects.length - 1, 1), stepPx),
917
+ minimumGapPx: stepPx * 0.42,
916
918
  };
917
919
  }
918
920
  const minMetric = Math.min(...presentMetrics);
@@ -926,9 +928,10 @@ function computeOrbitMetricContext(objects, parentRadius, spacingFactor, scaleMo
926
928
  innerPx,
927
929
  stepPx,
928
930
  pixelSpread: Math.max(stepPx * Math.max(objects.length - 1, 1), stepPx),
931
+ minimumGapPx: stepPx * 0.42,
929
932
  };
930
933
  }
931
- function resolveOrbitGeometry(object, index, count, parent, metricContext, context) {
934
+ function resolveOrbitGeometry(object, index, count, parent, metricContext, orbitRadiusPx, context) {
932
935
  const placement = object.placement;
933
936
  const band = object.type === "belt" || object.type === "ring";
934
937
  if (!placement || placement.mode !== "orbit") {
@@ -948,7 +951,7 @@ function resolveOrbitGeometry(object, index, count, parent, metricContext, conte
948
951
  };
949
952
  }
950
953
  const eccentricity = clampNumber(typeof placement.eccentricity === "number" ? placement.eccentricity : 0, 0, 0.92);
951
- const semiMajor = resolveOrbitRadiusPx(object, index, metricContext);
954
+ const semiMajor = orbitRadiusPx;
952
955
  const baseMinor = Math.max(semiMajor * Math.sqrt(1 - eccentricity * eccentricity), semiMajor * 0.18);
953
956
  const inclinationDeg = unitValueToDegrees(placement.inclination) ?? 0;
954
957
  const inclinationScale = context.projection === "isometric"
@@ -989,17 +992,23 @@ function resolveOrbitGeometry(object, index, count, parent, metricContext, conte
989
992
  objectY: objectPoint.y,
990
993
  };
991
994
  }
992
- function resolveOrbitRadiusPx(object, index, metricContext) {
993
- const metric = orbitMetric(object);
994
- if (metric === null) {
995
- return metricContext.innerPx + index * metricContext.stepPx;
996
- }
997
- if (metricContext.metricSpread > 0) {
998
- return (metricContext.innerPx +
999
- ((metric - metricContext.minMetric) / metricContext.metricSpread) *
1000
- metricContext.pixelSpread);
1001
- }
1002
- return metricContext.innerPx + Math.log10(metric + 1) * metricContext.stepPx;
995
+ function resolveOrbitRadiusPx(metric, metricContext) {
996
+ return metricContext.innerPx + metricContext.stepPx * log2(Math.max(metric, 0) + 1);
997
+ }
998
+ function resolveOrbitRadiiPx(objects, metricContext) {
999
+ const radii = [];
1000
+ objects.forEach((object, index) => {
1001
+ const metric = orbitMetric(object);
1002
+ const fallbackRadius = metricContext.innerPx + index * metricContext.stepPx;
1003
+ const baseRadius = metric === null
1004
+ ? fallbackRadius
1005
+ : resolveOrbitRadiusPx(metric, metricContext);
1006
+ const minimumRadius = index === 0
1007
+ ? metricContext.innerPx
1008
+ : (radii[index - 1] ?? metricContext.innerPx) + metricContext.minimumGapPx;
1009
+ radii.push(Math.max(baseRadius, minimumRadius));
1010
+ });
1011
+ return radii;
1003
1012
  }
1004
1013
  function orbitMetric(object) {
1005
1014
  if (!object.placement || object.placement.mode !== "orbit") {
@@ -1007,6 +1016,9 @@ function orbitMetric(object) {
1007
1016
  }
1008
1017
  return toDistanceMetric(object.placement.semiMajor ?? object.placement.distance ?? null);
1009
1018
  }
1019
+ function log2(value) {
1020
+ return Math.log(value) / Math.log(2);
1021
+ }
1010
1022
  function resolveOrbitPhase(phase, index, count) {
1011
1023
  const degreeValue = phase ? unitValueToDegrees(phase) : null;
1012
1024
  if (degreeValue !== null) {