evolvotron/BUGS 0000644 0001751 0001751 00000005301 11267025132 013316 0 ustar timday timday Known bugs:
- Enlargements seem to need silly amount of memory. Where's it all going ?
- Middle mouse drags sometimes don't seem to have any effect other than
triggering redisplay. Thought to be fixed by MutatableImage serial numbers
(was using pointer value as substitute for object identity before).
- Build dependencies don't seem to be very good; crashes and bad linkage
can sometimes be cleared by touching files or rebuild from clean.
(precompiled headers something to do with this?)
We're at the mercy of qmake here really.
- Simplifying functions sometimes changes their appearance
(implies "is_constant" probably buggy for some functions).
Some random testing of functions before and after simplify would help.
- When using -spheremap mode, middle mouse-button adjustments don't work
as expected (this is because they're not compensated for the projection).
Live with it.
- Gradient type operators produce a real mess when applied to
noise functions. High frequencies in the noise produce big derivatives.
Enlarging up to 4096x4096 sometimes looks a bit more sensible.
- Have yet to find a tool which can display anything other than the
first frame of a Qt-generated MNG format. (Apparently Qt's MNG
actually has nothing to do with the multi-frame PNG format).
- Very rarely image calculations appear to arrive seriously out-of-order.
May be a more of a problem on slower hardware ?
If this is causing trouble, try using "-t 1" command-line option to fix it.
- Example of "interesting" fullscreen bahaviour (Metacity on RedHat9):
Run app fullscreen.
Fire off a fullscreen "Big" display.
Open the properties dialog for the "big" window.
This results in metacity showing the task bar.
Use the task bar to select the main app window into the foreground.
Watch both fullscreen windows battle for supremacy!
This sort of thing is unlikely to be fixed.
- Resizing the evolvotron window queues up crazy numbers of tasks.
This didn't matter too much in 2D mode, but with animations the
memory reserved for each task's render target is considerably larger.
- Undo doesn't always work how you'd expect.
e.g respawn after undo doesn't respawn from what you'd expect.
Undo of a reset or restart doesn't put the mutation parameters & function weightings back how they were.
- Moire patterns & undersampling mean small images can show structures
not actually present in larger resolution versions.
- Once image colours become saturated there's not much which will cause
them to scale back down to sensible ranges, unless you're lucky.
- Recolour behaves strangely sometimes (?)
(e.g spawns all-black images or subtly warped images)
Not seen recently; may be fixed.
evolvotron/BUILD 0000755 0001751 0001751 00000000102 11055517066 013421 0 ustar timday timday #!/bin/sh
PATH=$QTDIR/bin:$PATH
export PATH
./configure && make
evolvotron/LICENSE 0000644 0001751 0001751 00000043131 11055517066 013652 0 ustar timday timday GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program 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 2 of the License, or
(at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
evolvotron/NEWS 0000644 0001751 0001751 00000026120 12100750300 013321 0 ustar timday timday [Most recent at top]
From release 0.6.2:
- Version to 0.6.3
- Files derived from USAGE (evolvotron.html and usage_text.h) are now under
svn control and no longer need to be generated as part of the build of a
fresh checkout.
- Migrated to new SourceForge platform.
Needed: svn switch --relocate https://evolvotron.svn.sourceforge.net/svnroot/evolvotron "svn+ssh://timday@svn.code.sf.net/p/evolvotron/code/"
From release 0.6.1:
- Version to 0.6.2
- CHANGES renamed to NEWS
- License boilerplate managed using "headache"
- Add some "tartan" inspired functions.
- Add pixel/voxel/hex grid quantizing functions.
- Port command line options to boost::program_options,
rationalize commandline options.
- Fix to evolvotron_mutate from Pedro Gimeno.
- Update mkdeb script to work on squeeze
- Functions to be loaded on startup can be specified on the commandline.
- Add option to shuffle startup functions.
From release 0.6.0:
- Version to 0.6.1
- Fix bug in saved functions: quotes missing around version attribute
From release 0.5.1:
- Version to 0.6.0
- Switch to Qt4.
- (Qt4 related) keyboard shortcuts rationalized
many removed, ctrl-modifiers dropped
- (Qt4 related) image displays now have a frame around them
- (Qt4 related) Remove non-standard Qt animated PNG support
- evolvotron_match removed
- Platform specific code (e.g number of processors identification)
isolated in libevolvotron/platform_specific.[h|cpp]
and selected by PLATFORM_LINUX or PLATFORM_BSD
(Fink Qt's __DARWIN_X11__ also detected and used to select PLATFORM_BSD).
- Repository migrated to svn
From release 0.5.0:
- Version to 0.5.1
- Replace not often used frontside heating/cooling buttons with autocooling mechanism.
- Separate tabs for info & license on "About" dialog.
- Better formatting of function properties dialog, and also shows XML function tree.
- Dialog with rendering controls
- Multisampling (antialiasing) options
- -a/-j/-s command line options for autocool/jitter/multisample
- evolvotron_render adds -j/-s to control jitter & multisampling
- Option (-E) of separate thread pool (with different nices: -n/-N) for enlargements.
Task totals for each reported separately.
- Enlargement and solo renderings are fragmented into multiple smaller
jobs to better utilize multiprocessor systems.
- Generally better use of ref-counted QImage and QPixmap.
- Middle-mouse drag adjustments flicker less.
From release 0.4.0:
- Version to 0.5.0
- Lists of functions in alphabetic order.
- New FunctionTop always at top level.
- New functions: Frieze groups.
- Constantness of functions more conservative (less overrides) and hopefully less buggy.
- Final colour space transform range more constrained to keep colours sane.
- More sensible mutation of top level spatial transform (less arbitrary shearing).
- Note that above changes mean old saved functions will appear different.
- New mutation parameter: probability of a function's parameters being reset.
- Code clean up:
- More std::auto_ptr, boost::shared_ptr, boost::ptr_vector. Code is now delete free.
- Get rid of hacked static function registration; uses auto-generated register_all_functions.
- Compute threads use QWaitCondition, not polling.
- Default number of threads is number of processors.
- Compute threads run at lower priority.
- -n command line option to control compute thread priority.
(NB assumes Linux NPTL's non-Posix compliant behaviour of threads NOT sharing a common nice value;
see "man pthreads" on Linux.)
- About dialog displays number of threads.
- Use precompiled headers (build time 2m45s down to 1m45s).
- code_review script
- Set an icon on various dialogs and main frame.
- Add -D (function debug) massively weighting in favour of FunctionNoiseOneChannel. Useful with -x/-X.
- Believed to fix Debian bug #436231 and gentoo #144160
- MutatableImage has serial number (fix problems caused by pointer value being wrongly used as equivalent)
From release 0.3.1:
- Version to 0.4.0
- Lock state moved to mutatable image so is stored in undo history
- Mandelbrot & Julia set only in x,y plane. Julia set uses fixed parameters.
- Add Juliabrot.
- Fix "Randomize" button on "All" functions tab.
- "Favourite" function dialog provides access to -x/-X command-line functionality
- Undo after reset works better
- Fix broken FunctionGradient.
Replace with GradientOfMagnitude, DivergenceOfMagnitude, Divergence, Curl
- Migrate float->double via typedef real
- Always builds with fullscreen option.
From release 0.3.0:
- Version to 0.3.1
- Fix for gcc 3.4
- ./configure made (slightly) more robust
From release 0.2.3:
- Version to 0.3.0
- Get rid of troublesome system call to ../VERSION
in common.pro and pass settings from configure script instead
- Add not-very-useful .qt-mng image file output format
- Add function stats to Properties dialog
- Add function simplification (more useful for debugging than anything)
- Don't use True and False in doc-building python script
(seems to be quite new thing, not in 2.1.x ?). Use 0 and 1 instead.
- Internal changes
- Add pkg/debian .deb builder script (still under development)
- Fix buggy Y rotation matrix
- Eliminate template-tastic Tuple and Matrix classes.
Fix XYZ and Transform to not require them.
- evolvotron_mutate - -g option more likely to generate insteresting functions
- -linz and -spheremap options where appropriate
- evolvotron_match utility.
- New dialog for function weightings (not fully implemented)
From release 0.2.2:
- Version to 0.2.3
- Break out USAGE file from README
- Add text_to_markup.py script to prettify USAGE file, used from configure
- Add quick reference and user manual accessible from help menu
From release 0.2.1:
- Version to 0.2.2
- CPU type an option to ./configure (p3,p4,xp supported)
- Build option for fullscreen & menu-hiding modes (from keyboard or command-line)
- Fullscreen mode for "Big" image displays
- Change default grid to 6x5 (would sooner have fat than thin images)
From release 0.2.0:
- Bump version to 0.2.1
- Display (not compute) priority to higher resolution images
(saves time enlarging low res images unnecessarily)
- Blank images on replacement (above change makes this more necessary)
- Round-robin dispatch of done tasks to displays means redisplay more balanced.
- -x and -X command line options to specify specifc top level function types.
- FunctionKaleidoscope*, FunctionWindmill*, FunctionSeparateZ added.
- More iterative functions also added: FunctionStreak Function*Ring
- Added -f option to evolvotron_render
- Internals: function framework changed (avoids FunctionNodeUsing::evaluate wrapper), speed improvement ?
- Internals: Type of top-level node can mutate, MutatableImage more sane.
- "Undo" keyboard accelerator works
- Per-image display "Properties" dialog added (placeholder)
From release 0.1.4:
- Bump version to 0.2.0
- Filenames converted to/from QString using Qt's "local8Bit" codec.
- -f option specifies number of frames (default 1, which is the non-animated behaviour of previous versions)
- -r option specifies framerate of full-resolution animation (default 8, about the minimum to look smooth)
- Animations save to multiple files
From release 0.1.3:
- Bump version to 0.1.4
- Function tree growth rate restored to pre-0.1.2 rates
- Both multiscale noise types counted as iterative as originally intended.
- "Substitute" mutation type added.
From release 0.1.2:
- Bump version to 0.1.3
- Build lib and separate executables. Use qmake "subdirs" at top level, move code into subdirs.
- Add evolvotron_render executable.
- Add evolvotron_mutate executable.
- Better Args class.
- Fix bug in FunctionAverageSamples
- Add noise class
- Add more functions.
- Use better random number generator (MT)
- Changes to initial setup probabilities, add chance of identity nodes front and back
From release 0.1.1:
- Bump version to 0.1.2. This is purely a bug-fix release.
- Gentoo compile bug fix (Karl Robillard)
- Disable implicit QString conversion (use explicit latin1() method).
- Workround "C++ static initializer fiasco" by moving problem static members
into instance-get methods.
From release 0.1.0:
- Bump version to 0.1.1
- Grid size now defaults to 7x5
- More functions!
From release 0.0.5:
- Bump version to 0.1.0
- Fix nasty bug in computers where a task could be delivered and deleted while
the compute thread was still setting state in it
(timing related so it never happened with ccmalloc and valgrind).
- Massive internal changes necessary for file save/load
(also makes adding functions easier)
- Save/load individual functions to XML
- configure checks QTDIR defined (biggest cause of build problems)
From release 0.0.4
- Bump version to 0.0.5
- configure script #!/bin/* changed to sh from csh
- Release tar files now unpack to a ./evolvotron directory
- More "Big" size options
- Big image can create big images
- Big image's initial window size decided by Qt
- Spawn warped offers more specific controls (zoom/pan/rotate)
- Middle mouse button does stuff (pan/zoom/rotate/shear)
- Undo menu entry describes type of action which will be undone
- Closing a big image cleans up undo history appropriately
- Bug with assumed EvolotronMain/MutableImageDisplay destructor order fixed.
From release 0.0.3:
- Bump version to 0.0.4
- More interesting start up functions
- More functions (e.g rotation and spirals, geometric inverse, iterated fns, fractals...)
- Controls to enable/disable expensive/ugly iterative and fractal functions (default off).
- Fix dumb bug in xy range of image
(makes everything generally behave a lot better; most noticeable with warp)
- "Identity supression" control which helps eliminate/reduces obvious origin centering.
- "Proportion constant" control (doesn't seem to have that much effect).
- Separate reset/restart functionality (reset also resets mutation parameters).
- Move Cool/Shield buttons to be adjacent (commonly used together).
- "is_constant" query method used to eliminate boring constant images.
- x&y co-ordinate alignment fixed (not something users would notice)
- Spawn warped made less messy: just generates translate/scale/rotate... no shearing.
- Reset clears locks / restart doesn't
- Gratuitously templatized tuple/matrix class added to help geometric transforms.
- Add "configure" script 'cos thats how lots of other apps do it. Apparently.
From release 0.0.2:
- Bump version to 0.0.3
- Add command line arg control of grid size and threads, don't override -geometry
- GUI control of mutation parameters
- "Respawn" regenerates a single display area using spawn/recolour/warp as appropriate.
- "Cancel" in file save dialog obeyed.
- "Insert" mutation type.
- "Undo" functionality.
From release 0.0.1:
- Bump version to 0.0.2
- Switch to QMainWindow base in anticipation of toolbar.
- Save as PPM or PNG
- Scrollable fixed-size image "Big" windows.
- Improvements to app response under load.
From release 0.0.0:
- Bump version to 0.0.1
- Add volatile to inter-thread communication flags
- Added a few more image node function types
- Add "spawn_recoloured"
- Add "spawn_warped"
evolvotron/README 0000644 0001751 0001751 00000023711 12100750252 013513 0 ustar timday timday NOTE
====
There is a ./configure script here, but it's NOT autoconf generated.
evolvotron is built using the qmake utility which is part of Qt.
However, most users should be able to
./configure ; make
PROVIDED their environment is set up correctly.
Page down to the BUILDING section for more info.
INTRODUCTION
============
Evolvotron is interactive "generative art" software to evolve
images/textures/patterns through an iterative process of random
mutation and user-selection driven evolution. If you like lava-lamps,
and still think the Mandelbrot set is cool, this could be the software
for you.
It uses C++ (and STL+Boost) & Qt (which is Trolltech's Qt GUI
toolkit; it's ABSOLUTELY NOTHING TO DO WITH APPLE'S QUICKTIME!).
It's multithreaded (using Qt's threading API).
Home page: http://www.bottlenose.demon.co.uk/share/evolvotron
Author: timday at timday dot com
This file describes how to build evolvotron.
See the USAGE file for details of what the built executable can do.
If you manage to make practical use of evolvotron, especially
if evolvotron derived imagery makes it into print or other
mass media, I'd love to hear about it: please email!
Have fun
Tim
LICENSE
=======
This program 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 2
of the License, or (at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
[The license should be in the LICENSE file in the same directory as this
README]
BUILDING
========
There's no reason it shouldn't work on any platform with a correctly
set up qmake. [A simple python script is now also used to build the
online documentation; I'm hoping this won't cause any problems]
You do NOT need to be root (there is no install stage).
In the top level directory, you can either do
./configure
make
or just have both done for you by doing
./BUILD
[Note that the BUILD script also adds $QTDIR/bin to the path while it runs the
commands, and is probably the easiest way to build if your PATH doesn't
include a directory containing qmake and you like it that way.]
Make will recurse into and build the libfunction & libevolvotron directories
(which is 99% of the work) and some additional subdirectories with
executables.
Among other things, this will give you an "evolvotron"
executable which you can run immediately with
./evolvotron/evolvotron
and/or copy where you like (there are no shared libs or "resource files"
needing additional attention).
See the USAGE file (or in-app manual) for instructions.
BUILD PROBLEMS
==============
Short story
-----------
1. Check you have your QTDIR environment variable defined correctly.
2. Check your PATH will find qmake (i.e do "which qmake")
(adding $QTDIR/bin to your path will fix this on many distros;
note that the BUILD script does this when it runs).
3. If your system appears to have some qt libraries, but not qmake,
you probably need to install a Qt development tools package
of some sort before you can build evolvotron.
The 0.6.0 code builds against Boost 1.35
Non-linux platform issues
-------------------------
On the whole, Qt does an excellent job of insulating code from
platform specific details. However, there is a little bit of
linux-specific code in evolvotron.
If you don't have a PLATFORM_... define set, you'll get some warnings
about no default implementations of functions in platform_specific.cpp,
but should still get a working evolvotron (although missing some functionality
with regard to automatically choosing how many threads to run and controlling
thread priority).
All the platform specific code should live in
libevolvtron/platform_specific.cpp
and is selected by compile options
-DPLATFORM_LINUX or -DPLATFORM_BSD
(with more potentially addable for other platforms).
Setting the appropriate build options is most easily set by editing
an appropriate
DEFINES+=PLATFORM_LINUX
or
DEFINES+=PLATFORM_BSD
near the top of the
common.pro
file. Qt doesn't make a fine enough distinction between unix platforms
to decide completely automatically, and the situation is further complicated
by e.g Fink's Qt not considering itself to be a Qt 'macx' build.
Long story
----------
[These days the author primarily develops on Debian stable
or testing. The comments below re RedHat are based on experience
with the now very old RH 8 & 9; they may or may not be applicable
to Fedora.]
QTDIR should point to your Qt installation. Your Qt installation
should be a directory somewhere (it might be /usr/share/qt3, it
might be /usr/lib/qt3-gcc3.2, who knows), containing some or all
of the subdirectories bin, doc, etc, include, lib, mkspecs, plugins.
NB you might have more than one qt installation (e.g on Debian
testing there is/was both /usr/share/qt and /usr/share/qt3).
You probably want qt3 if there's a choice.
I've never tried Qt4.
RedHat defines QTDIR for the normal user environment,
Debian needs QTDIR setting explicitly.
Additionally QMAKESPEC might possibly need setting
(only a Mandrake user has reported having to do this explicitly so far).
It will be something like "linux-g++" if you need to set it.
Check the Qt docs for other architectures or perhaps look in your
QT installation's mkspecs directory if you think you need this.
Many build failures are simply because the necessary Qt build tools
aren't in your path:
which qmake
which moc
should both find something.
RedHat makes life easy by putting these binaries in
/usr/bin, but many distros leave them languishing in $QTDIR/bin, in which
case you should either add this to your path or use the BUILD script
provided here (which sets it for the commands it runs).
If you have gcc/c++ compile problems problems:
If you have to change anything, the chances are it should be changed in
common.pro. Remember that any Makefiles you can see are generated
by qmake from .pro files and therefore hacking on the Makefiles is
generally a fruitless exercise.
Some source releases have had problems with other versions of gcc than
the ones I test on. A COMPLETE record of a failed build would be
appreciated (including the initial display of the gcc version).
If you can fix it, then patches would be even better!
And the hackiest build yet:
A Debian (3.0r1) user reported Debian's Qt package not including qmake.
(Having since played with Debian myself I now know this is probably
because they didn't install the various Qt -dev and/or -dev-tools
packages too). They eventually got hold of a qmake from somewhere
(builing Qt from source?). Attempting a regular evolvotron build
they apparently (unsurprisingly) encountered a header/library version
incompatibility (old headers, new library) which was solved by
hand editing the qmake-generated Makefile and adding "-I- -I. " in
front of the other -I paths. Yuk.
BUILDING ON OTHER PLATFORMS
===========================
[Very old information now!]
Linc Davis reports:
"I built it on a Mac with Qt installed via Fink (if you know what that is.)
All I had to do is add '$(QTDIR)/include/qt' to the include path and then
run make."
Paolo Greppi built it on OSX like this:
- get qt for osx http://www.trolltech.com/download/qt/mac.html
- configure qt with -thread to compile threading support
(takes a lot of time)
- remember to:
sudo ln -sf /usr/local/qt/lib/libqt-mt.3.dylib /usr/lib
- and add this to .tcshrc in your home directory:
setenv QTDIR /usr/local/qt
setenv PATH $QTDIR/bin:$PATH
setenv DYLD_LIBRARY_PATH $QTDIR/lib
- modify the Makefile in evolvotron adding -lqt-mt at the end of LIBS
- cd libevolvotron
mv mutatable_image_computer_farm.c mutatable_image_computer_farm.cpp
mv mutatable_image_computer_task.c mutatable_image_computer_task.cpp
- make ... while compiling, it keeps saying
c++: unrecognized option `-pthread'
(but this doesn't seem to matter)
INSTALL
=======
The evolvotron sources don't try to provide an installer.
The assumption is that packagers will have a better idea of where
files should be copied to on their systems, and the tools to do it.
Doing
make install
will recursively descend into the various build directories, but
does nothing in each one.
The things you're likely to want to install are
(in order of interest):
The main executable and man page:
./evolvotron/evolvotron
./man/man1/evolvotron.1
User documentation (standalone version of the builtin manual):
USAGE
An HTML version of the above:
./evolvotron.html
Command-line driven tools and their man pages:
./evolvotron_render/evolvotron_render
./man/man1/evolvotron_render.1
./evolvotron_mutate/evolvotron_mutate
./man/man1/evolvotron_mutate.1
An unsuccessful experiment:
./evolvotron_match/evolvotron_match
There are NO extra supporting files built
(e.g shared libraries, config files, "resource" files)
which need to be in special places for the software to work.
PACKAGING
=========
There are a few things which might be useful to packagers:
mkdeb
- script to build .deb files (using the strangely unpopular
"yada", and pbuilder). This is used to build the .debs put
up on sourceforge, but the "official" Debian ones (and Ubuntu
derivatives) are more conventionally packaged by Gurkan Sengun.
Yada is obsoleted as of Debian's "Wheezy" release however.
rpm/
- directory for contributed RPM related resources.
BUILDING CODE DOCUMENTATION
===========================
If you have doxygen (and graphviz too) and want to build
the source code documentation, execute
./mkdoc
at the top level.
The code documentation then appears in ./doc/html/
This hasn't been tested in a long while now, although the
doxygen commenting style has been kept up.
evolvotron/TODO 0000644 0001751 0001751 00000036036 12100750300 013321 0 ustar timday timday Proximity to one end or the other of this list does not necessarily
imply it will be done sooner or later than other items!
Infrastructure
--------------
- Ditch yada; migrate to...? dh? (yada gone in Debian Wheezy and Ubuntu P.)
Consequences of Qt4 port
------------------------
mutableimagedisplay actions need attention - hmmm shorcuts would need to be installed for the grid, then dispatched.
Margins in display grid - add command line option to control size ?
Why was DialogMutatableImageDisplay created with :QDialog(parent,0,TRUE) ?
EvolvotronMain destructor called on close ?
statusbar needs right justification ?
New-style include files; move to common
Lots of Qthingy* stuff needn't be declared in headers; clean up
Conventional Mode
-----------------
- Migrate to a stock threading/thread pool/futures lib.
- Just make "fullscreen mode support" be the default (and remove text in USAGE).
- Link on webpage to gallery http://gigrafx.110mb.com/evolvotron/index.html
- ...also flickr stuff (xargs?)
- Mouse manipulations: frame rate should be clamped to allow some time to produce a nice image
- At least split out evolvotron_main_history.cpp, even if the class remains nested in .h
- Smaller fragments for big enlargements; seeing unused processors.
- More feedback on when enlargements are ready for saving (have split tasks count now... need more ? yes)
- Triangles quantization mode (c.f hexes, pixels and voxels)
- Linear and cubic interpolation for pixel and voxel mode quantizer
- Enlargement menu: submenus for square, 4:3, 8:5, 16:9. 16x10. 5:4 SXGA 1024x1024 is a bit of an oddball.
And name them, see http://en.wikipedia.org/wiki/Computer_display_standard
- Friezegroups:
Cut taken out for 0.5.0 release.
Want cut and blend for those that support it.
Blend should use two functions in some cases.
Can't see how to blend cuts; needs something more like old warp approach.
- Work out how to add warping/blending to the (frieze) symmetry groups so they dont look so "cut".
Hop - Basic, Blend and Cut done. Cut needs attn to fit in with spinhop.
Jump - Basic, Blend and Cut done. (Is just Hop with y=0 reflection). Cut needs attn to fit in with spinhop.
Sidle - Basic. Can't be blended or cut as there are only reflection lines. (Could be blended, but doesn't hide much).
Spinjump - Basic. No blend or cut as there are only reflection lines. (Is just Sidle with y=0 reflection). (Again, could blend but not much point).
Spinhop - Basic. Blend done. Cut done.
Spinsidle - todo
Step - todo
- Not entirely convinced by separate thread pool for enlargements.
On the other hand, do need some mechanism to progress enlargements
while working on main grid.
- Add functions for the 17 "wallpaper" symmetry groups.
ref: http://www.scienceu.com/geometry/articles/tiling/wallpaper.html
Wikipedia http://en.wikipedia.org/wiki/Wallpaper_group is good.
Presumably there are 3D versions too.
See also http://www.mi.sanu.ac.yu/vismath/ana/ana5.htm
- The function properties dialog could construct a QListView instead of just displaying the XML.
But then you'd want full editing capabilities too (and why not?)
- When mutating parameters, have a chance of a "special" reset to "interesting" values, and maybe even patterns of values.
- Debian transitioning Apps to Applications (post Etch) see bug #361418
- GPLv3 ? Don't understand what else needs to be (e.g Qt3 etc)
- Maybe icon setting could do with some more attention; probably there are more things which should set it
(e.g respawn coloured) and loading could set a flag defering icon setting until that view is ready.
- Boost post-1.33 changes usage of ptr_map, apparently. (Waiting for 1.34 to hit Debian Testing).
- MutatableImageComputer::push_todo could handle defer a bit better.
Actually, complete overhaul of queue/computer kill/defer/abort would be better.
Computers should check priority on head of queue periodically and switch if there's
something better to work on.
- Move InstanceCounted out of useful.h (and #include
IMPORTANT: Initially you should select images with some sort of variation.
If you select a uniform image, you may get stuck in a degenerate zone with
little to mutate and therefore little chance of escape to more interesting
images. You can always reset/restart from the "File" menu (the difference is
that "reset" also resets the mutation parameters to their default values).
Selecting one of the "warp" options from a context menu (right-click on
an image) can also help by introducing an additional opportunity for
mutation on subsequent spawns.
Note that various spirals, grids and tiles, although complex looking,
are actually implemented by a single function node and may leave you stuck too.
Command Line Options
The following are equivalent:
- evolvotron --grid 12x8
- evolvotron --grid=12x8
- evolvotron -g 12x8
General Options
- -a, --autocool
Enable autocooling by default, and cause resets of mutation
parameters to re-enable autocooling if it was disabled.
- -F, --fullscreen
Start in "fullscreen" mode (NB for Qt on X11 this means
a screen-filling borderless/undecorated window is used;
it's not simply maximising the window, and it's not the
sort of framebuffer hijacking used by SDL games). The Qt
documentation claims some window managers may not be entirely
cooperative with this (in which case sorry, you're on your own).
evolvotron actions which bring up dialog boxes (e.g save) seem
to generally behave fairly sensibly but child windows
(e.g enlargements or dialogs) can show some "interesting" behaviour.
Fullscreen mode can be toggled within the application using "F" key.
The "Esc" key will also exit it.
- -g, --grid colsxrows
Sets size of the grid of image display cells in the main application area (defaults to 5x6)
- -h, --help
Print summary of command line options and exit.
- -j, --jitter
Enable sample jittering. Samples will be made at a random position
within a pixel instead of on a regular grid, providing some antialiasing.
- -m, --multisample multisample grid
Enables additional antialiasing passes.
Specifing 2 or 3 will provide an additional pass with 2x2 or 3x3 samples per pixel.
Specifiying 4 (of higher) will provide a 2x2 and a final 4x4 pass.
Specifying 1 provides the default behaviour of one sample per pixel.
For best rendering quality also specify -j.
- -M, --menuhide
Start with menu and status bar hidden. Nice with --fullscreen.
Hiding can be toggled within the application using ctrl-m.
The Esc key will also bring them back.
- -p, --spheremap
Images are produced by sampling the underlying 3D function on the
latitude-longitude grid of a sphere. The resulting images should be
usable as spheremaps/spherical environment maps. Animations vary
the radius of the sphere. NB when in spheremap mode,
middle mouse button adjustments do not yet behave like you'd expect.
- -S, --startup function_filename
Specify a function filename (evolvotron's XML format) to load on startup
(or reset). The option can be provided multiple times, and this is
also the interpretation of any positional arguments. Startup functions
are placed in the grid from left to right, top to bottom.
- -U, --shuffle
Use in conjunction with -S / --startup options, to display the specified
functions in random order, both on application startup and on each
reset of the application.
Animation Options
- -f, --frames frames
Number of frames in animations (defaults to 1 i.e no animation)
- -l, --linear
Vary z linearly with time rather than sinusoidally.
Sinusoidal variation generally looks better when animations are "bounced"
forwards and backwards, but this option is useful when generating slices to
use as volumetric textures.
- -s, --fps framerate
Rate at which frames are displayed per second (integer). (Defaults to 8).
Power-user & Debug Options
Note that the usual Qt/X11 options
(for example, -geometry widthxheight option to set on-screen size in pixels)
are processed and removed before evolvotron options are checked.
- -D, --debug
Puts the certain aspects of the app into a more debug oriented mode.
Currently (ie this may change) it simply changes function weightings
so virtually all function nodes are FunctionNoiseOneChannel. By itself
this is a pretty pointless thing to do, but in conjunction with the -X
options it's useful for examining the behaviour of specific functions.
- -E, --enlargement-threadpool
Use a separate thread pool for computing enlargements.
Using this option ensures computation of enlargements
continue to make some progress even while the main grid
is being actively worked on. However, this will be at
the expense of main grid rendering performance.
Without this option, enlargements' final high-resolution
renderings are invariably lower priority than computation
for images in the main grid.
See also the -N option to control the priority of threads
in this pool.
- -n, --nice niceness
Sets additional niceness (relative to the main application thread)
of the compute (rendering) thread(s).
It's useful to run compute threads at a slightly lower priority
("nice 4" is the default without this option) than the main (GUI)
part of the program (but note that this means other normal/lowish
priority tasks running on your machine may slow evolvotron down
a bit more than expected).
- -N, --Nice enlargement niceness
Sets additional niceness (relative to the main application thread)
of the compute thread(s) computing enlargements (default value is 8).
Only effective in conjunction with -E option.
- -t, --threads threads
Sets number of compute threads.
If this is not specified, then as many compute threads are created
as there are processors on the system (unless this cannot be
discovered in which case only a single compute thread is created).
Non-linux builds will likely not include code to determine processor count
(suitable patches gratefully received).
- -u, --unwrapped
Modifies -F behaviour so that the specified "favourite" function
is NOT wrapped by space/colour transforms. NB For functions without leaf nodes
or parameters (e.g FunctionSphericalToCartesian) this doesn't
leave any scope for variation or future mutation.
Function name recognition is case sensitive.
Example:
evolvotron -F FunctionKaleidoscope -u
- -v, --verbose
Verbose mode, writes various things to application stderr.
This is primarily intended to assist debugging.
This option used to be useful for getting a list of supported function
names for use with the -F option, but those can also be inspected
via the Settings dialogs.
- -x, --favourite functionname
Force a specific "favourite" function type to be used at the top level
of all function trees. The specified function is still wrapped
by spatial and colour warping functions which may disguise
it considerably. A list of all the function names understood
by evolvotron is output during app startup when the -v option
is specified. Function name recognition is case sensitive.
Example:
evolvotron -F FunctionSpiralLinear
Mouse Control
Left-click
A left-click on an image in the main window spawns the mutant offspring
of that image to all the other (non-locked) displays in the grid.
Right-click Context Menu
Right clicking on an image gets you a few more options:
- "Respawn" regenerates just the current image from whatever it was
spawned from (and using recolour or warp, if that's what was used
to produce it).
The main use of this is to make your grid of images look nice
for screendumps, by regenerating any which aren't up to scratch.
NB May not work as expected after an "undo".
- "Spawn" is the same as clicking an image. It generates mutated
images to all unlocked images in the grid.
- "Recolour" to produce different coloured variants of the selected image
- "Warp"'s sub-options produce variants of the image which have been
zoomed/rotated/panned.
- "Lock" to prevent an image from being overwritten by spawns from other
images (select again to toggle).
- "Enlarge" to produce a blow-up of the image in a single window.
Submenu items select either a freely resizable window or
a scrollable view of a fixed size image.
If the application is running in fullscreen mode (NB this is
NOT the same as a simply "maximised" window) then the enlarged
image will also be fullscreen (the "Resizeable" mode is probably
what you want in this case as the image will automatically be
rendered at the correct resolution).
- "Save image" to save the image in a file (.ppm or .png).
You generally want to save an enlarged image: if you
save a small image from the grid, the size you see on the screen
is the size you get in the file. Save isn't allowed until the
full resolution image has been generated; if you try to save too
early a dialog box will be displayed telling you to try again later.
- "Save function" to store the function to an XML file.
- "Load function" to load a stored function from an XML file.
NB if the file was saved from a different version numbered
evolvotron, a warning message will be generated.
Save/load of functions is an experimental feature and you should
not count on future versions of evolvotron being able to load
files saved from old versions, or producing the same image
from a loaded function. Attempting to load functions from later
versions into earlier versions is even less likely to succeed.
- "Simplify" prunes the function tree of redundant branches where
possible (the same action can be applied to all images from
the main "Edit" menu). This doesn't change the appearance of
the image, but may make it recompute faster.
- "Properties" brings up a dialog box containing some information
about the image (e.g the number of function nodes it contains).
Middle Mouse Button
[NB This feature will probably only be of practical use to those with high-end machines].
You can use the middle mouse button to drag-adjust individual images.
This is useful for "final composition" type tweaks, e.g centering an
image's most interesting feature, or just for satisfying your curiosity
about what's off the edge of the image.
It also works on enlarged images, although it's virtually unusable without
a bit of practice on smaller, faster ones (just boldly make the adjustment
you want, release the button... and wait).
Changes made can be rolled-back on the main Edit/Undo menu item,
one drag-action at a time.
An unmodified middle-mouse drag pans the image around following
the mouse motion.
A SHIFT-middle drag zooms the image in and out with scaling
proportional to the distance from the centre of the image. Beware of
generating huge zooms by clicking too near the centre of the image.
An ALT-SHIFT-middle drag is similar but anisotropic: the scaling
may be different in X and Y. Warning: this technique is very
sensitive and can be quite tricky to use! In particular,
if you initially click near the centre axes of the image the zoom factor
can be HUGE, so the best way to start using this is to click about halfway
on a diagonal between the image centre and a corner and gently move in and
out radially. Dragging from one side of the image to the other flips it over
(the degenerate case of infinite zoom at the centre is handled cleanly I think).
If it all goes horribly wrong, undo and try again.
A CTRL-middle drag rotates the image about its centre.
A CTRL-ALT-middle drag shears the image (the best way to see what
this does is to click in the corner of an image and move the mouse
horizontally or vertically).
Keyboard Control
There are some keyboard shortcuts.
Main Window
- "r"/"t"/"x" perform various starts of reset/restart.
- "q" quits the application.
- "u" (and also Ctrl-z) does an undo.
- "f": full-screen mode (on X11, Qt does this by asking the
window manager for a screen-filling undecorated window, and the
documentation contains some dire warnings about problems with broken
window managers). See also "-F" command line option.
Fullscreen mode propagates to enlarged image display windows.
NB The application may completely disappear from the screen for
a brief interval while switching mode.
- "m" : hides status and menu-bar hiding, which can be nice when
in full-screen or window-maximised mode. See also "-M"
command line option. Also note that while the menu bar
is hidden, most of these keyboard shortcuts won't function
as they're tied to the menu system.
- Esc : exits full-screen and/or menu-hiding mode, putting the
application into its normal default state.
Enlargement Windows
The image display windows created by selecting "Enlarge" from a
context menu also have a couple of keyboard operations:
- "f" : [NB only available with fullscreen build option] toggles
full-screen mode. When returning to normal mode, if the main app
window was fullscreen then it will also drop back to normal mode.
- Esc : [NB only available with fullscreen build option]
completely closes a fullscreen-mode enlargement window.
Gui Elements
Main Menu Bar
- File menu:
Items to restart, reset and quit the application.
The difference between restart and reset is that reset
sets the mutation parameters back the their default values.
The "randomize function weights" version of restart scrambles
the relative probability of the various function types (if you
think evolvotron just keeps generating the same kinds of
images give it a try). The "restart with specifc function"
item duplicates the functionality of the "-x" and "-X" command-line
options.
- Edit menu:
"Undo" lets you undo certain actions: e.g spawn,
middle-button adjustment, simplification and lock/unlock.
There is a large but limited number of levels of undo.
"Simplify" is of curiosity value only: it prunes redundant
branches from images ("junk DNA"); this may help them recompute
faster but at the cost of there being less mutatable material.
- Settings menu:
"Mutations" brings up a dialog to modify the amount
of change spawned images are subject to.
(See "advanced usage" below.)
"Functions" brings up a dialog to modify the relative probability
of functions being used. By default all functions are equally
likely except for iterative functions and fractals, which are
almost but not completely supressed. But if you think there
are too many spirals or grids (or not enough fractals) then this
is the place to adjust the frequency with which they appear.
If the software was built with the fullscreen option,
that can also be controlled from this menu.
"Favourite" brings up a dialog which allows you to select a specific
function type to always be used as the root node of any new functions.
The function can be wrapped by some other random stuff, or unwrapped.
See also the -X and -x command line options.
- Help menu:
Items to bring up documentation, and the usual "About" box
(which includes the license).
Status Bar
An area on the status bar shows how many compute "tasks" are
outstanding (or "Ready" when there are none). When two task
totals are reported, the first is for the main grid and the
second for any enlargements being computed.
Each "task" is the recomputation of an image at some resolution.
Tasks are prioritised by their number of pixels (small image
implies higher priority). This is why, if the main grid is still
recomputing, recalculations of enlargements will appear to freeze
after they have reached a certain resolution, at least until other
lower resolution tasks have completed.
The status bar also provides some control over the "autocool"
mechanism which reduces mutation strength with time.
See the advanced usage section below.
Tips
- Don't start a session with any preconceived ideas about the kind
of image you want to get out of it. You will be disappointed.
- I get the best results when I click the image which most
immediately catches my eye as they start appearing. If you stop
to think about it too much then things seem to go downhill.
- If you seem to be just getting the same old spirals and grids
all the time, stop clicking on spirals and grids!
(The same goes for random mush).
- Don't get too hung up on using the warp and middle-mouse drag
adjustments every iteration... use those tools for final
polishing of your masterpiece.
- You can quickly cycle through a lot of initial images (until
you find one with real potential) by bashing on Ctrl-r to
repeatedly restart.
- To add variety to an image's mutations, nudge it with a small
middle-mouse drag. This introduces a top level transform, and
therefore more parameters to be varied.
- Enlargements take a long time to complete their final
high-resolution rendering pass (especially with multisampling
enabled). Most convenient practice seems to be to go away and
leave them to complete, then come back and save them later.
Continuing to click away on the main grid effectively starves
them of CPU, unless the -E command-line option is used.
Animation
As of version 0.2.0 evolvotron contains some experimental support
for generation of animations (although so far the results have been
pretty disappointing IMHO, but it's still early days).
NB THIS IS EVEN MORE COMPUTATIONALLY AND MEMORY INTENSIVE THAN
THE STATIC IMAGE MODE.
Simply supply a -f frames command line option and evolvotron will
generate animated sequences with the specified number of frames.
These will be displayed at the frame rate specified by the
optional -s framerate option (default 8). So "evolvotron -s 24"
will generate 3 second long animations. Animations reverse direction
at each end to avoid a sudden jump.
If you save an animation as PPM or PNG, multiple files will
be saved with .fnnnnnn (where nnnnnn is the zero-filled frame
number) inserted in each filename before the filetype qualifier.
For example, if you enter foo.ppm as the filename to save,
files foo.f000000.ppm, foo.f000001.ppm... will be saved.
If you have the ImageMagick tools you can convert these to
an animated GIF playing at approx. 8 frames per second with:
convert -delay 12 foo.f??????.ppm foo.gif
Advanced Usage
Evolvotron's idea of an image is a function which converts
XYZ co-ordinates to an RGB colour (however we can only display
a 2D plane for now so the input Z is fixed to zero, or varied
with time when animating).
The image functions are constructed from trees of function nodes.
(In the mathematical expression 1+(2*x) the "+" and the "*" would
be function nodes.) Evolvotron's functions tend to correspond to
geometric or colour-space operations or anything else which can be
applied to a 3D vector.
By mutating the structure of the function tree (adding random
branches, for example) and the values of the constant embedded
within it, the image can be changed.
The mutation parameters are under control from the dialogs accessible
via the Settings menu, and the "autocool" mechanism exposed in the
status bar also has some influence.
There are two kinds of mutation: perturbations to the magnitude of constants,
and structural mutations which rearrage the function tree of an image.
Four types of structural mutations are currently implemented:
- replacement of a function branch by a new random stub (a "Glitch" mutation).
- a random shuffle of a node's sub-nodes
- insertion of random nodes between a node and it's sub-nodes
- the substitution of a node with one of a different type,
with sub-nodes unaffected where possible).
The probability (per function node) of these mutations is controlled
from spinboxes on the "Mutation Parameters" dialog (expressed as
chances-in-a-hundred), as is the size of perturbations to constants.
It is useful to think of the perturbations to constant parameters as
being a thermal effect (hence the "heat" and "cool" buttons), while
structural alterations are more drastic and are caused by high energy
gamma rays or something (hence "irradiate" and "shield" buttons to
adjust the probability of structual mutations).
So why would you want to change the mutation parameters from the initial
defaults ? Basically, if you're getting too much variation in spawned images
(this tends to happen after many generations of images, by which time the
function trees have grown quite large and therefore are experiencing a lot
of mutations) then cool and/or shield.
If all the images look too similar, heat and/or irradiate.
The "autocool" mechanism (enabled from the statusbar or mutation parameters
dialog) automatically reduces the strength of mutations from the base
values with successive generations. The cooling can be cancelled by
disabling autocooling or pressing the "Reheat" button to zero the number
of generations counted for cooling. The effect of the cooling is a compound
halving of the mutation strength after some number of generations (this number
is the "half-life" controllable from the mutation parameters dialog).
Note that if autocooling is enabled then eventually, after a number of
iterations more than many multiples of the half-life has passes, spawned
images will differ very little from their parents (hence the need for "reheat").
There is also a dialog accessible from "Functions..." on the "Settings" menu.
This allows control over the relative proportions in which functions occur.
There is a tab showing the relative weighting of all functions (log-2 scale: each
tick halves the probability of the function occurring), and additional tabs
for various classifications of function for quicker access.
The "Randomize" button on each tab assigns random weightings and helps
increase the uniqueness of your session.
The "Functions" dialog also has a "Dilution" tab which allows the average
function-tree branching ratio to be controlled (by changing the proportion
of trivial zero-branch functions added): note that using a high branching
ratio results in very complex images which will take a long time to compute,
while reducing the ratio results in simple, boring images.
3 types of function node are considered fundamental: constant nodes
(which return a constant), identity nodes (which return their
position argument) and transform nodes (which transform their positon
argument by random parameters). On the "Dilution" tab of the "Functions"
dialog there are two slider controls to affect things related to these:
- "proportion constant" controls the proportion of diluting fundamental nodes
which are constants. Changing this from its default value of 0.5 doesn't
actually seem to have much effect.
- "proportion transforms" sets the proportion of non-constant nodes diluting
which are transforms (as opposed to identity nodes).
The main effect of this is that images are less commonly obviously centred
on the origin or aligned with the axes. I think this is a good thing, so
the value is at 1.0 by default.
Other Executables
This release also builds some other command-line driven (non-GUI, non-interactive) utilities.
Consult the man pages for full details.
evolvotron_render reads a XML function description from its standard input and renders it to the
file specified.
evolvotron_mutate reads an XML function description from its standard input and outputs a mutated version.
A command line option allows the "genesis" situation of creating a random function description with no input.
Examples
Evolving and mutating on the command line:
evolvotron_mutate -g | tee fn.xml | evolvotron_render /tmp/xxx.ppm ; display /tmp/xxx.ppm
cat fn.xml | evolvotron_mutate | evolvotron_render -j -m 4 /tmp/xxx.ppm ; display /tmp/xxx.ppm
Animating a function ani.xml saved from evolvotron in animation mode:
cat ani.xml | evolvotron_render -f 100 -v -s 256 256 ani.ppm ; animate ani.f??????.ppm
Future Developments
Please check the TODO file first before you send me suggestions!
Please don't ask me to port evolvotron to proprietary platforms.
You are of course Free under the terms of the GPL to do so yourself,
but please read
http://www.fefe.de/nowindows/
first.
Thanks
To those who have contributed feedback, suggestions and patches:
- Dmitry Kirsanov
- Jonathan Melhuish
- Karl Robillard
- Linc Davis
- Paolo Greppi
- Marcin Wojtczuk
- Michael Sterrett
- Massimiliano Guastafierro
- Goetz Waschk
- Forrest Walter
And to the anonymous Linspire reviewer who perhaps came up with the best
summary of evolvotron yet: "Fascinating. Utterly pointless, but fascinating."
The friezegroups wouldn't have been possible without
http://michaelshepperd.tripod.com/resources/groups.html
Thanks to www.di.fm, www.somafm.com and Trance4Ever for music to code to.
Thanks especially to a SIGGRAPH conference panel many years ago (likely
including Karl Sims, the pioneer in this area) who first got me interested
in this stuff.
Why ?
I have always admired those who have the skill to wield a pen or paintbrush
and fill a sheet of paper or a canvas with some striking image from their
imagination. Unfortunately I lack the patience to learn such skills,
and probably the necessary manual dexterity and imagination too.
Evolvotron, and several predecessors developed on and off over a decade
since I first came across the idea, are an attempt to compensate for
this using the skills I do have i.e some mathematical sensibility
and the ability to write working code (well, sometimes). If you like
an image it produces, then as far as I'm concerned that's as satisfying
a result as if you liked something I'd drawn myself.
Tim Day
evolvotron/libfunction/update_register_all_functions 0000755 0001751 0001751 00000001734 11055517066 023220 0 ustar timday timday #!/bin/bash
rm -f register_all_functions.cpp
cat <> register_all_functions.cpp
/* AUTO GENERATED FILE. DO NOT EDIT */
/* Should be updated by update_register_all_functions script when new functions are added */
#include "libfunction_precompiled.h"
#include "register_all_functions.h"
#include "function_boilerplate.h"
EOF
HEADERS=`grep -l FUNCTION_BEGIN *.h | sed 's/function_boilerplate.h//'`
for f in $HEADERS ; do
sed -f stripcomments.sed "$f" \
| grep FUNCTION_BEGIN \
| sed 's/FUNCTION_BEGIN(//' \
| sed 's/,.*//' \
| awk '{printf("REGISTER_DCL(%s);\n",$0);}' \
>> register_all_functions.cpp
done
cat <> register_all_functions.cpp
void register_all_functions(FunctionRegistry& r)
{
EOF
for f in $HEADERS ; do
sed -f stripcomments.sed "$f" \
| grep FUNCTION_BEGIN \
| sed 's/FUNCTION_BEGIN(//' \
| sed 's/,.*//' \
| awk '{printf(" register_%s(r);\n",$0);}' \
>> register_all_functions.cpp
done
cat <> register_all_functions.cpp
}
EOF
evolvotron/mkdeb 0000755 0001751 0001751 00000006773 12100750252 013654 0 ustar timday timday #!/bin/bash
# Before using this you probably need to install
# sudo pbuilder yada devscripts lintian cdebootstrap
# and maybe dpkg-sig. Also:
# set up for sudo
# set up pbuilder's /etc/pbuilderrc (maybe no attention needed these days)
# sudo pbuilder create --distribution squeeze
# and/or update with
# sudo pbuilder update
# Expect a lot of warnings re LOGNAME - see Debian bug Bug#275118
# TODO: DEBEMAIL
VER=`./VERSION`
TARBALL=evolvotron-${VER}.tar.gz
if [ ! -s ${TARBALL} ] ; then
echo "Could't find ${TARBALL}" ;
exit ;
fi
export DISTRIBUTION=`lsb_release -s -c`
echo "*** Will package ${TARBALL} for distribution \"${DISTRIBUTION}\""
echo -n "*** Starting in 5 seconds..."
for t in 5 4 3 2 1 ; do sleep 1 ; echo -n "." ; done
PROJECT=`echo $TARBALL | sed 's/-.*//'`
TARBALLORIG="${PROJECT}_${VER}.orig.tar.gz"
REV="1${DISTRIBUTION}1"
WORKDIR=pkg_${VER}-${REV}
rm -r -f ${WORKDIR}
mkdir ${WORKDIR}
cd ${WORKDIR}
cp ../${TARBALL} ${TARBALLORIG}
tar xvfz ${TARBALLORIG}
mv ${PROJECT} ${PROJECT}-${VER}
cd ${PROJECT}-${VER}
sed -i "s/${VER}/${VER}-${REV}/g" VERSION
mkdir debian
dch --create --package evolvotron --distribution stable --newversion ${VER}-${REV} "Created by mkdeb script"
cat << EOF > debian/packages
Source: evolvotron
Section: graphics
Priority: extra
Maintainer: Tim Day
Standards-Version: 3.6.1
Upstream-Source:
Home-Page:
Description: Interactive evolutionary texture generator
Copyright: GPL
Copyright 2009 Tim Day
Build-Depends: qt4-qmake,qt4-dev-tools,libqt4-dev,libqt4-xml,libboost-dev,libboost-program-options-dev,yada
Build: sh
export QTDIR=/usr/share/qt4
# Note: yada install deals with DEB_BUILD_OPTIONS 'nostrip'
if [ "${DEB_BUILD_OPTIONS#*noopt}" != "$DEB_BUILD_OPTIONS" ]; then
./configure "CONFIG -= release" "CONFIG += debug"
else
./configure # No noticeable advantage in overriding qt optimisation options
fi
make
Clean: sh
make distclean || make clean || true
Package: evolvotron
Architecture: any
Depends: []
Suggests: gimp
Description: Interactive evolutionary texture generator
A "generative art" application to evolve images/textures/patterns through an
iterative process of random mutation and user-selection driven evolution.
If you like lava lamps, and never got bored with the Mandelbrot Set,
this could be the software for you.
Install: sh
yada install -bin evolvotron/evolvotron
yada install -bin evolvotron_mutate/evolvotron_mutate
yada install -bin evolvotron_render/evolvotron_render
yada install -bin evolvotron/evolvotron
yada install -doc evolvotron.html
yada install -doc BUGS TODO NEWS USAGE
yada install -man man/man1/evolvotron.1
yada install -man man/man1/evolvotron_mutate.1
yada install -man man/man1/evolvotron_render.1
Menu: ?package(evolvotron): needs="X11" section="Applications/Graphics" title="Evolvotron" hints="Bitmap" command="/usr/bin/evolvotron" longtitle="Evolutionary art program"
EOF
yada rebuild
cd ..
dpkg-source -b ${PROJECT}-${VER} ${TARBALLORIG}
# Alternative but inferior approach is apparently to do
# dpkg-buildpackage -rfakeroot
mkdir result
echo "Building package"
sudo pbuilder build --allow-untrusted --buildresult ./result ${PROJECT}_${VER}-${REV}.dsc
sudo chown ${USER}:${USER} result/*
RESULT=`(cd .. ; find ${WORKDIR} -name '*.deb')`
echo "Results: ${RESULT}"
echo "Don't forget to lintian ${RESULT}"
echo 'Also dpkg-sig --sign builder -k $DPKGSIG_KEYID any .deb files'
evolvotron/mkdoc 0000755 0001751 0001751 00000000061 11055517066 013663 0 ustar timday timday #!/bin/sh -v
mkdir -p doc
doxygen doxygen.cfg
evolvotron/mktgz 0000755 0001751 0001751 00000001772 12100750252 013720 0 ustar timday timday #!/bin/bash
# Execute this to package up evolvotron as a .tar.gz
VERSION=`./VERSION`
DIR=${PWD##*/}
cd ..
# NB Don't ship contents of pkg
PRUNE='-name moc -prune -o -name obj -prune -o -name pkg_* -prune'
FILES_MISC=`ls ${DIR}/{README,BUILD,LICENSE,TODO,NEWS,VERSION,USAGE,BUGS,configure,doxygen.cfg,mktgz,mkdeb,mkdoc,text_to_markup.py,evolvotron.html} ${DIR}/libfunction/update_register_all_functions`
FILES_EXTRAS="`ls ${DIR}/extras/{README,spheremap.pov,spheremap.sh}` `ls ${DIR}/rpm/{README,evolvotron.spec}`"
FILES_H=`find ${DIR} ${PRUNE} -o -name '*.h' -print`
FILES_CPP=`find ${DIR} ${PRUNE} -o -name '*.cpp' -print`
FILES_PRO=`find ${DIR} ${PRUNE} -o -name '*.pro' -print`
FILES_MAN=`find ${DIR}/man ${PRUNE} -o -name '*.1' -print`
FILES="$FILES_MISC $FILES_EXTRAS $FILES_H $FILES_CPP $FILES_PRO $FILES_MAN"
tar --transform "s:^${DIR}/:evolvotron/:" -cz -f ${DIR}/evolvotron.tar.gz $FILES
echo "***"
echo "*** Suggestion: mv evolvotron.tar.gz evolvotron-$VERSION.tar.gz"
echo "***"
evolvotron/text_to_markup.py 0000755 0001751 0001751 00000014641 11267025132 016264 0 ustar timday timday #!/usr/bin/env python
# Convert Tim-style text to html or qml
#
# The Rules:
# - Lines with all upper case words to h2 or h3 capwords depending on next line underlining (first to h1/title though)
# (must be 3 chars or more)
# (todo: relax to not all upper case... no need to capwords if not)
# - Other text to p, blank lines break a p
# - Lines beginning with "- " (NB space) to ul/li (bulleted)
# - Lines beginning with "-?" (no space) to ul/li (?) with
at end of first line
# - Words delim to xxx
# "$ " at start of line indicates one line of code (add
too)
import sys
import string
import re
def line_of_dashes(n):
r=""
for i in xrange(n):
r+="-"
return r
def line_of_equals(n):
r=""
for i in xrange(n):
r+="="
return r
class TextToMarkup:
def __init__(self,m,s):
self.startup=1 # True
self.scope_p=0 # False
self.scope_ul=0 # False
self.scope_li=0 # False
self.done_title=0 # False
self.skipnextline=0 # False
self.mode=m
self.stringify=s
def dispose(self,l):
if self.stringify:
self.output.write("\"") # Actually, they should all have been "-ed anyway
for c in l:
if c=="\"":
self.output.write("\\\"")
else:
self.output.write(c)
self.output.write("\\n\"\n")
else:
self.output.write(l+"\n")
def process_word(self,w):
r=""
if len(w)<3: # Special case allows "<" or "<>" without turning italic
for i in xrange(len(w)):
if w[i]=="<":
r+="<"
elif w[i]==">":
r+=">"
else:
r+=w[i]
else:
for i in xrange(len(w)):
if w[i]=="<":
r+=""
elif w[i]==">":
r+=""
elif w[i]=='"':
r+="""
elif w[i]=="&":
r+="&"
else:
r+=w[i]
return r
def process_paragraph_text(self,txt):
is_code=0 # False
specialbreak=0 # False
r=" "
if txt[0]=="-":
if txt[1]==" ":
txt=txt[2:]
else:
specialbreak=1 # True
if self.scope_ul and self.scope_li:
r+=""
self.scope_li=0 # False
if not self.scope_ul:
r+=""
self.scope_ul=1 # True
if not self.scope_li:
r+="- "
self.scope_li=1 # True
elif txt[0]=="$":
is_code=1 # True
r+="
"
txt=txt[2:]
for w in txt.split():
r+=self.process_word(w)
r+=" "
if is_code:
r+="
"
if specialbreak:
r+="
"
return r
def process(self,in_stream,out_stream):
self.output=out_stream
self.input=in_stream
if self.mode=="html":
self.dispose("")
while 1: # True
if self.startup:
self.currline_raw=in_stream.readline()
self.nextline_raw=in_stream.readline()
self.startup=0 # False
else:
self.currline_raw=self.nextline_raw
self.nextline_raw=in_stream.readline()
if not self.currline_raw:
break
if self.skipnextline:
self.skipnextline=0 # False
continue
# Should track last line too
self.currline=self.currline_raw.strip()
self.nextline=self.nextline_raw.strip()
if len(self.currline)>2 and self.nextline==line_of_equals(len(self.currline)):
if self.done_title:
self.dispose(""+string.capwords(self.currline)+"
")
self.skipnextline=1 # True
continue
else:
if (self.mode=="html"):
self.dispose("")
self.dispose("")
self.dispose(""+string.capwords(self.currline)+"")
self.dispose("")
self.dispose("")
elif (self.mode=="qml"):
self.dispose("")
self.dispose(""+string.capwords(self.currline)+"
")
self.done_title=1 # True
self.skipnextline=1 # True
continue
elif len(self.currline)>2 and self.nextline==line_of_dashes(len(self.currline)):
self.dispose(""+string.capwords(self.currline)+"
")
self.skipnextline=1 # True
continue
elif self.scope_p:
if (len(self.currline)):
self.dispose(self.process_paragraph_text(self.currline))
else:
if self.scope_li:
self.dispose(" ")
self.scope_li=0 # False
if self.scope_ul:
self.dispose("
")
self.scope_ul=0 # False
self.dispose("
")
self.scope_p=0 # False
elif len(self.currline):
self.dispose("")
self.dispose(self.process_paragraph_text(self.currline))
self.scope_p=1 # True
else:
self.dispose("")
if self.mode=="html":
self.dispose("")
self.dispose("")
#########################################
if __name__=='__main__':
mode=None
stringify=0 # False
for i in xrange(1,len(sys.argv)):
if sys.argv[i]=="-qml":
mode="qml"
if sys.argv[i]=="-html":
mode="html"
elif sys.argv[i]=="-s":
stringify=1 # True
t2m=TextToMarkup(mode,stringify) # "html" and "qml" are alternatives. Should be stringify option.
t2m.process(sys.stdin,sys.stdout)
evolvotron/extras/README 0000644 0001751 0001751 00000000453 11055517061 015026 0 ustar timday timday
---
spheremap.sh is a script to animate a spheremap applied to a rotating sphere.
The scene description is in spheremap.pov.
It assumes the existence of a file called spheremap.png, which you
should create by saving an (enlarged, probably) image from evolvotron
running in -spheremap mode.
---
evolvotron/extras/spheremap.pov 0000644 0001751 0001751 00000000360 11055517061 016655 0 ustar timday timday #include "colors.inc"
camera {perspective location <0,1,-4.5> look_at <0,0,0> angle 45}
light_source {<100,100,-100> color White}
sphere
{
<0,0,0>,1 pigment { image_map {png "spheremap.png" map_type 1} }
rotate <0,clock*360,0.0>
}
evolvotron/extras/spheremap.sh 0000755 0001751 0001751 00000000232 11055517061 016464 0 ustar timday timday #!/bin/bash
# Disclaimer: I'm using povray version "3.5 Unix". Which is probably quite old now.
povray spheremap.pov +KFI1 +KFF100 +H240 +W320 +Of.png
evolvotron/rpm/README 0000644 0001751 0001751 00000000455 11055517056 014324 0 ustar timday timday This directory contains contributed RPM packaging related resources.
-----
evolvotron.spec
- Karl Robillard's .spec file to build RPM packages on Mandriva, Fedora and Suse.
-----
See
http://www.bottlenose.demon.co.uk/share/evolvotron/download.htm
for up-to-date news re downloadable packages.
evolvotron/rpm/evolvotron.spec 0000644 0001751 0001751 00000002347 11055517056 016537 0 ustar timday timday Summary: Evolvotron Interactive Art Generator
Name: evolvotron
Version: 0.5.1
Release: 1
License: GPL
URL: http://sourceforge.net/projects/evolvotron
Packager:
Group: Applications/Graphics
Source: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%if 0%{?fedora_version}
BuildRequires: gcc-c++ boost-devel python qt-devel
%else
BuildRequires: gcc-c++ boost-devel python qt3-devel
%endif
%description
Evolvotron is interactive "generative art" software to evolve images/textures/patterns through an iterative process of random mutation and user-selection driven evolution.
%prep
%setup -q -n %{name}
%build
%if 0%{?fedora_version}
source /etc/profile.d/qt.sh
%endif
%if 0%{?mandriva_version}
export QTDIR=%{_prefix}/lib/qt3
export PATH=$QTDIR/bin:$PATH
%endif
%if 0%{?suse_version}
export QTDIR=/usr/%{_lib}/qt3
export PATH=$QTDIR/bin:$PATH
%endif
./configure
make
%install
# make install
mkdir -p $RPM_BUILD_ROOT/usr/bin
install -s -m 755 evolvotron/evolvotron $RPM_BUILD_ROOT/usr/bin
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
/usr/bin/evolvotron
%doc README USAGE CHANGES
%changelog
* Fri Mar 28 2008 Karl Robillard
- Initial package release.
evolvotron/evolvotron_render/evolvotron_render_precompiled.h 0000644 0001751 0001751 00000003126 12100750300 024707 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Precompiled header for evolvotron_render
*/
#ifndef _evolvotron_render_precompiled_h_
#define _evolvotron_render_precompiled_h_
#include "libevolvotron_precompiled.h"
#include
#endif
evolvotron/evolvotron/evolvotron_precompiled.h 0000644 0001751 0001751 00000003101 12100750300 022002 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Precompiled header for evolvotron
*/
#ifndef _evolvotron_precompiled_h_
#define _evolvotron_precompiled_h_
#include "libevolvotron_precompiled.h"
#include
#endif
evolvotron/evolvotron_mutate/evolvotron_mutate_precompiled.h 0000644 0001751 0001751 00000003117 12100750250 024753 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Precompiled header for evolvotron
*/
#ifndef _evolvotron_mutate_precompiled_h_
#define _evolvotron_mutate_precompiled_h_
#include "libevolvotron_precompiled.h"
#include
#endif
evolvotron/libfunction/functions_friezegroup_step.h 0000644 0001751 0001751 00000005307 12100750300 022777 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces and implementation for specific Function classes.
*/
#ifndef _functions_friezegroup_step_h_
#define _functions_friezegroup_step_h_
#include "friezegroup.h"
//! Step (Conway p1a1): glide reflection only.
/*! Sawtooth x, out of step by half range across y-axis.
\verbatim
o o
--- ---
--- ---
o o
\endverbatim
*/
struct Step
{
const XY operator()(const XY& p) const
{
return XY
(
(p.y()>0.0 ? modulusf(p.x(),1.0) : modulusf(p.x()+0.5,1.0)),
fabs(p.y())
);
}
};
struct StepInvariant;
struct StepBlend;
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionFriezeGroupStepFreeZ,0,1,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
return FriezegroupEvaluate(arg(0),p,Step(),FreeZ());
}
FUNCTION_END(FunctionFriezeGroupStepFreeZ)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionFriezeGroupStepClampZ,1,1,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
return FriezegroupEvaluate(arg(0),p,Step(),ClampZ(param(0)));
}
FUNCTION_END(FunctionFriezeGroupStepClampZ)
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/random.h 0000644 0001751 0001751 00000007010 12100750300 016564 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces for class Random and derived classes.
*/
#ifndef _random_h_
#define _random_h_
//! Abstract base class for random number generation
class Random
{
public:
//! Constructor (nothing to do in base class)
Random()
{}
//! Trivial destructor.
virtual ~Random()
{}
//! Return a random number.
/*! \warning Returns double instead of real because suspect NegExp can return Inf otherwise.
*/
virtual double operator()()
=0;
};
//! Generates random numbers in the range [0,1).
class Random01 : public Random
{
public:
//! Constructor
Random01(uint seed);
//! Trivial destructor
virtual ~Random01();
//! Return next number in sequence.
virtual double operator()();
private:
//! Base generator
boost::mt19937 _rng;
//! Distribution
boost::uniform_real<> _dist;
//! Actual generator
boost::variate_generator > _gen;
};
//! Return negative-exponentially distributed random numbers.
class RandomNegExp : public Random
{
protected:
//! Underlying generator.
Random01 _generator;
//! Mean value of distribution.
double _mean;
public:
//! Construct generator of numbers with mean value m.
RandomNegExp(uint seed,double m)
:_generator(seed)
,_mean(m)
{}
//! Trivial destructor.
virtual ~RandomNegExp()
{}
//! Return next number in sequence.
virtual double operator()()
{
return -_mean*log(1.0-_generator());
}
};
template void random_shuffle(boost::ptr_vector& v,Random01& r01)
{
boost::ptr_vector nv;
while (!v.empty())
{
const uint n=static_cast(r01()*v.size());
nv.transfer(nv.end(),v.begin()+n,v);
}
v.transfer(v.end(),nv.begin(),nv.end(),nv);
}
//! Adapter to use our random number generator to feed std::random_shuffle
class RandomInt
{
public:
RandomInt(Random01& r01)
:_r01(r01)
{}
uint operator()(uint n)
{
return static_cast(_r01()*n);
}
private:
Random01& _r01;
};
template void random_shuffle(std::vector& v,Random01& r01)
{
RandomInt r0n(r01);
std::random_shuffle(v.begin(),v.end(),r0n);
}
#endif
evolvotron/libfunction/register_all_functions.h 0000644 0001751 0001751 00000003336 12100750300 022057 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief File declaring function to register all functions.
NB The corresponding register_all_functions.cpp is AUTO GENERATED by update_register_all_functions script.
*/
#ifndef _libevolvotron_register_all_functions_h_
#define _libevolvotron_register_all_functions_h_
class FunctionRegistry;
extern void register_all_functions(FunctionRegistry&);
#endif
evolvotron/libfunction/functions_juliabrot.h 0000644 0001751 0001751 00000014026 12100750300 021374 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces and implementation for specific Function classes.
As much as possible of the implementation should be pushed into the FunctionBoilerplate template.
*/
#ifndef _functions_juliabrot_h_
#define _functions_juliabrot_h_
//------------------------------------------------------------------------------------------
//! Mandelbrot/Julia iterator for fractal functions.
/*! Returns i in 0 to iterations inclusive. i==iterations implies "in" set.
*/
inline uint brot(const real z0r,const real z0i,const real cr,const real ci,const uint iterations)
{
real zr=z0r;
real zi=z0i;
uint i;
for (i=0;i4.0)
break;
const real nzr=zr2-zi2+cr;
const real nzi=2.0*zr*zi+ci;
zr=nzr;
zi=nzi;
}
return i;
}
//------------------------------------------------------------------------------------------
//! Function selects arg to evaluate based on test for point in Mandelbrot set.
FUNCTION_BEGIN(FunctionMandelbrotChoose,0,2,true,FnIterative|FnFractal)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
return (brot(0.0,0.0,p.x(),p.y(),iterations())==iterations() ? arg(0)(p) : arg(1)(p));
}
FUNCTION_END(FunctionMandelbrotChoose)
//-----------------------------------------------------------------------------------------
//! Function returns -1 for points in set, 0-1 for escaped points
FUNCTION_BEGIN(FunctionMandelbrotContour,0,0,true,FnIterative|FnFractal)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const uint i=brot(0.0,0.0,p.x(),p.y(),iterations());
return (i==iterations() ? XYZ::fill(-1.0) : XYZ::fill(static_cast(i)/iterations()));
}
FUNCTION_END(FunctionMandelbrotContour)
//------------------------------------------------------------------------------------------
//! Function selects arg to evaluate based on test for point in Julia set.
FUNCTION_BEGIN(FunctionJuliaChoose,2,2,true,FnIterative|FnFractal)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
return (brot(p.x(),p.y(),param(0),param(1),iterations())==iterations() ? arg(0)(p) : arg(1)(p));
}
FUNCTION_END(FunctionJuliaChoose)
//------------------------------------------------------------------------------------------
//! Function returns -1 for points in set, 0-1 for escaped points
FUNCTION_BEGIN(FunctionJuliaContour,2,0,true,FnIterative|FnFractal)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const uint i=brot(p.x(),p.y(),param(0),param(1),iterations());
return (i==iterations() ? XYZ::fill(-1.0) : XYZ::fill(static_cast(i)/iterations()));
}
FUNCTION_END(FunctionJuliaContour)
//------------------------------------------------------------------------------------------
//! Function selects arg to evaluate based on test for point in Juliabrot set.
/*! Juliabrot is 4 dimensional, but we only have 3 incoming parameters,
so have 4 4d-basis vector parameters.
*/
FUNCTION_BEGIN(FunctionJuliabrotChoose,16,2,true,FnIterative|FnFractal)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const real zr=p.x()*param( 0)+p.y()*param( 1)+p.z()*param( 2)+param( 3);
const real zi=p.x()*param( 4)+p.y()*param( 5)+p.z()*param( 6)+param( 7);
const real cr=p.x()*param( 8)+p.y()*param( 9)+p.z()*param(10)+param(11);
const real ci=p.x()*param(12)+p.y()*param(13)+p.z()*param(14)+param(15);
return (brot(zr,zi,cr,ci,iterations())==iterations() ? arg(0)(p) : arg(1)(p));
}
FUNCTION_END(FunctionJuliabrotChoose)
//------------------------------------------------------------------------------------------
//! Function returns -1 for points in set, 0-1 for escaped points
/*! Juliabrot is 4 dimensional, but we only have 3 incoming parameters,
so have 4 4d-basis vector parameters.
*/
FUNCTION_BEGIN(FunctionJuliabrotContour,16,0,true,FnIterative|FnFractal)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const real zr=p.x()*param( 0)+p.y()*param( 1)+p.z()*param( 2)+param( 3);
const real zi=p.x()*param( 4)+p.y()*param( 5)+p.z()*param( 6)+param( 7);
const real cr=p.x()*param( 8)+p.y()*param( 9)+p.z()*param(10)+param(11);
const real ci=p.x()*param(12)+p.y()*param(13)+p.z()*param(14)+param(15);
const uint i=brot(zr,zi,cr,ci,iterations());
return (i==iterations() ? XYZ::fill(-1.0) : XYZ::fill(static_cast(i)/iterations()));
}
FUNCTION_END(FunctionJuliabrotContour)
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/function_post_transform.h 0000644 0001751 0001751 00000004446 12100750300 022303 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces for class FunctionPostTransform
This class would normally live in functions.h (and is included and registered there),
but is split out so it can be efficiently used by MutatableImageDisplay and EvolvotronMain.
NB There is no class heirarchy here as all virtualisation and boilerplate services are supplied when the functions are plugged into the FunctionNode template.
*/
#ifndef _function_post_transform_h_
#define _function_post_transform_h_
#include "transform.h"
//! Function class returning leaf node evaluated at given position; result is then transfomed by a 12-component linear transform.
FUNCTION_BEGIN(FunctionPostTransform,12,1,false,0)
//! Return the evaluation of arg(0) at the transformed position argument.
virtual const XYZ evaluate(const XYZ& p) const
{
const Transform transform(params());
return transform.transformed(arg(0)(p));
}
FUNCTION_END(FunctionPostTransform)
#endif
evolvotron/libfunction/functions_transform.h 0000644 0001751 0001751 00000012124 12100750300 021411 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces and implementation for specific Function classes.
As much as possible of the implementation should be pushed into the FunctionBoilerplate template.
*/
#ifndef _functions_transform_h_
#define _functions_transform_h_
#include "transform.h"
//------------------------------------------------------
//! Function class returning simply scaled position
FUNCTION_BEGIN(FunctionIsotropicScale,1,0,false,0)
//! Return the evaluation of arg(0) at the transformed position argument.
virtual const XYZ evaluate(const XYZ& p) const
{
return param(0)*p;
}
FUNCTION_END(FunctionIsotropicScale)
//------------------------------------------------------------------------------------------
//! Function class returning leaf node evaluated at position transfomed by a 12-component linear transform.
/*! Unlike FunctionPreTransform, the basis vectors for the transform are not fixed but determined from leaf functions
*/
FUNCTION_BEGIN(FunctionPreTransformGeneralised,0,5,false,0)
//! Return the evaluation of arg(0) at the transformed position argument.
virtual const XYZ evaluate(const XYZ& p) const
{
const Transform transform(arg(1)(p),arg(2)(p),arg(3)(p),arg(4)(p));
return arg(0)(transform.transformed(p));
}
FUNCTION_END(FunctionPreTransformGeneralised)
//------------------------------------------------------------------------------------------
//! Function class returning leaf node evaluated at given position; result is then transfomed by a 12-component linear transform.
/*! Unlike FunctionPostTransform, the basis vectors for the transform are not fixed but determined from leaf functions
*/
FUNCTION_BEGIN(FunctionPostTransformGeneralised,0,5,false,0)
//! Return the evaluation of arg(0) at the transformed position argument.
virtual const XYZ evaluate(const XYZ& p) const
{
const Transform transform(arg(1)(p),arg(2)(p),arg(3)(p),arg(4)(p));
return transform.transformed(arg(0)(p));
}
FUNCTION_END(FunctionPostTransformGeneralised)
//------------------------------------------------------------------------------------------
//! Transforms position transformed by a 30 paramter quadratic transform.
/*! This used to be a core function but it doesn't look that great.
*/
FUNCTION_BEGIN(FunctionTransformQuadratic,30,0,false,0)
//! Return p transformed.
virtual const XYZ evaluate(const XYZ& p) const
{
const XYZ translate(param( 0),param( 1),param( 2));
const XYZ basis_x (param( 3),param( 4),param( 5));
const XYZ basis_y (param( 6),param( 7),param( 8));
const XYZ basis_z (param( 9),param(10),param(11));
const XYZ basis_xy (param(12),param(13),param(14));
const XYZ basis_xz (param(15),param(16),param(17));
const XYZ basis_yz (param(18),param(19),param(20));
const XYZ basis_xx (param(21),param(22),param(23));
const XYZ basis_yy (param(24),param(25),param(26));
const XYZ basis_zz (param(27),param(28),param(29));
return
translate
+basis_x*p.x()+basis_y*p.y()+basis_z*p.z()
+basis_xy*(p.x()*p.y())+basis_xz*(p.x()*p.z())+basis_yz*(p.y()*p.z())
+basis_xx*(p.x()*p.x())+basis_yy*(p.y()*p.y())+basis_zz*(p.z()*p.z());
}
FUNCTION_END(FunctionTransformQuadratic)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionRotate,0,1,false,0)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const XYZ a(arg(0)(p)*M_PI);
const TransformRotateX rx(a.x());
const TransformRotateY ry(a.y());
const TransformRotateZ rz(a.z());
return rx*(ry*(rz*p));
}
FUNCTION_END(FunctionRotate)
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/functions_gradient.h 0000644 0001751 0001751 00000015550 12100750300 021201 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces and implementation for specific Function classes.
As much as possible of the implementation should be pushed into the FunctionBoilerplate template.
*/
#ifndef _functions_gradient_h_
#define _functions_gradient_h_
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionDerivative,3,1,false,0)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const XYZ d(epsilon()*XYZ(param(0),param(1),param(2)).normalised());
const XYZ v0(arg(0)(p-d));
const XYZ v1(arg(0)(p+d));
return (v1-v0)*inv_epsilon2();
}
FUNCTION_END(FunctionDerivative)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionDerivativeGeneralised,0,2,false,0)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
const XYZ d(epsilon()*(arg(1)(p)).normalised());
const XYZ v0(arg(0)(p-d));
const XYZ v1(arg(0)(p+d));
return (v1-v0)*inv_epsilon2();
}
FUNCTION_END(FunctionDerivativeGeneralised)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionGradient,3,1,false,0)
//! Evaluate function.
/*! Gradient converts scalar to vector, so need a scalar to work on.
*/
virtual const XYZ evaluate(const XYZ& p) const
{
const XYZ k(param(0),param(1),param(2));
const real vx0=k%arg(0)(p-XYZ(epsilon(),0.0,0.0));
const real vy0=k%arg(0)(p-XYZ(0.0,epsilon(),0.0));
const real vz0=k%arg(0)(p-XYZ(0.0,0.0,epsilon()));
const real vx1=k%arg(0)(p+XYZ(epsilon(),0.0,0.0));
const real vy1=k%arg(0)(p+XYZ(0.0,epsilon(),0.0));
const real vz1=k%arg(0)(p+XYZ(0.0,0.0,epsilon()));
return XYZ(vx1-vx0,vy1-vy0,vz1-vz0)*inv_epsilon2();
}
FUNCTION_END(FunctionGradient)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionGradientGeneralised,0,2,false,0)
//! Evaluate function.
/*! Gradient converts scalar to vector, so need a scalar to work on.
*/
virtual const XYZ evaluate(const XYZ& p) const
{
const XYZ k(arg(1)(p));
const real vx0=k%arg(0)(p-XYZ(epsilon(),0.0,0.0));
const real vy0=k%arg(0)(p-XYZ(0.0,epsilon(),0.0));
const real vz0=k%arg(0)(p-XYZ(0.0,0.0,epsilon()));
const real vx1=k%arg(0)(p+XYZ(epsilon(),0.0,0.0));
const real vy1=k%arg(0)(p+XYZ(0.0,epsilon(),0.0));
const real vz1=k%arg(0)(p+XYZ(0.0,0.0,epsilon()));
return XYZ(vx1-vx0,vy1-vy0,vz1-vz0)*inv_epsilon2();
}
FUNCTION_END(FunctionGradientGeneralised)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionDivergence,0,1,false,0)
//! Evaluate function.
/*! Divergence maps scalar to a scalar, so no problem doing vector->vector.
*/
virtual const XYZ evaluate(const XYZ& p) const
{
const XYZ vx0(arg(0)(p-XYZ(epsilon(),0.0,0.0)));
const XYZ vy0(arg(0)(p-XYZ(0.0,epsilon(),0.0)));
const XYZ vz0(arg(0)(p-XYZ(0.0,0.0,epsilon())));
const XYZ vx1(arg(0)(p+XYZ(epsilon(),0.0,0.0)));
const XYZ vy1(arg(0)(p+XYZ(0.0,epsilon(),0.0)));
const XYZ vz1(arg(0)(p+XYZ(0.0,0.0,epsilon())));
return (vx1-vx0+vy1-vy0+vz1-vz0)*inv_epsilon2();
}
FUNCTION_END(FunctionDivergence)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionCurl,0,1,false,0)
//! Evaluate function.
/*! Curl maps vector to vector, which is what we want.
*/
virtual const XYZ evaluate(const XYZ& p) const
{
const XYZ vx0(arg(0)(p-XYZ(epsilon(),0.0,0.0)));
const XYZ vy0(arg(0)(p-XYZ(0.0,epsilon(),0.0)));
const XYZ vz0(arg(0)(p-XYZ(0.0,0.0,epsilon())));
const XYZ vx1(arg(0)(p+XYZ(epsilon(),0.0,0.0)));
const XYZ vy1(arg(0)(p+XYZ(0.0,epsilon(),0.0)));
const XYZ vz1(arg(0)(p+XYZ(0.0,0.0,epsilon())));
const XYZ d_dx((vx1-vx0)*inv_epsilon2());
const XYZ d_dy((vy1-vy0)*inv_epsilon2());
const XYZ d_dz((vz1-vz0)*inv_epsilon2());
const real dzdy=d_dy.z();
const real dydz=d_dz.y();
const real dxdz=d_dz.x();
const real dzdx=d_dx.z();
const real dydx=d_dx.y();
const real dxdy=d_dy.x();
return XYZ
(
dzdy-dydz,
dxdz-dzdx,
dydx-dxdy
);
}
FUNCTION_END(FunctionCurl)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionScalarLaplacian,0,1,false,0)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
// Need to use a bigger baseline to avoid noise being amplified
const XYZ vx0(arg(0)(p-XYZ(big_epsilon(),0.0,0.0)));
const XYZ vy0(arg(0)(p-XYZ(0.0,big_epsilon(),0.0)));
const XYZ vz0(arg(0)(p-XYZ(0.0,0.0,big_epsilon())));
const XYZ v(arg(0)(p));
const XYZ vx1(arg(0)(p+XYZ(big_epsilon(),0.0,0.0)));
const XYZ vy1(arg(0)(p+XYZ(0.0,big_epsilon(),0.0)));
const XYZ vz1(arg(0)(p+XYZ(0.0,0.0,big_epsilon())));
const XYZ dx0(v-vx0);
const XYZ dy0(v-vy0);
const XYZ dz0(v-vz0);
const XYZ dx1(vx1-v);
const XYZ dy1(vy1-v);
const XYZ dz1(vz1-v);
return XYZ(dx1-dx0+dy1-dy0+dz1-dz0)/(big_epsilon()*big_epsilon());
}
FUNCTION_END(FunctionScalarLaplacian)
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/functions_tartan.h 0000644 0001751 0001751 00000012604 12100750300 020672 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Functions inspired by tartan patterns.
*/
#ifndef _functions_tartan_h_
#define _functions_tartan_h_
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionTartanSelectFree,10,6,false,FnStructure)
//! Evaluate function.
/*! Sign of one 1D function's dot product determines one bit, ditto for another bit.
2 bits used to select from 4 possibilities.
There's no guarantee of a repetitive pattern unless the generator functions are.
*/
virtual const XYZ evaluate(const XYZ& p) const
{
const XYZ p0(p.x(),param(0),param(1));
const XYZ p1(param(2),p.y(),param(3));
const XYZ d0(param(4),param(5),param(6));
const XYZ d1(param(7),param(8),param(9));
const int b0=(arg(0)(p0)%XYZ(d0)>0.0);
const int b1=(arg(1)(p1)%XYZ(d1)>0.0);
const int which=2+b0+2*b1;
assert(2<=which && which<6);
return arg(which)(p);
}
FUNCTION_END(FunctionTartanSelectFree)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionTartanSelect,14,6,false,FnStructure)
//! Evaluate function.
/*! Similar to function free except the generators repeat.
*/
virtual const XYZ evaluate(const XYZ& p) const
{
const real x=(param(0)>0.0 ? modulusf(p.x(),param(1)) : trianglef(p.x(),param(1)));
const real y=(param(2)>0.0 ? modulusf(p.y(),param(3)) : trianglef(p.y(),param(3)));
const XYZ p0(x,param(4),param(5));
const XYZ p1(param(6),y,param(7));
const XYZ d0(param(8),param(9),param(10));
const XYZ d1(param(11),param(12),param(13));
const int b0=(arg(0)(p0)%XYZ(d0)>0.0);
const int b1=(arg(1)(p1)%XYZ(d1)>0.0);
const int which=2+b0+2*b1;
assert(2<=which && which<6);
return arg(which)(p);
}
FUNCTION_END(FunctionTartanSelect)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionTartanSelectRepeat,14,6,false,FnStructure)
//! Evaluate function.
/*! Similar to above function except the invoked functions repeat too.
*/
virtual const XYZ evaluate(const XYZ& p) const
{
const real x=(param(0)>0.0 ? modulusf(p.x(),param(1)) : trianglef(p.x(),param(1)));
const real y=(param(2)>0.0 ? modulusf(p.y(),param(3)) : trianglef(p.y(),param(3)));
const XYZ p0(x,param(4),param(5));
const XYZ p1(param(6),y,param(7));
const XYZ d0(param(8),param(9),param(10));
const XYZ d1(param(11),param(12),param(13));
const int b0=(arg(0)(p0)%XYZ(d0)>0.0);
const int b1=(arg(1)(p1)%XYZ(d1)>0.0);
const int which=2+b0+2*b1;
assert(2<=which && which<6);
return arg(which)(XYZ(x,y,p.z()));
}
FUNCTION_END(FunctionTartanSelectRepeat)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionTartanMixFree,4,2,false,0)
//! Evaluate function.
/*! As above, but mix 2 functions.
*/
virtual const XYZ evaluate(const XYZ& p) const
{
const XYZ p0(p.x(),param(0),param(1));
const XYZ p1(param(2),p.y(),param(3));
const XYZ warp(arg(0)(p0));
const XYZ weft(arg(1)(p1));
return 0.5*(warp+weft);
}
FUNCTION_END(FunctionTartanMixFree)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionTartanMixRepeat,8,2,false,0)
//! Evaluate function.
/*! As above, but mix 2 functions.
*/
virtual const XYZ evaluate(const XYZ& p) const
{
const real x=(param(0)>0.0 ? modulusf(p.x(),param(1)) : trianglef(p.x(),param(1)));
const real y=(param(2)>0.0 ? modulusf(p.y(),param(3)) : trianglef(p.y(),param(3)));
const XYZ p0(x,param(4),param(5));
const XYZ p1(param(6),y,param(7));
const XYZ warp(arg(0)(p0));
const XYZ weft(arg(1)(p1));
return 0.5*(warp+weft);
}
FUNCTION_END(FunctionTartanMixRepeat)
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/xy.h 0000644 0001751 0001751 00000011527 12100750300 015754 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class XY.
*/
#ifndef _xy_h_
#define _xy_h_
//! Class to hold vectors in 2D cartesian co-ordinates.
/*! Direct access to the x,y members is not permitted.
*/
class XY
{
protected:
boost::array _rep;
public:
//@{
//! Accessor.
real x() const
{
return _rep[0];
}
real y() const
{
return _rep[1];
}
void x(real v)
{
_rep[0]=v;
}
void y(real v)
{
_rep[1]=v;
}
//@}
//! Null constructor.
/*! NB The components are not cleared to zero.
*/
XY()
{}
//! Copy constructor.
XY(const XY& v)
{
_rep[0]=v._rep[0];
_rep[1]=v._rep[1];
}
//! Initialise from separate components.
XY(real vx,real vy)
{
_rep[0]=vx;
_rep[1]=vy;
}
//! Trivial destructor.
~XY()
{}
//! Subtract a vector
void operator-=(const XY& v)
{
_rep[0]-=v._rep[0];
_rep[1]-=v._rep[1];
}
//! Add a vector
void operator+=(const XY& v)
{
_rep[0]+=v._rep[0];
_rep[1]+=v._rep[1];
}
//! Multiply by scalar
void operator*=(real k)
{
_rep[0]*=k;
_rep[1]*=k;
}
//! Divide by scalar.
/*! Implemented assuming one divide and two multiplies is faster than two divides.
*/
void operator/=(real k)
{
const real ik(1.0/k);
(*this)*=ik;
}
//! Assignment.
void assign(const XY& v)
{
x(v.x());
y(v.y());
}
//! Negation.
const XY operator-() const
{
return XY(-x(),-y());
}
//! Return the square of the magnitude.
real magnitude2() const
{
return x()*x()+y()*y();
}
//! Return the magnitude.
real magnitude() const
{
return sqrt(magnitude2());
}
//! Returns sum of x and y components.
real sum_of_components() const
{
return x()+y();
}
//! Return the vector normalised.
const XY normalised() const;
//! Normalise this vector.
void normalise();
//! Returns true if an origin centred rectangle with this vectors' semi-axes contains the argument.
bool origin_centred_rect_contains(const XY& p) const
{
return (-x()<=p.x() && p.x()<=x() && -y()<=p.y() && p.y()<=y());
}
//! Write the vector.
std::ostream& write(std::ostream&) const;
//! Helper for common case of creating an instance filled with a common value.
static const XY fill(real v)
{
return XY(v,v);
}
};
//! Dot product.
/*! Perhaps a curious choice of operator but it works for me.
*/
inline real operator%(const XY& a,const XY& b)
{
return a.x()*b.x()+a.y()*b.y();
}
//! Vector addition.
inline const XY operator+(const XY& a,const XY& b)
{
return XY(a.x()+b.x(),a.y()+b.y());
}
//! Vector subtraction.
inline const XY operator-(const XY& a,const XY& b)
{
return XY(a.x()-b.x(),a.y()-b.y());
}
//! Multiplication by scalar.
inline const XY operator*(real k,const XY& v)
{
XY ret(v);
ret*=k;
return ret;
}
//! Multiplication by scalar.
inline const XY operator*(const XY& v,real k)
{
XY ret(v);
ret*=k;
return ret;
}
//! Division by scalar.
inline const XY operator/(const XY& v,real k)
{
return v*(1.0/k);
}
/*! If magnitude is zero we return zero vector.
*/
inline const XY XY::normalised() const
{
const real m=magnitude();
return (m==0.0 ? XY(0.0,0.0) : (*this)/m);
}
inline void XY::normalise()
{
(*this)=normalised();
}
//! Stream output operator.
/*! Calls write().
*/
inline std::ostream& operator<<(std::ostream& out,const XY& v)
{
return v.write(out);
}
#endif
evolvotron/libfunction/transform.h 0000644 0001751 0001751 00000012314 12100750300 017322 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class Transform.
*/
#ifndef _transform_h_
#define _transform_h_
//! Class representing 3d linear transforms.
/*! Not much functionality currently because is used mainly to pass info around for warp functionality
*/
class Transform
{
public:
//! Default constructor. NB Doesn't set up identity or anything.
Transform();
//! Copy constructor.
Transform(const Transform&);
//! Constructor specifying column vectors.
Transform(const XYZ& t,const XYZ& x,const XYZ& y,const XYZ& z);
//! Constructor specifying column-wise elements.
Transform(const std::vector& v,uint starting_element=0);
//! virtual destructor in case of extension
virtual ~Transform();
//@{
//! Accessor
const XYZ& translate() const
{
return _translate;
}
const XYZ& basis_x() const
{
return _basis_x;
}
const XYZ& basis_y() const
{
return _basis_y;
}
const XYZ& basis_z() const
{
return _basis_z;
}
void translate(const XYZ &t)
{
_translate=t;
}
void basis_x(const XYZ &x)
{
_basis_x=x;
}
void basis_y(const XYZ &y)
{
_basis_y=y;
}
void basis_z(const XYZ &z)
{
_basis_z=z;
}
//@}
//! Get column-wise element values as a vector
const std::vector get_columns() const;
//! Transform a point
const XYZ transformed(const XYZ& p) const;
//! Transform a point with no translation
const XYZ transformed_no_translate(const XYZ& p) const;
//! Concatenate transforms
Transform& concatenate_on_right(const Transform& t);
//! Concatenate transforms
Transform& concatenate_on_left(const Transform& t);
protected:
//@{
//! Translation component (column vector in matrix).
XYZ _translate;
XYZ _basis_x;
XYZ _basis_y;
XYZ _basis_z;
};
inline const XYZ operator*(const Transform& t,const XYZ& p)
{
return
t.basis_x()*p.x()
+t.basis_y()*p.y()
+t.basis_z()*p.z()
+t.translate();
}
inline std::ostream& operator<<(std::ostream& out,const Transform& t)
{
return out << t.translate() << ";" << t.basis_x() << "," << t.basis_y() << "," << t.basis_z();
}
class TransformIdentity : public Transform
{
public:
TransformIdentity()
{
translate(XYZ(0.0,0.0,0.0));
basis_x(XYZ(1.0,0.0,0.0));
basis_y(XYZ(0.0,1.0,0.0));
basis_z(XYZ(0.0,0.0,1.0));
}
};
class TransformTranslate : public Transform
{
public:
TransformTranslate(const XYZ& t)
{
translate(t);
basis_x(XYZ(1.0,0.0,0.0));
basis_y(XYZ(0.0,1.0,0.0));
basis_z(XYZ(0.0,0.0,1.0));
}
};
class TransformScale : public Transform
{
public:
TransformScale(const XYZ& s)
{
translate(XYZ(0.0,0.0,0.0));
basis_x(XYZ(s.x(),0.0,0.0));
basis_y(XYZ(0.0,s.y(),0.0));
basis_z(XYZ(0.0,0.0,s.z()));
}
TransformScale(real s)
{
translate(XYZ(0.0,0.0,0.0));
basis_x(XYZ(s,0.0,0.0));
basis_y(XYZ(0.0,s,0.0));
basis_z(XYZ(0.0,0.0,s));
}
};
class TransformRotateX : public Transform
{
public:
TransformRotateX(real a)
{
const real sa=sin(a);
const real ca=cos(a);
translate(XYZ(0.0,0.0,0.0));
basis_x(XYZ(1.0,0.0,0.0));
basis_y(XYZ(0.0, ca , sa ));
basis_z(XYZ(0.0,-sa , ca ));
}
};
class TransformRotateY : public Transform
{
public:
TransformRotateY(real a)
{
const real sa=sin(a);
const real ca=cos(a);
translate(XYZ(0.0,0.0,0.0));
basis_x(XYZ( ca ,0.0,-sa ));
basis_y(XYZ(0.0,1.0,0.0));
basis_z(XYZ( sa ,0.0, ca ));
}
};
class TransformRotateZ : public Transform
{
public:
TransformRotateZ(real a)
{
const real sa=sin(a);
const real ca=cos(a);
translate(XYZ(0.0,0.0,0.0));
basis_x(XYZ( ca , sa ,0.0));
basis_y(XYZ(-sa , ca ,0.0));
basis_z(XYZ(0.0,0.0,1.0));
}
};
#endif
evolvotron/libfunction/mutation_parameters.h 0000644 0001751 0001751 00000026371 12100750300 021402 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interface for class MutationParameters.
*/
#ifndef _mutation_parameters_h_
#define _mutation_parameters_h_
#include "random.h"
class FunctionNode;
class FunctionRegistration;
class FunctionRegistry;
//! Class encapsulating mutation parameters.
/*! For example, magnitude of variations, probability of leaves being dropped.
Also provides a random number generator.
*/
class MutationParameters
{
private:
const std::auto_ptr _function_registry;
protected:
//! A random number generator.
/*! Declared mutable so we can pass const MutationParameters& around and still do useful work with it.
*/
mutable Random01 _r01;
//! Negative-exponential generator might be useful too.
mutable RandomNegExp _r_negexp;
//! Specifies the base magnitude of random changes the function parameters.
real _base_magnitude_parameter_variation;
//! Specifies the base probability of a the parameter set being completely reset.
real _base_probability_parameter_reset;
//! Specifies the base probability of a child being dropped and replaced with a new random stub.
real _base_probability_glitch;
//! Specifies the base probability of all child nodes being reordered.
real _base_probability_shuffle;
//! Specifies the base probability of a random stub being inserted before a child.
real _base_probability_insert;
//! Specifies the base probability of a node being replaced with an alternate type.
real _base_probability_substitute;
//! Specifies the proportion of basic node types.
real _proportion_basic;
//! Specifies the proportion of Constant nodes vs Position type nodes.
real _proportion_constant;
//! Specifies the probability of a using a FunctionNodePositionTransformed instead of FunctionNodePosition
real _identity_supression;
//! The maximum number of iterations an iterative function node can have initially.
uint _max_initial_iterations;
//! The base probability of the number of iterations changing by plus or minus 1.
real _base_probability_iterations_change_step;
//! The base probability of the number of iterations changing by times or divide 2.
real _base_probability_iterations_change_jump;
//! Individual weighting modifiers for each function type
/*! Will only be applied to random functions we're asked for.
The bulk of nodes are created by FunctionNode and are boring to keep the branching ratio down.
\todo Implement a branching ratio query method.
*/
std::map _function_weighting;
//! Total of function weights, for normalisation.
real _function_weighting_total;
//! Map from [0,1] to a function registration, taking weights into account.
std::map _function_pick;
//! What state a reset should return autocool to.
const bool _autocool_reset_state;
//! Whether autocooling is being applied.
bool _autocool_enable;
//! Number of generations at which parameters will be half cooled.
uint _autocool_halflife;
//! Count of number of generations for decay cooling.
uint _autocool_generations;
//! Just use SingleChannelNoise for almost all functions (useful for debugging).
const bool _debug_mode;
void recalculate_function_stuff();
public:
//! Trivial constructor.
MutationParameters(uint seed,bool ac,bool debug_mode);
//! Trivial destructor.
virtual ~MutationParameters();
//! Accessor.
const FunctionRegistry& function_registry() const
{
return *_function_registry;
}
//! Reset to initial values.
void reset();
//! Multiply most parameters by the given factor
void general_cool(real f);
//! Returns a reference to the random number generator.
/*! Need this for e.g RandomXYZInSphere constructor.
*/
Random01& rng01() const
{
return _r01;
}
//! Return a number in the range [0,1)
real r01() const
{
return _r01();
}
real rnegexp() const
{
return _r_negexp();
}
//! Accessor, with decay.
real effective_magnitude_parameter_variation() const
{
return base_magnitude_parameter_variation()*decay_factor();
}
//! Accessor.
real base_magnitude_parameter_variation() const
{
return _base_magnitude_parameter_variation;
}
//! Accessor.
void base_magnitude_parameter_variation(real v)
{
_base_magnitude_parameter_variation=v;
report_change();
}
//! Accessor, with decay.
real effective_probability_parameter_reset() const
{
return base_probability_parameter_reset()*decay_factor();
}
//! Accessor.
real base_probability_parameter_reset() const
{
return _base_probability_parameter_reset;
}
//! Accessor.
void base_probability_parameter_reset(real v)
{
_base_probability_parameter_reset=v;
report_change();
}
//! Accessor, with decay.
real effective_probability_glitch() const
{
return base_probability_glitch()*decay_factor();
}
//! Accessor.
real base_probability_glitch() const
{
return _base_probability_glitch;
}
//! Accessor.
void base_probability_glitch(real v)
{
_base_probability_glitch=v;
report_change();
}
//! Accessor, with decay.
real effective_probability_shuffle() const
{
return base_probability_shuffle()*decay_factor();
}
//! Accessor.
real base_probability_shuffle() const
{
return _base_probability_shuffle;
}
//! Accessor.
void base_probability_shuffle(real v)
{
_base_probability_shuffle=v;
report_change();
}
//! Accessor, with decay.
real effective_probability_insert() const
{
return base_probability_insert()*decay_factor();
}
//! Accessor.
real base_probability_insert() const
{
return _base_probability_insert;
}
//! Accessor.
void base_probability_insert(real v)
{
_base_probability_insert=v;
report_change();
}
//! Accessor.
real effective_probability_substitute() const
{
return base_probability_substitute()*decay_factor();
}
//! Accessor.
real base_probability_substitute() const
{
return _base_probability_substitute;
}
//! Accessor.
void base_probability_substitute(real v)
{
_base_probability_substitute=v;
report_change();
}
//! Accessor.
real proportion_constant() const
{
return _proportion_constant;
}
//! Accessor.
void proportion_constant(real v)
{
_proportion_constant=v;
report_change();
}
//! Accessor.
real identity_supression() const
{
return _identity_supression;
}
//! Accessor.
void identity_supression(real v)
{
_identity_supression=v;
report_change();
}
//! Accessor.
uint max_initial_iterations() const
{
return _max_initial_iterations;
}
//! Accessor.
void max_initial_iterations(uint v)
{
_max_initial_iterations=v;
report_change();
}
//! Accessor, with decay.
real effective_probability_iterations_change_step() const
{
return base_probability_iterations_change_step()*decay_factor();
}
//! Accessor.
real base_probability_iterations_change_step() const
{
return _base_probability_iterations_change_step;
}
//! Accessor.
void base_probability_iterations_change_step(real v)
{
_base_probability_iterations_change_step=v;
report_change();
}
//! Accessor, with decay.
real effective_probability_iterations_change_jump() const
{
return base_probability_iterations_change_jump()*decay_factor();
}
//! Accessor.
real base_probability_iterations_change_jump() const
{
return _base_probability_iterations_change_jump;
}
//! Accessor.
void base_probability_iterations_change_jump(real v)
{
_base_probability_iterations_change_jump=v;
report_change();
}
//! Accessor.
real proportion_basic() const
{
return _proportion_basic;
}
//! Accessor.
void proportion_basic(real p)
{
_proportion_basic=p;
report_change();
}
//! Accessor.
bool autocool_enable() const
{
return _autocool_enable;
}
//! Accessor.
void autocool_enable(bool v)
{
_autocool_enable=v;
std::clog << "Autocooling " << (autocool_enable() ? "ON" : "OFF") << "\n";
report_change();
}
//! Accessor.
int autocool_halflife() const
{
return _autocool_halflife;
}
//! Accessor.
void autocool_halflife(int v)
{
_autocool_halflife=v;
report_change();
}
//! Accessor
int autocool_generations() const
{
return _autocool_generations;
}
//! Accessor.
void autocool_generations(int v)
{
_autocool_generations=v;
report_change();
}
//! Accessor.
void autocool_generations_increment()
{
_autocool_generations++;
report_change();
}
//! Calculate branching ratio for above calls
/* Call user should be checking this and diluting with boring nodes to keep it under control
*/
real random_function_branching_ratio() const;
//! This returns a new random bit of tree.
/*! Setting the "exciting" flag avoids the most basic node types, but only at the top level of the stub tree.
*/
std::auto_ptr random_function_stub(bool exciting) const;
void change_function_weighting(const FunctionRegistration* fn,real w);
void randomize_function_weightings_for_classifications(uint classification_mask);
real get_weighting(const FunctionRegistration* fn);
protected:
//! Compute current decay factor
real decay_factor() const;
//! Return a random function appropriately biased by current settings
std::auto_ptr random_function() const;
//! Return a random function registration, appropriately biased by current settings
const FunctionRegistration* random_weighted_function_registration() const;
//! Intended for Qt-world subclass to override to emit signal.
virtual void report_change();
};
#endif
evolvotron/libfunction/functions_friezegroup_hop.h 0000644 0001751 0001751 00000007455 12100750300 022620 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces and implementation for specific Function classes.
*/
#ifndef _functions_friezegroup_hop_h_
#define _functions_friezegroup_hop_h_
#include "friezegroup.h"
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionFriezeGroupHopFreeZ,0,1,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
return FriezegroupEvaluate(arg(0),p,Hop(1.0),FreeZ());
}
FUNCTION_END(FunctionFriezeGroupHopFreeZ)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionFriezeGroupHopClampZ,1,1,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
return FriezegroupEvaluate(arg(0),p,Hop(1.0),ClampZ(param(0)));
}
FUNCTION_END(FunctionFriezeGroupHopClampZ)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionFriezeGroupHopBlendClampZ,1,2,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
return FriezegroupBlend(arg(0),arg(1),p,HopBlend(1.0),ClampZ(param(0)));
}
FUNCTION_END(FunctionFriezeGroupHopBlendClampZ)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionFriezeGroupHopBlendFreeZ,0,2,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
return FriezegroupBlend(arg(0),arg(1),p,HopBlend(1.0),FreeZ());
}
FUNCTION_END(FunctionFriezeGroupHopBlendFreeZ)
//------------------------------------------------------------------------------------------
/*
FUNCTION_BEGIN(FunctionFriezeGroupHopCutClampZ,2,2,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
const int d=FriezegroupCut(arg(1),p,HopCut(1.0),ClampZ(param(1)));
return FriezegroupEvaluate(arg(0),p,Hop(1.0,d),ClampZ(param(0)));
}
FUNCTION_END(FunctionFriezeGroupHopCutClampZ)
*/
//------------------------------------------------------------------------------------------
/*
FUNCTION_BEGIN(FunctionFriezeGroupHopCutFreeZ,0,2,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
const int d=FriezegroupCut(arg(1),p,HopCut(1.0),FreeZ());
return FriezegroupEvaluate(arg(0),p,Hop(1.0,d),FreeZ());
}
FUNCTION_END(FunctionFriezeGroupHopCutFreeZ)
*/
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/functions_shadow.h 0000644 0001751 0001751 00000004631 12100750300 020667 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces and implementation for specific Function classes.
*/
#ifndef _functions_shadow_h_
#define _functions_shadow_h_
//------------------------------------------------------------------------------------------
//! Sum of two evaluations of a function, one sampled at a constant offset and weighted.
FUNCTION_BEGIN(FunctionShadow,4,1,false,0)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
return
arg(0)(p)+param(3)*arg(0)(p+XYZ(param(0),param(1),param(2)));
}
FUNCTION_END(FunctionShadow)
//------------------------------------------------------------------------------------------
//! Like FunctionShadow but the offset is obtained from a function.
FUNCTION_BEGIN(FunctionShadowGeneralised,1,2,false,0)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
return
arg(0)(p)+param(0)*arg(0)(p+arg(1)(p));
}
FUNCTION_END(FunctionShadowGeneralised)
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/function_boilerplate_instantiate.h 0000644 0001751 0001751 00000003676 12100750300 024134 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Modifications to function_boilerplate macros.
Include this in function .cpp files before the header is included.
(This used to be simulated by putting #define INSTANTIATE_FN in front of function_boilerplate.h,
but we wanted function_boilerplate.h to go in precompiled header.
*/
#ifndef _function_boilerplate_instantiate_h_
#define _function_boilerplate_instantiate_h_
#undef FUNCTION_END
//! Replace definition to obtain concrete implementations
#define FUNCTION_END(FN) };FN_CTOR_IMP(FN);FN_DTOR_IMP(FN);FN_VNAME_IMP(FN);FN_SNAME_IMP(FN);REGISTER_IMP(FN);
#endif
evolvotron/libfunction/functions_friezegroup_sidle.h 0000644 0001751 0001751 00000004506 12100750300 023124 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces and implementation for specific Function classes.
*/
#ifndef _functions_friezegroup_sidle_h_
#define _functions_friezegroup_sidle_h_
#include "friezegroup.h"
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionFriezeGroupSidleFreeZ,0,1,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
return FriezegroupEvaluate(arg(0),p,Sidle(1.0),FreeZ());
}
FUNCTION_END(FunctionFriezeGroupSidleFreeZ)
//------------------------------------------------------------------------------------------
FUNCTION_BEGIN(FunctionFriezeGroupSidleClampZ,1,1,false,FnStructure)
virtual const XYZ evaluate(const XYZ& p) const
{
return FriezegroupEvaluate(arg(0),p,Sidle(1.0),ClampZ(param(0)));
}
FUNCTION_END(FunctionFriezeGroupSidleClampZ)
//------------------------------------------------------------------------------------------
#endif
evolvotron/libfunction/function_compose_triple.h 0000644 0001751 0001751 00000003766 12100750300 022253 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces and implementation for FunctionComposeTriple
*/
#ifndef _function_compose_triple_h_
#define _function_compose_triple_h_
FUNCTION_BEGIN(FunctionComposeTriple,0,3,false,0)
//! Evaluate function.
virtual const XYZ evaluate(const XYZ& p) const
{
return arg(2)(arg(1)(arg(0)(p)));
}
//! Is constant if any (rather than default "all") function is constant.
/*! One of the few cases it's worth overriding this method
*/
virtual bool is_constant() const
{
return (arg(0).is_constant() || arg(1).is_constant() || arg(2).is_constant());
}
FUNCTION_END(FunctionComposeTriple)
#endif
evolvotron/libfunction/libfunction_precompiled.h 0000644 0001751 0001751 00000003311 12100750300 022203 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Precompiled header for libfunction
*/
#ifndef _libfunction_precompiled_h_
#define _libfunction_precompiled_h_
// Ordering is important here because all headers assume all precompiled headers preceed them.
#include "useful.h"
#include "xy.h"
#include "xyz.h"
#include "function_node.h"
#include "function_boilerplate.h"
#endif
evolvotron/libfunction/function_node.h 0000644 0001751 0001751 00000020200 12100750300 020132 0 ustar timday timday /**************************************************************************/
/* Copyright 2012 Tim Day */
/* */
/* This file is part of Evolvotron */
/* */
/* Evolvotron 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 of the License, or */
/* (at your option) any later version. */
/* */
/* Evolvotron 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 Evolvotron. If not, see . */
/**************************************************************************/
/*! \file
\brief Interfaces for class FunctionNode and derived classes.
*/
#ifndef _function_node_h_
#define _function_node_h_
class FunctionNodeInfo;
class FunctionTop;
class FunctionPreTransform;
class FunctionPostTransform;
class FunctionRegistry;
class MutatableImage;
class MutationParameters;
class Function : boost::noncopyable
{
public:
virtual ~Function()
{}
//! Convenience wrapper for evaluate (actually, evaluate is protected so can't be called externally anyway)
const XYZ operator()(const XYZ& p) const
{
return evaluate(p);
}
//! Weighted evaluate; fastpath for zero weight.
const XYZ operator()(const real weight,const XYZ& p) const
{
return (weight==0.0 ? XYZ(0.0,0.0,0.0) : weight*evaluate(p));
}
//! This what distinguishes different types of function.
virtual const XYZ evaluate(const XYZ&) const
=0;
};
//! Abstract base class for all kinds of mutatable image node.
/*! MutatableImage declared a friend to help constification of the public accessors.
*/
class FunctionNode : public Function
{
public:
friend class MutatableImage;
private:
//! The arguments (ie child nodes) for this node.
boost::ptr_vector _args;
//! The parameters (ie constant values) for this node.
std::vector _params;
//! Number of iterations for iterative function types. If zero, indicates non-iterative function.
/*! \todo Perhaps someday push this out into a derived class.
*/
uint _iterations;
protected:
//! This returns a deep-cloned copy of the node's children.
std::auto_ptr > cloneargs() const;
//! This returns a copy of the node's parameters
const std::vector cloneparams() const;
//! Obtain some statistics about the image function
void get_stats(uint& total_nodes,uint& total_parameters,uint& depth,uint& width,real& proportion_constant) const;
//! Check function info against given number of parameters/arguments/iterative-flag.
/*! Return true on success, false on fail with reasons in report string.
Mainly for use by derived FunctionBoilerplate template to avoid duplicate code proliferation.
*/
static bool verify_info(const FunctionNodeInfo& info,unsigned int np,unsigned int na,bool it,std::string& report);
//! Build argument list.
/*! Return true on success, false on fail with reasons in report string.
Mainly for use by derived FunctionBoilerplate template to avoid duplicate code proliferation.
*/
static bool create_args(const FunctionRegistry&,const FunctionNodeInfo& info,boost::ptr_vector& args,std::string& report);
public:
//! Returns true if the function is independent of it's position argument.
/*! This isn't used for optimisation (which would require FunctionNode to have computation-specific state,
which would wreck plans for reference counted deepclone()),
but to cull boring constant images on creation.
Default implementation (and probably the only sensible one)
is constant if all args are constant; no args returns false.
*/
virtual bool is_constant() const;
//! Internal self consistency check.
virtual bool ok() const;
//! Bits give some classification of the function type
virtual uint self_classification() const
=0;
//@{
//! Query the node as to whether it is a FunctionTop (return null if not).
virtual const FunctionTop* is_a_FunctionTop() const;
virtual FunctionTop* is_a_FunctionTop();
//@}
//! This returns a new random bit of tree. Setting the "exciting" flag avoids basic node types, but only at the top level of the stub tree.
static std::auto_ptr stub(const MutationParameters& parameters,bool exciting);
//! This returns a vector of random parameter values.
static void stubparams(std::vector&,const MutationParameters& parameters,uint n);
//! This returns a vector of new random bits of tree.
static void stubargs(boost::ptr_vector&,const MutationParameters& parameters,uint n,bool exciting=false);
//! Return a suitable starting value for a node's iteration count (assuming it's iterative).
static uint stubiterations(const MutationParameters& parameters);
//! Constructor given an array of params and args and an iteration count.
/*! These MUST be provided; there are no alterative constructors.
*/
FunctionNode(const std::vector& p,boost::ptr_vector& a,uint iter);
//! Build a FunctionNode given a description
static std::auto_ptr create(const FunctionRegistry& function_registry,const FunctionNodeInfo& info,std::string& report);
//! Destructor.
virtual ~FunctionNode();
//! Accessor
void params(const std::vector& p)
{
_params=p;
}
//! Accessor.
const std::vector& params() const
{
return _params;
}
//! Accessor.
real param(uint n) const
{
assert(n& args() const
{
return _args;
}
//! Accessor.
void args(boost::ptr_vector& a)
{
_args=a.release();
}
//! Accessor.
const FunctionNode& arg(uint n) const
{
assert(n deepclone() const
=0;
//! Prune any is_constant() nodes and replace them with an actual constant node
virtual void simplify_constants();
//! Return a deepcloned copy of the node's arguments
virtual std::auto_ptr > deepclone_args() const;
//! Save the function tree.
virtual std::ostream& save_function(std::ostream& out,uint indent) const
=0;
protected:
//! Save the function tree. Common code needing a function name.
std::ostream& save_function(std::ostream& out,uint indent,const std::string& function_name) const;
//! Accessor (non-const).
boost::ptr_vector& args()
{
return _args;
}
//! Accessor (non-const).
std::vector& params()
{
return _params;
}
//! Accessor.
FunctionNode& arg(uint n)
{
assert(n