feat: 完善水星与金星全球凌日搜索及制图导出
- 基于平均下合周期与节点相位预筛候选,减少无效星历计算;跳过无法求解的单个会合周期,避免有限覆盖星历导致搜索提前终止 - 引入影轴 γ、半影半径及地球尺度几何判定,结合站心可见性识别地心无接触、仅部分地区可见的掠凌 - 添加金星 243 年、水星 46 年周期族编号,并明确编号适用范围及未分配时的零值语义 - 为 SVG、GeoJSON 和 KML 增加站心部分凌日可见区,适配接触等时线、几何元数据、图层样式及取景;为地心无接触凌日事件增加正射图,按可见区球面面积加权居中
This commit is contained in:
41 files changed
+1554
-307
No files matched your search
@@ -33,6 +33,7 @@ This manual covers solar- and lunar-eclipse queries and charts, plus the two Mer
|
||||
- [Transit charts](#transit-charts)
|
||||
- [Mercury: 2032-11-13 (Beijing)](#mercury-2032-11-13-beijing)
|
||||
- [Venus: 2012-06-06 (Beijing)](#venus-2012-06-06-beijing)
|
||||
- [Special case: partial transits without geocentric contacts](#special-case-partial-transits-without-geocentric-contacts)
|
||||
|
||||
## Simple example: the 2009 Great Yangtze Eclipse at a site in Shanghai
|
||||
|
||||
@@ -1064,10 +1065,14 @@ Transit contact times, topocentric visibility and `LocalTransit` live in [Planet
|
||||
|
||||
| Entry | Chart | Suggested canvas |
|
||||
| --- | --- | --- |
|
||||
| `TransitMapSVG` | Geocentric global visibility: entire transit, transit at sunrise, transit at sunset, not visible | 960×640 and up |
|
||||
| `TransitMapSVG` | Global visibility, including topocentric partial-only events without geocentric contacts | 960×640 and up |
|
||||
| `TransitLocalSVG` | Topocentric solar disk: north up, east left, planet-center track, planet disk at each contact and at greatest, contact table | 960×680 and up |
|
||||
|
||||
Regions follow whether the Sun's center is above the apparent horizon at C1, greatest and C4, with standard refraction (a horizon circle of 90°34′). Isochrones are off by default; enable them bitwise with `Isochrones`: `TransitIsochroneC1` … `TransitIsochroneC4`, or the combinations `TransitIsochroneExternal` (C1 and C4) and `TransitIsochroneAll`. C2/C3 are dropped for a grazing transit without internal contacts. Isochrones are topocentric contact times drawn only where the Sun is above the apparent horizon; a non-positive `IsochroneStep` uses 20 s for Mercury and 1 min for Venus. A transit is visible from roughly half the globe, so the map always shows the whole world; `Projection` selects one of the four projections.
|
||||
For ordinary transits, regions follow whether the Sun's center is above the apparent horizon at C1, greatest and C4, with standard refraction (a horizon circle of 90°34′); events without geocentric contacts use the actual topocentric visible footprint. Isochrones are off by default; enable them bitwise with `Isochrones`: `TransitIsochroneC1` … `TransitIsochroneC4`, or the combinations `TransitIsochroneExternal` (C1 and C4) and `TransitIsochroneAll`. C2/C3 are omitted, including from the legend, when no site has an internal contact; a graze with only geocentric external contacts can still have topocentric C2/C3 in some regions, and those are drawn. Isochrones are topocentric contact times drawn only where the Sun is above the apparent horizon; a non-positive `IsochroneStep` uses 20 s for Mercury and 1 min for Venus.
|
||||
|
||||
For events without geocentric contacts the partial footprint is sampled on a 2° longitude by 1° latitude grid and detected boundaries are refined. That is chart sampling, not contact accuracy: a footprint narrower than the grid may go undetected, so use `LocalTransit` for exact site decisions.
|
||||
|
||||
`Projection` selects one of four projections; the default equirectangular map shows the whole world. Orthographic maps show only the facing hemisphere. For both Mercury and Venus, events without geocentric contacts centre on the spherical area-weighted visible footprint, for example Mercury on `1937-05-11` and Venus on `2854-12-14`. Ordinary transits retain the subsolar centre at greatest. Polar events may also use an explicit north- or south-polar projection.
|
||||
|
||||
```go
|
||||
venus := time.Date(2012, 6, 6, 0, 0, 0, 0, time.UTC)
|
||||
@@ -1097,3 +1102,9 @@ The Venus transit of 2012-06-06 was visible in full from Beijing, with `6h39m4s`
|
||||

|
||||
|
||||

|
||||
|
||||
### Special case: partial transits without geocentric contacts
|
||||
|
||||
The Mercury transit of 1937-05-11 is one such event: with no geocentric contacts, its footprint spans the South Atlantic, southern Africa and the Indian Ocean east to eastern Australia. The Venus transit of `2854-12-14` belongs to the same class, with a footprint that crosses the Antarctic Circle, all south of 50°S.
|
||||
|
||||

|
||||
@@ -73,7 +73,11 @@ A partial eclipse may have no central path, so `centralPath` may be `nil`. This
|
||||
|
||||
## Exporting transit GeoJSON
|
||||
|
||||
The transit entry points take a geocentric `TransitInfo` and partition the globe exactly like the transit visibility map:
|
||||
The transit entry points take a global-event `TransitInfo`; contact fields remain geocentric, and regions match the transit visibility map.
|
||||
|
||||
Events without geocentric contacts, such as the Venus transit of 2854-12-14, export the actual topocentric
|
||||
`transit-partial` footprint and omit nonexistent geocentric C1/C4 horizons. Properties also carry
|
||||
`has_geocentric_contacts`, `gamma`, `penumbral_radius`, `series` and `series_period_years`. The footprint is sampled on a 2° longitude by 1° latitude grid with boundary refinement; that is chart sampling rather than contact accuracy, so a footprint narrower than the grid may go undetected — use `LocalTransit` for exact site decisions.
|
||||
|
||||
```go
|
||||
m := mercury.NextTransit(time.Date(2026, 10, 12, 0, 0, 0, 0, cst))
|
||||
@@ -194,7 +198,7 @@ Grouped by figure family, the `data-source` values are listed below; the `eclips
|
||||
- Solar-eclipse instants and magnitude lines: `rise-set-phase-lines`, `magnitude-contours`, `greatest-time-isochrones`
|
||||
- Instantaneous outlines: `penumbral-outlines`, `central-shadow-outlines`
|
||||
- Lunar eclipses: `p1-p4-visibility-regions`, `p1-p4-horizon-boundaries`
|
||||
- Transits: `c1-c4-visibility-regions`, `c1-c4-horizon-boundaries`, `transit-contact-isochrones`
|
||||
- Transits: `c1-c4-visibility-regions`, `c1-c4-horizon-boundaries`, `transit-contact-isochrones`; events without geocentric contacts fill the footprint from `topocentric-transit-visibility`
|
||||
|
||||
## Map Projections
|
||||
|
||||
@@ -312,7 +316,7 @@ Each event type has plain and time-marker variants:
|
||||
- `MarshalLunarEclipseWithOptions`: one `LunarEclipseOptions` value carrying the time markers, `SkipRoles` and the time-envelope sampling parameters. `SkipRoles` can omit envelopes and penumbra-only bands; skipping both envelopes also skips their sampling. `EnvelopeSweepSamples` defaults to 48 and is clamped to `[2, 192]`; `EnvelopeLongitudePoints` defaults to `max(360, boundaryPoints)` and is clamped to `[12, 720]`.
|
||||
- `MarshalStarOccultation` / `MarshalStarOccultationWithTimeMarkers`
|
||||
- `MarshalPlanetOccultation` / `MarshalPlanetOccultationWithTimeMarkers`
|
||||
- `MarshalMercuryTransit` / `MarshalVenusTransit`: take `mercury.TransitInfo` / `venus.TransitInfo` and partition the globe like the transit SVG map (whether the Sun's center is above the apparent horizon, standard refraction, at C1, greatest and C4). `BoundaryPoints` is the horizon sample count and also sets the region longitude columns to `max(360, BoundaryPoints)`, capped at 720. Roles are the three regions `transit-entire`, `transit-at-sunrise` and `transit-at-sunset`, the visible hemispheres and horizons `visible-at-c1` / `visible-at-c4` and `c1-horizon` / `c4-horizon`, `greatest` (the subsolar point) and the time markers `time-marker`. A positive `IsochroneStep` (at least 1 s) adds topocentric `c1-isochrone` through `c4-isochrone` (no C2/C3 for a grazing transit; the times are topocentric contacts and parallax can place them outside the geocentric C1–C4 interval), and a contact whose isochrone does not reach the visible hemisphere omits that role; skipping all three region roles skips the region computation.
|
||||
- `MarshalMercuryTransit` / `MarshalVenusTransit`: take `mercury.TransitInfo` / `venus.TransitInfo` and partition the globe like the transit SVG map (whether the Sun's center is above the apparent horizon, standard refraction, at C1, greatest and C4). `BoundaryPoints` is the horizon sample count and also sets the region longitude columns to `max(360, BoundaryPoints)`, capped at 720. Roles are the three regions `transit-entire`, `transit-at-sunrise` and `transit-at-sunset`, the visible hemispheres and horizons `visible-at-c1` / `visible-at-c4` and `c1-horizon` / `c4-horizon`, `greatest` (the subsolar point) and the time markers `subsolar-track`. Events without geocentric contacts switch to a `transit-partial` region and omit the three visibility regions, the horizons and the visible hemispheres. A positive `IsochroneStep` (at least 1 s) adds topocentric `c1-isochrone` through `c4-isochrone` (no C2/C3 when no site has an internal contact, though a graze with only geocentric external contacts can still have them in some regions; the times are topocentric contacts and parallax can place them outside the geocentric C1–C4 interval), and a contact whose isochrone does not reach the visible hemisphere omits that role; skipping all three region roles skips the region computation.
|
||||
- `MarshalSolarEclipseWithOptions`: one `SolarEclipseOptions` value carrying both the time markers and `SkipRoles`, equivalent to the solar entry points above plus layer trimming.
|
||||
|
||||
The usual entry in `SkipRoles` is `partial-footprint` (the instantaneous penumbral outlines); `partial-band` is the edge of the eclipse band (the magnitude-0 limit) and is normally kept.
|
||||
@@ -472,7 +476,7 @@ Features are grouped into Folders by `event` and `role`. Collections containing
|
||||
| Total and partial occultation bands | `total-band`, `partial-band`, `total-band-outline`, `occultation-band` | Yellow with translucent band fill |
|
||||
| Rise/set visibility edges, lunar time envelopes and solar partial-band edge | `visibility-boundary`, `p1-horizon`, `p4-horizon`, `visible-at-p1`, `visible-at-p4`, `visible-during-eclipse`, `visible-throughout-eclipse`, solar `partial-band` | Orange |
|
||||
| Penumbra-only moonrise/moonset bands | `penumbra-moonrise`, `penumbra-moonset` | Blue-violet for moonrise, violet for moonset, with a translucent fill |
|
||||
| Transit visibility regions and contact lines | `transit-entire`, `transit-at-sunrise`, `transit-at-sunset`, `c1-horizon`, `c4-horizon`, `visible-at-c1`, `visible-at-c4`, `c1-isochrone` … `c4-isochrone` | Each of the three regions has its own fill; C1/C4 horizons and visible hemispheres are orange; the four contact isochrones each get a color |
|
||||
| Transit visibility regions and contact lines | `transit-entire`, `transit-at-sunrise`, `transit-at-sunset`, `transit-partial`, `c1-horizon`, `c4-horizon`, `visible-at-c1`, `visible-at-c4`, `c1-isochrone` … `c4-isochrone` | Each of the three regions and the partial-transit footprint has its own fill; C1/C4 horizons and visible hemispheres are orange; the four contact isochrones each get a color |
|
||||
| Other limits, outlines, footprints and time markers | Other roles | Grey; polygons are outline-only by default |
|
||||
|
||||
Zero-valued `Style` fields retain palette defaults:
|
||||
|
||||
+15
-13
@@ -38,7 +38,7 @@ The inner planets (Mercury and Venus) add superior/inferior conjunction, greates
|
||||
- [Position and coordinates](#position-and-coordinates)
|
||||
- [Rise, set and culmination](#rise-set-and-culmination)
|
||||
- [Conjunctions, oppositions, stations and quadratures](#conjunctions-oppositions-stations-and-quadratures)
|
||||
- [Greatest elongation and geocentric transits](#greatest-elongation-and-geocentric-transits)
|
||||
- [Greatest elongation and transits](#greatest-elongation-and-transits)
|
||||
- [Nodes, phase, magnitude, diameter and parallactic angle](#nodes-phase-magnitude-diameter-and-parallactic-angle)
|
||||
- [Division of labour with other manuals](#division-of-labour-with-other-manuals)
|
||||
- [Physical ephemerides](#physical-ephemerides)
|
||||
@@ -188,22 +188,22 @@ fmt.Println(saturn.NextProgradeToRetrograde(date)) // Saturn's next prograde-to-
|
||||
|
||||
Event searches return the nearest event at or after the input instant and keep its time zone; the paired `Last...` functions and the direction-agnostic `NextRetrograde` are in [Conjunctions, oppositions, stations and quadratures](#conjunctions-oppositions-stations-and-quadratures);
|
||||
|
||||
Mercury's and Venus's `NextGreatestElongationEast` / `...West` are in [Greatest elongation and geocentric transits](#greatest-elongation-and-geocentric-transits).
|
||||
Mercury's and Venus's `NextGreatestElongationEast` / `...West` are in [Greatest elongation and transits](#greatest-elongation-and-transits).
|
||||
|
||||
### Mercury and Venus transits
|
||||
|
||||
```go
|
||||
transit := mercury.NextTransit(date) // next geocentric Mercury transit after 2020
|
||||
transit := mercury.NextTransit(date) // next Mercury transit after 2020
|
||||
fmt.Println(transit.Valid, transit.Start, transit.Greatest) // whether one was found, first contact, greatest transit
|
||||
fmt.Println(transit.Duration, transit.MinimumSeparationArcsec) // duration and minimum separation at greatest transit
|
||||
```
|
||||
|
||||
```text
|
||||
true 2032-11-13 14:41:13.161198198 +0800 CST 2032-11-13 16:54:12.821315824 +0800 CST
|
||||
4h26m2.695272267s 572.0643215495325
|
||||
true 2032-11-13 14:41:13.691189289 +0800 CST 2032-11-13 16:54:13.351347148 +0800 CST
|
||||
4h26m2.484410405s 572.0831814505963
|
||||
```
|
||||
|
||||
`TransitInfo.Valid` false means no transit inside the search window and every other field is the zero value; `TransitInfo` is the geocentric geometry. For the contact times seen from one site, `LocalTransit` returns the topocentric result:
|
||||
`TransitInfo.Valid` false means no transit inside the search window and every other field is the zero value; otherwise `TransitInfo` describes a global event whose contact fields are geocentric reference times. Without geocentric contacts `HasExternal` is false, `Start` / `End` are zero, and only the `WindowStart` / `WindowEnd` search window is set. For the contact times seen from one site, `LocalTransit` returns the topocentric result:
|
||||
|
||||
```go
|
||||
transit := mercury.NextTransit(time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC))
|
||||
@@ -214,12 +214,14 @@ fmt.Println(local.Start.Time, local.Start.SunAltitude) // topocentric C1
|
||||
|
||||
```text
|
||||
true true true
|
||||
2019-11-11 12:36:09.037762284 +0000 UTC 7.933256722170642
|
||||
2019-11-11 12:36:08.979182839 +0000 UTC 7.933092450591312
|
||||
```
|
||||
|
||||
Topocentric contacts are re-solved after applying parallax to the Sun and the planet separately; Venus contacts can shift by about ±7 minutes from the geocentric ones across the globe, Mercury by about ±2 minutes. `SunAltitude` is the geometric altitude of the Sun's center; `Visible`, `Sunrise` and `Sunset` test whether the Sun's center is above the apparent horizon with standard refraction (1010 hPa, 10 °C), a geometric threshold of about −34′. A site may see only a grazing transit even when the geocentric one has internal contacts (the 1999-11-15 Mercury transit at high southern latitudes); then `HasInternal` is false and `InternalStart` / `InternalEnd` are zero. Global maps and topocentric disk charts are in [Eclipses and transits](eclipse.md#transit-charts).
|
||||
|
||||
The four contacts, partial transits and the internal-contact fields are in [Greatest elongation and geocentric transits](#greatest-elongation-and-geocentric-transits).
|
||||
The four contacts, partial transits and the internal-contact fields are in [Greatest elongation and transits](#greatest-elongation-and-transits).
|
||||
|
||||
`Gamma` is the signed distance from Earth's centre to the shadow axis at greatest (positive to the north) and `PenumbralRadius` is the penumbral radius on the fundamental plane, both in Earth equatorial radii. The transit penumbra is far larger than Earth, so the solar-eclipse test `|Gamma| < 1` does not apply. `Series` is the transit family: Venus families average 243 years and are numbered for astronomical years −2000 to +4000, Mercury families average 46 years and are numbered for +1601 to +2300; outside those spans, or for an unnumbered family, `Number` is zero while `PeriodYears` still gives the mean period.
|
||||
|
||||
### Phase, diameter, magnitude and nodes
|
||||
|
||||
@@ -580,15 +582,15 @@ fmt.Println(saturn.LastProgradeToRetrograde(date), saturn.NextProgradeToRetrogra
|
||||
fmt.Println(saturn.LastRetrogradeToPrograde(date), saturn.NextRetrogradeToPrograde(date))
|
||||
```
|
||||
|
||||
### Greatest elongation and geocentric transits
|
||||
### Greatest elongation and transits
|
||||
|
||||
Greatest elongation only makes sense for Mercury and Venus: `LastGreatestElongation` / `NextGreatestElongation` ignore the side, while `LastGreatestElongationEast` / `NextGreatestElongationEast` and the `...West` forms distinguish it.
|
||||
|
||||
The public entry points for geocentric transits are likewise only in `mercury` / `venus`: `LastTransit` / `NextTransit` / `ClosestTransit` return a `TransitInfo`.
|
||||
The public transit entry points are likewise only in `mercury` / `venus`: `LastTransit` / `NextTransit` / `ClosestTransit` return a `TransitInfo`.
|
||||
|
||||
`Valid == false` means no transit inside the search window and every other field is a zero value; a partial transit has no internal contacts, so `HasInternal` is false and `InternalStart` / `InternalEnd` are zero.
|
||||
`Valid == false` means no transit inside the search window and every other field is a zero value. Without geocentric contacts `HasExternal` is false and `Start` / `End` are zero; the event is then accepted or rejected by topocentric surface visibility. Without a topocentric internal contact `HasInternal` is false and `InternalStart` / `InternalEnd` are zero.
|
||||
|
||||
A transit is a purely geocentric geometry test and does not check whether the Sun is above the horizon at a given site.
|
||||
Contact fields come from the geocentric geometry, but whether a site can see the transit, and which contacts it sees, is decided by `LocalTransit`.
|
||||
|
||||
```go
|
||||
// Greatest elongation: use ...East / ...West to pick a side, or the plain form for either.
|
||||
@@ -902,7 +904,7 @@ Geocentric, topocentric, and distance are three different conventions: `Apparent
|
||||
|
||||
### Zero values, out-of-range input and sentinel errors
|
||||
|
||||
When an event search finds nothing inside its window it returns zero values or a struct with `Valid == false` (`TransitInfo.Valid`, `GalileanPhenomenonEvent.Valid`, `GalileanPhenomenonContactEvent.Valid`) instead of an error; when `TransitInfo.HasInternal` is false, `InternalStart` / `InternalEnd` are zero values because a partial transit has no internal contacts.
|
||||
When an event search finds nothing inside its window it returns zero values or a struct with `Valid == false` (`TransitInfo.Valid`, `GalileanPhenomenonEvent.Valid`, `GalileanPhenomenonContactEvent.Valid`) instead of an error; when `TransitInfo.HasExternal` is false, `Start` / `End` are zero values, and when `TransitInfo.HasInternal` is false, `InternalStart` / `InternalEnd` are zero values.
|
||||
|
||||
`planet.WherePlanet` / `planet.WherePlanetN` return `NaN` instead of panicking when `xt` / `zn` is out of range. `n < 0` selects the full series; all nonnegative `n` select one semianalytic fast table, while Legacy truncates according to `n`.
|
||||
|
||||
|
||||
Reference in new issue
Block a user