mirror of
https://github.com/acamarata/moon-sighting-dart.git
synced 2026-06-30 19:04:23 +00:00
chore: polish README for P1 E6
This commit is contained in:
parent
cf07c69613
commit
7895dc7ee6
1 changed files with 20 additions and 110 deletions
130
README.md
130
README.md
|
|
@ -3,8 +3,11 @@
|
|||
[](https://pub.dev/packages/moon_sighting)
|
||||
[](https://github.com/acamarata/moon-sighting-dart/actions/workflows/ci.yml)
|
||||
[](LICENSE)
|
||||
[](https://github.com/acamarata/moon-sighting-dart/wiki)
|
||||
|
||||
Lunar crescent visibility for Dart and Flutter. Computes moon phase, topocentric position, illumination, and Yallop/Odeh crescent visibility criteria using Meeus algorithms. Zero dependencies.
|
||||
Lunar crescent visibility for Dart and Flutter. Moon phase, topocentric position, illumination, and Yallop/Odeh crescent criteria using Meeus algorithms. Zero dependencies.
|
||||
|
||||
Uses Meeus lite algorithms (~0.3 degree accuracy). The companion TypeScript package (`moon-sighting` on npm) uses JPL DE442S ephemeris for sub-arcminute precision.
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
@ -22,143 +25,50 @@ import 'package:moon_sighting/moon_sighting.dart';
|
|||
final phase = getMoonPhase();
|
||||
print('${phase.phaseName} ${phase.phaseSymbol}');
|
||||
print('Illumination: ${phase.illumination.toStringAsFixed(1)}%');
|
||||
print('Age: ${phase.age.toStringAsFixed(1)} hours');
|
||||
|
||||
// Moon position for an observer
|
||||
final pos = getMoonPosition(DateTime.now(), 51.5074, -0.1278, elevation: 10);
|
||||
print('Azimuth: ${pos.azimuth.toStringAsFixed(1)}');
|
||||
print('Azimuth: ${pos.azimuth.toStringAsFixed(1)}');
|
||||
print('Altitude: ${pos.altitude.toStringAsFixed(1)}');
|
||||
print('Distance: ${pos.distance.toStringAsFixed(0)} km');
|
||||
|
||||
// Crescent visibility estimate (pass a post-sunset time)
|
||||
final vis = getMoonVisibilityEstimate(
|
||||
DateTime.utc(2025, 3, 31, 18, 30),
|
||||
21.4225, 39.8262, // Mecca
|
||||
21.4225, 39.8262, // Makkah
|
||||
);
|
||||
print('Zone: ${vis.zone.label}'); // A through D
|
||||
print('Zone: ${vis.zone.label}'); // A through D
|
||||
print('Visible naked eye: ${vis.isVisibleNakedEye}');
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### getMoonPhase([DateTime? date])
|
||||
Five public functions. See the [API Reference](https://github.com/acamarata/moon-sighting-dart/wiki/API-Reference) for full field tables.
|
||||
|
||||
Returns `MoonPhaseResult` with:
|
||||
|
||||
| Field | Type | Description |
|
||||
| Function | Returns | Description |
|
||||
| --- | --- | --- |
|
||||
| `phase` | `MoonPhaseName` | Enum: newMoon, waxingCrescent, firstQuarter, etc. |
|
||||
| `phaseName` | `String` | Human-readable name |
|
||||
| `phaseSymbol` | `String` | Moon emoji |
|
||||
| `illumination` | `double` | Percent illuminated (0-100) |
|
||||
| `age` | `double` | Hours since last new moon |
|
||||
| `elongationDeg` | `double` | Moon-Sun elongation in degrees |
|
||||
| `isWaxing` | `bool` | True when illumination is increasing |
|
||||
| `nextNewMoon` | `DateTime` | Next new moon (UTC) |
|
||||
| `nextFullMoon` | `DateTime` | Next full moon (UTC) |
|
||||
| `prevNewMoon` | `DateTime` | Previous new moon (UTC) |
|
||||
|
||||
### getMoonPosition(DateTime? date, double lat, double lon, {double elevation = 0})
|
||||
|
||||
Returns `MoonPosition` with:
|
||||
|
||||
| Field | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `azimuth` | `double` | Degrees from North, clockwise |
|
||||
| `altitude` | `double` | Degrees above horizon (refraction applied) |
|
||||
| `distance` | `double` | Earth-Moon distance in km |
|
||||
| `parallacticAngle` | `double` | Parallactic angle in radians |
|
||||
|
||||
### getMoonIllumination([DateTime? date])
|
||||
|
||||
Returns `MoonIlluminationResult` with:
|
||||
|
||||
| Field | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `fraction` | `double` | Illuminated fraction (0-1) |
|
||||
| `phase` | `double` | Phase cycle (0=new, 0.25=Q1, 0.5=full, 0.75=Q3) |
|
||||
| `angle` | `double` | Bright limb position angle (radians) |
|
||||
| `isWaxing` | `bool` | True when waxing |
|
||||
|
||||
### getMoonVisibilityEstimate(DateTime? date, double lat, double lon, {double elevation = 0})
|
||||
|
||||
Returns `MoonVisibilityEstimate` with:
|
||||
|
||||
| Field | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `v` | `double` | Odeh V parameter |
|
||||
| `zone` | `OdehZone` | Visibility zone (a through d) |
|
||||
| `description` | `String` | Zone description |
|
||||
| `isVisibleNakedEye` | `bool` | True for zone A |
|
||||
| `isVisibleWithOpticalAid` | `bool` | True for zones A and B |
|
||||
| `arcl` | `double` | Sun-Moon elongation (degrees) |
|
||||
| `arcv` | `double` | Arc of vision (degrees) |
|
||||
| `w` | `double` | Crescent width (arc minutes) |
|
||||
| `moonAboveHorizon` | `bool` | Moon above horizon at given time |
|
||||
|
||||
### getMoon(DateTime? date, double lat, double lon, {double elevation = 0})
|
||||
|
||||
Returns `MoonSnapshot` combining all four results: `phase`, `position`, `illumination`, `visibility`.
|
||||
|
||||
## Visibility Criteria
|
||||
|
||||
The Odeh criterion (2006) classifies crescent visibility into four zones:
|
||||
|
||||
| Zone | V threshold | Meaning |
|
||||
| --- | --- | --- |
|
||||
| A | V >= 5.65 | Visible with naked eye |
|
||||
| B | V >= 2.00 | Visible with optical aid, may be seen naked eye |
|
||||
| C | V >= -0.96 | Visible with optical aid only |
|
||||
| D | V < -0.96 | Not visible even with optical aid |
|
||||
|
||||
The Yallop q-test (1997) uses six categories A through F with different threshold semantics. Both criteria use the same underlying polynomial for the minimum arc of vision as a function of crescent width.
|
||||
| `getMoonPhase([DateTime?])` | `MoonPhaseResult` | Phase name, illumination, age, next events |
|
||||
| `getMoonPosition(DateTime?, lat, lon)` | `MoonPosition` | Topocentric az/alt, distance |
|
||||
| `getMoonIllumination([DateTime?])` | `MoonIlluminationResult` | Fraction, phase cycle, bright limb angle |
|
||||
| `getMoonVisibilityEstimate(DateTime?, lat, lon)` | `MoonVisibilityEstimate` | Odeh V parameter, visibility zone A-D |
|
||||
| `getMoon(DateTime?, lat, lon)` | `MoonSnapshot` | All four results combined |
|
||||
|
||||
## Accuracy
|
||||
|
||||
All positions use Meeus (1998) approximations:
|
||||
|
||||
- **Sun:** < 0.01 deg ecliptic longitude error
|
||||
- **Moon:** < 0.3 deg longitude, < 0.2 deg latitude
|
||||
- **Distance:** ~300 km error (~0.08%)
|
||||
- **New/full moon times:** within ~2 hours
|
||||
|
||||
The GCRS-to-topocentric conversion uses a simplified Earth rotation (ERA only, no nutation/precession), adding ~1 deg systematic error. This is acceptable for phase displays, illumination calculations, and approximate visibility estimates.
|
||||
|
||||
For high-precision crescent sighting reports with DE442S ephemeris accuracy, see the TypeScript [moon-sighting](https://github.com/acamarata/moon-sighting) package.
|
||||
|
||||
## Lite Mode vs Full Mode
|
||||
|
||||
This Dart package implements lite mode only. It covers moon phase, position, illumination, and quick visibility estimates using analytical Meeus algorithms with no external data files.
|
||||
|
||||
The full-mode features (DE442S JPL ephemeris, sub-arcsecond accuracy, rise/set event finding, best-time optimization, full sighting reports) are available in the TypeScript package.
|
||||
|
||||
## Architecture
|
||||
|
||||
Two-mode design: lite mode uses Jean Meeus Chapters 47 and 48 for moon phase, position, and illumination: zero dependencies, no file I/O, works in any Dart environment. The GCRS-to-topocentric conversion applies ERA-only Earth rotation (no full nutation/precession), which introduces a ~1 degree systematic error acceptable for display and quick-estimate use cases.
|
||||
|
||||
Full-mode features (DE442S ephemeris, sub-arcsecond accuracy, rise/set event finding) are in the TypeScript [moon-sighting](https://github.com/acamarata/moon-sighting) package.
|
||||
|
||||
## Compatibility
|
||||
|
||||
- Dart SDK >= 3.7.0
|
||||
- Works in Flutter, Dart CLI, and server-side Dart
|
||||
- Zero runtime dependencies
|
||||
All positions use Meeus (1998) approximations: Moon longitude < 0.3 deg, latitude < 0.2 deg, distance ~300 km. New/full moon times are within ~2 hours.
|
||||
|
||||
## Related
|
||||
|
||||
- [moon-sighting](https://github.com/acamarata/moon-sighting) (TypeScript) - Full-accuracy lunar crescent visibility with DE442S ephemeris
|
||||
- [nrel-spa](https://github.com/acamarata/nrel-spa) (TypeScript) - Pure JS NREL Solar Position Algorithm
|
||||
- [pray-calc](https://github.com/acamarata/pray-calc) (JavaScript) - Islamic prayer time calculation
|
||||
- [luxon-hijri](https://github.com/acamarata/luxon-hijri) (TypeScript) - Hijri/Gregorian calendar conversion
|
||||
- [moon-sighting](https://github.com/acamarata/moon-sighting) (TypeScript) - Full accuracy with DE442S ephemeris
|
||||
- [nrel-spa](https://github.com/acamarata/nrel-spa) (TypeScript) - NREL Solar Position Algorithm
|
||||
- [pray-calc](https://github.com/acamarata/pray-calc) (TypeScript) - Islamic prayer times
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
Crescent visibility criteria implemented from:
|
||||
Crescent visibility criteria from:
|
||||
|
||||
- B.D. Yallop, "A Method for Predicting the First Sighting of the New Crescent Moon," NAO Technical Note No. 69, 1997.
|
||||
- M.Sh. Odeh, "New Criterion for Lunar Crescent Visibility," Experimental Astronomy 18(1), 39-64, 2006.
|
||||
|
||||
Meeus positions from: Jean Meeus, "Astronomical Algorithms," 2nd ed., Chapters 47 and 48.
|
||||
- Jean Meeus, "Astronomical Algorithms," 2nd ed., Chapters 47 and 48.
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue