# -*-Perl-*- # phase of moon display, ripped off from xphoon # instances allowed: multiple package MGMmodule::phoon; use POSIX; use vars qw($xpm $PI); $PI=3.14159265358979323846; # assume not near black hole nor in Tennessee # called once to initialize the module. The xpath here is a Class. sub module_init{ my$this=shift; my$toplevel=$this->{"toplevel"}; my$xclass=$this->{"xclass"}; $toplevel->optionAdd("$xclass.order", '.2',20); $this; } # called to build an instance. The xpath here is a name path. sub module_instance{ my$this=shift; my$widget=$this->{"widget"}; my$toplevel=$this->{"toplevel"}; my$xpath=$this->{"xpath"}; $toplevel->optionAdd("$xpath.relief", 'sunken' ,21); $toplevel->optionAdd("$xpath.ipad", 20 ,21); $toplevel->optionAdd("$xpath.borderwidth", 1 ,21); $toplevel->optionAdd("$xpath.scalewidadj", 150,21); $toplevel->optionAdd("$xpath.scalelenadj", 60,21); $toplevel->optionAdd("$xpath.scalejustify", 0,20); #centered $this->{"relief"}=$widget->optionGet("relief",''); my$border=$this->{"border"}=$widget->optionGet("borderwidth",''); $this->{"background"}=$widget->optionGet("background",''); $this->{"foreground"}=$widget->optionGet("foreground",''); # use our font and find the labelsize... my$testlabel=$this->{"widget"}->Label(-text=>"99 Mww", -borderwidth=>0, -padx=>1,-pady=>1); my$textheight=$this->{"textheight"}=$testlabel->reqheight; my$textwidth=$this->{"textwidth"}=$testlabel->reqwidth; $testlabel->destroy; my$pad=$widget->optionGet("ipad",""); my$minmoon=35+$pad/5; my$minx=(($textwidth<$minmoon?$minmoon:$textwidth)+$border*2); my$miny=$textheight+$minmoon+$border*2; $toplevel->optionAdd("$xpath.minx", $minx,21); # safe $toplevel->optionAdd("$xpath.miny", $miny,21); # safe $this; } sub module_run{ my$this=shift; my$width=$this->{"width"}; my$height=$this->{"height"}; my$textwidth=$this->{"textwidth"}; my$textheight=$this->{"textheight"}; my$toplevel=$this->{"toplevel"}; my$border=$this->{"border"}; my$back=$this->{"background"}; my$widget=$this->{"widget"}=$toplevel->Canvas(-class=>$this->{"name"}, Name=>$this->{"sequence"}, width=>$width-$border*2, height=>$height-$border*2, borderwidth=>$border, highlightthickness=>0); my$pad=$widget->optionGet("ipad",""); $height-=$textheight; my$square=$width; $square=$height if($square>$height); $square-=$border*2; $square*=(100-$pad)/100; $this->{"square"}=int($square); $this->{"time"}=-1; $this->{"day"}="un"; # build the moon! $this->{"moonxpm"}=MGM::Xpm::data($xpm,'#000000'); $this->{"moonxpm"}->scale($square,$square); my$darkdata=$this->{"moonxpm"}->write('#000','#888',16); $this->{"darkxpm"}=MGM::Xpm::data($darkdata); $this->module_update; $widget; } sub module_update{ my$this=shift; my$t=time; my$widget=$this->{"widget"}; my$square=$this->{"square"}; if($t-$this->{"time"}>60*60){ # once an hour update my$jd = &jtime; my$angphase = &phase($jd); my$cap =cos($angphase); my$height=$this->{"moonxpm"}->height; my$localxpm=$this->{"moonxpm"}->copy; my$r=$square/2; for(my$i=0;$i<$square;$i++){ my$h=($i+.5)-$r; my$x1 = -sqrt($r*$r-$h*$h); my$x2 = -$x1; if ( $angphase >= 0.0 && $angphase < $PI ){ $x2 *= $cap; }else{ $x1 *= $cap; } $x1=floor($r+$x1); $x2=ceil($r+$x2); $localxpm->merge($x1,$i,$this->{"darkxpm"}, $x1,$i,$x2-$x1+1,1); } # got an xpm. Blow it into the widget. my$width=$this->{"width"}; $height=$this->{"height"}; my$textwidth=$this->{"textwidth"}; my$textheight=$this->{"textheight"}; my$localpm=$widget-> Pixmap($widget->PathName.".moon",-data=>$localxpm-> write($this->{"background"},$this->{"foreground"},16)); $widget->delete("moon"); $widget->createImage($width/2-1,($height-$textheight)/2-1, -image=>$localpm,-anchor=>'center', -tags=>['moon']); $this->{"time"}=$t; } # date if($this->{"day"} ne (localtime)[7]){ $widget->delete("date"); my$date=localtime; $date=~s/\S+\s+(\S+)\s+(\d+)\s+\S+\s+(\d+)/$2 $1/; my$width=$this->{"width"}; my$height=$this->{"height"}; my$textwidth=$this->{"textwidth"}; my$textheight=$this->{"textheight"}; my$font=$widget->optionGet("font",""); my$y=$height-($height-$textheight+$square)/2; my$x=int(($width-$textwidth)/2+.5); $widget->createText($width/2-1,$height-$y/2-1,-text=>"$date", -fill=>$this->{"foreground"},-anchor=>'center', -font=>$font,-tags=>['date']); $this->{"day"}=(localtime)[7]; } } # from xphoon by Jef Poskanzer and Craig Leres. # and pom.c (unknown) # xphoon gets the julian date wrong. If I'm in PDT, tz will # negative because I lag GMT, and I want to *add* to my time to get # UTC. Also, DST is already applied; correcting for it again is a # screwup. Avoid it all! Use UTC. # for the record: Julian day zero began at noon UTC BC 4713. The # Julian date measures days since then. The day begins at noon UTC # (thus the -.5 below). # accurate to within about 20 minutes. sub jtime{ my@gmt=gmtime time; &jdate(@gmt)-0.5+ ($gmt[0] + 60 * ($gmt[1] + 60 * $gmt[2])) / 86400.0; } # jdate - convert internal GMT date and time to Julian day and fraction sub jdate{ my(@t)=@_; my($c, $m, $y); $y = $t[5]+1900; $m = $t[4] + 1; if ($m > 2){ $m -= 3; }else { $m += 9; $y--; } $c = int($y / 100); $y -= 100 * $c; $t[3]+int($c*146097/4) + int($y*1461/4) + int(($m*153+2)/5) + 1721119; } # Handy mathematical functions. sub fixangle{ my$a=shift; $a - 360.0 * (floor($a / 360.0)); } sub torad{ my$d=shift; $d*$PI/180.0; } sub todeg{ my$d=shift; $d*180.0/$PI; } # phase - calculate phase of moon as a fraction: # # The argument is the time for which the phase is requested, # expressed as a Julian date and fraction. sub phase{ my$epoch=2446065.5; # 1985 January 0.0 */ my$EPSILONg=279.611371; # solar ecliptic long at EPOCH my$RHOg=282.680403; # solar ecliptic long of perigee at EPOCH my$ECCEN=0.01671542; # solar orbit eccentricity my$lzero=18.251907; # lunar mean long at EPOCH my$Pzero=192.917585; # lunar mean long of perigee at EPOCH my$Nzero=55.204723; # lunar mean long of node at EPOCH my($pdate)=@_; # Calculation of the Sun's position. my$Day = $pdate - $epoch; # date within epoch my$N = &fixangle((360 / 365.2422) * $Day); # mean anomaly of the Sun my$M = &fixangle($N + $EPSILONg - $RHOg); # convert from perigee # co-ordinates to epoch 1980.0 my$Ec=360.0/$PI*$ECCEN*sin(&torad($M)); my$Lambdasun = &fixangle($N+ $Ec + $EPSILONg); # Sun's geocentric ecliptic # longitude # Moon's mean longitude. my$ml = &fixangle(13.1763966 * $Day + $lzero); # Moon's mean anomaly. my$MM = &fixangle($ml - 0.1114041 * $Day - $Pzero); # Evection. my$Ev = 1.2739 * sin(&torad(2 * ($ml - $Lambdasun) - $MM)); # Annual equation. my$Ae = 0.1858 * sin(&torad($M)); # Correction term. my$A3 = 0.37 * sin(&torad($M)); # Corrected anomaly. my$MmP = $MM + $Ev - $Ae - $A3; # Correction for the equation of the centre. my$mEc = 6.2886 * sin(&torad($MmP)); # Another correction term. my$A4 = 0.214 * sin(&torad(2 * $MmP)); # Corrected longitude. my$lP = $ml + $Ev + $mEc - $Ae + $A4; # Variation. my$V = 0.6583 * sin(&torad(2 * ($lP - $Lambdasun))); # True longitude. my$lPP = $lP + $V; # Age of the Moon in degrees. my$MoonAge = $lPP - $Lambdasun; &torad(&fixangle($MoonAge)); } sub kepler{ my($m, $ecc)=@_; my($e, $delta); $e = $m = &torad($m); do { $delta = $e - $ecc * sin($e) - $m; $e -= $delta / (1 - $ecc * cos($e)); } while (abs($delta) > .000001); $e; } $xpm= <<'EOXPM'; /* XPM */ static char * moon_xpm[] = { "71 71 16 1", ". c #020204", "+ c #8C8C8C", "@ c #C9C9CA", "# c #464644", "$ c #A6A6A5", "% c #E7E7E7", "& c #6D6D6C", "* c #1E1E1C", "= c #969697", "- c #DADADA", "; c #B6B6B5", "> c #F7F7F7", ", c #5A5A5C", "' c #7D7D7C", ") c #141414", "! c #2E2E2C", ".............................!#&'$$$==',#*)............................", ".........................!&=;@;$$$;@$;@;-%-$'#)........................", "......................*,$$=='''=''''&&===$$$;@;+#......................", "....................!,'&&'='==$==''&'&&&&'==$$@@@;,*...................", "..................*,&&&&'=$$$=$===$$$=='&&'''=$$;@@@&..................", ".................#,,,&==$=''&='''&'='+==$&&++++$=;@@--,................", "...............*,,,,,'''=&,&,,,&&&''''$;@=++=+''''+=@%%=*..............", "..............#,,,,,''''&,,,,,,&&&&''''$;;$===$$+'''+;%%$!.............", ".............#,,,,,&'&&,,,,,,,&&&&&'&''=$;;$$=$$++'''+;---,............", "...........*#,,#,,,,&,,,&,,,,&&&''&&''==$;;$;;;;;$==+=$$;@@,...........", "..........*,#,,,,,,&,,&&&&&,,&&&''&''=$=$;;;@;@;;$++=;$$$$@-,..........", ".........*###,,&&&&&&&&&,,,&,&&&&&&''====$;@@$;;$$+$==;;;;;@@,.........", "........*,###,&&&&&&&&&&&&&&&&&&'&&''=$==$@;;$;;$=+$;====@@=@-,........", "........####,'=&&&&&&&,&'&&&'&&'&&''==$='=@$'&'$$===$$$==;@$=@@#.......", ".......!,##,&==&&&,,,&&&&&&&&&='''===$$$=$='''''=$===$++;;@;$$@;*......", "......*,,##,&&&&&,&&&=&&'''&''='=$$$==$$==''&'''''''=='';;;;;;$@$......", "......#####,,,&&,&&&''''&''''''''$$$='';;=''''''''''$;'=$;;;;@;;-&.....", ".....!#####,,,&'&&&&&''''+''''''''$$$=$;$'''''''''''$@$$$;-@;@@@@-!....", "....*######,,,&'&,&'''+''''''''''&';;@;;$&&''''''''&'$;;@@@@;@@@;@+....", "....#######,,&&'&&'+;$=++++++'='''$;@@;$=&'&'''''''&&=;@@@@-@@@-;;@#...", "...*,####,,,,&'''&'+=+=====$$$$=;;;;;$$=''''''='''''&=@-@@@@-@@@;;@=...", "...,,####,,,,&==','=;==$$$=;$$+=$$;;$=$===='''='''''&=;--@@;>@@@;$@@*..", "..*',#,,,,,,&=$=''+===$-;===$$+===$='======='''''''''$;@@@@@@@@;@;@-&..", "..#',#,,,,,&'$;$''''==;%-====++='&'==='';@$=;$'''''''$;;$@@$;;@;@@@-@*.", "..&=,##,,,,,'=$''+++=========$'=''==''''+@++$@$$=''''$;$+@-;;;;@;;@@%!.", ".*'=,##,,,,,''=&''+====+=++=$+'=$;;;$''&+++$;$$''='''=$+++@-@@;$++;@-+.", ".!='###,,,,,'''''''+====+''++&'=;@;@;$+'++;;@+'&'&''''=+''$---$'+'$;-@.", ".#=&###,,,,,&&'&'=++$;=++++=+&'=;@;@@;;$=;-@;+'''''''''''';@>%$''''$@>!", ".,=&###,,,,,,&&&&'++$$;;+'++++++$;@;-%;;@@@-;+&'''==''&'&';;-%;'''&=@>,", ".&'',#,&,,,&,,&'''=++++;=++++==+$$;@---%%%--;+''''''''''&&$;@%$'&'&';-&", ".&,',#,,,,,,&&&''=''''+===++=;@;$+=@--@>>>-@;+++++''''''''&+;%@''&&&@-'", "*&&=,##,,,,&&&'&=='''$$;$=$$$$;@==;-%%>>>>%;-=+++'''''''''$+$--+'&&$@@=", "!'''&,,,,,,&&&'';$''=$;==+=%%;%;;@@-%%%-%%%@;$+'+++''''''+$$+--;'&'@@;=", "!'''&,&,,,&&&&&=$=&'==;;=++@-@@@@--@%%------@==+++'+='==''+$+$@@;;;@@;'", "!''=','&&&''&&&'$'&'''$@='+$@;@%%-@@%--------%;=++++=;=''++;;+;@;;;;;@=", "!''++''&''+=&&&'''&'''=;='+=;@@@@@%--%-----%%>%%$=++;>;''+;++'+@@;$=$@=", "!'''++&''+$$'&&&''''''=;;=+$;%-;@%%-%>>%%--%>>%%;++;>--@$$++''&;@;;'=@$", "*&'+'+'''+$+''&&'$@==$=$;'+;@---@-@@->%%%%%>>>-$===@-@-@@='=''&'$;;=$-$", "*&'++''+==$$&''&'$;''===='$$=-----@@%%-%%-%%>%@$$$$--@@@;'=='''&'$$$;-$", "*'+++'++;'&&,&===$=''=====+;$----%%%---%%>>%>>@;;$$---@@@===''''==';$@'", ".&$==++++&,,,&$$=$=====+++'$@--%--%%--%%%>%%>%%%@$;-->>@$$=='''==$$$$;,", ".,+;====+&,&,&$===$;=+''+++---%%%%%%-%%-%>%-%>>>@@;@-%>-$===''===;;$;$!", ".#';===+=&&&,,'='==$+++'++=-%-%%->>-%>%%---%%>>%--@=$@>>@$'''====;;;;=*", ".!'+++$$+&&&&&'=='$+''+'++$;%%--@%%-@-----%%%>>>-;$==;->@;=''==;;$$;;=*", ".*&'++=$=+'&&'$=$'=+'''''+=$@-@--@-@@----%%-%>>>@$==;;--@$===$;--;$;;=.", "..,'++=$$=+&'+;$=++$+'''++=;-@@-%-@---%%%%%-%%>%;$===@%-@@;$==;-@;;;;,.", "..!&'++;@;+++$;'+;;@======$@-@->-@-%%%%>%---%%%%@$==+-%@@@@;=$$;;;@@;!.", "..*&'''+==+$$$+'++$--;$=;@@%%%>>%-%>>>%%----%%%%-$$=+-@;@;@$=$;;;;;@$..", "...,''++=='+$$$'$+=->@;;-%%>-->>>%%>>%%%-@-%>>>-@;@@;;@;@$$$$;$;;$;-,..", "...*&'+++++'$$$;$;@@-%@--%%%>>%%>%%---%%%>%>>>-@@-%%$;-;@++;;$$;$;@@*..", "....,''+++++$;;;;;@@;%--%%>>>>-%>%%-@@%%>>>%%%%>%%@;@@;@@+=--;$$$@@=...", "....!'++'+$$$;;;$$-@;@--%>>>>%%>>%-%%%%>>%-%%%>>%@@@-@%@-$@-@$;;;--!...", ".....,'+&'++$;;;@@;@@--->%>>>%%%%->>>>>>%%>>%-%%@@@@@--%@;@-;;;;@-'....", ".....*&'''+++$;;;;@@@%-@--%>>>>%%%>>%-%%%>>>----%-@@@----;@-@;;;@;*....", "......#''++++$$;;;;@@@-->--%>%>>>>%%-%%---------%-@@@-%%-@@-@;;;@#.....", ".......&''+='++$@;;@-%--%@-%%>>%>>%%%%%>--------%@@@@%>%-@@;@;;@'......", ".......*'''=='+$;;;$$;%%--->%%>>>%%%>>>>>>>>%--%@@@--%%%%@@-;;-$.......", "........!&'=='+$$;=@@@@%>%%>>>>%%%-->-->--------;;;@--%>-@@;=@@*.......", ".........!&==+'$$$;;--;>>%%>>>%%%--@-----@@--%%-@@@---@;;;$@@@!........", "..........#'=$$+$$=;@@@%%%%%-%>%%%%--@--->>---%%%@-@;@;;;$@@;!.........", "...........#'=$$;$$;@;-%---%-%%%------@@->>--%%%-@;$$;$;;$@+!..........", "............#=$;$$$;;@@%--%-------@------@--%>%-@;$$$$$$;==!...........", ".............!==$$;;;@;-%%-@-----@-----------@@;;;;;$;==='*............", "..............!&=$;$$;@--%-@@@------@-@@----@@@@@-@;;=+$&..............", "...............*,=;;$;;@---@--@-@@@@@@@@-@;@;;;@;;=$+$+#...............", ".................*,$$;;$@@-@@@@--@@@@@@@;@@@;;;$+++++&*................", "...................!&$;;@@@@@@@-@@@@@@@@@@@@@@;;'=$&*..................", ".....................*#=;@;------@@@@@@--@@;;@;$$&*....................", "........................!&=;@>>---@@@@@@@@@;$=,!.......................", "...........................!,&=$;;;;;;$$$=&#*..........................", ".................................*!!#!*................................"}; EOXPM bless {};