untested cleanup
This commit is contained in:
674
generators/apollon/LICENSE
Executable file
674
generators/apollon/LICENSE
Executable file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. 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
|
||||
them 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 prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. 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.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey 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;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If 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 convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU 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 that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
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.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
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.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
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
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program 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, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU 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 Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
89
generators/apollon/README.rst
Executable file
89
generators/apollon/README.rst
Executable file
@@ -0,0 +1,89 @@
|
||||
Apollon
|
||||
#######
|
||||
|
||||
About
|
||||
=====
|
||||
|
||||
These are some python classes and functions for calculating Apollonian
|
||||
Gaskets and saving them as svg. For an overview about this
|
||||
mathematical object, see wikipedia_.
|
||||
|
||||
The code is split into the following files:
|
||||
|
||||
- `apollon.py`:code: contains all the pure math stuff
|
||||
- `coloring.py`:code: contains helpers for color mapping
|
||||
- `ag.py`:code: is a command-line tool for generating Apollonian Gaskets
|
||||
- `index.cgi`:code: is an interactive online cgi version
|
||||
- `colorbrewer.json`:code: contains the color schemes, copied from
|
||||
https://gist.github.com/jsundram/6004447#file-colorbrewer-json
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
CLI
|
||||
---
|
||||
|
||||
Run `./ag.py c1 c2 c3`:code: where c1, c2, c3 are the (positive) curvatures
|
||||
of the starting circles. Please also see the `--help`:code: option.
|
||||
|
||||
Note: The method used to calculate the circles is recursive. For depth
|
||||
d, 2*3^{d+1} circles are created. It is usually safe to do this up to
|
||||
d=10, but with higher values you can reach the limit of your
|
||||
RAM. Because of this, and to prevent typos potentially crashing your
|
||||
machine, the recursion depth is capped at d=10. If you know what you
|
||||
are doing, you can use the `--force`:code: option for higher values.
|
||||
|
||||
CGI
|
||||
---
|
||||
|
||||
Online interactive version. You can try it at
|
||||
http://lsandig.org/cgi-bin/apollon/index.cgi
|
||||
|
||||
Recursion depth is limited to 5 to reduce server load and RAM
|
||||
usage. This implementation might not be very fast, it is just intended
|
||||
as a showcase of what you can expect from the CLI-version.
|
||||
|
||||
Needs python3 and the other three files to work.
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
||||
For the cli-program see `ag.py --help`:code:.
|
||||
|
||||
For a somewhat complete documentation of the source files run
|
||||
`epydoc --html apollon.py ag.py coloring.py`:code:
|
||||
|
||||
For a writeup on how the math behind this program works see my
|
||||
blogpost here: http://lsandig.org/blog/2014/08/apollon-python/en/
|
||||
|
||||
TODO
|
||||
====
|
||||
- More logical structure of the source files
|
||||
- Better documentation
|
||||
- A time- and RAM-saving algorithm that excludes Circles from
|
||||
recursion which are too small to be seen.
|
||||
- fastcgi version of index.cgi?
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Colors from www.ColorBrewer.org by Cynthia A. Brewer, Geography,
|
||||
Pennsylvania State University.
|
||||
|
||||
Thanks to Dorothee Henke for helping me figuring out the math.
|
||||
|
||||
Author & License
|
||||
================
|
||||
|
||||
| Author: Ludger Sandig
|
||||
| Contact: contact@lsandig.org
|
||||
| Homepage: http://lsandig.org/
|
||||
|
||||
This software can be found on github:
|
||||
https://github.com/lsandig/apollon
|
||||
|
||||
This software is published under the GPL, see LICENSE
|
||||
|
||||
.. Links
|
||||
.. _wikipedia: https://en.wikipedia.org/wiki/Apollonian_gasket
|
||||
228
generators/apollon/ag.py
Executable file
228
generators/apollon/ag.py
Executable file
@@ -0,0 +1,228 @@
|
||||
#! /usr/bin/python3
|
||||
|
||||
# Command line program to create svg apollonian circles
|
||||
|
||||
# Copyright (c) 2014 Ludger Sandig
|
||||
# This file is part of apollon.
|
||||
|
||||
# Apollon 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.
|
||||
|
||||
# Apollon 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 Apollon. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import math
|
||||
|
||||
from apollon import ApollonianGasket
|
||||
from coloring import ColorMap, ColorScheme
|
||||
|
||||
def parseArguments(argv, colors):
|
||||
description = "Generate Apollonian Gaskets and save as svg"
|
||||
name = argv[0]
|
||||
|
||||
colors.append('none')
|
||||
colors.sort()
|
||||
|
||||
parser = argparse.ArgumentParser(description=description, prog=name)
|
||||
|
||||
parser.add_argument("-d", "--depth", metavar="D", type=int, default=3, help="Recursion depth, generates 2*3^{D+1} circles. Usually safe for D<=10. For higher D use --force if you know what you are doing.")
|
||||
parser.add_argument("-o", "--output", metavar="", type=str, default="", help="Output file name. If left blank, default is created from circle curvatures.")
|
||||
parser.add_argument("-r", "--radii", action="store_true", default=False, help="Interpret c1, c2, c3 as radii and not as curvatures")
|
||||
parser.add_argument("--color", choices=colors, metavar='SCHEME', default='none', help="Color Scheme. Choose from "+", ".join(colors))
|
||||
parser.add_argument("--treshold", metavar='T', default=0.005, type=float, help="Don't save circles that are too small. Useful for higher depths to reduce filesize.")
|
||||
parser.add_argument("--force", action="store_true", default=False, help="Use if you want a higher recursion depth than 10.")
|
||||
|
||||
parser.add_argument("c1", type=float, help="Curvature of first circle")
|
||||
parser.add_argument("c2", type=float, help="Curvature of second circle")
|
||||
parser.add_argument("c3", type=float, help="Curvature of third circle")
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
def colorMsg(color):
|
||||
print("Available color schemes (name: resmin -- resmax)")
|
||||
for i in color.info():
|
||||
print("%s: %d -- %d" % (i["name"], i["low"], i["high"]))
|
||||
|
||||
def ag_to_svg(circles, colors, tresh=0.005):
|
||||
"""
|
||||
Convert a list of circles to svg, optionally color them.
|
||||
@param circles: A list of L{Circle}s
|
||||
@param colors: A L{ColorMap} object
|
||||
@param tresh: Only circles with a radius greater than the product of tresh and maximal radius are saved
|
||||
"""
|
||||
svg = []
|
||||
|
||||
# Find the biggest circle, which hopefully is the enclosing one
|
||||
# and has a negative radius because of this. Note that this does
|
||||
# not have to be the case if we picked an unlucky set of radii at
|
||||
# the start. If that was the case, we're screwed now.
|
||||
|
||||
big = min(circles, key=lambda c: c.r.real)
|
||||
|
||||
# Move biggest circle to front so it gets drawn first
|
||||
circles.remove(big)
|
||||
circles.insert(0, big)
|
||||
|
||||
if big.r.real < 0:
|
||||
# Bounding box from biggest circle, lower left corner and two
|
||||
# times the radius as width
|
||||
corner = big.m - ( abs(big.r) + abs(big.r) * 1j )
|
||||
vbwidth = abs(big.r)*2
|
||||
width = 500 # Hardcoded!
|
||||
|
||||
# Line width independent of circle size
|
||||
lw = (vbwidth/width)
|
||||
|
||||
svg.append('<svg xmlns="http://www.w3.org/2000/svg" width="%f" height="%f" viewBox="%f %f %f %f">\n' % (width, width, corner.real, corner.imag, vbwidth, vbwidth))
|
||||
|
||||
# Keep stroke width relative
|
||||
svg.append('<g stroke-width="%f">\n' % lw)
|
||||
|
||||
# Iterate through circle list, circles with radius<radmin
|
||||
# will not be saved because they are too small for printing.
|
||||
radmin = tresh * abs(big.r)
|
||||
|
||||
for c in circles:
|
||||
if abs(c.r) > radmin:
|
||||
fill = colors.color_for(abs(c.r))
|
||||
svg.append(( '<circle cx="%f" cy="%f" r="%f" fill="%s" stroke="black"/>\n' % (c.m.real, c.m.imag, abs(c.r), fill)))
|
||||
|
||||
svg.append('</g>\n')
|
||||
svg.append('</svg>\n')
|
||||
|
||||
return ''.join(svg)
|
||||
|
||||
def ag_to_hpgl(circles, colors, tresh=0.005):
|
||||
"""
|
||||
Convert a list of circles to hpgl,
|
||||
@param circles: A list of L{Circle}s
|
||||
@param tresh: Only circles with a radius greater than the product of tresh and maximal radius are saved
|
||||
"""
|
||||
hpgl = []
|
||||
|
||||
# Find the biggest circle, which hopefully is the enclosing one
|
||||
# and has a negative radius because of this. Note that this does
|
||||
# not have to be the case if we picked an unlucky set of radii at
|
||||
# the start. If that was the case, we're screwed now.
|
||||
|
||||
big = min(circles, key=lambda c: c.r.real)
|
||||
|
||||
# Move biggest circle to front so it gets drawn first
|
||||
circles.remove(big)
|
||||
circles.insert(0, big)
|
||||
|
||||
eps = 0.001
|
||||
|
||||
if big.r.real < 0:
|
||||
# Bounding box from biggest circle, lower left corner and two
|
||||
# times the radius as width
|
||||
corner = big.m - ( abs(big.r) + abs(big.r) * 1j )
|
||||
|
||||
# Gerards Hack
|
||||
big.r = abs(big.r) + 2*eps
|
||||
|
||||
vbwidth = abs(big.r)*2
|
||||
width = 500 # Hardcoded!
|
||||
|
||||
# Line width independent of circle size
|
||||
lw = (vbwidth/width)
|
||||
|
||||
hpgl.append('IN;SP1;')
|
||||
|
||||
# Iterate through circle list, circles with radius<radmin
|
||||
# will not be saved because they are too small for printing.
|
||||
radmin = tresh * abs(big.r)
|
||||
|
||||
for c in circles:
|
||||
if abs(c.r)-eps > radmin:
|
||||
hpgl.append('PU'+str(c.m.real)+','+str(c.m.imag)+';CI'+str(abs(c.r)-eps)+';')
|
||||
|
||||
|
||||
return ''.join(hpgl)
|
||||
|
||||
def impossible_combination(c1, c2, c3):
|
||||
# If any curvatures x, y, z satisfy the equation
|
||||
# x = 2*sqrt(y*z) + y + z
|
||||
# then no fourth enclosing circle can be genereated, because it
|
||||
# would be a line.
|
||||
# We need to see for c1, c2, c3 if they could be "x".
|
||||
|
||||
impossible = False
|
||||
|
||||
sets = [(c1,c2,c3), (c2,c3,c1), (c3,c1,c2)]
|
||||
|
||||
for (x, y, z) in sets:
|
||||
if x == 2*math.sqrt(y*z) + y + z:
|
||||
impossible = True
|
||||
|
||||
return impossible
|
||||
|
||||
def main():
|
||||
color = ColorScheme("colorbrewer.json")
|
||||
available = [d['name'] for d in color.info()]
|
||||
|
||||
args = parseArguments(sys.argv, available)
|
||||
|
||||
# Sanity checks
|
||||
for c in [args.c1, args.c2, args.c3]:
|
||||
if c == 0:
|
||||
print("Error: curvature or radius can't be 0")
|
||||
exit(1)
|
||||
if impossible_combination(args.c1, args.c2, args.c3):
|
||||
print("Error: no apollonian gasket possible for these curvatures")
|
||||
exit(1)
|
||||
|
||||
# Given curvatures were in fact radii, so take the reciprocal
|
||||
if args.radii:
|
||||
args.c1 = 1/args.c1
|
||||
args.c2 = 1/args.c2
|
||||
args.c3 = 1/args.c3
|
||||
|
||||
ag = ApollonianGasket(args.c1, args.c2, args.c3)
|
||||
|
||||
# At a recursion depth > 10 things start to get serious.
|
||||
if args.depth > 10:
|
||||
if not args.force:
|
||||
print("Note: Number of cicles increases exponentially with 2*3^{D+1} at depth D.\nIf you want to use D>10, specify the --force option.")
|
||||
args.depth = 10
|
||||
|
||||
ag.generate(args.depth)
|
||||
|
||||
# Get smallest and biggest radius
|
||||
smallest = abs(min(ag.genCircles, key=lambda c: abs(c.r.real)).r.real)
|
||||
biggest = abs(max(ag.genCircles, key=lambda c: abs(c.r.real)).r.real)
|
||||
|
||||
# Construct color map
|
||||
if args.color == 'none':
|
||||
mp = ColorMap('none')
|
||||
else:
|
||||
# TODO: resolution of 8 is hardcoded, some color schemes have
|
||||
# resolutions up to 11. Make this configurable.
|
||||
mp = color.makeMap(smallest, biggest, args.color, 8)
|
||||
|
||||
svg = ag_to_svg(ag.genCircles, mp, tresh=args.treshold)
|
||||
hpgl = ag_to_hpgl(ag.genCircles, mp, tresh=args.treshold)
|
||||
# User supplied filename? If not, we need to construct something.
|
||||
if len(args.output) == 0:
|
||||
args.output = 'ag_%.4f_%.4f_%.4f.svg' % (args.c1, args.c2, args.c3)
|
||||
|
||||
with open(args.output, 'w') as f:
|
||||
f.write(svg)
|
||||
f.close()
|
||||
|
||||
with open(args.output+'.hpgl', 'w') as f:
|
||||
f.write(hpgl)
|
||||
f.close()
|
||||
|
||||
if( __name__ == "__main__" ):
|
||||
main()
|
||||
195
generators/apollon/apollon.py
Executable file
195
generators/apollon/apollon.py
Executable file
@@ -0,0 +1,195 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Generate Apollonian Gaskets -- the math part.
|
||||
|
||||
# Copyright (c) 2014 Ludger Sandig
|
||||
# This file is part of apollon.
|
||||
|
||||
# Apollon 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.
|
||||
|
||||
# Apollon 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 Apollon. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from cmath import *
|
||||
import random
|
||||
|
||||
class Circle(object):
|
||||
"""
|
||||
A circle represented by center point as complex number and radius.
|
||||
"""
|
||||
def __init__ ( self, mx, my, r ):
|
||||
"""
|
||||
@param mx: x center coordinate
|
||||
@type mx: int or float
|
||||
@param my: y center coordinate
|
||||
@type my: int or float
|
||||
@param r: radius
|
||||
@type r: int or float
|
||||
"""
|
||||
self.r = r
|
||||
self.m = (mx +my*1j)
|
||||
|
||||
def __repr__ ( self ):
|
||||
"""
|
||||
Pretty printing
|
||||
"""
|
||||
return "Circle( self, %s, %s, %s )" % (self.m.real, self.m.imag, self.r)
|
||||
|
||||
def __str__ ( self ):
|
||||
"""
|
||||
Pretty printing
|
||||
"""
|
||||
return "Circle x:%.3f y:%.3f r:%.3f [cur:%.3f]" % (self.m.real, self.m.imag, self.r.real, self.curvature().real)
|
||||
|
||||
def curvature (self):
|
||||
"""
|
||||
Get circle's curvature.
|
||||
@rtype: float
|
||||
@return: Curvature of the circle.
|
||||
"""
|
||||
return 1/self.r
|
||||
|
||||
def outerTangentCircle( circle1, circle2, circle3 ):
|
||||
"""
|
||||
Takes three externally tangent circles and calculates the fourth one enclosing them.
|
||||
@param circle1: first circle
|
||||
@param circle2: second circle
|
||||
@param circle3: third circle
|
||||
@type circle1: L{Circle}
|
||||
@type circle2: L{Circle}
|
||||
@type circle3: L{Circle}
|
||||
@return: The enclosing circle
|
||||
@rtype: L{Circle}
|
||||
"""
|
||||
cur1 = circle1.curvature()
|
||||
cur2 = circle2.curvature()
|
||||
cur3 = circle3.curvature()
|
||||
m1 = circle1.m
|
||||
m2 = circle2.m
|
||||
m3 = circle3.m
|
||||
cur4 = -2 * sqrt( cur1*cur2 + cur2*cur3 + cur1 * cur3 ) + cur1 + cur2 + cur3
|
||||
m4 = ( -2 * sqrt( cur1*m1*cur2*m2 + cur2*m2*cur3*m3 + cur1*m1*cur3*m3 ) + cur1*m1 + cur2*m2 + cur3*m3 ) / cur4
|
||||
circle4 = Circle( m4.real, m4.imag, 1/cur4 )
|
||||
|
||||
return circle4
|
||||
|
||||
|
||||
def tangentCirclesFromRadii( r2, r3, r4 ):
|
||||
"""
|
||||
Takes three radii and calculates the corresponding externally
|
||||
tangent circles as well as a fourth one enclosing them. The enclosing
|
||||
circle is the first one.
|
||||
|
||||
@param r2, r3, r4: Radii of the circles to calculate
|
||||
@type r2: int or float
|
||||
@type r3: int or float
|
||||
@type r4: int or float
|
||||
@return: The four circles, where the first one is the enclosing one.
|
||||
@rtype: (L{Circle}, L{Circle}, L{Circle}, L{Circle})
|
||||
"""
|
||||
circle2 = Circle( 0, 0, r2 )
|
||||
circle3 = Circle( r2 + r3, 0, r3 )
|
||||
m4x = (r2*r2 + r2*r4 + r2*r3 - r3*r4) / (r2 + r3)
|
||||
m4y = sqrt( (r2 + r4) * (r2 + r4) - m4x*m4x )
|
||||
circle4 = Circle( m4x, m4y, r4 )
|
||||
circle1 = outerTangentCircle( circle2, circle3, circle4 )
|
||||
return ( circle1, circle2, circle3, circle4 )
|
||||
|
||||
def secondSolution( fixed, c1, c2, c3 ):
|
||||
"""
|
||||
If given four tangent circles, calculate the other one that is tangent
|
||||
to the last three.
|
||||
|
||||
@param fixed: The fixed circle touches the other three, but not
|
||||
the one to be calculated.
|
||||
|
||||
@param c1, c2, c3: Three circles to which the other tangent circle
|
||||
is to be calculated.
|
||||
|
||||
@type fixed: L{Circle}
|
||||
@type c1: L{Circle}
|
||||
@type c2: L{Circle}
|
||||
@type c3: L{Circle}
|
||||
@return: The circle.
|
||||
@rtype: L{Circle}
|
||||
"""
|
||||
|
||||
curf = fixed.curvature()
|
||||
cur1 = c1.curvature()
|
||||
cur2 = c2.curvature()
|
||||
cur3 = c3.curvature()
|
||||
|
||||
curn = 2 * (cur1 + cur2 + cur3) - curf
|
||||
mn = (2 * (cur1*c1.m + cur2*c2.m + cur3*c3.m) - curf*fixed.m ) / curn
|
||||
return Circle( mn.real, mn.imag, 1/curn )
|
||||
|
||||
class ApollonianGasket(object):
|
||||
"""
|
||||
Container for an Apollonian Gasket.
|
||||
"""
|
||||
def __init__(self, c1, c2, c3):
|
||||
"""
|
||||
Creates a basic apollonian Gasket with four circles.
|
||||
|
||||
@param c1, c2, c3: The curvatures of the three inner circles of the
|
||||
starting set (i.e. depth 0 of the recursion). The fourth,
|
||||
enclosing circle will be calculated from them.
|
||||
@type c1: int or float
|
||||
@type c2: int or float
|
||||
@type c3: int or float
|
||||
"""
|
||||
self.start = tangentCirclesFromRadii( 1/c1, 1/c2, 1/c3 )
|
||||
self.genCircles = list(self.start)
|
||||
|
||||
def recurse(self, circles, depth, maxDepth):
|
||||
"""Recursively calculate the smaller circles of the AG up to the
|
||||
given depth. Note that for depth n we get 2*3^{n+1} circles.
|
||||
|
||||
@param maxDepth: Maximal depth of the recursion.
|
||||
@type maxDepth: int
|
||||
|
||||
@param circles: 4-Tuple of circles for which the second
|
||||
solutions are calculated
|
||||
@type circles: (L{Circle}, L{Circle}, L{Circle}, L{Circle})
|
||||
|
||||
@param depth: Current depth
|
||||
@type depth: int
|
||||
"""
|
||||
if( depth == maxDepth ):
|
||||
return
|
||||
(c1, c2, c3, c4) = circles
|
||||
if( depth == 0 ):
|
||||
# First recursive step, this is the only time we need to
|
||||
# calculate 4 new circles.
|
||||
del self.genCircles[4:]
|
||||
cspecial = secondSolution( c1, c2, c3, c4 )
|
||||
self.genCircles.append( cspecial )
|
||||
self.recurse( (cspecial, c2, c3, c4), 1, maxDepth )
|
||||
|
||||
cn2 = secondSolution( c2, c1, c3, c4 )
|
||||
self.genCircles.append( cn2 )
|
||||
cn3 = secondSolution( c3, c1, c2, c4 )
|
||||
self.genCircles.append( cn3 )
|
||||
cn4 = secondSolution( c4, c1, c2, c3 )
|
||||
self.genCircles.append( cn4 )
|
||||
|
||||
self.recurse( (cn2, c1, c3, c4), depth+1, maxDepth )
|
||||
self.recurse( (cn3, c1, c2, c4), depth+1, maxDepth )
|
||||
self.recurse( (cn4, c1, c2, c3), depth+1, maxDepth )
|
||||
|
||||
def generate(self, depth):
|
||||
"""
|
||||
Wrapper for the recurse function. Generate the AG,
|
||||
@param depth: Recursion depth of the Gasket
|
||||
@type depth: int
|
||||
"""
|
||||
self.recurse(self.start, 0, depth)
|
||||
|
||||
301
generators/apollon/colorbrewer.json
Executable file
301
generators/apollon/colorbrewer.json
Executable file
@@ -0,0 +1,301 @@
|
||||
{"YlGn": {
|
||||
"3": ["#f7fcb9","#addd8e","#31a354"],
|
||||
"4": ["#ffffcc","#c2e699","#78c679","#238443"],
|
||||
"5": ["#ffffcc","#c2e699","#78c679","#31a354","#006837"],
|
||||
"6": ["#ffffcc","#d9f0a3","#addd8e","#78c679","#31a354","#006837"],
|
||||
"7": ["#ffffcc","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#005a32"],
|
||||
"8": ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#005a32"],
|
||||
"9": ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"]
|
||||
},"YlGnBu": {
|
||||
"3": ["#edf8b1","#7fcdbb","#2c7fb8"],
|
||||
"4": ["#ffffcc","#a1dab4","#41b6c4","#225ea8"],
|
||||
"5": ["#ffffcc","#a1dab4","#41b6c4","#2c7fb8","#253494"],
|
||||
"6": ["#ffffcc","#c7e9b4","#7fcdbb","#41b6c4","#2c7fb8","#253494"],
|
||||
"7": ["#ffffcc","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#0c2c84"],
|
||||
"8": ["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#0c2c84"],
|
||||
"9": ["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"]
|
||||
},"GnBu": {
|
||||
"3": ["#e0f3db","#a8ddb5","#43a2ca"],
|
||||
"4": ["#f0f9e8","#bae4bc","#7bccc4","#2b8cbe"],
|
||||
"5": ["#f0f9e8","#bae4bc","#7bccc4","#43a2ca","#0868ac"],
|
||||
"6": ["#f0f9e8","#ccebc5","#a8ddb5","#7bccc4","#43a2ca","#0868ac"],
|
||||
"7": ["#f0f9e8","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#08589e"],
|
||||
"8": ["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#08589e"],
|
||||
"9": ["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#0868ac","#084081"]
|
||||
},"BuGn": {
|
||||
"3": ["#e5f5f9","#99d8c9","#2ca25f"],
|
||||
"4": ["#edf8fb","#b2e2e2","#66c2a4","#238b45"],
|
||||
"5": ["#edf8fb","#b2e2e2","#66c2a4","#2ca25f","#006d2c"],
|
||||
"6": ["#edf8fb","#ccece6","#99d8c9","#66c2a4","#2ca25f","#006d2c"],
|
||||
"7": ["#edf8fb","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#005824"],
|
||||
"8": ["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#005824"],
|
||||
"9": ["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#006d2c","#00441b"]
|
||||
},"PuBuGn": {
|
||||
"3": ["#ece2f0","#a6bddb","#1c9099"],
|
||||
"4": ["#f6eff7","#bdc9e1","#67a9cf","#02818a"],
|
||||
"5": ["#f6eff7","#bdc9e1","#67a9cf","#1c9099","#016c59"],
|
||||
"6": ["#f6eff7","#d0d1e6","#a6bddb","#67a9cf","#1c9099","#016c59"],
|
||||
"7": ["#f6eff7","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016450"],
|
||||
"8": ["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016450"],
|
||||
"9": ["#fff7fb","#ece2f0","#d0d1e6","#a6bddb","#67a9cf","#3690c0","#02818a","#016c59","#014636"]
|
||||
},"PuBu": {
|
||||
"3": ["#ece7f2","#a6bddb","#2b8cbe"],
|
||||
"4": ["#f1eef6","#bdc9e1","#74a9cf","#0570b0"],
|
||||
"5": ["#f1eef6","#bdc9e1","#74a9cf","#2b8cbe","#045a8d"],
|
||||
"6": ["#f1eef6","#d0d1e6","#a6bddb","#74a9cf","#2b8cbe","#045a8d"],
|
||||
"7": ["#f1eef6","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#034e7b"],
|
||||
"8": ["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#034e7b"],
|
||||
"9": ["#fff7fb","#ece7f2","#d0d1e6","#a6bddb","#74a9cf","#3690c0","#0570b0","#045a8d","#023858"]
|
||||
},"BuPu": {
|
||||
"3": ["#e0ecf4","#9ebcda","#8856a7"],
|
||||
"4": ["#edf8fb","#b3cde3","#8c96c6","#88419d"],
|
||||
"5": ["#edf8fb","#b3cde3","#8c96c6","#8856a7","#810f7c"],
|
||||
"6": ["#edf8fb","#bfd3e6","#9ebcda","#8c96c6","#8856a7","#810f7c"],
|
||||
"7": ["#edf8fb","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#6e016b"],
|
||||
"8": ["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#6e016b"],
|
||||
"9": ["#f7fcfd","#e0ecf4","#bfd3e6","#9ebcda","#8c96c6","#8c6bb1","#88419d","#810f7c","#4d004b"]
|
||||
},"RdPu": {
|
||||
"3": ["#fde0dd","#fa9fb5","#c51b8a"],
|
||||
"4": ["#feebe2","#fbb4b9","#f768a1","#ae017e"],
|
||||
"5": ["#feebe2","#fbb4b9","#f768a1","#c51b8a","#7a0177"],
|
||||
"6": ["#feebe2","#fcc5c0","#fa9fb5","#f768a1","#c51b8a","#7a0177"],
|
||||
"7": ["#feebe2","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177"],
|
||||
"8": ["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177"],
|
||||
"9": ["#fff7f3","#fde0dd","#fcc5c0","#fa9fb5","#f768a1","#dd3497","#ae017e","#7a0177","#49006a"]
|
||||
},"PuRd": {
|
||||
"3": ["#e7e1ef","#c994c7","#dd1c77"],
|
||||
"4": ["#f1eef6","#d7b5d8","#df65b0","#ce1256"],
|
||||
"5": ["#f1eef6","#d7b5d8","#df65b0","#dd1c77","#980043"],
|
||||
"6": ["#f1eef6","#d4b9da","#c994c7","#df65b0","#dd1c77","#980043"],
|
||||
"7": ["#f1eef6","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#91003f"],
|
||||
"8": ["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#91003f"],
|
||||
"9": ["#f7f4f9","#e7e1ef","#d4b9da","#c994c7","#df65b0","#e7298a","#ce1256","#980043","#67001f"]
|
||||
},"OrRd": {
|
||||
"3": ["#fee8c8","#fdbb84","#e34a33"],
|
||||
"4": ["#fef0d9","#fdcc8a","#fc8d59","#d7301f"],
|
||||
"5": ["#fef0d9","#fdcc8a","#fc8d59","#e34a33","#b30000"],
|
||||
"6": ["#fef0d9","#fdd49e","#fdbb84","#fc8d59","#e34a33","#b30000"],
|
||||
"7": ["#fef0d9","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#990000"],
|
||||
"8": ["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#990000"],
|
||||
"9": ["#fff7ec","#fee8c8","#fdd49e","#fdbb84","#fc8d59","#ef6548","#d7301f","#b30000","#7f0000"]
|
||||
},"YlOrRd": {
|
||||
"3": ["#ffeda0","#feb24c","#f03b20"],
|
||||
"4": ["#ffffb2","#fecc5c","#fd8d3c","#e31a1c"],
|
||||
"5": ["#ffffb2","#fecc5c","#fd8d3c","#f03b20","#bd0026"],
|
||||
"6": ["#ffffb2","#fed976","#feb24c","#fd8d3c","#f03b20","#bd0026"],
|
||||
"7": ["#ffffb2","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#b10026"],
|
||||
"8": ["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#b10026"],
|
||||
"9": ["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"]
|
||||
},"YlOrBr": {
|
||||
"3": ["#fff7bc","#fec44f","#d95f0e"],
|
||||
"4": ["#ffffd4","#fed98e","#fe9929","#cc4c02"],
|
||||
"5": ["#ffffd4","#fed98e","#fe9929","#d95f0e","#993404"],
|
||||
"6": ["#ffffd4","#fee391","#fec44f","#fe9929","#d95f0e","#993404"],
|
||||
"7": ["#ffffd4","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#8c2d04"],
|
||||
"8": ["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#8c2d04"],
|
||||
"9": ["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#993404","#662506"]
|
||||
},"Purples": {
|
||||
"3": ["#efedf5","#bcbddc","#756bb1"],
|
||||
"4": ["#f2f0f7","#cbc9e2","#9e9ac8","#6a51a3"],
|
||||
"5": ["#f2f0f7","#cbc9e2","#9e9ac8","#756bb1","#54278f"],
|
||||
"6": ["#f2f0f7","#dadaeb","#bcbddc","#9e9ac8","#756bb1","#54278f"],
|
||||
"7": ["#f2f0f7","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#4a1486"],
|
||||
"8": ["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#4a1486"],
|
||||
"9": ["#fcfbfd","#efedf5","#dadaeb","#bcbddc","#9e9ac8","#807dba","#6a51a3","#54278f","#3f007d"]
|
||||
},"Blues": {
|
||||
"3": ["#deebf7","#9ecae1","#3182bd"],
|
||||
"4": ["#eff3ff","#bdd7e7","#6baed6","#2171b5"],
|
||||
"5": ["#eff3ff","#bdd7e7","#6baed6","#3182bd","#08519c"],
|
||||
"6": ["#eff3ff","#c6dbef","#9ecae1","#6baed6","#3182bd","#08519c"],
|
||||
"7": ["#eff3ff","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#084594"],
|
||||
"8": ["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#084594"],
|
||||
"9": ["#f7fbff","#deebf7","#c6dbef","#9ecae1","#6baed6","#4292c6","#2171b5","#08519c","#08306b"]
|
||||
},"Greens": {
|
||||
"3": ["#e5f5e0","#a1d99b","#31a354"],
|
||||
"4": ["#edf8e9","#bae4b3","#74c476","#238b45"],
|
||||
"5": ["#edf8e9","#bae4b3","#74c476","#31a354","#006d2c"],
|
||||
"6": ["#edf8e9","#c7e9c0","#a1d99b","#74c476","#31a354","#006d2c"],
|
||||
"7": ["#edf8e9","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#005a32"],
|
||||
"8": ["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#005a32"],
|
||||
"9": ["#f7fcf5","#e5f5e0","#c7e9c0","#a1d99b","#74c476","#41ab5d","#238b45","#006d2c","#00441b"]
|
||||
},"Oranges": {
|
||||
"3": ["#fee6ce","#fdae6b","#e6550d"],
|
||||
"4": ["#feedde","#fdbe85","#fd8d3c","#d94701"],
|
||||
"5": ["#feedde","#fdbe85","#fd8d3c","#e6550d","#a63603"],
|
||||
"6": ["#feedde","#fdd0a2","#fdae6b","#fd8d3c","#e6550d","#a63603"],
|
||||
"7": ["#feedde","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#8c2d04"],
|
||||
"8": ["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#8c2d04"],
|
||||
"9": ["#fff5eb","#fee6ce","#fdd0a2","#fdae6b","#fd8d3c","#f16913","#d94801","#a63603","#7f2704"]
|
||||
},"Reds": {
|
||||
"3": ["#fee0d2","#fc9272","#de2d26"],
|
||||
"4": ["#fee5d9","#fcae91","#fb6a4a","#cb181d"],
|
||||
"5": ["#fee5d9","#fcae91","#fb6a4a","#de2d26","#a50f15"],
|
||||
"6": ["#fee5d9","#fcbba1","#fc9272","#fb6a4a","#de2d26","#a50f15"],
|
||||
"7": ["#fee5d9","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#99000d"],
|
||||
"8": ["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#99000d"],
|
||||
"9": ["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15","#67000d"]
|
||||
},"Greys": {
|
||||
"3": ["#f0f0f0","#bdbdbd","#636363"],
|
||||
"4": ["#f7f7f7","#cccccc","#969696","#525252"],
|
||||
"5": ["#f7f7f7","#cccccc","#969696","#636363","#252525"],
|
||||
"6": ["#f7f7f7","#d9d9d9","#bdbdbd","#969696","#636363","#252525"],
|
||||
"7": ["#f7f7f7","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525"],
|
||||
"8": ["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525"],
|
||||
"9": ["#ffffff","#f0f0f0","#d9d9d9","#bdbdbd","#969696","#737373","#525252","#252525","#000000"]
|
||||
},"PuOr": {
|
||||
"3": ["#f1a340","#f7f7f7","#998ec3"],
|
||||
"4": ["#e66101","#fdb863","#b2abd2","#5e3c99"],
|
||||
"5": ["#e66101","#fdb863","#f7f7f7","#b2abd2","#5e3c99"],
|
||||
"6": ["#b35806","#f1a340","#fee0b6","#d8daeb","#998ec3","#542788"],
|
||||
"7": ["#b35806","#f1a340","#fee0b6","#f7f7f7","#d8daeb","#998ec3","#542788"],
|
||||
"8": ["#b35806","#e08214","#fdb863","#fee0b6","#d8daeb","#b2abd2","#8073ac","#542788"],
|
||||
"9": ["#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788"],
|
||||
"10": ["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"],
|
||||
"11": ["#7f3b08","#b35806","#e08214","#fdb863","#fee0b6","#f7f7f7","#d8daeb","#b2abd2","#8073ac","#542788","#2d004b"]
|
||||
},"BrBG": {
|
||||
"3": ["#d8b365","#f5f5f5","#5ab4ac"],
|
||||
"4": ["#a6611a","#dfc27d","#80cdc1","#018571"],
|
||||
"5": ["#a6611a","#dfc27d","#f5f5f5","#80cdc1","#018571"],
|
||||
"6": ["#8c510a","#d8b365","#f6e8c3","#c7eae5","#5ab4ac","#01665e"],
|
||||
"7": ["#8c510a","#d8b365","#f6e8c3","#f5f5f5","#c7eae5","#5ab4ac","#01665e"],
|
||||
"8": ["#8c510a","#bf812d","#dfc27d","#f6e8c3","#c7eae5","#80cdc1","#35978f","#01665e"],
|
||||
"9": ["#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e"],
|
||||
"10": ["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"],
|
||||
"11": ["#543005","#8c510a","#bf812d","#dfc27d","#f6e8c3","#f5f5f5","#c7eae5","#80cdc1","#35978f","#01665e","#003c30"]
|
||||
},"PRGn": {
|
||||
"3": ["#af8dc3","#f7f7f7","#7fbf7b"],
|
||||
"4": ["#7b3294","#c2a5cf","#a6dba0","#008837"],
|
||||
"5": ["#7b3294","#c2a5cf","#f7f7f7","#a6dba0","#008837"],
|
||||
"6": ["#762a83","#af8dc3","#e7d4e8","#d9f0d3","#7fbf7b","#1b7837"],
|
||||
"7": ["#762a83","#af8dc3","#e7d4e8","#f7f7f7","#d9f0d3","#7fbf7b","#1b7837"],
|
||||
"8": ["#762a83","#9970ab","#c2a5cf","#e7d4e8","#d9f0d3","#a6dba0","#5aae61","#1b7837"],
|
||||
"9": ["#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837"],
|
||||
"10": ["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"],
|
||||
"11": ["#40004b","#762a83","#9970ab","#c2a5cf","#e7d4e8","#f7f7f7","#d9f0d3","#a6dba0","#5aae61","#1b7837","#00441b"]
|
||||
},"PiYG": {
|
||||
"3": ["#e9a3c9","#f7f7f7","#a1d76a"],
|
||||
"4": ["#d01c8b","#f1b6da","#b8e186","#4dac26"],
|
||||
"5": ["#d01c8b","#f1b6da","#f7f7f7","#b8e186","#4dac26"],
|
||||
"6": ["#c51b7d","#e9a3c9","#fde0ef","#e6f5d0","#a1d76a","#4d9221"],
|
||||
"7": ["#c51b7d","#e9a3c9","#fde0ef","#f7f7f7","#e6f5d0","#a1d76a","#4d9221"],
|
||||
"8": ["#c51b7d","#de77ae","#f1b6da","#fde0ef","#e6f5d0","#b8e186","#7fbc41","#4d9221"],
|
||||
"9": ["#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221"],
|
||||
"10": ["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"],
|
||||
"11": ["#8e0152","#c51b7d","#de77ae","#f1b6da","#fde0ef","#f7f7f7","#e6f5d0","#b8e186","#7fbc41","#4d9221","#276419"]
|
||||
},"RdBu": {
|
||||
"3": ["#ef8a62","#f7f7f7","#67a9cf"],
|
||||
"4": ["#ca0020","#f4a582","#92c5de","#0571b0"],
|
||||
"5": ["#ca0020","#f4a582","#f7f7f7","#92c5de","#0571b0"],
|
||||
"6": ["#b2182b","#ef8a62","#fddbc7","#d1e5f0","#67a9cf","#2166ac"],
|
||||
"7": ["#b2182b","#ef8a62","#fddbc7","#f7f7f7","#d1e5f0","#67a9cf","#2166ac"],
|
||||
"8": ["#b2182b","#d6604d","#f4a582","#fddbc7","#d1e5f0","#92c5de","#4393c3","#2166ac"],
|
||||
"9": ["#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac"],
|
||||
"10": ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"],
|
||||
"11": ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#f7f7f7","#d1e5f0","#92c5de","#4393c3","#2166ac","#053061"]
|
||||
},"RdGy": {
|
||||
"3": ["#ef8a62","#ffffff","#999999"],
|
||||
"4": ["#ca0020","#f4a582","#bababa","#404040"],
|
||||
"5": ["#ca0020","#f4a582","#ffffff","#bababa","#404040"],
|
||||
"6": ["#b2182b","#ef8a62","#fddbc7","#e0e0e0","#999999","#4d4d4d"],
|
||||
"7": ["#b2182b","#ef8a62","#fddbc7","#ffffff","#e0e0e0","#999999","#4d4d4d"],
|
||||
"8": ["#b2182b","#d6604d","#f4a582","#fddbc7","#e0e0e0","#bababa","#878787","#4d4d4d"],
|
||||
"9": ["#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d"],
|
||||
"10": ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"],
|
||||
"11": ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"]
|
||||
},"RdYlBu": {
|
||||
"3": ["#fc8d59","#ffffbf","#91bfdb"],
|
||||
"4": ["#d7191c","#fdae61","#abd9e9","#2c7bb6"],
|
||||
"5": ["#d7191c","#fdae61","#ffffbf","#abd9e9","#2c7bb6"],
|
||||
"6": ["#d73027","#fc8d59","#fee090","#e0f3f8","#91bfdb","#4575b4"],
|
||||
"7": ["#d73027","#fc8d59","#fee090","#ffffbf","#e0f3f8","#91bfdb","#4575b4"],
|
||||
"8": ["#d73027","#f46d43","#fdae61","#fee090","#e0f3f8","#abd9e9","#74add1","#4575b4"],
|
||||
"9": ["#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4"],
|
||||
"10": ["#a50026","#d73027","#f46d43","#fdae61","#fee090","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"],
|
||||
"11": ["#a50026","#d73027","#f46d43","#fdae61","#fee090","#ffffbf","#e0f3f8","#abd9e9","#74add1","#4575b4","#313695"]
|
||||
},"Spectral": {
|
||||
"3": ["#fc8d59","#ffffbf","#99d594"],
|
||||
"4": ["#d7191c","#fdae61","#abdda4","#2b83ba"],
|
||||
"5": ["#d7191c","#fdae61","#ffffbf","#abdda4","#2b83ba"],
|
||||
"6": ["#d53e4f","#fc8d59","#fee08b","#e6f598","#99d594","#3288bd"],
|
||||
"7": ["#d53e4f","#fc8d59","#fee08b","#ffffbf","#e6f598","#99d594","#3288bd"],
|
||||
"8": ["#d53e4f","#f46d43","#fdae61","#fee08b","#e6f598","#abdda4","#66c2a5","#3288bd"],
|
||||
"9": ["#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd"],
|
||||
"10": ["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"],
|
||||
"11": ["#9e0142","#d53e4f","#f46d43","#fdae61","#fee08b","#ffffbf","#e6f598","#abdda4","#66c2a5","#3288bd","#5e4fa2"]
|
||||
},"RdYlGn": {
|
||||
"3": ["#fc8d59","#ffffbf","#91cf60"],
|
||||
"4": ["#d7191c","#fdae61","#a6d96a","#1a9641"],
|
||||
"5": ["#d7191c","#fdae61","#ffffbf","#a6d96a","#1a9641"],
|
||||
"6": ["#d73027","#fc8d59","#fee08b","#d9ef8b","#91cf60","#1a9850"],
|
||||
"7": ["#d73027","#fc8d59","#fee08b","#ffffbf","#d9ef8b","#91cf60","#1a9850"],
|
||||
"8": ["#d73027","#f46d43","#fdae61","#fee08b","#d9ef8b","#a6d96a","#66bd63","#1a9850"],
|
||||
"9": ["#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850"],
|
||||
"10": ["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"],
|
||||
"11": ["#a50026","#d73027","#f46d43","#fdae61","#fee08b","#ffffbf","#d9ef8b","#a6d96a","#66bd63","#1a9850","#006837"]
|
||||
},"Accent": {
|
||||
"3": ["#7fc97f","#beaed4","#fdc086"],
|
||||
"4": ["#7fc97f","#beaed4","#fdc086","#ffff99"],
|
||||
"5": ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0"],
|
||||
"6": ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f"],
|
||||
"7": ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17"],
|
||||
"8": ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0","#f0027f","#bf5b17","#666666"]
|
||||
},"Dark2": {
|
||||
"3": ["#1b9e77","#d95f02","#7570b3"],
|
||||
"4": ["#1b9e77","#d95f02","#7570b3","#e7298a"],
|
||||
"5": ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e"],
|
||||
"6": ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02"],
|
||||
"7": ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d"],
|
||||
"8": ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"]
|
||||
},"Paired": {
|
||||
"3": ["#a6cee3","#1f78b4","#b2df8a"],
|
||||
"4": ["#a6cee3","#1f78b4","#b2df8a","#33a02c"],
|
||||
"5": ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99"],
|
||||
"6": ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c"],
|
||||
"7": ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f"],
|
||||
"8": ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00"],
|
||||
"9": ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6"],
|
||||
"10": ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a"],
|
||||
"11": ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99"],
|
||||
"12": ["#a6cee3","#1f78b4","#b2df8a","#33a02c","#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6","#6a3d9a","#ffff99","#b15928"]
|
||||
},"Pastel1": {
|
||||
"3": ["#fbb4ae","#b3cde3","#ccebc5"],
|
||||
"4": ["#fbb4ae","#b3cde3","#ccebc5","#decbe4"],
|
||||
"5": ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6"],
|
||||
"6": ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc"],
|
||||
"7": ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd"],
|
||||
"8": ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec"],
|
||||
"9": ["#fbb4ae","#b3cde3","#ccebc5","#decbe4","#fed9a6","#ffffcc","#e5d8bd","#fddaec","#f2f2f2"]
|
||||
},"Pastel2": {
|
||||
"3": ["#b3e2cd","#fdcdac","#cbd5e8"],
|
||||
"4": ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4"],
|
||||
"5": ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9"],
|
||||
"6": ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae"],
|
||||
"7": ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc"],
|
||||
"8": ["#b3e2cd","#fdcdac","#cbd5e8","#f4cae4","#e6f5c9","#fff2ae","#f1e2cc","#cccccc"]
|
||||
},"Set1": {
|
||||
"3": ["#e41a1c","#377eb8","#4daf4a"],
|
||||
"4": ["#e41a1c","#377eb8","#4daf4a","#984ea3"],
|
||||
"5": ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00"],
|
||||
"6": ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33"],
|
||||
"7": ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628"],
|
||||
"8": ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf"],
|
||||
"9": ["#e41a1c","#377eb8","#4daf4a","#984ea3","#ff7f00","#ffff33","#a65628","#f781bf","#999999"]
|
||||
},"Set2": {
|
||||
"3": ["#66c2a5","#fc8d62","#8da0cb"],
|
||||
"4": ["#66c2a5","#fc8d62","#8da0cb","#e78ac3"],
|
||||
"5": ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854"],
|
||||
"6": ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f"],
|
||||
"7": ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494"],
|
||||
"8": ["#66c2a5","#fc8d62","#8da0cb","#e78ac3","#a6d854","#ffd92f","#e5c494","#b3b3b3"]
|
||||
},"Set3": {
|
||||
"3": ["#8dd3c7","#ffffb3","#bebada"],
|
||||
"4": ["#8dd3c7","#ffffb3","#bebada","#fb8072"],
|
||||
"5": ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3"],
|
||||
"6": ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462"],
|
||||
"7": ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69"],
|
||||
"8": ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5"],
|
||||
"9": ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9"],
|
||||
"10": ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd"],
|
||||
"11": ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5"],
|
||||
"12": ["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"]
|
||||
}}
|
||||
86
generators/apollon/coloring.py
Executable file
86
generators/apollon/coloring.py
Executable file
@@ -0,0 +1,86 @@
|
||||
# Select a color from colorbrewer schemes
|
||||
|
||||
# Copyright (c) 2014 Ludger Sandig
|
||||
# This file is part of apollon.
|
||||
|
||||
# Apollon 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.
|
||||
|
||||
# Apollon 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 Apollon. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import json
|
||||
|
||||
class ColorMap(object):
|
||||
"""
|
||||
Map numbers to colors.
|
||||
"""
|
||||
def __init__(self, default):
|
||||
"""
|
||||
@param default: Is returned when a number can't be mapped.
|
||||
"""
|
||||
self.pairs = []
|
||||
self.default = default
|
||||
|
||||
def add_interval(self, left, right, color):
|
||||
"""
|
||||
A number in interval [left,right] gets mapped to color.
|
||||
"""
|
||||
self.pairs.append((left, right, color))
|
||||
|
||||
def color_for(self, number):
|
||||
"""
|
||||
Map number to color. If not found, return default value.
|
||||
"""
|
||||
ret = self.default
|
||||
for p in self.pairs:
|
||||
if (number >= p[0]) and (number <= p[1]):
|
||||
ret = p[2]
|
||||
break
|
||||
return ret
|
||||
|
||||
class ColorScheme(object):
|
||||
"""
|
||||
Color Scheme helper class.
|
||||
"""
|
||||
def __init__(self, filename):
|
||||
"""
|
||||
Load color scheme definitions from json file.
|
||||
"""
|
||||
json_data = open(filename)
|
||||
|
||||
self.schemes=json.load(json_data)
|
||||
json_data.close()
|
||||
|
||||
def info(self):
|
||||
"""
|
||||
Get information on available color schemes
|
||||
"""
|
||||
infos = []
|
||||
for name in self.schemes:
|
||||
smallest = min(self.schemes[name], key=lambda k: len(self.schemes[name][k]))
|
||||
biggest = max(self.schemes[name], key=lambda k: len(self.schemes[name][k]))
|
||||
infos.append({"name" : name, "low" : int(smallest), "high" : int(biggest)})
|
||||
return infos
|
||||
|
||||
def makeMap(self, frm, to, name, res):
|
||||
"""
|
||||
Construct a L{ColorMap} that maps numbers between frm and to to color scheme name with resolution res.
|
||||
"""
|
||||
# TODO: Proper error handling when name or res are not available
|
||||
delta = to-frm
|
||||
step = delta/res
|
||||
colors = self.schemes[name][str(res)]
|
||||
mp = ColorMap("none")
|
||||
# Items are (lower_bound, color)
|
||||
for n in range(res):
|
||||
mp.add_interval(frm + n*step, frm + (n+1)*step, colors[n])
|
||||
return mp
|
||||
271
generators/apollon/index.cgi
Executable file
271
generators/apollon/index.cgi
Executable file
@@ -0,0 +1,271 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (c) 2014 Ludger Sandig
|
||||
# This file is part of apollon.
|
||||
|
||||
# Apollon 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.
|
||||
|
||||
# Apollon 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 Apollon. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import cgi
|
||||
import cgitb
|
||||
|
||||
from apollon import ApollonianGasket
|
||||
from coloring import ColorScheme, ColorMap
|
||||
from ag import ag_to_svg, impossible_combination
|
||||
|
||||
|
||||
|
||||
# Container for sanitized settings
|
||||
class Settings(object):
|
||||
def __init__(self, form):
|
||||
self.color = form.getvalue("color", "Blues")
|
||||
self.resolution = int(form.getvalue("res", 8))
|
||||
self.c1 = float(form.getvalue("c1", 1))
|
||||
self.c2 = float(form.getvalue("c2", 2))
|
||||
self.c3 = float(form.getvalue("c3", 2))
|
||||
self.rad_or_curv = form.getvalue("roc", "curvature")
|
||||
self.depth = int(form.getvalue("depth", 3))
|
||||
|
||||
# Sanity check
|
||||
|
||||
if (self.resolution > 8) or (self.resolution < 3):
|
||||
self.resolution = 8
|
||||
|
||||
if self.c1 <= 0: self.c1 = 1
|
||||
if self.c2 <= 0: self.c2 = 1
|
||||
if self.c3 <= 0: self.c3 = 1
|
||||
|
||||
if not (self.rad_or_curv == "curvature" or self.rad_or_curv == "radius"):
|
||||
self.rad_or_curvature = "curvature"
|
||||
|
||||
if (self.depth < 0) or (self.depth > 5):
|
||||
self.depth = 3
|
||||
|
||||
# For a more usable form
|
||||
if self.rad_or_curv == "curvature":
|
||||
self.rad_checked = ""
|
||||
self.curv_checked = "checked"
|
||||
else:
|
||||
self.rad_checked = "checked"
|
||||
self.curv_checked = ""
|
||||
|
||||
# Curvature or Radius?
|
||||
if self.rad_or_curv == "radius":
|
||||
self.c1 = 1/self.c1
|
||||
self.c2 = 1/self.c2
|
||||
self.c3 = 1/self.c3
|
||||
|
||||
# AG possible in the first place?
|
||||
self.impossible = impossible_combination(self.c1, self.c2, self.c3)
|
||||
|
||||
# What to print: With form or only svg
|
||||
action = form.getvalue("submit","Update")
|
||||
self.onlysvg = False
|
||||
if action == "Save":
|
||||
self.onlysvg = True
|
||||
|
||||
|
||||
def print_with_form(svg, settings, schemes):
|
||||
# Print first chunk of html
|
||||
print("Content-type: text/html")
|
||||
|
||||
print("""
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Apollonian Gasket Generator</title>
|
||||
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
width: 800px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
padding: 10px;
|
||||
border: 2px solid #ccc;
|
||||
border-radius: 25px;
|
||||
text-align: center;
|
||||
width: 780px;
|
||||
}
|
||||
|
||||
#gasket {
|
||||
width: 500px;
|
||||
float: left;
|
||||
padding: 10px;
|
||||
border: 2px solid #ccc;
|
||||
border-radius: 25px;
|
||||
}
|
||||
|
||||
#settings {
|
||||
width: 250px;
|
||||
float: right;
|
||||
border: 2px solid #ccc;
|
||||
border-radius: 25px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#about {
|
||||
width: 780px;
|
||||
border: 2px solid #ccc;
|
||||
border-radius: 25px;
|
||||
padding: 10px;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
div.wrapper {
|
||||
padding-top: 2px;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
input[type=number] {
|
||||
width: 75px;
|
||||
|
||||
}
|
||||
|
||||
input, label, select {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
form {
|
||||
display: table;
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
#settings p { display: table-row; }
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>Apollonian Gasket Generator</h1>
|
||||
""")
|
||||
|
||||
print('<div id="gasket">\n%s\n</div>' % svg)
|
||||
|
||||
# Print form
|
||||
print("""
|
||||
<div id="settings">
|
||||
<form method="post" action="index.cgi" id="params">
|
||||
|
||||
<p><label for="c1">First circle</label><input type="number" name="c1" id="c1" step="any" min="0" value="%.2f"/></p>
|
||||
<p><label for="c2">Second circle</label> <input type="number" name="c2" id="c2" step="any" min="0" value="%.2f"/></p>
|
||||
<p><label for="c3">Third circle</label><input type="number" name="c3" id="c3" step="any" min="0" value="%.2f"/></p>
|
||||
<p><label for="curv">Curvature</label><input type="radio" name="roc" id="curv" value="curvature" %s/></p>
|
||||
<p><label for="rad">Radius</label><input type="radio" name="roc" id="rad" value="radius" %s/></p>
|
||||
<p><label for="depth">Recursion depth</label> <input type="number" name="depth" value="%d" min="0" max="5"/></p>
|
||||
<p><label for="num">No. of colors</label><input type="number" name="res" value="%d" min="3" max="8"/> </p>
|
||||
<p><label>Color scheme</label><select name="color">
|
||||
""" % (settings.c1, settings.c2, settings.c3, settings.curv_checked, settings.rad_checked, settings.depth, settings.resolution))
|
||||
|
||||
# Sort color scheme names
|
||||
info = schemes.info()
|
||||
info.sort(key=lambda d: d["name"])
|
||||
info.insert(0, {"name" : "none"})
|
||||
for s in info:
|
||||
if s["name"] == settings.color:
|
||||
selected = "selected"
|
||||
else:
|
||||
selected = ""
|
||||
print('<option value="%s" %s>%s</value>' % (s["name"], selected, s["name"]))
|
||||
|
||||
# Print last chunk of form and help text
|
||||
print("""
|
||||
</select></p>
|
||||
<p><input type="submit" name="submit" value="Update"> <input type="submit" name="submit" value="Save"></p>
|
||||
</form>
|
||||
</div>
|
||||
<div class="wrapper">
|
||||
<div id="about">
|
||||
<h2>About</h2>
|
||||
|
||||
<p> Apollonian Gaskets are groups of circles in which three are
|
||||
mutally tangent to each other. You can think of it as tightly filling
|
||||
a big circle with lots of smaller cicles. These sets of circles can be
|
||||
computed recusively with relative ease. If you are interested in the
|
||||
mathematical part, see <a
|
||||
href="https://en.wikipedia.org/wiki/Apollonian_gasket">Wikipedia on
|
||||
this subject</a>. </p>
|
||||
|
||||
<p>This site showcases a small command line program I wrote to
|
||||
generate svg images of those circles. It can be found on <a
|
||||
href="https://github.com/lsandig/apollon">github</a>.</p>
|
||||
|
||||
<p>For a more in-depth explanation of this implementation see <a
|
||||
href="http://lsandig.org/blog/2014/08/apollon-python/en/">this
|
||||
post</a> on my blog (English and German version)</p>
|
||||
|
||||
<p>Please note that the online version has a recursion limit of depth
|
||||
5 to reduce the time and memory consumption on the server. With the
|
||||
command line version only your RAM is the limit.</p>
|
||||
|
||||
<p>This is free software published under the GPLv3.</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
""")
|
||||
|
||||
|
||||
def print_only_image(svg):
|
||||
print('Content-type: image/svg+xml\nContent-Disposition: attachment; filename="apollonian_gasket.svg"\n\n')
|
||||
print(svg)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Debugging
|
||||
#cgitb.enable()
|
||||
|
||||
# Get settings from form
|
||||
form = cgi.FieldStorage()
|
||||
param = Settings(form)
|
||||
|
||||
# Construct color map
|
||||
schemes = ColorScheme("colorbrewer.json")
|
||||
|
||||
if not param.impossible:
|
||||
# Magic
|
||||
ag = ApollonianGasket(param.c1, param.c2, param.c3)
|
||||
|
||||
ag.generate(param.depth)
|
||||
|
||||
# Get smallest and biggest radius
|
||||
smallest = abs(min(ag.genCircles, key=lambda c: abs(c.r.real)).r.real)
|
||||
biggest = abs(max(ag.genCircles, key=lambda c: abs(c.r.real)).r.real)
|
||||
|
||||
|
||||
if param.color == 'none':
|
||||
mp = ColorMap('none')
|
||||
else:
|
||||
mp = schemes.makeMap(smallest, biggest, param.color, param.resolution)
|
||||
|
||||
# Convert to svg
|
||||
svg = ag_to_svg(ag.genCircles, mp, tresh=0.005)
|
||||
|
||||
# Output
|
||||
if param.onlysvg:
|
||||
print_only_image(svg)
|
||||
else:
|
||||
print_with_form(svg, param, schemes)
|
||||
else:
|
||||
errortext = "<h2>No Apollonian gasket possible for these curvatures :(</2>"
|
||||
print_with_form(errortext, param, schemes)
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user