ascii-side-of-the-moon 1.0.9 → 1.0.11
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/README.md +23 -2
- package/dist/cli.cjs +49 -14
- package/dist/index.cjs +9 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -4
- package/dist/index.d.ts +22 -4
- package/dist/index.mjs +9 -9
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference frame for viewing the moon.
|
|
3
|
+
* - celestial_up: Standard geocentric orientation with celestial north up
|
|
4
|
+
* - celestial_down: Inverted geocentric orientation with celestial south up
|
|
5
|
+
* - observer: Observer-relative orientation with zenith up, uses lat/lon to calculate parallactic angle
|
|
6
|
+
*/
|
|
7
|
+
type Frame = "celestial_up" | "celestial_down" | "observer";
|
|
1
8
|
interface MoonLibration {
|
|
2
9
|
/** Ecliptic longitude libration (degrees). */
|
|
3
10
|
elon: number;
|
|
@@ -57,8 +64,16 @@ interface RenderOptions {
|
|
|
57
64
|
invert?: boolean;
|
|
58
65
|
/** If true, prefer legacy block elements instead of twelfth-circle glyphs. (Unused now.) */
|
|
59
66
|
forceLegacySymbols?: boolean;
|
|
60
|
-
/** Controls whether the renderer draws the horizon overlay (default true). */
|
|
67
|
+
/** Controls whether the renderer draws the horizon overlay (default true for observer frame). */
|
|
61
68
|
showHorizon?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Reference frame for viewing the moon.
|
|
71
|
+
* - celestial_up: Standard geocentric orientation with celestial north up (no parallactic rotation)
|
|
72
|
+
* - celestial_down: Inverted geocentric orientation with celestial south up (180° rotation)
|
|
73
|
+
* - observer: Observer-relative orientation with zenith up (uses parallactic angle from MoonState.position)
|
|
74
|
+
* Defaults to 'observer' if MoonState.position is available, 'celestial_up' otherwise.
|
|
75
|
+
*/
|
|
76
|
+
frame?: Frame;
|
|
62
77
|
}
|
|
63
78
|
|
|
64
79
|
declare function getMoonState(date: Date, observerLocation?: ObserverLocation): MoonState;
|
|
@@ -82,8 +97,11 @@ declare function getMoonPhase(moonState: MoonState): string;
|
|
|
82
97
|
* 2. Calculate sun direction in CELESTIAL frame (standard north-up orientation)
|
|
83
98
|
* 3. Apply Lambertian phase lighting to create illumination mask (in celestial frame)
|
|
84
99
|
* 4. Combine texture with phase mask (both in celestial frame)
|
|
85
|
-
* 5. Rotate the COMBINED result
|
|
86
|
-
*
|
|
100
|
+
* 5. Rotate the COMBINED result based on frame:
|
|
101
|
+
* - celestial_up: no rotation (celestial north up)
|
|
102
|
+
* - celestial_down: 180° rotation (celestial south up)
|
|
103
|
+
* - observer: rotate by parallactic angle to match observer's view (zenith up)
|
|
104
|
+
* 6. Optionally overlay horizon line (only for observer frame)
|
|
87
105
|
*
|
|
88
106
|
* Key insight: The phase illumination is a property of the moon itself (which physical
|
|
89
107
|
* areas are lit by the sun). When we rotate the moon's appearance for the observer,
|
|
@@ -92,4 +110,4 @@ declare function getMoonPhase(moonState: MoonState): string;
|
|
|
92
110
|
*/
|
|
93
111
|
declare function renderMoon(state: MoonState, _options?: RenderOptions): string;
|
|
94
112
|
|
|
95
|
-
export { type MoonLibration, type MoonPhase, type MoonPosition, type MoonSize, type MoonState, type ObserverLocation, type RenderOptions, getMoonPhase, getMoonState, renderMoon };
|
|
113
|
+
export { type Frame, type MoonLibration, type MoonPhase, type MoonPosition, type MoonSize, type MoonState, type ObserverLocation, type RenderOptions, getMoonPhase, getMoonState, renderMoon };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference frame for viewing the moon.
|
|
3
|
+
* - celestial_up: Standard geocentric orientation with celestial north up
|
|
4
|
+
* - celestial_down: Inverted geocentric orientation with celestial south up
|
|
5
|
+
* - observer: Observer-relative orientation with zenith up, uses lat/lon to calculate parallactic angle
|
|
6
|
+
*/
|
|
7
|
+
type Frame = "celestial_up" | "celestial_down" | "observer";
|
|
1
8
|
interface MoonLibration {
|
|
2
9
|
/** Ecliptic longitude libration (degrees). */
|
|
3
10
|
elon: number;
|
|
@@ -57,8 +64,16 @@ interface RenderOptions {
|
|
|
57
64
|
invert?: boolean;
|
|
58
65
|
/** If true, prefer legacy block elements instead of twelfth-circle glyphs. (Unused now.) */
|
|
59
66
|
forceLegacySymbols?: boolean;
|
|
60
|
-
/** Controls whether the renderer draws the horizon overlay (default true). */
|
|
67
|
+
/** Controls whether the renderer draws the horizon overlay (default true for observer frame). */
|
|
61
68
|
showHorizon?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Reference frame for viewing the moon.
|
|
71
|
+
* - celestial_up: Standard geocentric orientation with celestial north up (no parallactic rotation)
|
|
72
|
+
* - celestial_down: Inverted geocentric orientation with celestial south up (180° rotation)
|
|
73
|
+
* - observer: Observer-relative orientation with zenith up (uses parallactic angle from MoonState.position)
|
|
74
|
+
* Defaults to 'observer' if MoonState.position is available, 'celestial_up' otherwise.
|
|
75
|
+
*/
|
|
76
|
+
frame?: Frame;
|
|
62
77
|
}
|
|
63
78
|
|
|
64
79
|
declare function getMoonState(date: Date, observerLocation?: ObserverLocation): MoonState;
|
|
@@ -82,8 +97,11 @@ declare function getMoonPhase(moonState: MoonState): string;
|
|
|
82
97
|
* 2. Calculate sun direction in CELESTIAL frame (standard north-up orientation)
|
|
83
98
|
* 3. Apply Lambertian phase lighting to create illumination mask (in celestial frame)
|
|
84
99
|
* 4. Combine texture with phase mask (both in celestial frame)
|
|
85
|
-
* 5. Rotate the COMBINED result
|
|
86
|
-
*
|
|
100
|
+
* 5. Rotate the COMBINED result based on frame:
|
|
101
|
+
* - celestial_up: no rotation (celestial north up)
|
|
102
|
+
* - celestial_down: 180° rotation (celestial south up)
|
|
103
|
+
* - observer: rotate by parallactic angle to match observer's view (zenith up)
|
|
104
|
+
* 6. Optionally overlay horizon line (only for observer frame)
|
|
87
105
|
*
|
|
88
106
|
* Key insight: The phase illumination is a property of the moon itself (which physical
|
|
89
107
|
* areas are lit by the sun). When we rotate the moon's appearance for the observer,
|
|
@@ -92,4 +110,4 @@ declare function getMoonPhase(moonState: MoonState): string;
|
|
|
92
110
|
*/
|
|
93
111
|
declare function renderMoon(state: MoonState, _options?: RenderOptions): string;
|
|
94
112
|
|
|
95
|
-
export { type MoonLibration, type MoonPhase, type MoonPosition, type MoonSize, type MoonState, type ObserverLocation, type RenderOptions, getMoonPhase, getMoonState, renderMoon };
|
|
113
|
+
export { type Frame, type MoonLibration, type MoonPhase, type MoonPosition, type MoonSize, type MoonState, type ObserverLocation, type RenderOptions, getMoonPhase, getMoonState, renderMoon };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import*as
|
|
1
|
+
import*as z from'astronomy-engine';var o=z.default??z;function Y($,g){let n=new Date($.getTime());return n.setDate(n.getDate()+g),n}function j($){return ($%360+360)%360}function G($){let g=o.GeoVector(o.Body.Sun,$,true),n=o.GeoVector(o.Body.Moon,$,true),_=o.EquatorFromVector(g),t=o.EquatorFromVector(n),B=(_.ra-t.ra)*15*o.DEG2RAD,e=t.dec*o.DEG2RAD,s=_.dec*o.DEG2RAD,a=Math.sin(B),i=Math.cos(B),r=a,l=Math.cos(e)*Math.tan(s)-Math.sin(e)*i,m=Math.atan2(r,l)*o.RAD2DEG;return j(m)}function H($){let g=($%24+24)%24;return g>12&&(g-=24),g}function v($){let g=o.Illumination(o.Body.Moon,$).phase_fraction;return o.Illumination(o.Body.Moon,Y($,1)).phase_fraction>g}function J($,g,n){let _=o.SiderealTime($),t=g.longitude/15,B=H(t+_-n.ra)*15*o.DEG2RAD,e=g.latitude*o.DEG2RAD,s=n.dec*o.DEG2RAD,a=Math.sin(B),i=Math.tan(e)*Math.cos(s)-Math.sin(s)*Math.cos(B);return Math.atan2(a,i)*o.RAD2DEG}function V($,g){let n=new o.Observer(g.latitude,g.longitude,g.elevationMeters??0),_=o.Equator(o.Body.Moon,$,n,true,true),t=o.Horizon($,n,_.ra,_.dec,"normal");return {azimuth:j(t.azimuth),altitude:t.altitude,parallacticAngle:J($,g,_)}}function Q($,g){let n=o.Illumination(o.Body.Moon,$),_=o.Libration($);return {date:$,phase:{phaseAngleDeg:n.phase_angle,illuminatedFraction:n.phase_fraction,isWaxing:v($),brightLimbAngle:G($)},size:{distanceKm:_.dist_km,angularDiameterDeg:_.diam_deg},libration:{elon:_.elon,elat:_.elat},position:g?V($,g):void 0}}function I($){let{phaseAngleDeg:g,illuminatedFraction:n}=$.phase,_=$.phase.isWaxing??g>90,t=(g%360+360)%360,R=t>180?360-t:t,B=10,e=10,s=8,a=.98,i=.02,r=.02;return R<=B||n>=a?"Full Moon":R>=180-e||n<=i?"New Moon":Math.abs(R-90)<=s||Math.abs(n-.5)<=r?_?"First Quarter":"Last Quarter":R<90?_?"Waxing Gibbous":"Waning Gibbous":_?"Waxing Crescent":"Waning Crescent"}var Z={moons:[{index:0,distance_km:405493.5,libration_elat:-0.888,libration_elon:-0.412,ascii:`
|
|
2
2
|
|
|
3
3
|
._ . - .
|
|
4
4
|
,_++> a, +. \`-.
|
|
@@ -894,12 +894,12 @@ import*as T from'astronomy-engine';var s=T.default??T;function p($,g){let n=new
|
|
|
894
894
|
'FFF'"Z"@MGR^^'\`
|
|
895
895
|
|
|
896
896
|
|
|
897
|
-
`}]};var c=60,
|
|
898
|
-
`),n=1/0,
|
|
899
|
-
`),B=R.length,
|
|
900
|
-
`)}function
|
|
901
|
-
`),
|
|
902
|
-
`);
|
|
903
|
-
`),
|
|
904
|
-
`)}function
|
|
897
|
+
`}]};var c=60,A=29,p=-45;function q($){let g=$.split(`
|
|
898
|
+
`),n=1/0,_=-1/0,t=1/0,R=-1/0;if(g.forEach((s,a)=>{let i=s.search(/\S/);if(i!==-1){let r=s.search(/\s+$/);n=Math.min(n,i),_=Math.max(_,r===-1?s.length-1:r-1),t===1/0&&(t=a),R=a;}}),n===1/0)return {width:c,height:A,centerX:Math.floor(c/2),centerY:Math.floor(A/2)};let B=_-n+1,e=R-t+1;return {width:B,height:e,centerX:n+Math.floor(B/2),centerY:t+Math.floor(e/2)}}function X($,g,n){return Math.min(n,Math.max(g,$))}function T($){return $*Math.PI/180}function C($,g,n,_=0){let t=T($),R=T(_),B;g!==void 0?B=T(g):B=T(n?270:90);let e=-Math.sin(B),s=-Math.cos(B),a=e*Math.sin(t),i=s*Math.sin(t),r=Math.cos(t),l=i*Math.cos(R)-r*Math.sin(R),m=i*Math.sin(R)+r*Math.cos(R);i=l,r=m;let W=Math.sqrt(a*a+i*i+r*r);return {sx:a/W,sy:i/W,sz:r/W}}function U($,g,n,_,t){let R=1/c,B=1/A,e=[-0.5,-0.25,0,.25,.5],s=0,a=0;for(let i of e)for(let r of e){let l=$+i*R,m=g+r*B,W=l*l+m*m;if(W>1)continue;let d=Math.sqrt(Math.max(0,1-W)),f=l*n+m*_+d*t;s+=Math.max(0,f),a++;}return a===0?0:s/a}function O($){let _=0,t=1/0;for(let R=0;R<Z.moons.length;R++){let B=Z.moons[R],e=Math.abs(B.distance_km-$.size.distanceKm)*1,s=Math.abs(B.libration_elat-$.libration.elat)*1e4,a=Math.abs(B.libration_elon-$.libration.elon)*1e4,i=e+s+a;i<t&&(t=i,_=R);}return Z.moons[_]}var P=22/10;function D($,g,n,_){let t=(g%360+360)%360;if(Math.abs(t)<.1)return $;let R=$.split(`
|
|
899
|
+
`),B=R.length,e=R[0]?.length??0,s=n??(e-1)/2,a=_??(B-1)/2,i=t*Math.PI/180,r=Math.cos(i),l=Math.sin(i),m=Array.from({length:B},()=>Array(e).fill(" "));for(let W=0;W<B;W++)for(let d=0;d<e;d++){let f=d-s,F=(W-a)*P,h=f*r-F*l,x=f*l+F*r,w=Math.round(h+s),M=Math.round(x/P+a);if(w>=0&&w<e&&M>=0&&M<B){let y=R[M]?.[w]??" ";m[W][d]=y;}}return m.map(W=>W.join("")).join(`
|
|
900
|
+
`)}function $$($,g){return g.frame!==void 0?g.frame:$.position!==void 0?"observer":"celestial_up"}function n$($,g={}){let n=g??{},_=$$($,n),t=n.showHorizon??_==="observer",R=O($),B=q(R.ascii),e=R.ascii;Math.abs(p)>.1&&(e=D(e,p,B.centerX,B.centerY));let s=e.split(`
|
|
901
|
+
`),{sx:a,sy:i,sz:r}=C($.phase.phaseAngleDeg,$.phase.brightLimbAngle,$.phase.isWaxing,$.libration.elat),l=Array.from({length:A},()=>Array(c).fill(0)),m=Array.from({length:A},()=>Array(c).fill(-1)),W=Array.from({length:A},()=>Array(c).fill(false)),d=0,f=0;for(let M=0;M<A;M++)for(let y=0;y<c;y++){let b=y-B.centerX,E=M-B.centerY,u=b/(B.width/2),K=E/(B.height/2),k=u*u+K*K;if(k>1){l[M][y]=0,m[M][y]=-1;continue}W[M][y]=true,d++;let L=U(u,K,a,i,r);l[M][y]=L,L>0&&f++;let N=Math.sqrt(Math.max(0,1-k));m[M][y]=u*a+K*i+N*r;}let F=Array.from({length:A},()=>Array(c).fill(false));if(f>0)for(let M=0;M<A;M++)for(let y=0;y<c;y++)F[M][y]=l[M][y]>0;else {let M=X($.phase.illuminatedFraction??0,0,1),y=Math.max(1,Math.round(M*d)),b=[];for(let E=0;E<A;E++)for(let u=0;u<c;u++)W[E][u]&&b.push({ix:u,iy:E,v:m[E][u]});b.sort((E,u)=>u.v-E.v);for(let E=0;E<Math.min(y,b.length);E++){let{ix:u,iy:K}=b[E];F[K][u]=true;}}let h=[];for(let M=0;M<A;M++){let y="",b=s[M]??"";for(let E=0;E<c;E++)F[M][E]?y+=b[E]??" ":y+=" ";h.push(y);}let x=h.join(`
|
|
902
|
+
`),w=0;return _==="celestial_down"?w=180:_==="observer"&&$.position?.parallacticAngle!==void 0&&(w=-$.position.parallacticAngle),Math.abs(w)>.1&&(x=D(x,w,B.centerX,B.centerY)),t?g$(x,$,B):x}function g$($,g,n){let _=g.position;if(!_||g.size.angularDiameterDeg<=0)return $;let t=_.altitude??0,R=g.size.angularDiameterDeg/2,B=t+R;if(t-R>=0)return $;let s=$.split(`
|
|
903
|
+
`),a=g.size.angularDiameterDeg/Math.max(1,n.height),i=n.centerY+t/a;i=Math.round(X(i,0,A-1));let r;return B<=0?r=`${Math.abs(t).toFixed(1).replace(/\.0$/,"")}-deg-below-horizon`:r="horizon",s[i]=_$(r),s.join(`
|
|
904
|
+
`)}function _$($){let n=`--${$.trim().replace(/\s+/g,"-")}--`;if(n.length>c&&(n=n.slice(0,c)),n.length===c)return n;let _=c-n.length,t=Math.floor(_/2),R=_-t;return "-".repeat(t)+n+"-".repeat(R)}export{I as getMoonPhase,Q as getMoonState,n$ as renderMoon};//# sourceMappingURL=index.mjs.map
|
|
905
905
|
//# sourceMappingURL=index.mjs.map
|