@johnmorrisdotca/wakusei-planets 0.7.0 → 0.11.1

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.
Files changed (49) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/NOTICE.md +16 -1
  3. package/README.md +6 -6
  4. package/dist/bodies/all.d.ts +2 -0
  5. package/dist/bodies/all.js +2 -0
  6. package/dist/bodies/dwarfs.d.ts +1 -0
  7. package/dist/bodies/dwarfs.js +32 -0
  8. package/dist/bodies/moons-dwarf.d.ts +1 -0
  9. package/dist/bodies/moons-dwarf.js +6 -0
  10. package/dist/bodies/moons-neptune.js +1 -0
  11. package/dist/bodies/moons-pluto.js +1 -1
  12. package/dist/bodies/moons-saturn.js +3 -2
  13. package/dist/data/dwarf.d.ts +16 -0
  14. package/dist/data/dwarf.js +24 -0
  15. package/dist/data/orbits.d.ts +2 -2
  16. package/dist/data/orbits.js +4 -0
  17. package/dist/element.d.ts +4 -2
  18. package/dist/element.js +4 -0
  19. package/dist/embed.d.ts +1 -1
  20. package/dist/embed.js +5 -3
  21. package/dist/ephemeris.d.ts +6 -6
  22. package/dist/ephemeris.js +33 -12
  23. package/dist/facts.d.ts +44 -6
  24. package/dist/facts.js +32 -3
  25. package/dist/index.d.ts +1 -1
  26. package/dist/index.js +1 -1
  27. package/dist/line.js +7 -4
  28. package/dist/portrait/model.d.ts +2 -2
  29. package/dist/portrait/model.js +138 -5
  30. package/dist/portrait/overlay.js +2 -1
  31. package/dist/pose.d.ts +7 -5
  32. package/dist/pose.js +25 -11
  33. package/dist/scene/glsl.d.ts +2 -2
  34. package/dist/scene/glsl.js +10 -6
  35. package/dist/textures/ceres-1024.webp +0 -0
  36. package/dist/textures/ceres-512.webp +0 -0
  37. package/dist/textures/charon-1024.webp +0 -0
  38. package/dist/textures/charon-512.webp +0 -0
  39. package/dist/textures/dione-1024.webp +0 -0
  40. package/dist/textures/dione-512.webp +0 -0
  41. package/dist/textures/iapetus-1024.webp +0 -0
  42. package/dist/textures/iapetus-512.webp +0 -0
  43. package/dist/textures/tethys-1024.webp +0 -0
  44. package/dist/textures/tethys-512.webp +0 -0
  45. package/dist/textures/triton-1024.webp +0 -0
  46. package/dist/textures/triton-512.webp +0 -0
  47. package/dist/version.d.ts +1 -1
  48. package/dist/version.js +1 -1
  49. package/package.json +11 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.11.1 - 2026-11-03
4
+
5
+ The dwarf planets' realistic look is smooth when it is small (MODULES-332).
6
+
7
+ - **No more pixel-sized specks on a small body.** At about 80 px (the portrait builder) Ceres, Orcus, Quaoar, Makemake, Gonggong and Sedna showed square dark specks: the craters and the fine noise were finer than a pixel and were sampled anyway. The shader now knows how big a pixel is: an octave of noise finer than the pixel is replaced by its average, a crater smaller than about two pixels fades out, a crater's rim no longer starts with a step (which a pixel could not draw), and the bump-mapped relief, which is worked out from neighbouring pixels and cannot show a bump a few pixels wide, fades out on a small disc so the colour alone carries the craters. Compared at 64, 128 and 512 px, light and dark: soft craters at every size, the same look as before at 512. All the realistic bodies share the shader, so Mercury, the Moon and the rest are smoother when small too. Test: a realistic dwarf planet at 64, 80 and 128 px has under 0.4 in a thousand speck pixels (the old shader had 17 in a thousand at 64 px).
8
+ - **Ceres looks like Ceres in the realistic look** (it uses Dawn's map as the painted look does, with Occator's bright spots), not a generic cratered ball.
9
+ - **Triton's filled north is soft**: the unseen north of the map (a fill made by `scripts/make-textures.py`) took the dark ground at its edge and smeared it into blobs with a hard line at the seam; it now fades gradually from the real picture's colour to the map's mean, over a long smooth band.
10
+ ## 0.11.0 - 2026-11-03
11
+
12
+ The drag rule, checked with the family's own check.
13
+
14
+ - **The surface follows the pointer, exactly** (MODULES-224): the demo tells the shared view controls the radius of the body's disc (`grab-radius`, kept up to date as the view is resized or scaled), so a drag of a few pixels moves the ground at the middle of the body by as many pixels, and the touched point stays under the pointer. New `discRadius` on `<wakusei-body>` (the disc's radius on the screen, in CSS pixels).
15
+ - **The check** is kazoku-ui's shared `e2e/ground.mjs` (copied unchanged from its `templates/e2e-ground.mjs`): in Mars (line, realistic and painted), Venus and the Moon a drag right moves the ground right, a drag up moves it up, the arrow keys agree and Auto-turn goes the right way; exact grab is checked in painted Mars and the Moon.
16
+ - **The documentation site is the family's of 2026-11-03** (MODULES-331): a seeded sample of its pages is read in the browser, and the guides show their pictures as real images (`![..](../images/..)`) instead of links, in English and Japanese.
17
+ - The freeze test that counts what the page keeps now counts after two rounds of changes, not one: on a slow runner the first round was still making the rows' pictures, so the count rose once and then stayed flat (24, 24, 24 with the processor slowed four times); a real leak would keep rising.
18
+ - **The Turn button goes the body's real way** (MODULES-203): Mars turns to the right and Venus, which turns backwards, to the left (it turned every body the same way before); a test per direction.
19
+
20
+ ## 0.10.0 - 2026-11-03
21
+
22
+ Painted maps for five more moons.
23
+
24
+ - **Tethys, Dione, Iapetus, Triton and Charon are painted** (MODULES-220), from public-domain maps: Cassini's global colour maps of Tethys, Dione and Iapetus (Paul Schenk, PIA18439, PIA18434, PIA18436), Voyager 2's global colour mosaic of Triton (PIA18668) and New Horizons' global map of Charon. Every source file is public domain by its Wikimedia Commons file page, and `NOTICE.md` has each one's credit and what was done to it, including where the map was centred (turned to match known features: Tethys's crater Odysseus, Iapetus's dark Cassini Regio; Triton's centre is from the USGS label of the same mosaic) and the unmapped north of Triton and south of Charon, which are continued smoothly from the real rows.
25
+ - The pictures add 0.45 MB to the package (the 512 and 1024 pixel widths; the 2048 ones are fetched when a view is zoomed in), which makes the pictures 1.94 MB; the test that holds their size now allows 2 MB.
26
+
27
+ ## 0.9.0 - 2026-11-03
28
+
29
+ The other dwarf planets.
30
+
31
+ - **Ceres, Orcus, Haumea, Quaoar, Makemake, Gonggong, Eris and Sedna** (MODULES-232), in the line, realistic and painted looks (`DWARF_IDS`, `DwarfId`, `BODIES.eris`...), and the moons whose orbits are published with a date: **Vanth** (Orcus), **Hiʻiaka and Namaka** (Haumea) and **Dysnomia** (Eris). Weywot, Xiangliu and S/2015 (136472) 1 are left out: no orbit with a published phase exists.
32
+ - **Where they are**: `heliocentric()` takes a dwarf planet too, from JPL's Small-Body Database osculating elements of June 2026, run as a plain ellipse. Against JPL Horizons on 2026-11-03 all five checked are within 0.0002 au (a test holds it). The moons' orbits are from Holler et al. 2021 (Dysnomia), Ragozzine & Brown 2009 (Hiʻiaka, Namaka) and Brown et al. 2010 (Vanth); `NOTICE.md` has the sources and says which numbers are estimates (poles that have not been measured are taken along the orbit's pole; the shaded surfaces other than Ceres's are drawn from colours alone).
33
+ - **Haumea and Quaoar are long shapes** (1161 x 852 x 513 km, turning every 3.9 hours; 1241 x 1093 x 1023 km): the line look now draws the outline of a body with `axesKm` as the ellipse it really shows, and its features on that shape (Phobos, Deimos, Proteus, Nix and Hydra too).
34
+ - **Ceres is painted** from Dawn's colourised global map (public domain; the incomplete colour at high latitudes is made the surface's own grey).
35
+ - **The picker has three groups** (MODULES-204): the Sun and the planets, the dwarf planets and the well-known moons (the Moon, Phobos, Deimos, Io, Europa, Ganymede, Callisto, Enceladus, Titan, Triton, Charon), each a click away; the group follows the body chosen and the address keeps the choice. The portrait builder and the code builder have a dwarf planets group too.
36
+ - **Tests that every body turns about its real axis the right way** (MODULES-203): the rotation rate matches the period, and the spin axis of each planet and dwarf planet makes the published axial tilt with its orbit's pole, backwards for Venus, Uranus and Pluto.
37
+ - New entry points `@johnmorrisdotca/wakusei-planets/dwarfs` and `/moons-dwarf`; `/all` has both. `DWARF_IDS`, `DwarfId` and `HostId` (a planet or dwarf planet a moon can go round) are exported; `BODIES` and `BODY_IDS` have 12 more bodies, and the Portrait builder's order puts the dwarf planets after Pluto.
38
+ - The painted pictures of Ceres add 0.13 MB to the package (512 and 1024 pixels wide).
39
+
40
+ ## 0.8.0 - 2026-11-03
41
+
42
+ The portrait builder at true orbit distance.
43
+
44
+ - **True orbit distance** (MODULES-283): a fourth arrangement beside row, arc and grid. Each moon is as far from its planet, and each planet from the Sun, as it really is, with the orbits drawn as circles, and the view backed off to hold them all. With a date set, every body is where it is then, seen from above the ecliptic; with none, they are lined up from the Sun along one side. `arrange: "orbit"` in the scene, `?scene=arrange:orbit~...` in the address.
45
+ - **A link from the demo** ("At true orbit distance", under the buttons that show bodies together) opens the same bodies in the portrait builder at true orbit distance, in the look that is chosen.
46
+
3
47
  ## 0.7.0 - 2026-11-03
4
48
 
5
49
  The portrait builder: any bodies, one picture.
package/NOTICE.md CHANGED
@@ -11,6 +11,15 @@ No picture is used by the line and shaded looks: they are drawn from numbers.
11
11
  - **Moons' orbits**: JPL Solar System Dynamics, "Planetary Satellite Mean Elements" (https://ssd.jpl.nasa.gov/sats/elem/, read 2026-11-02), made into `src/data/orbits.ts` by `scripts/make-moon-data.py`. Credit: NASA/JPL-Caltech; the elements are from R. A. Jacobson and colleagues' ephemerides cited on that page.
12
12
  - **The Moon's position**: the largest terms of the series in Jean Meeus, "Astronomical Algorithms" (2nd edition), chapter 47, written out here as numbers; the mean arguments are the standard ones.
13
13
 
14
+ ## The dwarf planets
15
+
16
+ Ceres, Orcus, Haumea, Quaoar, Makemake, Gonggong, Eris and Sedna (Pluto is with the planets) and the moons Vanth, Hiʻiaka, Namaka and Dysnomia. Values read on 2026-11-03.
17
+
18
+ - **Where they are**: NASA/JPL Small-Body Database, osculating elements at JD 2461200.5 (https://ssd.jpl.nasa.gov/api/sbdb.api), run as a plain ellipse (`src/data/dwarf.ts`): good for a few years either side of June 2026, and Ceres, pulled by Jupiter, drifts most.
19
+ - **Sizes and spin**: Ceres (966.2 x 962.0 x 891.8 km) and its pole: Ermakov et al. 2017 (as listed in Wikipedia's Ceres article); its rotation: JPL SBDB (9.074170 h). Haumea: Ortiz et al. 2017, Nature 550:219 (semi-axes 1161 x 852 x 513 km), rotation 3.915341 h from Santos-Sanz et al. 2017, A&A 604:A95, pole from Kondratyev & Kornoukhov 2018, MNRAS 478:3159 (RA 282.6, Dec -13.0). Eris: radius 1163 km, Sicardy et al. 2011; it keeps one face to Dysnomia, so its rotation is Dysnomia's orbital period, Szakats et al. 2023, A&A 669:L3. Makemake: radius 715 km, Brown 2013; rotation 22.8266 h, Hromakina et al. 2019. Gonggong: radius 615 km and rotation 22.4 h, Kiss et al. 2019, Icarus. Quaoar: 1241.4 x 1093.0 x 1023.0 km and 17.6788 h, Margoti et al. 2026 and Pereira et al. 2023. Sedna: radius 453 km (Lellouch et al. 2013, TNOs are Cool IX, which allows far more) and 10.273 h, Gaudi et al. 2005. Orcus: radius 455 km, Brown & Butler 2018, rotation 13.188 h (JPL SBDB; 7 to 21 h in the literature). Wikipedia's articles on each body were the finding aid; the papers are the sources.
20
+ - **Moons' orbits**: Dysnomia, Holler et al. 2021, Icarus 355:114130, Table 2 (arXiv 2009.13733). Hiʻiaka and Namaka, Ragozzine & Brown 2009, AJ 137:4766, Table 2 (osculating elements of 2008; the two moons pull on each other, so the position years later is rough). Vanth, Brown et al. 2010, AJ 139:2700, Table 2, solution 1 of two mirror solutions. Radii: Dysnomia 308 km (Brown & Butler 2023), Vanth 221 km (Sickafoose et al. 2018, occultation), Hiʻiaka and Namaka from the Haumea article's listed diameters (370 and 150 km). Weywot, Xiangliu and Makemake's moon S/2015 (136472) 1 are left out: no orbit with a published phase.
21
+ - **Estimated, not measured** (the pictures say so only here): these bodies' poles are not measured, so each is drawn with its spin axis along its orbit's pole (Quaoar, Makemake, Gonggong, Sedna), along Dysnomia's orbit pole (Eris) or along the far end of Vanth's orbit pole, so that it spins forwards (Orcus). Hiʻiaka's and Namaka's spin is unknown and they are drawn still. Dysnomia and Vanth are assumed to keep one face to their planet. Every drawn feature on the line look of a dwarf planet except Ceres's Occator crater and Haumea's long axis is a generic crater, and so is each shaded (realistic) look: only the colour (from the published colour indices and albedos) and the sizes are from numbers. Ceres, Haumea and Dysnomia's shapes are from the sources above. Only Ceres has a painted look.
22
+
14
23
  The tests compare the Galilean moons and four planets with astronomy-engine (MIT, https://github.com/cosinekitty/astronomy), a development dependency that is never shipped.
15
24
 
16
25
  ## The Earth
@@ -44,6 +53,12 @@ NASA says its content "generally are not subject to copyright in the United Stat
44
53
  | `rhea-*.webp` | Rhea | [Rhea Color Map.jpg](https://commons.wikimedia.org/wiki/File:Rhea_Color_Map.jpg) | Public domain | NASA/JPL-Caltech/Space Science Institute/Lunar and Planetary Institute | Cassini global colour map (PIA18438), turned half way round so longitude 0 is in the middle (the source does not say where it is centred; the dark trailing side is put at 90 degrees east); the colours are false-colour (infrared, green, ultraviolet) and are turned about half way to grey |
45
54
  | `enceladus-*.webp` | Enceladus | [Enceladus Color Map.jpg](https://commons.wikimedia.org/wiki/File:Enceladus_Color_Map.jpg) | Public domain | NASA/JPL-Caltech/Space Science Institute/Lunar and Planetary Institute | Cassini global colour map (PIA18435), turned half way round the same way as Rhea's (the source does not say where it is centred; the fractured trailing terrain is put at 90 degrees east); the colours are false-colour (the blue of the tiger stripes is ultraviolet) and are turned most of the way to grey |
46
55
  | `mimas-*.webp` | Mimas | [Map of Mimas 2010-02 PIA12780.jpg](https://commons.wikimedia.org/wiki/File:Map_of_Mimas_2010-02_PIA12780.jpg) | Public domain | NASA/JPL/Space Science Institute | Cassini ISS map of February 2010 (PIA12780), cropped inside its frame and labels; Herschel is at 110 degrees west as its own scale says |
56
+ | `ceres-*.webp` | Ceres | [PIA20354-Ceres-DwarfPlanet-MercatorMap-HAMO-20160322-0DegreeLongitude.jpg](https://commons.wikimedia.org/wiki/File:PIA20354-Ceres-DwarfPlanet-MercatorMap-HAMO-20160322-0DegreeLongitude.jpg) | Public domain | NASA/JPL-Caltech/UCLA/MPS/DLR/IDA | Dawn's colourised global map of Ceres (PIA20354, 140 m a pixel), longitude 0 in the middle as the file says (Occator's bright spots fall at 239 degrees east); the green and yellow high latitudes, where Dawn's colour coverage is incomplete (the map says so), are made the surface's own grey keeping their detail, and the last rows with no data repeat the nearest real ones; the colour is turned most of the way to grey |
57
+ | `tethys-*.webp` | Tethys | [Tethys Color Map.jpg](https://commons.wikimedia.org/wiki/File:Tethys_Color_Map.jpg) | Public domain | NASA/JPL-Caltech/Space Science Institute/Lunar and Planetary Institute | Cassini global colour map (PIA18439, Paul Schenk), turned half way round so longitude 0 is in the middle (the source does not say where it is centred; Odysseus, at 129 degrees west, falls at 131 degrees west and the dark trailing side at 90 degrees east); the colours are enhanced (ultraviolet to infrared) and are turned about half way to grey |
58
+ | `dione-*.webp` | Dione | [Dione Color Map.jpg](https://commons.wikimedia.org/wiki/File:Dione_Color_Map.jpg) | Public domain | NASA/JPL-Caltech/Space Science Institute/Lunar and Planetary Institute | Cassini global colour map (PIA18434), turned half way round the same way as Tethys's (the source does not say where it is centred; the dark trailing side with its wispy fractures is put at 90 degrees east); the colours are enhanced and are turned about half way to grey |
59
+ | `iapetus-*.webp` | Iapetus | [Iapetus Color Map.jpg](https://commons.wikimedia.org/wiki/File:Iapetus_Color_Map.jpg) | Public domain | NASA/JPL-Caltech/Space Science Institute/Lunar and Planetary Institute | Cassini global colour map (PIA18436), turned half way round the same way (the source does not say where it is centred; the dark leading side, Cassini Regio, is put at 270 degrees east, 90 degrees west); the colours are enhanced and are turned a third of the way to grey |
60
+ | `triton-*.webp` | Triton | [Triton map no grid.jpg](https://commons.wikimedia.org/wiki/File:Triton_map_no_grid.jpg) | Public domain | NASA/JPL-Caltech/Lunar & Planetary Institute (Paul Schenk; Voyager 2 images) | Voyager 2 global colour mosaic (PIA18668, 600 m a pixel, enhanced colour), as it is: USGS Astrogeology's label of the same mosaic (14138 samples wide) says the map is centred on longitude 0, east positive. Voyager never saw the north (it was in winter's dark), so the black there is continued smoothly from the colour just inside it and fades to the mean colour; the colours are turned a little under half way to grey |
61
+ | `charon-*.webp` | Charon | [Charon map iau1803c.jpg](https://commons.wikimedia.org/wiki/File:Charon_map_iau1803c.jpg) | Public domain | NASA/Johns Hopkins University Applied Physics Laboratory/Southwest Research Institute (via the IAU) | New Horizons global map of Charon (iau1803c, no labels or grid), as it is, with longitude 0 in the middle (the source does not say; the sharp hemisphere New Horizons saw best is the one that faces Pluto, which is longitude 0); the south, in the polar night New Horizons never saw, is continued from the last real rows and fades to the mean grey |
47
62
  | `saturn-ring-2048.webp` | Saturn's rings | [Saturn's rings in visible light and radio.jpg](https://commons.wikimedia.org/wiki/File:Saturn's_rings_in_visible_light_and_radio.jpg) | Public domain | NASA / JPL / Space Science Institute | Cassini's natural-colour mosaic of the lit rings (PIA07874, from PIA06175), read along one radius into a strip of 2048 colours and opacities from 74,794 to 137,035 km. The radii are fitted to five edges the picture shows (the B ring's inner edge, the two edges of the Cassini Division, the Encke gap and the A ring's outer edge), each within 300 km. The opacity is taken from the brightness, and the colour balance is moved to match the Saturn portrait above; the F ring and the D ring are not in the picture |
48
63
 
49
- The package does not ship the 2048 pixel widths: `TEXTURE_FAR_BASE` fetches them from this repository by jsDelivr's GitHub address when a view is zoomed in. The 512 and 1024 pixel widths of every picture, and the ring strip, are 1.31 MB in the package (the nine of 0.2.0 were 0.53 MB). Tethys, Dione, Iapetus, Triton and Charon have no picture: Cassini's maps of the first three are not made yet, the source of Triton's map does not give its longitudes, and the only clean public-domain map of Charon is under a grid of labels, so those five keep their drawn look.
64
+ The package does not ship the 2048 pixel widths: `TEXTURE_FAR_BASE` fetches them from this repository by jsDelivr's GitHub address when a view is zoomed in. The 512 and 1024 pixel widths of every picture, and the ring strip, are 1.94 MB in the package (the nine of 0.2.0 were 0.53 MB; Ceres adds 0.13 MB and Tethys, Dione, Iapetus, Triton and Charon 0.45 MB). Where a source does not say where its map is centred, its row says what the picture was matched to.
package/README.md CHANGED
@@ -13,9 +13,9 @@ A clean line drawing, a shaded realistic drawing, or a painted surface map, with
13
13
 
14
14
  <p align="center"><a href="https://johnmorrisdotca.github.io/wakusei-planets/"><strong>Open the demo →</strong></a> · <a href="https://johnmorrisdotca.github.io/wakusei-planets/embed.html">Embed page</a> · <a href="https://johnmorrisdotca.github.io/wakusei-planets/docs/">Docs</a></p>
15
15
 
16
- <p align="center"><img alt="Jupiter and Saturn drawn in the realistic look, and Saturn as a line drawing" src="https://raw.githubusercontent.com/johnmorrisdotca/wakusei-planets/v0.7.0/docs/images/hero-desk.png" width="640"></p>
16
+ <p align="center"><img alt="Jupiter and Saturn drawn in the realistic look, and Saturn as a line drawing" src="https://raw.githubusercontent.com/johnmorrisdotca/wakusei-planets/v0.11.1/docs/images/hero-desk.png" width="640"></p>
17
17
 
18
- <p align="center"><img alt="Every body at one scale, the Earth among them: each small body has a magnified picture joined by a line, and the Sun shows only its edge" src="https://raw.githubusercontent.com/johnmorrisdotca/wakusei-planets/v0.7.0/docs/images/lineup-desk.png" width="640"></p>
18
+ <p align="center"><img alt="Every body at one scale, the Earth among them: each small body has a magnified picture joined by a line, and the Sun shows only its edge" src="https://raw.githubusercontent.com/johnmorrisdotca/wakusei-planets/v0.11.1/docs/images/lineup-desk.png" width="640"></p>
19
19
 
20
20
  ## One minute
21
21
 
@@ -79,7 +79,7 @@ A bundled app imports it: `import "@johnmorrisdotca/wakusei-planets/element"` (a
79
79
 
80
80
  ## Features
81
81
 
82
- - The Sun, the eight planets, Pluto and 25 moons, each with its real size, flattening, axial tilt, pole and rotation as data.
82
+ - The Sun, the eight planets, Pluto, eight more dwarf planets and 29 moons, each with its real size, flattening, axial tilt, pole and rotation as data.
83
83
  - Three looks: a clean `line` drawing (an SVG string), a shaded `realistic` sphere worked out in a shader, and a `painted` surface map from public-domain imagery.
84
84
  - The sky for any date and time: a body's pole, rotation, phase and ring opening as the Earth sees it, and a planet's moons where they are then.
85
85
  - One WebGL context for the page, nothing drawn at rest, at most thirty frames a second, and everything freed when an element leaves.
@@ -109,7 +109,7 @@ Import the element once in client code, and the entry point of each body you dra
109
109
  | `realistic` | A shaded sphere drawn from the body's real colours and features, lit from the Sun's side, with the rings casting shadows. No pictures: the surface is worked out in a shader. | `three`, the body's entry point |
110
110
  | `painted` | A real surface map from public-domain NASA, USGS and JPL imagery. Small pictures first (1.31 MB for all of them in the package), a sharper one fetched when you zoom in. | `three`, the body's entry point |
111
111
 
112
- Every body has its real size relative to the others (`scale-to="jupiter"`), its axial tilt and its rotation. The Sun, Mercury, Venus, Mars, Jupiter, Saturn, Uranus, Neptune and Pluto are drawn, and so are 25 moons (the Moon, Phobos and Deimos, the four Galilean moons, Saturn's seven larger moons, Uranus's five, Proteus, Triton and Nereid, Charon, Nix and Hydra). The Earth is drawn like the rest in the realistic and painted looks (NASA's Blue Marble), and its line look is [chikyu-earth](https://github.com/johnmorrisdotca/chikyu-earth)'s own globe: `import "@johnmorrisdotca/wakusei-planets/earth"` (it needs `@johnmorrisdotca/chikyu-earth` 0.10.0 or later installed). The painted looks cover the Sun, the planets from Mercury to Earth and Pluto, the Moon, the four Galilean moons, Titan, Rhea, Enceladus and Mimas, and Saturn's rings are Cassini's own picture of them.
112
+ Every body has its real size relative to the others (`scale-to="jupiter"`), its axial tilt and its rotation. The Sun, Mercury, Venus, Mars, Jupiter, Saturn, Uranus, Neptune and Pluto are drawn, and so are the eight other dwarf planets (Ceres, Orcus, Haumea, Quaoar, Makemake, Gonggong, Eris and Sedna; Haumea and Quaoar as the long shapes they are, and Ceres with a painted map from Dawn) and 29 moons (the Moon, Phobos and Deimos, the four Galilean moons, Saturn's seven larger moons, Uranus's five, Proteus, Triton and Nereid, Charon, Nix and Hydra, and Vanth, Hiʻiaka, Namaka and Dysnomia, the moons of the dwarf planets whose orbits are published with a date). The Earth is drawn like the rest in the realistic and painted looks (NASA's Blue Marble), and its line look is [chikyu-earth](https://github.com/johnmorrisdotca/chikyu-earth)'s own globe: `import "@johnmorrisdotca/wakusei-planets/earth"` (it needs `@johnmorrisdotca/chikyu-earth` 0.10.0 or later installed). The painted looks cover the Sun, the planets from Mercury to Earth and Pluto, Ceres, the Moon, the four Galilean moons, Saturn's Mimas, Enceladus, Tethys, Dione, Rhea, Titan and Iapetus, Triton and Charon, and Saturn's rings are Cassini's own picture of them.
113
113
 
114
114
  ## As the Earth sees it
115
115
 
@@ -273,9 +273,9 @@ A body that turns by itself and a moving sky, in HTML:
273
273
 
274
274
  ## The portrait builder
275
275
 
276
- <p align="center"><img alt="The Sun and the planets in an arc, painted, with their names, in the portrait builder" src="https://raw.githubusercontent.com/johnmorrisdotca/wakusei-planets/v0.7.0/docs/images/portrait-family.png" width="640"></p>
276
+ <p align="center"><img alt="The Sun and the planets in an arc, painted, with their names, in the portrait builder" src="https://raw.githubusercontent.com/johnmorrisdotca/wakusei-planets/v0.11.1/docs/images/portrait-family.png" width="640"></p>
277
277
 
278
- [The portrait builder](https://johnmorrisdotca.github.io/wakusei-planets/portrait.html) puts any bodies in one picture: drag them, size them, turn them, order them front to back, arrange them in a row, an arc or a grid (true or readable sizes, a planet's moons round it in orbit order), light them from one direction, and take the code, a PNG or an SVG. The scene is kept in the address, and every body is drawn in one WebGL scene, so the page holds one WebGL context. [The portrait builder](docs/guides/portrait-builder.md) is its guide.
278
+ [The portrait builder](https://johnmorrisdotca.github.io/wakusei-planets/portrait.html) puts any bodies in one picture: drag them, size them, turn them, order them front to back, arrange them in a row, an arc, a grid or at true orbit distance (true or readable sizes, a planet's moons round it in orbit order), light them from one direction, and take the code, a PNG or an SVG. The scene is kept in the address, and every body is drawn in one WebGL scene, so the page holds one WebGL context. [The portrait builder](docs/guides/portrait-builder.md) is its guide.
279
279
 
280
280
  ```html
281
281
  <script type="module" src="https://cdn.jsdelivr.net/npm/@johnmorrisdotca/wakusei-planets/portrait/+esm"></script>
@@ -7,6 +7,7 @@ import "./saturn.ts";
7
7
  import "./uranus.ts";
8
8
  import "./neptune.ts";
9
9
  import "./pluto.ts";
10
+ import "./dwarfs.ts";
10
11
  import "./earth-look.ts";
11
12
  import "./moons-earth.ts";
12
13
  import "./moons-mars.ts";
@@ -15,3 +16,4 @@ import "./moons-saturn.ts";
15
16
  import "./moons-uranus.ts";
16
17
  import "./moons-neptune.ts";
17
18
  import "./moons-pluto.ts";
19
+ import "./moons-dwarf.ts";
@@ -7,6 +7,7 @@ import "./saturn.js";
7
7
  import "./uranus.js";
8
8
  import "./neptune.js";
9
9
  import "./pluto.js";
10
+ import "./dwarfs.js";
10
11
  import "./earth-look.js";
11
12
  import "./moons-earth.js";
12
13
  import "./moons-mars.js";
@@ -15,3 +16,4 @@ import "./moons-saturn.js";
15
16
  import "./moons-uranus.js";
16
17
  import "./moons-neptune.js";
17
18
  import "./moons-pluto.js";
19
+ import "./moons-dwarf.js";
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ import { registerLook } from "../scene/look.js";
2
+ import { ice, rock } from "../scene/recipes.js";
3
+ registerLook({
4
+ id: "ceres",
5
+ surface: rock({
6
+ dark: "#4d4a47",
7
+ light: "#7e7a75",
8
+ craters: 1.4,
9
+ contrast: 0.8,
10
+ seed: 61,
11
+ patches: 3,
12
+ extra: `
13
+ float occ = oval(p, 239.0, 19.8, 3.4, 3.4, 0.5);
14
+ col = mix(col, vec3(0.93, 0.93, 0.92), occ * 0.95);`,
15
+ }),
16
+ relief: 0.7,
17
+ ambient: 0.02,
18
+ painted: { map: "ceres", widths: [512, 1024, 2048], far: 2048 },
19
+ mapped: true,
20
+ });
21
+ registerLook({ id: "orcus", surface: rock({ dark: "#6f7074", light: "#a9a9ab", craters: 0.5, contrast: 0.5, seed: 63, patches: 2.2 }), relief: 0.5, ambient: 0.02 });
22
+ registerLook({
23
+ id: "haumea",
24
+ surface: ice({ base: "#e4e5e8", stain: "#bfc0c4", craters: 0.08, extra: "col = mix(col, vec3(0.50, 0.17, 0.12), oval(p, 40.0, 5.0, 24.0, 13.0, 0.5) * 0.85);" }),
25
+ relief: 0.3,
26
+ ambient: 0.02,
27
+ });
28
+ registerLook({ id: "quaoar", surface: rock({ dark: "#7d5844", light: "#b58b72", craters: 0.35, contrast: 0.4, seed: 65, patches: 2.4 }), relief: 0.5, ambient: 0.02 });
29
+ registerLook({ id: "makemake", surface: rock({ dark: "#8e5a3c", light: "#cf9a76", craters: 0.12, contrast: 0.3, seed: 67, patches: 2.8, extra: "col = mix(col, vec3(0.45, 0.25, 0.17), oval(p, 30.0, 10.0, 34.0, 20.0, 0.45) * 0.5);" }), relief: 0.35, ambient: 0.02 });
30
+ registerLook({ id: "gonggong", surface: rock({ dark: "#6e3524", light: "#a9604a", craters: 0.3, contrast: 0.4, seed: 69, patches: 2.5 }), relief: 0.5, ambient: 0.02 });
31
+ registerLook({ id: "eris", surface: ice({ base: "#ece8e0", stain: "#cdc6ba", craters: 0.06 }), atmosphere: { colour: [0.9, 0.9, 0.95], strength: 0.03, power: 5 }, relief: 0.2, ambient: 0.02 });
32
+ registerLook({ id: "sedna", surface: rock({ dark: "#6a2a1b", light: "#a24b34", craters: 0.2, contrast: 0.3, seed: 71, patches: 2.6 }), relief: 0.4, ambient: 0.02 });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import { registerLook } from "../scene/look.js";
2
+ import { ice, rock } from "../scene/recipes.js";
3
+ registerLook({ id: "dysnomia", surface: rock({ dark: "#3f3d3b", light: "#6c6967", craters: 1.2, contrast: 0.8, seed: 73 }), relief: 0.8, ambient: 0.02 });
4
+ registerLook({ id: "hiiaka", surface: ice({ base: "#e6e6e6", stain: "#c4c4c4", craters: 0.25 }), relief: 0.6, ambient: 0.02 });
5
+ registerLook({ id: "namaka", surface: ice({ base: "#d8d8d8", stain: "#b4b4b4", craters: 0.25 }), relief: 0.6, ambient: 0.02 });
6
+ registerLook({ id: "vanth", surface: rock({ dark: "#55514d", light: "#827d78", craters: 1.2, contrast: 0.8, seed: 75 }), relief: 0.8, ambient: 0.02 });
@@ -7,5 +7,6 @@ registerLook({
7
7
  atmosphere: { colour: [0.8, 0.8, 0.9], strength: 0.05, power: 5 },
8
8
  ambient: 0.025,
9
9
  relief: 0.4,
10
+ painted: { map: "triton", widths: [512, 1024, 2048], far: 2048 },
10
11
  });
11
12
  registerLook({ id: "nereid", surface: rock({ dark: "#6e6e6e", light: "#9b9b9b", craters: 1, seed: 40 }), relief: 0.8, ambient: 0.02 });
@@ -1,5 +1,5 @@
1
1
  import { registerLook } from "../scene/look.js";
2
2
  import { rock } from "../scene/recipes.js";
3
- registerLook({ id: "charon", surface: rock({ dark: "#756f6a", light: "#aaa29a", craters: 0.7, contrast: 0.7, seed: 41, extra: "col = mix(col, vec3(0.42, 0.20, 0.13), smoothstep(radians(52.0), radians(78.0), lat(p)) * 0.85);" }), relief: 0.6, ambient: 0.02 });
3
+ registerLook({ id: "charon", surface: rock({ dark: "#756f6a", light: "#aaa29a", craters: 0.7, contrast: 0.7, seed: 41, extra: "col = mix(col, vec3(0.42, 0.20, 0.13), smoothstep(radians(52.0), radians(78.0), lat(p)) * 0.85);" }), relief: 0.6, ambient: 0.02, painted: { map: "charon", widths: [512, 1024, 2048], far: 2048 } });
4
4
  registerLook({ id: "nix", surface: rock({ dark: "#8d8983", light: "#c9c3b9", craters: 1, contrast: 0.7, seed: 43 }), relief: 0.7, ambient: 0.02 });
5
5
  registerLook({ id: "hydra", surface: rock({ dark: "#9e9a92", light: "#d4cec4", craters: 1, contrast: 0.7, seed: 47 }), relief: 0.7, ambient: 0.02 });
@@ -8,8 +8,8 @@ registerLook({
8
8
  relief: 0.3,
9
9
  painted: { map: "enceladus", widths: [512, 1024, 2048], far: 2048 },
10
10
  });
11
- registerLook({ id: "tethys", surface: rock({ dark: "#8f8d88", light: "#d0cec9", craters: 1.2, contrast: 0.9, seed: 14, patches: 2.2, extra: "float od = bowl(p, 232.0, 5.0, 24.0, 0.6); h += od; col *= 1.0 + 0.7 * od;" }), relief: 0.8, ambient: 0.02 });
12
- registerLook({ id: "dione", surface: rock({ dark: "#8c8a85", light: "#cdcbc5", craters: 1, contrast: 0.9, seed: 18, patches: 2.6 }), relief: 0.8, ambient: 0.02 });
11
+ registerLook({ id: "tethys", surface: rock({ dark: "#8f8d88", light: "#d0cec9", craters: 1.2, contrast: 0.9, seed: 14, patches: 2.2, extra: "float od = bowl(p, 232.0, 5.0, 24.0, 0.6); h += od; col *= 1.0 + 0.7 * od;" }), relief: 0.8, ambient: 0.02, painted: { map: "tethys", widths: [512, 1024, 2048], far: 2048 } });
12
+ registerLook({ id: "dione", surface: rock({ dark: "#8c8a85", light: "#cdcbc5", craters: 1, contrast: 0.9, seed: 18, patches: 2.6 }), relief: 0.8, ambient: 0.02, painted: { map: "dione", widths: [512, 1024, 2048], far: 2048 } });
13
13
  registerLook({ id: "rhea", surface: rock({ dark: "#8a8883", light: "#cac8c2", craters: 1.5, contrast: 0.9, seed: 24, patches: 2 }), relief: 0.85, ambient: 0.02, painted: { map: "rhea", widths: [512, 1024, 2048], far: 2048 } });
14
14
  registerLook({
15
15
  id: "titan",
@@ -31,4 +31,5 @@ registerLook({
31
31
  }),
32
32
  relief: 0.7,
33
33
  ambient: 0.02,
34
+ painted: { map: "iapetus", widths: [512, 1024, 2048], far: 2048 },
34
35
  });
@@ -0,0 +1,16 @@
1
+ import type { DwarfId } from "../facts.ts";
2
+ import type { OrbitElements } from "./orbits.ts";
3
+ /** The osculating heliocentric elements of one epoch. */
4
+ export interface Osculating {
5
+ /** Milliseconds since 1970. */
6
+ epoch: number;
7
+ a: number;
8
+ e: number;
9
+ i: number;
10
+ node: number;
11
+ w: number;
12
+ m: number;
13
+ n: number;
14
+ }
15
+ export declare const DWARF_ELEMENTS: Readonly<Record<DwarfId, Osculating>>;
16
+ export declare const DWARF_MOON_ORBITS: Record<string, OrbitElements>;
@@ -0,0 +1,24 @@
1
+ const epoch = 1780963200000;
2
+ export const DWARF_ELEMENTS = {
3
+ ceres: { epoch, a: 2.765552595034094, e: 0.07969229514816586, i: 10.58802780183462, node: 80.24862682043221, w: 73.29421453021587, m: 274.4193463761342, n: 0.21430445064843 },
4
+ orcus: { epoch, a: 39.37686537914865, e: 0.2205240628250881, i: 20.55681019612, node: 268.4053519455824, w: 73.56848606705262, m: 189.0972913554275, n: 0.003988800931399829 },
5
+ haumea: { epoch, a: 43.06029023650952, e: 0.1944430148898797, i: 28.20847393040364, node: 121.7860561329425, w: 240.6905472508661, m: 223.2104118812299, n: 0.003488097731816818 },
6
+ quaoar: { epoch, a: 43.15617622670811, e: 0.03520019261837198, i: 7.991575800732639, node: 188.9191248092036, w: 163.209046106457, m: 292.8487574842713, n: 0.003476479214379914 },
7
+ makemake: { epoch, a: 45.57093317300052, e: 0.1588889953992523, i: 29.02785603743067, node: 79.2948338209406, w: 297.0922733397207, m: 169.9379962048232, n: 0.003203850120050116 },
8
+ gonggong: { epoch, a: 66.86666567773766, e: 0.5042510000302973, i: 30.89906721170288, node: 336.8383156185827, w: 206.6232839773693, m: 111.664541568459, n: 0.001802559348482343 },
9
+ eris: { epoch, a: 67.93394687853566, e: 0.4382385347971672, i: 43.9258279471791, node: 36.00477044417249, w: 150.7949235840312, m: 211.774434275007, n: 0.001760247770619088 },
10
+ sedna: { epoch, a: 543.7195289104732, e: 0.8598824585187618, i: 11.92527582847476, node: 144.5061662673739, w: 311.0987725939751, m: 358.5956944005428, n: 7.773948799642578e-05 },
11
+ };
12
+ // Moons of the dwarf planets whose orbit is published with an epoch, so they can be put where they are on a date. Moons with no published phase are left out (Weywot, Xiangliu, S/2015 (136472) 1).
13
+ // Dysnomia: Holler, Grundy, Buie & Noll (2021), "The Eris/Dysnomia system I: The orbit of Dysnomia", Icarus 355:114130, Table 2 (combined fit; epoch JD 2453979.0; the angles are to the J2000 equator;
14
+ // the table gives the longitude of periapsis 307 and the mean longitude 125.78, so the argument of periapsis is 307 - 126.17 and the mean anomaly 125.78 - 307). Period 15.785899 days.
15
+ // Hiʻiaka and Namaka: Ragozzine & Brown (2009), "Orbits and Masses of the Satellites of the Dwarf Planet Haumea (2003 EL61)", AJ 137:4766, Table 2: osculating elements at HJD 2454615.0, J2000 ecliptic,
16
+ // the periods from their section III.1. The two moons pull on each other, so a plain ellipse from 2008 is only roughly right years later.
17
+ // Vanth: Brown, Ragozzine, Stansberry & Fraser (2010), "The Size, Density, and Formation of the Orcus-Vanth System in the Kuiper Belt", AJ 139:2700, Table 2, solution 1 of the two mirror solutions
18
+ // (epoch JD 2454439.280, J2000 ecliptic, a circle). Period 9.5393 days.
19
+ export const DWARF_MOON_ORBITS = {
20
+ dysnomia: { parent: "eris", frame: "j2000", epoch: 1157025600000, a: 37273, e: 0.0062, w: 180.83, m: 178.78, i: 45.49, node: 126.17, sid: 22.8051630, dw: 0, dn: 0 },
21
+ hiiaka: { parent: "haumea", frame: "ecliptic", epoch: 1211976000000, a: 49880, e: 0.0513, w: 154.1, m: 152.8, i: 126.356, node: 206.766, sid: 7.2783147, dw: 0, dn: 0 },
22
+ namaka: { parent: "haumea", frame: "ecliptic", epoch: 1211976000000, a: 25657, e: 0.249, w: 178.9, m: 178.5, i: 113.013, node: 205.016, sid: 19.6954859, dw: 0, dn: 0 },
23
+ vanth: { parent: "orcus", frame: "ecliptic", epoch: 1196793792000, a: 8980, e: 0, w: 0, m: 143.1, i: 90.2, node: 50.0, sid: 37.7386181, dw: 0, dn: 0 },
24
+ };
@@ -1,8 +1,8 @@
1
1
  export interface OrbitElements {
2
2
  /** The planet it goes round. */
3
3
  parent: string;
4
- /** The reference plane: the ecliptic, the planet's equator, or the Laplace plane whose pole is `pole` (right ascension, declination, degrees). */
5
- frame: "ecliptic" | "equatorial" | "laplace";
4
+ /** The reference plane: the ecliptic, the Earth's equator of J2000, the planet's equator, or the Laplace plane whose pole is `pole` (right ascension, declination, degrees). */
5
+ frame: "ecliptic" | "j2000" | "equatorial" | "laplace";
6
6
  pole?: [number, number];
7
7
  /** The epoch of the elements, in milliseconds since 1970. */
8
8
  epoch: number;
@@ -1,3 +1,6 @@
1
+ // Made by scripts/make-moon-data.py from JPL's Planetary Satellite Mean Elements (https://ssd.jpl.nasa.gov/sats/elem/); do not edit by hand.
2
+ // The moons of the dwarf planets are not on that page: their orbits are in dwarf.ts, from the papers it cites, and are added at the end.
3
+ import { DWARF_MOON_ORBITS } from "./dwarf.js";
1
4
  export const ORBITS = {
2
5
  moon: { parent: "earth", frame: "ecliptic", epoch: 946728000000, a: 384400, e: 0.0554, w: 318.15, m: 135.27, i: 5.16, node: 125.08, sid: 13.1763585, dw: 0.16435, dn: -0.05299 },
3
6
  phobos: { parent: "mars", frame: "laplace", pole: [317.7, 52.9], epoch: 946728000000, a: 9375, e: 0.015, w: 216.3, m: 189.7, i: 1.1, node: 169.2, sid: 1128.8443146, dw: -0.74464, dn: -0.42853 },
@@ -24,4 +27,5 @@ export const ORBITS = {
24
27
  charon: { parent: "pluto", frame: "equatorial", epoch: 946728000000, a: 19600, e: 0, w: 0, m: 304.1, i: 0, node: 0, sid: 56.3624607, dw: 0.00000, dn: 0.00000 },
25
28
  nix: { parent: "pluto", frame: "equatorial", epoch: 946728000000, a: 49300, e: 0.015, w: 31.4, m: 338.2, i: 0, node: 0, sid: 14.4842403, dw: 0.00000, dn: 0.00000 },
26
29
  hydra: { parent: "pluto", frame: "equatorial", epoch: 946728000000, a: 65200, e: 0.009, w: 139.3, m: 335, i: 0.3, node: 114.3, sid: 9.4236471, dw: 0.00000, dn: -0.07040 },
30
+ ...DWARF_MOON_ORBITS,
27
31
  };
package/dist/element.d.ts CHANGED
@@ -25,7 +25,7 @@ export type WakuseiState = "line" | "loading" | "still" | "live" | "lost" | "una
25
25
  * console.log(TEXTURE_BASE);
26
26
  * ```
27
27
  */
28
- export declare const TEXTURE_BASE = "https://cdn.jsdelivr.net/npm/@johnmorrisdotca/wakusei-planets@0.7.0/dist/textures/";
28
+ export declare const TEXTURE_BASE = "https://cdn.jsdelivr.net/npm/@johnmorrisdotca/wakusei-planets@0.11.1/dist/textures/";
29
29
  /**
30
30
  * Where the sharpest surface pictures are: the files of this exact version in the repository, on jsDelivr's GitHub address. The npm package holds only the two smaller widths, so a page that
31
31
  * never zooms in never fetches them. Set `texture-far-base` on an element to serve them yourself.
@@ -37,7 +37,7 @@ export declare const TEXTURE_BASE = "https://cdn.jsdelivr.net/npm/@johnmorrisdot
37
37
  * console.log(TEXTURE_FAR_BASE);
38
38
  * ```
39
39
  */
40
- export declare const TEXTURE_FAR_BASE = "https://cdn.jsdelivr.net/gh/johnmorrisdotca/wakusei-planets@v0.7.0/textures/";
40
+ export declare const TEXTURE_FAR_BASE = "https://cdn.jsdelivr.net/gh/johnmorrisdotca/wakusei-planets@v0.11.1/textures/";
41
41
  /**
42
42
  * The `<wakusei-body>` custom element: a body of the solar system, drawn in a look.
43
43
  *
@@ -59,6 +59,8 @@ export declare const TEXTURE_FAR_BASE = "https://cdn.jsdelivr.net/gh/johnmorrisd
59
59
  export declare class WakuseiBody extends HTMLElement {
60
60
  #private;
61
61
  static observedAttributes: string[];
62
+ /** The radius of the body's disc on the screen in CSS pixels, at the picture's own size: what `grab-radius` on the shared view controls wants for a drag that keeps the touched point under the pointer. */
63
+ get discRadius(): number;
62
64
  get body(): BodyId;
63
65
  get look(): Look;
64
66
  /** What the element is doing now. */
package/dist/element.js CHANGED
@@ -145,6 +145,10 @@ export class WakuseiBody extends HTMLElement {
145
145
  else
146
146
  this.#resume();
147
147
  };
148
+ /** The radius of the body's disc on the screen in CSS pixels, at the picture's own size: what `grab-radius` on the shared view controls wants for a drag that keeps the touched point under the pointer. */
149
+ get discRadius() {
150
+ return (this.getBoundingClientRect().width / 2) * this.#fill();
151
+ }
148
152
  get body() {
149
153
  const id = this.getAttribute("body");
150
154
  return id !== null && id in BODIES ? id : "earth";
package/dist/embed.d.ts CHANGED
@@ -61,7 +61,7 @@ export interface EmbedSettings {
61
61
  /** The package's address on the CDN, with its version. */
62
62
  cdn?: string;
63
63
  }
64
- /** The entry point that holds a body's shaded and painted look. */
64
+ /** The entry point that holds a body's shaded and painted look: the body's own, `dwarfs` for the dwarf planets besides Pluto, `moons-<planet>` for a moon and `moons-dwarf` for a moon of a dwarf planet. */
65
65
  export declare function entryOf(id: BodyId): string;
66
66
  /**
67
67
  * The text that puts a body in a page, for one way of making the page. Each way is built, parsed or run by the package's tests: the plain HTML one with a script tag from jsDelivr, an ES module, a React component,
package/dist/embed.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // The text to put a body in a page, for each way a page is made: a script tag from a CDN, an ES module, React, Vue, Angular, Svelte, or an iframe of `embed.html`. The demo's "Put it in your page"
2
2
  // section shows these as the reader changes a choice, and the tests build or parse every one. Pure: no DOM.
3
- import { BODIES } from "./facts.js";
3
+ import { BODIES, DWARF_IDS } from "./facts.js";
4
4
  import { decodeScene } from "./portrait/model.js";
5
5
  import { VERSION } from "./version.js";
6
6
  /**
@@ -17,10 +17,12 @@ export const EMBED_KINDS = ["html", "module", "react", "vue", "angular", "svelte
17
17
  const SITE = "https://johnmorrisdotca.github.io/wakusei-planets/";
18
18
  const CDN = `https://cdn.jsdelivr.net/npm/@johnmorrisdotca/wakusei-planets@${VERSION}`;
19
19
  const PACKAGE = "@johnmorrisdotca/wakusei-planets";
20
- /** The entry point that holds a body's shaded and painted look. */
20
+ /** The entry point that holds a body's shaded and painted look: the body's own, `dwarfs` for the dwarf planets besides Pluto, `moons-<planet>` for a moon and `moons-dwarf` for a moon of a dwarf planet. */
21
21
  export function entryOf(id) {
22
22
  const parent = BODIES[id].parent;
23
- return parent === undefined ? id : `moons-${parent}`;
23
+ if (parent === undefined)
24
+ return DWARF_IDS.includes(id) ? "dwarfs" : id;
25
+ return DWARF_IDS.includes(parent) ? "moons-dwarf" : `moons-${parent}`;
24
26
  }
25
27
  /** The attributes of the element for these choices, in the order they are written. */
26
28
  function attributesOf(o) {
@@ -1,10 +1,10 @@
1
- import { type BodyId, type MoonId, type PlanetId } from "./facts.ts";
1
+ import { type BodyId, type HostId, type MoonId } from "./facts.ts";
2
2
  import { type Vec3 } from "./vec.ts";
3
3
  /** Solve Kepler's equation for the eccentric anomaly, all in radians. */
4
4
  export declare function kepler(meanAnomaly: number, e: number): number;
5
5
  /**
6
- * A planet's position in the Sun's frame (J2000 ecliptic, astronomical units) at a time, from JPL's approximate elements.
7
- * @param planet - The planet's name.
6
+ * A planet's or dwarf planet's position in the Sun's frame (J2000 ecliptic, astronomical units) at a time: a planet from JPL's approximate elements, a dwarf planet from the osculating elements of one epoch (JPL's Small-Body Database).
7
+ * @param planet - The planet's or dwarf planet's name.
8
8
  * @param ms - The instant, in milliseconds since 1970.
9
9
  * @returns The position as x, y, z in au.
10
10
  *
@@ -16,7 +16,7 @@ export declare function kepler(meanAnomaly: number, e: number): number;
16
16
  * console.log(Math.hypot(x, y, z).toFixed(3));
17
17
  * ```
18
18
  */
19
- export declare function heliocentric(planet: PlanetId, ms: number): Vec3;
19
+ export declare function heliocentric(planet: HostId, ms: number): Vec3;
20
20
  /**
21
21
  * The Moon's position from the Earth's centre (J2000 ecliptic, kilometres), from the largest terms of Meeus's lunar series.
22
22
  * @param ms - The instant, in milliseconds since 1970.
@@ -164,7 +164,7 @@ export interface System {
164
164
  * console.log(moons.map((moon) => `${moon.id} ${moon.x.toFixed(1)}`).join(", "));
165
165
  * ```
166
166
  */
167
- export declare function system(planet: PlanetId, time: number): System;
167
+ export declare function system(planet: HostId, time: number): System;
168
168
  /**
169
169
  * The path one moon follows round its planet over one trip, as the Earth sees it at `time`: x, y, z in planet radii, in the viewer's frame at that moment.
170
170
  *
@@ -183,7 +183,7 @@ export declare function system(planet: PlanetId, time: number): System;
183
183
  */
184
184
  export declare function orbitPath(id: MoonId, time: number, points?: number): Float32Array;
185
185
  /** The planets' moons that are near enough to draw in a system view, nearest first, with how far each goes in planet radii. */
186
- export declare function nearMoons(planet: PlanetId, within?: number): {
186
+ export declare function nearMoons(planet: HostId, within?: number): {
187
187
  id: MoonId;
188
188
  reach: number;
189
189
  }[];
package/dist/ephemeris.js CHANGED
@@ -3,6 +3,7 @@
3
3
  // good to about an arc minute. The Moon: the largest terms of Meeus, "Astronomical Algorithms", chapter 47. Other moons: JPL's mean elements (data/orbits.ts).
4
4
  // Light travel time is allowed for, so a turning planet shows the face it really showed when the light left. Pure: no DOM, no three.js.
5
5
  import { ORBITS } from "./data/orbits.js";
6
+ import { DWARF_ELEMENTS } from "./data/dwarf.js";
6
7
  import { BODIES, MOONS_OF } from "./facts.js";
7
8
  import { add, cross, DEG, dot, fromRaDec, length, OBLIQUITY, RAD, scale, sub, toEcliptic, unit, wrap360 } from "./vec.js";
8
9
  /** Milliseconds since 1970 at J2000.0 (2000-01-01 12:00 TT, taken as UTC). */
@@ -42,8 +43,8 @@ export function kepler(meanAnomaly, e) {
42
43
  return E;
43
44
  }
44
45
  /**
45
- * A planet's position in the Sun's frame (J2000 ecliptic, astronomical units) at a time, from JPL's approximate elements.
46
- * @param planet - The planet's name.
46
+ * A planet's or dwarf planet's position in the Sun's frame (J2000 ecliptic, astronomical units) at a time: a planet from JPL's approximate elements, a dwarf planet from the osculating elements of one epoch (JPL's Small-Body Database).
47
+ * @param planet - The planet's or dwarf planet's name.
47
48
  * @param ms - The instant, in milliseconds since 1970.
48
49
  * @returns The position as x, y, z in au.
49
50
  *
@@ -56,16 +57,34 @@ export function kepler(meanAnomaly, e) {
56
57
  * ```
57
58
  */
58
59
  export function heliocentric(planet, ms) {
59
- const el = ELEMENTS[planet];
60
- const T = centuries(ms);
61
- const a = el[0] + el[6] * T;
62
- const e = el[1] + el[7] * T;
63
- const I = (el[2] + el[8] * T) * RAD;
64
- const L = el[3] + el[9] * T;
65
- const peri = el[4] + el[10] * T;
66
- const node = (el[5] + el[11] * T) * RAD;
67
- const w = peri * RAD - node;
68
- const E = kepler((L - peri) * RAD, e);
60
+ let a;
61
+ let e;
62
+ let I;
63
+ let node;
64
+ let w;
65
+ let E;
66
+ const dwarf = DWARF_ELEMENTS[planet];
67
+ if (dwarf !== undefined) {
68
+ // a dwarf planet: the osculating elements of one epoch, run as a plain ellipse (good for years either side of it)
69
+ a = dwarf.a;
70
+ e = dwarf.e;
71
+ I = dwarf.i * RAD;
72
+ node = dwarf.node * RAD;
73
+ w = dwarf.w * RAD;
74
+ E = kepler((dwarf.m + (dwarf.n * (ms - dwarf.epoch)) / DAY) * RAD, e);
75
+ }
76
+ else {
77
+ const el = ELEMENTS[planet];
78
+ const T = centuries(ms);
79
+ a = el[0] + el[6] * T;
80
+ e = el[1] + el[7] * T;
81
+ I = (el[2] + el[8] * T) * RAD;
82
+ const L = el[3] + el[9] * T;
83
+ const peri = el[4] + el[10] * T;
84
+ node = (el[5] + el[11] * T) * RAD;
85
+ w = peri * RAD - node;
86
+ E = kepler((L - peri) * RAD, e);
87
+ }
69
88
  const x = a * (Math.cos(E) - e);
70
89
  const y = a * Math.sqrt(1 - e * e) * Math.sin(E);
71
90
  const cw = Math.cos(w);
@@ -231,6 +250,8 @@ export function moonVector(id, ms) {
231
250
  function referenceBasis(orbit) {
232
251
  if (orbit.frame === "ecliptic")
233
252
  return { x: [1, 0, 0], y: [0, 1, 0], z: [0, 0, 1] };
253
+ if (orbit.frame === "j2000")
254
+ return { x: toEcliptic([1, 0, 0]), y: toEcliptic([0, 1, 0]), z: toEcliptic([0, 0, 1]) };
234
255
  const pole = orbit.frame === "laplace" && orbit.pole !== undefined ? orbit.pole : [BODIES[orbit.parent].pole.ra, BODIES[orbit.parent].pole.dec];
235
256
  const z = fromRaDec(pole[0], pole[1]);
236
257
  const x = fromRaDec(pole[0] + 90, 0);