#!perl -w

# Copyright 2010, 2011 Kevin Ryde

# This file is part of Math-Image.
#
# Math-Image is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3, or (at your option) any later
# version.
#
# Math-Image is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with Math-Image.  If not, see <http://www.gnu.org/licenses/>.

use 5.004;
use strict;
use App::MathImage;
use vars '$VERSION';
$VERSION = 67;
exit App::MathImage->command_line;

__END__

=for stopwords recurrences Gtk Gtk2 Ulam's --ulam Ulam sprial Vogel pronic
--pronic fibonacci --fibonacci fullscreen --fullscreen unfullscreened --png
png --xpm xpm RGB menubar toplevel colormap Ryde ie perrin --perrin padovan
--padovan Perrin Padovan Vogel's --vogel Archimedian WIDTHxHEIGHT
--theodorus Theodorus semiprimes segfault Aronson's --aronson startup
GdkPixbuf prima Prima --prima tty renamings MathImageFoo

=head1 NAME

math-image -- display some mathematical images

=head1 SYNOPSIS

 math-image [--options]

=head1 DESCRIPTION

C<math-image> displays some mathematical images, either in a Gtk2 GUI, as an
image file output, or setting the root window.

There's lots of options for what to display, in particular including Ulam's
spiral of prime numbers, and variations on the numbers in a path theme
including Sacks spiral and Vogel floret.  Try C<--random> or the Randomize
button for interesting combinations.

Most of the code is plain Perl, so it's not blindingly fast, but the GUI or
the root window are drawn progressively so you can see what's happening.  In
the GUI you can change the controls while drawing to start again on
something else.

Mouse button 1 in the GUI drags the image to see parts away from the origin
and which otherwise wouldn't fit on screen.  This can become particularly
slow when displaying things like prime numbers which must be calculated all
the way up to the desired part.

=head1 OPTIONS

=head2 Values Options

The following otpions control what set of values to display.  The
C<--values> option described last is the most general.

=over

=item --primes

The prime numbers.

=item --twin

=item --twin1

=item --twin2

The twin primes.  C<--twin> is both twins like 11,13.  C<--twin1> is just
the first of each like 11, or C<--twin2> is just the second like 13.

=item --semi-primes

=item --semi-primes-odd

The semi-prime or bi-prime numbers, meaning integers which have two prime
factors p*q, including p==q squares of primes.  C<--semi-primes-odd> is just
the odd semiprimes.

=item --squares

The perfect squares 1, 4, 9, 16, 25, 36, etc.

=item --pronic

The pronic numbers 2, 6, 12, 20, 30, 42, etc, k*(k+1).  These are half way
between successive perfect squares, and twice the triangular numbers.

=item --triangular

The triangular numbers 1, 3, 6, 10, 15, 21, etc, k*(k+1)/2.

=item --polygonal=K

The K-sided polygon numbers.  For example C<--polygonal=3> is the triangular
numbers, C<--polygonal=4> is the squares.

=item --cubes

=item --tetrahedral

The cubes 1, 8, 27, 64, 125, etc or tetrahedral numbers 1, 4, 10, 20, 35,
56, etc.  These tend to grow too quickly to display much of a pattern,
though the Vogel floret is close,

    math-image --cubes --vogel

=item --fibonacci

The Fibonacci numbers 1,1,2,3,5,8,13,21, etc.  On the Vogel floret these
fall on an axis going to the right.  For other spirals and paths they tend
to grow too quickly to show much.

=item --perrin

=item --padovan

The Perrin numbers 3, 0, 2, 3, 2, 5, 5, 7, 10, etc.  Or Padovan numbers 1,
1, 1, 2, 2, 3, 4, 5, 7, 9, etc.  These are cubic recurrences and tend to
grow too quickly to display much in the way of patterns.

=item --fraction=5/29

=item --fraction=1.234

The digits in the decimal expansion of a fraction.  For example the default
in the GUI is 5/29 which means 9,11,12, 17, 21,22,24, 27,28,29,30, etc.
A decimal like 1.234 means 1234/1000.

A fraction is always a repeating pattern, with length no longer than the
denominator, but can give interesting patterns for various paths.  For
example in the Corner path the fine structure constant 1/137 in binary is a
repeating pattern of an angry man with a beard and a skull wearing a hat.
No doubt this has deep cosmic significance.

    math-image --corner --values=FractionDigits,radix=2,fraction=1/137

=item --all

=item --odd

=item --even

All integers, or just odd or even integers.  For the paths which fill the
plane C<--all> will just fill the screen (slowly!), but for C<--sacks> and
C<--vogel> it shows where all the points lie.

=item --aronson

Aronson's sequence 1,4,9,... of "T is the first, fourth, ninth, ...".  This
requires the C<Math::Aronson> module.

=item --expression='x^2+2*x+1'

Draw values following a formula.  It should have a single variable which
will be evaluated at 0,1,2, etc.  This option requires C<Math::Symbolic>.

=item --lines

Draw lines along the path instead of a set of selected points.  This shows
where a path travels but you may have to increase the C<--scale> to see it
properly.

=item --values=MODULE

=item --values=MODULE,NAME=VALUE,NAME=VALUE,...

Draw values from the given C<App::MathImage::NumSeq> module.  For
example

    math-image --values=Emirps

The names for these modules are not settled, so expect some splits, mergers
or renamings.  Parameters can be passed as comma separated NAME=VALUE, for
example

    math-image --values=TwinPrimes,pairs=both

This can be used to read values from a text file

    math-image --values=File,filename=/my/dir/data.txt

And the OEIS module takes a sequence of values by its OEIS A-number, for
example tribonnaci numbers A000073

    math-image --values=OEIS,anum=A000073

This selects whichever module implements the desired sequence, or will read
downloaded OEIS files from a F<$HOME/OEIS/> directory,

    A000073.internal     # for info
    A000073.html         # fragile for info, but accepted
    b000073.txt          # values file, if available

A F<.internal> file is the "internal format" OEIS info download.  The
F<.html> rendition of the same works, but parsing it is likely to be fragile
and may or may not work.

=back

=head2 Path Options

The following control the path in the plane where on which the values will
be displayed.  The C<--path> option described last is the most general.

=over 4

=item --ulam

Ulam's primes in a square spiral (currently the default).

=item --vogel

Vogel's floret design for the positions of seeds in a sunflower (see
L<Math::PlanePath::VogelFloret>).  Try the following to see all the points
in the pattern before applying various special sets of values.

    math-image --vogel --all --scale=10

Scaling up helps the circles draw properly.  When the values displayed are
less than all the integers a lower scale can be used.

=item --sacks

An Archimedian spiral with the square root as angle of rotation, by Robert
Sacks (see L<Math::PlanePath::SacksSpiral>).

=item --theodorus

The spiral of Theodorus or square-root spiral (see
L<Math::PlanePath::TheodorusSpiral>).

=item --diamond

A diamond shaped spiral (see L<Math::PlanePath::DiamondSpiral>).

=item --pyramid

The sides of a pyramid shape (see L<Math::PlanePath::PyramidSides>).

=item --pyramid-rows

A pyramid made from horizontal rows (see L<Math::PlanePath::PyramidRows>).

=item --corner

=item --diagonals

Corners or diagonals between the X and Y axes, per
L<Math::PlanePath::Corner> and L<Math::PlanePath::Diagonals>.

=item --rows

=item --columns

Points drawn in successive rows or columns.

=item --path=MODULE

=item --path=MODULE,NAME=VALUE,NAME=VALUE,...

Draw following the given C<Math::PlanePath> module.  For example

    math-image --path=HeptSpiralSkewed

This includes experimental paths called "MathImageFoo", but expect their
names to change when finished.

Parameters to the path are supplied as comma separated C<NAME=VALUE>, for
example,

    math-image --path=SquareSpiral,wider=3

=back

=head2 Output Options

The default is to run the Gtk GUI.

=over

=item --fullscreen

Start the GUI in full screen mode.  Menu entry Tools/Fullscreen can toggle
between full screen and a normal window.  In full screen mode the menus
still work, just press Alt-F, Alt-T, etc as normal.

=item --root

Set the root window background to the requested image and exit.  For example
a random image from your F<~/.xsession> file,

    math-image --root --random

Add C<--verbose> to print what was in fact chosen and displayed.  Output in
F<~/.xsession> normally goes to the F<~/.xsession-errors> file.  Sometimes
C<--random> may use a lot of memory, so consider a C<limit> (see L<sh(1)>)
or timeout (see L<timeout(1)>), or both.

Under X the root window is set with C<X11::Protocol> if available, otherwise
C<Gtk2>.  C<X11::Protocol> is preferred as it allows C<--foreground> and
C<--background> colours to be preserved on a PseudoColor visual.  C<Gtk2> is
fine on a TrueColor, or using black and white (those colours permanent in
the default colormap), but otherwise colours won't be preserved.

=item --flash

Flash the requested image on the screen instead of starting the GUI.
Together with C<--root> the image is drawn to the root then flashed as well.
This is good if updating the background randomly every so often, as it shows
the image when otherwise obscured by lots of windows.

    math-image --root --random --flash

=item --display=DPY

Select the X server for X11 or Gtk output.  The default is from the
C<DISPLAY> environment variable (normally set at X startup).

    math-image --display=:3

=item --png

=item --xpm

Write a PNG or XPM image file to standard output and exit.  PNG is always
possible with GdkPixbuf but can also use GD, PNGwriter, Imager, ImageMagick,
Prima or Tk with the right libraries and C<Image::Base> supporting module.

    math-image --png >/tmp/my-file.png

XPM output requires either C<Image::Xpm>, ImageMagick, Prima, or Tk.  Note
that Prima and Tk for X11 require an X server even for file output (expect
an obscure error if no display).

=item --text

Write a text-only image to standard output and exit.  The default size
follows the terminal with C<Term::Size>.  A typical tty size like 80x25 is
usually too small to see much, but a bigger image might be cute to send to a
line printer or similar.

    math-image --text --size=130x49 | lpr

=item --prima

Run the Prima GUI.  This requires the C<Prima> and
C<Image::Base::Prima::Drawable> modules.  It doesn't yet have the full set
of options the Gtk GUI does, but works as far as it goes.

A combination C<--prima --png> means write a PNG image to standard output,
using Prima.  This requires a graphics screen (which other PNG output
modules don't).

=item --tk

Run the Tk GUI.  This requires Perl-Tk.  It doesn't yet have the full set of
options the Gtk GUI does, but works as far as it goes.

A combination C<--tk --png> or C<--tk --xpm> means write a PNG or XPM image
to standard output using C<Tk::Photo>.  This requires a graphics screen
though (which other output modules don't).

=item --curses

Run the Curses interactive text interface.  This requires the C<Curses::UI>
modules.  It's experimental and the control options are minimal.

=back

=head2 Other Options

=over

=item --random

Choose a path and values at random.  For example in your F<~/.xsession>

    math-image --root --random

=item --foreground=COLOUR

=item --background=COLOUR

Set the foreground and background colours.  The colours can be either names
or hex style #RRGGBB or #RRRRGGGGBBBB.  For example white on a shade of red,

    math-image --foreground=white --background=#A01010

The default is white foreground on black background.  For a C<--root>
background a full white can be a bit hard on the eye when there's a lot of
points shown.  Try a shade of grey instead

    math-image --root --foreground=lightgrey

Available names depend on the output type.  Gtk uses a hard-coded copy of
the X F</etc/X11/rgb.txt>.  The C<X11::Protocol> C<--root> uses the server's
database.  C<--png> output with GD has the C<GD::Simple> names.  C<--xpm>
passes anything at all through to the file.  For C<--text> currently the
colours can be single characters to show, though perhaps that will change.

=item --size=PIXELS

=item --size=WIDTHxHEIGHT

Set the size of the image in pixels.  A single value means that size square,
otherwise WIDTHxHEIGHT.  For C<--root> this size is currently ignored and
the full screen used.

For the GUI this is an initial size, though it might be widened to
accommodate the menubar.  Under C<--fullscreen> the size is the
unfullscreened window if you switch back to that (menu entry
Tools/Fullscreen).

The default for the GUI is about 4/5 of the screen.  The default for PNG etc
image file output is an arbitrary 200x200, or for C<--text> output the size
of the terminal from C<Term::Size>.

=item --scale=PIXELS

How many pixels for each value shown.  The current default is 3 to show 3x3
pixel squares, or for C<--text> output just 1 for a pixel per character

=item --help, -?

Print a summary of the options.

=item --version

Print the program version number.

=item --<gtk-options>

Standard Gtk options.  See L<gtk-options(7)> for the full list.  The only
one which does much for C<math-image> is C<--display> to set the X display
(default from the C<DISPLAY> environment variable).

=back

=head1 MODULES

In addition to the modules noted above, the following are used in the GUI if
available,

=over

=item C<Gtk2::Ex::PodViewer>

A "Help/POD Documentation" menu item to display this documentation and the
C<Math::PlanePath> classes.

=item C<Gtk2::Ex::CrossHair>

Lines following the cursor, enabled from the Tools/Cross menu item.

=item C<Gtk2::Ex::ErrorTextDialog>

Error messages in a dialog instead of to C<STDERR>.  Of course there
shouldn't be any errors!

=item C<Gtk2::Ex::QuadButton>

Scroll arrows in the bottom right corner.

=back

=head1 ENVIRONMENT

=over

=item C<DISPLAY>

The X display to use.

=back

=head1 BUGS

Some of the values plotted can be a bit slow to generate or use a lot of
memory, or both.  When the path goes out to large positions, or when paged
out away from the origin, the display can hang generating values.  This
happens for example plotting primes on the PythagoreanTree.

=head1 SEE ALSO

L<gtk-options(7)>, L<xsetroot(1)>

L<Math::PlanePath>, L<Math::Aronson>, L<Gtk2>, L<X11::Protocol>,
L<Gtk2::Ex::PodViewer>, L<Gtk2::Ex::CrossHair>, L<Gtk2::Ex::ErrorTextDialog>

=head1 HOME PAGE

http://user42.tuxfamily.org/math-image/index.html

=head1 LICENSE

Math-Image is Copyright 2010, 2011 Kevin Ryde

Math-Image is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

Math-Image is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
more details.

You should have received a copy of the GNU General Public License along with
Math-Image.  If not, see <http://www.gnu.org/licenses/>.

=cut
