diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /graphics/epix |
Initial commit
Diffstat (limited to 'graphics/epix')
344 files changed, 71175 insertions, 0 deletions
diff --git a/graphics/epix/AUTHORS b/graphics/epix/AUTHORS new file mode 100644 index 0000000000..24ded708ef --- /dev/null +++ b/graphics/epix/AUTHORS @@ -0,0 +1,5 @@ +Jay P. Belanger +Marcus D. Hanwell +Andrew D. Hwang + +Please see THANKS for the list of contributors.
\ No newline at end of file diff --git a/graphics/epix/BUGS b/graphics/epix/BUGS new file mode 100644 index 0000000000..3436bad2ed --- /dev/null +++ b/graphics/epix/BUGS @@ -0,0 +1,24 @@ +ePiX-1.2 -- BUGS + +Last Change: September 19, 2007 + +This file lists known idiosyncrasies ("features, not bugs") whose +behavior may be unexpected. Some are too minor and/or messy to fix, +some are outside the author's control. + +* The build-time script elaps-local calls epix, not epix-local. + +* Polygons are not shaded with simulated ambient light. The "fill" + attribute controls whether or not to color fill. + +* Surface mesh elements are always color-filled. The fill attribute + controls whether to use cos^2 (on) or flat (off) shading. + +* Dot-like markers may be slightly larger in tikz than in pst/eepic. + +* Line underlayer widths may be larger in pst than in eepic/tikz. + +* Line caps are round in eepic, square (butt) in pst/tikz. + +* Affine maps have no effect on label alignment, only on the offset. + (N.B. Non-invertible affine maps may cause NaN label positions.)
\ No newline at end of file diff --git a/graphics/epix/COPYING b/graphics/epix/COPYING new file mode 100644 index 0000000000..14db8fc79d --- /dev/null +++ b/graphics/epix/COPYING @@ -0,0 +1,340 @@ + 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. + + <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 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. + + <signature of Ty Coon>, 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. diff --git a/graphics/epix/ChangeLog b/graphics/epix/ChangeLog new file mode 100644 index 0000000000..832d25f939 --- /dev/null +++ b/graphics/epix/ChangeLog @@ -0,0 +1,743 @@ +ePiX 1.1.x + +Andrew D. Hwang <ahwang -at- mathcs -dot- holycross -dot- edu> + +2007-10.03 (ADH) + Version 1.2.1 + * configure.ac, Makefile.am: New option --enable-epix-el + (formerly --with-nolisp) + * doc/Makefile.am: Build ps, pdf under manual-stamp so package can + be built with parallel make (error noted by Ren\'e Rebe) + +2007-09.28 (ADH) + * legend_tile.cc, legend_tile.h: Store offset as a pair + * legend.cc: (draw) Pass offset as a pair + * screen_data.cc: (paste) "affine" object named af, not affine + +2007-09.26 (ADH) + Version 1.2.0-2 + * debug.h, interval.cc: #include <cstdlib> (Maik Beckmann) + * (Multiple files) Replace const double arguments by double + +2007-09.25 (ADH) + Version 1.2.0-1 + * doc/plotting3.xp: crop -> set_crop, and update image + +2007-09.24 (ADH) + Version 1.1.22 (promoted to 1.2.0) + * lens.cc: bubble lens projects to camera sphere + + * angle_units.cc, angle_units.h: (convert_to_radians) Remove + - (to_radians, to_degrees, from_degrees) New functions + - Store rad/unit, unit/deg, and rev/unit for efficiency + + * state.cc, state.h: (angle) Remove function + - (full_turn) Reimplement as from_degrees(360) + * functions.cc: Use angle_state::to_radians in trig functions + + * glyph.cc: (map_by) Reimplement label angle computation + * label_style.cc, label_style.h: New public void constructor + - Non-void constructor is private + - (label_angle) Pass non-const double + - (label_angle) Use the_angle_style to convert to degrees + - (label_angle()) Returns degrees, not current angle units + +2007-09.23 (ADH) + Version 1.1.21 + * affine.cc, affine.h: Member functions accept P as well as pair + +2007-09.22 (ADH) + * length.cc: Remove support for scaled pt + * state.cc, state.h: crop() -> set_crop() + - (crop) New function, calls screen::crop + - (crop_rectangle, crop_ellipse, crop_diamond): Set crop state + + * lens.cc: fisheye, bubble are *not* linear + * lens.cc, lens.h: (needs_clip) New function + * camera.cc, camera.h: (needs_clip) New function + - the_camera() -> cam() + * path_data.cc: (photo) Clip to camera.front_plane only if nec. + * arrow_data.cc: (photo) Clip to camera.front_plane only if nec. + + * facet.cc, geometry.cc: camera, the_camera() -> cam() + * arrow_data.cc, axis.cc, curves.cc, label_data.cc, legend.cc, + legend_item.cc, path.cc, path_data.cc, screen_data.cc, + sphere.cc, state.cc: the_camera() -> cam() + +2007-09.19 (ADH) + Version 1.1.20 + * pen_line.cc: (add_to_pallet) Needn't check for unset + * pen_data.cc, pen_data.h: (is_empty) New member + * pen_fill.cc: (is_unset) Check line pen for invisibility + - (print_to) If bd non-solid, draw fill/border only if visible + - (add_to_pallet) Needn't check for unset colors + * eepic.cc: (print_line) No base layer if narrower than line + * pst.cc: (print_line) Adjust base layer width (m_bwidth too large) + +2007-09.18 (ADH) + Version 1.1.19 + * affine.cc: Group scaling operators in parentheses + * glyph.cc: (map_by) Map offset direction, not length + +2007-09.17 (ADH) + * format.cc: (print_mark) Use mask color for circ background, add + to pallet if necessary + - Fix label padding + - Draw label border if pen width is positive + * markers.cc: (circ) Handle like other markers + - (marker) Handle CIRC like other types + * label_style.cc: (seen_through) Needn't check for unset mask + * label_style.h: Default label_pad 0 + + * picture.cc: Remove mp_format stubs + + * data_bins.cc, data_bins.h: Handle data on cuts + - New data member m_cut_hits + - (d_bin::insert) Rename add_datum + - Copy constructor mis-copied d_bins + - Implement m_bins as a list, not a vector + +2007-09.16 (ADH) + Version 1.1.18 + * pair_map.cc, pair_map.h: Rename file, class to affine + * epix.h: Add affine.h + * screen.cc, screen.h: Pass-through affine operations + - (apply) New member function + * screen_data.cc, screen_data.h: Affine operations on contents + + * label_data.cc, label_data.h: Store offset as a pair + * axis.cc, markers.cc: (label) Adjust label_data ctor + * glyph.cc, glyph.h: Store offset as a pair + * glyph.cc: (map_to) Adjust offset, label angle + * legend_item.cc: (key) Adjust glyph ctor + +2007-09.15 (ADH) + * pair_map.cc, pair_map.h: Complete re-write + * screen_data.cc: (paste) Use new pair_map ctor + + * utils.cc, utils.h: (get_chars) New function + * path_style.cc: Rename get_breaks -> __epix_get_breakpts + - (extract) Move to utils, rename -> get_chars + - Use get_chars to extract dot/dash pattern + - (__epix_get_breakpts) Check for anomalous patterns + + * screen_data.cc, screen_data.h: (is_cropped) Remove + * screen.cc, screen.h: (is_cropped) Remove + +2007-09.14 (ADH) + * format.cc: (print_color) Check for empty vector of densities + * picture_data.cc: (add_to_pallet) Check for unset color + + * label_style.cc, label_style.h: Dependency cleanup + * format.cc, legend.cc, markers.cc, state.cc: Consequent changes + * arrow_data.cc, Color_Neutral.cc, glyph.cc, legend.cc, + path_data.h, path.cc, pen_arrow.cc, pen_data.cc, pen_fill.cc + picture.cc, picture_data.cc, plots.cc: Dependency cleanup + +2007-09.14 (ADH) + Version 1.1.17 + * functions.cc, functions.h: (clip_to_unit) Move to Color_Utils + * Color_Utils.cc: #include "Color_Utils.h" + * Color_Utils.cc, Color_Utils.h: Move clip_to_unit from functions + +2007-09.13 (ADH) + * length.cc, length.h: (operator+, operator*) Pass one arg by value + + * configure.ac, Makefile.am: --with-nolisp option (for Gentoo) + - Make scripts dependent on epix.el (to force build before install) + + * Color_Base.h: print_to(format) -> model, densities + - Color is not a friend class + * Color.cc, Color.h: (print_to) Remove function + - (model, densities) New functions + * Color_CMY.cc, Color_CMY.h, Color_CMYK.cc, Color_CMYK.h: Same + * Color_Gray.cc, Color_Gray.h, Color_RGB.cc, Color_RGB.h: Same + * Color_Neutral.cc, Color_Neutral.h, Color_Sep.cc, Color_Sep.h: Same + + * format.cc, format.h: (print_color(string, string, vector<double>) + New function, calls existing print_color functions + + * plane.cc, plane.h: (pt, perp) New member functions + - Intersection operators aren't friends + * intersections.cc: Use Plane member functions + +2007-09.12 (ADH) + * (Update README et. al.) + +2007-09.11 (ADH) + Version 1.1.16 + * picture.cc, picture.h: (end_picture) New function (formerly end) + - (end) Set output format on command-line flags, call end_picture + + * elaps.in, epix.in, flix.in: --pst, --tikz, --eepic options + +2007-09.10 (ADH) + * facet.cc: (draw) Handle unset pen, reorganize logic + + * Makefile.am: Install all headers under $(pkgincludedir) + - Remove libepix_a_HDRS from libepix_a_LIBADD deps + * make_header: Preserve include guards in epix.h + - Include string + - Don't include cstdio + * Color.h, Color_CMY.h, Color_CMYK.h, Color_Gray.h, + Color_Neutral.h, Color_RGB.h, Color_Sep.h, Color_Utils.h: + EPIX2 -> EPIX in include guard symbol + +2007-09.09 (ADH) + * eepic.cc: (print_circle_marker) Set allinethickness, draw once + + * markers.h: (right_angle, arc_measure) Default size 8pt (was 12) + +2007-09.08 (ADH) + Version 1.1.15 + * arrow_style.cc, arrow_style.h, pen_arrow.cc, state.cc, state.h: + camber -> inset + * constants.h: ACAMBER -> INSET + + * label_style.cc, label_style.h: (is_masked) New function + * markers.cc: (label) Get mask flag from current label style + + * glyph.cc: (print_to) Don't call print_latex_hbox on label text + + * screen_data.h: Remove void constructor + + * pair_map.cc, pair_map.h: const pair args -> const pair& + + * screen_data.cc, screen_data.h: Store mask-indep corners + - (paste) Use corners, not mask, to generate affine_map + - (add_tile(tile*)) clone argument + - (extract, extract_diamond, extract_ellipse) New functions + + * screen.cc: pair2P -> __epix_pair2P, accept const pair& + - (extract, extract_diamond, extract_ellipse) New functions + +2007-09.07 (ADH) + * format.h: (print_circle_marker) New function + * format.cc: (print_latex_marker) Needn't handle dot-like marks + - (print_mark) Use print_circle_marker for dot-like marks + - (print_edge) Use print_circle_marker for path dots + + * eepic.cc, eepic.h: (print_circle_marker) New function + * pst.cc, pst.h: (print_circle_marker) New function + * tikz.cc, tikz.h: (print_circle_marker) New function + + * tikz.cc: (put_box) truncate coordinates + +2007-09.05 (ADH) + * format.cc: (print_latex_hbox) "default" -> "rm" + - "normalsize" -> "nsz" + * label_style.h: (label_state) Same as above + * state.h: (font_size, font_face) Same as above + + * mask_rectangle.h, mask_ellipse.h, mask_diamond.h: Remove void + constructor + + * pen_fill.cc: (print_to, add_to_pallet) No action if is_empty + +2007-08.31 (ADH) + * epix-lib.sh: Remove unused global EPIX_VERBOSE + - New global LATEX_PKGS + - (ePiX_usepackages) New function (only used by elaps) + + * elaps.in: (elaps_make_latex) Get LaTeX packages from input file + +2007-08.30 (ADH) + Version 1.1.14 + * format.h: (usepackages) New function + * format.c (file_comments) Call usepackages + + * eepic.cc, eepic.h: (usepackages) + * pts.cc, pst.h: (usepackages) + * tikz.cc, tikz.h: (usepackages) + * fmt_template.cc, fmt_template.h: (usepackages) + +2007-08.30 (ADH) + Version 1.1.13 + * epix.el.in: New file + * epix.el: Obsolete file removed + +2007-08.29 (ADH) + * hatching.cc, hatching.h: Reimplement + +2007-08.25 (ADH) + * format.cc, format.h: (path_break) Default implementation + - (path_conector) New virtual function, default implementation + - (print_edge, print_paths) Use path_connector + - (xdefinecolor) Non-virtual functions for xcolor formats + + * tikz.cc, tikz.h: New files + + * eepic.cc: (print_color) Use xdefinecolor + * eepic.cc, eepic.h: (path_break) Use default implementation + * pst.cc, pst.h: (path_break) Use default implementation + + * picture.cc, picture.h: (mp_format, print_mp) Comment out + - pgf_format -> tikz_format + - print_pgf -> print_tikz + +2007-08.23 (ADH) + * clipping.cc, clipping.h: New face list m_extras + - (clip_face, clip_slice, clip_restore) New functions + * state.cc, state.h: (clip_face, clip_slice, clip_restore) New + functions + - (label_border) Accept double for length arg + + * legend.cc: (draw) Position is not camera-dependent + + * picture.cc, picture.h: (border) Accept double for length arg + * screen.cc, screen.h: (border) Accept double for length arg + +2007-08.21 (ADH) + Version 1.1.12 + * axis.cc: log labels in decimal by default, sci available + +2007-08.20 (ADH) + * axis.cc, axis.h: (unmark(double)) New member function + +2007-08.19 (ADH) + * label_data.cc: (label_data(P, mark, align): Axis tick markers + restrictively aligned, cannot be rotated + + * legend_tile.cc, legend_tile.h: Copy ctor/assign, destructor + + * lens.cc, lens.h: New files + - Add clone function + * camera.cc, camera.h: Factor out Lens code + - Add copy ctor/assign + + * picture.cc, picture.h: (pic_units_per_pt, units_per_pic_unit, + pt_to_screen) New functions for true-size drawing + - Remove svg functions + + * markers.cc, markers.h: (right_angle, arc_measure, axis_break, + h_error_bar, v_error_bar) New functions + + +2007-08.18 (ADH) + Version 1.1.11 + * screen_data.cc, screen_data.h: (print_to) Accept bool flag to + encapsulate in a picture-like environment + + * format.h: (reset_state) New pure virtual function + * eepic.cc, eepic.h, pst.cc, pst.h: (reset_state) New function + +2007-08.17 (ADH) + * format.cc, format.h: (start_picture, end_picture, print_pallet, + print_latex_hbox, set_unitlength) New functions + - (pic_header, pic_footer) Implemented in lower-level functions + * glyph.cc: (print_to) Font attributes handled in format. + + * legend_item.cc, legend_item.h: New files + * legend_tile.cc, legend_tile.h: New files + +2007-08.16 (ADH) + * format.cc, format.h: (print_latex_label) Masking flag + - (print_latex_label) Always print text color + + * legend.cc, legend.h: New files + + * length.cc, length.h: (name) New member function + +2007-08.15 (ADH) + * fmt_template.cc, fmt_template.h: New files + + * active_screen.cc, active_screen.h: screen_broker class replaces + global screen pointer active_screen + + * picture.cc, picture.h: (inlay, inlay_vertical, inlay_horizontal) + New functions + - (deactivate) New function + - (activate) Re-implement using screen_broker + + * arrow_data.cc, axis.cc, curves.cc, label_data.cc, path.cc, + path_data.cc, state.cc: Use active_screen() + +2007-08.12 (ADH) + * curves.cc: grid calls rect for outmost lines (enables filling) + + * format.h: Re-design interface + * eepic.cc, eepic.h, pst.cc, pst.h: Re-implement + + * glyph.cc, pen_fill.cc, pen_line.cc: Re-implement print_to + * pen_arrow.cc: Generate own arrow head data + * picture_data.cc: Reimplement print_to + * pen_fill.h: Remove hatch angle members + +2007-08.09 (ADH) + Version 1.1.10 + * mask_diamond.cc, mask_ellipse.cc, mask_rectangle.cc: (backing) + Use plain backing color for edge + + * domain.cc: (resize1, resize2, resize3) Hack to avoid round-down + +2007-08.08 (ADH) + * curves.cc, curves.h: (line) Make num_pts argument unsigned + * curves.cc: (line, triangle, quad, arrow) Sensitive to whether + camera preserves lines + + * constants.h: New constants MAX_LOG_BASE, DEF_PRECISION, MAX_PRECISION + +2007-08.07 (ADH) + * frac.cc, frac.h: New files (rational number class) + + * pen_arrow.cc: (print_to) Use copy of label_state to print a dot + + * label_data.cc, label_data.h: (mask_color, text_color, align_to) + New pass-through functions + * markers.cc, markers.h: Label commands use label_data + pass-through + - Move axis and axis label functions to new file axis.cc + * axis.cc, axis.h: New files (Coordinate axes, global functions) + - New log label commands with same signature as Cartesian versions + - New axes along sides of bounding box + + * eepic.cc, pst.cc: (pic_header, pic_footer, print_color) Print + "%" at end of line + +2007-08.06 (ADH) + * state_data.h: Remove file + * state.cc: Include style headers explicitly + + * pst.cc: (pic_footer, pic_header) Don't use pspicture* when cropping + +2007-08.04 (ADH) + * epix-lib.sh (ePiX_usage, ePiX_version): Update copyright, + licence notices + - Get script name from caller + - (ePiX_bugreport) New function + * elaps.in, epix.in, flix.in, laps.in: Specify script name for + usage, version + - Call ePiX_bugreport at end of help + + * triples.cc, triples.h: (Several binary operators) Pass first + argument as value when implementation must copy anyway + +2007-08.03 (ADH) + Version 1.1.9 + * flix.in: (flix_png) Pass tmax to bc, don't let shell evaluate + + * path_data.c: (photo) Print filled only if >= 3 non-null edges + +2007-08.02 (ADH) + * spline.cc: (data) Indexing errors; increase max indices by 1 + + * data_bins.cc: (plot) Use 20 intervals per spline + - (bar_chart, histogram, plot): Check for sero population + - (bar_chart) Bar height = frac of population in bin + - (histogram) Box height = frac of pop per horizontal unit + - (pop) Implement function + + * path_style.cc: (path_state(string)) Fix test for solidity + + * README-changes, README-porting: Removed + +2007-08.01 (ADH) + * functions.h: Remove "D", "I" aliases for Deriv, Integral + * functions.cc: (recip) Return 1.0/x (sec, csc, tan have poles) + * functions.cc, functions.h: Remove nine lowercase trig functions + * plots.cc: D -> Deriv, I -> Integral + + * triples.h: Remove "triple" alias for P + * triples.cc, triples.h: New member function is_valid() + - (midpoint) Remove function + * circle.cc: Replace P::midpoint + + * elaps.in: Keep eepic file, back up existing file if any + - Unset EPIX_OUTFILE, EPIX_OUTROOT on loop exit + - Print informative (but fake) lines on latex/dvips failure + + * curves.cc, curves.h: (spline(vector<P>, int)) New function + * data_bins.cc: (plot) Draw piecewise-cubic spline, not n_spline + +2007-07.31 (ADH) + * crop_algorithms.h: (loopify) + - Increment twice after insertion + - Erase lone edge correctly + + * markers.cc, markers.h: (h_axis_tick, v_axis_tick) Alignment option + - (h_axis, h_log_axis, v_axis, v_log_axis) Alignment option + * label_data.cc, label_data.h: (label_data(P, mark_type)) Accepts + alignment option + * eepic.cc: (print_mark) Handle alignment + * pst.cc: (print_mark) Handle alignment + - (print_edges) Use pspolygon for closed paths + + * path_data.cc, path_data.h: New constructor from list of edge3d + - (is_closed, is_filled) Move body to source file + - vector<P>, list<edge3d> constructors do not fill unless closed + * plot_algorithms.h: (plot_map_dom, euler_plot) Build plots from + edges, not vertices + - (plot_map_dom) Don't close or fill surface/solid plots + +2007-07.30 (ADH) + * circle.cc, circle.h, plane.cc, plane.h, segment.cc, segment.h, + sphere.cc, sphere.h: + - Remove intersection member operators + - Add bool malformed member, constructor for malformed objects + - Intersection operators do not throw + * intersections.cc, intersections.h: New files, handle + intersections of object classes + * make_header: Add intersections.h + +2007-07.29 (ADH) + * errors.h: Remove error type enums + + * data_file.cc: (write(fmt)) Column indices reversed in try block + + * curves.cc: (ellipse_left, ellipse_right) Correct angle bounds + * path.cc: Ellipse constructor creates path containing specified + number of edges + + * markers.cc: marker(P, circ) calls circ + - masked log axis labels + - log axis labels accept optional base argument + + * eepic.cc, pst.cc: BOX and DOT, BBOX and DDOT of the same size + - Label padding works more similarly to PSTricks + * pst.cc: (print(label_state, string)) If no label border, set + linestyle=none + * glyph.cc: (print_to) Handle font face + + * constants.h: AVG_DOT=4 (was 2), AVG_TICK=3 (was 2) + - Arrow head parameter bounds (MIN_AWIDTH, MIN_ARATIO, etc.) + * arrow_style.cc, arrowhead_style.h: + - Handle bounds on arrow head dimensions + - (width, ratio, camber, fill) Return arrowhead_state& (not void) + + * state.cc: (dash_size) Pass unchecked argument to path_state + - (dot_size, tick_size) Pass unchecked argument to marker_state + * marker_style.cc: (dot_size, tick_size) + - Handle unchecked arg + - Return marker_style& (not void) + * path_style.cc: (dash_size) Handle unchecked arg + +2007-07.28 (ADH) + Version 1.1.8 + * eepic.cc: (print(label_state, string)): Fix masklabel padding + * markers.cc: Don't pad axis labels with \phantom{-} + * camera.cc: No warning if point is behind film plane + * screen_data.cc: backing(), border() activate cropping + * data_file.cc: (read) Don't try to read empty files + - (column) Check for empty m_data + +2007-07.22 (ADH) + * data_mask.cc: (reverse) return *this + * length.cc: (get_lengths) Initialize len1, len2 + * crop_algorithms.h: (loopify) If only one edge is visible, return + empty edge list. + +2007-07.19 (ADH) + * edge_data.h: Rename seen() -> is_seen(), null() -> is_null() + * crop_algorithms.h, pen_fill.cc, pen_line.cc: seen() -> is_seen() + * pen_arrow.cc, pen_arrow.h: Remove member m_at_base (unused) + - (crop_to) Shaft visibility bug + - (print_to) Draw ddot if head, tail project to same location + * arrow_data.cc, arrow_data.h: Remove member m_at_base (unused) + - Remove clip() function (constructor applies automatically) + - seen() -> is_seen() + * format.h, eepic.h, pst.h: (print_arrow) Omit alignment argument + * eepic.cc, pst.cc: (print_arrow) Change signature, reimplement + - seen() -> is_seen() + * constants.h: Names in all caps + - New constants MIN_CLIP, TWO_PI + - BBOLD_WIDTH is 1.2pt (was 1.6pt) + * angle_units.cc, hatching.cc, marker_style.cc, path_style.cc, + state.cc: Use capitalized constants + * camera.cc, camera.h: Use MIN_CLIP + - Rename function to_front() -> clip_plane() + +2007-07.17 (ADH) + * crop_algorithms.h: New file for path-chopping templates + * halfspace.cc, halfspace.h: Remove private member functions + - Use crop_algorithms.h + * screen_crop.cc, screen_crop.h: New files for crop_path_2nd, + crop_loop_2nd (from edge_data.cc) + * edge_data.h: Move crop_path_2nd, crop_loop_2nd to screen_crop.cc + (file contains only template class and two typedefs) + * edge_data.cc: Remove file + +2007-07.16 (ADH) + * state.cc: (fill(true)) Set fill color to White() if unset + * halfspace.cc, halfspace.h: (clip_path) Out-of-order bug + - Move constructor body from header. + +2007-07.14 (ADH) + Version 1.1.7 + * eepic.cc, eepic.h, pst.cc, pst.h: Implement path styles + - (print_edge, print_edges) New functions + - (print_line) Implement in terms of print_edge + - (print_verbatim): New function + * verbatim.cc, verbatim.h: New files, implementing tile class for + verbatim output to file + * picture.cc, picture.h: (write, pre_write, post_write) New + functions to write verbatim strings to output + * screen.h: Declare global "write" function a friend + * picture_data.cc, picture_data.h: Add support for pre- and + post-written strings in output + * constants.h: Default axis ticks 4pt long + +2007-07.13 (ADH) + * path_style.cc, path_style.h: Interface redesign + - String-parsing implementation + - Use constants.h + * marker_style.cc: Use constants.h + * state.cc: Reimplement path style functions + - Use constants.h + - (dash_size) New function + - (dash_fill, dash_length) Functions removed + - (pen(Color, double), base(Color, double)) New functions + * label_data.cc: Constructors set tick mark color to line color + * edge_data.h: (length) New member function + +2007-07.08 (ADH) + * markers.cc: (h_axis, h_axis_labels, v_axis, v_axis_labels) If no + endpoints are specified, use dimensions of active screen + * curves.cc: (grid, log_grid) If corners not specified, use + corners of active screen + * pst.cc: (print_arrow) Draw head manually + (print_line) Use PSTricks border attribute in two-pen versions + (update_base) Bug fixes + * facet.cc, facet.h: New files + * surface.cc: Factor out utility classes facet, by_distance + - Support domain-dependent coloring + * path_data.cc: (photo) Print unfilled paths in chunks of 250 + points to ameliorate LaTeX overflow + +2007-07.07 (ADH) + Version 1.1.6 + * surface.cc, surface.h: Support position-dependent coloring + +2007-07.06 (ADH) + * eepic.cc, pst.cc: (print(style, string)) Fix alignment bug + (print_mark) No padding, border + * screen.cc, screen.h, screen_data.cc, screen_data.h: (is_cropped) + New function to add support for label cropping + * format.h, eepic.cc, eepic.h: Change signature of pic_header + * pst.cc, pst.h: Add support for label cropping + * picture_data.cc: (print_to) Pass crop flag + +2007-07.05 (ADH) + * markers.h: (h_axis_log_labels, v_axis_log_labels) Align argument + defaults to none + * picture.cc, picture.h: (eepic, pst) New functions to set output + format. (mp, pgf, svg stubs written.) + * camera.cc: (to_front) Min clip distance is 0.01 + * path_data.cc: (photo) Clip by camera.to_front() + +2007-07.04 (ADH) + * pst.cc, pst.h: New files + * eepic.cc: Implement label borders and padding + * state.cc, state.h: (new functions) + - plain(Color), bold(Color), bbold(Color), set line Color/width + - rgb(P), cmyk(P), use components as densities + - New functions to set label attributes + . label_color(Color); + . label_pad(string); + . label_border(Color, [string]), label_border(string); + . no_label_border(); + * curves.cc, curves.h: (draw_rect, swatch, rect(P, P, bool), + draw_polar_grid) Remove functions + * domain.cc, domain.h: + - No default domain constructor + - New constructor domain(P, P, mesh) + - Inline 1-dim'l constructor moved to cc file + - domain data members made private + New functions corner1_x1(), coarse_n1(), etc. + - "Net" typename removed + * plot_algorithms.h, plots.cc, surface.cc: Use domain state + functions + * data_bins.cc, data_bins.h: (bar_chart) New function + * data_file.cc, data_file.h: New global functions + - plot(filename, mark_type, col1, col2, col3, [F]) + plot(filename, mark_type, F, col1, col2, col3) + - histogram, bar_chart + +2007-07.03 (ADH) + * dataplot.cc, dataplot.h: Break up and remove files + * data_bins.cc, data_bins.h, data_file.cc, data_file.h, + data_mask.cc, data_mask.h, interval.cc, interval.h: New files + * samples: Remove sample document + * doc: Update + +2007-06.28 (ADH) + * circle,cc, circle.h: + - Rename class -> Circle + - Remove m_filled data member, fill operator + - Remove translation, scaling operators += and *= + - (translate) Rename "shift" + - (move_to) New function + - Circle::draw() fills according to current paint style + - (circle) New functions which draw automatically + * sphere.cc, sphere.h: + - Rename class -> Sphere + - Remove translation, scaling operators += and *= + - (shift, move_to, scale) New functions + - (poles) Remove global function + - (sphere) New functions which draw automatically + * plane.cc, plane.h: + - Rename class -> Plane + - (shift, move_to) New functions + - Remove translate, separates, parallel_to, contains, height + functions + - (draw) Reimplement + * segment.cc, segment.h: + - Rename class -> Segment + - (shift, move_to, scale) New functions + - Remove translation operator += + * path.cc, path.h,path_data.cc, path_data.h: Update class names + Circle, Plane, Segment, Sphere + * polyhedron.cc, polyhedron.h: Remove files + +2007-06.25 (ADH) + * contrib: Remove package + * surface.cc: (facet) Class contains a normal vector, + (facet::front_facing) Use normal vector to test + +2007-06.25 (ADH) + * surface.cc: (facet::draw) Use "direction" to compute density + * path.cc: (ellipse constructor) Don't close/fill automatically + * curves.cc: (ellipse) Close/fill if appropriate + * format.h, eepic.cc, eepic.h: (file_comment) New function + * picture_data.cc, picture_data.h: (file_header) Move to format.h + * path_data.cc, path_data.h: (draw) Implement base pen, + draw filled regions with both pens + * state.cc, state.h: Functions to control drawing state + - pen(Color, [string]), base(Color, [string]) + - fill(Color) + * doc/manual.tex: Update + +2007-06.20 (ADH) + Version 1.1.5 + * pen_arrow.cc, pen_arrow.h: Store shaft as edge, not as two pairs + * format.h, eepic.cc, eepic.h: (print_arrow) Adjust call syntax + * mask_diamond.cc, mask_ellipse.cc: (crop_to) Fix crop criterion + * geometry.cc, geometry.h: Re-implement spherical geometry + * sphere.cc, sphere.h: (latitude, longitude) Move to geometry.* + * functions.cc, functions.h + - Remove templates for id, zero, proj1, proj2, min, max + (put id, proj1, proj2 in map.h) + - Implement "zero" function with four call signatures + * plots.cc: (shadeplot) Path closure bug + * path.cc: (ellipse constructors) Close and fill if appropriate + * markers.cc: (arrow) Re-implement labeled arrow + * label_data.cc, label_data.h: Add visibility flag + * glyph.cc: (print_to) Implement font_size + * edge_data.cc: (crop_path_2nd) Loop processing bug + +2007-06.19 (ADH) + Version 1.1.4 + + Clipping and cropping work. Elliptical and diamond-shaped screen + masks are implemented. + +2007-06.03 (ADH) + Version 1.1.3, first public release + + Implements ePiX-2's color capabilities, including named models + (RGB, CMY, CMYK, and Gray), color blending, filtering, CMYK + separation, limited transparency, color filling and colorable + arrows in eepic, decorable screens, and page markup. + + The global parameters x_min, etc., should be replaced with + function calls, e.g. xmin(), from now on. Aside from this, the + syntax is backward compatible with Version 1.0.x. diff --git a/graphics/epix/Color.cc b/graphics/epix/Color.cc new file mode 100644 index 0000000000..1b4d01b717 --- /dev/null +++ b/graphics/epix/Color.cc @@ -0,0 +1,369 @@ +/* + * Color.cc -- ePiX Color functions + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * + * Last Change: September 13, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <sstream> +#include <string> +#include <vector> + +#include <cmath> + +#include "functions.h" + +#include "Color_Base.h" +#include "Color_Utils.h" + +#include "Color_CMY.h" +#include "Color_CMYK.h" +#include "Color_Gray.h" +#include "Color_Neutral.h" +#include "Color_RGB.h" +#include "Color_Sep.h" + +#include "Color.h" + +namespace ePiX { + + Color::Color() + : m_color(Neutral().m_color), m_alpha(1) { } + + Color::Color(const Color_Base& col) + : m_color(col.clone()), m_alpha(1) { } + + Color::Color(const Color_Base* col) + : m_color(col->clone()), m_alpha(1) { } + + + Color::Color(const Color& col) + : m_color(col.m_color->clone()), m_alpha(col.m_alpha) { } + + + Color& Color::operator= (const Color& col) + { + if (*this != col) + { + Color_Base* tmp(col.m_color->clone()); + delete m_color; + + m_color = tmp; + m_alpha = col.m_alpha; + } + + return *this; + } + + Color::~Color() + { + delete m_color; + } + + const Color_Base* Color::operator->() const + { + return m_color; + } + + double Color::alpha() const + { + return m_alpha; + } + + + bool Color::operator== (const Color& col) const + { + return m_color->name() == col.m_color->name(); + } + + bool Color::operator< (const Color& col) const + { + // N.B. add_colors_to() must check for Unset + return m_color->name() < col.m_color->name(); + } + + bool Color::is_unset() const + { + // we're Neutral() + return (name() == ""); + } + + + // no effect if we or col are Neutral + Color Color::filter(const Color& col) const + { + if (m_color->name() == "" || col.is_unset()) + return col; + + else + { + Color_Base* fil(m_color->clone()); + fil->filter(*(col.m_color)); + + Color val(fil); + delete fil; + return val; + } + } + + Color& Color::operator*= (double c) + { + (*m_color) *= c; + + return *this; + } + + // Blending with Unset has no effect + Color& Color::blend(const Color& col, double d) + { + if (!col.is_unset()) + m_color->blend(*(col.m_color), d); + + return *this; + } + + Color& Color::superpose(const Color& col) + { + if (!col.is_unset()) + m_color->superpose(*(col.m_color)); + + return *this; + } + + Color& Color::invert() + { + m_color->invert(); + + return *this; + } + + Color& Color::alpha(double t) + { + m_alpha = t; + return *this; + } + + + std::string Color::model() const + { + return m_color->model(); + } + + std::string Color::name() const + { + return m_color->name(); + } + + std::vector<double> Color::densities() const + { + return m_color->densities(); + } + + + // Named constructors + Color RGB(double r, double g, double b) + { + return Color(RGB_Color(r, g, b)); + } + + Color CMY(double c, double m, double y) + { + return Color(CMY_Color(c, m, y)); + } + + Color CMYK(double c, double m, double y, double k) + { + return Color(CMYK_Color(c, m, y, k)); + } + + Color Gray(double d) + { + return Color(Gray_Color(d)); + } + + + // Scale operator + Color operator* (double c, const Color& col) + { + Color tmp(col); + return tmp *= c; + } + + + /* * * Extended primaries in the global namespace * * */ + Color Red(double d) + { + return RGB(clippy(d), clippy(-d), clippy(-d)); + } + + Color Green(double d) + { + return RGB(clippy(-d), clippy(d), clippy(-d)); + } + + Color Blue(double d) + { + return RGB(clippy(-d), clippy(-d), clippy(d)); + } + + Color White(double d) + { + return RGB(clippy(d), clippy(d), clippy(d)); + } + + Color Black(double d) + { + return RGB(clippy(1-d), clippy(1-d), clippy(1-d)); + } + + + /* * * CMY * * */ + Color Cyan(double d) + { + return CMY_Color(clippy(d), clippy(-d), clippy(-d), true); + } + + Color Magenta(double d) + { + return CMY_Color(clippy(-d), clippy(d), clippy(-d), true); + } + + Color Yellow(double d) + { + return CMY_Color(clippy(-d), clippy(-d), clippy(d), true); + } + + Color CMY_White(double d) + { + return CMY_Color(clippy(1-d), clippy(1-d), clippy(1-d), true); + } + + Color CMY_Black(double d) + { + return CMY_Color(clippy(d), clippy(d), clippy(d), true); + } + + + /* * * CMYK * * */ + Color CyanK(double d) + { + double c(clippy(d)); + double m(clippy(-d)); + double y(m); // [sic] + double k(min(c,m)); // y=m + + return CMYK_Color(c-k, m-k, y-k, k, true); + } + + Color MagentaK(double d) + { + double c(clippy(-d)); + double m(clippy(d)); + double y(c); + double k(min(c,m)); // y=c + + return CMYK_Color(c-k, m-k, y-k, k, true); + } + + Color YellowK(double d) + { + double c(clippy(-d)); + double m(c); + double y(clippy(d)); + double k(min(c,y)); // m=c + + return CMYK_Color(c-k, m-k, y-k, k, true); + } + + Color CMYK_White(double d) + { + return CMYK_Color(0, 0, 0, clippy(1-d), true); + } + + Color CMYK_Black(double d) + { + return CMYK_Color(0, 0, 0, clippy(d), true); + } + + + Color C_Process(double d) + { + return Cyan_Layer(d); + } + + Color M_Process(double d) + { + return Magenta_Layer(d); + } + + Color Y_Process(double d) + { + return Yellow_Layer(d); + } + + Color K_Process(double d) + { + return Black_Layer(d); + } + + + /* * * Neutral filters * * */ + Color Neutral() + { + static Neutral_Color* neutral(new Neutral_Color()); + return Color(*neutral); + } + + Color RGB_Neutral() + { + static RGB_Color* rgb_neutral(new RGB_Color(1, 1, 1)); + return Color(*rgb_neutral); + } + + Color CMY_Neutral() + { + static CMY_Color* cmy_neutral(new CMY_Color(0, 0, 0, true)); + return Color(*cmy_neutral); + } + + Color CMYK_Neutral() + { + static CMYK_Color* cmyk_neutral(new CMYK_Color(0, 0, 0, 0, true)); + return Color(*cmyk_neutral); + } + + Color Gray_Neutral() + { + static Gray_Color* gray_neutral(new Gray_Color(1)); + return Color(*gray_neutral); + } +} // end of namespace diff --git a/graphics/epix/Color.h b/graphics/epix/Color.h new file mode 100644 index 0000000000..fc2db6127e --- /dev/null +++ b/graphics/epix/Color.h @@ -0,0 +1,156 @@ +/* + * Color.h -- ePiX::Color class and helpers + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * Last Change: September 13, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file defines the ePiX Color user interface: + * operator*= Modify intensity + * blend(Color, double) Color mixing + * filter(Color) Apply us as a filter + * superpose(Color) Add colors, clip intensities + * invert() Color negative + * + * - Named primary constructors + * + * Scaling and filtering are implemented by converting to the filter's + * color model. Color model conversions come from the LaTeX xcolor + * package documentation, V 1.11 (2044/05/09) by Uwe Kern. + */ + +#ifndef EPIX_COLOR +#define EPIX_COLOR + +#include <string> +#include <vector> + +namespace ePiX { + + class Color_Base; + + class Color { + public: + Color(); + Color(const Color_Base*); + Color(const Color_Base&); + Color(const Color&); + + Color& operator= (const Color&); + + ~Color(); + + const Color_Base* operator->() const; + double alpha() const; + + bool operator== (const Color&) const; + bool operator< (const Color&) const; // needed for Screen::pallet + bool operator!= (const Color& col) const { return !((*this) == col); } + bool is_unset() const; + + Color filter(const Color&) const; + + Color& operator*= (double c); // scale the intensity + Color& blend(const Color&, double); + Color& superpose(const Color&); + Color& invert(); + Color& alpha(double); + + std::string model() const; + std::string name() const; + std::vector<double> densities() const; + + private: + Color_Base* m_color; + double m_alpha; + + }; // end of class Color + + Color operator* (double, const Color&); + + + /* + * * * Primary color functions in the global namespace * * * + * + * A primary color constructor accepts a numerical argument, which is + * reduced mod 4, then interpreted as a color density as follows: + * d = -2 or 2 : white + * d = -1: full anti-saturation + * d = 0: black + * d = 1: full saturation (default) + * + * The primary changes continuously, and linearly on each interval + * [-2,-1], [-1,0], [0,1], and [1,2]. + * + * Example: + * Red(0.3) = rgb(0.3, 0, 0) = Red(-3.7) + * Red(1.3) = rgb(1,0.3,0.3) = Red(-2.7) + * Red(2.3) = rgb(0.7, 1, 1) = Red(-1.7) + * Red(3.3) = rgb(0,0.7,0.7) = Red(-0.7) + */ + Color RGB(double r=0, double g=0, double b=0); + Color CMY(double c=1, double m=1, double y=1); + Color CMYK(double c=1, double m=1, double y=1, + double k=0); // void same as CMYK(0,0,0,1); + Color Gray(double d=0); + + Color Red(double d=1); + Color Green(double d=1); + Color Blue(double d=1); + Color White(double d=1); + Color Black(double d=1); + + Color Cyan(double d=1); + Color Magenta(double d=1); + Color Yellow(double d=1); + Color CMY_White(double d=1); + Color CMY_Black(double d=1); + + Color CyanK(double d=1); + Color MagentaK(double d=1); + Color YellowK(double d=1); + Color CMYK_White(double d=1); + Color CMYK_Black(double d=1); + + // color separation + Color C_Process(double d=1); + Color M_Process(double d=1); + Color Y_Process(double d=1); + Color K_Process(double d=1); + + // "conversion filters" + Color Neutral(); + Color RGB_Neutral(); + Color CMY_Neutral(); + Color CMYK_Neutral(); + Color Gray_Neutral(); + +} // end of namespace + +#endif /* EPIX_COLOR */ diff --git a/graphics/epix/Color_Base.cc b/graphics/epix/Color_Base.cc new file mode 100644 index 0000000000..74fdf5c7a8 --- /dev/null +++ b/graphics/epix/Color_Base.cc @@ -0,0 +1,52 @@ +/* + * Color_Base.cc -- ePiX Color_Base functions + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.3 + * + * Last Change: June 03, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "Color_Utils.h" +#include "Color_Base.h" + +namespace ePiX { + + Color_Base::RGB_Densities::RGB_Densities(double r, + double g, + double b) + : m_dens_red (make_r(r, g, b)), + m_dens_green(make_g(r, g, b)), + m_dens_blue (make_b(r, g, b)) { } + + bool Color_Base::operator== (const Color_Base& col) const + { + return (name() == col.name()); + } +} // end of namespace diff --git a/graphics/epix/Color_Base.h b/graphics/epix/Color_Base.h new file mode 100644 index 0000000000..7c369f33ba --- /dev/null +++ b/graphics/epix/Color_Base.h @@ -0,0 +1,84 @@ +/* + * Color_Base.h -- ePiX::Color interface + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * Last Change: September 13, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_COLOR_BASE +#define EPIX_COLOR_BASE + +#include <string> +#include <vector> + +namespace ePiX { + + class Color_Base { + + protected: + struct RGB_Densities + { + // ensures densities are in [0,1] + RGB_Densities (double r, double g, double b); + + double m_dens_red, m_dens_green, m_dens_blue; + }; + + public: + virtual ~Color_Base() { } + virtual Color_Base* clone() const = 0; + + // blending (all non-const) + // apply us as filter + virtual Color_Base& filter(const Color_Base&) = 0; + + // scale intensities + virtual Color_Base& operator*= (double) = 0; + + // clip d to [0,1], then return (1-d)*this + d*col + virtual Color_Base& blend(const Color_Base&, double) = 0; + + // add channels + virtual Color_Base& superpose(const Color_Base&) = 0; + + // return negative color + virtual Color_Base& invert() = 0; + + // internal colorname and densities + virtual std::string model() const = 0; + virtual std::string name() const = 0; + virtual std::vector<double> densities() const = 0; + + bool operator== (const Color_Base& col) const; + virtual RGB_Densities to_rgb() const = 0; + + }; // end of class Color_Base + +} // end of namespace + +#endif /* EPIX_COLOR_BASE */ diff --git a/graphics/epix/Color_CMY.cc b/graphics/epix/Color_CMY.cc new file mode 100644 index 0000000000..085823acc2 --- /dev/null +++ b/graphics/epix/Color_CMY.cc @@ -0,0 +1,160 @@ +/* + * Color_CMY.cc -- ePiX::CMY_Color functions + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * + * Last Change: September 13, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <sstream> +#include <string> +#include <vector> + +#include <cmath> + +#include "functions.h" + +#include "Color_Utils.h" +#include "Color.h" +#include "Color_CMY.h" + +namespace ePiX { + + CMY_Color::CMY_Color(double c, double m, double y) + : cyan(make_r(c,m,y)), magenta(make_g(c,m,y)), yellow(make_b(c,m,y)) { } + + // private, no arg checking, bool unused + CMY_Color::CMY_Color(double c, double m, double y, + const bool arg) + : cyan(c), magenta(m), yellow(y) { } + + + CMY_Color::CMY_Color(const RGB_Densities& s) + : cyan(1-s.m_dens_red), + magenta(1-s.m_dens_green), + yellow(1-s.m_dens_blue) { } + + + Color_Base::RGB_Densities CMY_Color::to_rgb() const + { + // Use conventional formulas since our densities are already in [0,1] + return Color_Base::RGB_Densities(1-cyan, 1-magenta, 1-yellow); + } + + CMY_Color* CMY_Color::clone() const + { + return new CMY_Color(*this); + } + + CMY_Color& CMY_Color::filter(const Color_Base& color) + { + Color_Base::RGB_Densities s(color.to_rgb()); + + // filter in RGB; 1 - min(1-x, 1-y) = max(x, y) + cyan = max(cyan, 1-s.m_dens_red); + magenta = max(magenta, 1-s.m_dens_green); + yellow = max(yellow, 1-s.m_dens_blue); + + return *this; + } + + CMY_Color& CMY_Color::operator*= (double sc) + { + Color_Base::RGB_Densities s(to_rgb()); + + // scale in RGB + double r(sc*(s.m_dens_red)); + double g(sc*(s.m_dens_green)); + double b(sc*(s.m_dens_blue)); + + cyan = 1 - make_r(r, g, b); + magenta = 1 - make_g(r, g, b); + yellow = 1 - make_b(r, g, b); + + return *this; + } + + CMY_Color& CMY_Color::blend(const Color_Base& color, double d) + { + Color_Base::RGB_Densities s(color.to_rgb()); + double wt(clip_to_unit(d)); + + // blending is a convex lin. comb., may as well do in CMY + cyan += wt*(1 - cyan - s.m_dens_red); + magenta += wt*(1 - magenta - s.m_dens_green); + yellow += wt*(1 - yellow - s.m_dens_blue); + + return *this; + } + + CMY_Color& CMY_Color::superpose(const Color_Base& color) + { + Color_Base::RGB_Densities s(color.to_rgb()); + + // add in RGB + cyan = 1 - clip_to_unit(1 - cyan + s.m_dens_red); + magenta = 1 - clip_to_unit(1 - magenta + s.m_dens_green); + yellow = 1 - clip_to_unit(1 - yellow + s.m_dens_blue); + + return *this; + } + + + CMY_Color& CMY_Color::invert() + { + cyan = 1 - cyan; + magenta = 1 - magenta; + yellow = 1 - yellow; + + return *this; + } + + + std::string CMY_Color::model() const + { + return "cmy"; + } + + std::string CMY_Color::name() const + { + std::ostringstream nm; + + nm << "cmy_" << dtohex(cyan) << dtohex(magenta) << dtohex(yellow); + + return nm.str(); + } + + std::vector<double> CMY_Color::densities() const + { + std::vector<double> val(3); + val.at(0) = rd(cyan); + val.at(1) = rd(magenta); + val.at(2) = rd(yellow); + return val; + } +} // end of namespace diff --git a/graphics/epix/Color_CMY.h b/graphics/epix/Color_CMY.h new file mode 100644 index 0000000000..3a8b8ed821 --- /dev/null +++ b/graphics/epix/Color_CMY.h @@ -0,0 +1,82 @@ +/* + * Color_CMY.h -- ePiX::CMY_Color class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * Last Change: September 13, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_COLOR_CMY +#define EPIX_COLOR_CMY +#include <string> +#include <vector> + +#include "Color_Base.h" +#include "Color.h" + +namespace ePiX { + + class CMY_Color : public Color_Base { + public: + explicit CMY_Color(double c=1, double m=1, double y=1); + CMY_Color(const RGB_Densities&); + + CMY_Color* clone() const; + + CMY_Color& filter(const Color_Base&); + + CMY_Color& operator*= (double c); + + CMY_Color& blend(const Color_Base&, double); + CMY_Color& superpose(const Color_Base&); + CMY_Color& invert(); + + std::string model() const; + std::string name() const; + std::vector<double> densities() const; + + RGB_Densities to_rgb() const; + + // These need to call our private constructor + friend Color Cyan(double); + friend Color Magenta(double); + friend Color Yellow(double); + friend Color CMY_White(double); + friend Color CMY_Black(double); + friend Color CMY_Neutral(); + + private: + double cyan; + double magenta; + double yellow; + + // Construct a CMY color without checking arguments. Final argument + // only changes call signature + CMY_Color(double c, double m, double y, const bool); + }; // end of class CMY_Color + +} // end of namespace +#endif /* EPIX_COLOR_CMY */ diff --git a/graphics/epix/Color_CMYK.cc b/graphics/epix/Color_CMYK.cc new file mode 100644 index 0000000000..ef730a1998 --- /dev/null +++ b/graphics/epix/Color_CMYK.cc @@ -0,0 +1,216 @@ +/* + * Color_CMYK.cc -- ePiX::CMYK_Color functions + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * + * Last Change: September 13, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <sstream> +#include <string> +#include <vector> + +#include <cmath> + +#include "functions.h" + +#include "Color_Utils.h" +#include "Color.h" +#include "Color_CMYK.h" + +namespace ePiX { + + // Behaves "classically" if c+k, m+k, y+k are in [0,1] + // Except as noted, CMYK methods enforce/preserve this condition + CMYK_Color::CMYK_Color(double c, double m, double y, + double k) + : cyan(make_r(c+k, m+k, y+k)), + magenta(make_g(c+k, m+k, y+k)), + yellow(make_b(c+k, m+k, y+k)), + black(min(min(cyan, magenta), yellow)) + { + /* conventional RGB densities + double r(1 - min(1, c+k)); + double g(1 - min(1, m+k)); + double b(1 - min(1, y+k)); + */ + cyan -= black; + magenta -= black; + yellow -= black; + } + + // private, no arg checking, bool unused + CMYK_Color::CMYK_Color(double c, double m, + double y, double k, const bool arg) + : cyan(c), magenta(m), yellow(y), black(k) { } + + + // black = min(c,m,y), following Uwe Kern's xcolor documentation + // V 1.11, 2004/05/09, p. 31 + CMYK_Color::CMYK_Color(const RGB_Densities& s) + { + // may assume densities are in [0,1] + double c(1-s.m_dens_red), m(1-s.m_dens_green), y(1-s.m_dens_blue); + + black = min(min(c, m), y); + cyan = c-black; + magenta = m-black; + yellow = y-black; + } + + Color_Base::RGB_Densities CMYK_Color::to_rgb() const + { + // Use conventional formulas since our densities are already in [0,1]; + // "min" for safety, should be unnecessary. + return Color_Base::RGB_Densities(1 - min(1.0, cyan + black), + 1 - min(1.0, magenta + black), + 1 - min(1.0, yellow + black)); + } + + CMYK_Color* CMYK_Color::clone() const + { + return new CMYK_Color(*this); + } + + CMYK_Color& CMYK_Color::filter(const Color_Base& color) + { + Color_Base::RGB_Densities s(color.to_rgb()); // arg + Color_Base::RGB_Densities t(to_rgb()); // this + + // filter in RGB + double c(1 - min(t.m_dens_red, s.m_dens_red)); + double m(1 - min(t.m_dens_green, s.m_dens_green)); + double y(1 - min(t.m_dens_blue, s.m_dens_blue)); + black = min(min(c, m), y); + + cyan = c-black; + magenta = m-black; + yellow = y-black; + + return *this; + } + + + CMYK_Color& CMYK_Color::operator*= (double sc) + { + Color_Base::RGB_Densities s(to_rgb()); + + // scale in RGB + double r(sc*(s.m_dens_red)); + double g(sc*(s.m_dens_green)); + double b(sc*(s.m_dens_blue)); + + // Necessary b/c sc may not be in [0,1] + double c(1 - make_r(r, g, b)); + double m(1 - make_g(r, g, b)); + double y(1 - make_b(r, g, b)); + + black = min(min(c, m), y); + cyan = c-black; + magenta = m-black; + yellow = y-black; + + return *this; + } + + CMYK_Color& CMYK_Color::blend(const Color_Base& color, double d) + { + Color_Base::RGB_Densities s(color.to_rgb()); + double wt(clip_to_unit(d)); + + double c((1-wt)*min(1.0, cyan+black) + wt*(1 - s.m_dens_red)); + double m((1-wt)*min(1.0, magenta+black) + wt*(1 - s.m_dens_green)); + double y((1-wt)*min(1.0, yellow+black) + wt*(1 - s.m_dens_blue)); + + black = min(min(c, m), y); + cyan = c-black; + magenta = m-black; + yellow = y-black; + + return *this; + } + + CMYK_Color& CMYK_Color::superpose(const Color_Base& color) + { + Color_Base::RGB_Densities s(color.to_rgb()); + Color_Base::RGB_Densities t(to_rgb()); + + // add in RGB + double c(1 - clip_to_unit(t.m_dens_red + s.m_dens_red)); + double m(1 - clip_to_unit(t.m_dens_green + s.m_dens_green)); + double y(1 - clip_to_unit(t.m_dens_blue + s.m_dens_blue)); + + black = min(min(c, m), y); + cyan = c-black; + magenta = m-black; + yellow = y-black; + + return *this; + } + + CMYK_Color& CMYK_Color::invert() + { + Color_Base::RGB_Densities s(to_rgb()); + + // invert in RGB + double c(1 - s.m_dens_red); + double m(1 - s.m_dens_green); + double y(1 - s.m_dens_blue); + + black = min(min(c, m), y); + cyan = c-black; + magenta = m-black; + yellow = y-black; + + return *this; + } + + std::string CMYK_Color::model() const + { + return "cmyk"; + } + + std::string CMYK_Color::name() const + { + std::ostringstream nm; + + nm << "cmyk_" << dtohex(cyan) << dtohex(magenta) << dtohex(yellow) + << dtohex(black); + return nm.str(); + } + + std::vector<double> CMYK_Color::densities() const + { + std::vector<double> val(4); + val.at(0) = rd(cyan); + val.at(1) = rd(magenta); + val.at(2) = rd(yellow); + val.at(3) = rd(black); + return val; + } +} // end of namespace diff --git a/graphics/epix/Color_CMYK.h b/graphics/epix/Color_CMYK.h new file mode 100644 index 0000000000..8b99aaa573 --- /dev/null +++ b/graphics/epix/Color_CMYK.h @@ -0,0 +1,85 @@ +/* + * Color_CMYK.h -- ePiX::CMYK_Color class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * Last Change: September 13, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_COLOR_CMYK +#define EPIX_COLOR_CMYK +#include <string> +#include <vector> + +#include "Color_Base.h" +#include "Color.h" + +namespace ePiX { + + class CMYK_Color : public Color_Base { + public: + CMYK_Color(double c=1, double m=1, double y=1, + double k=1); + CMYK_Color(const RGB_Densities&); + + CMYK_Color* clone() const; + + CMYK_Color& filter(const Color_Base&); + + CMYK_Color& operator*= (double c); + + CMYK_Color& blend(const Color_Base&, double); + CMYK_Color& superpose(const Color_Base&); + CMYK_Color& invert(); + + std::string model() const; + std::string name() const; + std::vector<double> densities() const; + + RGB_Densities to_rgb() const; + + // These need to call our private constructor + friend Color CyanK(double); + friend Color MagentaK(double); + friend Color YellowK(double); + friend Color CMYK_White(double); + friend Color CMYK_Black(double); + friend Color CMYK_Neutral(); + + private: + double cyan; + double magenta; + double yellow; + double black; + + // Construct a CMYK color without checking arguments. Final argument + // only changes call signature + CMYK_Color(double c, double m, double y, + double k, const bool); + }; // end of class CMYK_Color + +} // end of namespace +#endif /* EPIX_COLOR_CMYK */ diff --git a/graphics/epix/Color_Gray.cc b/graphics/epix/Color_Gray.cc new file mode 100644 index 0000000000..9d0901ca29 --- /dev/null +++ b/graphics/epix/Color_Gray.cc @@ -0,0 +1,129 @@ +/* + * Color_Gray.cc -- ePiX::Gray_Color functions + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * + * Last Change: September 13, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <sstream> +#include <string> +#include <vector> + +#include <cmath> + +#include "functions.h" + +#include "Color_Utils.h" +#include "Color_Gray.h" + +namespace ePiX { + + Gray_Color::Gray_Color(double d) + : m_gray(clip_to_unit(d)) { } + + + Gray_Color::Gray_Color(const RGB_Densities& s) + : m_gray((1.0/3)*(s.m_dens_red+s.m_dens_green+s.m_dens_blue)) { } + + Color_Base::RGB_Densities Gray_Color::to_rgb() const + { + return Color_Base::RGB_Densities(m_gray, m_gray, m_gray); + } + + Gray_Color* Gray_Color::clone() const + { + return new Gray_Color(*this); + } + + + Gray_Color& Gray_Color::filter(const Color_Base& color) + { + Color_Base::RGB_Densities s(color.to_rgb()); + + m_gray = min(m_gray, (1.0/3)*(s.m_dens_red+s.m_dens_green+s.m_dens_blue)); + return *this; + } + + Gray_Color& Gray_Color::operator*= (double c) + { + m_gray = clip_to_unit(c*m_gray); + return *this; + } + + Gray_Color& Gray_Color::blend(const Color_Base& color, double d) + { + Color_Base::RGB_Densities s(color.to_rgb()); + double wt(clip_to_unit(d)); + + m_gray += wt*((1.0/3)*(s.m_dens_red+s.m_dens_green+s.m_dens_blue)-m_gray); + + return *this; + } + + Gray_Color& Gray_Color::superpose(const Color_Base& color) + { + Color_Base::RGB_Densities s(color.to_rgb()); + + m_gray = clip_to_unit((1.0/3)*(s.m_dens_red + + s.m_dens_green + + s.m_dens_blue) + m_gray); + + return *this; + } + + Gray_Color& Gray_Color::invert() + { + m_gray = 1 - m_gray; + return *this; + } + + + std::string Gray_Color::model() const + { + return "rgb"; + } + + std::string Gray_Color::name() const + { + std::ostringstream nm; + + nm << "gray_" << dtohex(m_gray); + + return nm.str(); + } + + std::vector<double> Gray_Color::densities() const + { + std::vector<double> val(3); + val.at(0) = rd(m_gray); + val.at(1) = rd(m_gray); + val.at(2) = rd(m_gray); + return val; + } +} // end of namespace diff --git a/graphics/epix/Color_Gray.h b/graphics/epix/Color_Gray.h new file mode 100644 index 0000000000..681861affa --- /dev/null +++ b/graphics/epix/Color_Gray.h @@ -0,0 +1,67 @@ +/* + * Color_Gray.h -- ePiX::Gray_Color class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * Last Change: September 13, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_COLOR_GRAY +#define EPIX_COLOR_GRAY +#include <string> +#include <vector> + +#include "Color_Base.h" + +namespace ePiX { + + class Gray_Color : public Color_Base { + public: + Gray_Color(double dens=0); + Gray_Color(const RGB_Densities&); + + Gray_Color* clone() const; + + Gray_Color& filter(const Color_Base&); + + Gray_Color& operator*= (double c); + + Gray_Color& blend(const Color_Base&, double); + Gray_Color& superpose(const Color_Base&); + Gray_Color& invert(); + + std::string model() const; + std::string name() const; + std::vector<double> densities() const; + + RGB_Densities to_rgb() const; + + private: + double m_gray; + }; // end of class Gray_Color + +} // end of namespace +#endif /* EPIX_COLOR_GRAY */ diff --git a/graphics/epix/Color_Neutral.cc b/graphics/epix/Color_Neutral.cc new file mode 100644 index 0000000000..66e149eafd --- /dev/null +++ b/graphics/epix/Color_Neutral.cc @@ -0,0 +1,98 @@ +/* + * Color_Neutral.cc -- ePiX::Neutral_Color + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.18 + * Last Change: September 14, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <string> + +#include "Color.h" +#include "Color_Neutral.h" + +namespace ePiX { + + Neutral_Color::Neutral_Color() { } + + Color_Base::RGB_Densities Neutral_Color::to_rgb() const + { + return Color_Base::RGB_Densities(1, 1, 1); + } + + Neutral_Color* Neutral_Color::clone() const + { + return new Neutral_Color(*this); + } + + + Color_Base& Neutral_Color::filter(const Color_Base& color) + { + Color_Base* tmp(color.clone()); + return *tmp; + } + + Neutral_Color& Neutral_Color::operator*= (double c) + { + return *this; + } + + Neutral_Color& Neutral_Color::blend(const Color_Base& color, double d) + { + return *this; + } + + Neutral_Color& Neutral_Color::superpose(const Color_Base& color) + { + return *this; + } + + Neutral_Color& Neutral_Color::invert() + { + return *this; + } + + // string identifier -- not output-specific + std::string Neutral_Color::name() const + { + return ""; + } + + std::string Neutral_Color::model() const + { + return ""; + } + + std::vector<double> Neutral_Color::densities() const + { + std::vector<double> value(0); + return value; + } +} // end of namespace diff --git a/graphics/epix/Color_Neutral.h b/graphics/epix/Color_Neutral.h new file mode 100644 index 0000000000..76d73ae284 --- /dev/null +++ b/graphics/epix/Color_Neutral.h @@ -0,0 +1,64 @@ +/* + * Color_Neutral.h -- ePiX::Neutral ("unset") class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * Last Change: September 13, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_COLOR_NEUTRAL +#define EPIX_COLOR_NEUTRAL +#include <string> + +#include "Color_Base.h" + +namespace ePiX { + class Neutral_Color : public Color_Base { + public: + Neutral_Color(); + + Color_Base& filter(const Color_Base&); + + std::string name() const; + + private: + // these functions are implemented, but should never be called + RGB_Densities to_rgb() const; + Neutral_Color* clone() const; + + Neutral_Color& operator*= (double c); + + Neutral_Color& blend(const Color_Base&, double); + Neutral_Color& superpose(const Color_Base&); + Neutral_Color& invert(); + + // not implemented, should never be called + std::string model() const; + std::vector<double> densities() const; + }; // end of class Neutral_Color + +} // end of namespace +#endif /* EPIX_COLOR_NEUTRAL */ diff --git a/graphics/epix/Color_RGB.cc b/graphics/epix/Color_RGB.cc new file mode 100644 index 0000000000..9ea0f6bb3f --- /dev/null +++ b/graphics/epix/Color_RGB.cc @@ -0,0 +1,146 @@ +/* + * Color_RGB.cc -- ePiX::RGB_Color + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * + * Last Change: September 13, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <sstream> +#include <string> +#include <vector> + +#include <cmath> + +#include "functions.h" + +#include "Color_Utils.h" +#include "Color_RGB.h" + +namespace ePiX { + + RGB_Color::RGB_Color(double r, double g, double b) + : red(make_r(r, g, b)), green(make_g(r, g, b)), blue(make_b(r, g, b)) { } + + + RGB_Color::RGB_Color(const RGB_Densities& s) + : red(s.m_dens_red), green(s.m_dens_green), blue(s.m_dens_blue) { } + + Color_Base::RGB_Densities RGB_Color::to_rgb() const + { + return Color_Base::RGB_Densities(red, green, blue); + } + + RGB_Color* RGB_Color::clone() const + { + return new RGB_Color(*this); + } + + + RGB_Color& RGB_Color::filter(const Color_Base& color) + { + Color_Base::RGB_Densities s(color.to_rgb()); + + red = min(red, s.m_dens_red); + green = min(green, s.m_dens_green); + blue = min(blue, s.m_dens_blue); + + return *this; + } + + RGB_Color& RGB_Color::operator*= (double c) + { + double r(red*c); + double g(green*c); + double b(blue*c); + + red = make_r(r, g, b); + green = make_g(r, g, b); + blue = make_b(r, g, b); + + return *this; + } + + RGB_Color& RGB_Color::blend(const Color_Base& color, double d) + { + Color_Base::RGB_Densities s(color.to_rgb()); + double wt(clip_to_unit(d)); + + red += wt*(s.m_dens_red - red); + green += wt*(s.m_dens_green - green); + blue += wt*(s.m_dens_blue - blue); + + return *this; + } + + RGB_Color& RGB_Color::superpose(const Color_Base& color) + { + Color_Base::RGB_Densities s(color.to_rgb()); + + red = clip_to_unit(red + s.m_dens_red); + green = clip_to_unit(green + s.m_dens_green); + blue = clip_to_unit(blue + s.m_dens_blue); + + return *this; + } + + RGB_Color& RGB_Color::invert() + { + red = 1 - red; + green = 1 - green; + blue = 1 - blue; + + return *this; + } + + std::string RGB_Color::model() const + { + return "rgb"; + } + + std::string RGB_Color::name() const + { + std::ostringstream nm; + + nm << "rgb_" << dtohex(red) << dtohex(green) << dtohex(blue); + + return nm.str(); + } + + std::vector<double> RGB_Color::densities() const + { + std::vector<double> val(3); + val.at(0) = rd(red); + val.at(1) = rd(green); + val.at(2) = rd(blue); + return val; + } +} // end of namespace diff --git a/graphics/epix/Color_RGB.h b/graphics/epix/Color_RGB.h new file mode 100644 index 0000000000..696577466a --- /dev/null +++ b/graphics/epix/Color_RGB.h @@ -0,0 +1,68 @@ +/* + * Color_RGB.h -- ePiX::RGB_Color class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * Last Change: September 13, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_COLOR_RGB +#define EPIX_COLOR_RGB +#include <string> +#include <vector> + +#include "Color_Base.h" + +namespace ePiX { + class RGB_Color : public Color_Base { + public: + RGB_Color(double r=0, double g=0, double b=0); + RGB_Color(const RGB_Densities&); + + RGB_Color* clone() const; + + RGB_Color& filter(const Color_Base&); + + RGB_Color& operator*= (double c); + + RGB_Color& blend(const Color_Base&, double); + RGB_Color& superpose(const Color_Base&); + RGB_Color& invert(); + + std::string model() const; + std::string name() const; + std::vector<double> densities() const; + + RGB_Densities to_rgb() const; + + private: + double red; + double green; + double blue; + }; // end of class RGB_Color + +} // end of namespace +#endif /* EPIX_COLOR_RGB */ diff --git a/graphics/epix/Color_Sep.cc b/graphics/epix/Color_Sep.cc new file mode 100644 index 0000000000..e9652a9d11 --- /dev/null +++ b/graphics/epix/Color_Sep.cc @@ -0,0 +1,278 @@ +/* + * Color_Sep.cc -- ePiX CMYK Color separation functions + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * + * Last Change: September 13, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <sstream> +#include <string> +#include <vector> + +#include <cmath> + +#include "functions.h" + +#include "Color_Utils.h" +#include "Color.h" +#include "Color_Sep.h" + +namespace ePiX { + + Cyan_Layer::Cyan_Layer(double arg) + : m_dens(clip_to_unit(arg)) { } + + // Return Cyan channel of color + Cyan_Layer& Cyan_Layer::filter(const Color_Base& color) + { + Color_Base::RGB_Densities s(color.to_rgb()); + if (Color(color).is_unset()) + s = Color_Base::RGB_Densities(1,1,1); + + m_dens = min(m_dens, 1-s.m_dens_red); + return *this; + } + + Cyan_Layer* Cyan_Layer::clone() const + { + return new Cyan_Layer(*this); + } + + Color_Base::RGB_Densities Cyan_Layer::to_rgb() const + { + return Color_Base::RGB_Densities(1-m_dens, 1, 1); + } + + + std::string Cyan_Layer::model() const + { + return "cmyk"; + } + + std::string Cyan_Layer::name() const + { + std::ostringstream nm; + nm << "c_proc_" << dtohex(m_dens); + return nm.str(); + } + + std::vector<double> Cyan_Layer::densities() const + { + std::vector<double> val(4); + val.at(0) = rd(m_dens); + val.at(1) = 0; + val.at(2) = 0; + val.at(3) = 0; + return val; + } + + + // Magenta_Layer + Magenta_Layer::Magenta_Layer(double arg) + : m_dens(clip_to_unit(arg)) { } + + // Return Magenta channel of color + Magenta_Layer& Magenta_Layer::filter(const Color_Base& color) + { + Color_Base::RGB_Densities s(color.to_rgb()); + if (Color(color).is_unset()) + s = Color_Base::RGB_Densities(1,1,1); + + m_dens = min(m_dens, 1-s.m_dens_green); + return *this; + } + + Magenta_Layer* Magenta_Layer::clone() const + { + return new Magenta_Layer(*this); + } + + Color_Base::RGB_Densities Magenta_Layer::to_rgb() const + { + return Color_Base::RGB_Densities(1, 1-m_dens, 1); + } + + + std::string Magenta_Layer::model() const + { + return "cmyk"; + } + + std::string Magenta_Layer::name() const + { + std::ostringstream nm; + nm << "m_proc_" << dtohex(m_dens); + return nm.str(); + } + + std::vector<double> Magenta_Layer::densities() const + { + std::vector<double> val(4); + val.at(0) = 0; + val.at(1) = rd(m_dens); + val.at(2) = 0; + val.at(3) = 0; + return val; + } + + + // Yellow_Layer + Yellow_Layer::Yellow_Layer(double arg) + : m_dens(clip_to_unit(arg)) { } + + // Return Yellow channel of color + Yellow_Layer& Yellow_Layer::filter(const Color_Base& color) + { + Color_Base::RGB_Densities s(color.to_rgb()); + if (Color(color).is_unset()) + s = Color_Base::RGB_Densities(1,1,1); + + m_dens = min(m_dens, 1-s.m_dens_blue); + return *this; + } + + Yellow_Layer* Yellow_Layer::clone() const + { + return new Yellow_Layer(*this); + } + + Color_Base::RGB_Densities Yellow_Layer::to_rgb() const + { + return Color_Base::RGB_Densities(1, 1, 1-m_dens); + } + + + std::string Yellow_Layer::model() const + { + return "cmyk"; + } + + std::string Yellow_Layer::name() const + { + std::ostringstream nm; + nm << "y_proc_" << dtohex(m_dens); + return nm.str(); + } + + std::vector<double> Yellow_Layer::densities() const + { + std::vector<double> val(4); + val.at(0) = 0; + val.at(1) = 0; + val.at(2) = rd(m_dens); + val.at(3) = 0; + return val; + } + + + // Black_Layer + Black_Layer::Black_Layer(double arg) + : m_dens(clip_to_unit(arg)) { } + + // Return Black channel of color + Black_Layer& Black_Layer::filter(const Color_Base& color) + { + Color_Base::RGB_Densities s(color.to_rgb()); + if (Color(color).is_unset()) + s = Color_Base::RGB_Densities(1,1,1); + + double c(1-s.m_dens_red), m(1-s.m_dens_green), y(1-s.m_dens_blue); + double k(min(min(c, m), y)); + + m_dens = min(m_dens, k); + return *this; + } + + Black_Layer* Black_Layer::clone() const + { + return new Black_Layer(*this); + } + + Color_Base::RGB_Densities Black_Layer::to_rgb() const + { + return Color_Base::RGB_Densities(1-m_dens, 1-m_dens, 1-m_dens); + } + + + std::string Black_Layer::model() const + { + return "cmyk"; + } + + std::string Black_Layer::name() const + { + std::ostringstream nm; + nm << "k_proc_" << dtohex(m_dens); + return nm.str(); + } + + std::vector<double> Black_Layer::densities() const + { + std::vector<double> val(4); + val.at(0) = 0; + val.at(1) = 0; + val.at(2) = 0; + val.at(3) = rd(m_dens); + return val; + } + + + // null operations + Cyan_Layer& Cyan_Layer::operator*= (double x) { return *this; } + Cyan_Layer& Cyan_Layer::blend(const Color_Base& col, double d) + { return *this; } + + Cyan_Layer& Cyan_Layer::superpose(const Color_Base& col) { return *this; } + Cyan_Layer& Cyan_Layer::invert() { return *this; } + + + Magenta_Layer& Magenta_Layer::operator*= (double x) { return *this; } + Magenta_Layer& Magenta_Layer::blend(const Color_Base& col, double d) + { return *this; } + + Magenta_Layer& Magenta_Layer::superpose(const Color_Base& col) { return *this; } + Magenta_Layer& Magenta_Layer::invert() { return *this; } + + + Yellow_Layer& Yellow_Layer::operator*= (double x) { return *this; } + Yellow_Layer& Yellow_Layer::blend(const Color_Base& col, double d) + { return *this; } + + Yellow_Layer& Yellow_Layer::superpose(const Color_Base& col) { return *this; } + Yellow_Layer& Yellow_Layer::invert() { return *this; } + + + Black_Layer& Black_Layer::operator*= (double x) { return *this; } + Black_Layer& Black_Layer::blend(const Color_Base& col, double d) + { return *this; } + + Black_Layer& Black_Layer::superpose(const Color_Base& col) { return *this; } + Black_Layer& Black_Layer::invert() { return *this; } + +} // end of namespace diff --git a/graphics/epix/Color_Sep.h b/graphics/epix/Color_Sep.h new file mode 100644 index 0000000000..599a14e039 --- /dev/null +++ b/graphics/epix/Color_Sep.h @@ -0,0 +1,133 @@ +/* + * Color_Sep.h -- ePiX CMYK Color separation classes + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * Last Change: September 13, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_COLOR_SEP +#define EPIX_COLOR_SEP +#include <string> +#include <vector> + +#include "Color_Base.h" + +namespace ePiX { + + class Cyan_Layer : public Color_Base { + public: + Cyan_Layer(double dens=1); + // Return Cyan channel of input + Cyan_Layer& filter(const Color_Base&); + + Cyan_Layer* clone() const; + RGB_Densities to_rgb() const; // returns RGB(0,1,1) + + std::string model() const; + std::string name() const; + std::vector<double> densities() const; + + private: + double m_dens; + + // null operations + Cyan_Layer& operator*= (double); + Cyan_Layer& blend(const Color_Base&, double); + Cyan_Layer& superpose(const Color_Base&); + Cyan_Layer& invert(); + }; + + class Magenta_Layer : public Color_Base { + public: + Magenta_Layer(double dens=1); + // Return Magenta channel of input + Magenta_Layer& filter(const Color_Base&); + + Magenta_Layer* clone() const; + RGB_Densities to_rgb() const; // returns RGB(0,1,1) + + std::string model() const; + std::string name() const; + std::vector<double> densities() const; + + private: + double m_dens; + + // null operations + Magenta_Layer& operator*= (double); + Magenta_Layer& blend(const Color_Base&, double); + Magenta_Layer& superpose(const Color_Base&); + Magenta_Layer& invert(); + }; + + class Yellow_Layer : public Color_Base { + public: + Yellow_Layer(double dens=1); + // Return Yellow channel of input + Yellow_Layer& filter(const Color_Base&); + + Yellow_Layer* clone() const; + RGB_Densities to_rgb() const; // returns RGB(0,1,1) + + std::string model() const; + std::string name() const; + std::vector<double> densities() const; + + private: + double m_dens; + + // null operations + Yellow_Layer& operator*= (double); + Yellow_Layer& blend(const Color_Base&, double); + Yellow_Layer& superpose(const Color_Base&); + Yellow_Layer& invert(); + }; + + class Black_Layer : public Color_Base { + public: + Black_Layer(double dens=1); + // Return Black channel of input + Black_Layer& filter(const Color_Base&); + + Black_Layer* clone() const; + RGB_Densities to_rgb() const; // returns RGB(0,1,1) + + std::string model() const; + std::string name() const; + std::vector<double> densities() const; + + private: + double m_dens; + + // null operations + Black_Layer& operator*= (double); + Black_Layer& blend(const Color_Base&, double); + Black_Layer& superpose(const Color_Base&); + Black_Layer& invert(); + }; +} // end of namespace +#endif /* EPIX_COLOR_SEP */ diff --git a/graphics/epix/Color_Utils.cc b/graphics/epix/Color_Utils.cc new file mode 100644 index 0000000000..0045aafcc3 --- /dev/null +++ b/graphics/epix/Color_Utils.cc @@ -0,0 +1,113 @@ +/* + * Color_Utils.cc -- Functions for manipulating color densities + * These functions are not normally available to users. + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * + * Last Change: September 14, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <sstream> +#include <cmath> + +// #include "constants.h" +// #include "functions.h" + +#include "Color_Utils.h" + +namespace ePiX { + + // Magic number: 8-bits per color channel + const int COLORS(0xFF); + + // Force double to [0,1] + double clip_to_unit(double t) + { + if (t < 0) return 0; + else if (t > 1) return 1; + else return t; + } + + double rd(double arg) // may assume arg in [0,1] + { + return floor(COLORS*arg)/COLORS; // round down to nearest 8-bit + } + + // represent a double in [0,1] by an 8-bit hex string + std::string dtohex(double arg) // assumes arg>0 + { + using std::ios_base; + int dens((int) floor(arg*COLORS)); + + std::ostringstream value; + value.setf(ios_base::hex, ios_base::basefield); + + if (dens <= 0xF) // pad + value << "0"; + + value << dens; + return value.str(); + } + + // saw2th:R -> [-2,2] is (1) a sawtooth function; (2) the identity on [-2,2] + double saw2th(double x) + { + return x - 4*floor((x+2)/4); + } + + /* + * clippy(x): + * 1.... ____ if (x >= 0) + * .\ /. . return x <= 1 ? x : 1; + * . \ / . . + * 0......\____/ . . else + * -2 -1 0 1 2 --> x return x >= -1 ? 0 : -1-x; + */ + double clippy(double x) + { + x = saw2th(x); + return (x >= 0) ? ( x <= 1 ? x : 1 ) : ( x >= -1 ? 0 : -1-x ); + } + + double make_r(double r, double g, double b) + { + return clip_to_unit(clippy( r) + clippy(-g) + clippy(-b)); + } + + double make_g(double r, double g, double b) + { + return clip_to_unit(clippy(-r) + clippy( g) + clippy(-b)); + } + + double make_b(double r, double g, double b) + { + return clip_to_unit(clippy(-r) + clippy(-g) + clippy( b)); + } +} // end of namespace diff --git a/graphics/epix/Color_Utils.h b/graphics/epix/Color_Utils.h new file mode 100644 index 0000000000..9dc54f92c7 --- /dev/null +++ b/graphics/epix/Color_Utils.h @@ -0,0 +1,66 @@ +/* + * Color_Utils.h -- Functions for manipulating color densities + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * + * Last Change: September 14, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_COLOR_UTILS +#define EPIX_COLOR_UTILS + +#include <string> + +namespace ePiX { + + double clip_to_unit(double t); // 0 if t<0, 1 if t>1, t otherwise + + double rd(double); // assumes arg is in [0,1] + + // represent a double in [0,1] by an 8-bit hex string + std::string dtohex(double arg); // assumes arg>0 + + // saw2th:R -> [-2,2] is (1) a sawtooth function; (2) the identity on [-2,2] + double saw2th(double x); + + /* + * clippy(x): + * 1.... ____ if (x >= 0) + * .\ /. . return x <= 1 ? x : 1; + * . \ / . . + * 0......\____/ . . else + * -2 -1 0 1 2 --> x return x >= -1 ? 0 : -1-x; + */ + double clippy(double x); + + double make_r(double r, double g, double b); + double make_g(double r, double g, double b); + double make_b(double r, double g, double b); +} // end of namespace + +#endif /* EPIX_COLOR_UTILS */ diff --git a/graphics/epix/INSTALL b/graphics/epix/INSTALL new file mode 100644 index 0000000000..fb13967718 --- /dev/null +++ b/graphics/epix/INSTALL @@ -0,0 +1,179 @@ +ePiX-1.2 -- INSTALL + +Last Change: September 12, 2007 + +Please consult the following files as appropriate: + +INSTALL (this file) -- Detailed installation instructions +NEWS -- Recent major changes (see ChangeLog for code changes) +README -- General overview and information + + +CONVENTIONS + +Lines starting with a "%" denote commands typed at a shell prompt. +Lines starting with a "#" denote commands run as root. +Don't type the prompt characters "%" or "#". :) + +"$(prefix)" stands for the complete path to the install directory, +e.g. "/usr/local" or "/home/pootle/epix". + + +DEPENDENCIES + +The following software must be installed on your system in order for +you to use ePiX: + + * The GNU shell, bash + * A C++ compiler and development libraries, preferably g++ (> 3.2) + * GhostScript, ImageMagick, and teTeX + * GNU binutils, textutils, and fileutils (ar, sed, grep, ln, rm...) + +Please consult your system documentation for information on installing +these components. The POST-INSTALL file contains potentially helpful +information, as well. The manual contains more detailed instructions +for Windows (Cygwin) and Mac OS X (fink/fink commander) users. + + +INSTALLATION + +--- Synopsis --- + +(1) Unpack +(2) Configure: + +% ./configure [options] + +(3) Build: + +% make +% make install (may require system privileges) + + +--- Step-by-step Instructions --- + +(1) Unpack + + Tarballs are available gzip or bzip2 compressed. To unpack, use the + appropriate version number and tar options (z for .gz, j for .bz2, v + to see filenames unpacked): + +% tar -zxf epix-x.y.z.tar.gz + + or + +% tar -jxf epix-x.y.z.tar.bz2 + + If your "tar" doesn't understand decompression, do + +% gunzip -c epix-x.y.z.tar.gz | tar -xf - + + or + +% bzcat epix-x.y.z.tar.bz2 | tar -xf - + + + Change to the source directory: + +% cd epix-x.y.z + + +(2) Configure the package: + + Most users can run the command + +% ./configure + + To change the installation directory from the default (/usr/local) + to (say) your home directory, do + +% ./configure --prefix=${HOME} + + To list all options, run + +% ./configure --help + + +(3) Compile and install: + +% make + + Be sure you are using GNU make. If the build fails immediately with + an error about unexpected characters in the Makefile, speak to your + system administrator about availability of GNU make, or try running + the command "gmake". + + If there are no build errors, you're ready to install. + + You must have write permission in the install directory you selected + in step (2). If you have been logged on as yourself until now (a Very + Good Idea) and are installing in a system directory, do: + +% su +Password: <your root password> + +# make install + + (The root prompt on many systems is # rather than %.) If the install + succeeds, you're done: + +# exit + + If you are installing somewhere in your HOME directory, just type + +% make install + + +(4) Post-Install: + + Documentation is installed in $(prefix)/share/doc/epix, as compiled + files (ps, pdf, info) and tarred LaTeX sources. + + The directory $(prefix)/share/doc/epix/config contains two optional + files: Jay Belanger's emacs mode for working with ePiX files, and + completions for users of Ian MacDonald's bash completions package. + POST-INSTALL has instructions on installing and using these files. + + From the source directory, do + +% make clean + + to clean the source tree of compiled files. This command removes the + top-level Makefile. Run ./configure to re-create the Makefile if + necessary. + + +(5) Uninstalling: + + To remove a version of ePiX from your system, go to the directory + where the sources were unpacked, run ./config.status, log on as root + if necessary, and do: + +# make uninstall + + + Alternatively, remove the following files and directories manually, + replacing $(prefix) with the install path, e.g. "/usr/local". + +[] Shell scripts + $(prefix)/bin/{elaps,epix,flix,laps} + +[] Static libraries and shell code + $(prefix)/lib/epix/ + +[] Header files + $(prefix)/include/epix.h (user header) + $(prefix)/include/epix/ (devel headers) + +[] Configuration files, manuals, and samples + $(prefix)/share/doc/epix/ + + +--- Contact Information --- + +If you have questions, comments, suggestions, etc., please write to: + +Andrew D. ("Andy") Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> +Dept. of Mathematics and Computer Science +College of the Holy Cross +Worcester, MA, 01610-2395, USA diff --git a/graphics/epix/Makefile.am b/graphics/epix/Makefile.am new file mode 100644 index 0000000000..eada49e89c --- /dev/null +++ b/graphics/epix/Makefile.am @@ -0,0 +1,115 @@ +## epix-1.x Makefile.am for top-level directory +## +## Process this file with automake to produce Makefile.in + +#if BUILD_CONTRIB + # Must be in this order! +# MAYBE_DIRS = contrib contrib/doc +#endif + +# SUBDIRS = . samples doc $(MAYBE_DIRS) +SUBDIRS = . samples doc + +# Now stuff for this directory specifically + +bin_SCRIPTS = epix elaps flix laps + +pkglib_LIBRARIES = libepix.a +pkglib_DATA = epix-lib.sh +include_HEADERS = epix.h + +libepix_a_CXXSOURCES = active_screen.cc affine.cc angle_units.cc \ + arrow_data.cc arrow_style.cc axis.cc camera.cc circle.cc clipping.cc \ + Color_Base.cc Color.cc Color_CMY.cc Color_CMYK.cc Color_Gray.cc \ + Color_Neutral.cc Color_RGB.cc Color_Sep.cc Color_Utils.cc \ + cropping.cc curves.cc \ + data_bins.cc data_file.cc data_mask.cc domain.cc \ + eepic.cc facet.cc format.cc frac.cc frame.cc functions.cc \ + geometry.cc glyph.cc halfspace.cc hatching.cc \ + intersections.cc interval.cc label_data.cc label_style.cc \ + legend.cc legend_item.cc legend_tile.cc \ + length.cc lens.cc markers.cc marker_style.cc \ + mask_diamond.cc mask_ellipse.cc mask_rectangle.cc \ + paint_style.cc pairs.cc path.cc path_data.cc \ + path_style.cc pen_arrow.cc pen_data.cc pen_fill.cc pen_line.cc \ + picture.cc picture_data.cc plane.cc plots.cc pst.cc \ + screen.cc screen_crop.cc screen_data.cc screen_mask.cc \ + segment.cc spline.cc sphere.cc state.cc surface.cc tikz.cc tile.cc \ + triples.cc utils.cc verbatim.cc +# polygon.cc + +libepix_a_HDRS = $(libepix_a_CXXSOURCES:.cc=.h) constants.h \ + crop_algorithms.h deriv.h edge_data.h enums.h errors.h \ + map.h plot_algorithms.h spline_data.h + +libepix_a_SOURCES = $(libepix_a_CXXSOURCES) $(libepix_a_HDRS) + +libepix_a_LIBADD = $(libepix_a_CXXSOURCES:.cc=.o) + +pkginclude_HEADERS = $(libepix_a_HDRS) + +man_MANS = epix.1 elaps.1 flix.1 laps.1 + +if ENABLE_EPIX_EL + EPIX_EL = epix.el +endif + +EPIX_CONFFILES = bash_completions $(EPIX_EL) + +EPIX_NOTEFILES = AUTHORS BUGS ChangeLog COPYING INSTALL NEWS POST-INSTALL \ + README THANKS VERSION + +EXTRA_DIST = $(bin_SCRIPTS) $(man_MANS) $(EPIX_CONFFILES) $(EPIX_NOTEFILES) \ + $(pkgdata_DATA) + +CLEANFILES = *~ $(libepix_a_OBJECTS) $(bin_SCRIPTS) $(bin_SCRIPTS:=-local) \ + epix.h epix.1 epix.el + +# Headers +epix.h: $(libepix_a_HDRS) + ./make_header + +# Scripts; we create local variants which will work during the build process +epix elaps flix laps: %: %.in epix.el + sed -e 's%^#! /bin/bash%#! $(BASH_PATH)%;' \ + -e 's%@bindir\@%$(bindir)%;' \ + -e 's%@pkglibdir\@%$(pkglibdir)%;' \ + -e 's%@includedir\@%$(includedir)%;' \ + -e 's%@RUNTIME_COMPILER\@%$(RUNTIME_COMPILER)%;' $< > $@ + sed -e 's%^#! /bin/bash%#! $(BASH_PATH)%;' \ + -e 's%@bindir\@%$(CURDIR)%;' \ + -e 's%@pkglibdir\@%$(CURDIR)%;' \ + -e 's%@includedir\@%$(CURDIR)%;' \ + -e 's%@RUNTIME_COMPILER\@%$(CXX)%;' $< > $@-local + chmod a+x $@ $@-local + +# libepix.a +libepix.a: $(libepix_a_OBJECTS) + ar -ru libepix.a $(libepix_a_OBJECTS) + $(RANLIB) libepix.a + +# object file dependencies +$(libepix_a_LIBADD): %.o: %.cc %.h + +# Manpage +epix.1: epix.1.in + sed -e 's%@docdir\@%$(docdir)%;' $< > $@ + +# emacs mode +epix.el: epix.el.in + sed -e 's%@docdir\@%$(docdir)%;' $< > $@ + +# Extra things to install +install-data-local: + @echo; echo "Installing notes and configuration files" + ./mkinstalldirs $(DESTDIR)$(docdir)/notes $(DESTDIR)$(docdir)/config + $(INSTALL_DATA) $(EPIX_NOTEFILES) $(DESTDIR)$(docdir)/notes + $(INSTALL_DATA) $(EPIX_CONFFILES) $(DESTDIR)$(docdir)/config + +# This is being installed by install-exec, but should not be executable +install-exec-local: install-pkglibDATA + chmod a-x $(DESTDIR)$(pkglibdir)/epix-lib.sh + +uninstall-local: + -rm -rf $(DESTDIR)$(docdir)/notes $(DESTDIR)$(docdir)/config + -rmdir $(DESTDIR)$(docdir) diff --git a/graphics/epix/Makefile.in b/graphics/epix/Makefile.in new file mode 100644 index 0000000000..7aee503276 --- /dev/null +++ b/graphics/epix/Makefile.in @@ -0,0 +1,1025 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = . +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = . +DIST_COMMON = README $(am__configure_deps) $(include_HEADERS) \ + $(pkginclude_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \ + ChangeLog INSTALL NEWS THANKS TODO config.guess config.sub \ + depcomp install-sh missing mkinstalldirs +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno configure.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(pkglibdir)" \ + "$(DESTDIR)$(includedir)" "$(DESTDIR)$(pkgincludedir)" +pkglibLIBRARIES_INSTALL = $(INSTALL_DATA) +LIBRARIES = $(pkglib_LIBRARIES) +AR = ar +ARFLAGS = cru +libepix_a_AR = $(AR) $(ARFLAGS) +am__DEPENDENCIES_1 = active_screen.o affine.o angle_units.o \ + arrow_data.o arrow_style.o axis.o camera.o circle.o clipping.o \ + Color_Base.o Color.o Color_CMY.o Color_CMYK.o Color_Gray.o \ + Color_Neutral.o Color_RGB.o Color_Sep.o Color_Utils.o \ + cropping.o curves.o data_bins.o data_file.o data_mask.o \ + domain.o eepic.o facet.o format.o frac.o frame.o functions.o \ + geometry.o glyph.o halfspace.o hatching.o intersections.o \ + interval.o label_data.o label_style.o legend.o legend_item.o \ + legend_tile.o length.o lens.o markers.o marker_style.o \ + mask_diamond.o mask_ellipse.o mask_rectangle.o paint_style.o \ + pairs.o path.o path_data.o path_style.o pen_arrow.o pen_data.o \ + pen_fill.o pen_line.o picture.o picture_data.o plane.o plots.o \ + pst.o screen.o screen_crop.o screen_data.o screen_mask.o \ + segment.o spline.o sphere.o state.o surface.o tikz.o tile.o \ + triples.o utils.o verbatim.o +libepix_a_DEPENDENCIES = $(am__DEPENDENCIES_1) +am__objects_1 = active_screen.$(OBJEXT) affine.$(OBJEXT) \ + angle_units.$(OBJEXT) arrow_data.$(OBJEXT) \ + arrow_style.$(OBJEXT) axis.$(OBJEXT) camera.$(OBJEXT) \ + circle.$(OBJEXT) clipping.$(OBJEXT) Color_Base.$(OBJEXT) \ + Color.$(OBJEXT) Color_CMY.$(OBJEXT) Color_CMYK.$(OBJEXT) \ + Color_Gray.$(OBJEXT) Color_Neutral.$(OBJEXT) \ + Color_RGB.$(OBJEXT) Color_Sep.$(OBJEXT) Color_Utils.$(OBJEXT) \ + cropping.$(OBJEXT) curves.$(OBJEXT) data_bins.$(OBJEXT) \ + data_file.$(OBJEXT) data_mask.$(OBJEXT) domain.$(OBJEXT) \ + eepic.$(OBJEXT) facet.$(OBJEXT) format.$(OBJEXT) \ + frac.$(OBJEXT) frame.$(OBJEXT) functions.$(OBJEXT) \ + geometry.$(OBJEXT) glyph.$(OBJEXT) halfspace.$(OBJEXT) \ + hatching.$(OBJEXT) intersections.$(OBJEXT) interval.$(OBJEXT) \ + label_data.$(OBJEXT) label_style.$(OBJEXT) legend.$(OBJEXT) \ + legend_item.$(OBJEXT) legend_tile.$(OBJEXT) length.$(OBJEXT) \ + lens.$(OBJEXT) markers.$(OBJEXT) marker_style.$(OBJEXT) \ + mask_diamond.$(OBJEXT) mask_ellipse.$(OBJEXT) \ + mask_rectangle.$(OBJEXT) paint_style.$(OBJEXT) pairs.$(OBJEXT) \ + path.$(OBJEXT) path_data.$(OBJEXT) path_style.$(OBJEXT) \ + pen_arrow.$(OBJEXT) pen_data.$(OBJEXT) pen_fill.$(OBJEXT) \ + pen_line.$(OBJEXT) picture.$(OBJEXT) picture_data.$(OBJEXT) \ + plane.$(OBJEXT) plots.$(OBJEXT) pst.$(OBJEXT) screen.$(OBJEXT) \ + screen_crop.$(OBJEXT) screen_data.$(OBJEXT) \ + screen_mask.$(OBJEXT) segment.$(OBJEXT) spline.$(OBJEXT) \ + sphere.$(OBJEXT) state.$(OBJEXT) surface.$(OBJEXT) \ + tikz.$(OBJEXT) tile.$(OBJEXT) triples.$(OBJEXT) \ + utils.$(OBJEXT) verbatim.$(OBJEXT) +am__objects_2 = +am__objects_3 = $(am__objects_2) +am_libepix_a_OBJECTS = $(am__objects_1) $(am__objects_3) +libepix_a_OBJECTS = $(am_libepix_a_OBJECTS) +binSCRIPT_INSTALL = $(INSTALL_SCRIPT) +SCRIPTS = $(bin_SCRIPTS) +DEFAULT_INCLUDES = -I. -I$(srcdir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libepix_a_SOURCES) +DIST_SOURCES = $(libepix_a_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-exec-recursive install-info-recursive \ + install-recursive installcheck-recursive installdirs-recursive \ + pdf-recursive ps-recursive uninstall-info-recursive \ + uninstall-recursive +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +pkglibDATA_INSTALL = $(INSTALL_DATA) +DATA = $(pkglib_DATA) +includeHEADERS_INSTALL = $(INSTALL_HEADER) +pkgincludeHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(include_HEADERS) $(pkginclude_HEADERS) +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASH_PATH = @BASH_PATH@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_EPIX_EL_FALSE = @ENABLE_EPIX_EL_FALSE@ +ENABLE_EPIX_EL_TRUE = @ENABLE_EPIX_EL_TRUE@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RUNTIME_COMPILER = @RUNTIME_COMPILER@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +# MAYBE_DIRS = contrib contrib/doc +#endif + +# SUBDIRS = . samples doc $(MAYBE_DIRS) +SUBDIRS = . samples doc + +# Now stuff for this directory specifically +bin_SCRIPTS = epix elaps flix laps +pkglib_LIBRARIES = libepix.a +pkglib_DATA = epix-lib.sh +include_HEADERS = epix.h +libepix_a_CXXSOURCES = active_screen.cc affine.cc angle_units.cc \ + arrow_data.cc arrow_style.cc axis.cc camera.cc circle.cc clipping.cc \ + Color_Base.cc Color.cc Color_CMY.cc Color_CMYK.cc Color_Gray.cc \ + Color_Neutral.cc Color_RGB.cc Color_Sep.cc Color_Utils.cc \ + cropping.cc curves.cc \ + data_bins.cc data_file.cc data_mask.cc domain.cc \ + eepic.cc facet.cc format.cc frac.cc frame.cc functions.cc \ + geometry.cc glyph.cc halfspace.cc hatching.cc \ + intersections.cc interval.cc label_data.cc label_style.cc \ + legend.cc legend_item.cc legend_tile.cc \ + length.cc lens.cc markers.cc marker_style.cc \ + mask_diamond.cc mask_ellipse.cc mask_rectangle.cc \ + paint_style.cc pairs.cc path.cc path_data.cc \ + path_style.cc pen_arrow.cc pen_data.cc pen_fill.cc pen_line.cc \ + picture.cc picture_data.cc plane.cc plots.cc pst.cc \ + screen.cc screen_crop.cc screen_data.cc screen_mask.cc \ + segment.cc spline.cc sphere.cc state.cc surface.cc tikz.cc tile.cc \ + triples.cc utils.cc verbatim.cc + +# polygon.cc +libepix_a_HDRS = $(libepix_a_CXXSOURCES:.cc=.h) constants.h \ + crop_algorithms.h deriv.h edge_data.h enums.h errors.h \ + map.h plot_algorithms.h spline_data.h + +libepix_a_SOURCES = $(libepix_a_CXXSOURCES) $(libepix_a_HDRS) +libepix_a_LIBADD = $(libepix_a_CXXSOURCES:.cc=.o) +pkginclude_HEADERS = $(libepix_a_HDRS) +man_MANS = epix.1 elaps.1 flix.1 laps.1 +@ENABLE_EPIX_EL_TRUE@EPIX_EL = epix.el +EPIX_CONFFILES = bash_completions $(EPIX_EL) +EPIX_NOTEFILES = AUTHORS BUGS ChangeLog COPYING INSTALL NEWS POST-INSTALL \ + README THANKS VERSION + +EXTRA_DIST = $(bin_SCRIPTS) $(man_MANS) $(EPIX_CONFFILES) $(EPIX_NOTEFILES) \ + $(pkgdata_DATA) + +CLEANFILES = *~ $(libepix_a_OBJECTS) $(bin_SCRIPTS) $(bin_SCRIPTS:=-local) \ + epix.h epix.1 epix.el + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .cc .o .obj +am--refresh: + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ + cd $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +install-pkglibLIBRARIES: $(pkglib_LIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(pkglibdir)" || $(mkdir_p) "$(DESTDIR)$(pkglibdir)" + @list='$(pkglib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(pkglibLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(pkglibLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(pkglibdir)/$$f"; \ + else :; fi; \ + done + @$(POST_INSTALL) + @list='$(pkglib_LIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + p=$(am__strip_dir) \ + echo " $(RANLIB) '$(DESTDIR)$(pkglibdir)/$$p'"; \ + $(RANLIB) "$(DESTDIR)$(pkglibdir)/$$p"; \ + else :; fi; \ + done + +uninstall-pkglibLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_LIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(pkglibdir)/$$p'"; \ + rm -f "$(DESTDIR)$(pkglibdir)/$$p"; \ + done + +clean-pkglibLIBRARIES: + -test -z "$(pkglib_LIBRARIES)" || rm -f $(pkglib_LIBRARIES) +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f $$d$$p; then \ + f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ + echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \ + else :; fi; \ + done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_Base.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_CMY.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_CMYK.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_Gray.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_Neutral.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_RGB.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_Sep.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color_Utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/active_screen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/affine.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/angle_units.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arrow_data.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arrow_style.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/axis.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camera.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/circle.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clipping.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cropping.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curves.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data_bins.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data_file.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data_mask.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/domain.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eepic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/facet.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/format.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frac.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/functions.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geometry.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glyph.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/halfspace.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hatching.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intersections.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interval.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/label_data.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/label_style.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/legend.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/legend_item.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/legend_tile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/length.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lens.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/marker_style.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/markers.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mask_diamond.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mask_ellipse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mask_rectangle.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paint_style.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pairs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path_data.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/path_style.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pen_arrow.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pen_data.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pen_fill.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pen_line.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/picture.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/picture_data.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plane.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plots.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pst.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/screen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/screen_crop.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/screen_data.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/screen_mask.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/segment.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sphere.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/surface.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tikz.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triples.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/verbatim.Po@am__quote@ + +.cc.o: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +uninstall-info-am: +install-man1: $(man1_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man1dir)" || $(mkdir_p) "$(DESTDIR)$(man1dir)" + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 1*) ;; \ + *) ext='1' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \ + done +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 1*) ;; \ + *) ext='1' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \ + rm -f "$(DESTDIR)$(man1dir)/$$inst"; \ + done +install-pkglibDATA: $(pkglib_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkglibdir)" || $(mkdir_p) "$(DESTDIR)$(pkglibdir)" + @list='$(pkglib_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(pkglibDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkglibdir)/$$f'"; \ + $(pkglibDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkglibdir)/$$f"; \ + done + +uninstall-pkglibDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkglib_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ + rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ + done +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ + $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ + rm -f "$(DESTDIR)$(includedir)/$$f"; \ + done +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(pkgincludedir)" || $(mkdir_p) "$(DESTDIR)$(pkgincludedir)" + @list='$(pkginclude_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(pkgincludeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgincludedir)/$$f'"; \ + $(pkgincludeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgincludedir)/$$f"; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(pkgincludedir)/$$f'"; \ + rm -f "$(DESTDIR)$(pkgincludedir)/$$f"; \ + done + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + mkdir $(distdir) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(mkdir_p) "$(distdir)/$$subdir" \ + || exit 1; \ + distdir=`$(am__cd) $(distdir) && pwd`; \ + top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$top_distdir" \ + distdir="$$distdir/$$subdir" \ + distdir) \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(LIBRARIES) $(SCRIPTS) $(MANS) $(DATA) $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(pkgincludedir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-pkglibLIBRARIES mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +info: info-recursive + +info-am: + +install-data-am: install-data-local install-includeHEADERS install-man \ + install-pkgincludeHEADERS + +install-exec-am: install-binSCRIPTS install-exec-local \ + install-pkglibDATA install-pkglibLIBRARIES + +install-info: install-info-recursive + +install-man: install-man1 + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binSCRIPTS uninstall-includeHEADERS \ + uninstall-info-am uninstall-local uninstall-man \ + uninstall-pkgincludeHEADERS uninstall-pkglibDATA \ + uninstall-pkglibLIBRARIES + +uninstall-info: uninstall-info-recursive + +uninstall-man: uninstall-man1 + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \ + check-am clean clean-generic clean-pkglibLIBRARIES \ + clean-recursive ctags ctags-recursive dist dist-all dist-bzip2 \ + dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \ + distclean-compile distclean-generic distclean-recursive \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-binSCRIPTS install-data install-data-am \ + install-data-local install-exec install-exec-am \ + install-exec-local install-includeHEADERS install-info \ + install-info-am install-man install-man1 \ + install-pkgincludeHEADERS install-pkglibDATA \ + install-pkglibLIBRARIES install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic maintainer-clean-recursive \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-binSCRIPTS \ + uninstall-includeHEADERS uninstall-info-am uninstall-local \ + uninstall-man uninstall-man1 uninstall-pkgincludeHEADERS \ + uninstall-pkglibDATA uninstall-pkglibLIBRARIES + + +#if BUILD_CONTRIB + # Must be in this order! + +# Headers +epix.h: $(libepix_a_HDRS) + ./make_header + +# Scripts; we create local variants which will work during the build process +epix elaps flix laps: %: %.in epix.el + sed -e 's%^#! /bin/bash%#! $(BASH_PATH)%;' \ + -e 's%@bindir\@%$(bindir)%;' \ + -e 's%@pkglibdir\@%$(pkglibdir)%;' \ + -e 's%@includedir\@%$(includedir)%;' \ + -e 's%@RUNTIME_COMPILER\@%$(RUNTIME_COMPILER)%;' $< > $@ + sed -e 's%^#! /bin/bash%#! $(BASH_PATH)%;' \ + -e 's%@bindir\@%$(CURDIR)%;' \ + -e 's%@pkglibdir\@%$(CURDIR)%;' \ + -e 's%@includedir\@%$(CURDIR)%;' \ + -e 's%@RUNTIME_COMPILER\@%$(CXX)%;' $< > $@-local + chmod a+x $@ $@-local + +# libepix.a +libepix.a: $(libepix_a_OBJECTS) + ar -ru libepix.a $(libepix_a_OBJECTS) + $(RANLIB) libepix.a + +# object file dependencies +$(libepix_a_LIBADD): %.o: %.cc %.h + +# Manpage +epix.1: epix.1.in + sed -e 's%@docdir\@%$(docdir)%;' $< > $@ + +# emacs mode +epix.el: epix.el.in + sed -e 's%@docdir\@%$(docdir)%;' $< > $@ + +# Extra things to install +install-data-local: + @echo; echo "Installing notes and configuration files" + ./mkinstalldirs $(DESTDIR)$(docdir)/notes $(DESTDIR)$(docdir)/config + $(INSTALL_DATA) $(EPIX_NOTEFILES) $(DESTDIR)$(docdir)/notes + $(INSTALL_DATA) $(EPIX_CONFFILES) $(DESTDIR)$(docdir)/config + +# This is being installed by install-exec, but should not be executable +install-exec-local: install-pkglibDATA + chmod a-x $(DESTDIR)$(pkglibdir)/epix-lib.sh + +uninstall-local: + -rm -rf $(DESTDIR)$(docdir)/notes $(DESTDIR)$(docdir)/config + -rmdir $(DESTDIR)$(docdir) +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/graphics/epix/NEWS b/graphics/epix/NEWS new file mode 100644 index 0000000000..c9b7c4ddd6 --- /dev/null +++ b/graphics/epix/NEWS @@ -0,0 +1,91 @@ +ePiX-1.2 -- NEWS + +Last Change: September 12, 2007 + +Please consult the following files as appropriate: + +INSTALL -- Detailed installation instructions +NEWS (this file) -- Recent major changes (see ChangeLog for code changes) +README -- General overview and information + + +If you are new to ePiX, you may safely ignore this file. + +OVERVIEW + +ePiX 1.2.x has been written almost entirely from scratch. The drawing +model is unchanged, and some old files will compile as is, but there +are a few changes of syntax. + + +SYNTAX CHANGES + +Generally, global variables have been deprecated or removed, and +should be replaced by function calls in new files. + +* (Recommended) The global size variables x_min, x_max, y_min, y_max, + x_size, and y_size should be replaced by the function calls xmin(), + etc. (No underscores.) + +* (Mandatory) The global variable tix in a flix file must be + manipulated through the function tix(). + +* (Suggested) The camera may be accessed through the function + the_camera(). + +* (Mandatory) Camera orientation is controlled with functions named + tilt, pan, and roll; each rotates the camera about an axis through + the viewpoint, not through the target. + +* (Suggested) The size and bounding box may be given in one command, + such as picture(P(-1,0), P(1,1), "4x3in"). The old syntax will be + retained indefinitely. + +* (Mandatory) The command use_pstricks() is obsolete. + +* (Mandatory) Deprecated aliases no longer exist: triple (for the P + class), D (for Deriv), and I (for Integral). Lowercase trig function + names conflicted with the standard namespace and have been removed. + +* (Mandatory) The geometric object commands (circle, plane, segment, + sphere) which used to create class objects now perform drawing. The + classes are available with capitalized names (Circle, Plane, + Segment, Sphere). + + +NEW FEATURES + +* Output is cleanly separated from the internal representation. + Figures may be written with a choice of macros---PSTricks, tikz, and + eepic at present---and new output types are easily coded so long as + the format supports arbitrary line segments, color, and the ability + to place a LaTeX box at a specified location. + +* Colors are a manipulable data type, available in RGB, CMY, CMYK, and + Gray models. xcolor-style operations, such as color model + conversion, blending, superposition, and inversion are provided. + + The camera has a filter which affects the colors of all scene + elements. Filters performing CMYK separation are provided. + +* Color filling is controlled with declarations, similarly to line + colors in ePiX 1.0.x. Arrows and markers of type spot, dot, ddot, + and~circ are now colored like other markers. Shaded surfaces may be + colored with position-dependent functions. + + If a figure contains many shaded elements, a color-capable output + format (PSTricks or tikz) should be used for efficiency. Filled + regions are implemented as fine hatching in eepic. + +* An axis class provides coordinate axes with labels in a variety of + styles: decimals or scientific notation of specified precision, + fractions, trig fractions, logarithmic labels in arbitrary (integer) + base, and user-supplied styles. + +* ePiX 1.2.x performs page layout. Sub-figures may be manipulated + flexibly. The sample files give several applications. + +* Non-member intersection operators for Circles, Planes, Segments, and + Spheres are provided. A ``non-generic'' intersection does not + throw an exception, but instead returns an undrawable ``malformed'' + object. diff --git a/graphics/epix/POST-INSTALL b/graphics/epix/POST-INSTALL new file mode 100644 index 0000000000..5dec6e6970 --- /dev/null +++ b/graphics/epix/POST-INSTALL @@ -0,0 +1,123 @@ +ePiX-1.2 -- POST-INSTALL + +Last Change: September 12, 2007 + +This file contains post-install configuration instructions for users. +Please consult the following files as appropriate: + +INSTALL -- Detailed installation instructions +NEWS -- Recent major changes (see ChangeLog for code changes) +README -- General overview and information + + +CONVENTIONS + +Lines starting with a "%" denote commands typed at a shell prompt. +Lines starting with a "#" denote commands run as root. +Don't type the prompt characters "%" or "#". :) + +"$(prefix)" stands for the complete path to the install directory, +e.g. "/usr/local" or "/home/pootle/epix". + +Files mentioned below are installed in $(prefix)/share/doc/epix/config/ + + +PROGRAMMABLE COMPLETION in bash + +If you type "epix c[TAB]", bash normally displays all files and +directories whose name starts with "c". If programmable completion is +enabled, bash will show only those files whose name starts with "c" +*and* whose extension is that of an epix input file. + +Programmable completion in bash is available only with Version 2.05 and +later, and you must install Ian MacDonald's bash completion package. Do +a search for "bash programmable completion" at + + http://freshmeat.net + +The file "$(prefix)/share/doc/epix/config/bash_completions" contains +programmable completion code for ePiX's shell scripts. These lines +should be put into your bash config file (~/.bashrc) just after the +line that includes the system-wide bash completion config file (q.v.). + + +EMACS MODE + +Jay Belanger has kindly provided an emacs mode (epix.el) for working +with epix source files. To use epix mode, put a copy of the file +"epix.el" in your emacs load path; under GNU/Linux, an appropriate +system directory is /usr/share/emacs. If you are not the superuser, +use a directory such as ${HOME}/share/emacs: + +% mkdir -p ~/share/emacs +% cp $(prefix)/share/doc/epix/config/epix.el ~/share/emacs/ + +Then add these lines to your .emacs file: +---(snip)--- +(setq load-path (cons "~/share/emacs/" load-path)) +(setq auto-mode-alist (cons '("\\.xp" . epix-mode) auto-mode-alist)) +(autoload 'epix-mode "epix" "ePiX editing mode" t) +(setq epix-mark-files-as-epix t) +(setq epix-insert-template-in-empty-buffer t) + +(autoload 'flix-mode "epix" "ePiX editing mode" t) +(setq auto-mode-alist (cons '("\\.flx" . flix-mode) auto-mode-alist)) +---(snip)--- + +Change "~/share/emacs/" in the first line as appropriate. If you open +a new file with extension ".xp" or ".flx", emacs will automatically +insert a matching preamble template and enter epix-mode or flix-mode, +respectively. You can then compile and preview ePiX source files with +emacs commands, or read the info file; please see epix.el for more +details. + +If necessary (for instance, if your source file must have extension +".cc" for some reason), you can enter epix mode manually by typing + +M-x epix-mode + +in emacs. (The notation "M-x" means the emacs META key, usually ESC, +followed by "x".) + + +OTHER CONFIG FILES + +The files ~/.dvipsrc and ~/.epixrc affect the behavior of epix, elaps, +and laps. The use of .epixrc is documented in the tutorial. Neither +file is required in order to use ePiX. + + +SETTING the PATH + +If you've installed ePiX but receive a "command not found" error +message when trying to compile figures, you probably need to set your +PATH, the shell environment variable listing the directories to be +searched for executable code. + +As above, $(prefix) stands for the directory in which ePiX has been +installed and "%" denotes a prompt. Below, $(prefix) must be replaced +with the actual path. Issue the command + +% echo $PATH + +If $(prefix)/bin is not shown, you must determine what shell you're +using and edit the appropriate shell configuration file. Do + +% ? + +If the response is: Put this line: Into the file: +------------------- -------------- -------------- +bash: ?: command not found export PATH=$PATH:$(prefix)/bin ~/.bashrc + +?: no match setenv PATH $PATH:$(prefix)/bin ~/.cshrc + +In the first case, do not put spaces around the equals sign. If the +response is something else, please consult your system administrator +for assistance. + +Now re-load the appropriate configuration file and try an ePiX command: + +% source ~/.bashrc +% epix --help + +If this still doesn't work, please consult your system administrator. diff --git a/graphics/epix/README b/graphics/epix/README new file mode 100644 index 0000000000..91d8889ceb --- /dev/null +++ b/graphics/epix/README @@ -0,0 +1,139 @@ +ePiX -- README + +Last Change: September 12, 2007 + +Please consult the following files as appropriate: + +INSTALL -- Detailed installation instructions +NEWS -- Recent major changes (see ChangeLog for code changes) +README (this file) -- General overview and information + + +DESCRIPTION + +ePiX (pronounced like "epic" with a soft "k", playing on "TeX"), a +collection of command line utilities for *nix, creates mathematically +accurate figures, plots, and movies using easy-to-learn syntax. The +output is expressly designed for use with LaTeX. + +The user interface resembles that of LaTeX itself: You prepare a short +scene description in a text editor, then compile the input file into a +picture. LaTeX- and web-compatible output types include a LaTeX +picture-like environment written with PSTricks, tikz, or eepic macros; +vector images (eps, ps, and pdf); and bitmap images (png, mng, gif). + + +INSTALLATION + +Please see the "INSTALL" file. + + +OVERVIEW + +ePiX's command-line conversion utilities are + +* epix: ePiX to eepic + +* elaps: ePiX and eepic to eps or pdf + +* laps: (La)TeX to PostScript + +* flix: ePiX to png or mng + +Each script prints a detailed help message when invoked with the +option "-h" (help) + + +DOCUMENTATION + +ePiX documentation is installed in $(prefix)/share/doc/epix, by +default /usr/local/share/doc/epix. + +The manual, a complete description of ePiX's features and use, is +installed as PostScript (for printing), hyperlinked PDF (for online +reading), GNU info (for reference within emacs), and as LaTeX sources. + + +DEVELOPER FILES + +The header files are installed in $(pkgincludedir), by default +$(prefix)/include/epix. + + +INTERNET DOWNLOAD SITES + +* http://math.holycross.edu/~ahwang/epix/ePiX.html + + Links to currently available packages and documentation, general + information, sample images and animations, and summaries of the + latest developments. + + +* http://freshmeat.net/projects/epix + + Announcements of recent releases, project stats, and links. + + +* http://www.ctan.org/tex-archive/graphics/epix/ + + Stable releases with synchronized documentation. + + +* http://savannah.nongnu.org/cgi-bin/viewcvs/epix/1.2 + + The very latest source code by CVS. + + +As with all free (GPL) software, the source code can be obtained on a +floppy disk from the author by post ("snail mail"), in this case from: + +Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> +Dept. of Mathematics and Computer Science +College of the Holy Cross +Worcester, MA, 01610-2395, USA + + +PYEPIX + +Though ePiX can be compiled and run using CygWin, Windows users may be +more interested in Andrew Sterian's Pyepix package, an implementation +of ePiX-1.0.4 in Python. Pyepix is available from + + http://claymore.engineer.gvsu.edu/~steriana/Python/index.html + +and requires Python 2.2 or newer. + + +MAILING LIST + +There are two mailing lists, for users and for development issues. +Please visit + + http://savannah.nongnu.org/mail/?group=epix + +to subscribe. + + +COPYLEFT and DISTRIBUTION + +ePiX and its documentation are distributed under the terms of the GNU +GPL. This program and its documentation come with ABSOLUTELY NO +WARRANTY OF ANY KIND, INCLUDING ANY WARRANTY OF MERCHANTABILITY OR +FITNESS FOR A PARTICULAR PURPOSE. This is the same guarantee granted +by all common software, including expensive, proprietary software +whose quality you have no way to verify directly, and whose license +you tacitly accept merely by opening the package. + +Feedback about this program (suggestions for features, etc.) is +welcome. If you find this program useful, please consider making a +contribution to the Free Software Foundation; see + + http://www.fsf.org + + +--- Contact Information --- + +Andrew D. ("Andy") Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> +Dept. of Mathematics and Computer Science +College of the Holy Cross +Worcester, MA, 01610-2395, USA diff --git a/graphics/epix/THANKS b/graphics/epix/THANKS new file mode 100644 index 0000000000..49890d72bc --- /dev/null +++ b/graphics/epix/THANKS @@ -0,0 +1,122 @@ +ePiX -- THANKS + +ePiX is built on the work of many people (unfortunately, most of whom +I am unaware). A few of the obvious ones are, in alphabetical order: + +Donald E. Knuth TeX, and so much more +Conrad Kwok eepic + +Leslie Lamport LaTeX + +Tim Morgan tpic + +Piet van Oostrum eepic + +Sunil Podar the epic style + +Richard M. Stallman the GNU project + +Till Tantau pgf/tikz + +Herbert Voss PSTricks +Timothy Van Zandt + +---------------------------------------------------------------------- + +Special thanks to: For: + +Jay Belanger The emacs mode +Robin Blume-Kohout Design suggestions + +Svend Daugaard Pedersen Extended coordinate systems and plotting capability + +Julian Gilbey Getting ePiX to work with autoconf/automake +Guido Gonzato Creating and maintaining the RPM + +Marcus Hanwell Data plotting and manipulation code +Yvon Henel French translation of the manual + +Jean-Michel Sarlat http://melusine.eu.org/syracuse/epix/ +Andrew Sterian Pyepix and its Windows package + + +--- + +Ports contributors and maintainers: + +Crux: +Youn\`es Hafri http://yhafri.club.fr/crux/index.html + +Debian: http://packages.debian.org/unstable/tex/epix1 +Julian Gilbey + + +FreeBSD: http://www.freshports.org/graphics/epix/ +Tsuguru Kato + + +Gentoo: http://packages.gentoo.org/search/?sstring=epix +Markus Dittrich +Danny van Dyk +Christian Faulhammer +Olivier Fisette +Chris Gianelloni +Michael Hanselmann +Marcus Hanwell +David Holm +Peter Johanson +Patrick Kursawe +Tobias Scherbaum +Markus Ullmann + +T2: http://www.t2-project.org/packages/epix.html +Ren\'e Rebe + + +---------------------------------------------------------------------- + +Many thanks to the following people, who have helped publicize ePiX +or reported and/or patched bugs (in both code and documentation) + +<Anonymous> + +Maik Beckmann +Jay Belanger +Felipe Paulo Guazzi Bergo +Karl Berry +Robin Blume-Kohout + +Patrick Cousot + +Stephen Gibson +Julian Gilbey +Dov Grobgeld +Bob Grover + +Jim Hefferon +Yvon Henel +Hartmut Henkel + +Herng-Jeng Jou + +Walter A. Kehowski + +Jacques L'helgoual + +Kevin McKormick +Ross Moore + +Thorsten Riess + +Neel Smith +Michael Somos +Andrew Sterian + +Ryszard Tanas +Kai Trukenmueller + +Torbjorn Vik + +Wenguang Wang +Gabe Weaver +Mariusz Wodzicki diff --git a/graphics/epix/TODO b/graphics/epix/TODO new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/graphics/epix/TODO diff --git a/graphics/epix/VERSION b/graphics/epix/VERSION new file mode 100644 index 0000000000..6085e94650 --- /dev/null +++ b/graphics/epix/VERSION @@ -0,0 +1 @@ +1.2.1 diff --git a/graphics/epix/aclocal.m4 b/graphics/epix/aclocal.m4 new file mode 100644 index 0000000000..b6186f2ab8 --- /dev/null +++ b/graphics/epix/aclocal.m4 @@ -0,0 +1,879 @@ +# generated automatically by aclocal 1.9.6 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.9.6])]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 7 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 3 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.58])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +AC_DEFUN([AM_MAINTAINER_MODE], +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. +# +# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories +# created by `make install' are always world readable, even if the +# installer happens to have an overly restrictive umask (e.g. 077). +# This was a mistake. There are at least two reasons why we must not +# use `-m 0755': +# - it causes special bits like SGID to be ignored, +# - it may be too restrictive (some setups expect 775 directories). +# +# Do not use -m 0755 and let people choose whatever they expect by +# setting umask. +# +# We cannot accept any implementation of `mkdir' that recognizes `-p'. +# Some implementations (such as Solaris 8's) are not thread-safe: if a +# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' +# concurrently, both version can detect that a/ is missing, but only +# one can create it and the other will error out. Consequently we +# restrict ourselves to GNU make (using the --version option ensures +# this.) +AC_DEFUN([AM_PROG_MKDIR_P], +[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar <conftest.tar]) + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/graphics/epix/active_screen.cc b/graphics/epix/active_screen.cc new file mode 100644 index 0000000000..05fafc804e --- /dev/null +++ b/graphics/epix/active_screen.cc @@ -0,0 +1,80 @@ +/* + * active_screen.cc -- ePiX screen_broker class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.11 + * Last Change: August 15, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "screen.h" +#include "picture_data.h" +#include "picture.h" +#include "active_screen.h" + +namespace ePiX { + + screen_broker::screen_broker() + { + m_screens.push_front(&the_picture().the_canvas); + } + + screen* screen_broker::active() const + { + return *(m_screens.begin()); + } + + void screen_broker::push(screen& scr) + { + m_screens.push_front(&scr); + } + + screen* screen_broker::pop() + { + std::list<screen*>::const_iterator sp(m_screens.begin()); + + screen* val(*sp); + + if (++sp != m_screens.end()) + m_screens.pop_front(); + + return val; + } + + + // global functions + screen_broker& the_screen_stack() + { + static screen_broker* the_screen_broker(new screen_broker()); + return *the_screen_broker; + } + + screen* active_screen() + { + return the_screen_stack().active(); + } +} // end of namespace diff --git a/graphics/epix/active_screen.h b/graphics/epix/active_screen.h new file mode 100644 index 0000000000..79bb909063 --- /dev/null +++ b/graphics/epix/active_screen.h @@ -0,0 +1,72 @@ +/* + * active_screen.h -- ePiX screen_broker class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.11 + * Last Change: August 15, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * A screen_broker is a simple stack of screen*, permitting client code + * to activate a screen then restore the state later. No attempt is made + * to handle concurrent threads, but the global "deactivate" function + * in picture.h prints a warning if its argument is not active. + */ +#ifndef EPIX_ACTIVE_SCREEN +#define EPIX_ACTIVE_SCREEN + +#include <list> + +namespace ePiX { + + class screen; + + class screen_broker { + public: + screen_broker(); + + // no need for destructor; we don't manage resources + + screen* active() const; + void push(screen&); + screen* pop(); + + private: + std::list<screen*> m_screens; + + // forbid copying + screen_broker(const screen_broker&); + screen_broker& operator= (const screen_broker&); + }; + + screen_broker& the_screen_stack(); + screen* active_screen(); +} // end of namespace + +#endif /* EPIX_ACTIVE_SCREEN */ diff --git a/graphics/epix/affine.cc b/graphics/epix/affine.cc new file mode 100644 index 0000000000..cc28e40cbf --- /dev/null +++ b/graphics/epix/affine.cc @@ -0,0 +1,300 @@ +/* + * affine.cc -- ePiX::affine class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.21 + * Last Change: September 23, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> + +#include "errors.h" +#include "constants.h" + +#include "pairs.h" +#include "triples.h" +#include "functions.h" + +#include "affine.h" + +namespace ePiX { + + // rotate/reflect about (0,0) + static pair __epix_rotate(double Cs, double Sn, const pair& arg) + { + double x(arg.x1()), y(arg.x2()); + return pair(Cs*x - Sn*y, Sn*x + Cs*y); + } + + static pair __epix_reflect(double Cs, double Sn, const pair& arg) + { + double x(arg.x1()), y(arg.x2()); + return pair(Cs*x + Sn*y, Sn*x - Cs*y); + } + + // identity + affine::affine() + : m_00(0,0), m_10(1,0), m_01(0,1) { } + + // images of (1,0), (0,1), (0,0) + affine::affine(const pair& pr1, const pair& pr2, const pair& loc) + : m_00(loc), m_10(pr1), m_01(pr2) { } + + affine::affine(const P& pr1, const P& pr2, const P& loc) + : m_00(loc.x1(), loc.x2()), + m_10(pr1.x1(), pr1.x2()), + m_01(pr2.x1(), pr2.x2()) { } + + affine& affine::shift(const pair& arg) + { + m_00 += arg; + m_10 += arg; + m_01 += arg; + + return *this; + } + + affine& affine::shift(const P& arg) + { + return shift(pair(arg.x1(), arg.x2())); + } + + affine& affine::rotate(double theta, const pair& ctr) + { + const double Cs(Cos(theta)); + const double Sn(Sin(theta)); + + // shift + m_00 -= ctr; + m_10 -= ctr; + m_01 -= ctr; + + // rotate about origin and shift back + m_00 = __epix_rotate(Cs, Sn, m_00) + ctr; + m_10 = __epix_rotate(Cs, Sn, m_10) + ctr; + m_01 = __epix_rotate(Cs, Sn, m_01) + ctr; + + return *this; + } + + affine& affine::rotate(double theta, const P& ctr) + { + return rotate(theta, pair(ctr.x1(), ctr.x2())); + } + + affine& affine::reflect(double theta, const pair& ctr) + { + const double Cs(Cos(2*theta)); + const double Sn(Sin(2*theta)); + + // shift + m_00 -= ctr; + m_10 -= ctr; + m_01 -= ctr; + + // reflect about origin and shift back + m_00 = __epix_reflect(Cs, Sn, m_00) + ctr; + m_10 = __epix_reflect(Cs, Sn, m_10) + ctr; + m_01 = __epix_reflect(Cs, Sn, m_01) + ctr; + + return *this; + } + + affine& affine::reflect(double theta, const P& ctr) + { + return reflect(theta, pair(ctr.x1(), ctr.x2())); + } + + affine& affine::h_scale(double sc, const pair& ctr) + { + m_00 -= ctr; + m_10 -= ctr; + m_01 -= ctr; + + const pair scale(sc, 1); + + m_00 = (m_00 & scale) + ctr; + m_10 = (m_10 & scale) + ctr; + m_01 = (m_01 & scale) + ctr; + + return *this; + } + + affine& affine::h_scale(double sc, const P& ctr) + { + return h_scale(sc, pair(ctr.x1(), ctr.x2())); + } + + affine& affine::v_scale(double sc, const pair& ctr) + { + // shift + m_00 -= ctr; + m_10 -= ctr; + m_01 -= ctr; + + const pair scale(1, sc); + + m_00 = (m_00 & scale) + ctr; + m_10 = (m_10 & scale) + ctr; + m_01 = (m_01 & scale) + ctr; + + return *this; + } + + affine& affine::v_scale(double sc, const P& ctr) + { + return v_scale(sc, pair(ctr.x1(), ctr.x2())); + } + + affine& affine::scale(double sc, const pair& ctr) + { + // shift + m_00 -= ctr; + m_10 -= ctr; + m_01 -= ctr; + + const pair scale(sc, sc); + + m_00 = (m_00 & scale) + ctr; + m_10 = (m_10 & scale) + ctr; + m_01 = (m_01 & scale) + ctr; + + return *this; + } + + affine& affine::scale(double sc, const P& ctr) + { + return scale(sc, pair(ctr.x1(), ctr.x2())); + } + + + affine& affine::h_shear(double sc, const pair& ctr) + { + // shift + m_00 -= ctr; + m_10 -= ctr; + m_01 -= ctr; + + m_00 += pair(sc*m_00.x2(), 0) + ctr; + m_10 += pair(sc*m_10.x2(), 0) + ctr; + m_01 += pair(sc*m_01.x2(), 0) + ctr; + + return *this; + } + + affine& affine::h_shear(double sc, const P& ctr) + { + return h_shear(sc, pair(ctr.x1(), ctr.x2())); + } + + affine& affine::v_shear(double sc, const pair& ctr) + { + // shift + m_00 -= ctr; + m_10 -= ctr; + m_01 -= ctr; + + m_00 += pair(0, sc*m_00.x1()) + ctr; + m_10 += pair(0, sc*m_10.x1()) + ctr; + m_01 += pair(0, sc*m_01.x1()) + ctr; + + return *this; + } + + affine& affine::v_shear(double sc, const P& ctr) + { + return v_shear(sc, pair(ctr.x1(), ctr.x2())); + } + + affine& affine::postcomp(const affine& af) + { + m_00 = af(m_00); + m_10 = af(m_10); + m_01 = af(m_01); + + return *this; + } + + affine& affine::invert() + { + m_10 -= m_00; + m_01 -= m_00; + + const double denom(m_10.x1()*m_01.x2() - m_10.x2()*m_01.x1()); + + if (fabs(denom) < EPIX_EPSILON) + { + // restore + m_10 += m_00; + m_01 += m_00; + epix_warning("affine not invertible, no action"); + return *this; + } + + // else compute inverse entries + const double a11( m_01.x2()/denom); + const double a12(-m_01.x1()/denom); + const double a21(-m_10.x2()/denom); + const double a22( m_10.x1()/denom); + + pair tmp_00(-a11*m_00.x1() + a12*m_00.x2(), + a21*m_00.x1() - a22*m_00.x2()); + + m_00 = tmp_00; + m_10 = m_00 + pair(a11, a21); + m_01 = m_00 + pair(a12, a22); + + return *this; + } + + + // evaluation + pair affine::operator() (const pair& arg) const + { + return m_00 + arg.x1()*(m_10 - m_00) + arg.x2()*(m_01 - m_00); + } + + pair affine::operator() (const P& arg) const + { + return m_00 + arg.x1()*(m_10 - m_00) + arg.x2()*(m_01 - m_00); + } + + // pre-composition + affine affine::operator() (const affine& af) const + { + return affine(this->operator()(af.m_10), + this->operator()(af.m_01), + this->operator()(af.m_00)); + } + + bool affine::reverses_orientation() const + { + const pair col1(m_10 - m_00); + const pair col2(m_01 - m_00); + + return (col1.x1()*col2.x2() - col1.x2()*col2.x1() < -EPIX_EPSILON); + } +} // end of namespace diff --git a/graphics/epix/affine.h b/graphics/epix/affine.h new file mode 100644 index 0000000000..a56758e550 --- /dev/null +++ b/graphics/epix/affine.h @@ -0,0 +1,114 @@ +/* + * affine.h -- ePiX::affine class (affine screen maps) + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.21 + * Last Change: September 23, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * An affine map is constructed from the images of the "standard + * triple" (0,0), (1,0), and (0,1). + * + * An affine map may be (post)-composed with translation, rotation, + * reflection, scaling along either or both coordinate axes, shearing, + * and may be inverted. An optional pair argument, defaulting to + * (0,0), gives the center of the operation (if appropriate). + * + * An affine map may be post-composed via member function, and + * pre-composed with operator syntax. The evaluation operator + * returns the image of the argument. + */ + +#ifndef EPIX_AFFINE +#define EPIX_AFFINE + +#include "pairs.h" +#include "triples.h" + +namespace ePiX { + + class affine { + public: + // the identity map + affine(); + + // images of (1,0), (0,1), (0,0) + affine(const pair&, const pair&, const pair& loc=pair(0,0)); + affine(const P&, const P&, const P& loc=P(0,0)); + + // post-operations + // translate by arg + affine& shift(const pair& arg); + affine& shift(const P& arg); + + // rotate by theta about ctr + affine& rotate(double theta, const pair& ctr = pair(0,0)); + affine& rotate(double theta, const P& ctr); + + // reflect in angle-theta line through ctr + affine& reflect(double theta, const pair& ctr = pair(0,0)); + affine& reflect(double theta, const P& ctr); + + // scale coord direction(s) fixing ctr + affine& h_scale(double, const pair& ctr=pair(0,0)); + affine& v_scale(double, const pair& ctr=pair(0,0)); + affine& scale(double, const pair& ctr=pair(0,0)); + + affine& h_scale(double, const P& ctr); + affine& v_scale(double, const P& ctr); + affine& scale(double, const P& ctr); + + // shear, fixing ctr + affine& h_shear(double, const pair& ctr=pair(0,0)); + affine& v_shear(double, const pair& ctr=pair(0,0)); + + affine& h_shear(double, const P& ctr); + affine& v_shear(double, const P& ctr); + + // post-compose + affine& postcomp(const affine&); + + affine& invert(); + + // evaluation + pair operator() (const pair&) const; + pair operator() (const P&) const; + + // pre-compose + affine operator() (const affine&) const; + + bool reverses_orientation() const; + + private: + pair m_00; + pair m_10; + pair m_01; + }; +} // end of ePiX namespace + +#endif /* EPIX_AFFINE */ diff --git a/graphics/epix/angle_units.cc b/graphics/epix/angle_units.cc new file mode 100644 index 0000000000..cbc8973703 --- /dev/null +++ b/graphics/epix/angle_units.cc @@ -0,0 +1,94 @@ +/* + * angle_units.cc -- Implementation of ePiX's angular units + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.22 + * Last Change: September 24, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "constants.h" +#include "angle_units.h" + +namespace ePiX { + + angle_state::angle_state() + : m_rad_per_unit(1.0), + m_unit_per_deg(PI_180), + m_rev_per_unit(1.0/TWO_PI) { } + + void angle_state::set_radians_mode() + { + m_rad_per_unit = 1.0; + m_unit_per_deg = PI_180; + m_rev_per_unit = 1.0/TWO_PI; + } + + void angle_state::set_degrees_mode() + { + m_rad_per_unit = PI_180; + m_unit_per_deg = 1.0; + m_rev_per_unit = 1.0/360; + } + + void angle_state::set_revolutions_mode() + { + m_rad_per_unit = TWO_PI; + m_unit_per_deg = 1.0/360; + m_rev_per_unit = 1.0; + } + + + double angle_state::to_radians(double t) + { + return t *= m_rad_per_unit; + } + + // result lies in (-180, 180] + double angle_state::to_degrees(double t) + { + t *= m_rev_per_unit; + + t -= 0.5; // shift half a turn + t -= ceil(t); // map to (-1,0] + t += 0.5; // shift to (-0.5, 0.5] + + return t *= 360.0; + } + + double angle_state::from_degrees(double t) + { + return t *= m_unit_per_deg; + } + + angle_state& the_angle_style() + { + static angle_state* the_angle_state(new angle_state()); + return *the_angle_state; + } +} // end of namespace diff --git a/graphics/epix/angle_units.h b/graphics/epix/angle_units.h new file mode 100644 index 0000000000..b250b02d51 --- /dev/null +++ b/graphics/epix/angle_units.h @@ -0,0 +1,77 @@ +/* + * angle_units.h -- Implementation of ePiX's angular units + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.22 + * Last Change: September 24, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file contains: + * + * [] angle_state + * Angular mode (radians, degrees, revolutions) + * + * The class in this file implements backend for user-level global + * functions defined in state.h. This header is not part of epix.h. + */ +#ifndef EPIX_ANGLE_UNITS +#define EPIX_ANGLE_UNITS + +#include <cmath> + +namespace ePiX { + + class angle_state { + public: + angle_state(); + + void set_radians_mode(); + void set_degrees_mode(); + void set_revolutions_mode(); + + // convert to radians, for angle-sensitive trig functions + double to_radians(double t); + + // current angle units to/from degrees, for label_style + double to_degrees(double t); + double from_degrees(double t); + + private: + // store state redundantly; small overhead, saves conversion + double m_rad_per_unit; + double m_unit_per_deg; + double m_rev_per_unit; + }; // end of class angle_state + + angle_state& the_angle_style(); + +} // end of namespace + +#endif /* EPIX_ANGLE_UNITS */ diff --git a/graphics/epix/arrow_data.cc b/graphics/epix/arrow_data.cc new file mode 100644 index 0000000000..2c50b0f8bc --- /dev/null +++ b/graphics/epix/arrow_data.cc @@ -0,0 +1,130 @@ +/* + * arrow_data.cc -- ePiX arrow class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <list> +#include <cmath> + +#include "triples.h" +#include "functions.h" + +#include "camera.h" + +#include "edge_data.h" +#include "path_data.h" +#include "clipping.h" + +#include "arrow_style.h" +#include "pen_data.h" +#include "paint_style.h" + +#include "halfspace.h" +#include "pen_line.h" +#include "pen_arrow.h" + +#include "screen_data.h" +#include "screen.h" +#include "active_screen.h" + +#include "arrow_data.h" + +namespace ePiX { + + arrow_data::arrow_data(const std::vector<P>& pv, const P& base, const P& tip, + double scale) + : m_base(base), m_tip(tip), m_scale(scale), + m_head_seen(!the_clip_box().clips(m_tip)) + { + for (unsigned int i=0; i<pv.size()-1; ++i) + m_shaft.push_back(edge3d(pv.at(i), pv.at(i+1), true)); + + the_clip_box().clip_path(m_shaft); + } + + arrow_data& arrow_data::clip_to(const halfspace& knife) + { + knife.clip_path(m_shaft); + if (knife.clips(m_tip)) + m_head_seen = false; + + return *this; + } + + + void arrow_data::photo(screen& scr, const Camera& mycam, + const pen_data& line, const pen_data& under) const + { + arrow_data tmp_data(*this); + if (mycam.needs_clip()) + tmp_data.clip_to(mycam.clip_plane()); + + std::list<edge2d> edges; + for (std::list<edge3d>::const_iterator p=tmp_data.m_shaft.begin(); + p != tmp_data.m_shaft.end(); ++p) + { + edge2d tmp(mycam((*p).tail()), mycam((*p).head()), (*p).is_seen()); + + if (!tmp.is_null()) // endpoints not equal + edges.push_back(tmp); + } + + // draw shaft + scr.m_screen->add_tile(pen_line(line.seen_through(mycam), + under.seen_through(mycam), edges)); + + // and arrowhead + if (m_head_seen) + { + const P dir(m_tip-m_base); + const P to_cam(mycam.viewpt()-m_base); + + const double sin_th(norm(dir*to_cam)/(norm(dir)*norm(to_cam))); + + scr.m_screen->add_tile(pen_arrow(mycam(m_base), mycam(m_tip), + line.seen_through(mycam), + under.seen_through(mycam), + m_scale, sin_th, m_head_seen)); + } + } + + void arrow_data::draw() const + { + photo(*active_screen(), cam(), + the_paint_style().line_pen(), the_paint_style().base_pen()); + } + + void arrow_data::draw(const pen_data& p1, const pen_data& p2) const + { + photo(*active_screen(), cam(), p1, p2); + } +} // end of namespace diff --git a/graphics/epix/arrow_data.h b/graphics/epix/arrow_data.h new file mode 100644 index 0000000000..5840cd35d3 --- /dev/null +++ b/graphics/epix/arrow_data.h @@ -0,0 +1,77 @@ +/* + * arrow_data.h -- ePiX implementation class for arrows + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.8 + * Last Change: July 19, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_ARROW_DATA +#define EPIX_ARROW_DATA + +#include <list> +#include <vector> + +#include "triples.h" +#include "edge_data.h" + +namespace ePiX { + + class Camera; + class Color; + class halfspace; + class pen_data; + class screen; + + // sequence of vertices + class arrow_data { + public: + arrow_data(const std::vector<P>&, const P& base, const P& tip, + double scale=1); + + arrow_data& clip(); + arrow_data& clip_to(const halfspace&); + + void photo(screen&, const Camera&, const pen_data&, const pen_data&) const; + + void draw() const; + void draw(const pen_data&, const pen_data&) const; + + private: + // head data + P m_base, m_tip; + double m_scale; // size multiplier + bool m_head_seen; + + // shaft + std::list<edge3d> m_shaft; + }; // end of class arrow_data + +} // end of namespace + +#endif /* EPIX_ARROW_DATA */ diff --git a/graphics/epix/arrow_style.cc b/graphics/epix/arrow_style.cc new file mode 100644 index 0000000000..1397545909 --- /dev/null +++ b/graphics/epix/arrow_style.cc @@ -0,0 +1,103 @@ +/* + * arrow_atyle.cc -- ePiX's arrowhead parameters + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.15 + * Last Change: September 08, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * The class in this file implements backend for user-level global + * functions defined in state.h. This header is not part of epix.h. + */ +#include <cmath> + +#include "constants.h" +#include "functions.h" // for snip_to +#include "arrow_style.h" + +namespace ePiX { + + arrowhead_state::arrowhead_state() + : m_width(0.5*AVG_AWIDTH), m_ratio(AVG_ARATIO), + m_inset(AVG_INSET), m_fill(false) { } + + // set + arrowhead_state& arrowhead_state::width(double w) + { + m_width = fabs(0.5*snip_to(w, MIN_AWIDTH, MAX_AWIDTH)); + return *this; + } + + arrowhead_state& arrowhead_state::ratio(double r) + { + m_ratio = fabs(snip_to(r, MIN_ARATIO, MAX_ARATIO)); + return *this; + } + + arrowhead_state& arrowhead_state::inset(double arg) + { + m_inset = snip_to(arg, MIN_INSET, MAX_INSET); + return *this; + } + + arrowhead_state& arrowhead_state::fill(bool fill) + { + m_fill = fill; + return *this; + } + + + // get + double arrowhead_state::width() const + { + return m_width; + } + + double arrowhead_state::ratio() const + { + return m_ratio; + } + + double arrowhead_state::inset() const + { + return m_inset; + } + + bool arrowhead_state::fill() const + { + return m_fill; + } + + arrowhead_state& the_arrowhead_style() + { + static arrowhead_state* the_arrowhead_state(new arrowhead_state()); + return *the_arrowhead_state; + } +} // end of namespace diff --git a/graphics/epix/arrow_style.h b/graphics/epix/arrow_style.h new file mode 100644 index 0000000000..0f9691516e --- /dev/null +++ b/graphics/epix/arrow_style.h @@ -0,0 +1,76 @@ +/* + * arrow_style.h -- ePiX's arrowhead parameters + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.15 + * Last Change: September 08, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * The class in this file implements backend for user-level global + * functions defined in state.h. This header is not part of epix.h. + */ +#ifndef EPIX_ARROW_STYLE +#define EPIX_ARROW_STYLE + +namespace ePiX { + + // arrowhead parameters + // Magic numbers: initialization constants + class arrowhead_state { + public: + arrowhead_state(); + + // set + arrowhead_state& width(double w); + arrowhead_state& ratio(double r); + arrowhead_state& inset(double arg); + + arrowhead_state& fill(bool); + + // get + double width() const; + double ratio() const; + double inset() const; + + bool fill() const; + + private: + double m_width; // Half-width of arrowheads in pt + double m_ratio; // 2*Length/width ratio of arrowheads + double m_inset; // Base indentation (frac of width*ratio) + + bool m_fill; + }; // end of class arrowhead_state + + arrowhead_state& the_arrowhead_style(); + +} // end of namespace + +#endif /* EPIX_ARROW_STYLE */ diff --git a/graphics/epix/axis.cc b/graphics/epix/axis.cc new file mode 100644 index 0000000000..ed86be7ee3 --- /dev/null +++ b/graphics/epix/axis.cc @@ -0,0 +1,925 @@ +/* + * axis.cc -- ePiX axis class and global compatibility functions + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.18 + * Last Change: September 18, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> +#include <sstream> + +#include "errors.h" + +#include "constants.h" +#include "triples.h" + +#include "pairs.h" +#include "frac.h" +#include "functions.h" + +#include "length.h" +#include "picture.h" + +#include "camera.h" + +#include "screen.h" +#include "active_screen.h" +#include "curves.h" + +#include "label_data.h" + +#include "markers.h" +#include "axis.h" + +namespace ePiX { + + // functions to get axis label from position + double __epix_coord1(const P&); + double __epix_coord2(const P&); + double __epix_coord3(const P&); + + // string representations of double + std::string __epix_coord_as_double(double x, unsigned int digits, + unsigned int base); + std::string __epix_coord_as_frac(double x, unsigned int digits, + unsigned int base); + std::string __epix_coord_as_trig_frac(double x, unsigned int digits, + unsigned int base); + std::string __epix_coord_as_log(double x, unsigned int digits, + unsigned int base); + std::string __epix_coord_as_log_sci(double x, unsigned int digits, + unsigned int base); + std::string __epix_coord_as_sci(double x, unsigned int digits, + unsigned int base); + + //// Member functions //// + // Constructor automatically selects coordinate function from endpoints + axis::axis(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN) + : m_tail(tail), m_head(head), m_major_segs(n), m_minor_segs(n), + m_tick_ratio(0.5), m_align_ticks(c), + m_offset(offset), m_align_labels(POSN), + m_log_base(10), m_log(false), m_precision(DEF_PRECISION), + m_coord(__epix_coord1), m_rep(__epix_coord_as_double) + { + m_log_tags.insert(1); + int count(fabs(head.x1() - tail.x1()) < EPIX_EPSILON ? 0 : 1); + if (EPIX_EPSILON < fabs(head.x2() - tail.x2())) + { + ++count; + m_coord = __epix_coord2; + } + + if (EPIX_EPSILON < fabs(head.x3() - tail.x3())) + { + ++count; + m_coord = __epix_coord3; + } + + if (1 < count) + epix_warning("Axis not parallel to a Cartesian axis"); + + else if (count == 0) + epix_warning("Degenerate coordinate axis"); + } + + + axis& axis::frac() + { + m_rep = __epix_coord_as_frac; + return *this; + } + + axis& axis::trig() + { + m_rep = __epix_coord_as_trig_frac; + m_log = false; + + return *this; + } + + axis& axis::sci() + { + if (m_log) + m_rep = __epix_coord_as_log_sci; + else + m_rep = __epix_coord_as_sci; + return *this; + } + + // f(x, precision, base) returns a string representing x + axis& axis::label_rep(std::string f(double, unsigned int, unsigned int)) + { + m_rep = f; + return *this; + } + + axis& axis::unmark(double arg) + { + m_omitted.insert(arg); + return *this; + } + + axis& axis::log(unsigned int base) + { + if (m_rep == __epix_coord_as_sci) // preserve sci notation + m_rep = __epix_coord_as_log_sci; + else + m_rep = __epix_coord_as_log; + + if (2 <= base && base <= MAX_LOG_BASE) + m_log_base = base; + else + epix_warning("axis::log base out of range, ignoring"); + + m_log = true; + + return *this; + } + + // add logarithmic labels + axis& axis::tag(double arg) + { + if (0 < arg && 2 < m_log_base) + { + int k((int) ceil(-std::log(arg)/std::log((double)m_log_base))); + + // arg != b^-k + if (k == (int) floor(1 - std::log(arg)/std::log((double)m_log_base))) + m_log_tags.insert(arg*pow(m_log_base, k)); + } + + return *this; + } + + axis& axis::tag235() + { + if (m_log_base == 10) + { + m_log_tags.insert(2); + m_log_tags.insert(3); + m_log_tags.insert(5); + } + + return *this; + } + + axis& axis::tags() + { + for (unsigned int i=1; i<m_log_base; ++i) + m_log_tags.insert(i); + + return *this; + } + + axis& axis::untag(double arg) + { + m_log_tags.erase(arg); + return *this; + } + + axis& axis::untag() + { + m_log_tags.clear(); + return *this; + } + + axis& axis::align_labels(epix_label_posn POSN) + { + m_align_labels = POSN; + return *this; + } + + axis& axis::align(epix_label_posn POSN) + { + m_align_ticks = POSN; + return *this; + } + + + // number of minor ticks per segment + axis& axis::subdivide(unsigned int n) + { + m_minor_segs = m_major_segs*((unsigned int) snip_to(n, 1, MAX_LOG_BASE)); + return *this; + } + + // set tick length; printed size governed by MIN/MAX_TICK, but 0 significant + axis& axis::tick_ratio(double ratio) + { + m_tick_ratio = snip_to(ratio, 0, 1); + return *this; + } + + + // set precision for printing axis labels in decimal + axis& axis::precision(unsigned int digits) + { + if (digits == 0) + m_precision = DEF_PRECISION; + + else + m_precision = (unsigned int) min(digits, MAX_PRECISION); + + return *this; + } + + void axis::draw_ticks() const + { + const P major_step((1.0/m_major_segs)*(m_head - m_tail)); + + const pair screen_dir(cam()(m_head) - cam()(m_tail)); + + if (norm(screen_dir) < EPIX_EPSILON) // poke in the eye + return; + + // else, are we closer to horiz or vert? + bool nearly_horiz(fabs(screen_dir.x2()) < fabs(screen_dir.x1())); + + // axis + line(m_tail, m_head); + + // major ticks + for (unsigned int i=0; i <= m_major_segs; ++i) + { + if (nearly_horiz) + h_axis_tick(m_tail + i*major_step, m_align_ticks); + + else + v_axis_tick(m_tail + i*major_step, m_align_ticks); + } + + // Cartesian minor ticks + if (!m_log && m_tick_ratio != 0 && m_major_segs != m_minor_segs) + { + // get tick size + const double old_tick_len(the_mark_size().tick_size()); + + the_mark_size().tick_size(m_tick_ratio*old_tick_len); + const P minor_step((1.0/m_minor_segs)*(m_head - m_tail)); + + for (unsigned int i=0; i <= m_minor_segs; ++i) + { + if (nearly_horiz) + h_axis_tick(m_tail + i*minor_step, m_align_ticks); + + else + v_axis_tick(m_tail + i*minor_step, m_align_ticks); + } + + the_mark_size().tick_size(old_tick_len); // restore state + } + + // logarithmic minor ticks + else if (m_log && m_tick_ratio != 0) + { + // get tick size + const double old_tick_len(the_mark_size().tick_size()); + + the_mark_size().tick_size(m_tick_ratio*old_tick_len); + + const double denom(std::log((double)m_log_base)); + + for (unsigned int i=0; i < m_major_segs; ++i) + for (unsigned int j=1; j<m_log_base; ++j) + { + if (nearly_horiz) + h_axis_tick(m_tail + (i+std::log((double)j)/denom)*major_step, + m_align_ticks); + + else + v_axis_tick(m_tail + (i+std::log((double)j)/denom)*major_step, + m_align_ticks); + } + + the_mark_size().tick_size(old_tick_len); // restore state + } + } + + void axis::draw_labels() const + { + const P major_step((1.0/m_major_segs)*(m_head - m_tail)); + + if (!m_log) + for (unsigned int i=0; i <= m_major_segs; ++i) + { + const P loc(m_tail + i*major_step); + const double tmp_lbl(m_coord(loc)); + if (m_omitted.find(tmp_lbl) != m_omitted.end()) // omit marked labels + continue; + + // else + label_data mk(loc, m_offset, + m_rep(tmp_lbl, m_precision, m_log_base)); + + mk.align_to(m_align_labels).draw(); + } + + else if (2 < m_log_base) // m_log + { + const double denom(std::log((double)m_log_base)); + + for (unsigned int i=0; i < m_major_segs; ++i) + for (std::set<double>::const_iterator tp=m_log_tags.begin(); + tp != m_log_tags.end(); ++tp) + { + double dx(std::log(*tp)/denom); + const P posn(m_tail + (i + dx)*major_step); + + label_data mk(posn, m_offset, + m_rep(m_coord(posn), m_precision, m_log_base)); + + mk.align_to(m_align_labels).draw(); + } + + // final label + label_data mk(m_head, m_offset, + m_rep(m_coord(m_head), m_precision, m_log_base)); + + mk.align_to(m_align_labels).draw(); + } + } + + void axis::draw() const + { + draw_ticks(); + draw_labels(); + } + + + //// Misc utilities for global functions //// + // raw Cartesian coordinates + std::string __epix_axis_label(double x) + { + std::stringstream obuf; + obuf << "$" << x << "$"; + + return obuf.str(); + } + + std::string __epix_axis1_label(double x, double y) + { + return __epix_axis_label(x); + } + + std::string __epix_axis2_label(double x, double y) + { + return __epix_axis_label(y); + } + + // log coordinates + std::string __epix_log_label(double x, const unsigned int base) + { + std::stringstream obuf; + + int N((int) ceil(x)); + + double k(pow(base, x - N)); + + // obuf.precision(2); + obuf << "$"; + if (k != 1.0) + { + k *= base; + N -= 1; + obuf << k << "\\times"; + } + + obuf << base << "^{" << N << "}$"; + + return obuf.str(); + } + + std::string __epix_log_axis1_label(double x, double y, + const unsigned int base=10) + { + return __epix_log_label(x, base); + } + + std::string __epix_log_axis2_label(double x, double y, + const unsigned int base=10) + { + return __epix_log_label(y, base); + } + + //// Global functions //// + // Draws n+1 equally-spaced axis labels between <tail> and <head>. + // Uses the string-valued function f to generate label text. + void __epix_axis_labels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN, + std::string f(double, double), bool masked) + { + const P step((1.0/n)*(head - tail)); + + // get mask color, if any + Color my_mask(masked ? the_label_style().mask_color() : Neutral()); + + if (masked && my_mask.is_unset()) + my_mask = White(); + + for (unsigned int i=0; i<= n; ++i) + { + label_data mk(tail+i*step, offset, f); + + mk.mask_color(my_mask).align_to(POSN).draw(); + } + } + + + //// User-visible commands //// + // Not implemented with the axis class because masking behavior differs. + void h_axis_labels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN) + { + __epix_axis_labels(tail, head, n, offset, POSN, __epix_axis1_label, false); + } + + void v_axis_labels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN) + { + __epix_axis_labels(tail, head, n, offset, POSN, __epix_axis2_label, false); + } + + + void h_axis_masklabels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN) + { + __epix_axis_labels(tail, head, n, offset, POSN, __epix_axis1_label, true); + } + + void v_axis_masklabels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN) + { + __epix_axis_labels(tail, head, n, offset, POSN, __epix_axis2_label, true); + } + + + // automatic endpoints + void h_axis_labels(unsigned int n, const P& offset, epix_label_posn POSN) + { + __epix_axis_labels(P(active_screen()->h_min(), 0), + P(active_screen()->h_max(), 0), n, offset, POSN, + __epix_axis1_label, false); + } + + void h_axis_masklabels(unsigned int n, const P& offset, epix_label_posn POSN) + { + __epix_axis_labels(P(active_screen()->h_min(), 0), + P(active_screen()->h_max(), 0), n, offset, POSN, + __epix_axis1_label, true); + } + + void v_axis_labels(unsigned int n, const P& offset, epix_label_posn POSN) + { + __epix_axis_labels(P(0, active_screen()->v_min()), + P(0, active_screen()->v_max()), n, offset, POSN, + __epix_axis2_label, false); + } + + void v_axis_masklabels(unsigned int n, const P& offset, epix_label_posn POSN) + { + __epix_axis_labels(P(0, active_screen()->v_min()), + P(0, active_screen()->v_max()), n, offset, POSN, + __epix_axis2_label, true); + } + + + // log axis labels + void __epix_log_axis_labels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN, + std::string f(double, double, unsigned int), + bool masked, unsigned int base=10) + { + const P step((1.0/n)*(head - tail)); + + // get mask color, if any + Color my_mask(masked ? the_label_style().mask_color() : Neutral()); + + if (masked && my_mask.is_unset()) + my_mask = White(); + + for (unsigned int i=0; i<= n; ++i) + { + P here(tail+i*step); + std::string text(f(here.x1(), here.x2(), base)); + + label_data mk(here, offset, text); + + mk.mask_color(my_mask).align_to(POSN).draw(); + } + } + + // number of labels specified + void h_axis_log_labels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN, + unsigned int base) + { + __epix_log_axis_labels(tail, head, n, offset, POSN, + __epix_log_axis1_label, false, base); + } + + void v_axis_log_labels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN, + unsigned int base) + { + __epix_log_axis_labels(tail, head, n, offset, POSN, + __epix_log_axis2_label, false, base); + } + + + // put labels at integer coordinates + void h_axis_log_labels(const P& tail, const P& head, + const P& offset, epix_label_posn POSN, + unsigned int base) + { + if (EPIX_EPSILON < (tail.x2() - head.x2()) ) // non-horizontal axis + return; + + const double my_y(tail.x2()); + + // get integers in horiz interval + const int k_lo((int) ceil(min(tail.x1(), head.x1()))); + const int k_hi((int) floor(max(tail.x1(), head.x1()))); + + h_axis_log_labels(P(k_lo, my_y), P(k_hi, my_y), k_hi - k_lo, + offset, POSN, base); + } + + void v_axis_log_labels(const P& tail, const P& head, + const P& offset, epix_label_posn POSN, + unsigned int base) + { + if (EPIX_EPSILON < (tail.x1() - head.x1()) ) // non-vertical axis + return; + + const double my_x(tail.x1()); + + // get integers in vert interval + const int k_lo((int) ceil(min(tail.x2(), head.x2()))); + const int k_hi((int) floor(max(tail.x2(), head.x2()))); + + v_axis_log_labels(P(my_x, k_lo), P(my_x, k_hi), k_hi - k_lo, + offset, POSN, base); + } + + + //// masked versions + void h_axis_log_masklabels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN, + unsigned int base) + { + __epix_log_axis_labels(tail, head, n, offset, POSN, + __epix_log_axis1_label, true, base); + } + + void v_axis_log_masklabels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN, + unsigned int base) + { + __epix_log_axis_labels(tail, head, n, offset, POSN, + __epix_log_axis2_label, true, base); + } + + + // put labels at integer coordinates + void h_axis_log_masklabels(const P& tail, const P& head, + const P& offset, epix_label_posn POSN, + unsigned int base) + { + if (EPIX_EPSILON < (tail.x2() - head.x2()) ) // non-horizontal axis + return; + + const double my_y(tail.x2()); + + // get integers in horiz interval + const int k_lo((int) ceil(min(tail.x1(), head.x1()))); + const int k_hi((int) floor(max(tail.x1(), head.x1()))); + + h_axis_log_masklabels(P(k_lo, my_y), P(k_hi, my_y), k_hi - k_lo, + offset, POSN, base); + } + + void v_axis_log_masklabels(const P& tail, const P& head, + const P& offset, epix_label_posn POSN, + unsigned int base) + { + if (EPIX_EPSILON < (tail.x1() - head.x1()) ) // non-vertical axis + return; + + const double my_x(tail.x1()); + + // get integers in vert interval + const int k_lo((int) ceil(min(tail.x2(), head.x2()))); + const int k_hi((int) floor(max(tail.x2(), head.x2()))); + + v_axis_log_masklabels(P(my_x, k_lo), P(my_x, k_hi), k_hi - k_lo, + offset, POSN, base); + } + + + // Coordinate axes + void h_axis(const P& tail, const P& head, unsigned int n, epix_label_posn AL) + { + line(tail, head); + + const P step((1.0/n)*(head - tail)); + + for (unsigned int i=0; i <= n; ++i) + h_axis_tick(tail + i*step, AL); + } + + void v_axis(const P& tail, const P& head, unsigned int n, epix_label_posn AL) + { + line(tail, head); + + const P step((1.0/n)*(head - tail)); + + for (unsigned int i=0; i <= n; ++i) + v_axis_tick(tail + i*step, AL); + } + + // n+1 = #ticks, num_pts = #segments used to draw + void h_axis(unsigned int n, epix_label_posn AL) + { + h_axis(P(active_screen()->h_min(), 0), + P(active_screen()->h_max(), 0), n, AL); + } + + void v_axis(unsigned int n, epix_label_posn AL) + { + v_axis(P(0, active_screen()->v_min()), + P(0, active_screen()->v_max()), n, AL); + } + + + void h_log_axis(const P& tail, const P& head, + unsigned int segs, epix_label_posn AL, unsigned int base) + { + line(tail, head, 0, segs); + + const P step((1.0/segs)*(head - tail)); + const double denom(log(base)); + + for (unsigned int i=0; i < segs; ++i) + for (unsigned int j=1; j<base; ++j) + h_axis_tick(tail + (i+log(j)/denom)*step, AL); + + h_axis_tick(head, AL); + } + + void v_log_axis(const P& tail, const P& head, + unsigned int segs, epix_label_posn AL, unsigned int base) + { + line(tail, head, 0, segs); + + const P step((1.0/segs)*(head - tail)); + const double denom(log(base)); + + for (unsigned int i=0; i < segs; ++i) + for (unsigned int j=1; j<base; ++j) + v_axis_tick(tail + (i+log(j)/denom)*step, AL); + + v_axis_tick(head, AL); + } + + + //// New global functions //// + axis top_axis(unsigned int n, const P& offset, epix_label_posn POSN) + { + axis A(active_screen()->tl(), active_screen()->tr(), n, offset, POSN); + A.align(b); + return A; + } + + axis bottom_axis(unsigned int n, const P& offset, epix_label_posn POSN) + { + axis A(active_screen()->bl(), active_screen()->br(), n, offset, POSN); + A.align(t); + return A; + } + + axis left_axis(unsigned int n, const P& offset, epix_label_posn POSN) + { + axis A(active_screen()->bl(), active_screen()->tl(), n, offset, POSN); + A.align(r); + return A; + } + + axis right_axis(unsigned int n, const P& offset, epix_label_posn POSN) + { + axis A(active_screen()->br(), active_screen()->tr(), n, offset, POSN); + A.align(l); + return A; + } + + + //// Formatting functions for ePiX::axis //// + // standard functions to get axis label from position + double __epix_coord1(const P& arg) + { + return arg.x1(); + } + + double __epix_coord2(const P& arg) + { + return arg.x2(); + } + + double __epix_coord3(const P& arg) + { + return arg.x3(); + } + + + // String representations of double + // triples separated by commas + std::string __epix_coord_as_double(double x, unsigned int digits, + unsigned int base) + { + std::stringstream obuf; + obuf.precision(digits); + + obuf << "$" << x << "$"; + + if (fabs(x) < 1000) + return obuf.str(); + + // else insert commas + std::string val(obuf.str()); + + std::string::size_type i(val.find_first_of(".")); + + if (i == std::string::npos) + i = val.size()-1; + + while (4 < i) + { + i -= 3; + val.insert(i, ","); + } + + return val; + } + + // [-]\frac{p}{q} + std::string __epix_coord_as_frac(double x, unsigned int digits, + unsigned int base) + { + ePiX::frac xfrac(x); + + std::stringstream obuf; + obuf.precision(digits); + + obuf << "$"; + + if (xfrac.is_int()) + obuf << xfrac.num() << "$"; + + else + { + if (xfrac.num() < 0) // x may have rounded to zero + obuf << "-"; + + obuf << "\\frac{" << abs(xfrac.num()) << "}" + << "{" << xfrac.denom() << "}$"; + } + + return obuf.str(); + } + + // [-]\frac{p\pi}{q} + std::string __epix_coord_as_trig_frac(double x, unsigned int digits, + unsigned int base) + { + ePiX::frac xfrac(x/M_PI); + + int xnum(xfrac.num()); + + std::stringstream obuf; + obuf.precision(digits); + + obuf << "$"; + + if (xfrac.is_int()) + { + if (xnum == 0) + obuf << 0 << "$"; + + else if (xnum == 1) + obuf << "\\pi$"; + + else if (xnum == -1) + obuf << "-\\pi$"; + + else + obuf << xfrac.num() << "\\pi$"; + } + + else // xfrac not an int + { + if (xfrac.num() < 0) + obuf << "-"; + + if (abs(xnum) == 1) + obuf << "\\frac{\\pi}{" << xfrac.denom() << "}$"; + + else + obuf << "\\frac{" << abs(xnum) << "\\pi}" + << "{" << xfrac.denom() << "}$"; + } + + return obuf.str(); + } + + // b^x + std::string __epix_coord_as_log(double x, unsigned int digits, + unsigned int base) + { + std::stringstream obuf; + obuf.precision(digits); + + obuf << "$" << pow(base, x) << "$"; + + return obuf.str(); + } + + // x = N + k, write as eval(b^k) \times b^N + std::string __epix_coord_as_log_sci(double x, unsigned int digits, + unsigned int base) + { + std::stringstream obuf; + obuf.precision(digits); + + int N((int) ceil(x)); + + double k(pow(base, x - N)); + + obuf << "$"; + if (k != 1.0) + { + k *= base; + N -= 1; + obuf << k << "\\times"; + } + + obuf << base << "^{" << N << "}$"; + + return obuf.str(); + } + + std::string __epix_coord_as_sci(double x, unsigned int digits, + unsigned int base) + { + std::stringstream obuf; + obuf.precision(digits); + + int sgn(x < 0 ? -1 : 1); + x = fabs(x); + if (x < EPIX_EPSILON) + return "$0$"; + + // else + const double tmp(log10(x)/log10(base)); + + int N((int) floor(tmp)); + + double k(pow(base, tmp - N)); + + obuf << "$"; + if (sgn < 0) + obuf << "-"; + + if (k != 1.0) + obuf << k << "\\times"; + + obuf << base << "^{" << N << "}$"; + + return obuf.str(); + } +} // end of namespace diff --git a/graphics/epix/axis.h b/graphics/epix/axis.h new file mode 100644 index 0000000000..2c5d47d568 --- /dev/null +++ b/graphics/epix/axis.h @@ -0,0 +1,207 @@ +/* + * axis.h -- Decorable coordinate axis class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.13 + * Last Change: August 23, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_AXIS +#define EPIX_AXIS + +#include <string> +#include <set> + +#include "enums.h" +#include "triples.h" + +namespace ePiX { + + class axis { + public: + axis(const P&, const P&, unsigned int n, + const P& offset = P(0,0), epix_label_posn POSN=none); + + // attribute-setting + axis& dec(); // default + axis& frac(); // fractional labels + axis& trig(); // fractions times pi + axis& sci(); // scientific notation + + // f(x, precision, base) returns a string representing x + axis& label_rep(std::string f(double, unsigned int, unsigned int)); + + // unmark selected location (non-log labels only) + axis& unmark(double arg=0); + + // add or remove logarithmic tags ("sublabels") + axis& log(unsigned int base=10); // log ticks and labels + axis& tag(double); // put label at arg in log mode + axis& tag235(); // tags at 2, 3, 5 in log10 mode + axis& tags(); // tags at 2, ..., b-1 in logb mode + + axis& untag(); // remove all log tags + axis& untag(double); // remove selected tag + + axis& align_labels(epix_label_posn); + axis& align(epix_label_posn); // align tick marks + + // number of minor ticks per segment + axis& subdivide(unsigned int); + + // set length of minor ticks + axis& tick_ratio(double); + + // set precision for axis labels + axis& precision(unsigned int digits=0); // 0: reset to default + + void draw_ticks() const; + void draw_labels() const; + void draw() const; + + private: + P m_tail; + P m_head; + + unsigned int m_major_segs; + unsigned int m_minor_segs; + + double m_tick_ratio; + + epix_label_posn m_align_ticks; + + P m_offset; + epix_label_posn m_align_labels; + + unsigned int m_log_base; + bool m_log; + unsigned int m_precision; + + double (*m_coord)(const P&); // value to place at arg + + // represent arg as string + std::string (*m_rep)(double arg, unsigned int prec, unsigned int base); + + std::set<double> m_omitted; + std::set<double> m_log_tags; + }; // end of axis class + + // axes along sides of bounding box, ticks automatically aligned + axis top_axis(unsigned int n, const P& offset=P(0,0), + epix_label_posn POSN=t); + axis bottom_axis(unsigned int n, const P& offset=P(0,0), + epix_label_posn POSN=b); + axis left_axis(unsigned int n, const P& offset=P(0,0), + epix_label_posn POSN=l); + axis right_axis(unsigned int n, const P& offset=P(0,0), + epix_label_posn POSN=r); + + + // Global functions from Version 1.0 + void h_axis_labels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN=none); + + void v_axis_labels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN=none); + + void h_axis_masklabels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN=none); + + void v_axis_masklabels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN=none); + + // Axis labels with default endpoints + void h_axis_labels(unsigned int n, const P& offset, + epix_label_posn POSN=none); + void h_axis_masklabels(unsigned int n, const P& offset, + epix_label_posn POSN=none); + + void v_axis_labels(unsigned int n, const P& offset, + epix_label_posn POSN=none); + void v_axis_masklabels(unsigned int n, const P& offset, + epix_label_posn POSN=none); + + //// logarithmic labels //// + // labels written $k x base^i$ at i + log_b(k) + void h_axis_log_labels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN=none, + unsigned int base=10); + + void v_axis_log_labels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN=none, + unsigned int base=10); + + // labels written $base^i$ at coord i + void h_axis_log_labels(const P& tail, const P& head, + const P& offset, epix_label_posn POSN=none, + unsigned int base=10); + + void v_axis_log_labels(const P& tail, const P& head, + const P& offset, epix_label_posn POSN=none, + unsigned int base=10); + + + void h_axis_log_masklabels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN=none, + unsigned int base=10); + + void v_axis_log_masklabels(const P& tail, const P& head, unsigned int n, + const P& offset, epix_label_posn POSN=none, + unsigned int base=10); + + void h_axis_log_masklabels(const P& tail, const P& head, + const P& offset, epix_label_posn POSN=none, + unsigned int base=10); + + void v_axis_log_masklabels(const P& tail, const P& head, + const P& offset, epix_label_posn POSN=none, + unsigned int base=10); + + + // Coordinate axes, specified by initial and final points, number of + // tick marks. h/v_axis are identical except for style of tick marks. + + // n subintervals + void h_axis(const P& tail, const P& head, unsigned int n, + epix_label_posn align=c); + void v_axis(const P& tail, const P& head, unsigned int n, + epix_label_posn align=c); + + // Default endpoints (xmin(), 0), xmax(), 0), etc. + void h_axis(unsigned int n = xsize(), epix_label_posn align=c); + void v_axis(unsigned int n = ysize(), epix_label_posn align=c); + + void h_log_axis(const P& tail, const P& head, unsigned int segs, + epix_label_posn align=c, unsigned int base=10); + + void v_log_axis(const P& tail, const P& head, unsigned int segs, + epix_label_posn align=c, unsigned int base=10); + +} // end of namespace + +#endif /* EPIX_AXIS */ diff --git a/graphics/epix/bash_completions b/graphics/epix/bash_completions new file mode 100644 index 0000000000..a05daab7e4 --- /dev/null +++ b/graphics/epix/bash_completions @@ -0,0 +1,8 @@ +# If you use Ian MacDonald's bash completion package, put these +# lines in either /etc/bash_completions or $HOME/.bashrc to use +# programmable completion with ePiX. +# +complete -f -X '!*.@(xp|flx|cc|c|C|cpp)' epix +complete -f -X '!*.@(tex|dtx|ltx)' laps +complete -f -X '!*.@(xp|flx|cc|c|C|cpp|eepic)' elaps +complete -f -X '!*.@(flx|cc|c|C|cpp)' flix diff --git a/graphics/epix/camera.cc b/graphics/epix/camera.cc new file mode 100644 index 0000000000..0a70da081b --- /dev/null +++ b/graphics/epix/camera.cc @@ -0,0 +1,318 @@ +/* + * camera.cc -- ePiX::camera functions + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.21 + * Last Change: September 22, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> + +#include "errors.h" +#include "constants.h" + +#include "pairs.h" +#include "triples.h" +#include "frame.h" + +#include "functions.h" + +#include "halfspace.h" + +#include "lens.h" +#include "camera.h" + +namespace ePiX { + + // Need to initialize frame argument for Apple gcc; otherwise cam() + // gets null vectors in frame()... + Camera::Camera() + : the_viewpt(P(0,0,EPIX_INFTY)), the_target(P(0,0,0)), + the_orient(frame(E_1, E_2, E_3)), + the_distance(EPIX_INFTY), the_clip_range(MIN_CLIP), + the_filter(Neutral()), the_lens(new Perspective()) { } + + // viewpt, target, orient + Camera::Camera(const P& vpt) + : the_viewpt(vpt), the_target(P(0,0,0)), the_clip_range(MIN_CLIP), + the_filter(Neutral()) + { + if (the_viewpt == P(0,0,0)) + { + epix_warning("Cannot initialize Camera at Origin, using (0, 0, oo)"); + the_viewpt = P(0, 0, EPIX_INFTY); + } + P viewer(the_viewpt - the_target); + the_distance = norm(viewer); + + viewer *= recip(norm(viewer)); + + // viewer is "eye", if possible E_3 is "sky" + P tmp_sea(E_3*viewer); + + if (norm(tmp_sea) < EPIX_EPSILON) // we're on the "z-axis through vpt" + tmp_sea = E_1; + + // eye*sea = sky + the_orient = frame(tmp_sea, viewer*tmp_sea, viewer); + adjust(); + + the_lens = new Perspective(); + } + + + Camera::Camera(const Camera& cam) + : the_viewpt(cam.the_viewpt), the_target(cam.the_target), + the_orient(cam.the_orient), the_distance(cam.the_distance), + the_clip_range(cam.the_clip_range), the_filter(cam.the_filter), + the_lens(cam.the_lens->clone()) { } + + Camera& Camera::operator= (const Camera& cam) + { + Lens* tmp_lens(cam.the_lens->clone()); + the_lens = tmp_lens; + + the_viewpt = cam.the_viewpt; + the_target = cam.the_target; + the_orient =cam.the_orient; + the_distance = cam.the_distance; + the_clip_range = cam.the_distance; + + the_filter = cam.the_filter; + + return *this; + } + + Camera::~Camera() + { + delete the_lens; + } + + // rotate up/down + Camera& Camera::tilt(double angle) + { + the_orient.rot1(-angle); + the_target = the_viewpt + (-the_distance)*the_orient.eye(); + return *this; + } + + // rotate left/right + Camera& Camera::pan(double angle) + { + the_orient.rot2(-angle); + the_target = the_viewpt + (-the_distance)*the_orient.eye(); + return *this; + } + + // rotate about viewing axis + Camera& Camera::roll(double angle) + { + the_orient.rot3(-angle); // target unchanged + return *this; + } + + // fix target, move viewpt radially along eye() + Camera& Camera::range(double d) + { + if (d == 0) + d = EPIX_INFTY; + + the_distance = d; + the_viewpt = the_target + d*the_orient.eye(); + + return *this; + } + + // fix viewpt, move target radially along eye() + Camera& Camera::focus(double d) + { + if (d == 0) + d = EPIX_INFTY; + + the_distance = d; + the_target = the_viewpt - d*the_orient.eye(); + + return *this; + } + + // clip everything behind this + Camera& Camera::clip_range(double dist) + { + the_clip_range = (dist < MIN_CLIP ? MIN_CLIP : dist); + return *this; + } + + // fix target, set viewpt + Camera& Camera::at(const P& vpt) + { + the_viewpt = vpt; + adjust(); + + return *this; + } + + // fix viewpt, set target + Camera& Camera::look_at(const P& tgt) + { + the_target = tgt; + adjust(); + + return *this; + } + + Camera& Camera::at(double x1, double x2, double x3) + { + the_viewpt = P(x1, x2, x3); + adjust(); + + return *this; + } + + // fix viewpt, set target + Camera& Camera::look_at(double x1, double x2, double x3) + { + the_target = P(x1, x2, x3); + adjust(); + + return *this; + } + + Camera& Camera::filter(const Color& filter) + { + the_filter=filter; + return *this; + } + + Camera& Camera::perspective() + { + delete the_lens; + the_lens = new Perspective; + return *this; + } + + Camera& Camera::orthog() + { + delete the_lens; + the_lens = new Orthog; + return *this; + } + + Camera& Camera::fisheye() + { + delete the_lens; + the_lens = new Fisheye; + return *this; + } + + Camera& Camera::bubble() + { + delete the_lens; + the_lens = new Bubble; + return *this; + } + + Color Camera::operator() (const Color& in_color) const + { + Color temp = the_filter; + return temp.filter(in_color); + } + + // lens interface + pair Camera::operator() (const P& arg) const + { + return (*the_lens)(arg, the_orient, the_viewpt, the_distance); + } + + bool Camera::is_linear() const + { + return (*the_lens).is_linear(); + } + + bool Camera::needs_clip() const + { + return (*the_lens).needs_clip(); + } + + + halfspace Camera::clip_plane() const + { + const P N(-the_orient.eye()); + return halfspace(the_viewpt + the_clip_range*N, N); + } + + P Camera::eye() const + { + return the_orient.eye(); + } + + P Camera::viewpt() const + { + return the_viewpt; + } + + // private function + void Camera::adjust() + { + P temp(the_target - the_viewpt); + the_distance = norm(temp); + + if (the_distance < EPIX_EPSILON) + { + epix_warning("Cannot make viewpoint and target the same, no action"); + return; + } + + // else + temp *= -1.0/the_distance; // reverse direction + + double z_ht(temp|E_3); + + // too close to "z-axis" through target? + if (sqrt((1-z_ht)*(1+z_ht)) < EPIX_EPSILON) + { + if (z_ht >= 0) + the_orient = frame(); + + else // z_ht < 0 + the_orient = frame(-E_1, E_2, -E_3); + } + + else // far enough from axis + the_orient = frame(P(-temp.x2(), temp.x1(), 0), E_3, temp); + } + + + Camera& cam() + { + static Camera* the_camera(new Camera()); + return *the_camera; + } + + Camera& camera(cam()); + +} // end of namespace diff --git a/graphics/epix/camera.h b/graphics/epix/camera.h new file mode 100644 index 0000000000..87a3590db2 --- /dev/null +++ b/graphics/epix/camera.h @@ -0,0 +1,134 @@ +/* + * camera.h -- ePiX::Camera + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.21 + * Last Change: September 22, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * A Camera has a location, orientation, lens, and color filter. The + * viewer sits at given <distance> from the <target>, in the direction + * of the <eye>. The vectors <sea> and <sky> point horizontally to the + * right and vertically upward on the screen. The viewing angle is + * controlled by changing the viewer, target, and/or the distance + * between them. + * + * The implementation data comprise: + * - a frame ({sea, sky, eye}, with the intuitive meanings:) + * - a viewpoint + * - a target (at the center of the field of view) + * - the distance from the viewpoint to the target + * - a "filter" color, Neutral by default, for color separation, etc. + * - a Lens + * + * A Lens is a mapping P -> pair. In the implementation, the Camera + * ("body") passes the orientation, target, and distance to the Lens + * operator. + */ + +#ifndef EPIX_CAMERA +#define EPIX_CAMERA + +#include "triples.h" +#include "frame.h" +#include "Color.h" + +namespace ePiX { + + class halfspace; + class Lens; + class pair; + + class Camera { + public: + Camera(); + Camera(const P& vpt); + + Camera(const Camera&); + Camera& operator= (const Camera&); + ~Camera(); + + // rotate + Camera& tilt(double angle); // up/down (pitch) + Camera& pan(double angle); // left/right (yaw) + Camera& roll(double angle); // about viewing axis + + // fix target, move viewpt radially along eye() + Camera& range(double); + // fix viewpt, move target radially along eye() + Camera& focus(double); + + // set clip distance + Camera& clip_range(double); + + Camera& at(const P& arg); // fix target, set viewpt + Camera& look_at(const P& arg); // fix viewpt, set target + + // alternative syntax + Camera& at(double, double, double); + Camera& look_at(double, double, double); + + Camera& filter(const Color&); + + // set lens + Camera& perspective(); // default + Camera& orthog(); // faster + Camera& fisheye(); + Camera& bubble(); + + // Functions for internal use + // Camera maps + Color operator() (const Color&) const; // filter + pair operator() (const P&) const; // lens map + bool is_linear() const; // lens preserves lines? + + bool needs_clip() const; // lens needs scene pre-clipping + halfspace clip_plane() const; + + // situation + P eye() const; + P viewpt() const; + + private: + P the_viewpt; // center of projection + P the_target; // mapped to Screen origin + frame the_orient; // our {sea, sky, eye} + double the_distance; + double the_clip_range; + + Color the_filter; + void adjust(); // re-orient according to target, viewpt + Lens* the_lens; + }; // end of class Camera + + // global Camera + Camera& cam(); + extern Camera& camera; +} // end of namespace + +#endif /* EPIX_CAMERA */ diff --git a/graphics/epix/circle.cc b/graphics/epix/circle.cc new file mode 100644 index 0000000000..b81150587a --- /dev/null +++ b/graphics/epix/circle.cc @@ -0,0 +1,197 @@ +/* + * circle.cc -- ePiX::Circle class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.9 + * Last Change: July 30, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> + +#include "errors.h" + +#include "constants.h" + +#include "triples.h" +#include "state.h" + +#include "segment.h" +#include "frame.h" +#include "camera.h" + +#include "path.h" + +#include "paint_style.h" + +#include "intersections.h" + +#include "circle.h" + +namespace ePiX { + + static const double EPS(EPIX_EPSILON); + + Circle::Circle(const P& ctr, const double rad, const P& perp) + : m_center(ctr), m_radius(rad), m_perp(perp), m_malformed(false) + { + double temp(norm(perp)); + if (temp < EPS) + { + epix_warning("Degenerate circle normal, using (0,0,1)"); + m_perp=E_3; + } + + else + m_perp *= (1.0/temp); // normalize + } + + // point-and-center constructor -- parallel to (x1,x2,0)-plane + Circle::Circle(const P& ctr, const P& pt) + : m_center(ctr), m_radius(norm(pt - ctr)), m_perp(E_3), m_malformed(false) + { + if (fabs(E_3|(pt - ctr)) > EPS) + epix_warning("Circle requested with point not in (x,y) plane"); + } + + // three-point circle constructor + Circle::Circle(const P& pt1, const P& pt2, const P& pt3) + : m_malformed(false) + { + P D21(pt2-pt1), D31(pt3-pt1), D32(pt3-pt2), N(D21*D31); + + if (norm(D21) < EPS || + norm(D31) < EPS || + norm(D32) < EPS || + norm(N) < EPS) + { + epix_warning("Collinear points in Circle constructor"); + m_malformed = true; + } + + else + { + m_perp = (1.0/norm(N))*N; + + P q2(0.5*(pt1+pt2)); + P dir2(m_perp*(q2-pt1)); + + P q3(0.5*(pt1+pt3)); + P dir3(m_perp*(q3-pt1)); + + m_center = Segment(q2, q2+dir2)*Segment(q3, q3+dir3); + m_radius = norm(m_center - pt1); + } + } + + + Circle::Circle(bool tag) : m_malformed(true) { } + + + P Circle::center() const + { + return m_center; + } + + double Circle::radius() const + { + return m_radius; + } + + P Circle::perp() const + { + return m_perp; + } + + bool Circle::malformed() const + { + return m_malformed; + } + + // translation + Circle& Circle::shift(const P& arg) + { + if (!m_malformed) + m_center += arg; + return *this; + } + + Circle& Circle::move_to(const P& arg) + { + if (!m_malformed) + m_center = arg; + return *this; + } + + // scale radius + Circle& Circle::scale(const double c) + { + if (!m_malformed) + m_radius *= c; + return *this; + } + + + // project to screen by camera + void Circle::draw() const + { + if (m_malformed) + return; + + // else + double r(m_radius); + P N(m_perp); + frame axes; // standard basis + + if (EPS <= norm(N*E_3)) + axes = frame(E_3*N, E_3, N); + + path data(m_center, r*(axes.sea()), r*(axes.sky()), 0, full_turn()); + data.close().fill(the_paint_style().fill_flag()); + data.draw(); + } + + + //// global functions //// + void circle(const P& ctr, const double rad, const P& perp) + { + Circle C(ctr, rad, perp); + C.draw(); + } + + void circle(const P& ctr, const P& pt) + { + Circle C(ctr, pt); + C.draw(); + } + + void circle(const P& pt1, const P& pt2, const P& pt3) + { + Circle C(pt1, pt2, pt3); + C.draw(); + } +} // end of namespace diff --git a/graphics/epix/circle.h b/graphics/epix/circle.h new file mode 100644 index 0000000000..5d3e80dd72 --- /dev/null +++ b/graphics/epix/circle.h @@ -0,0 +1,94 @@ +/* + * circle.h -- ePiX::Circle class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.9 + * Last Change: July 30, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file provides: + * + * The Circle class (center, radius, unit normal). + * + * - Circle() (defaults to origin, unit radius, in (x1,x2,0)-plane + * - Circle(ctr, pt) (parallel to (x1,x2,0)-plane, center ctr, through pt) + * - Circle(pt1, pt2, pt3) (arbitrary non-collinear points) + * - center(), radius(), perp() + * - affine operations: shift(P), move_to(P), scale(double) + * - draw() (ePiX ellipse) + */ +#ifndef EPIX_CIRCLE +#define EPIX_CIRCLE + +#include "triples.h" + +namespace ePiX { + + class Circle { + public: + // defaults to unit circle in (x1,x2,0) plane + Circle(const P& ctr=P(0,0,0), double rad=1, const P& perp=E_3); + + Circle(const P& ctr, const P& pt); // center, and point, normal = E_3 + Circle(const P& pt1, const P& pt2, const P& pt3); // three points + + Circle(bool); // malformed Circle for intersection operators + + P center() const; + double radius() const; + P perp() const; + + bool malformed() const; + + // translate + Circle& shift(const P&); + Circle& move_to(const P&); + // scale radius by c + Circle& scale(double c); + + void draw() const; + + private: + P m_center; + double m_radius; + P m_perp; // unit normal, even if rad = 0 + + bool m_malformed; + }; // end of Circle class + + // global object-drawing commands + void circle(const P& ctr=P(0,0,0), double rad=1, const P& perp=E_3); + + void circle(const P& ctr, const P& pt); // center, and point, normal = E_3 + void circle(const P& pt1, const P& pt2, const P& pt3); // three points + +} // end of namespace + +#endif /* EPIX_CIRCLE */ diff --git a/graphics/epix/clipping.cc b/graphics/epix/clipping.cc new file mode 100644 index 0000000000..8da785d2f5 --- /dev/null +++ b/graphics/epix/clipping.cc @@ -0,0 +1,136 @@ +/* + * clipping.cc -- Implementation of ePiX's current drawing state + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.13 + * Last Change: August 23, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <list> + +#include "constants.h" +#include "triples.h" +#include "functions.h" +#include "clipping.h" + +namespace ePiX { + + typedef std::list<halfspace>::const_iterator Hp; + static const double INF(EPIX_INFTY); + + clip_state::clip_state(const P& arg1, const P& arg2) + { + double min1(min(arg1.x1(), arg2.x1())), max1(max(arg1.x1(), arg2.x1())); + double min2(min(arg1.x2(), arg2.x2())), max2(max(arg1.x2(), arg2.x2())); + double min3(min(arg1.x3(), arg2.x3())), max3(max(arg1.x3(), arg2.x3())); + + double avg1(0.5*(min1+max1)), avg2(0.5*(min2+max2)), avg3(0.5*(min3+max3)); + + // inward-pointing faces of clip_box + m_walls.push_back(halfspace(P(max1,avg2,avg3), P(-1, 0, 0))); + m_walls.push_back(halfspace(P(min1,avg2,avg3), P( 1, 0, 0))); + + m_walls.push_back(halfspace(P(avg1,max2,avg3), P( 0,-1, 0))); + m_walls.push_back(halfspace(P(avg1,min2,avg3), P( 0, 1, 0))); + + m_walls.push_back(halfspace(P(avg1,avg2,max3), P( 0, 0,-1))); + m_walls.push_back(halfspace(P(avg1,avg2,min3), P( 0, 0, 1))); + } + + clip_state::clip_state() + { + m_walls.push_back(halfspace(P( INF, 0, 0), P(-1, 0, 0))); + m_walls.push_back(halfspace(P(-INF, 0, 0), P( 1, 0, 0))); + + m_walls.push_back(halfspace(P( 0, INF, 0), P( 0,-1, 0))); + m_walls.push_back(halfspace(P( 0,-INF, 0), P( 0, 1, 0))); + + m_walls.push_back(halfspace(P( 0, 0, INF), P( 0, 0,-1))); + m_walls.push_back(halfspace(P( 0, 0,-INF), P( 0, 0, 1))); + } + + + clip_state& clip_state::add_face(const P& loc, const P& perp) + { + if (EPIX_EPSILON < norm(perp)) + m_extras.push_back(halfspace(loc, perp)); + + return *this; + } + + + clip_state& clip_state::clear_extras() + { + m_extras.clear(); + + return *this; + } + + + bool clip_state::clips(const P& arg) const + { + for (Hp p=m_walls.begin(); p != m_walls.end(); ++p) + if ( (*p).clips(arg) ) + return true; + + for (Hp p=m_extras.begin(); p != m_extras.end(); ++p) + if ( (*p).clips(arg) ) + return true; + + return false; + } + + // return reference to clipped argument + std::list<edge3d>& clip_state::clip_path(std::list<edge3d>& L) const + { + for (Hp p=m_walls.begin(); p != m_walls.end(); ++p) + (*p).clip_path(L); + + for (Hp p=m_extras.begin(); p != m_extras.end(); ++p) + (*p).clip_path(L); + + return L; + } + + std::list<edge3d>& clip_state::clip_loop(std::list<edge3d>& L) const + { + for (Hp p=m_walls.begin(); p != m_walls.end(); ++p) + (*p).clip_loop(L); + + for (Hp p=m_extras.begin(); p != m_extras.end(); ++p) + (*p).clip_loop(L); + + return L; + } + + clip_state& the_clip_box() + { + static clip_state* the_clip_state(new clip_state()); + return *the_clip_state; + } +} // end of namespace diff --git a/graphics/epix/clipping.h b/graphics/epix/clipping.h new file mode 100644 index 0000000000..bec60a3801 --- /dev/null +++ b/graphics/epix/clipping.h @@ -0,0 +1,77 @@ +/* + * clipping.h -- ePiX's clip box + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.13 + * Last Change: August 23, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * The class in this file implements backend for user-level global + * functions defined in state.h. This header is not part of epix.h. + */ +#ifndef EPIX_CLIPPING +#define EPIX_CLIPPING + +#include <string> + +#include "edge_data.h" +#include "halfspace.h" + +namespace ePiX { + + class P; + + class clip_state { + public: + // create inward-pointing faces of clip_box + clip_state(const P& arg1, const P& arg2); + clip_state(); // very large box by default + + // add and remove faces + clip_state& add_face(const P& loc, const P& perp); + clip_state& clear_extras(); + + bool clips(const P&) const; + + // return reference to clipped argument + std::list<edge3d>& clip_path(std::list<edge3d>&) const; + std::list<edge3d>& clip_loop(std::list<edge3d>&) const; + + private: + std::list<halfspace> m_walls; // always present + + std::list<halfspace> m_extras; // user-added + }; // end of class clip_state + + clip_state& the_clip_box(); + +} // end of namespace + +#endif /* EPIX_CLIPPING */ diff --git a/graphics/epix/config.guess b/graphics/epix/config.guess new file mode 100644 index 0000000000..c38553dc74 --- /dev/null +++ b/graphics/epix/config.guess @@ -0,0 +1,1497 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2006-02-23' + +# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner <per@bothner.com>. +# Please send patches to <config-patches@gnu.org>. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerppc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS_NT-*:*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + x86:Interix*:[345]*) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T:Interix*:[345]*) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <features.h> + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <hewes@openmarket.com>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c <<EOF +#ifdef _SEQUENT_ +# include <sys/types.h> +# include <sys/utsname.h> +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include <sys/param.h> +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 <<EOF +$0: unable to guess system type + +This script, last modified $timestamp, has failed to recognize +the operating system you are using. It is advised that you +download the most up to date version of the config scripts from + + http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess +and + http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <config-patches@gnu.org> in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/graphics/epix/config.sub b/graphics/epix/config.sub new file mode 100644 index 0000000000..ad9f395711 --- /dev/null +++ b/graphics/epix/config.sub @@ -0,0 +1,1608 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + +timestamp='2006-02-23' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to <config-patches@gnu.org>. Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m32c) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + m32c-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16c) + basic_machine=cr16c-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/graphics/epix/configure b/graphics/epix/configure new file mode 100644 index 0000000000..14efb92c86 --- /dev/null +++ b/graphics/epix/configure @@ -0,0 +1,6396 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.60 for epix 1.2.1. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +# Find out whether ``test -x'' works. Don't use a zero-byte file, as +# systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + as_executable_p="test -x" +else + as_executable_p=: +fi +rm -f conf$$.file + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 </dev/null 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME='epix' +PACKAGE_TARNAME='epix' +PACKAGE_VERSION='1.2.1' +PACKAGE_STRING='epix 1.2.1' +PACKAGE_BUGREPORT='' + +ac_unique_file="utils.h" +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +CYGPATH_W +PACKAGE +VERSION +ACLOCAL +AUTOCONF +AUTOMAKE +AUTOHEADER +MAKEINFO +install_sh +STRIP +INSTALL_STRIP_PROGRAM +mkdir_p +AWK +SET_MAKE +am__leading_dot +AMTAR +am__tar +am__untar +MAINTAINER_MODE_TRUE +MAINTAINER_MODE_FALSE +MAINT +CXX +CXXFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CXX +EXEEXT +OBJEXT +DEPDIR +am__include +am__quote +AMDEP_TRUE +AMDEP_FALSE +AMDEPBACKSLASH +CXXDEPMODE +am__fastdepCXX_TRUE +am__fastdepCXX_FALSE +LN_S +RANLIB +ENABLE_EPIX_EL_TRUE +ENABLE_EPIX_EL_FALSE +BASH_PATH +RUNTIME_COMPILER +CC +CFLAGS +ac_ct_CC +CCDEPMODE +am__fastdepCC_TRUE +am__fastdepCC_FALSE +CPP +GREP +EGREP +LIBOBJS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CXX +CXXFLAGS +LDFLAGS +CPPFLAGS +CCC +CC +CFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures epix 1.2.1 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/epix] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of epix 1.2.1:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-epix-el Install emacs mode for ePiX files + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-bash=<bash> The path to bash + --with-runtime=<g++> The runtime compiler + +Some influential environment variables: + CXX C++ compiler command + CXXFLAGS C++ compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CC C compiler command + CFLAGS C compiler flags + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +epix configure 1.2.1 +generated by GNU Autoconf 2.60 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by epix $as_me 1.2.1, which was +generated by GNU Autoconf 2.60. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +am__api_version="1.9" +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm -f conftest.sed + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='epix' + VERSION='1.2.1' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +install_sh=${install_sh-"$am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + +{ echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5 +echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6; } + + +if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { echo "$as_me:$LINENO: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C++ compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C++ compiler default output file name" >&5 +echo $ECHO_N "checking for C++ compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C++ compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C++ compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5 +echo $ECHO_N "checking whether the C++ compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CXXFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +{ echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + + +if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + + +depcc="$CXX" am_compiler_list= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +{ echo "$as_me:$LINENO: checking whether ln -s works" >&5 +echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +else + { echo "$as_me:$LINENO: result: no, using $LN_S" >&5 +echo "${ECHO_T}no, using $LN_S" >&6; } +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +# Check whether --enable-epix-el was given. +if test "${enable_epix_el+set}" = set; then + enableval=$enable_epix_el; enable_epix_el=${enableval-yes} +else + enable_epix_el=yes +fi + + + +if test "$enable_epix_el" = yes; then + ENABLE_EPIX_EL_TRUE= + ENABLE_EPIX_EL_FALSE='#' +else + ENABLE_EPIX_EL_TRUE='#' + ENABLE_EPIX_EL_FALSE= +fi + + +# Extract the first word of "bash", so it can be a program name with args. +set dummy bash; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_BASH_PATH+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $BASH_PATH in + [\\/]* | ?:[\\/]*) + ac_cv_path_BASH_PATH="$BASH_PATH" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_BASH_PATH="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + test -z "$ac_cv_path_BASH_PATH" && ac_cv_path_BASH_PATH="/bin/bash" + ;; +esac +fi +BASH_PATH=$ac_cv_path_BASH_PATH +if test -n "$BASH_PATH"; then + { echo "$as_me:$LINENO: result: $BASH_PATH" >&5 +echo "${ECHO_T}$BASH_PATH" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + +# Check whether --with-bash was given. +if test "${with_bash+set}" = set; then + withval=$with_bash; BASH_PATH=$withval +fi + + +# Extract the first word of "g++", so it can be a program name with args. +set dummy g++; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_RUNTIME_COMPILER+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $RUNTIME_COMPILER in + [\\/]* | ?:[\\/]*) + ac_cv_path_RUNTIME_COMPILER="$RUNTIME_COMPILER" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_RUNTIME_COMPILER="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + test -z "$ac_cv_path_RUNTIME_COMPILER" && ac_cv_path_RUNTIME_COMPILER="g++" + ;; +esac +fi +RUNTIME_COMPILER=$ac_cv_path_RUNTIME_COMPILER +if test -n "$RUNTIME_COMPILER"; then + { echo "$as_me:$LINENO: result: $RUNTIME_COMPILER" >&5 +echo "${ECHO_T}$RUNTIME_COMPILER" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + +# Check whether --with-runtime was given. +if test "${with_runtime+set}" = set; then + withval=$with_runtime; RUNTIME_COMPILER=$withval +fi + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + + +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset x; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *ccp; + char **p; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + ccp = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !x[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6; } +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_inline=$ac_kw +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$ac_cv_c_inline" >&6; } + + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + + + +for ac_func in strtod +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +ac_config_files="$ac_config_files Makefile samples/Makefile doc/Makefile" + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${ENABLE_EPIX_EL_TRUE}" && test -z "${ENABLE_EPIX_EL_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"ENABLE_EPIX_EL\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"ENABLE_EPIX_EL\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +# Find out whether ``test -x'' works. Don't use a zero-byte file, as +# systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + as_executable_p="test -x" +else + as_executable_p=: +fi +rm -f conf$$.file + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by epix $as_me 1.2.1, which was +generated by GNU Autoconf 2.60. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Configuration commands: +$config_commands + +Report bugs to <bug-autoconf@gnu.org>." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +epix config.status 1.2.1 +configured by $0, generated by GNU Autoconf 2.60, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "samples/Makefile") CONFIG_FILES="$CONFIG_FILES samples/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +CYGPATH_W!$CYGPATH_W$ac_delim +PACKAGE!$PACKAGE$ac_delim +VERSION!$VERSION$ac_delim +ACLOCAL!$ACLOCAL$ac_delim +AUTOCONF!$AUTOCONF$ac_delim +AUTOMAKE!$AUTOMAKE$ac_delim +AUTOHEADER!$AUTOHEADER$ac_delim +MAKEINFO!$MAKEINFO$ac_delim +install_sh!$install_sh$ac_delim +STRIP!$STRIP$ac_delim +INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim +mkdir_p!$mkdir_p$ac_delim +AWK!$AWK$ac_delim +SET_MAKE!$SET_MAKE$ac_delim +am__leading_dot!$am__leading_dot$ac_delim +AMTAR!$AMTAR$ac_delim +am__tar!$am__tar$ac_delim +am__untar!$am__untar$ac_delim +MAINTAINER_MODE_TRUE!$MAINTAINER_MODE_TRUE$ac_delim +MAINTAINER_MODE_FALSE!$MAINTAINER_MODE_FALSE$ac_delim +MAINT!$MAINT$ac_delim +CXX!$CXX$ac_delim +CXXFLAGS!$CXXFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CXX!$ac_ct_CXX$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +DEPDIR!$DEPDIR$ac_delim +am__include!$am__include$ac_delim +am__quote!$am__quote$ac_delim +AMDEP_TRUE!$AMDEP_TRUE$ac_delim +AMDEP_FALSE!$AMDEP_FALSE$ac_delim +AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim +CXXDEPMODE!$CXXDEPMODE$ac_delim +am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim +am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim +LN_S!$LN_S$ac_delim +RANLIB!$RANLIB$ac_delim +ENABLE_EPIX_EL_TRUE!$ENABLE_EPIX_EL_TRUE$ac_delim +ENABLE_EPIX_EL_FALSE!$ENABLE_EPIX_EL_FALSE$ac_delim +BASH_PATH!$BASH_PATH$ac_delim +RUNTIME_COMPILER!$RUNTIME_COMPILER$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +CCDEPMODE!$CCDEPMODE$ac_delim +am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim +am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 94; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS <conf$$subs.sed +rm -f conf$$subs.sed +cat >>$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :C $CONFIG_COMMANDS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + + + :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 +echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir=$dirpart/$fdir + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + + esac +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/graphics/epix/configure.ac b/graphics/epix/configure.ac new file mode 100644 index 0000000000..b751aa69c4 --- /dev/null +++ b/graphics/epix/configure.ac @@ -0,0 +1,58 @@ +dnl Process this file with autoconf 2.60 or later +dnl to produce a configure script. +AC_INIT(epix, 1.2.1) +AC_PREREQ(2.60) +AC_CONFIG_SRCDIR(utils.h) +AM_INIT_AUTOMAKE +AM_MAINTAINER_MODE + +dnl Checks for programs. +AC_PROG_CXX +AC_PROG_LN_S +AC_PROG_RANLIB +AC_PROG_MAKE_SET +AC_PROG_INSTALL + +dnl User may request epix.el non-installation +AC_ARG_ENABLE(epix-el, + AS_HELP_STRING([--enable-epix-el], + [Install emacs mode for ePiX files]), + enable_epix_el=${enableval-yes}, + enable_epix_el=yes) +AM_CONDITIONAL(ENABLE_EPIX_EL, [test "$enable_epix_el" = yes]) + +dnl For all shell scripts +AC_PATH_PROG(BASH_PATH, bash, /bin/bash) +AC_ARG_WITH(bash, + AS_HELP_STRING([--with-bash=<bash>], + [The path to bash]), + BASH_PATH=$withval) + +dnl For epix and flix +AC_PATH_PROG(RUNTIME_COMPILER, g++, g++) +AC_ARG_WITH(runtime, + AS_HELP_STRING([--with-runtime=<g++>], + [The runtime compiler]), + RUNTIME_COMPILER=$withval) + +dnl AC_ARG_WITH(contrib, +dnl AS_HELP_STRING([--with-contrib], +dnl [Build contributed code and docs])) +dnl AM_CONDITIONAL(BUILD_CONTRIB, [test "$with_contrib" = yes]) + +dnl Checks for libraries. + +dnl Checks for header files. +AC_HEADER_STDC + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE + +dnl Checks for library functions. +AC_CHECK_FUNCS(strtod) + +AC_CONFIG_FILES([Makefile samples/Makefile doc/Makefile]) +dnl contrib/Makefile contrib/doc/Makefile]) + +AC_OUTPUT diff --git a/graphics/epix/constants.h b/graphics/epix/constants.h new file mode 100644 index 0000000000..c888c1d4da --- /dev/null +++ b/graphics/epix/constants.h @@ -0,0 +1,108 @@ +/* + * constants.h -- ePiX's hidden compile-time constants + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.15 + * Last Change: September 08, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_CONSTANTS +#define EPIX_CONSTANTS + +#include "length.h" + +namespace ePiX { + + // See lengths.cc for units conversion factors + + //// Style Parameters -- min, default, max //// + // standard pen widths + const length PLAIN_WIDTH("0.4pt"); + const length BOLD_WIDTH("0.8pt"); + const length BBOLD_WIDTH("1.2pt"); + + + // dot diam in pt + const double MIN_DOT(1); + const double AVG_DOT(4); + const double MAX_DOT(36); + + // page length of dash pattern in pt + const double MIN_SEP(4); + const double AVG_SEP(12); + const double MAX_SEP(36); + + // axis tick half-lengths + const double MIN_TICK(1); + const double AVG_TICK(3); + const double MAX_TICK(8); + + // arrow head parameters + const double MIN_AWIDTH(1); + const double AVG_AWIDTH(3); + const double MAX_AWIDTH(12); + + const double MIN_ARATIO(1); + const double AVG_ARATIO(5.5); + const double MAX_ARATIO(8); + + const double MIN_INSET(-1); + const double AVG_INSET(0); + const double MAX_INSET(0.95); // not 1, so head can be hatched + + + // too small/large + const double EPIX_EPSILON(0.0001); // 10^-4 (prints as decimal) + const double EPIX_INFTY(100000.0); // 10^5 + + // Numerical constants + const double PI_180(0.01745329251994329577); + const double TWO_PI(6.28318530717958647692); + + // smallest distance from camera to clipping plane + const double MIN_CLIP(0.01); + + // No more than this many minor ticks per segment in log axis + const unsigned int MAX_LOG_BASE(100); + + // For output + const unsigned int DEF_PRECISION(6); + const unsigned int MAX_PRECISION(20); + + // In calculus plotting, the interval between adjacent points is too large + // for accuracy. Divide each such interval into this many subintervals + const unsigned int EPIX_ITERATIONS(200); + + // Output-formatting constants: + const unsigned int EPIX_NUM_PTS(120); // # of points in ellipses, splines + const unsigned int EPIX_FILE_WIDTH(70); // Width of output file + +} // end of namespace + +#endif /* EPIX_CONSTANTS */ diff --git a/graphics/epix/crop_algorithms.h b/graphics/epix/crop_algorithms.h new file mode 100644 index 0000000000..e81646958e --- /dev/null +++ b/graphics/epix/crop_algorithms.h @@ -0,0 +1,225 @@ +/* + * crop_algorithms.h -- clipping/cropping templates + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.9 + * Last Change: July 31, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file defines list<edge> manipulating template functions and + * associated utilities. Each chop function returns a reference to its + * list<edge> argument. + * + * double height(perp, base, arg) + * PT cut_location(perp, base, tail, head) + * cull(edges) // remove edges whose tail and head are equal + * loopify(edges) // replace contiguous unseen edges with one seen edge + * chop_path(perp, base, edges) // cull to a halfspace/halfplane + * chop_loop(perp, base, edges) // same, for loops + */ + +#ifndef EPIX_CROP_ALGO +#define EPIX_CROP_ALGO + +#include <list> + +#include "constants.h" + +namespace ePiX { + + // perp assumed to be *unit* + template <typename PT> + double height(const PT& perp, const PT& base, const PT& arg) + { + // return (perp|(operator-(arg, base))); + return (perp|(arg - base)); + } + + // no check for parallel + template <typename PT> + PT cut_location(const PT& perp, const PT& base, const PT& p1, const PT& p2) + { + // PT dir(operator-(p2, p1)); // -dir to base + // return p1 + (((operator-(base, p1))|perp)/(dir|perp))*dir; + PT dir(p2 - p1); // -dir to base + return p1 + (((base - p1)|perp)/(dir|perp))*dir; + } + + // remove edges whose tail, head are equal + template <typename PT> + std::list<edge_data<PT> >& cull(std::list<edge_data<PT> >& edges) + { + typename std::list<edge_data<PT> >::iterator ep(edges.begin()); + + while (ep != edges.end()) + { + if ((*ep).is_null()) + ep = edges.erase(ep); + + else + ++ep; + } + + return edges; + } + + template <typename PT> + std::list<edge_data<PT> >& loopify(std::list<edge_data<PT> >& edges) + { + if (edges.begin() == edges.end()) + return edges; + + typename std::list<edge_data<PT> >::iterator ep(edges.begin()); + bool in_path(false); // currently in a visible sublist? + + // After first pass, ep points to first visible edge + while (ep != edges.end()) + { + if (!(*ep).is_seen()) // invisible edge + { + ep=edges.erase(ep); + in_path=false; + continue; + } + + // else visible edge + if (in_path) + { + ++ep; + continue; + } + + // else + in_path=true; + if (ep != edges.begin()) // join our tail to previous head + { + typename std::list<edge_data<PT> >::iterator prev(ep); + --prev; + ep = edges.insert(ep, edge_data<PT>((*prev).head(), + (*ep).tail(), + true)); + ++ep; + ++ep; + } + } + + // all edges examined; if we contain multiple edges, close final cut + ep = edges.begin(); + // contains at most one edge + if (ep == edges.end()) + ; // return below + + else if (++ep == edges.end()) + edges.erase(edges.begin()); + + else + { + ep = edges.end(); + --ep; + edges.push_back(edge_data<PT>((*ep).head(), + (*edges.begin()).tail(), + true)); + } + + return edges; + } // end of loopify() + + + // return result of clipping edges to half space/plane through base + // with unit inward normal perp + template <typename PT> + std::list<edge_data<PT> >& chop_path(const PT& perp, const PT& base, + std::list<edge_data<PT> >& edges) + { + typename std::list<edge_data<PT> >::iterator ep(edges.begin()); + + while(ep != edges.end()) + { + if (!(*ep).is_seen()) + { + ++ep; + continue; + } + + // else + const PT tail((*ep).tail()); + const PT head((*ep).head()); + + const double ht_tail(height(perp, base, tail)); + const double ht_head(height(perp, base, head)); + + // non-crossings: + // unclipped + if (-EPIX_EPSILON < ht_tail && -EPIX_EPSILON < ht_head) + { + ++ep; + continue; + } + + // clipped + else if (ht_tail <= 0 && ht_head <= 0) + { + (*ep).seen(false); + ++ep; + continue; + } + + // else one end below -EPS, one above 0; split edge + const PT crossing(cut_location(perp, base, tail, head)); + + // visibility of segments + bool vis_tail(false), vis_head(true); + + if (0 < ht_tail) + { + vis_tail=true; + vis_head=false; + } + + ep = edges.erase(ep); + ep=edges.insert(ep, edge_data<PT>(crossing, head, vis_head)); + ep=edges.insert(ep, edge_data<PT>(tail, crossing, vis_tail)); + ++ep; + ++ep; + } // all edges examined + + return cull(edges); + } // end of chop_path() + + + template <typename PT> + std::list<edge_data<PT> >& chop_loop(const PT& perp, const PT& base, + std::list<edge_data<PT> >& edges) + { + return loopify(chop_path(perp, base, edges)); + } +} // end of namespace + +#endif /* EPIX_CROP_ALGO */ diff --git a/graphics/epix/cropping.cc b/graphics/epix/cropping.cc new file mode 100644 index 0000000000..3bc89a030b --- /dev/null +++ b/graphics/epix/cropping.cc @@ -0,0 +1,88 @@ +/* + * state_data.cc -- Implementation of ePiX's current drawing state + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.4 + * Last Change: June 17, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file defines (wrapper functions for) static objects that hold + * the current drawing state + */ + +#include <list> + +#include "constants.h" +#include "screen_mask.h" +#include "mask_ellipse.h" +#include "mask_rectangle.h" + +#include "cropping.h" + +namespace ePiX { + + crop_state::crop_state(const crop_state& cs) + : crop_state_mask(cs.crop_state_mask->clone()) { } + + crop_state& crop_state::operator= (const crop_state& cs) + { + if (this != &cs) + { + screen_mask* tmp(cs.crop_state_mask->clone()); + + delete crop_state_mask; + crop_state_mask=tmp; + } + + return *this; + } + + crop_state::~crop_state() + { + delete crop_state_mask; + } + + std::list<edge2d>& crop_state::crop_path(std::list<edge2d>& L) const + { + return crop_state_mask->crop_path(L); + } + + std::list<edge2d>& crop_state::crop_loop(std::list<edge2d>& L) const + { + return crop_state_mask->crop_loop(L); + } + + crop_state& the_crop_box() + { + const pair M(EPIX_INFTY, EPIX_INFTY); + static crop_state* current_crop_box(new crop_state(mask_rectangle(-M,M))); + return *current_crop_box; + } +} // end of namespace diff --git a/graphics/epix/cropping.h b/graphics/epix/cropping.h new file mode 100644 index 0000000000..b8885e528b --- /dev/null +++ b/graphics/epix/cropping.h @@ -0,0 +1,68 @@ +/* + * cropping.h -- Implementation of ePiX's current drawing state. + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.0.23 + * Last Change: January 07, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * The class in this file implements backend for user-level global + * functions defined in state.h. This header is not part of epix.h. + */ +#ifndef EPIX_CROPPING +#define EPIX_CROPPING + +#include <string> + +#include "edge_data.h" +#include "screen_mask.h" + +namespace ePiX { + + class crop_state { + public: + crop_state(const screen_mask& M) + : crop_state_mask(M.clone()) { } + + crop_state(const crop_state&); + crop_state& operator= (const crop_state&); + ~crop_state(); + + std::list<edge2d>& crop_path(std::list<edge2d>&) const; + std::list<edge2d>& crop_loop(std::list<edge2d>&) const; + + private: + screen_mask* crop_state_mask; + + }; // end of class crop_state + +} // end of namespace + +#endif /* EPIX_CROPPING */ diff --git a/graphics/epix/curves.cc b/graphics/epix/curves.cc new file mode 100644 index 0000000000..5783dcf83c --- /dev/null +++ b/graphics/epix/curves.cc @@ -0,0 +1,663 @@ +/* + * curves.cc -- polygons, ellipses, circular arcs, splines + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <cmath> + +#include "constants.h" +#include "triples.h" +#include "errors.h" + +#include "functions.h" +#include "pairs.h" + +#include "camera.h" + +#include "active_screen.h" +#include "screen.h" + +#include "paint_style.h" + +#include "state.h" +#include "domain.h" + +#include "arrow_data.h" +#include "path.h" +#include "picture.h" + +#include "spline.h" +#include "spline_data.h" +#include "curves.h" + +namespace ePiX { + + // Simple geometric objects + + // Lines take a stretch factor, roughly in percent + void line(const P& tail, const P& head, double expand) + { + unsigned int num_pts(cam().is_linear() ? 2 : EPIX_NUM_PTS); + + path data(tail, head, expand, num_pts); + data.draw(); + } + + void line(const P& tail, const P& head, double expand, + unsigned int num_pts) + { + if (!cam().is_linear()) + num_pts = (unsigned int) max(num_pts, EPIX_NUM_PTS); + + path data(tail, head, expand, num_pts); + data.draw(); + } + + // Line(p1, p2) -- draw uncropped portion of long line through p1, p2 + void Line(const P& arg1, const P& arg2) + { + P dir(arg2-arg1); + const double denom(norm(dir)); + + if (EPIX_EPSILON < denom) + { + // TO DO: Not as robust as could be: + // 1. Assumes endpoint(s) are fairly close to origin + // 2. May not handle non-linear lenses well + dir *= 1/denom; + line(arg1-EPIX_INFTY*dir, arg1+EPIX_INFTY*dir); + } + } // end of Line + + + // point-slope form + void Line(const P& tail, double slope) + { + Line(tail, tail+P(1, slope, 0)); + } + + + void triangle(const P& p1, const P& p2, const P& p3) + { + path data; + if (cam().is_linear()) + data.pt(p1).pt(p2).pt(p3); + else + { + // Magic number 60 + const unsigned int N(60); + const double dt(1.0/N); + + const P step12(dt*(p2-p1)); + const P step23(dt*(p3-p2)); + const P step31(dt*(p1-p3)); + + for (unsigned int i=0; i<N; ++i) + data.pt(p1 + i*step12); + + for (unsigned int i=0; i<N; ++i) + data.pt(p2 + i*step23); + + for (unsigned int i=0; i<N; ++i) + data.pt(p3 + i*step31); + } + + data.close().fill(the_paint_style().fill_flag()); + data.draw(); + } + + void quad(const P& p1, const P& p2, const P& p3, const P& p4) + { + path data; + if (cam().is_linear()) + data.pt(p1).pt(p2).pt(p3).pt(p4); + else + { + // Magic number 60 -> quad has 240 pts, is printed in one segment + const unsigned int N(60); + const double dt(1.0/N); + + const P step12(dt*(p2-p1)); + const P step23(dt*(p3-p2)); + const P step34(dt*(p4-p3)); + const P step41(dt*(p1-p4)); + + for (unsigned int i=0; i<N; ++i) + data.pt(p1 + i*step12); + + for (unsigned int i=0; i<N; ++i) + data.pt(p2 + i*step23); + + for (unsigned int i=0; i<N; ++i) + data.pt(p3 + i*step34); + + for (unsigned int i=0; i<N; ++i) + data.pt(p4 + i*step41); + } + + data.close().fill(the_paint_style().fill_flag()); + data.draw(); + } + + // Draw coordinate rectangle with opposite corners as given. Arguments + // must lie is a plane parallel to a coordinate plane, but not on a + // line parallel to a coordinate axis. + + void rect(const P& p1, const P& p2) + { + P diagonal(p2 - p1); + P jump; + int perp_count(0); + + // count coordinate axes perp to diagonal and flag normal + if (fabs(diagonal|E_1) < EPIX_EPSILON) + { + ++perp_count; + jump = E_2&(diagonal); + } + if (fabs(diagonal|E_2) < EPIX_EPSILON) + { + ++perp_count; + jump = E_3&(diagonal); + } + if (fabs(diagonal|E_3) < EPIX_EPSILON) + { + ++perp_count; + jump = E_1&(diagonal); + } + + quad(p1, p1+jump, p2, p2-jump); + } // end rect + + void dart(const P& tail, const P& head) + { + arrow(tail, head, 0.5); + } + + void aarrow(const P& tail, const P& head, double scale) + { + P midpt(0.5*(tail+head)); + arrow(midpt, tail, scale); + arrow(midpt, head, scale); + } + + void ellipse(const P& center, const P& axis1, const P& axis2, + double t_min, double t_max, unsigned int num_pts) + { + path data(center, axis1, axis2, t_min, t_max, num_pts); + + + if (min(fabs(t_max-t_min)/full_turn(), 1) == 1) + { + data.close(); + if (the_paint_style().fill_flag()) + data.fill(); + } + data.draw(); + } + + void ellipse(const P& center, const P& axis1, const P& axis2, + double t_min, double t_max) + { + ellipse(center, axis1, axis2, t_min, t_max, EPIX_NUM_PTS); + } + + + void ellipse(const P& center, const P& axis1, const P& axis2) + { + ellipse(center, axis1, axis2, 0, full_turn()); + } + + + void ellipse_arc(const P& center, const P& axis1, const P& axis2, + double t_min, double t_max) + { + ellipse(center, axis1, axis2, t_min, t_max); + } + + + void arrow(const P& tail, const P& head, double scale) + { + std::vector<P> shaft(2); + shaft.at(0) = tail; + shaft.at(1) = head; + + arrow_data data(shaft, tail, head, scale); + data.draw(); + } + + void ellipse(const P& center, const P& radius) + { + ellipse(center, radius.x1()*E_1, radius.x2()*E_2); + } + + // Standard half-ellipse functions + void ellipse_left (const P& center, const P& radius) + { + ellipse(center, radius.x1()*E_1, radius.x2()*E_2, + 0.25*full_turn(), 0.75*full_turn()); + } + + void ellipse_right (const P& center, const P& radius) + { + ellipse(center, radius.x1()*E_1, radius.x2()*E_2, + -0.25*full_turn(), 0.25*full_turn()); + } + + void ellipse_top (const P& center, const P& radius) + { + ellipse(center, radius.x1()*E_1, radius.x2()*E_2, 0, 0.5*full_turn()); + } + + void ellipse_bottom (const P& center, const P& radius) + { + ellipse(center, radius.x1()*E_1, radius.x2()*E_2, -0.5*full_turn(), 0); + } + + void arc(const P& center, double r, + double start, double finish) + { + ellipse(center, r*E_1, r*E_2, start, finish); + } + + void arrow(const P& center, const P& axis1, const P& axis2, + double t_min, double t_max, double scale) + { + // EPIX_NUM_PTS pts = one full turn; scale accordingly + double frac(fabs(t_max-t_min)/full_turn()); + unsigned int num_pts((unsigned int) max(2, ceil(frac*EPIX_NUM_PTS))); + + const double dt((t_max - t_min)/num_pts); + + std::vector<P> shaft(num_pts+1); + + for (unsigned int i=0; i <= num_pts; ++i) + { + double t(t_min + i*dt); + shaft.at(i) = center + ((Cos(t)*axis1)+(Sin(t)*axis2)); + } + + arrow_data data(shaft, shaft.at(num_pts-1), shaft.at(num_pts), scale); + data.draw(); + } + + // circular arcs parallel to (x,y)-plane + + void arc_arrow(const P& center, double r, + double start, double finish, double scale) + { + arrow(center, r*E_1, r*E_2, start, finish, scale); + } + + + // quadratic spline + void spline(const P& p1, const P& p2, const P& p3, unsigned int num_pts) + { + path data(p1, p2, p3, num_pts); + data.draw(); + } + + void spline(const P& p1, const P& p2, const P& p3) + { + spline(p1, p2, p3, EPIX_NUM_PTS); + } + + void arrow(const P& p1, const P& p2, const P& p3, double scale) + { + const unsigned int num_pts(EPIX_NUM_PTS); + const double dt(1.0/num_pts); + std::vector<P> shaft(num_pts+1); + + for (unsigned int i=0; i <= num_pts; ++i) + shaft.at(i) = spl_pt(p1, p2, p3, i*dt); + + arrow_data data(shaft, shaft.at(num_pts-1), shaft.at(num_pts), scale); + data.draw(); + } + + // cubic spline + void spline(const P& p1, const P& p2, + const P& p3, const P& p4, unsigned int num_pts) + { + path data(p1, p2, p3, p4, num_pts); + data.draw(); + } + + void spline(const P& p1, const P& p2, const P& p3, const P& p4) + { + spline(p1, p2, p3, p4, EPIX_NUM_PTS); + } + + // natural spline through points + void spline(const std::vector<P>& data, unsigned int num_pts) + { + n_spline tmp(data, data.at(0) == data.at(data.size()-1)); + path trace(tmp.data(num_pts)); + + trace.draw(); + } + + void arrow(const P& p1, const P& p2, const P& p3, const P& p4, double scale) + { + const unsigned int num_pts(EPIX_NUM_PTS); + const double dt(1.0/num_pts); + std::vector<P> shaft(num_pts+1); + + for (unsigned int i=0; i <= num_pts; ++i) + shaft.at(i) = spl_pt(p1, p2, p3, p4, i*dt); + + arrow_data data(shaft, shaft.at(num_pts-1), shaft.at(num_pts), scale); + data.draw(); + } + + + // n1 x n2 Cartesian grid, where coarse = (n1, n2) + void grid(const P& p1, const P& p2, mesh coarse, mesh fine) + { + P diagonal(p2 - p1); + P jump1, jump2; // sides of grid + + int perp_count(0); + + int N1(coarse.n1()); + int N2(coarse.n2()); + + // count coordinate axes diagonal is perp to and flag normal + if (fabs(diagonal|E_1) < EPIX_EPSILON) + { + ++perp_count; + jump1 = E_2&diagonal; + jump2 = E_3&diagonal; + + } + if (fabs(diagonal|E_2) < EPIX_EPSILON) + { + ++perp_count; + jump1 = E_3&diagonal; + jump2 = E_1&diagonal; + } + if (fabs(diagonal|E_3) < EPIX_EPSILON) + { + ++perp_count; + jump1 = E_1&diagonal; + jump2 = E_2&diagonal; + } + + if (perp_count != 1) + epix_warning("Ignoring degenerate coordinate grid"); + + else + { + // grid line spacing + P grid_step1((1.0/N1)*jump1); + P grid_step2((1.0/N2)*jump2); + + // makes grid subject to filling + rect(p1, p1 + jump1 + jump2); + + for (int i=1; i < N1; ++i) + line(p1+i*grid_step1, p1+i*grid_step1+jump2, 0, fine.n2()); + + for (int j=1; j < N2; ++j) + line(p1+j*grid_step2, p1+j*grid_step2+jump1, 0, fine.n1()); + } + } + + // Grids that fill bounding_box with default camera + void grid(const P& p1, const P& p2, unsigned int n1, unsigned int n2) + { + grid(p1, p2, mesh(n1, n2), mesh(1,1)); + } + + void grid(unsigned int n1, unsigned int n2) + { + grid(active_screen()->bl(), active_screen()->tr(), n1, n2); + } + + + // polar grid with specified radius, mesh (rings and sectors), and resolution + void polar_grid(double radius, mesh coarse, mesh fine) + { + for (int i=1; i <= coarse.n1(); ++i) + ellipse(P(0,0,0), + (i*radius/coarse.n1())*E_1, (i*radius/coarse.n1())*E_2, + 0, full_turn(), fine.n2()); + + for (int j=0; j < coarse.n2(); ++j) + line(P(0,0,0), polar(radius, j*(full_turn())/coarse.n2()), + 0, 2*fine.n1()); + } + + void polar_grid(double radius, unsigned int n1, unsigned int n2) + { + polar_grid(radius, mesh(n1,n2), mesh(n1,EPIX_NUM_PTS)); + } + + + // logarithmic grids + + // local helpers + void grid_lines1_log(double x_lo, double x_hi, double y_lo, double y_hi, + unsigned int segs, unsigned int base) + { + if (segs == 0) + return; + + const double dx((x_hi-x_lo)/segs); // "major grid" steps + const double denom(log(base)); // "minor"/log grid scale factor + + for (unsigned int i=0; i < segs; ++i) + for (unsigned int j=1; j<base; ++j) + { + double x_tmp(x_lo + dx*(i+log(j)/denom)); + + line(P(x_tmp, y_lo), P(x_tmp, y_hi)); + } + + line(P(x_hi,y_lo), P(x_hi, y_hi)); // draw rightmost line manually + } + + void grid_lines2_log(double x_lo, double x_hi, double y_lo, double y_hi, + unsigned int segs, unsigned int base) + { + if (segs == 0) + return; + + const double dy((y_hi-y_lo)/segs); + const double denom(log(base)); + + for (unsigned int i=0; i < segs; ++i) + for (unsigned int j=1; j<base; ++j) + { + double y_tmp(y_lo + dy*(i+log(j)/denom)); + + line(P(x_lo, y_tmp), P(x_hi, y_tmp)); + } + + line(P(x_hi,y_lo), P(x_hi, y_hi)); + } + + // global functions + void log_grid(const P& p1, const P& p2, + unsigned int segs1, unsigned int segs2, + unsigned int base1, unsigned int base2) + { + grid_lines1_log(min(p1.x1(), p2.x1()), max(p1.x1(), p2.x1()), + min(p1.x2(), p2.x2()), max(p1.x2(), p2.x2()), + segs1, base1); + + grid_lines2_log(min(p1.x1(), p2.x1()), max(p1.x1(), p2.x1()), + min(p1.x2(), p2.x2()), max(p1.x2(), p2.x2()), + segs2, base2); + } + + void log1_grid(const P& p1, const P& p2, + unsigned int segs1, unsigned int segs2, + unsigned int base1) + { + grid_lines1_log(min(p1.x1(), p2.x1()), max(p1.x1(), p2.x1()), + min(p1.x2(), p2.x2()), max(p1.x2(), p2.x2()), + segs1, base1); + + grid_lines2_log(min(p1.x1(), p2.x1()), max(p1.x1(), p2.x1()), + min(p1.x2(), p2.x2()), max(p1.x2(), p2.x2()), + segs2, 2); + } + + void log2_grid(const P& p1, const P& p2, + unsigned int segs1, unsigned int segs2, + unsigned int base2) + { + grid_lines1_log(min(p1.x1(), p2.x1()), + max(p1.x1(), p2.x1()), + min(p1.x2(), p2.x2()), + max(p1.x2(), p2.x2()), + segs1, 2); + + grid_lines2_log(min(p1.x1(), p2.x1()), + max(p1.x1(), p2.x1()), + min(p1.x2(), p2.x2()), + max(p1.x2(), p2.x2()), + segs2, base2); + } + + + // grids fill current bounding box + void log_grid(unsigned int segs1, unsigned int segs2, + unsigned int base1, unsigned int base2) + { + grid_lines1_log(active_screen()->h_min(), active_screen()->h_max(), + active_screen()->v_min(), active_screen()->v_max(), + segs1, base1); + + grid_lines2_log(active_screen()->h_min(), active_screen()->h_max(), + active_screen()->v_min(), active_screen()->v_max(), + segs2, base2); + } + + void log1_grid(unsigned int segs1, unsigned int segs2, + unsigned int base1) + { + grid_lines1_log(active_screen()->h_min(), active_screen()->h_max(), + active_screen()->v_min(), active_screen()->v_max(), + segs1, base1); + + grid_lines2_log(active_screen()->h_min(), active_screen()->h_max(), + active_screen()->v_min(), active_screen()->v_max(), + segs2, 2); + } + + void log2_grid(unsigned int segs1, unsigned int segs2, + unsigned int base2) + { + grid_lines1_log(active_screen()->h_min(), active_screen()->h_max(), + active_screen()->v_min(), active_screen()->v_max(), + segs1, 2); + + grid_lines2_log(active_screen()->h_min(), active_screen()->h_max(), + active_screen()->v_min(), active_screen()->v_max(), + segs2, base2); + } + + + // fractal generation + // + // The basic recursion unit is a piecewise-linear path whose segments + // are parallel to spokes on a wheel, labelled modulo <spokes>. + // Recursively up to <depth>, each segment is replaced by a copy of the + // recursion unit, scaled and rotated in order to join p to q. + // + // Kludge: pre_seed[0] = spokes, pre_seed[1] = length of seed; + // + // Sample data for _/\_ standard Koch snowflake: + // const int seed[] = {6, 4, 0, 1, -1, 0}; + + P jump(int spokes, int length, const std::vector<int>& seed) + { + P sum(P(0,0)); + + for (int i=0; i< length; ++i) + sum += cis(seed.at(i)*(full_turn())/spokes); + + return sum; + } + + void fractal(const P& p, const P& q, const int depth, const int *pre_seed) + { + int spokes(pre_seed[0]); + int seed_length(pre_seed[1]); + std::vector<int> seed(seed_length); + + // extract seed from pre_seed + for (int i=0; i<seed_length; ++i) + seed.at(i) = pre_seed[i+2]; + + // Unit-length steps in <seed> sequence add up to <scale> + P scale(jump(spokes, seed_length, seed)); + + // Number of points in final fractal + int length(1+(int)pow(seed_length, depth)); + std::vector<int> dir(length); // stepping information + std::vector<P> data(length); // vertices + + // dir[] starts out [0, 1, -1, 0, ..., 0] (seed_length^depth entries) + // then take repeated "Kronecker sum" with seed = [0, 1, -1, 0] + + for(int i=0; i<seed_length; ++i) + dir.at(i) = seed.at(i); + + for(int i=1; i<depth; ++i) // recursively fill dir array + for(int j=0; j < pow(seed_length,i); ++j) + for(int k=seed_length-1; 0 < k; --k) + dir.at(k*(int)pow(seed_length,i) + j) = dir.at(j) + seed.at(k); + + P curr(p); + // 10/09/06: -depth -> 1-depth + double radius(pow(norm(scale), 1-depth)); + + for(int i=0; i<length; ++i) + { + data.at(i) = curr; + // increment between successive points as a pair + pair temp((polar(radius, dir.at(i)*(full_turn())/spokes))*pair(q-p)); + + // complex arithmetic + temp /= pair(scale); // homothety to join p to q + + curr += P(temp.x1(), temp.x2()); + } + + path fractal(data, false, false); + fractal.draw(); + } + +} // end of namespace diff --git a/graphics/epix/curves.h b/graphics/epix/curves.h new file mode 100644 index 0000000000..d15966d9b0 --- /dev/null +++ b/graphics/epix/curves.h @@ -0,0 +1,187 @@ +/* + * curves.h -- Ellipses, arcs, splines, coordinate grids + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.10 + * Last Change: August 08, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_CURVES +#define EPIX_CURVES + +#include <vector> + +#include "constants.h" + +namespace ePiX { + + class P; + class mesh; + + // lines can be "stretched" by double parameter + void line(const P& tail, const P& head, double expand=0); + void line(const P& tail, const P& head, double expand, + unsigned int num_pts); + + // "Visible" portion of the line through p1, p2 + void Line(const P& tail, const P& head); + + // point-slope form + void Line(const P&, double); + + void triangle(const P&, const P&, const P&); + void quad(const P&, const P&, const P&, const P&); + + void rect(const P&, const P&); + void rect(const P&, const P&, bool solid); + + // arrows + void arrow(const P& tail, const P& head, double scale=1); + void dart(const P& tail, const P& head); + + // double-tipped + void aarrow(const P& tail, const P& head, double scale=1); + + // arbitrary elliptical arc + void arrow(const P& center, const P& axis1, const P& axis2, + double t_min, double t_max, double scale=1); + + // Algebraic curves (elliptical and circular arcs, splines) + void ellipse(const P& center, const P& axis1, const P& axis2); // full turn + + void ellipse(const P& center, const P& axis1, const P& axis2, + double t_min, double t_max); // angle range + + void ellipse(const P& center, const P& axis1, const P& axis2, + double t_min, double t_max, unsigned int num_pts); + + // for backward compatibility + void ellipse_arc(const P& center, const P& axis1, const P& axis2, + double t_min, double t_max); + + // old style "center and polyradius" + void ellipse (const P& center, const P& radius); + + // Standard half-ellipse functions + void ellipse_left (const P&, const P&); + void ellipse_right (const P&, const P&); + void ellipse_top (const P&, const P&); + void ellipse_bottom (const P&, const P&); + + // Circular arcs parallel to (x,y)-plane + void arc(const P& center, double r, + double start, double finish); + + void arc_arrow (const P& center, double r, + double start, double finish, + double scale=1); + + + // Quadratic and cubic splines/spline arrows + void spline(const P& p1, const P& p2, const P& p3, unsigned int num_pts); + void spline(const P& p1, const P& p2, const P& p3); + + void arrow(const P& p1, const P& p2, const P& p3, double scale=1); + + void spline (const P& p1, const P& p2, const P& p3, const P& p4, + unsigned int num_pts); + void spline (const P& p1, const P& p2, const P& p3, const P& p4); + + void arrow(const P&, const P&, const P&, const P&, double scale=1); + + // natural spline + void spline(const std::vector<P>&, unsigned int num_pts); + + + // A "mesh" is an ordered pair of positive integers, and is used to + // specify the "fineness" of a grid. Grids, like parametric surface + // meshes, have a "coarse mesh" -- the numbers of grid intervals in + // each direction, and a "fine mesh" -- the numbers of points used + // to render the grid lines. Since an ePiX camera does not always + // map lines in object space to lines on the screen, grid lines cannot + // generally be drawn using only two points. + // A grid may look strange unless each component of fine is a multiple + // of the corresponding entry of coarse, of course. :) + + // Cartesian grid of specified size, mesh, and resolution + void grid(const P& arg1, const P& arg2, mesh coarse, mesh fine); + + // coarse = fine = (n1,n2) + void grid(const P& arg1, const P& arg2, + unsigned int n1=1, unsigned int n2=1); + void grid(unsigned int n1=1, unsigned int n2=1); + + // polar grid of specified radius, mesh (rings and sectors), and resolution + void polar_grid(double r, mesh coarse, mesh fine); + + // polar grid with n1 rings and n2 sectors + void polar_grid(double r, unsigned int n1, unsigned int n2); + + + // (semi-)logarithmic grids specified by corners and numbers of orders of + // magnitude or grid divisions in each direction. Optional arguments + // specify the log base (10 by default). If corners are omitted, the grid + // fills the bounding box. + void log_grid(const P& arg1, const P& arg2, + unsigned int segs1, unsigned int segs2, + unsigned int base1=10, unsigned int base2=10); + + void log1_grid(const P& arg1, const P& arg2, + unsigned int segs1, unsigned int segs2, + unsigned int base1=10); + + void log2_grid(const P& arg1, const P& arg2, + unsigned int segs1, unsigned int segs2, + unsigned int base2=10); + + void log_grid(unsigned int segs1, unsigned int segs2, + unsigned int base1=10, unsigned int base2=10); + + void log1_grid(unsigned int segs1, unsigned int segs2, + unsigned int base1=10); + + void log2_grid(unsigned int segs1, unsigned int segs2, + unsigned int base2=10); + + // fractal generation + // + // The basic "level-1" recursion unit is a piecewise-linear path whose + // segments are parallel to spokes on a wheel, labelled modulo <spokes>. + // Recursively up to <depth>, each segment is replaced by a copy of the + // recursion unit. + // + // Sample data for _/\_ standard Koch snowflake: + // const int pre_seed[] = {6, 4, 0, 1, -1, 0}; + // pre_seed[0] = spokes, pre_seed[1] = seed_length; + + void fractal (const P& p, const P& q, const int depth, const int *pre_seed); + +} // end of namespace + +#endif /* EPIX_CURVES */ diff --git a/graphics/epix/data_bins.cc b/graphics/epix/data_bins.cc new file mode 100644 index 0000000000..9474c1de25 --- /dev/null +++ b/graphics/epix/data_bins.cc @@ -0,0 +1,411 @@ +/* + * data_bins.cc -- ePiX::data_bins class for histogram data + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> +#include <string> +#include <sstream> +#include <list> +#include <vector> + +#include "errors.h" + +#include "constants.h" +#include "functions.h" +#include "triples.h" + +#include "path.h" +#include "spline.h" + +#include "curves.h" + +#include "data_bins.h" + +namespace ePiX { + + // print summary statistics + static void __epix_out_of_range(const std::string& fcn, + unsigned int lo, unsigned int hi, + unsigned int hits) + { + if (0 == lo + hi && 0 == hits) + return; + + // else + if (0 < lo + hi) + { + std::stringstream buf; + buf << fcn << " has " << lo + hi << " point(s) out of range: "; + + bool need_comma(false); + + if (0 < lo) + { + buf << lo << " below"; + need_comma = true; + } + + if (0 < hi) + { + if (need_comma) + buf << ", "; + + buf << hi << " above"; + } + epix_warning(buf.str()); + } + + if (0 < hits) + { + std::stringstream buf; + buf << fcn << " has " << hits/2 << " point(s) on cuts"; + epix_warning(buf.str()); + } + } + + + //// histogram data bin //// + class d_bin { + public: + d_bin(double low, double high) + : m_lo(low), m_hi(high), m_dbl_count(0) { } + + double add_datum(double x) + { + if (x < m_lo || m_hi < x) + return 0.0; + + else if (m_lo < x && x < m_hi) + { + m_dbl_count += 2; + return 1.0; + } + + else // x == m_lo || x == m_hi + { + ++m_dbl_count; + return 0.5; + } + } + + // draw rectangle; height = scale*population + void draw_ht(double scale) const + { + rect(P(m_lo,0), P(m_hi, 0.5*scale*m_dbl_count)); + } + + // area = scale*population + void draw_area(double scale) const + { + if (EPIX_EPSILON < m_hi - m_lo) + rect(P(m_lo,0), P(m_hi, 0.5*scale*m_dbl_count/(m_hi - m_lo))); + } + + double lo() const + { + return m_lo; + } + + double hi() const + { + return m_hi; + } + + double ht(double scale) const + { + return 0.5*scale*m_dbl_count; + } + + P loc(double scale) const + { + return P(0.5*(m_lo + m_hi), 0.5*scale*m_dbl_count); + } + + d_bin* clone() const + { + return new d_bin(*this); + } + + private: + double m_lo, m_hi; // end values + + // twice the number of elements; endpoint hits count as 1 + unsigned int m_dbl_count; + }; // end of class d_bin + + + //// data_bins functions //// + data_bins::data_bins(double lo, double hi, unsigned int n) + : m_lo_val(min(lo, hi)), m_hi_val(max(lo, hi)), + m_lo_ct(0), m_hi_ct(0), m_pop(0), m_cut_hits(0), + m_cuts_locked(false) + { + // divide [lo, hi] into n pieces (n>0), or into unit pieces (n=0) + unsigned int ct(n>0 ? n : (unsigned int)(m_hi_val - m_lo_val)); + const double dx((m_hi_val - m_lo_val)/ct); + + for (unsigned int i=0; i<=ct; ++i) + m_cuts.push_back(m_lo_val + i*dx); + } + + data_bins::data_bins(const data_bins& db) + : m_lo_val(db.m_lo_val), m_hi_val(db.m_hi_val), + m_lo_ct(db.m_lo_ct), m_hi_ct(db.m_hi_ct), + m_pop(db.m_pop), m_cut_hits(db.m_cut_hits), + m_cuts_locked(db.m_cuts_locked), m_cuts(db.m_cuts) + { + for (std::list<d_bin*>::const_iterator p=db.m_bins.begin(); + p != db.m_bins.end(); ++p) + m_bins.push_back((*p)->clone()); + } + + data_bins& data_bins::operator= (const data_bins& db) + { + if (this != &db) + { + std::list<d_bin*> tmp; + for (std::list<d_bin*>::const_iterator p=db.m_bins.begin(); + p!=db.m_bins.end(); ++p) + tmp.push_back((*p)->clone()); + + // assign data + m_lo_val = db.m_lo_val; + m_hi_val = db.m_hi_val; + + m_lo_ct = db.m_lo_ct; + m_hi_ct = db.m_hi_ct; + m_pop = db.m_pop; + m_cut_hits = db.m_cut_hits; + m_cuts_locked = db.m_cuts_locked; + + // deallocate memory + for (std::list<d_bin*>::iterator p=m_bins.begin(); + p!=m_bins.end(); ++p) + delete *p; + + m_cuts = db.m_cuts; + swap(m_bins, tmp); + } + + return *this; + } + + data_bins::~data_bins() + { + for (std::list<d_bin*>::iterator p=m_bins.begin(); p!=m_bins.end(); ++p) + delete *p; + } + + + data_bins& data_bins::cut(double x) + { + if (m_cuts_locked) + epix_warning("cut() called on locked data_bins, no action"); + + else if (x < m_lo_val || m_hi_val < x) + epix_warning("cut() out of range, no action"); + + else + m_cuts.push_back(x); + + return *this; + } + + data_bins& data_bins::read(const std::vector<double>& data) + { + if (0 < data.size()) + { + if (!m_cuts_locked) + initialize(); + + for (std::vector<double>::const_iterator p=data.begin(); + p != data.end(); ++p) + insert(*p); + } + return *this; + } + + unsigned int data_bins::pop() const + { + return m_pop; + } + + // rectangles + void data_bins::histogram(double scale) const + { + if (m_pop == 0) + return; + + // else + __epix_out_of_range("histogram", m_lo_ct, m_hi_ct, m_cut_hits); + + // const double denom((m_hi_val - m_lo_val)/m_pop); + const double adj(scale/m_pop); + + for (std::list<d_bin*>::const_iterator p=m_bins.begin(); + p != m_bins.end(); ++p) + (*p)->draw_area(adj); + } + + void data_bins::bar_chart(double scale) const + { + if (m_pop == 0) + return; + + // else + __epix_out_of_range("bar_chart", m_lo_ct, m_hi_ct, m_cut_hits); + + const double adj(scale/m_pop); // scale=1 -> ht=frac of pop in bin + + for (std::list<d_bin*>::const_iterator p=m_bins.begin(); + p != m_bins.end(); ++p) + (*p)->draw_ht(adj); + } + + // piecewise-cubic interpolation of bar_chart + void data_bins::plot(double scale) const + { + if (m_pop == 0) + return; + + // else + __epix_out_of_range("data_bins::plot", m_lo_ct, m_hi_ct, m_cut_hits); + + // get rectangle corners + std::vector<P> vertices; + + std::list<d_bin*>::const_iterator bn(m_bins.begin()); + vertices.push_back(P((*bn)->lo(),0)); + + for (bn = m_bins.begin(); bn != m_bins.end(); ++bn) + { + vertices.push_back(P((*bn)->lo(), (*bn)->ht(scale/m_pop))); + vertices.push_back(P((*bn)->hi(), (*bn)->ht(scale/m_pop))); + } + + --bn; // last bin + vertices.push_back(P((*bn)->hi(),0)); + + const unsigned int N(vertices.size()); + + // draw piecewise cubic interpolation + line(vertices.at(0), 0.5*(vertices.at(0) + vertices.at(1))); + + // Magic number 20 to reduce file size + for (unsigned int i=1; i< N-1; ++i) + spline(0.5*(vertices.at(i-1) + vertices.at(i)), + vertices.at(i), + vertices.at(i), + 0.5*(vertices.at(i) + vertices.at(i+1)), 20); + + line(0.5*(vertices.at(N-2) + vertices.at(N-1)), vertices.at(N-1)); + } // end of plot(scale) + + + // private bookkeeping functions + void data_bins::initialize() + { + if (!m_cuts_locked) // defensive redundancy + { + // sort list of cuts, remove duplicates, and lock + m_cuts.sort(); + m_cuts.unique(); + + m_cuts_locked=true; + + // allocate d_bins + for (std::list<double>::const_iterator curr = m_cuts.begin(); + curr != m_cuts.end(); ++curr) + { + std::list<double>::const_iterator next(curr); + ++next; + + if (next != m_cuts.end() && *curr != *next) + m_bins.push_back(new d_bin(*curr, *next)); + + else if (*curr != m_hi_val) + m_bins.push_back(new d_bin(*curr, m_hi_val)); + } + } + } + + // Ideally no data lies on a cut, but we'll cope as well as possible + // otherwise. Data on an end cut is "out of range". Data on an interior + // cut contributes 1/2 to the population of each adjacent bin. + void data_bins::insert(double x) + { + ++m_pop; + + std::list<d_bin*>::iterator p(m_bins.begin()); + + // check end bins first + if (x <= m_lo_val) + { + ++m_lo_ct; + if (fabs(x - m_lo_val) < EPIX_EPSILON) + { + (*p)->add_datum(x); + m_cut_hits += 2; + } + return; + } + + if (m_hi_val <= x) + { + ++m_hi_ct; + if (fabs(x - m_hi_val) < EPIX_EPSILON) + { + p = m_bins.end(); + --p; + (*p)->add_datum(x); + m_cut_hits += 2; + } + return; + } + + // else + double success(0.0); + p = m_bins.begin(); + + // try "normal" bins serially + while (success < 0.75 && p!=m_bins.end()) // success is a half-integer + { + double ct((*p++)->add_datum(x)); // 1 for yes, 0.5 for endpt, 0 for no + success += ct; + if (fabs(ct - 0.5) < EPIX_EPSILON) + ++m_cut_hits; + } + + if (success < 0.75) // still not added! + epix_warning("data_bin::insert() internal error"); + } +} // end of namespace diff --git a/graphics/epix/data_bins.h b/graphics/epix/data_bins.h new file mode 100644 index 0000000000..e0d9a200e6 --- /dev/null +++ b/graphics/epix/data_bins.h @@ -0,0 +1,101 @@ +/* + * data_bins.h -- ePiX::data_bins class for histogram data + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.19 + * Last Change: September 17, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file provides the "data_bins" class. + * + * An object of type data_bins models a closed interval [lo, hi] + * divided into subintervals (not necessarily of equal length). Each + * subinterval is a "d_bin", whose endpoints are "cuts". A data_bins + * can read and sort numerical data, count how many numbers lie in + * each bin, and print the result as a bar chart (rectangle height + * proportional to population), histogram (area proportional to + * population), or as a spline interpolation. + * + * Ideally no data lies outside (lo, hi) or on a cut. Data on an end + * cut is "out of range", data on an interior cut contributes 1/2 to + * the population of each adjacent bin. A summary statistic warning is + * printed if any points are out of range or lie on a cut. + */ + +#ifndef EPIX_DATA_BINS +#define EPIX_DATA_BINS + +#include <vector> +#include <list> + +namespace ePiX { + + class d_bin; + + class data_bins { + public: + data_bins(double lo, double hi, unsigned int n=1); + + data_bins(const data_bins&); + data_bins& operator= (const data_bins&); + ~data_bins(); + + data_bins& cut(double); // add a cut + data_bins& read(const std::vector<double>&); + + unsigned int pop() const; // current population + + // draw rectangles + void histogram(double scale=1) const; // area prop to pop + void bar_chart(double scale=1) const; // height prop to pop + void plot(double scale=1) const; // smooth interpolation + + private: + double m_lo_val; + double m_hi_val; + + unsigned int m_lo_ct; // population smaller than m_lo_val + unsigned int m_hi_ct; // population larger than m_hi_val + unsigned int m_pop; // current total population + + unsigned int m_cut_hits; // number of data on a cut + bool m_cuts_locked; // true once we read data + + std::list<double> m_cuts; + std::list<d_bin*> m_bins; + + // bookkeeping + void initialize(); // convert cuts to bins and lock + void insert(double); // add data point + }; // end of class data_bins + +} // end of namespace + +#endif /* EPIX_DATA_BINS */ diff --git a/graphics/epix/data_file.cc b/graphics/epix/data_file.cc new file mode 100644 index 0000000000..fb2e6a5a5b --- /dev/null +++ b/graphics/epix/data_file.cc @@ -0,0 +1,687 @@ +/* + * data_file.cc -- ePiX::data_file class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> +#include <fstream> +#include <sstream> +#include <list> +#include <vector> +#include <stdexcept> + +#include "errors.h" + +#include "functions.h" +#include "triples.h" +#include "path.h" +#include "spline.h" + +#include "label_data.h" +#include "curves.h" + +#include "interval.h" +#include "data_bins.h" +#include "data_mask.h" +#include "data_file.h" + +namespace ePiX { + + const std::string default_delim("\t"); + const std::string default_commt("%"); + + // magic number -- precision for data_file.write() + const unsigned int PRECISION(6); + + double truncate(double arg, const unsigned int n) + { + if (fabs(arg) < pow(0.1, n)) + return 0; + + return arg; + } + + // warning message for data_file::tokenize + void non_parsable(const std::string& msg) + { + std::stringstream obuf; + obuf << "data_file::tokenise():" << std::endl + << " Non-parsable input \"" << msg << "\", setting value to 0"; + epix_warning(obuf.str()); + } + + //// private data_file functions //// + // returns # of columns, i.e. # of entries in first parsable row + unsigned int data_file::entries(const char* filename) + { + std::ifstream input(filename); + if (!input) + { + epix_warning("Cannot open file \""+std::string(filename)+"\""); + return(0); + } + + // else + std::string linebuf; + std::vector<double> tmp; + + while (getline(input, linebuf) && tmp.size() == 0) + { + // strip comments + linebuf = linebuf.substr(0, linebuf.find_first_of(m_commt)); + if (linebuf.length() > 0) + tmp = tokenise(linebuf); + } + + input.close(); + + if (tmp.size() == 0) + { + std::stringstream obuf; // solely for code readability :) + obuf << "File \"" << std::string(filename) + << "\" contains no parsable data"; + + epix_warning(obuf.str()); + } + + return tmp.size(); + } // end of entries(const char*) + + + // private function: + // Tokenise line using our delimiter, return a vector of doubles + std::vector<double> data_file::tokenise(std::string line) + { + size_t pos(line.find(m_delim, 0)); // first delimiter + std::string tmpStr; // current chunk of input + double tmpDbl; // current parsed chunk + std::vector<double> tmpVec; // output found so far + + // read current line into a vector of doubles + while(pos != std::string::npos) + { + tmpStr = line.substr(0, pos); + line.erase(0, pos+1); + std::istringstream convStr(tmpStr); + + if (!(convStr >> tmpDbl)) + { + tmpDbl = 0; + non_parsable(convStr.str()); + } + + tmpVec.push_back(tmpDbl); + pos = line.find(m_delim, 0); + } + + if (line.size()) // There's input remaining + { + std::istringstream convStr(line); + + if (!(convStr >> tmpDbl)) + { + tmpDbl = 0; + non_parsable(convStr.str()); + } + + else + tmpVec.push_back(tmpDbl); + } + + return tmpVec; + } + + //// public data_file functions //// + data_file::data_file(unsigned int n) + : m_precision(PRECISION), m_data(n), + m_delim(default_delim), + m_commt(default_commt) { } + + // provide two version to avoid exposing default delim, commt + data_file::data_file(const char* filename, + const std::string& delim, const std::string& commt ) + : m_precision(PRECISION), m_delim(delim), m_commt(commt) + { + // get number of columns by parsing first line of file + const unsigned int N(entries(filename)); + m_data.resize(N); + + if (N > 0) // file contains data + read(filename); + + } // end of data_file() + + // filename-only version + data_file::data_file(const char* filename) + : m_precision(PRECISION), m_delim(default_delim), m_commt(default_commt) + { + // get number of columns by parsing first line of file + const unsigned int N(entries(filename)); + m_data.resize(N); + + if (N > 0) // file contains data + read(filename); + + } // end of data_file(const char*) + + + // file made from components + data_file::data_file(double f(double), + double t_min, double t_max, unsigned int num_pts) + : m_precision(PRECISION), m_data(1), + m_delim(default_delim), m_commt(default_commt) + { + const double dt((t_max - t_min)/num_pts); + for (unsigned int i=0; i<= num_pts; ++i) + m_data.at(0).push_back(f(t_min+i*dt)); + } + + data_file::data_file(double f1(double), double f2(double), + double t_min, double t_max, unsigned int num_pts) + : m_precision(PRECISION), m_data(2), + m_delim(default_delim), m_commt(default_commt) + { + const double dt((t_max - t_min)/num_pts); + for (unsigned int i=0; i<= num_pts; ++i) + { + m_data.at(0).push_back(f1(t_min+i*dt)); + m_data.at(1).push_back(f2(t_min+i*dt)); + } + } + + + data_file::data_file(double f1(double), double f2(double), double f3(double), + double t_min, double t_max, unsigned int num_pts) + : m_precision(PRECISION), m_data(3), + m_delim(default_delim), m_commt(default_commt) + { + const double dt((t_max - t_min)/num_pts); + for (unsigned int i=0; i<= num_pts; ++i) + { + m_data.at(0).push_back(f1(t_min+i*dt)); + m_data.at(1).push_back(f2(t_min+i*dt)); + m_data.at(2).push_back(f3(t_min+i*dt)); + } + } + + + data_file& data_file::read(const char* filename) + { + unsigned int columns(entries(filename)); + if (columns != m_data.size()) + { + std::stringstream msg; + msg << "Column count mismatch in file " << filename; + epix_warning(msg.str()); + } + + else if (0 < columns) + { + std::ifstream input(filename); + std::string linebuf; + std::vector<double> line; + + bool warned(false); + + while (getline(input, linebuf)) + { + // strip comments + linebuf = linebuf.substr(0, linebuf.find_first_of(m_commt)); + if (linebuf.length() > 0) + { + line = tokenise(linebuf); + + if (line.size() > m_data.size()) + { + if (!warned) + { + epix_warning("File has more columns than allocated"); + warned = true; + } + } + else if (line.size() < m_data.size()) + { + if (!warned) + { + epix_warning("File has fewer columns than allocated"); + warned = true; + } + } + else + { + for (unsigned int i = 0; i < m_data.size(); i++) + m_data.at(i).push_back(line.at(i)); + } + } // linebuf non-empty + } // end of file + input.close(); + } + return *this; + } // end of data_file::read(const char*, const std::string&) + + + // transform column(s) + data_file& data_file::transform(double f(double), unsigned int col) + { + unsigned int rows(m_data.at(0).size()); + + if (0 < col) // apply to selected column + for (unsigned int i=0; i<rows; ++i) + m_data.at(col-1).at(i) = f(m_data.at(col-1).at(i)); + + else // apply to all columns, default + { + for (unsigned int j=0; j<m_data.size(); ++j) + for (unsigned int i=0; i<rows; ++i) + m_data.at(j).at(i) = f(m_data.at(j).at(i)); + } + + return *this; + } + + // apply f to selected columns, components of image go back to columns + data_file& data_file::transform(P f(double, double), + unsigned int col1, unsigned int col2) + { + unsigned int rows(m_data.at(0).size()); + + for (unsigned int i=0; i<rows; ++i) + { + P tmp(f(m_data.at(col1 - 1).at(i), m_data.at(col2 - 1).at(i))); + + m_data.at(col1 - 1).at(i) = tmp.x1(); + m_data.at(col2 - 1).at(i) = tmp.x2(); + } + + return *this; + } + + data_file& data_file::transform(P f(double, double, double), + unsigned int col1, unsigned int col2) + { + unsigned int rows(m_data.at(0).size()); + + for (unsigned int i=0; i<rows; ++i) + { + P tmp(f(m_data.at(col1 - 1).at(i), m_data.at(col2 - 1).at(i), 0)); + + m_data.at(col1 - 1).at(i) = tmp.x1(); + m_data.at(col2 - 1).at(i) = tmp.x2(); + } + + return *this; + } + + data_file& data_file::transform(P f(double, double, double), + unsigned int col1, + unsigned int col2, + unsigned int col3) + { + unsigned int rows(m_data.at(0).size()); + + for (unsigned int i=0; i<rows; ++i) + { + P tmp(f(m_data.at(col1 - 1).at(i), + m_data.at(col2 - 1).at(i), + m_data.at(col3 - 1).at(i))); + + m_data.at(col1 - 1).at(i) = tmp.x1(); + m_data.at(col2 - 1).at(i) = tmp.x2(); + m_data.at(col3 - 1).at(i) = tmp.x3(); + } + + return *this; + } + + // Erase rows where the data is outside of the specified range + data_file& data_file::prune(const data_mask& dm, const unsigned int col) + { + std::vector<std::vector<double>::iterator> iter(m_data.size()); + for (unsigned int i = 0; i < m_data.size(); i++) + iter.at(i) = m_data.at(i).begin(); + + while (iter.at(0) != m_data.at(0).end()) + { + if ( dm.masks(*iter.at(col-1)) ) + for (unsigned int j = 0; j < m_data.size(); j++) + m_data.at(j).erase(iter.at(j)); + + else + for (unsigned int j = 0; j < m_data.size(); j++) + iter.at(j)++; + } + + return *this; + } + + data_file& data_file::prune(const interval& range, const unsigned int col) + { + data_mask dm(range); + return prune(dm, col); + } + + data_file& data_file::prune(double rmin, double rmax, + const unsigned int col) + { + data_mask dm(rmin, rmax); + return prune(dm, col); + } + + + // (col1|col2) + double data_file::dot(unsigned int col1, unsigned int col2) const + { + double sum(0); + + if ((col1 > m_data.size()) || (col2 > m_data.size()) ) + epix_warning("Invalid column index in dot product"); + + else + for (unsigned int i=0; i < m_data.at(0).size(); ++i) + sum += m_data.at(col1-1).at(i)*m_data.at(col2-1).at(i); + + return sum; + } // end of dot + + // avg (mean) of col1 + double data_file::avg(unsigned int col1) const + { + double sum(0); + + if (col1 > m_data.size()) + epix_warning("Invalid column index in mean"); + + else + for (unsigned int i=0; i < m_data.at(0).size(); ++i) + sum += m_data.at(col1-1).at(i); + + return sum/m_data.at(0).size(); + } // end of avg + + // variance (x|x) - n*\bar{x}^2 + double data_file::var(unsigned int col1) const + { + double mean(avg(col1)); + + return dot(col1, col1) - mean*mean*m_data.at(0).size(); + } // end of var + + // covariance (x|y) - n*\bar{x}*\bar{y} + double data_file::covar(unsigned int col1, unsigned int col2) const + { + return dot(col1, col2) - (m_data.at(0).size())*avg(col1)*avg(col2); + } // end of covar + + void data_file::regression(unsigned int col1, unsigned int col2) const + { + Line(P(avg(col1), avg(col2)), covar(col1, col2)/var(col1)); + } + + + //// Output functions //// + // return selected column + std::vector<double> data_file::column(unsigned int n) const + { + if (1 <= n && n <= m_data.size()) + return m_data.at(n-1); + else + { + if (0 < m_data.size()) + { + epix_warning("Out of range argument to data_file::column()"); + return m_data.at(0); + } + else + { + epix_warning("data_file::column() requested for empty file"); + std::vector<double> err_val(1, 0); + return err_val; + } + } + } + + // apply f to selected column + std::vector<double> data_file::column(double f(double), unsigned int n) const + { + // must copy data + std::vector<double> value(m_data.at(0).size()); + unsigned int col(n); + + if (col < 1 || m_data.size() < col) + { + if (0 < m_data.size()) + { + epix_warning("Out of range argument to data_file::column()"); + col=1; + } + else + { + epix_warning("data_file::column() requested for empty file"); + std::vector<double> err_val(1, 0); + return err_val; + } + } + + for (unsigned int i=0; i<m_data.at(0).size(); ++i) + value.at(i) = f(m_data.at(col-1).at(i)); + + return value; + } + + + // set precision for write() + void data_file::precision(const unsigned int n) const + { + m_precision=n; + } + + // write file or selected columns + void data_file::write(const char* filename) const + { + std::ofstream output(filename); + if (!output) + { + epix_warning("data_file::write() cannot open file"); + return; + } + + // else + output.precision(m_precision); + output.setf(std::ios_base::showpoint); // pad with 0s + output.setf(std::ios_base::right); // right-justify + + unsigned int cols(m_data.size()); + + for (unsigned int j=0; j < m_data.at(0).size(); ++j) + { + output << m_data.at(0).at(j); + for (unsigned int i=1; i < cols; ++i) + output << m_delim << m_data.at(i).at(j); + + output << std::endl; + } + output.close(); + } + + + void data_file::write(const char* fname, std::string pt_out(double, double), + unsigned int col1, unsigned int col2) const + { + std::ofstream output(fname); + if (!output) + { + epix_warning("data_file::write() cannot open file"); + return; + } + + // else + output.precision(m_precision); + + for (unsigned int i=0; i < m_data.at(0).size(); ++i) + try + { + output << pt_out(m_data.at(col1-1).at(i), m_data.at(col2-1).at(i)); + } + + catch (std::out_of_range) + { + epix_warning("data_file::write(): Invalid column index"); + return; + } + + output.close(); + } // end of data_file::write(const char*, string function) + + // experimental: LaTeX tabular environment + void data_file::tabular(const char* filename, + const std::string& alignment, + const std::string& legend) const + { + std::ofstream output(filename); + if (!output) + { + epix_warning("data_file::table() cannot open file"); + return; + } + + // else + using std::endl; + + output.precision(m_precision); + unsigned int cols(m_data.size()); + + output << "\\begin{tabular}{" << alignment << "}" << endl + << "\\hline" << endl; + if (legend != "") + output << legend << endl << "\\hline" << endl; + + for (unsigned int j=0; j < m_data.at(0).size(); ++j) + { + output << "$" << truncate(m_data.at(0).at(j), m_precision) << "$"; + for (unsigned int i=1; i < cols; ++i) + output << " & $" << truncate(m_data.at(i).at(j), m_precision) << "$"; + + output << " \\\\" << endl; + } + + output << "\\hline" << endl + << "\\end{tabular}" << endl; + + output.close(); + } // end of data_file::tabular() + + + void data_file::plot(epix_mark_type TYPE, + unsigned int col1, unsigned int col2, unsigned int col3, + P f(double, double, double)) const + { + unsigned int num_entries(m_data.at(0).size()); + + std::vector<P> data(num_entries); + + // create path + for (unsigned int i=0; i < num_entries; ++i) + try + { + if (col3 == 0) + data.at(i) = f(m_data.at(col1-1).at(i), + m_data.at(col2-1).at(i), + 0); + + else + data.at(i) = f(m_data.at(col1-1).at(i), + m_data.at(col2-1).at(i), + m_data.at(col3-1).at(i)); + } + + catch (std::out_of_range) + { + epix_warning("data_file::plot(): Invalid column index"); + return; + } + + // and write it + if (PATH == TYPE) // N.B. Unaffected by "select" + { + path temp(data, false, false); // not closed or filled + temp.draw(); + } + + else + for (unsigned int i=0; i < num_entries; ++i) + { + // if (m_select(data.at(i))) + label_data temp(data.at(i), TYPE); + temp.draw(); + } + } + + void data_file::plot(epix_mark_type TYPE, P f(double, double, double), + unsigned int col1, unsigned int col2, + unsigned int col3) const + { + plot(TYPE, col1, col2, col3, f); + } + + //// global functions //// + void plot(const char* filename, epix_mark_type TYPE, + unsigned int col1, unsigned int col2, unsigned int col3, + P f(double, double, double)) + { + data_file temp(filename); + temp.plot(TYPE, col1, col2, col3, f); + } + + void plot(const char* filename, epix_mark_type TYPE, + P f(double, double, double), + unsigned int col1, unsigned int col2, unsigned int col3) + { + data_file temp(filename); + temp.plot(TYPE, col1, col2, col3, f); + } + + // pass 3rd arg by value + void histogram(const char* filename, unsigned int col, data_bins db, + double scale) + { + data_file temp(filename); + db.read(temp.column(col)); + db.histogram(scale); + } + + void bar_chart(const char* filename, unsigned int col, data_bins db, + double scale) + { + data_file temp(filename); + db.read(temp.column(col)); + db.bar_chart(scale); + } +} // end of namespace diff --git a/graphics/epix/data_file.h b/graphics/epix/data_file.h new file mode 100644 index 0000000000..e5a3af956e --- /dev/null +++ b/graphics/epix/data_file.h @@ -0,0 +1,172 @@ +/* + * data_file.h -- ePiX::data_file class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.6 + * Last Change: July 04, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_DATA_FILE +#define EPIX_DATA_FILE + +#include <vector> +#include <list> + +#include "enums.h" + +namespace ePiX { + + class data_bins; + class data_mask; + class interval; + + class data_file { + public: + explicit data_file(unsigned int n=2); + + // get size from first line of file; + // provide two versions to avoid exposing default delim/commt strings + data_file(const char* filename, + const std::string& delim, const std::string& commt); + explicit data_file(const char* filename); + + // file made from components + data_file(double f(double), + double t_min, double t_max, unsigned int num_pts); + + data_file(double f1(double), double f2(double), + double t_min, double t_max, unsigned int num_pts); + + data_file(double f1(double), double f2(double), double f3(double), + double t_min, double t_max, unsigned int num_pts); + + // input + data_file& read(const char*); + + // transform column(s) + data_file& transform(double f(double), unsigned int col=0); + + // apply f to selected columns; components of image go back to columns + data_file& transform(P f(double, double), + unsigned int col1=1, unsigned int col2=2); + + data_file& transform(P f(double, double, double), + unsigned int col1, unsigned int col2); + + data_file& transform(P f(double, double, double), + unsigned int col1, + unsigned int col2, + unsigned int col3); + + // remove rows where specified entry is masked or outside interval/range + data_file& prune(const data_mask&, const unsigned int col); + data_file& prune(const interval&, const unsigned int col); + data_file& prune(double, double, const unsigned int col); + + // basic statistical operations on columns + double dot(unsigned int col1, unsigned int col2) const; // dot product + double avg(unsigned int col1) const; // mean + double var(unsigned int col1) const; // |x|^2 - n*avg^2 + double covar(unsigned int col1, unsigned int col2) const; + void regression(unsigned int col1, unsigned int col2) const; + + + // output functions + // extract column + std::vector<double> column(unsigned int) const; + // apply f to values + std::vector<double> column(double f(double), unsigned int) const; + + // set C++ output precision for write + void precision(unsigned int n=6) const; + + // Setters and getters for delimiter and comment character + void delimiter(const char* delim) { m_delim = delim; } + std::string delimiter() const { return m_delim; } + + void comment(const char* commt) { m_commt = commt; } + std::string comment() const { return m_commt; } + + // write raw data to file + void write(const char* filename) const; + + // write selected columns formatted by string-valued function + void write(const char* filename, std::string pt_out(double, double), + unsigned int col1=1, unsigned int col2=2) const; + + // LaTeX tabular environment + void tabular(const char* filename, + const std::string& alignment, + const std::string& legend="") const; + + + /* + // (un)set cropping criterion for plotting + void select(bool Fsel(P)); + void select(const selection&); // e.g. select(all()); + */ + + // scatter plots; f applied to selected columns + void plot(epix_mark_type TYPE, + unsigned int col1=1, unsigned int col2=2, unsigned int col3=0, + P f(double, double, double) = xyz) const; + + void plot(epix_mark_type TYPE, P f(double, double, double), + unsigned int col1=1, unsigned int col2=2, + unsigned int col3=0) const; + + private: + std::vector<double> tokenise(std::string line); + unsigned int entries(const char* filename); + + mutable unsigned int m_precision; + // selection m_select; + + std::vector<std::vector<double> > m_data; + std::string m_delim; // Field delimiter + std::string m_commt; // Comment character + }; // end of class data_file + + + //// Global functions that use file_data, data_bins //// + void plot(const char* filename, epix_mark_type TYPE, + unsigned int col1=1, unsigned int col2=2, unsigned int col3=0, + P f(double, double, double) = xyz); + + void plot(const char* filename, epix_mark_type TYPE, + P f(double, double, double), + unsigned int col1=1, unsigned int col2=2, unsigned int col3=0); + + // pass 3rd arg by value + void histogram(const char* filename, unsigned int col, data_bins, + double scale=1); + void bar_chart(const char* filename, unsigned int col, data_bins, + double scale=1); +} // end of namespace + +#endif /* EPIX_DATA_FILE */ diff --git a/graphics/epix/data_mask.cc b/graphics/epix/data_mask.cc new file mode 100644 index 0000000000..d2f0290426 --- /dev/null +++ b/graphics/epix/data_mask.cc @@ -0,0 +1,76 @@ +/* + * data_mask.cc -- ePiX::data_mask class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.8 + * Last Change: July 22, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "functions.h" +#include "interval.h" +#include "data_mask.h" + +namespace ePiX { + + double identity(double x) { return x; } + + data_mask::data_mask(std::string arg) + : m_range(arg), m_filter(identity), m_reverse(false) { } + + data_mask::data_mask(std::string arg, double f(double)) + : m_range(arg), m_filter(f), m_reverse(false) { } + + + data_mask::data_mask(const interval& range) + : m_range(range), m_filter(identity), m_reverse(false) { } + + data_mask::data_mask(const interval& range, double f(double)) + : m_range(range), m_filter(f), m_reverse(false) { } + + data_mask::data_mask(double arg1, double arg2) + : m_range(arg1, arg2), m_filter(identity), m_reverse(false) { } + + data_mask::data_mask(double arg1, double arg2, double f(double)) + : m_range(arg1, arg2), m_filter(f), m_reverse(false) { } + + data_mask& data_mask::reverse() + { + m_reverse = !m_reverse; + return *this; + } + + bool data_mask::masks(double x) const + { + bool masked(!m_range.contains(m_filter(x))); + + if (m_reverse) + masked = !masked; + + return masked; + } +} // end of namespace diff --git a/graphics/epix/data_mask.h b/graphics/epix/data_mask.h new file mode 100644 index 0000000000..e522af0975 --- /dev/null +++ b/graphics/epix/data_mask.h @@ -0,0 +1,66 @@ +/* + * data_mask.h -- ePiX::data_mask, for selective row removal from data_file + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.6 + * Last Change: July 3, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_DATA_MASK +#define EPIX_DATA_MASK + +#include <string> + +#include "interval.h" + +namespace ePiX { + + class data_mask { + public: + data_mask(std::string); + data_mask(std::string, double f(double)); + + data_mask(const interval& range); + data_mask(const interval& range, double f(double)); + + data_mask(double range_min, double range_max); + data_mask(double range_min, double range_max, + double f(double)); + + data_mask& reverse(); // negate mask criterion + bool masks(double) const; // true if we mask arg + + private: + interval m_range; + double (*m_filter)(double); // filter criterion + bool m_reverse; + + }; // end of data_mask +} // end of namespace + +#endif /* EPIX_DATA_MASK */ diff --git a/graphics/epix/debug.h b/graphics/epix/debug.h new file mode 100644 index 0000000000..204063447a --- /dev/null +++ b/graphics/epix/debug.h @@ -0,0 +1,37 @@ +#ifndef EPIX_DEBUG +#define EPIX_DEBUG + +#include <iostream> +#include <cstdlib> +#include <sstream> +#include <string> + +#include "pairs.h" +#include "triples.h" + +#include "errors.h" + +namespace ePiX +{ + inline void debug_msg(const std::string& msg) + { + std::cerr << msg << std::endl; + } + + inline void debug_print(const pair& arg, const std::string& msg="") + { + std::cerr << msg << " (" + << arg.x1() << ", " + << arg.x2() << ")" << std::endl; + } + + inline void debug_print(const P& arg, const std::string& msg="") + { + std::cerr << msg << " (" + << arg.x1() << ", " + << arg.x2() << ", " + << arg.x3() << ")" << std::endl; + } + +} +#endif /* EPIX_DEBUG */ diff --git a/graphics/epix/depcomp b/graphics/epix/depcomp new file mode 100644 index 0000000000..04701da536 --- /dev/null +++ b/graphics/epix/depcomp @@ -0,0 +1,530 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2005-07-09.11 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. + +# 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to <bug-automake@gnu.org>. +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + stat=$? + + if test -f "$tmpdepfile"; then : + else + stripped=`echo "$stripped" | sed 's,^.*/,,'` + tmpdepfile="$stripped.u" + fi + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + outname="$stripped.o" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mecanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/graphics/epix/deriv.h b/graphics/epix/deriv.h new file mode 100644 index 0000000000..56214ef462 --- /dev/null +++ b/graphics/epix/deriv.h @@ -0,0 +1,49 @@ +/* + * deriv.h -- ePiX derivative function template + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.0.23 + * Last Change: January 06, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_DERIV +#define EPIX_DERIV + +#include "constants.h" + +namespace ePiX { + + // moved from functions.h to hide global constant EPIX_EPSILON + template<class T> T deriv(T f(double), double t, double dt=EPIX_EPSILON) + { + return (1.0/dt)*(f(t+0.5*dt) - f(t-0.5*dt)); + } +} // end of namespace + +#endif /* EPIX_DERIV */ diff --git a/graphics/epix/doc/Makefile.am b/graphics/epix/doc/Makefile.am new file mode 100644 index 0000000000..ec9ac95e5f --- /dev/null +++ b/graphics/epix/doc/Makefile.am @@ -0,0 +1,45 @@ +# Makefile.am for ePiX v1.x "doc" directory +# + +EPIXFLAGS = --no-defaults -I.. -L.. -lepix -v + +%.eepic: %.xp + ../epix-local $(EPIXFLAGS) $< + +XPS := $(wildcard *.xp) + +EEPICS = $(XPS:.xp=.eepic) + +CLEANFILES = *~ *.aux *.dvi *.log *.out *.idx *.ilg *.ind *.toc \ + epix.info.bz2 manual_src.tar manual.pdf manual.ps \ + manual_src.tar.gz manual.pdf.gz manual.ps.gz manual-stamp + +MAINTAINERCLEANFILES = *.eepic *.aux *.dvi *.log *.out *.toc *.idx *.ind *.ilg + +## Targets ## +doc_DATA = manual.pdf.gz manual.ps.gz manual_src.tar.gz epix.info.bz2 + + +# tar up tex, xp, and eepic files; build ps, pdf +manual-stamp: manual.tex $(XPS) $(EEPICS) + latex -interaction=batchmode manual &>/dev/null + latex -interaction=batchmode manual &>/dev/null + makeindex manual.idx &>/dev/null + ../laps-local --pdf manual.tex + touch manual-stamp + +manual_src.tar.gz: manual-stamp + tar -cf manual_src.tar manual.aux manual.ind manual.tex manual.toc \ + $(XPS) $(EEPICS) + gzip -9 manual_src.tar + +#PS +manual.ps.gz: manual-stamp + gzip -9 -c manual.ps > manual.ps.gz + +#PDF +manual.pdf.gz: manual-stamp + gzip -9 -c manual.pdf > manual.pdf.gz + +epix.info.bz2: manual-stamp epix.info + bzip2 -fk epix.info diff --git a/graphics/epix/doc/Makefile.in b/graphics/epix/doc/Makefile.in new file mode 100644 index 0000000000..293c547251 --- /dev/null +++ b/graphics/epix/doc/Makefile.in @@ -0,0 +1,364 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Makefile.am for ePiX v1.x "doc" directory +# + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = doc +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(docdir)" +docDATA_INSTALL = $(INSTALL_DATA) +DATA = $(doc_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASH_PATH = @BASH_PATH@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_EPIX_EL_FALSE = @ENABLE_EPIX_EL_FALSE@ +ENABLE_EPIX_EL_TRUE = @ENABLE_EPIX_EL_TRUE@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RUNTIME_COMPILER = @RUNTIME_COMPILER@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +EPIXFLAGS = --no-defaults -I.. -L.. -lepix -v +XPS := $(wildcard *.xp) +EEPICS = $(XPS:.xp=.eepic) +CLEANFILES = *~ *.aux *.dvi *.log *.out *.idx *.ilg *.ind *.toc \ + epix.info.bz2 manual_src.tar manual.pdf manual.ps \ + manual_src.tar.gz manual.pdf.gz manual.ps.gz manual-stamp + +MAINTAINERCLEANFILES = *.eepic *.aux *.dvi *.log *.out *.toc *.idx *.ind *.ilg +doc_DATA = manual.pdf.gz manual.ps.gz manual_src.tar.gz epix.info.bz2 +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu doc/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +uninstall-info-am: +install-docDATA: $(doc_DATA) + @$(NORMAL_INSTALL) + test -z "$(docdir)" || $(mkdir_p) "$(DESTDIR)$(docdir)" + @list='$(doc_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(docDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(docdir)/$$f'"; \ + $(docDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(docdir)/$$f"; \ + done + +uninstall-docDATA: + @$(NORMAL_UNINSTALL) + @list='$(doc_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(docdir)/$$f'"; \ + rm -f "$(DESTDIR)$(docdir)/$$f"; \ + done +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: + for dir in "$(DESTDIR)$(docdir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-docDATA + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-docDATA uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic distclean \ + distclean-generic distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-docDATA install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am uninstall uninstall-am uninstall-docDATA \ + uninstall-info-am + + +%.eepic: %.xp + ../epix-local $(EPIXFLAGS) $< + +# tar up tex, xp, and eepic files; build ps, pdf +manual-stamp: manual.tex $(XPS) $(EEPICS) + latex -interaction=batchmode manual &>/dev/null + latex -interaction=batchmode manual &>/dev/null + makeindex manual.idx &>/dev/null + ../laps-local --pdf manual.tex + touch manual-stamp + +manual_src.tar.gz: manual-stamp + tar -cf manual_src.tar manual.aux manual.ind manual.tex manual.toc \ + $(XPS) $(EEPICS) + gzip -9 manual_src.tar + +#PS +manual.ps.gz: manual-stamp + gzip -9 -c manual.ps > manual.ps.gz + +#PDF +manual.pdf.gz: manual-stamp + gzip -9 -c manual.pdf > manual.pdf.gz + +epix.info.bz2: manual-stamp epix.info + bzip2 -fk epix.info +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/graphics/epix/doc/alignment.eepic b/graphics/epix/doc/alignment.eepic new file mode 100644 index 0000000000..1c5d93bd48 --- /dev/null +++ b/graphics/epix/doc/alignment.eepic @@ -0,0 +1,19 @@ +%% Generated from alignment.xp on Fri Jan 7 14:18:43 EST 2005 by +%% ePiX-1.0.3 +%% +%% Cartesian bounding box: [-1,1] x [-1,1] +%% Actual size: 72pt x 24pt +%% Figure offset: right by 0pt, up by 0pt +%% +\setlength{\unitlength}{1pt} +\begin{picture}(72,24)(-0,-0) +%% --- +\path(0.00140226,12)(12.001,12)(24.0006,12)(36.0002,12)(47.9998,12) + (59.9994,12)(71.999,12) +\path(36,0.00046742)(36,12.0001)(36,23.9997) +\put(36,12){\makebox(0,0)[bl]{\texttt{[tr]}}} +\put(36,12){\makebox(0,0)[c]{{\circle*{3}}}} +\put(36,12){\makebox(0,0)[br]{\texttt{[tl]}}} +\put(36,12){\makebox(0,0)[tl]{\texttt{[br]}}} +\put(36,12){\makebox(0,0)[tr]{\texttt{[bl]}}} +\end{picture} diff --git a/graphics/epix/doc/alignment.xp b/graphics/epix/doc/alignment.xp new file mode 100644 index 0000000000..e6bfc3c298 --- /dev/null +++ b/graphics/epix/doc/alignment.xp @@ -0,0 +1,26 @@ +/* -*-ePiX-*- */ +/* alignment.c -- ePiX's reverse-LaTeX label alignment option */ +#include "epix.h" +using namespace ePiX; + +P O(0,0); + +int main() +{ + bounding_box(P(-1,-1), P(1,1)); + picture(P(72,24)); + unitlength("1pt"); + + begin(); + + Line(O, E_1); + Line(O, E_2); + + font_face("tt"); + dot(O, P(0,0), "[tr]", tr); + label(O, P(0,0), "[tl]", tl); + label(O, P(0,0), "[br]", br); + label(O, P(0,0), "[bl]", bl); + + end(); +} diff --git a/graphics/epix/doc/alignment_lr.eepic b/graphics/epix/doc/alignment_lr.eepic new file mode 100644 index 0000000000..111098caf3 --- /dev/null +++ b/graphics/epix/doc/alignment_lr.eepic @@ -0,0 +1,17 @@ +%% Generated from alignment_lr.xp on Fri Jan 7 14:18:31 EST 2005 by +%% ePiX-1.0.3 +%% +%% Cartesian bounding box: [-1,1] x [-1,1] +%% Actual size: 72pt x 24pt +%% Figure offset: right by 0pt, up by 0pt +%% +\setlength{\unitlength}{1pt} +\begin{picture}(72,24)(-0,-0) +%% --- +\put(0,12){\makebox(0,0)[r]{\texttt{[l]}}} +\put(0,12){\makebox(0,0)[c]{{\circle*{3}}}} +\put(0,12){\makebox(0,0)[l]{\texttt{[r]}}} +\put(72,12){\makebox(0,0)[b]{\texttt{[t]}}} +\put(72,12){\makebox(0,0)[c]{{\circle*{3}}}} +\put(72,12){\makebox(0,0)[t]{\texttt{[b]}}} +\end{picture} diff --git a/graphics/epix/doc/alignment_lr.xp b/graphics/epix/doc/alignment_lr.xp new file mode 100644 index 0000000000..a6871278e3 --- /dev/null +++ b/graphics/epix/doc/alignment_lr.xp @@ -0,0 +1,24 @@ +/* -*-ePiX-*- */ +/* alignment_lr.c -- ePiX's reverse-LaTeX label alignment option */ +#include "epix.h" +using namespace ePiX; + +P p1(-1,0), p2(1,0); + +int main() +{ + bounding_box(P(-1,-1), P(1,1)); + picture(P(72,24)); + unitlength("1pt"); + + begin(); + + font_face("tt"); + dot(p1, P(0,0), "[l]", l); + label(p1, P(0,0), "[r]", r); + + dot(p2, P(0,0), "[t]", t); + label(p2, P(0,0), "[b]", b); + + end(); +} diff --git a/graphics/epix/doc/arrow.eepic b/graphics/epix/doc/arrow.eepic new file mode 100644 index 0000000000..98adf21b49 --- /dev/null +++ b/graphics/epix/doc/arrow.eepic @@ -0,0 +1,22 @@ +%% Generated from arrows.xp on Mon Jul 2 20:38:11 EDT 2007 by +%% ePiX-1.1.6 +%% +%% Cartesian bounding box: [-2,2] x [-1,1] +%% Actual size: 24 x 12pt +%% Figure offset: left by 0pt, down by 0pt +%% +\xdefinecolor{rgb_000000}{rgb}{0,0,0} +\setlength{\unitlength}{1pt} +\begin{picture}(24,12)(-0,-0) +\path(0,6)(24,6) +%% +\path(17.8125,4.875)(15.75,4.875) +\path(19.875,5.25)(15.75,5.25) +\path(21.9375,5.625)(15.75,5.625) +\path(24,6)(15.75,6) +\path(21.9375,6.375)(15.75,6.375) +\path(19.875,6.75)(15.75,6.75) +\path(17.8125,7.125)(15.75,7.125) +\path(15.75,6)(15.75,4.5)(24,6)(15.75,7.5)(15.75,6) +%% +\end{picture} diff --git a/graphics/epix/doc/arrow.xp b/graphics/epix/doc/arrow.xp new file mode 100644 index 0000000000..34c47ad5e0 --- /dev/null +++ b/graphics/epix/doc/arrow.xp @@ -0,0 +1,18 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +int main() +{ + picture(P(-2,-1),P(2,1), "24x12pt"); + + begin(); +#ifdef CAMBER25 + arrow_camber(0.25); +#elif CAMBER50 + arrow_camber(0.5); +#endif + + arrow(P(xmin(),0), P(xmax(),0)); + end(); +} diff --git a/graphics/epix/doc/arrow25.eepic b/graphics/epix/doc/arrow25.eepic new file mode 100644 index 0000000000..196889e2b2 --- /dev/null +++ b/graphics/epix/doc/arrow25.eepic @@ -0,0 +1,22 @@ +%% Generated from arrows.xp on Mon Jul 2 20:38:23 EDT 2007 by +%% ePiX-1.1.6 +%% +%% Cartesian bounding box: [-2,2] x [-1,1] +%% Actual size: 24 x 12pt +%% Figure offset: left by 0pt, down by 0pt +%% +\xdefinecolor{rgb_000000}{rgb}{0,0,0} +\setlength{\unitlength}{1pt} +\begin{picture}(24,12)(-0,-0) +\path(0,6)(24,6) +%% +\path(17.8125,4.875)(16.2656,4.875) +\path(19.875,5.25)(16.7813,5.25) +\path(21.9375,5.625)(17.2969,5.625) +\path(24,6)(17.8125,6) +\path(21.9375,6.375)(17.2969,6.375) +\path(19.875,6.75)(16.7813,6.75) +\path(17.8125,7.125)(16.2656,7.125) +\path(17.8125,6)(15.75,4.5)(24,6)(15.75,7.5)(17.8125,6) +%% +\end{picture} diff --git a/graphics/epix/doc/arrow50.eepic b/graphics/epix/doc/arrow50.eepic new file mode 100644 index 0000000000..e22fec0fd0 --- /dev/null +++ b/graphics/epix/doc/arrow50.eepic @@ -0,0 +1,22 @@ +%% Generated from arrows.xp on Mon Jul 2 20:38:34 EDT 2007 by +%% ePiX-1.1.6 +%% +%% Cartesian bounding box: [-2,2] x [-1,1] +%% Actual size: 24 x 12pt +%% Figure offset: left by 0pt, down by 0pt +%% +\xdefinecolor{rgb_000000}{rgb}{0,0,0} +\setlength{\unitlength}{1pt} +\begin{picture}(24,12)(-0,-0) +\path(0,6)(24,6) +%% +\path(17.8125,4.875)(16.7813,4.875) +\path(19.875,5.25)(17.8125,5.25) +\path(21.9375,5.625)(18.8438,5.625) +\path(24,6)(19.875,6) +\path(21.9375,6.375)(18.8438,6.375) +\path(19.875,6.75)(17.8125,6.75) +\path(17.8125,7.125)(16.7813,7.125) +\path(19.875,6)(15.75,4.5)(24,6)(15.75,7.5)(19.875,6) +%% +\end{picture} diff --git a/graphics/epix/doc/basepoint.eepic b/graphics/epix/doc/basepoint.eepic new file mode 100644 index 0000000000..efd76dfaa5 --- /dev/null +++ b/graphics/epix/doc/basepoint.eepic @@ -0,0 +1,16 @@ +%% Generated from basepoint.xp on Tue Jan 4 15:32:04 EST 2005 by +%% ePiX-1.0.3 +%% +%% Cartesian bounding box: [0,3.75] x [0,1] +%% Actual size: 3.75pc x 1pc +%% Figure offset: right by 0pc, up by 0pc +%% +\setlength{\unitlength}{1pc} +\begin{picture}(3.75,1)(-0,-0) +%% --- +\path(0,-0.375)(3.75,-0.375)(3.75,1)(0,1)(0,-0.375) +\allinethickness{0.15pt}% +\path(0,0)(3.75,0) +\put(0,0){$y=f(x)$} +\put(0,0){\makebox(0,0)[c]{{\circle*{0.111111}}}} +\end{picture} diff --git a/graphics/epix/doc/basepoint.xp b/graphics/epix/doc/basepoint.xp new file mode 100644 index 0000000000..7fc15f6cb1 --- /dev/null +++ b/graphics/epix/doc/basepoint.xp @@ -0,0 +1,36 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +int main() { + bounding_box(P(0,0),P(3.75,1)); + unitlength("1pc"); + picture(3.75,1); + // offset(-0.5,0); + + begin(); + + rect(P(x_min, y_min-0.375), P(x_max, y_max)); + + pen(0.15); + line(P(x_min,0), P(x_max,0)); + + dot_size(2); + + // std::cout << "\n\\LARGE"; + /* + label(P(0,0), P(0,0), "$b$"); + ddot(P(0,0)); + + label(P(1,0), P(0,0), "$f$"); + ddot(P(1,0)); + + label(P(2,0), P(0,0), "$p$"); + ddot(P(2,0)); + */ + + label(P(0,0), P(0,0), "$y=f(x)$"); + ddot(P(0,0)); + + end(); +} diff --git a/graphics/epix/doc/camera.eepic b/graphics/epix/doc/camera.eepic new file mode 100644 index 0000000000..7da56f9987 --- /dev/null +++ b/graphics/epix/doc/camera.eepic @@ -0,0 +1,285 @@ +%% Generated from camera.xp on Sat Sep 22 17:10:34 EDT 2007 by +%% ePiX-1.2.0 +%% +%% Cartesian bounding box: [-3.5,3.5] x [-3.5,2.5] +%% Actual size: 2.625 x 2.25in +%% Figure offset: left by 0in, down by 0in +%% +%% usepackages epic,eepic,xcolor +%% +\xdefinecolor{rgb_000000}{rgb}{0,0,0}% +\xdefinecolor{rgb_7f7f7f}{rgb}{0.498039,0.498039,0.498039}% +\xdefinecolor{rgb_e5e5e5}{rgb}{0.898039,0.898039,0.898039}% +\xdefinecolor{rgb_ffffff}{rgb}{1,1,1}% +\setlength{\unitlength}{1in}% +\begin{picture}(2.625,2.25)(0,0)% +\path(1.42243,1.30711)(1.4086,1.26997)(1.29561,1.27568) +\path(1.3125,1.3125)(1.4523,1.30564)(1.59359,1.29871) +\path(1.3125,1.3125)(1.3125,1.44704)(1.3125,1.58496) +\path(0.307912,0.721822)(0.173332,2.09409)(2.55902,2.04543) + (2.39965,0.566596)(0.307912,0.721822) +\put(1.58249,0.490175){\makebox(0,0)[l]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize \textbf{Sea}}}}} +\put(0.937572,1.11972){\makebox(0,0)[b]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize \textbf{Sky}}}}} +\put(0.735053,0.174015){\makebox(0,0)[r]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize \textbf{Eye}}}}} +\put(0.929482,0.537641){\makebox(0,0)[r]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize Viewpoint}}}} +\put(0.957156,0.537641){\color{rgb_000000}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\put(2.476,2.01776){\makebox(0,0)[tr]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize Canvas}}}} +\path(0.957156,0.537641)(1.17567,1.01413)(1.3125,1.3125) +\color{rgb_7f7f7f}% +\path(1.83216,0.911179)(1.84054,0.911179) +\path(1.82052,0.916691)(1.83729,0.916691) +\path(1.80888,0.922203)(1.83404,0.922203) +\path(1.79724,0.927715)(1.83079,0.927715) +\path(1.7856,0.933227)(1.82754,0.933227) +\path(1.77396,0.938739)(1.82429,0.938739) +\path(1.76232,0.944251)(1.82104,0.944251) +\path(1.75068,0.949763)(1.81779,0.949763) +\path(1.73904,0.955275)(1.81454,0.955275) +\path(1.7274,0.960787)(1.81129,0.960787) +\path(1.71576,0.966299)(1.80804,0.966299) +\path(1.70412,0.971811)(1.80479,0.971811) +\path(1.69248,0.977323)(1.80154,0.977323) +\path(1.68084,0.982835)(1.79829,0.982835) +\path(1.6692,0.988347)(1.79503,0.988347) +\path(1.65756,0.993859)(1.79178,0.993859) +\path(1.64592,0.999371)(1.78853,0.999371) +\path(1.63428,1.00488)(1.78528,1.00488) +\path(1.62264,1.0104)(1.78203,1.0104) +\path(1.611,1.01591)(1.77878,1.01591) +\path(1.60612,1.02142)(1.77553,1.02142) +\path(1.60892,1.02693)(1.77228,1.02693) +\path(1.61172,1.03244)(1.76903,1.03244) +\path(1.61452,1.03796)(1.76578,1.03796) +\path(1.61732,1.04347)(1.76253,1.04347) +\path(1.62012,1.04898)(1.75928,1.04898) +\path(1.62292,1.05449)(1.75603,1.05449) +\path(1.62572,1.06)(1.75278,1.06) +\path(1.62852,1.06551)(1.74952,1.06551) +\path(1.63132,1.07103)(1.74627,1.07103) +\path(1.63412,1.07654)(1.74302,1.07654) +\path(1.63692,1.08205)(1.73977,1.08205) +\path(1.63972,1.08756)(1.73652,1.08756) +\path(1.64252,1.09307)(1.73327,1.09307) +\path(1.64532,1.09859)(1.73002,1.09859) +\path(1.64812,1.1041)(1.72677,1.1041) +\path(1.65091,1.10961)(1.72352,1.10961) +\path(1.65371,1.11512)(1.72027,1.11512) +\path(1.65651,1.12063)(1.71702,1.12063) +\path(1.65931,1.12615)(1.71377,1.12615) +\path(1.66211,1.13166)(1.71052,1.13166) +\path(1.66491,1.13717)(1.70726,1.13717) +\path(1.66771,1.14268)(1.70401,1.14268) +\path(1.67051,1.14819)(1.70076,1.14819) +\path(1.67331,1.15371)(1.69751,1.15371) +\path(1.67611,1.15922)(1.69426,1.15922) +\path(1.67891,1.16473)(1.69101,1.16473) +\path(1.68171,1.17024)(1.68776,1.17024) +\path(1.83836,0.908239)(1.83836,0.914877) +\path(1.83293,0.910811)(1.83293,0.924087) +\path(1.8275,0.913384)(1.8275,0.933297) +\path(1.82207,0.915956)(1.82207,0.942506) +\path(1.81664,0.918528)(1.81664,0.951716) +\path(1.81121,0.9211)(1.81121,0.960926) +\path(1.80577,0.923672)(1.80577,0.970136) +\path(1.80034,0.926244)(1.80034,0.979345) +\path(1.79491,0.928816)(1.79491,0.988555) +\path(1.78948,0.931388)(1.78948,0.997765) +\path(1.78405,0.93396)(1.78405,1.00697) +\path(1.77862,0.936532)(1.77862,1.01618) +\path(1.77319,0.939104)(1.77319,1.02539) +\path(1.76775,0.941676)(1.76775,1.0346) +\path(1.76232,0.944248)(1.76232,1.04381) +\path(1.75689,0.94682)(1.75689,1.05302) +\path(1.75146,0.949392)(1.75146,1.06223) +\path(1.74603,0.951964)(1.74603,1.07144) +\path(1.7406,0.954536)(1.7406,1.08065) +\path(1.73517,0.957108)(1.73517,1.08986) +\path(1.72973,0.95968)(1.72973,1.09907) +\path(1.7243,0.962252)(1.7243,1.10828) +\path(1.71887,0.964824)(1.71887,1.11749) +\path(1.71344,0.967396)(1.71344,1.1267) +\path(1.70801,0.969968)(1.70801,1.13591) +\path(1.70258,0.97254)(1.70258,1.14512) +\path(1.69715,0.975112)(1.69715,1.15433) +\path(1.69171,0.977684)(1.69171,1.16354) +\path(1.68628,0.980256)(1.68628,1.17275) +\path(1.68085,0.982828)(1.68085,1.16855) +\path(1.67542,0.9854)(1.67542,1.15786) +\path(1.66999,0.987972)(1.66999,1.14716) +\path(1.66456,0.990544)(1.66456,1.13647) +\path(1.65912,0.993116)(1.65912,1.12577) +\path(1.65369,0.995689)(1.65369,1.11508) +\path(1.64826,0.998261)(1.64826,1.10439) +\path(1.64283,1.00083)(1.64283,1.09369) +\path(1.6374,1.0034)(1.6374,1.083) +\path(1.63197,1.00598)(1.63197,1.07231) +\path(1.62654,1.00855)(1.62654,1.06161) +\path(1.6211,1.01112)(1.6211,1.05092) +\path(1.61567,1.01369)(1.61567,1.04022) +\path(1.61024,1.01626)(1.61024,1.02953) +\color{rgb_000000}% +\path(1.68451,1.17575)(1.8438,0.905667)(1.60481,1.01884)(1.68451,1.17575) +\path(1.55858,1.06528)(1.62462,1.12321)(1.68451,1.17575) +\path(1.64966,0.825085)(1.75291,0.867943)(1.8438,0.905667) +\path(1.42984,0.888834)(1.52409,0.958865)(1.60481,1.01884) +\path(0.957156,0.537641)(1.4039,0.929569)(1.68451,1.17575) +\path(0.957156,0.537641)(1.50556,0.765274)(1.8438,0.905667) +\path(0.957156,0.537641)(1.35769,0.835234)(1.60481,1.01884) +\color{rgb_e5e5e5}% +\path(1.64572,0.826226)(1.5548,1.06009) +\path(1.63918,0.828123)(1.55101,1.0549) +\path(1.63264,0.830021)(1.54722,1.04971) +\path(1.6261,0.831918)(1.54344,1.04452) +\path(1.61955,0.833815)(1.53965,1.03933) +\path(1.61301,0.835712)(1.53586,1.03414) +\path(1.60647,0.837609)(1.53208,1.02895) +\path(1.59993,0.839507)(1.52829,1.02376) +\path(1.59339,0.841404)(1.5245,1.01857) +\path(1.58684,0.843301)(1.52072,1.01338) +\path(1.5803,0.845198)(1.51693,1.00819) +\path(1.57376,0.847095)(1.51314,1.003) +\path(1.56722,0.848993)(1.50936,0.997814) +\path(1.56068,0.85089)(1.50557,0.992624) +\path(1.55413,0.852787)(1.50178,0.987435) +\path(1.54759,0.854684)(1.498,0.982245) +\path(1.54105,0.856581)(1.49421,0.977056) +\path(1.53451,0.858479)(1.49042,0.971866) +\path(1.52797,0.860376)(1.48664,0.966677) +\path(1.52142,0.862273)(1.48285,0.961487) +\path(1.51488,0.86417)(1.47906,0.956298) +\path(1.50834,0.866067)(1.47528,0.951108) +\path(1.5018,0.867965)(1.47149,0.945919) +\path(1.49526,0.869862)(1.4677,0.940729) +\path(1.48871,0.871759)(1.46392,0.93554) +\path(1.48217,0.873656)(1.46013,0.93035) +\path(1.47563,0.875553)(1.45634,0.925161) +\path(1.46909,0.877451)(1.45256,0.919971) +\path(1.46255,0.879348)(1.44877,0.914781) +\path(1.456,0.881245)(1.44498,0.909592) +\path(1.44946,0.883142)(1.4412,0.904402) +\path(1.44292,0.885039)(1.43741,0.899213) +\path(1.43638,0.886937)(1.43362,0.894023) +\path(1.56052,1.06017)(1.55261,1.05709) +\path(1.56246,1.05506)(1.54664,1.04891) +\path(1.5644,1.04995)(1.54066,1.04072) +\path(1.56633,1.04484)(1.53469,1.03253) +\path(1.56827,1.03973)(1.52872,1.02435) +\path(1.57021,1.03461)(1.52274,1.01616) +\path(1.57215,1.0295)(1.51677,1.00797) +\path(1.57409,1.02439)(1.5108,0.999787) +\path(1.57602,1.01928)(1.50482,0.991601) +\path(1.57796,1.01417)(1.49885,0.983414) +\path(1.5799,1.00906)(1.49288,0.975228) +\path(1.58184,1.00395)(1.4869,0.967042) +\path(1.58377,0.998841)(1.48093,0.958855) +\path(1.58571,0.993731)(1.47496,0.950669) +\path(1.58765,0.988621)(1.46898,0.942483) +\path(1.58959,0.98351)(1.46301,0.934296) +\path(1.59152,0.9784)(1.45704,0.92611) +\path(1.59346,0.973289)(1.45106,0.917923) +\path(1.5954,0.968179)(1.44509,0.909737) +\path(1.59734,0.963068)(1.43911,0.901551) +\path(1.59928,0.957958)(1.43314,0.893364) +\path(1.60121,0.952847)(1.43369,0.887715) +\path(1.60315,0.947737)(1.44233,0.88521) +\path(1.60509,0.942626)(1.45097,0.882705) +\path(1.60703,0.937516)(1.45961,0.880199) +\path(1.60896,0.932405)(1.46825,0.877694) +\path(1.6109,0.927295)(1.47689,0.875189) +\path(1.61284,0.922184)(1.48552,0.872684) +\path(1.61478,0.917074)(1.49416,0.870179) +\path(1.61672,0.911963)(1.5028,0.867673) +\path(1.61865,0.906853)(1.51144,0.865168) +\path(1.62059,0.901742)(1.52008,0.862663) +\path(1.62253,0.896632)(1.52872,0.860158) +\path(1.62447,0.891521)(1.53736,0.857653) +\path(1.6264,0.886411)(1.54599,0.855147) +\path(1.62834,0.8813)(1.55463,0.852642) +\path(1.63028,0.87619)(1.56327,0.850137) +\path(1.63222,0.871079)(1.57191,0.847632) +\path(1.63416,0.865969)(1.58055,0.845127) +\path(1.63609,0.860858)(1.58919,0.842621) +\path(1.63803,0.855748)(1.59783,0.840116) +\path(1.63997,0.850637)(1.60646,0.837611) +\path(1.64191,0.845527)(1.6151,0.835106) +\path(1.64384,0.840416)(1.62374,0.8326) +\path(1.64578,0.835306)(1.63238,0.830095) +\path(1.64772,0.830195)(1.64102,0.82759) +\color{rgb_000000}% +\path(1.55858,1.06528)(1.64966,0.825085)(1.42984,0.888834)(1.55858,1.06528) +\path(1.69177,1.3845)(1.6229,1.16677)(1.54714,0.927292) +\put(1.69177,1.3845){\makebox(0,0)[b]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize Object}}}} +\path(2.05075,0.923554)(1.88188,0.980517)(1.71366,1.03726) +\put(2.05075,0.923554){\makebox(0,0)[l]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize Shadow}}}} +\put(1.12218,1.68556){\makebox(0,0)[b]{\colorbox{rgb_ffffff}{\hbox{\color{rgb_000000}\footnotesize Target}}}} +\path(1.12218,1.68556)(1.29391,1.34894) +\path(1.27634,1.40359)(1.2621,1.39054) +\path(1.27896,1.39892)(1.26528,1.38638) +\path(1.28062,1.39336)(1.26846,1.38222) +\path(1.28229,1.38781)(1.27164,1.37806) +\path(1.28395,1.38226)(1.27482,1.3739) +\path(1.28561,1.3767)(1.278,1.36974) +\path(1.28727,1.37115)(1.28118,1.36558) +\path(1.28893,1.3656)(1.28437,1.36142) +\path(1.29059,1.36005)(1.28755,1.35726) +\path(1.29225,1.35449)(1.29073,1.3531) +\path(1.25949,1.39395)(1.29061,1.35998) +\path(1.26348,1.39703)(1.28731,1.37102) +\path(1.26812,1.39939)(1.28401,1.38205) +\path(1.27276,1.40176)(1.28071,1.39309) +\path(1.26816,1.39941)(1.25892,1.3947)(1.29391,1.34894) + (1.2774,1.40413)(1.26816,1.39941) +\put(1.3125,1.3125){\color{rgb_000000}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\allinethickness{0.8pt}% +\path(0.957156,0.537641)(1.55482,0.490175) +\allinethickness{0.0055348in}% +\path(1.4989,0.489651)(1.50786,0.485229) +\path(1.49933,0.495061)(1.51726,0.486218) +\path(1.49976,0.500472)(1.52665,0.487207) +\path(1.50454,0.503736)(1.53604,0.488197) +\path(1.52968,0.496955)(1.54543,0.489186) +\path(1.54888,0.489549)(1.54985,0.491516) +\path(1.54293,0.488923)(1.54487,0.492858) +\path(1.53699,0.488297)(1.5399,0.494199) +\path(1.53104,0.487671)(1.53493,0.495541) +\path(1.5251,0.487045)(1.52995,0.496882) +\path(1.51916,0.486419)(1.52498,0.498223) +\path(1.51321,0.485792)(1.52001,0.499565) +\path(1.50727,0.485166)(1.51504,0.500906) +\path(1.50133,0.48454)(1.51006,0.502247) +\path(1.49903,0.491318)(1.50509,0.503589) +\allinethickness{0.8pt}% +\path(1.49929,0.494585)(1.49847,0.48424)(1.55482,0.490175) + (1.50012,0.50493)(1.49929,0.494585) +\path(0.957156,0.537641)(0.790401,0.174015) +\allinethickness{0.0055348in}% +\path(0.807364,0.192334)(0.808098,0.200697) +\path(0.80171,0.186228)(0.803178,0.202954) +\path(0.796055,0.180122)(0.798257,0.20521) +\path(0.807022,0.201191)(0.793617,0.202367) +\path(0.810836,0.196084)(0.793081,0.197642) +\path(0.806749,0.19167)(0.792545,0.192917) +\path(0.802662,0.187256)(0.792009,0.188191) +\path(0.798575,0.182843)(0.791473,0.183466) +\path(0.794488,0.178429)(0.790937,0.178741) +\allinethickness{0.8pt}% +\path(0.803586,0.202767)(0.794153,0.207092)(0.790401,0.174015) + (0.813019,0.198441)(0.803586,0.202767) +\path(0.957156,0.537641)(0.937572,1.09205) +\allinethickness{0.0055348in}% +\path(0.938782,1.08718)(0.936611,1.08655) +\path(0.939993,1.08231)(0.935649,1.08104) +\path(0.941204,1.07743)(0.934688,1.07554) +\path(0.942414,1.07256)(0.933727,1.07003) +\path(0.943625,1.06769)(0.932765,1.06453) +\path(0.944835,1.06282)(0.931804,1.05902) +\path(0.946046,1.05794)(0.930842,1.05352) +\path(0.947256,1.05307)(0.929881,1.04801) +\path(0.948467,1.0482)(0.929251,1.04261) +\path(0.931094,1.05496)(0.934635,1.0428) +\path(0.933253,1.06732)(0.940334,1.043) +\path(0.935413,1.07969)(0.946034,1.0432) +\allinethickness{0.8pt}% +\path(0.939306,1.04296)(0.949677,1.04333)(0.937572,1.09205) + (0.928935,1.0426)(0.939306,1.04296) +\end{picture}% diff --git a/graphics/epix/doc/camera.xp b/graphics/epix/doc/camera.xp new file mode 100644 index 0000000000..66f8fdb334 --- /dev/null +++ b/graphics/epix/doc/camera.xp @@ -0,0 +1,86 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const double ht(4); + +const P target(0,0,0); +const P observer(0,-4,0); +const P dtarg(-0.5,0,1); +const double dx(0.375); + +// location of label +const P obj_loc(1,0,0.25); + +P F(P arg) +{ + double x(arg.x2()); + return (ht/(ht+x))*P(arg.x1(), 0, arg.x3()); +} + +P P1(0.75, -1, -0.25); +P P2(1, -1.25, -0.75); +P P3(0.5, -1.5, -0.5 ); +P midpt((1.0/3)*(P1+P2+P3)); + +int main() { + bounding_box(P(-3.5,-3.5),P(3.5,2.5)); + unitlength("0.375in"); + picture(P(7,6)); + + begin(); + + camera.at(P(1.5,-10,3.5)); + camera.range(10); + + font_size("footnotesize"); + right_angle(target, E_1, -E_2); + + line(target, target+2*dx*E_1); + line(target, target+2*dx*E_3); + + // grid(P(-3,0,-2), P(3,0,2), 6, 8); + grid(P(-3,0,-2), P(3,0,2)); + + masklabel(observer+E_1, P(2,0), "\\textbf{Sea}", r); + masklabel(observer+E_3, P(0,2), "\\textbf{Sky}", t); + masklabel(observer-E_2, P(-4,0), "\\textbf{Eye}", l); + + masklabel(observer, P(-2,0), "Viewpoint", l); + dot(observer); + + masklabel(P(3,0,2), P(-6,-2), "Canvas", bl); + + line(observer, target); + + fill(Black(0.5)); + triangle(F(P1), F(P2), F(P3)); + + line(P1, F(P1)); + line(P2, F(P2)); + line(P3, F(P3)); + + line(observer, F(P1)); + line(observer, F(P2)); + line(observer, F(P3)); + + fill(Black(0.1)); + triangle(P1, P2, P3); + + line(obj_loc, midpt); + masklabel(obj_loc, P(0,0), "Object", t); + + line(P(2,0,-1), F(midpt)); + masklabel(P(2,0,-1), P(0,0), "Shadow", r); + + masklabel(target+dtarg, P(0,0), "Target", t); + arrow(target+dtarg, target+0.1*dtarg, 0.5); + dot(target); + + bold(); + arrow(observer, observer+E_1, 0.5); + arrow(observer, observer-E_2, 0.5); + arrow(observer, observer+E_3, 0.5); + + end(); +} diff --git a/graphics/epix/doc/cb.eepic b/graphics/epix/doc/cb.eepic new file mode 100644 index 0000000000..7df0354645 --- /dev/null +++ b/graphics/epix/doc/cb.eepic @@ -0,0 +1,25 @@ +%% Generated from cb.xp on Tue Jan 4 15:32:10 EST 2005 by +%% ePiX-1.0.3 +%% +%% Cartesian bounding box: [-2,2] x [-1,1] +%% Actual size: 1.5in x 0.75in +%% Figure offset: right by 0in, up by 0in +%% +\setlength{\unitlength}{1in} +\begin{picture}(1.5,0.75)(-0,-0) +%% --- +\path(0,0.375)(1.5,0.375) +\put(0,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}} +\put(0.375,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}} +\put(0.75,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}} +\put(1.125,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}} +\put(1.5,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}} +%% --- +\path(0.75,0)(0.75,0.75) +\put(0.75,0){\makebox(0,0)[c]{\rule{4pt}{0.5pt}}} +\put(0.75,0.75){\makebox(0,0)[c]{\rule{4pt}{0.5pt}}} +%% --- +\thicklines +\path(0,0.375)(0.375,0.75)(0.75,0.375)(1.125,0.75)(1.5,0.375) +\put(0.75,-0.055348){\makebox(0,0)[t]{\code{cb}}} +\end{picture} diff --git a/graphics/epix/doc/cb.xp b/graphics/epix/doc/cb.xp new file mode 100644 index 0000000000..e0434b483e --- /dev/null +++ b/graphics/epix/doc/cb.xp @@ -0,0 +1,22 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +int main() +{ + bounding_box(P(-2,-1),P(2,1)); + unitlength("1in"); + picture(1.5,0.75); + + begin(); + + h_axis(4); + v_axis(1); + + bold(); + plot(cb, x_min, x_max, 4); + + label(P(0,y_min), P(0,-4), "\\code{cb}", b); + + end(); +} diff --git a/graphics/epix/doc/color_density.eepic b/graphics/epix/doc/color_density.eepic new file mode 100644 index 0000000000..1b0ee79028 --- /dev/null +++ b/graphics/epix/doc/color_density.eepic @@ -0,0 +1,139 @@ +%% Generated from color_density.xp on Thu Jul 5 10:01:14 EDT 2007 by +%% ePiX-1.1.6 +%% +%% Cartesian bounding box: [-2,2] x [0,1.375] +%% Actual size: 4 x 1.5in +%% Figure offset: left by 0in, down by 0in +%% +\newrgbcolor{rgb_000000}{0 0 0} +\newrgbcolor{rgb_005454}{0 0.329412 0.329412} +\newrgbcolor{rgb_00a9a9}{0 0.662745 0.662745} +\newrgbcolor{rgb_00fefe}{0 0.996078 0.996078} +\newrgbcolor{rgb_00ffff}{0 1 1} +\newrgbcolor{rgb_540000}{0.329412 0 0} +\newrgbcolor{rgb_54ffff}{0.329412 1 1} +\newrgbcolor{rgb_a90000}{0.662745 0 0} +\newrgbcolor{rgb_a9ffff}{0.662745 1 1} +\newrgbcolor{rgb_fe0000}{0.996078 0 0} +\newrgbcolor{rgb_feffff}{0.996078 1 1} +\newrgbcolor{rgb_ff0000}{1 0 0} +\newrgbcolor{rgb_ff5454}{1 0.329412 0.329412} +\newrgbcolor{rgb_ffa9a9}{1 0.662745 0.662745} +\newrgbcolor{rgb_fffefe}{1 0.996078 0.996078} +\psset{unit=1in,linewidth=0.4pt} +\begin{pspicture}(4,1.5)(-0,-0) +\psset{fillcolor=rgb_feffff}% +\psline[fillstyle=solid] + (-0.123,1.22727)(0.127,1.22727)(0.127,1.5)(-0.123,1.5)(-0.123,1.22727) +%% +\psline(-0.123,1.22727)(0.127,1.22727)(0.127,1.5)(-0.123,1.5)(-0.123,1.22727) +%% +\psset{fillcolor=rgb_a9ffff}% +\psline[fillstyle=solid] + (0.21,1.22727)(0.46,1.22727)(0.46,1.5)(0.21,1.5)(0.21,1.22727) +%% +\psline(0.21,1.22727)(0.46,1.22727)(0.46,1.5)(0.21,1.5)(0.21,1.22727) +%% +\psset{fillcolor=rgb_54ffff}% +\psline[fillstyle=solid] + (0.543,1.22727)(0.793,1.22727)(0.793,1.5)(0.543,1.5)(0.543,1.22727) +%% +\psline(0.543,1.22727)(0.793,1.22727)(0.793,1.5)(0.543,1.5)(0.543,1.22727) +%% +\psset{fillcolor=rgb_00fefe}% +\psline[fillstyle=solid] + (0.876,1.22727)(1.126,1.22727)(1.126,1.5)(0.876,1.5)(0.876,1.22727) +%% +\psline(0.876,1.22727)(1.126,1.22727)(1.126,1.5)(0.876,1.5)(0.876,1.22727) +%% +\psset{fillcolor=rgb_00a9a9}% +\psline[fillstyle=solid] + (1.209,1.22727)(1.459,1.22727)(1.459,1.5)(1.209,1.5)(1.209,1.22727) +%% +\psline(1.209,1.22727)(1.459,1.22727)(1.459,1.5)(1.209,1.5)(1.209,1.22727) +%% +\psset{fillcolor=rgb_005454}% +\psline[fillstyle=solid] + (1.542,1.22727)(1.792,1.22727)(1.792,1.5)(1.542,1.5)(1.542,1.22727) +%% +\psline(1.542,1.22727)(1.792,1.22727)(1.792,1.5)(1.542,1.5)(1.542,1.22727) +%% +\psset{fillcolor=rgb_000000}% +\psline[fillstyle=solid] + (1.875,1.22727)(2.125,1.22727)(2.125,1.5)(1.875,1.5)(1.875,1.22727) +%% +\psline(1.875,1.22727)(2.125,1.22727)(2.125,1.5)(1.875,1.5)(1.875,1.22727) +%% +\psset{fillcolor=rgb_540000}% +\psline[fillstyle=solid] + (2.208,1.22727)(2.458,1.22727)(2.458,1.5)(2.208,1.5)(2.208,1.22727) +%% +\psline(2.208,1.22727)(2.458,1.22727)(2.458,1.5)(2.208,1.5)(2.208,1.22727) +%% +\psset{fillcolor=rgb_a90000}% +\psline[fillstyle=solid] + (2.541,1.22727)(2.791,1.22727)(2.791,1.5)(2.541,1.5)(2.541,1.22727) +%% +\psline(2.541,1.22727)(2.791,1.22727)(2.791,1.5)(2.541,1.5)(2.541,1.22727) +%% +\psset{fillcolor=rgb_fe0000}% +\psline[fillstyle=solid] + (2.874,1.22727)(3.124,1.22727)(3.124,1.5)(2.874,1.5)(2.874,1.22727) +%% +\psline(2.874,1.22727)(3.124,1.22727)(3.124,1.5)(2.874,1.5)(2.874,1.22727) +%% +\psset{fillcolor=rgb_ff5454}% +\psline[fillstyle=solid] + (3.207,1.22727)(3.457,1.22727)(3.457,1.5)(3.207,1.5)(3.207,1.22727) +%% +\psline(3.207,1.22727)(3.457,1.22727)(3.457,1.5)(3.207,1.5)(3.207,1.22727) +%% +\psset{fillcolor=rgb_ffa9a9}% +\psline[fillstyle=solid] + (3.54,1.22727)(3.79,1.22727)(3.79,1.5)(3.54,1.5)(3.54,1.22727) +%% +\psline(3.54,1.22727)(3.79,1.22727)(3.79,1.5)(3.54,1.5)(3.54,1.22727) +%% +\psset{fillcolor=rgb_fffefe}% +\psline[fillstyle=solid] + (3.873,1.22727)(4.123,1.22727)(4.123,1.5)(3.873,1.5)(3.873,1.22727) +%% +\psline(3.873,1.22727)(4.123,1.22727)(4.123,1.5)(3.873,1.5)(3.873,1.22727) +%% +\psline(0,0)(4,0) +%% +\rput(0,0){\makebox(0,0){{$\rule{0.5pt}{4pt}$}}} +\rput(1,0){\makebox(0,0){{$\rule{0.5pt}{4pt}$}}} +\rput(2,0){\makebox(0,0){{$\rule{0.5pt}{4pt}$}}} +\rput(3,0){\makebox(0,0){{$\rule{0.5pt}{4pt}$}}} +\rput(4,0){\makebox(0,0){{$\rule{0.5pt}{4pt}$}}} +\psline(2,0)(2,1.09091) +%% +\rput(2,0){\makebox(0,0){{$\rule{4pt}{0.5pt}$}}} +\rput(2,1.09091){\makebox(0,0){{$\rule{4pt}{0.5pt}$}}} +\rput(0,-0.055348){\makebox(0,0)[t]{{$-2$}}} +\rput(1,-0.055348){\makebox(0,0)[t]{{$-1$}}} +\rput(2,-0.055348){\makebox(0,0)[t]{{$\phantom{-}0$}}} +\rput(3,-0.055348){\makebox(0,0)[t]{{$\phantom{-}1$}}} +\rput(4,-0.055348){\makebox(0,0)[t]{{$\phantom{-}2$}}} +\psset{linecolor=rgb_00ffff}% +\psline(0,1.09091)(1,1.09091) +%% +\psline(1,1.09091)(2,0) +%% +\psline(2,0)(3,0) +%% +\psline(3,0)(4,1.09091) +%% +\psset{linewidth=0.8pt}% +\psset{linecolor=rgb_ff0000}% +\psline + (0,1.09091)(1,0) +%% +\psline(1,0)(2,0) +%% +\psline(2,0)(3,1.09091) +%% +\psline(3,1.09091)(4,1.09091) +%% +\end{pspicture} diff --git a/graphics/epix/doc/color_density.xp b/graphics/epix/doc/color_density.xp new file mode 100644 index 0000000000..f561fa43e3 --- /dev/null +++ b/graphics/epix/doc/color_density.xp @@ -0,0 +1,42 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +double dX(0.125), dY(0.25); + +int main() +{ + picture(P(-2, 0), P(2, 1.125 + dY), "4 x 1.5in"); + + begin(); + + fill(); + for (int i=-6; i<=6; ++i) + { + const double x(0.333*i); + fill(Red(x)); + rect(P(x-dX, 1.125), P(x+dX, 1.125+dY)); + } + nofill(); + + h_axis(4); + v_axis(P(0,0), P(0,1), 1); + + h_axis_labels(4, P(0,-4), b); + red(-1); + line(P(-2,1), P(-1,1)); + line(P(-1,1), P(0,0)); + line(P(0,0), P(1,0)); + line(P(1,0), P(2,1)); + + red(); + bold(); + line(P(-2,1), P(-1,0)); + line(P(-1,0), P(0,0)); + + line(P(0,0), P(1,1)); + line(P(1,1), P(2,1)); + + pst_format(); + end(); +} diff --git a/graphics/epix/doc/dots.eepic b/graphics/epix/doc/dots.eepic new file mode 100644 index 0000000000..839663481d --- /dev/null +++ b/graphics/epix/doc/dots.eepic @@ -0,0 +1,19 @@ +%% Generated from dots.xp on Tue Jan 4 15:32:12 EST 2005 by +%% ePiX-1.0.3 +%% +%% Cartesian bounding box: [0,8] x [0,1] +%% Actual size: 72pt x 12pt +%% Figure offset: right by 10pt, up by 2pt +%% +\setlength{\unitlength}{1pt} +\begin{picture}(72,12)(-10,-2) +%% --- +\put(0,0){\makebox(0,0)[c]{{\circle*{4.5}}}} +\put(9,0){\makebox(0,0)[c]{{\circle*{3}}}} +\put(18,0){\makebox(0,0)[c]{{\circle*{2}}}} +\put(36,0){\makebox(0,0)[c]{\rule{3pt}{3pt}}} +\put(45,0){\makebox(0,0)[c]{\rule{2pt}{2pt}}} +\path(58.5,0)(78.75,0) +\put(63,0){\makebox(0,0)[c]{{\circle{4.5}}}} +\whiten\put(72,0){\makebox(0,0)[c]{{\circle{3}}}} +\end{picture} diff --git a/graphics/epix/doc/dots.xp b/graphics/epix/doc/dots.xp new file mode 100644 index 0000000000..1f13fb6099 --- /dev/null +++ b/graphics/epix/doc/dots.xp @@ -0,0 +1,28 @@ +/* -*-ePiX-*- */ +/* dots.c -- Dot primitives */ +#include "epix.h" +using namespace ePiX; + +int main() +{ + unitlength("1pt"); + bounding_box(P(0,0), P(8,1)); + picture(P(72,12)); + offset(P(10,2)); + + begin(); + + spot(P(0,0)); + dot(P(1,0)); + ddot(P(2,0)); + + box(P(4,0)); + bbox(P(5,0)); + + line(P(6.5,0), P(8.75,0)); + + ring(P(7,0)); + circ(P(8,0)); + + end(); +} diff --git a/graphics/epix/doc/ePiX.eepic b/graphics/epix/doc/ePiX.eepic new file mode 100644 index 0000000000..4bdec31118 --- /dev/null +++ b/graphics/epix/doc/ePiX.eepic @@ -0,0 +1,1099 @@ +%% Generated from ePiX.xp on Sat Sep 22 20:16:03 EDT 2007 by +%% ePiX-1.2.0 +%% +%% Cartesian bounding box: [-0.5,5.75] x [2,10] +%% Actual size: 4 x 7.5in +%% Figure offset: left by 0in, down by 0in +%% +%% usepackages epic,eepic,xcolor +%% +\xdefinecolor{cmy_000019}{cmyk}{0,0,0.0980392,0}% +\xdefinecolor{rgb_0000ff}{rgb}{0,0,1}% +\xdefinecolor{rgb_009800}{rgb}{0,0.596078,0}% +\xdefinecolor{rgb_7f7f7f}{rgb}{0.498039,0.498039,0.498039}% +\xdefinecolor{rgb_ff0000}{rgb}{1,0,0}% +\setlength{\unitlength}{1in}% +\begin{picture}(4,7.5)(0,0)% +\color{rgb_7f7f7f}% +\path(0.32,7.03125)(0.96,7.03125) +\path(0.902922,7.02606)(0.931461,7.02606) +\path(0.902922,7.03125)(0.96,7.03125) +\path(0.902922,7.03644)(0.931461,7.03644) +\path(0.954811,7.03031)(0.954811,7.03219) +\path(0.949622,7.02936)(0.949622,7.03314) +\path(0.944433,7.02842)(0.944433,7.03408) +\path(0.939244,7.02748)(0.939244,7.03502) +\path(0.934056,7.02653)(0.934056,7.03597) +\path(0.928867,7.02559)(0.928867,7.03691) +\path(0.923678,7.02465)(0.923678,7.03785) +\path(0.918489,7.0237)(0.918489,7.0388) +\path(0.9133,7.02276)(0.9133,7.03974) +\path(0.908111,7.02182)(0.908111,7.04068) +\path(0.902922,7.02087)(0.902922,7.04163) +\path(0.902922,7.03125)(0.902922,7.02087)(0.96,7.03125) + (0.902922,7.04163)(0.902922,7.03125) +\put(0.32,7.0866){\makebox(0,0)[b]{\hbox{\color{rgb_7f7f7f}\footnotesize \texttt{xp}, \texttt{flx}}}} +\put(0.32,7.03125){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\put(0.97999,7.08981){\makebox(0,0)[b]{\hbox{\color{rgb_7f7f7f}\footnotesize \texttt{eepic}}}} +\put(0.96,7.03125){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\allinethickness{1.2pt}% +\color{rgb_ff0000}% +\path(0.96,7.03125)(0.963187,7.03115)(0.966347,7.03086) + (0.969482,7.03039)(0.972591,7.02972)(0.975676,7.02888) + (0.978736,7.02785)(0.981772,7.02665)(0.984785,7.02528) + (0.987774,7.02374)(0.990741,7.02203)(0.993685,7.02016) + (0.996608,7.01813)(0.999509,7.01594)(1.00239,7.0136) + (1.00525,7.01111)(1.00809,7.00847)(1.01091,7.00569) + (1.01371,7.00277)(1.01649,6.99972)(1.01926,6.99653) + (1.02201,6.99321)(1.02474,6.98976)(1.02745,6.98619)(1.03014,6.9825) + (1.03282,6.97869)(1.03549,6.97477)(1.03814,6.97074)(1.04077,6.9666) + (1.04339,6.96235)(1.046,6.95801)(1.04859,6.95356)(1.05117,6.94903) + (1.05374,6.9444)(1.0563,6.93968)(1.05884,6.93488)(1.06138,6.93) + (1.0639,6.92504)(1.06641,6.92)(1.06891,6.9149)(1.07141,6.90972) + (1.07389,6.90448)(1.07637,6.89918)(1.07884,6.89382)(1.0813,6.8884) + (1.08375,6.88293)(1.0862,6.87742)(1.08864,6.87185)(1.09107,6.86625) + (1.0935,6.86061)(1.09593,6.85493)(1.09835,6.84921)(1.10076,6.84347) + (1.10317,6.8377)(1.10558,6.83191)(1.10799,6.8261)(1.1104,6.82028) + (1.1128,6.81444)(1.1152,6.80859)(1.1176,6.80273)(1.12,6.79688) + (1.1224,6.79102)(1.1248,6.78516)(1.1272,6.77931)(1.1296,6.77347) + (1.13201,6.76765)(1.13442,6.76184)(1.13683,6.75605) + (1.13924,6.75028)(1.14165,6.74454)(1.14407,6.73882)(1.1465,6.73314) + (1.14893,6.7275)(1.15136,6.7219)(1.1538,6.71633)(1.15625,6.71082) + (1.1587,6.70535)(1.16116,6.69993)(1.16363,6.69457)(1.16611,6.68927) + (1.16859,6.68403)(1.17109,6.67885)(1.17359,6.67375)(1.1761,6.66871) + (1.17862,6.66375)(1.18116,6.65887)(1.1837,6.65407)(1.18626,6.64935) + (1.18883,6.64472)(1.19141,6.64019)(1.194,6.63574)(1.19661,6.6314) + (1.19923,6.62715)(1.20186,6.62301)(1.20451,6.61898) + (1.20718,6.61506)(1.20986,6.61125)(1.21255,6.60756) + (1.21526,6.60399)(1.21799,6.60054)(1.22074,6.59722) + (1.22351,6.59403)(1.22629,6.59098)(1.22909,6.58806) + (1.23191,6.58528)(1.23475,6.58264)(1.23761,6.58015) + (1.24049,6.57781)(1.24339,6.57562)(1.24631,6.57359) + (1.24926,6.57172)(1.25223,6.57001)(1.25522,6.56847)(1.25823,6.5671) + (1.26126,6.5659)(1.26432,6.56487)(1.26741,6.56403)(1.27052,6.56336) + (1.27365,6.56289)(1.27681,6.5626)(1.28,6.5625) +\path(1.28,6.5625)(1.6,6.5625) +\allinethickness{0.0055348in}% +\path(1.59481,6.56156)(1.59402,6.56359) +\path(1.58962,6.56061)(1.58804,6.56467) +\path(1.58443,6.55967)(1.58207,6.56576) +\path(1.57924,6.55873)(1.57609,6.56685) +\path(1.57406,6.55778)(1.57011,6.56793) +\path(1.56887,6.55684)(1.56413,6.56902) +\path(1.56368,6.5559)(1.55815,6.57011) +\path(1.55849,6.55495)(1.55217,6.5712) +\path(1.5533,6.55401)(1.5462,6.57228) +\path(1.54811,6.55307)(1.54292,6.56641) +\path(1.55244,6.57115)(1.54292,6.56745) +\path(1.56195,6.56942)(1.54292,6.56202) +\path(1.57146,6.56769)(1.54292,6.55659) +\path(1.58097,6.56596)(1.54755,6.55296) +\path(1.59049,6.56423)(1.57377,6.55773) +\allinethickness{1.2pt}% +\path(1.54292,6.5625)(1.54292,6.55212)(1.6,6.5625)(1.54292,6.57288)(1.54292,6.5625) +\path(1.6,6.5625)(2.24,6.5625) +\allinethickness{0.0055348in}% +\path(2.18926,6.57172)(2.18292,6.56591) +\path(2.19561,6.57057)(2.18292,6.55895) +\path(2.20195,6.56942)(2.1831,6.55216) +\path(2.20829,6.56827)(2.19259,6.55388) +\path(2.21463,6.56711)(2.20207,6.5556) +\path(2.22097,6.56596)(2.21155,6.55733) +\path(2.22732,6.56481)(2.22103,6.55905) +\path(2.23366,6.56365)(2.23052,6.56078) +\path(2.18292,6.5602)(2.18926,6.55328) +\path(2.18292,6.56827)(2.19561,6.55443) +\path(2.18674,6.57218)(2.20195,6.55558) +\path(2.19562,6.57057)(2.20829,6.55673) +\path(2.20449,6.56896)(2.21463,6.55789) +\path(2.21337,6.56734)(2.22097,6.55904) +\path(2.22225,6.56573)(2.22732,6.56019) +\path(2.23112,6.56411)(2.23366,6.56135) +\allinethickness{1.2pt}% +\path(2.18292,6.5625)(2.18292,6.55212)(2.24,6.5625) + (2.18292,6.57288)(2.18292,6.5625) +\put(1.6,6.61785){\makebox(0,0)[b]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\footnotesize \texttt{dvi}}}}} +\put(1.6,6.5625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\put(2.21793,6.59482){\makebox(0,0)[br]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\footnotesize \texttt{ps}}}}} +\put(2.24,6.5625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\path(0.96,6.09375)(0.963187,6.09385)(0.966347,6.09414) + (0.969482,6.09461)(0.972591,6.09528)(0.975676,6.09612) + (0.978736,6.09715)(0.981772,6.09835)(0.984785,6.09972) + (0.987774,6.10126)(0.990741,6.10297)(0.993685,6.10484) + (0.996608,6.10687)(0.999509,6.10906)(1.00239,6.1114) + (1.00525,6.11389)(1.00809,6.11653)(1.01091,6.11931) + (1.01371,6.12223)(1.01649,6.12528)(1.01926,6.12847) + (1.02201,6.13179)(1.02474,6.13524)(1.02745,6.13881)(1.03014,6.1425) + (1.03282,6.14631)(1.03549,6.15023)(1.03814,6.15426)(1.04077,6.1584) + (1.04339,6.16265)(1.046,6.16699)(1.04859,6.17144)(1.05117,6.17597) + (1.05374,6.1806)(1.0563,6.18532)(1.05884,6.19012)(1.06138,6.195) + (1.0639,6.19996)(1.06641,6.205)(1.06891,6.2101)(1.07141,6.21528) + (1.07389,6.22052)(1.07637,6.22582)(1.07884,6.23118)(1.0813,6.2366) + (1.08375,6.24207)(1.0862,6.24758)(1.08864,6.25315)(1.09107,6.25875) + (1.0935,6.26439)(1.09593,6.27007)(1.09835,6.27579)(1.10076,6.28153) + (1.10317,6.2873)(1.10558,6.29309)(1.10799,6.2989)(1.1104,6.30472) + (1.1128,6.31056)(1.1152,6.31641)(1.1176,6.32227)(1.12,6.32812) + (1.1224,6.33398)(1.1248,6.33984)(1.1272,6.34569)(1.1296,6.35153) + (1.13201,6.35735)(1.13442,6.36316)(1.13683,6.36895) + (1.13924,6.37472)(1.14165,6.38046)(1.14407,6.38618)(1.1465,6.39186) + (1.14893,6.3975)(1.15136,6.4031)(1.1538,6.40867)(1.15625,6.41418) + (1.1587,6.41965)(1.16116,6.42507)(1.16363,6.43043)(1.16611,6.43573) + (1.16859,6.44097)(1.17109,6.44615)(1.17359,6.45125)(1.1761,6.45629) + (1.17862,6.46125)(1.18116,6.46613)(1.1837,6.47093)(1.18626,6.47565) + (1.18883,6.48028)(1.19141,6.48481)(1.194,6.48926)(1.19661,6.4936) + (1.19923,6.49785)(1.20186,6.50199)(1.20451,6.50602) + (1.20718,6.50994)(1.20986,6.51375)(1.21255,6.51744) + (1.21526,6.52101)(1.21799,6.52446)(1.22074,6.52778) + (1.22351,6.53097)(1.22629,6.53402)(1.22909,6.53694) + (1.23191,6.53972)(1.23475,6.54236)(1.23761,6.54485) + (1.24049,6.54719)(1.24339,6.54938)(1.24631,6.55141) + (1.24926,6.55328)(1.25223,6.55499)(1.25522,6.55653)(1.25823,6.5579) + (1.26126,6.5591)(1.26432,6.56013)(1.26741,6.56097)(1.27052,6.56164) + (1.27365,6.56211)(1.27681,6.5624)(1.28,6.5625) +\put(0.97999,6.03519){\makebox(0,0)[t]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\footnotesize \texttt{tex}}}}} +\put(0.96,6.09375){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\path(2.24,6.5625)(2.24533,6.55472)(2.25067,6.54701)(2.256,6.53936) + (2.26133,6.53177)(2.26667,6.52425)(2.272,6.5168)(2.27733,6.50941) + (2.28267,6.50208)(2.288,6.49482)(2.29333,6.48763)(2.29867,6.4805) + (2.304,6.47344)(2.30933,6.46644)(2.31467,6.45951)(2.32,6.45264) + (2.32533,6.44583)(2.33067,6.4391)(2.336,6.43242)(2.34133,6.42581) + (2.34667,6.41927)(2.352,6.41279)(2.35733,6.40638)(2.36267,6.40003) + (2.368,6.39375)(2.37333,6.38753)(2.37867,6.38138)(2.384,6.37529) + (2.38933,6.36927)(2.39467,6.36331)(2.4,6.35742)(2.40533,6.3516) + (2.41067,6.34583)(2.416,6.34014)(2.42133,6.33451)(2.42667,6.32894) + (2.432,6.32344)(2.43733,6.318)(2.44267,6.31263)(2.448,6.30732) + (2.45333,6.30208)(2.45867,6.29691)(2.464,6.2918)(2.46933,6.28675) + (2.47467,6.28177)(2.48,6.27686)(2.48533,6.27201)(2.49067,6.26722) + (2.496,6.2625)(2.50133,6.25785)(2.50667,6.25326)(2.512,6.24873) + (2.51733,6.24427)(2.52267,6.23988)(2.528,6.23555)(2.53333,6.23128) + (2.53867,6.22708)(2.544,6.22295)(2.54933,6.21888)(2.55467,6.21488) + (2.56,6.21094)(2.56533,6.20706)(2.57067,6.20326)(2.576,6.19951) + (2.58133,6.19583)(2.58667,6.19222)(2.592,6.18867)(2.59733,6.18519) + (2.60267,6.18177)(2.608,6.17842)(2.61333,6.17513)(2.61867,6.17191) + (2.624,6.16875)(2.62933,6.16566)(2.63467,6.16263)(2.64,6.15967) + (2.64533,6.15677)(2.65067,6.15394)(2.656,6.15117)(2.66133,6.14847) + (2.66667,6.14583)(2.672,6.14326)(2.67733,6.14076)(2.68267,6.13831) + (2.688,6.13594)(2.69333,6.13363)(2.69867,6.13138)(2.704,6.1292) + (2.70933,6.12708)(2.71467,6.12503)(2.72,6.12305)(2.72533,6.12113) + (2.73067,6.11927)(2.736,6.11748)(2.74133,6.11576)(2.74667,6.1141) + (2.752,6.1125)(2.75733,6.11097)(2.76267,6.10951)(2.768,6.10811) + (2.77333,6.10677)(2.77867,6.1055)(2.784,6.1043)(2.78933,6.10316) + (2.79467,6.10208)(2.8,6.10107)(2.80533,6.10013)(2.81067,6.09925) + (2.816,6.09844)(2.82133,6.09769)(2.82667,6.09701)(2.832,6.09639) + (2.83733,6.09583)(2.84267,6.09535)(2.848,6.09492)(2.85333,6.09456) + (2.85867,6.09427)(2.864,6.09404)(2.86933,6.09388)(2.87467,6.09378)(2.88,6.09375) +\allinethickness{0.0055348in}% +\path(2.82289,6.08916)(2.83102,6.08515) +\path(2.82293,6.09461)(2.83919,6.08659) +\path(2.82296,6.10005)(2.84735,6.08802) +\path(2.82634,6.10385)(2.85551,6.08945) +\path(2.84423,6.10048)(2.86367,6.09088) +\path(2.86211,6.09712)(2.87184,6.09232) +\path(2.8738,6.09266)(2.87482,6.09473) +\path(2.8676,6.09157)(2.86963,6.0957) +\path(2.8614,6.09048)(2.86445,6.09668) +\path(2.8552,6.0894)(2.85927,6.09765) +\path(2.84899,6.08831)(2.85408,6.09863) +\path(2.84279,6.08722)(2.8489,6.0996) +\path(2.83659,6.08613)(2.84372,6.10058) +\path(2.83039,6.08504)(2.83854,6.10155) +\path(2.82419,6.08395)(2.83335,6.10253) +\path(2.82292,6.09285)(2.82817,6.1035) +\allinethickness{1.2pt}% +\path(2.82292,6.0941)(2.82286,6.08372)(2.88,6.09375) + (2.82299,6.10448)(2.82292,6.0941) +\put(2.93535,6.09375){\makebox(0,0)[l]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\footnotesize \texttt{pdf}}}}} +\put(2.88,6.09375){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\allinethickness{0.4pt}% +\color{rgb_7f7f7f}% +\path(2.24,6.5625)(2.24533,6.57028)(2.25067,6.57799)(2.256,6.58564) + (2.26133,6.59323)(2.26667,6.60075)(2.272,6.6082)(2.27733,6.61559) + (2.28267,6.62292)(2.288,6.63018)(2.29333,6.63737)(2.29867,6.6445) + (2.304,6.65156)(2.30933,6.65856)(2.31467,6.66549)(2.32,6.67236) + (2.32533,6.67917)(2.33067,6.6859)(2.336,6.69258)(2.34133,6.69919) + (2.34667,6.70573)(2.352,6.71221)(2.35733,6.71862)(2.36267,6.72497) + (2.368,6.73125)(2.37333,6.73747)(2.37867,6.74362)(2.384,6.74971) + (2.38933,6.75573)(2.39467,6.76169)(2.4,6.76758)(2.40533,6.7734) + (2.41067,6.77917)(2.416,6.78486)(2.42133,6.79049)(2.42667,6.79606) + (2.432,6.80156)(2.43733,6.807)(2.44267,6.81237)(2.448,6.81768) + (2.45333,6.82292)(2.45867,6.82809)(2.464,6.8332)(2.46933,6.83825) + (2.47467,6.84323)(2.48,6.84814)(2.48533,6.85299)(2.49067,6.85778) + (2.496,6.8625)(2.50133,6.86715)(2.50667,6.87174)(2.512,6.87627) + (2.51733,6.88073)(2.52267,6.88512)(2.528,6.88945)(2.53333,6.89372) + (2.53867,6.89792)(2.544,6.90205)(2.54933,6.90612)(2.55467,6.91012) + (2.56,6.91406)(2.56533,6.91794)(2.57067,6.92174)(2.576,6.92549) + (2.58133,6.92917)(2.58667,6.93278)(2.592,6.93633)(2.59733,6.93981) + (2.60267,6.94323)(2.608,6.94658)(2.61333,6.94987)(2.61867,6.95309) + (2.624,6.95625)(2.62933,6.95934)(2.63467,6.96237)(2.64,6.96533) + (2.64533,6.96823)(2.65067,6.97106)(2.656,6.97383)(2.66133,6.97653) + (2.66667,6.97917)(2.672,6.98174)(2.67733,6.98424)(2.68267,6.98669) + (2.688,6.98906)(2.69333,6.99137)(2.69867,6.99362)(2.704,6.9958) + (2.70933,6.99792)(2.71467,6.99997)(2.72,7.00195)(2.72533,7.00387) + (2.73067,7.00573)(2.736,7.00752)(2.74133,7.00924)(2.74667,7.0109) + (2.752,7.0125)(2.75733,7.01403)(2.76267,7.01549)(2.768,7.01689) + (2.77333,7.01823)(2.77867,7.0195)(2.784,7.0207)(2.78933,7.02184) + (2.79467,7.02292)(2.8,7.02393)(2.80533,7.02487)(2.81067,7.02575) + (2.816,7.02656)(2.82133,7.02731)(2.82667,7.02799)(2.832,7.02861) + (2.83733,7.02917)(2.84267,7.02965)(2.848,7.03008)(2.85333,7.03044) + (2.85867,7.03073)(2.864,7.03096)(2.86933,7.03112)(2.87467,7.03122)(2.88,7.03125) +\path(2.87464,7.03024)(2.87481,7.03216) +\path(2.86927,7.02923)(2.86961,7.03307) +\path(2.86391,7.02822)(2.86442,7.03399) +\path(2.85855,7.02721)(2.85922,7.0349) +\path(2.85318,7.02621)(2.85403,7.03581) +\path(2.84782,7.0252)(2.84883,7.03672) +\path(2.84246,7.02419)(2.84364,7.03763) +\path(2.8371,7.02318)(2.83844,7.03854) +\path(2.83173,7.02217)(2.83325,7.03946) +\path(2.82637,7.02116)(2.82805,7.04037) +\path(2.87938,7.03113)(2.82289,7.03609) +\path(2.86058,7.0276)(2.82292,7.0309) +\path(2.84178,7.02406)(2.82296,7.02571) +\path(2.82292,7.0309)(2.82299,7.02052)(2.88,7.03125) + (2.82286,7.04128)(2.82292,7.0309) +\put(2.86001,7.08981){\makebox(0,0)[b]{\hbox{\color{rgb_7f7f7f}\footnotesize \texttt{eps}}}} +\put(2.88,7.03125){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\path(2.88,7.03125)(3.52,7.03125) +\path(3.47434,7.03955)(3.46292,7.03623) +\path(3.48575,7.03748)(3.46292,7.03083) +\path(3.49717,7.0354)(3.46292,7.02543) +\path(3.50858,7.03333)(3.4706,7.02227) +\path(3.46292,7.03964)(3.46811,7.02182) +\path(3.46808,7.04069)(3.4733,7.02276) +\path(3.47385,7.03964)(3.47849,7.0237) +\path(3.47962,7.03859)(3.48368,7.02465) +\path(3.48539,7.03754)(3.48887,7.02559) +\path(3.49116,7.03649)(3.49406,7.02653) +\path(3.49692,7.03545)(3.49924,7.02748) +\path(3.50269,7.0344)(3.50443,7.02842) +\path(3.50846,7.03335)(3.50962,7.02936) +\path(3.51423,7.0323)(3.51481,7.03031) +\path(3.46292,7.03125)(3.46292,7.02087)(3.52,7.03125) + (3.46292,7.04163)(3.46292,7.03125) +\put(3.57535,7.03125){\makebox(0,0)[l]{\hbox{\color{rgb_7f7f7f}\footnotesize \begin{minipage}{0.225in}\texttt{png mng gif}\end{minipage}}}} +\put(3.52,7.03125){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\put(1.92,6.09375){\makebox(0,0)[c]{\hbox{\color{rgb_009800}\texttt{\Large laps}}}} +\allinethickness{1.2pt}% +\color{rgb_ff0000}% +\path(0.32,5.15625)(0.96,5.15625) +\allinethickness{0.0055348in}% +\path(0.902922,5.15435)(0.90863,5.14691) +\path(0.902922,5.16284)(0.914338,5.14795) +\path(0.907102,5.16587)(0.920046,5.14899) +\path(0.914659,5.16449)(0.925753,5.15002) +\path(0.922216,5.16312)(0.931461,5.15106) +\path(0.929773,5.16175)(0.937169,5.1521) +\path(0.93733,5.16037)(0.942877,5.15314) +\path(0.944886,5.159)(0.948584,5.15417) +\path(0.952443,5.15762)(0.954292,5.15521) +\path(0.948429,5.15415)(0.952865,5.15755) +\path(0.936859,5.15204)(0.945731,5.15884) +\path(0.925288,5.14994)(0.938596,5.16014) +\path(0.913717,5.14783)(0.931461,5.16144) +\path(0.902922,5.14633)(0.924326,5.16274) +\path(0.902922,5.15309)(0.917192,5.16403) +\path(0.902922,5.15986)(0.910057,5.16533) +\allinethickness{1.2pt}% +\path(0.902922,5.15625)(0.902922,5.14587)(0.96,5.15625) + (0.902922,5.16663)(0.902922,5.15625) +\put(0.32,5.2116){\makebox(0,0)[b]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{xp}, \texttt{flx}}}}}} +\put(0.32,5.15625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\put(0.97999,5.21481){\makebox(0,0)[b]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{eepic}}}}}} +\put(0.96,5.15625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\allinethickness{0.4pt}% +\color{rgb_7f7f7f}% +\path(0.96,5.15625)(0.963187,5.15615)(0.966347,5.15586) + (0.969482,5.15539)(0.972591,5.15472)(0.975676,5.15388) + (0.978736,5.15285)(0.981772,5.15165)(0.984785,5.15028) + (0.987774,5.14874)(0.990741,5.14703)(0.993685,5.14516) + (0.996608,5.14313)(0.999509,5.14094)(1.00239,5.1386) + (1.00525,5.13611)(1.00809,5.13347)(1.01091,5.13069) + (1.01371,5.12777)(1.01649,5.12472)(1.01926,5.12153) + (1.02201,5.11821)(1.02474,5.11476)(1.02745,5.11119)(1.03014,5.1075) + (1.03282,5.10369)(1.03549,5.09977)(1.03814,5.09574)(1.04077,5.0916) + (1.04339,5.08735)(1.046,5.08301)(1.04859,5.07856)(1.05117,5.07403) + (1.05374,5.0694)(1.0563,5.06468)(1.05884,5.05988)(1.06138,5.055) + (1.0639,5.05004)(1.06641,5.045)(1.06891,5.0399)(1.07141,5.03472) + (1.07389,5.02948)(1.07637,5.02418)(1.07884,5.01882)(1.0813,5.0134) + (1.08375,5.00793)(1.0862,5.00242)(1.08864,4.99685)(1.09107,4.99125) + (1.0935,4.98561)(1.09593,4.97993)(1.09835,4.97421)(1.10076,4.96847) + (1.10317,4.9627)(1.10558,4.95691)(1.10799,4.9511)(1.1104,4.94528) + (1.1128,4.93944)(1.1152,4.93359)(1.1176,4.92773)(1.12,4.92188) + (1.1224,4.91602)(1.1248,4.91016)(1.1272,4.90431)(1.1296,4.89847) + (1.13201,4.89265)(1.13442,4.88684)(1.13683,4.88105) + (1.13924,4.87528)(1.14165,4.86954)(1.14407,4.86382)(1.1465,4.85814) + (1.14893,4.8525)(1.15136,4.8469)(1.1538,4.84133)(1.15625,4.83582) + (1.1587,4.83035)(1.16116,4.82493)(1.16363,4.81957)(1.16611,4.81427) + (1.16859,4.80903)(1.17109,4.80385)(1.17359,4.79875)(1.1761,4.79371) + (1.17862,4.78875)(1.18116,4.78387)(1.1837,4.77907)(1.18626,4.77435) + (1.18883,4.76972)(1.19141,4.76519)(1.194,4.76074)(1.19661,4.7564) + (1.19923,4.75215)(1.20186,4.74801)(1.20451,4.74398) + (1.20718,4.74006)(1.20986,4.73625)(1.21255,4.73256) + (1.21526,4.72899)(1.21799,4.72554)(1.22074,4.72222) + (1.22351,4.71903)(1.22629,4.71598)(1.22909,4.71306) + (1.23191,4.71028)(1.23475,4.70764)(1.23761,4.70515) + (1.24049,4.70281)(1.24339,4.70063)(1.24631,4.69859) + (1.24926,4.69672)(1.25223,4.69501)(1.25522,4.69347)(1.25823,4.6921) + (1.26126,4.6909)(1.26432,4.68987)(1.26741,4.68903)(1.27052,4.68836) + (1.27365,4.68789)(1.27681,4.6876)(1.28,4.6875) +\path(1.28,4.6875)(1.6,4.6875) +\path(1.59287,4.6862)(1.59429,4.68854) +\path(1.58575,4.68491)(1.58858,4.68958) +\path(1.57862,4.68361)(1.58288,4.69061) +\path(1.5715,4.68232)(1.57717,4.69165) +\path(1.56437,4.68102)(1.57146,4.69269) +\path(1.55725,4.67973)(1.56575,4.69373) +\path(1.55012,4.67843)(1.56005,4.69476) +\path(1.543,4.67714)(1.55434,4.6958) +\path(1.54292,4.68744)(1.54863,4.69684) +\path(1.59185,4.68602)(1.58488,4.69025) +\path(1.58369,4.68453)(1.56976,4.693) +\path(1.57554,4.68305)(1.55464,4.69575) +\path(1.56738,4.68157)(1.54292,4.69643) +\path(1.55923,4.68009)(1.54292,4.68999) +\path(1.55108,4.6786)(1.54292,4.68356) +\path(1.54292,4.6875)(1.54292,4.67712)(1.6,4.6875)(1.54292,4.69788)(1.54292,4.6875) +\path(1.6,4.6875)(2.24,4.6875) +\path(2.22632,4.68501)(2.18292,4.69269) +\path(2.21185,4.68238)(2.18292,4.6875) +\path(2.19739,4.67975)(2.18292,4.68231) +\path(2.18811,4.69693)(2.18466,4.67744) +\path(2.1933,4.69599)(2.1902,4.67844) +\path(2.19849,4.69505)(2.19573,4.67945) +\path(2.20368,4.6941)(2.20126,4.68046) +\path(2.20887,4.69316)(2.2068,4.68146) +\path(2.21406,4.69222)(2.21233,4.68247) +\path(2.21924,4.69127)(2.21787,4.68348) +\path(2.22443,4.69033)(2.2234,4.68448) +\path(2.22962,4.68939)(2.22893,4.68549) +\path(2.23481,4.68844)(2.23447,4.68649) +\path(2.18292,4.6875)(2.18292,4.67712)(2.24,4.6875) + (2.18292,4.69788)(2.18292,4.6875) +\put(1.6,4.74285){\makebox(0,0)[b]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{dvi}}}}} +\put(1.6,4.6875){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\put(2.21793,4.71982){\makebox(0,0)[br]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{ps}}}}} +\put(2.24,4.6875){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\path(0.96,4.21875)(0.963187,4.21885)(0.966347,4.21914) + (0.969482,4.21961)(0.972591,4.22028)(0.975676,4.22112) + (0.978736,4.22215)(0.981772,4.22335)(0.984785,4.22472) + (0.987774,4.22626)(0.990741,4.22797)(0.993685,4.22984) + (0.996608,4.23188)(0.999509,4.23406)(1.00239,4.2364) + (1.00525,4.23889)(1.00809,4.24153)(1.01091,4.24431) + (1.01371,4.24723)(1.01649,4.25028)(1.01926,4.25347) + (1.02201,4.25679)(1.02474,4.26024)(1.02745,4.26381)(1.03014,4.2675) + (1.03282,4.27131)(1.03549,4.27523)(1.03814,4.27926)(1.04077,4.2834) + (1.04339,4.28765)(1.046,4.29199)(1.04859,4.29644)(1.05117,4.30097) + (1.05374,4.3056)(1.0563,4.31032)(1.05884,4.31512)(1.06138,4.32) + (1.0639,4.32496)(1.06641,4.33)(1.06891,4.3351)(1.07141,4.34028) + (1.07389,4.34552)(1.07637,4.35082)(1.07884,4.35618)(1.0813,4.3616) + (1.08375,4.36707)(1.0862,4.37258)(1.08864,4.37815)(1.09107,4.38375) + (1.0935,4.38939)(1.09593,4.39507)(1.09835,4.40079)(1.10076,4.40653) + (1.10317,4.4123)(1.10558,4.41809)(1.10799,4.4239)(1.1104,4.42972) + (1.1128,4.43556)(1.1152,4.44141)(1.1176,4.44727)(1.12,4.45312) + (1.1224,4.45898)(1.1248,4.46484)(1.1272,4.47069)(1.1296,4.47653) + (1.13201,4.48235)(1.13442,4.48816)(1.13683,4.49395) + (1.13924,4.49972)(1.14165,4.50546)(1.14407,4.51118)(1.1465,4.51686) + (1.14893,4.5225)(1.15136,4.5281)(1.1538,4.53367)(1.15625,4.53918) + (1.1587,4.54465)(1.16116,4.55007)(1.16363,4.55543)(1.16611,4.56073) + (1.16859,4.56597)(1.17109,4.57115)(1.17359,4.57625)(1.1761,4.58129) + (1.17862,4.58625)(1.18116,4.59113)(1.1837,4.59593)(1.18626,4.60065) + (1.18883,4.60528)(1.19141,4.60981)(1.194,4.61426)(1.19661,4.6186) + (1.19923,4.62285)(1.20186,4.62699)(1.20451,4.63102) + (1.20718,4.63494)(1.20986,4.63875)(1.21255,4.64244) + (1.21526,4.64601)(1.21799,4.64946)(1.22074,4.65278) + (1.22351,4.65597)(1.22629,4.65902)(1.22909,4.66194) + (1.23191,4.66472)(1.23475,4.66736)(1.23761,4.66985) + (1.24049,4.67219)(1.24339,4.67437)(1.24631,4.67641) + (1.24926,4.67828)(1.25223,4.67999)(1.25522,4.68153)(1.25823,4.6829) + (1.26126,4.6841)(1.26432,4.68513)(1.26741,4.68597)(1.27052,4.68664) + (1.27365,4.68711)(1.27681,4.6874)(1.28,4.6875) +\put(0.97999,4.16019){\makebox(0,0)[t]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{tex}}}}} +\put(0.96,4.21875){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\path(2.24,4.6875)(2.24533,4.67972)(2.25067,4.67201)(2.256,4.66436) + (2.26133,4.65677)(2.26667,4.64925)(2.272,4.6418)(2.27733,4.63441) + (2.28267,4.62708)(2.288,4.61982)(2.29333,4.61263)(2.29867,4.6055) + (2.304,4.59844)(2.30933,4.59144)(2.31467,4.58451)(2.32,4.57764) + (2.32533,4.57083)(2.33067,4.5641)(2.336,4.55742)(2.34133,4.55081) + (2.34667,4.54427)(2.352,4.53779)(2.35733,4.53138)(2.36267,4.52503) + (2.368,4.51875)(2.37333,4.51253)(2.37867,4.50638)(2.384,4.50029) + (2.38933,4.49427)(2.39467,4.48831)(2.4,4.48242)(2.40533,4.4766) + (2.41067,4.47083)(2.416,4.46514)(2.42133,4.45951)(2.42667,4.45394) + (2.432,4.44844)(2.43733,4.443)(2.44267,4.43763)(2.448,4.43232) + (2.45333,4.42708)(2.45867,4.42191)(2.464,4.4168)(2.46933,4.41175) + (2.47467,4.40677)(2.48,4.40186)(2.48533,4.39701)(2.49067,4.39222) + (2.496,4.3875)(2.50133,4.38285)(2.50667,4.37826)(2.512,4.37373) + (2.51733,4.36927)(2.52267,4.36488)(2.528,4.36055)(2.53333,4.35628) + (2.53867,4.35208)(2.544,4.34795)(2.54933,4.34388)(2.55467,4.33988) + (2.56,4.33594)(2.56533,4.33206)(2.57067,4.32826)(2.576,4.32451) + (2.58133,4.32083)(2.58667,4.31722)(2.592,4.31367)(2.59733,4.31019) + (2.60267,4.30677)(2.608,4.30342)(2.61333,4.30013)(2.61867,4.29691) + (2.624,4.29375)(2.62933,4.29066)(2.63467,4.28763)(2.64,4.28467) + (2.64533,4.28177)(2.65067,4.27894)(2.656,4.27617)(2.66133,4.27347) + (2.66667,4.27083)(2.672,4.26826)(2.67733,4.26576)(2.68267,4.26331) + (2.688,4.26094)(2.69333,4.25863)(2.69867,4.25638)(2.704,4.2542) + (2.70933,4.25208)(2.71467,4.25003)(2.72,4.24805)(2.72533,4.24613) + (2.73067,4.24427)(2.736,4.24248)(2.74133,4.24076)(2.74667,4.2391) + (2.752,4.2375)(2.75733,4.23597)(2.76267,4.23451)(2.768,4.23311) + (2.77333,4.23177)(2.77867,4.2305)(2.784,4.2293)(2.78933,4.22816) + (2.79467,4.22708)(2.8,4.22607)(2.80533,4.22513)(2.81067,4.22425) + (2.816,4.22344)(2.82133,4.22269)(2.82667,4.22201)(2.832,4.22139) + (2.83733,4.22083)(2.84267,4.22035)(2.848,4.21992)(2.85333,4.21956) + (2.85867,4.21927)(2.864,4.21904)(2.86933,4.21888)(2.87467,4.21878)(2.88,4.21875) +\path(2.82416,4.22925)(2.82805,4.20963) +\path(2.82975,4.2282)(2.83325,4.21054) +\path(2.83533,4.22715)(2.83844,4.21146) +\path(2.84091,4.2261)(2.84364,4.21237) +\path(2.8465,4.22505)(2.84883,4.21328) +\path(2.85208,4.224)(2.85403,4.21419) +\path(2.85767,4.22295)(2.85922,4.2151) +\path(2.86325,4.2219)(2.86442,4.21601) +\path(2.86883,4.22085)(2.86961,4.21693) +\path(2.87442,4.2198)(2.87481,4.21784) +\path(2.82289,4.21293)(2.86575,4.22143) +\path(2.82292,4.21845)(2.85149,4.22411) +\path(2.82295,4.22396)(2.83724,4.22679) +\path(2.82292,4.2191)(2.82286,4.20872)(2.88,4.21875) + (2.82299,4.22948)(2.82292,4.2191) +\put(2.93535,4.21875){\makebox(0,0)[l]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{pdf}}}}} +\put(2.88,4.21875){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\path(2.24,4.6875)(2.24533,4.69528)(2.25067,4.70299)(2.256,4.71064) + (2.26133,4.71823)(2.26667,4.72575)(2.272,4.7332)(2.27733,4.74059) + (2.28267,4.74792)(2.288,4.75518)(2.29333,4.76237)(2.29867,4.7695) + (2.304,4.77656)(2.30933,4.78356)(2.31467,4.79049)(2.32,4.79736) + (2.32533,4.80417)(2.33067,4.8109)(2.336,4.81758)(2.34133,4.82419) + (2.34667,4.83073)(2.352,4.83721)(2.35733,4.84362)(2.36267,4.84997) + (2.368,4.85625)(2.37333,4.86247)(2.37867,4.86862)(2.384,4.87471) + (2.38933,4.88073)(2.39467,4.88669)(2.4,4.89258)(2.40533,4.8984) + (2.41067,4.90417)(2.416,4.90986)(2.42133,4.91549)(2.42667,4.92106) + (2.432,4.92656)(2.43733,4.932)(2.44267,4.93737)(2.448,4.94268) + (2.45333,4.94792)(2.45867,4.95309)(2.464,4.9582)(2.46933,4.96325) + (2.47467,4.96823)(2.48,4.97314)(2.48533,4.97799)(2.49067,4.98278) + (2.496,4.9875)(2.50133,4.99215)(2.50667,4.99674)(2.512,5.00127) + (2.51733,5.00573)(2.52267,5.01012)(2.528,5.01445)(2.53333,5.01872) + (2.53867,5.02292)(2.544,5.02705)(2.54933,5.03112)(2.55467,5.03512) + (2.56,5.03906)(2.56533,5.04294)(2.57067,5.04674)(2.576,5.05049) + (2.58133,5.05417)(2.58667,5.05778)(2.592,5.06133)(2.59733,5.06481) + (2.60267,5.06823)(2.608,5.07158)(2.61333,5.07487)(2.61867,5.07809) + (2.624,5.08125)(2.62933,5.08434)(2.63467,5.08737)(2.64,5.09033) + (2.64533,5.09323)(2.65067,5.09606)(2.656,5.09883)(2.66133,5.10153) + (2.66667,5.10417)(2.672,5.10674)(2.67733,5.10924)(2.68267,5.11169) + (2.688,5.11406)(2.69333,5.11637)(2.69867,5.11862)(2.704,5.1208) + (2.70933,5.12292)(2.71467,5.12497)(2.72,5.12695)(2.72533,5.12887) + (2.73067,5.13073)(2.736,5.13252)(2.74133,5.13424)(2.74667,5.1359) + (2.752,5.1375)(2.75733,5.13903)(2.76267,5.14049)(2.768,5.14189) + (2.77333,5.14323)(2.77867,5.1445)(2.784,5.1457)(2.78933,5.14684) + (2.79467,5.14792)(2.8,5.14893)(2.80533,5.14987)(2.81067,5.15075) + (2.816,5.15156)(2.82133,5.15231)(2.82667,5.15299)(2.832,5.15361) + (2.83733,5.15417)(2.84267,5.15465)(2.848,5.15508)(2.85333,5.15544) + (2.85867,5.15573)(2.864,5.15596)(2.86933,5.15612)(2.87467,5.15622)(2.88,5.15625) +\path(2.86706,5.15382)(2.87286,5.1575) +\path(2.85412,5.15138)(2.86572,5.15876) +\path(2.84118,5.14895)(2.85857,5.16001) +\path(2.82824,5.14651)(2.85143,5.16126) +\path(2.82297,5.14896)(2.84429,5.16252) +\path(2.82293,5.15473)(2.83715,5.16377) +\path(2.8229,5.1605)(2.83,5.16503) +\path(2.8743,5.15518)(2.87281,5.15751) +\path(2.8686,5.1541)(2.86563,5.15877) +\path(2.8629,5.15303)(2.85844,5.16003) +\path(2.85719,5.15196)(2.85126,5.1613) +\path(2.85149,5.15089)(2.84407,5.16256) +\path(2.84579,5.14981)(2.83688,5.16382) +\path(2.84009,5.14874)(2.8297,5.16508) +\path(2.83439,5.14767)(2.82286,5.16579) +\path(2.82869,5.1466)(2.82292,5.15566) +\path(2.82292,5.1559)(2.82299,5.14552)(2.88,5.15625) + (2.82286,5.16628)(2.82292,5.1559) +\put(2.86001,5.21481){\makebox(0,0)[b]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{eps}}}}} +\put(2.88,5.15625){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\path(2.88,5.15625)(3.52,5.15625) +\path(3.51287,5.15495)(3.50817,5.1584) +\path(3.50573,5.15366)(3.49634,5.16055) +\path(3.4986,5.15236)(3.48451,5.1627) +\path(3.49146,5.15106)(3.47268,5.16485) +\path(3.48433,5.14976)(3.46292,5.16548) +\path(3.47719,5.14847)(3.46292,5.15895) +\path(3.47006,5.14717)(3.46292,5.15241) +\path(3.46863,5.16559)(3.46292,5.15782) +\path(3.47434,5.16455)(3.46292,5.14901) +\path(3.48005,5.16351)(3.46773,5.14675) +\path(3.48575,5.16248)(3.4752,5.1481) +\path(3.49146,5.16144)(3.48267,5.14946) +\path(3.49717,5.1604)(3.49013,5.15082) +\path(3.50288,5.15936)(3.4976,5.15218) +\path(3.50858,5.15833)(3.50507,5.15353) +\path(3.51429,5.15729)(3.51253,5.15489) +\path(3.46292,5.15625)(3.46292,5.14587)(3.52,5.15625) + (3.46292,5.16663)(3.46292,5.15625) +\put(3.57535,5.15625){\makebox(0,0)[l]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \begin{minipage}{0.225in}\texttt{png mng gif}\end{minipage}}}}} +\put(3.52,5.15625){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\put(1.92,4.21875){\makebox(0,0)[c]{\hbox{\color{rgb_009800}\texttt{\Large epix}}}} +\allinethickness{1.2pt}% +\color{rgb_ff0000}% +\path(0.32,3.28125)(0.96,3.28125) +\allinethickness{0.0055348in}% +\path(0.908111,3.29068)(0.902922,3.27138) +\path(0.9133,3.28974)(0.9085,3.27189) +\path(0.918489,3.2888)(0.914223,3.27293) +\path(0.923678,3.28785)(0.919945,3.27397) +\path(0.928867,3.28691)(0.925667,3.27501) +\path(0.934056,3.28597)(0.931389,3.27605) +\path(0.939244,3.28502)(0.937111,3.27709) +\path(0.944433,3.28408)(0.942833,3.27813) +\path(0.949622,3.28314)(0.948556,3.27917) +\path(0.954811,3.28219)(0.954278,3.28021) +\path(0.902922,3.27602)(0.914338,3.27295) +\path(0.902922,3.28116)(0.925753,3.27502) +\path(0.902922,3.28631)(0.937169,3.2771) +\path(0.902922,3.29145)(0.948584,3.27917) +\allinethickness{1.2pt}% +\path(0.902922,3.28125)(0.902922,3.27087)(0.96,3.28125) + (0.902922,3.29163)(0.902922,3.28125) +\put(0.32,3.3366){\makebox(0,0)[b]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{xp}, \texttt{flx}}}}}} +\put(0.32,3.28125){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\put(0.97999,3.33981){\makebox(0,0)[b]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{eepic}}}}}} +\put(0.96,3.28125){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\path(0.96,3.28125)(0.963187,3.28115)(0.966347,3.28086) + (0.969482,3.28039)(0.972591,3.27972)(0.975676,3.27888) + (0.978736,3.27785)(0.981772,3.27665)(0.984785,3.27528) + (0.987774,3.27374)(0.990741,3.27203)(0.993685,3.27016) + (0.996608,3.26813)(0.999509,3.26594)(1.00239,3.2636) + (1.00525,3.26111)(1.00809,3.25847)(1.01091,3.25569) + (1.01371,3.25277)(1.01649,3.24972)(1.01926,3.24653) + (1.02201,3.24321)(1.02474,3.23976)(1.02745,3.23619)(1.03014,3.2325) + (1.03282,3.22869)(1.03549,3.22477)(1.03814,3.22074)(1.04077,3.2166) + (1.04339,3.21235)(1.046,3.20801)(1.04859,3.20356)(1.05117,3.19903) + (1.05374,3.1944)(1.0563,3.18968)(1.05884,3.18488)(1.06138,3.18) + (1.0639,3.17504)(1.06641,3.17)(1.06891,3.1649)(1.07141,3.15972) + (1.07389,3.15448)(1.07637,3.14918)(1.07884,3.14382)(1.0813,3.1384) + (1.08375,3.13293)(1.0862,3.12742)(1.08864,3.12185)(1.09107,3.11625) + (1.0935,3.11061)(1.09593,3.10493)(1.09835,3.09921)(1.10076,3.09347) + (1.10317,3.0877)(1.10558,3.08191)(1.10799,3.0761)(1.1104,3.07028) + (1.1128,3.06444)(1.1152,3.05859)(1.1176,3.05273)(1.12,3.04688) + (1.1224,3.04102)(1.1248,3.03516)(1.1272,3.02931)(1.1296,3.02347) + (1.13201,3.01765)(1.13442,3.01184)(1.13683,3.00605) + (1.13924,3.00028)(1.14165,2.99454)(1.14407,2.98882)(1.1465,2.98314) + (1.14893,2.9775)(1.15136,2.9719)(1.1538,2.96633)(1.15625,2.96082) + (1.1587,2.95535)(1.16116,2.94993)(1.16363,2.94457)(1.16611,2.93927) + (1.16859,2.93403)(1.17109,2.92885)(1.17359,2.92375)(1.1761,2.91871) + (1.17862,2.91375)(1.18116,2.90887)(1.1837,2.90407)(1.18626,2.89935) + (1.18883,2.89472)(1.19141,2.89019)(1.194,2.88574)(1.19661,2.8814) + (1.19923,2.87715)(1.20186,2.87301)(1.20451,2.86898) + (1.20718,2.86506)(1.20986,2.86125)(1.21255,2.85756) + (1.21526,2.85399)(1.21799,2.85054)(1.22074,2.84722) + (1.22351,2.84403)(1.22629,2.84098)(1.22909,2.83806) + (1.23191,2.83528)(1.23475,2.83264)(1.23761,2.83015) + (1.24049,2.82781)(1.24339,2.82563)(1.24631,2.82359) + (1.24926,2.82172)(1.25223,2.82001)(1.25522,2.81847)(1.25823,2.8171) + (1.26126,2.8159)(1.26432,2.81487)(1.26741,2.81403)(1.27052,2.81336) + (1.27365,2.81289)(1.27681,2.8126)(1.28,2.8125) +\path(1.28,2.8125)(1.6,2.8125) +\allinethickness{0.0055348in}% +\path(1.54292,2.80731)(1.59652,2.81313) +\path(1.54292,2.8125)(1.57865,2.81638) +\path(1.54292,2.81769)(1.56079,2.81963) +\path(1.59481,2.81156)(1.5946,2.81348) +\path(1.58962,2.81061)(1.5892,2.81446) +\path(1.58443,2.80967)(1.58381,2.81544) +\path(1.57924,2.80873)(1.57841,2.81643) +\path(1.57406,2.80778)(1.57301,2.81741) +\path(1.56887,2.80684)(1.56761,2.81839) +\path(1.56368,2.8059)(1.56221,2.81937) +\path(1.55849,2.80495)(1.55682,2.82035) +\path(1.5533,2.80401)(1.55142,2.82133) +\path(1.54811,2.80307)(1.54602,2.82231) +\allinethickness{1.2pt}% +\path(1.54292,2.8125)(1.54292,2.80212)(1.6,2.8125)(1.54292,2.82288)(1.54292,2.8125) +\path(1.6,2.8125)(2.24,2.8125) +\allinethickness{0.0055348in}% +\path(2.23481,2.81156)(2.23373,2.81364) +\path(2.22962,2.81061)(2.22746,2.81478) +\path(2.22443,2.80967)(2.22119,2.81592) +\path(2.21924,2.80873)(2.21492,2.81706) +\path(2.21406,2.80778)(2.20864,2.8182) +\path(2.20887,2.80684)(2.20237,2.81934) +\path(2.20368,2.8059)(2.1961,2.82048) +\path(2.19849,2.80495)(2.18983,2.82162) +\path(2.1933,2.80401)(2.18356,2.82276) +\path(2.18811,2.80307)(2.18292,2.81306) +\path(2.19108,2.8214)(2.18292,2.81716) +\path(2.19923,2.81991)(2.18292,2.81144) +\path(2.20738,2.81843)(2.18292,2.80573) +\path(2.21554,2.81695)(2.18919,2.80326) +\path(2.22369,2.81547)(2.20612,2.80634) +\path(2.23185,2.81398)(2.22306,2.80942) +\allinethickness{1.2pt}% +\path(2.18292,2.8125)(2.18292,2.80212)(2.24,2.8125) + (2.18292,2.82288)(2.18292,2.8125) +\put(1.6,2.86785){\makebox(0,0)[b]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{dvi}}}}}} +\put(1.6,2.8125){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\put(2.21793,2.84482){\makebox(0,0)[br]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{ps}}}}}} +\put(2.24,2.8125){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\allinethickness{0.4pt}% +\color{rgb_7f7f7f}% +\path(0.96,2.34375)(0.963187,2.34385)(0.966347,2.34414) + (0.969482,2.34461)(0.972591,2.34528)(0.975676,2.34612) + (0.978736,2.34715)(0.981772,2.34835)(0.984785,2.34972) + (0.987774,2.35126)(0.990741,2.35297)(0.993685,2.35484) + (0.996608,2.35688)(0.999509,2.35906)(1.00239,2.3614) + (1.00525,2.36389)(1.00809,2.36653)(1.01091,2.36931) + (1.01371,2.37223)(1.01649,2.37528)(1.01926,2.37847) + (1.02201,2.38179)(1.02474,2.38524)(1.02745,2.38881)(1.03014,2.3925) + (1.03282,2.39631)(1.03549,2.40023)(1.03814,2.40426)(1.04077,2.4084) + (1.04339,2.41265)(1.046,2.41699)(1.04859,2.42144)(1.05117,2.42597) + (1.05374,2.4306)(1.0563,2.43532)(1.05884,2.44012)(1.06138,2.445) + (1.0639,2.44996)(1.06641,2.455)(1.06891,2.4601)(1.07141,2.46528) + (1.07389,2.47052)(1.07637,2.47582)(1.07884,2.48118)(1.0813,2.4866) + (1.08375,2.49207)(1.0862,2.49758)(1.08864,2.50315)(1.09107,2.50875) + (1.0935,2.51439)(1.09593,2.52007)(1.09835,2.52579)(1.10076,2.53153) + (1.10317,2.5373)(1.10558,2.54309)(1.10799,2.5489)(1.1104,2.55472) + (1.1128,2.56056)(1.1152,2.56641)(1.1176,2.57227)(1.12,2.57812) + (1.1224,2.58398)(1.1248,2.58984)(1.1272,2.59569)(1.1296,2.60153) + (1.13201,2.60735)(1.13442,2.61316)(1.13683,2.61895) + (1.13924,2.62472)(1.14165,2.63046)(1.14407,2.63618)(1.1465,2.64186) + (1.14893,2.6475)(1.15136,2.6531)(1.1538,2.65867)(1.15625,2.66418) + (1.1587,2.66965)(1.16116,2.67507)(1.16363,2.68043)(1.16611,2.68573) + (1.16859,2.69097)(1.17109,2.69615)(1.17359,2.70125)(1.1761,2.70629) + (1.17862,2.71125)(1.18116,2.71613)(1.1837,2.72093)(1.18626,2.72565) + (1.18883,2.73028)(1.19141,2.73481)(1.194,2.73926)(1.19661,2.7436) + (1.19923,2.74785)(1.20186,2.75199)(1.20451,2.75602) + (1.20718,2.75994)(1.20986,2.76375)(1.21255,2.76744) + (1.21526,2.77101)(1.21799,2.77446)(1.22074,2.77778) + (1.22351,2.78097)(1.22629,2.78402)(1.22909,2.78694) + (1.23191,2.78972)(1.23475,2.79236)(1.23761,2.79485) + (1.24049,2.79719)(1.24339,2.79937)(1.24631,2.80141) + (1.24926,2.80328)(1.25223,2.80499)(1.25522,2.80653)(1.25823,2.8079) + (1.26126,2.8091)(1.26432,2.81013)(1.26741,2.81097)(1.27052,2.81164) + (1.27365,2.81211)(1.27681,2.8124)(1.28,2.8125) +\put(0.97999,2.28519){\makebox(0,0)[t]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{tex}}}}} +\put(0.96,2.34375){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\allinethickness{1.2pt}% +\color{rgb_ff0000}% +\path(2.24,2.8125)(2.24533,2.80472)(2.25067,2.79701)(2.256,2.78936) + (2.26133,2.78177)(2.26667,2.77425)(2.272,2.7668)(2.27733,2.75941) + (2.28267,2.75208)(2.288,2.74482)(2.29333,2.73763)(2.29867,2.7305) + (2.304,2.72344)(2.30933,2.71644)(2.31467,2.70951)(2.32,2.70264) + (2.32533,2.69583)(2.33067,2.6891)(2.336,2.68242)(2.34133,2.67581) + (2.34667,2.66927)(2.352,2.66279)(2.35733,2.65638)(2.36267,2.65003) + (2.368,2.64375)(2.37333,2.63753)(2.37867,2.63138)(2.384,2.62529) + (2.38933,2.61927)(2.39467,2.61331)(2.4,2.60742)(2.40533,2.6016) + (2.41067,2.59583)(2.416,2.59014)(2.42133,2.58451)(2.42667,2.57894) + (2.432,2.57344)(2.43733,2.568)(2.44267,2.56263)(2.448,2.55732) + (2.45333,2.55208)(2.45867,2.54691)(2.464,2.5418)(2.46933,2.53675) + (2.47467,2.53177)(2.48,2.52686)(2.48533,2.52201)(2.49067,2.51722) + (2.496,2.5125)(2.50133,2.50785)(2.50667,2.50326)(2.512,2.49873) + (2.51733,2.49427)(2.52267,2.48988)(2.528,2.48555)(2.53333,2.48128) + (2.53867,2.47708)(2.544,2.47295)(2.54933,2.46888)(2.55467,2.46488) + (2.56,2.46094)(2.56533,2.45706)(2.57067,2.45326)(2.576,2.44951) + (2.58133,2.44583)(2.58667,2.44222)(2.592,2.43867)(2.59733,2.43519) + (2.60267,2.43177)(2.608,2.42842)(2.61333,2.42513)(2.61867,2.42191) + (2.624,2.41875)(2.62933,2.41566)(2.63467,2.41263)(2.64,2.40967) + (2.64533,2.40677)(2.65067,2.40394)(2.656,2.40117)(2.66133,2.39847) + (2.66667,2.39583)(2.672,2.39326)(2.67733,2.39076)(2.68267,2.38831) + (2.688,2.38594)(2.69333,2.38363)(2.69867,2.38138)(2.704,2.3792) + (2.70933,2.37708)(2.71467,2.37503)(2.72,2.37305)(2.72533,2.37113) + (2.73067,2.36927)(2.736,2.36748)(2.74133,2.36576)(2.74667,2.3641) + (2.752,2.3625)(2.75733,2.36097)(2.76267,2.35951)(2.768,2.35811) + (2.77333,2.35677)(2.77867,2.3555)(2.784,2.3543)(2.78933,2.35316) + (2.79467,2.35208)(2.8,2.35107)(2.80533,2.35013)(2.81067,2.34925) + (2.816,2.34844)(2.82133,2.34769)(2.82667,2.34701)(2.832,2.34639) + (2.83733,2.34583)(2.84267,2.34535)(2.848,2.34492)(2.85333,2.34456) + (2.85867,2.34427)(2.864,2.34404)(2.86933,2.34388)(2.87467,2.34378)(2.88,2.34375) +\allinethickness{0.0055348in}% +\path(2.82869,2.3534)(2.82294,2.34686) +\path(2.83439,2.35233)(2.82289,2.33925) +\path(2.84009,2.35126)(2.82501,2.3341) +\path(2.84579,2.35019)(2.83287,2.33548) +\path(2.85149,2.34911)(2.84072,2.33686) +\path(2.85719,2.34804)(2.84858,2.33823) +\path(2.8629,2.34697)(2.85643,2.33961) +\path(2.8686,2.3459)(2.86429,2.34099) +\path(2.8743,2.34482)(2.87214,2.34237) +\path(2.8229,2.34038)(2.82921,2.33484) +\path(2.82294,2.34704)(2.83556,2.33595) +\path(2.82298,2.35369)(2.84191,2.33706) +\path(2.83154,2.35287)(2.84826,2.33818) +\path(2.84123,2.35104)(2.8546,2.33929) +\path(2.85092,2.34922)(2.86095,2.34041) +\path(2.86062,2.3474)(2.8673,2.34152) +\path(2.87031,2.34557)(2.87365,2.34264) +\allinethickness{1.2pt}% +\path(2.82292,2.3441)(2.82286,2.33372)(2.88,2.34375) + (2.82299,2.35448)(2.82292,2.3441) +\put(2.93535,2.34375){\makebox(0,0)[l]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{pdf}}}}}} +\put(2.88,2.34375){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\path(2.24,2.8125)(2.24533,2.82028)(2.25067,2.82799)(2.256,2.83564) + (2.26133,2.84323)(2.26667,2.85075)(2.272,2.8582)(2.27733,2.86559) + (2.28267,2.87292)(2.288,2.88018)(2.29333,2.88737)(2.29867,2.8945) + (2.304,2.90156)(2.30933,2.90856)(2.31467,2.91549)(2.32,2.92236) + (2.32533,2.92917)(2.33067,2.9359)(2.336,2.94258)(2.34133,2.94919) + (2.34667,2.95573)(2.352,2.96221)(2.35733,2.96862)(2.36267,2.97497) + (2.368,2.98125)(2.37333,2.98747)(2.37867,2.99362)(2.384,2.99971) + (2.38933,3.00573)(2.39467,3.01169)(2.4,3.01758)(2.40533,3.0234) + (2.41067,3.02917)(2.416,3.03486)(2.42133,3.04049)(2.42667,3.04606) + (2.432,3.05156)(2.43733,3.057)(2.44267,3.06237)(2.448,3.06768) + (2.45333,3.07292)(2.45867,3.07809)(2.464,3.0832)(2.46933,3.08825) + (2.47467,3.09323)(2.48,3.09814)(2.48533,3.10299)(2.49067,3.10778) + (2.496,3.1125)(2.50133,3.11715)(2.50667,3.12174)(2.512,3.12627) + (2.51733,3.13073)(2.52267,3.13512)(2.528,3.13945)(2.53333,3.14372) + (2.53867,3.14792)(2.544,3.15205)(2.54933,3.15612)(2.55467,3.16012) + (2.56,3.16406)(2.56533,3.16794)(2.57067,3.17174)(2.576,3.17549) + (2.58133,3.17917)(2.58667,3.18278)(2.592,3.18633)(2.59733,3.18981) + (2.60267,3.19323)(2.608,3.19658)(2.61333,3.19987)(2.61867,3.20309) + (2.624,3.20625)(2.62933,3.20934)(2.63467,3.21237)(2.64,3.21533) + (2.64533,3.21823)(2.65067,3.22106)(2.656,3.22383)(2.66133,3.22653) + (2.66667,3.22917)(2.672,3.23174)(2.67733,3.23424)(2.68267,3.23669) + (2.688,3.23906)(2.69333,3.24137)(2.69867,3.24362)(2.704,3.2458) + (2.70933,3.24792)(2.71467,3.24997)(2.72,3.25195)(2.72533,3.25387) + (2.73067,3.25573)(2.736,3.25752)(2.74133,3.25924)(2.74667,3.2609) + (2.752,3.2625)(2.75733,3.26403)(2.76267,3.26549)(2.768,3.26689) + (2.77333,3.26823)(2.77867,3.2695)(2.784,3.2707)(2.78933,3.27184) + (2.79467,3.27292)(2.8,3.27393)(2.80533,3.27487)(2.81067,3.27575) + (2.816,3.27656)(2.82133,3.27731)(2.82667,3.27799)(2.832,3.27861) + (2.83733,3.27917)(2.84267,3.27965)(2.848,3.28008)(2.85333,3.28044) + (2.85867,3.28073)(2.864,3.28096)(2.86933,3.28112)(2.87467,3.28122)(2.88,3.28125) +\allinethickness{0.0055348in}% +\path(2.82295,3.27579)(2.83249,3.27231) +\path(2.82292,3.28106)(2.84199,3.2741) +\path(2.82289,3.28633)(2.85149,3.27589) +\path(2.82456,3.29098)(2.861,3.27767) +\path(2.85228,3.28612)(2.8705,3.27946) +\path(2.87406,3.28013)(2.87481,3.28216) +\path(2.86813,3.27902)(2.86961,3.28307) +\path(2.86219,3.2779)(2.86442,3.28399) +\path(2.85626,3.27678)(2.85922,3.2849) +\path(2.85032,3.27567)(2.85403,3.28581) +\path(2.84439,3.27455)(2.84883,3.28672) +\path(2.83845,3.27343)(2.84364,3.28763) +\path(2.83252,3.27232)(2.83844,3.28854) +\path(2.82658,3.2712)(2.83325,3.28946) +\path(2.82295,3.27639)(2.82805,3.29037) +\allinethickness{1.2pt}% +\path(2.82292,3.2809)(2.82299,3.27052)(2.88,3.28125) + (2.82286,3.29128)(2.82292,3.2809) +\put(2.86001,3.33981){\makebox(0,0)[b]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{eps}}}}}} +\put(2.88,3.28125){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\allinethickness{0.4pt}% +\color{rgb_7f7f7f}% +\path(2.88,3.28125)(3.52,3.28125) +\path(3.51481,3.28031)(3.51477,3.2822) +\path(3.50962,3.27936)(3.50954,3.28315) +\path(3.50443,3.27842)(3.50432,3.2841) +\path(3.49924,3.27748)(3.49909,3.28505) +\path(3.49406,3.27653)(3.49386,3.286) +\path(3.48887,3.27559)(3.48863,3.28695) +\path(3.48368,3.27465)(3.4834,3.2879) +\path(3.47849,3.2737)(3.47818,3.28885) +\path(3.4733,3.27276)(3.47295,3.2898) +\path(3.46811,3.27182)(3.46772,3.29076) +\path(3.48855,3.28697)(3.46292,3.28644) +\path(3.51417,3.28231)(3.46292,3.28125) +\path(3.49512,3.27673)(3.46292,3.27606) +\path(3.46292,3.28125)(3.46292,3.27087)(3.52,3.28125) + (3.46292,3.29163)(3.46292,3.28125) +\put(3.57535,3.28125){\makebox(0,0)[l]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \begin{minipage}{0.225in}\texttt{png mng gif}\end{minipage}}}}} +\put(3.52,3.28125){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\put(1.92,2.34375){\makebox(0,0)[c]{\hbox{\color{rgb_009800}\texttt{\Large elaps}}}} +\allinethickness{1.2pt}% +\color{rgb_ff0000}% +\path(0.32,1.40625)(0.96,1.40625) +\allinethickness{0.0055348in}% +\path(0.912435,1.4149)(0.902922,1.41097) +\path(0.921948,1.41317)(0.902922,1.40531) +\path(0.931461,1.41144)(0.902922,1.39966) +\path(0.940974,1.40971)(0.91102,1.39734) +\path(0.950487,1.40798)(0.93551,1.4018) +\path(0.902922,1.40939)(0.908111,1.39682) +\path(0.905721,1.41612)(0.9133,1.39776) +\path(0.911752,1.41502)(0.918489,1.3987) +\path(0.917783,1.41393)(0.923678,1.39965) +\path(0.923814,1.41283)(0.928867,1.40059) +\path(0.929845,1.41173)(0.934056,1.40153) +\path(0.935876,1.41064)(0.939244,1.40248) +\path(0.941907,1.40954)(0.944433,1.40342) +\path(0.947938,1.40844)(0.949622,1.40436) +\path(0.953969,1.40735)(0.954811,1.40531) +\allinethickness{1.2pt}% +\path(0.902922,1.40625)(0.902922,1.39587)(0.96,1.40625) + (0.902922,1.41663)(0.902922,1.40625) +\put(0.32,1.4616){\makebox(0,0)[b]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{xp}, \texttt{flx}}}}}} +\put(0.32,1.40625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\put(0.97999,1.46481){\makebox(0,0)[b]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{eepic}}}}}} +\put(0.96,1.40625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\path(0.96,1.40625)(0.963187,1.40615)(0.966347,1.40586) + (0.969482,1.40539)(0.972591,1.40472)(0.975676,1.40388) + (0.978736,1.40285)(0.981772,1.40165)(0.984785,1.40028) + (0.987774,1.39874)(0.990741,1.39703)(0.993685,1.39516) + (0.996608,1.39313)(0.999509,1.39094)(1.00239,1.3886) + (1.00525,1.38611)(1.00809,1.38347)(1.01091,1.38069) + (1.01371,1.37777)(1.01649,1.37472)(1.01926,1.37153) + (1.02201,1.36821)(1.02474,1.36476)(1.02745,1.36119)(1.03014,1.3575) + (1.03282,1.35369)(1.03549,1.34977)(1.03814,1.34574)(1.04077,1.3416) + (1.04339,1.33735)(1.046,1.33301)(1.04859,1.32856)(1.05117,1.32403) + (1.05374,1.3194)(1.0563,1.31468)(1.05884,1.30988)(1.06138,1.305) + (1.0639,1.30004)(1.06641,1.295)(1.06891,1.2899)(1.07141,1.28472) + (1.07389,1.27948)(1.07637,1.27418)(1.07884,1.26882)(1.0813,1.2634) + (1.08375,1.25793)(1.0862,1.25242)(1.08864,1.24685)(1.09107,1.24125) + (1.0935,1.23561)(1.09593,1.22993)(1.09835,1.22421)(1.10076,1.21847) + (1.10317,1.2127)(1.10558,1.20691)(1.10799,1.2011)(1.1104,1.19528) + (1.1128,1.18944)(1.1152,1.18359)(1.1176,1.17773)(1.12,1.17188) + (1.1224,1.16602)(1.1248,1.16016)(1.1272,1.15431)(1.1296,1.14847) + (1.13201,1.14265)(1.13442,1.13684)(1.13683,1.13105) + (1.13924,1.12528)(1.14165,1.11954)(1.14407,1.11382)(1.1465,1.10814) + (1.14893,1.1025)(1.15136,1.0969)(1.1538,1.09133)(1.15625,1.08582) + (1.1587,1.08035)(1.16116,1.07493)(1.16363,1.06957)(1.16611,1.06427) + (1.16859,1.05903)(1.17109,1.05385)(1.17359,1.04875)(1.1761,1.04371) + (1.17862,1.03875)(1.18116,1.03387)(1.1837,1.02907)(1.18626,1.02435) + (1.18883,1.01972)(1.19141,1.01519)(1.194,1.01074)(1.19661,1.0064) + (1.19923,1.00215)(1.20186,0.998013)(1.20451,0.99398) + (1.20718,0.990058)(1.20986,0.98625)(1.21255,0.982559) + (1.21526,0.978989)(1.21799,0.975542)(1.22074,0.972222) + (1.22351,0.969033)(1.22629,0.965977)(1.22909,0.963057) + (1.23191,0.960278)(1.23475,0.957642)(1.23761,0.955152) + (1.24049,0.952812)(1.24339,0.950625)(1.24631,0.948594) + (1.24926,0.946723)(1.25223,0.945015)(1.25522,0.943472) + (1.25823,0.942099)(1.26126,0.940898)(1.26432,0.939874) + (1.26741,0.939028)(1.27052,0.938364)(1.27365,0.937886) + (1.27681,0.937597)(1.28,0.9375) +\path(1.28,0.9375)(1.6,0.9375) +\allinethickness{0.0055348in}% +\path(1.54292,0.934917)(1.54926,0.928275) +\path(1.54292,0.942712)(1.55561,0.929428) +\path(1.54596,0.947325)(1.56195,0.930581) +\path(1.55497,0.945688)(1.56829,0.931735) +\path(1.56397,0.94405)(1.57463,0.932888) +\path(1.57298,0.942413)(1.58097,0.934041) +\path(1.58199,0.940775)(1.58732,0.935194) +\path(1.59099,0.939138)(1.59366,0.936347) +\path(1.59067,0.935804)(1.59366,0.938653) +\path(1.58135,0.934109)(1.58732,0.939806) +\path(1.57202,0.932413)(1.58097,0.940959) +\path(1.5627,0.930718)(1.57463,0.942112) +\path(1.55337,0.929022)(1.56829,0.943265) +\path(1.54405,0.927327)(1.56195,0.944419) +\path(1.54292,0.933461)(1.55561,0.945572) +\path(1.54292,0.940669)(1.54926,0.946725) +\allinethickness{1.2pt}% +\path(1.54292,0.9375)(1.54292,0.927122)(1.6,0.9375) + (1.54292,0.947878)(1.54292,0.9375) +\path(1.6,0.9375)(2.24,0.9375) +\allinethickness{0.0055348in}% +\path(2.23385,0.936381)(2.23481,0.938443) +\path(2.22769,0.935262)(2.22962,0.939387) +\path(2.22154,0.934143)(2.22443,0.94033) +\path(2.21538,0.933024)(2.21924,0.941274) +\path(2.20923,0.931905)(2.21406,0.942217) +\path(2.20308,0.930787)(2.20887,0.943161) +\path(2.19692,0.929668)(2.20368,0.944104) +\path(2.19077,0.928549)(2.19849,0.945047) +\path(2.18461,0.92743)(2.1933,0.945991) +\path(2.18292,0.935846)(2.18811,0.946934) +\path(2.23185,0.936017)(2.22148,0.940867) +\path(2.22369,0.934535)(2.20297,0.944233) +\path(2.21554,0.933052)(2.18445,0.9476) +\path(2.20738,0.93157)(2.18292,0.943017) +\path(2.19923,0.930087)(2.18292,0.937719) +\path(2.19108,0.928605)(2.18292,0.93242) +\allinethickness{1.2pt}% +\path(2.18292,0.9375)(2.18292,0.927122)(2.24,0.9375) + (2.18292,0.947878)(2.18292,0.9375) +\put(1.6,0.992848){\makebox(0,0)[b]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{dvi}}}}}} +\put(1.6,0.9375){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\put(2.21793,0.969823){\makebox(0,0)[br]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{ps}}}}}} +\put(2.24,0.9375){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\allinethickness{0.4pt}% +\color{rgb_7f7f7f}% +\path(0.96,0.46875)(0.963187,0.468847)(0.966347,0.469136) + (0.969482,0.469614)(0.972591,0.470278)(0.975676,0.471124) + (0.978736,0.472148)(0.981772,0.473349)(0.984785,0.474722) + (0.987774,0.476265)(0.990741,0.477973)(0.993685,0.479844) + (0.996608,0.481875)(0.999509,0.484062)(1.00239,0.486402) + (1.00525,0.488892)(1.00809,0.491528)(1.01091,0.494307) + (1.01371,0.497227)(1.01649,0.500283)(1.01926,0.503472) + (1.02201,0.506792)(1.02474,0.510239)(1.02745,0.513809) + (1.03014,0.5175)(1.03282,0.521308)(1.03549,0.52523) + (1.03814,0.529263)(1.04077,0.533403)(1.04339,0.537647) + (1.046,0.541992)(1.04859,0.546435)(1.05117,0.550972) + (1.05374,0.555601)(1.0563,0.560317)(1.05884,0.565118)(1.06138,0.57) + (1.0639,0.57496)(1.06641,0.579996)(1.06891,0.585103) + (1.07141,0.590278)(1.07389,0.595518)(1.07637,0.60082) + (1.07884,0.606181)(1.0813,0.611597)(1.08375,0.617065) + (1.0862,0.622582)(1.08864,0.628145)(1.09107,0.63375) + (1.0935,0.639394)(1.09593,0.645074)(1.09835,0.650786) + (1.10076,0.656528)(1.10317,0.662295)(1.10558,0.668086) + (1.10799,0.673896)(1.1104,0.679722)(1.1128,0.685562) + (1.1152,0.691411)(1.1176,0.697266)(1.12,0.703125)(1.1224,0.708984) + (1.1248,0.714839)(1.1272,0.720688)(1.1296,0.726528) + (1.13201,0.732354)(1.13442,0.738164)(1.13683,0.743955) + (1.13924,0.749722)(1.14165,0.755464)(1.14407,0.761176) + (1.1465,0.766856)(1.14893,0.7725)(1.15136,0.778105) + (1.1538,0.783668)(1.15625,0.789185)(1.1587,0.794653) + (1.16116,0.800069)(1.16363,0.80543)(1.16611,0.810732) + (1.16859,0.815972)(1.17109,0.821147)(1.17359,0.826254) + (1.1761,0.83129)(1.17862,0.83625)(1.18116,0.841132) + (1.1837,0.845933)(1.18626,0.850649)(1.18883,0.855278) + (1.19141,0.859815)(1.194,0.864258)(1.19661,0.868603) + (1.19923,0.872847)(1.20186,0.876987)(1.20451,0.88102) + (1.20718,0.884942)(1.20986,0.88875)(1.21255,0.892441) + (1.21526,0.896011)(1.21799,0.899458)(1.22074,0.902778) + (1.22351,0.905967)(1.22629,0.909023)(1.22909,0.911943) + (1.23191,0.914722)(1.23475,0.917358)(1.23761,0.919848) + (1.24049,0.922188)(1.24339,0.924375)(1.24631,0.926406) + (1.24926,0.928277)(1.25223,0.929985)(1.25522,0.931528) + (1.25823,0.932901)(1.26126,0.934102)(1.26432,0.935126) + (1.26741,0.935972)(1.27052,0.936636)(1.27365,0.937114) + (1.27681,0.937403)(1.28,0.9375) +\put(0.97999,0.410187){\makebox(0,0)[t]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{tex}}}}} +\put(0.96,0.46875){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\path(2.24,0.9375)(2.24533,0.92972)(2.25067,0.922005) + (2.256,0.914355)(2.26133,0.906771)(2.26667,0.899251) + (2.272,0.891797)(2.27733,0.884408)(2.28267,0.877083) + (2.288,0.869824)(2.29333,0.86263)(2.29867,0.855501)(2.304,0.848438) + (2.30933,0.841439)(2.31467,0.834505)(2.32,0.827637) + (2.32533,0.820833)(2.33067,0.814095)(2.336,0.807422) + (2.34133,0.800814)(2.34667,0.794271)(2.352,0.787793) + (2.35733,0.78138)(2.36267,0.775033)(2.368,0.76875) + (2.37333,0.762533)(2.37867,0.75638)(2.384,0.750293) + (2.38933,0.744271)(2.39467,0.738314)(2.4,0.732422) + (2.40533,0.726595)(2.41067,0.720833)(2.416,0.715137) + (2.42133,0.709505)(2.42667,0.703939)(2.432,0.698438) + (2.43733,0.693001)(2.44267,0.68763)(2.448,0.682324) + (2.45333,0.677083)(2.45867,0.671908)(2.464,0.666797) + (2.46933,0.661751)(2.47467,0.656771)(2.48,0.651855) + (2.48533,0.647005)(2.49067,0.64222)(2.496,0.6375)(2.50133,0.632845) + (2.50667,0.628255)(2.512,0.62373)(2.51733,0.619271) + (2.52267,0.614876)(2.528,0.610547)(2.53333,0.606283) + (2.53867,0.602083)(2.544,0.597949)(2.54933,0.59388) + (2.55467,0.589876)(2.56,0.585938)(2.56533,0.582064) + (2.57067,0.578255)(2.576,0.574512)(2.58133,0.570833) + (2.58667,0.56722)(2.592,0.563672)(2.59733,0.560189) + (2.60267,0.556771)(2.608,0.553418)(2.61333,0.55013) + (2.61867,0.546908)(2.624,0.54375)(2.62933,0.540658) + (2.63467,0.53763)(2.64,0.534668)(2.64533,0.531771) + (2.65067,0.528939)(2.656,0.526172)(2.66133,0.52347) + (2.66667,0.520833)(2.672,0.518262)(2.67733,0.515755) + (2.68267,0.513314)(2.688,0.510937)(2.69333,0.508626) + (2.69867,0.50638)(2.704,0.504199)(2.70933,0.502083) + (2.71467,0.500033)(2.72,0.498047)(2.72533,0.496126) + (2.73067,0.494271)(2.736,0.49248)(2.74133,0.490755) + (2.74667,0.489095)(2.752,0.4875)(2.75733,0.48597)(2.76267,0.484505) + (2.768,0.483105)(2.77333,0.481771)(2.77867,0.480501) + (2.784,0.479297)(2.78933,0.478158)(2.79467,0.477083)(2.8,0.476074) + (2.80533,0.47513)(2.81067,0.474251)(2.816,0.473437) + (2.82133,0.472689)(2.82667,0.472005)(2.832,0.471387) + (2.83733,0.470833)(2.84267,0.470345)(2.848,0.469922) + (2.85333,0.469564)(2.85867,0.469271)(2.864,0.469043) + (2.86933,0.46888)(2.87467,0.468783)(2.88,0.46875) +\path(2.86583,0.471416)(2.82296,0.474287) +\path(2.86567,0.466235)(2.82292,0.469098) +\path(2.84427,0.462478)(2.82289,0.46391) +\path(2.82817,0.478501)(2.82689,0.459429) +\path(2.83335,0.477526)(2.8322,0.460361) +\path(2.83854,0.476551)(2.83751,0.461293) +\path(2.84372,0.475576)(2.84282,0.462225) +\path(2.8489,0.474601)(2.84814,0.463157) +\path(2.85408,0.473625)(2.85345,0.464089) +\path(2.85927,0.47265)(2.85876,0.465021) +\path(2.86445,0.471675)(2.86407,0.465954) +\path(2.86963,0.4707)(2.86938,0.466886) +\path(2.87482,0.469725)(2.87469,0.467818) +\path(2.82292,0.469098)(2.82286,0.458721)(2.88,0.46875) + (2.82299,0.479476)(2.82292,0.469098) +\put(2.93535,0.46875){\makebox(0,0)[l]{\hbox{\color{rgb_7f7f7f}\texttt{\footnotesize \texttt{pdf}}}}} +\put(2.88,0.46875){\color{rgb_7f7f7f}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\allinethickness{1.2pt}% +\color{rgb_ff0000}% +\path(2.24,0.9375)(2.24533,0.94528)(2.25067,0.952995) + (2.256,0.960645)(2.26133,0.968229)(2.26667,0.975749) + (2.272,0.983203)(2.27733,0.990592)(2.28267,0.997917)(2.288,1.00518) + (2.29333,1.01237)(2.29867,1.0195)(2.304,1.02656)(2.30933,1.03356) + (2.31467,1.04049)(2.32,1.04736)(2.32533,1.05417)(2.33067,1.0609) + (2.336,1.06758)(2.34133,1.07419)(2.34667,1.08073)(2.352,1.08721) + (2.35733,1.09362)(2.36267,1.09997)(2.368,1.10625)(2.37333,1.11247) + (2.37867,1.11862)(2.384,1.12471)(2.38933,1.13073)(2.39467,1.13669) + (2.4,1.14258)(2.40533,1.1484)(2.41067,1.15417)(2.416,1.15986) + (2.42133,1.16549)(2.42667,1.17106)(2.432,1.17656)(2.43733,1.182) + (2.44267,1.18737)(2.448,1.19268)(2.45333,1.19792)(2.45867,1.20309) + (2.464,1.2082)(2.46933,1.21325)(2.47467,1.21823)(2.48,1.22314) + (2.48533,1.22799)(2.49067,1.23278)(2.496,1.2375)(2.50133,1.24215) + (2.50667,1.24674)(2.512,1.25127)(2.51733,1.25573)(2.52267,1.26012) + (2.528,1.26445)(2.53333,1.26872)(2.53867,1.27292)(2.544,1.27705) + (2.54933,1.28112)(2.55467,1.28512)(2.56,1.28906)(2.56533,1.29294) + (2.57067,1.29674)(2.576,1.30049)(2.58133,1.30417)(2.58667,1.30778) + (2.592,1.31133)(2.59733,1.31481)(2.60267,1.31823)(2.608,1.32158) + (2.61333,1.32487)(2.61867,1.32809)(2.624,1.33125)(2.62933,1.33434) + (2.63467,1.33737)(2.64,1.34033)(2.64533,1.34323)(2.65067,1.34606) + (2.656,1.34883)(2.66133,1.35153)(2.66667,1.35417)(2.672,1.35674) + (2.67733,1.35924)(2.68267,1.36169)(2.688,1.36406)(2.69333,1.36637) + (2.69867,1.36862)(2.704,1.3708)(2.70933,1.37292)(2.71467,1.37497) + (2.72,1.37695)(2.72533,1.37887)(2.73067,1.38073)(2.736,1.38252) + (2.74133,1.38424)(2.74667,1.3859)(2.752,1.3875)(2.75733,1.38903) + (2.76267,1.39049)(2.768,1.39189)(2.77333,1.39323)(2.77867,1.3945) + (2.784,1.3957)(2.78933,1.39684)(2.79467,1.39792)(2.8,1.39893) + (2.80533,1.39987)(2.81067,1.40075)(2.816,1.40156)(2.82133,1.40231) + (2.82667,1.40299)(2.832,1.40361)(2.83733,1.40417)(2.84267,1.40465) + (2.848,1.40508)(2.85333,1.40544)(2.85867,1.40573)(2.864,1.40596) + (2.86933,1.40612)(2.87467,1.40622)(2.88,1.40625) +\allinethickness{0.0055348in}% +\path(2.82288,1.41337)(2.82817,1.3965) +\path(2.82772,1.41543)(2.83335,1.39747) +\path(2.83353,1.41441)(2.83854,1.39845) +\path(2.83934,1.41339)(2.84372,1.39942) +\path(2.84515,1.41237)(2.8489,1.4004) +\path(2.85096,1.41135)(2.85408,1.40137) +\path(2.85677,1.41033)(2.85927,1.40235) +\path(2.86257,1.40931)(2.86445,1.40332) +\path(2.86838,1.40829)(2.86963,1.4043) +\path(2.87419,1.40727)(2.87482,1.40527) +\path(2.83547,1.39787)(2.86857,1.40826) +\path(2.82296,1.39954)(2.85714,1.41026) +\path(2.82293,1.40512)(2.84572,1.41227) +\path(2.82289,1.4107)(2.83429,1.41427) +\allinethickness{1.2pt}% +\path(2.82292,1.4059)(2.82299,1.39552)(2.88,1.40625) + (2.82286,1.41628)(2.82292,1.4059) +\put(2.86001,1.46481){\makebox(0,0)[b]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \texttt{eps}}}}}} +\put(2.88,1.40625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\path(2.88,1.40625)(3.52,1.40625) +\allinethickness{0.0055348in}% +\path(3.50867,1.40419)(3.51287,1.40755) +\path(3.49734,1.40213)(3.50573,1.40884) +\path(3.48601,1.40007)(3.4986,1.41014) +\path(3.47467,1.39801)(3.49146,1.41144) +\path(3.46334,1.39595)(3.48433,1.41274) +\path(3.46292,1.40262)(3.47719,1.41403) +\path(3.46292,1.40962)(3.47006,1.41533) +\path(3.51429,1.40521)(3.51235,1.40764) +\path(3.50858,1.40417)(3.5047,1.40903) +\path(3.50288,1.40314)(3.49705,1.41042) +\path(3.49717,1.4021)(3.4894,1.41181) +\path(3.49146,1.40106)(3.48175,1.41321) +\path(3.48575,1.40002)(3.47409,1.4146) +\path(3.48005,1.39899)(3.46644,1.41599) +\path(3.47434,1.39795)(3.46292,1.41222) +\path(3.46863,1.39691)(3.46292,1.40404) +\allinethickness{1.2pt}% +\path(3.46292,1.40625)(3.46292,1.39587)(3.52,1.40625) + (3.46292,1.41663)(3.46292,1.40625) +\put(3.57535,1.40625){\makebox(0,0)[l]{\fboxrule0.1pt% +\fcolorbox{rgb_ff0000}{cmy_000019}{\hbox{\color{rgb_0000ff}\texttt{\footnotesize \begin{minipage}{0.225in}\texttt{png mng gif}\end{minipage}}}}}} +\put(3.52,1.40625){\color{rgb_0000ff}$\allinethickness{0.0207555in}\circle{0.0207555}$}% +\put(1.92,0.46875){\makebox(0,0)[c]{\hbox{\color{rgb_009800}\texttt{\Large flix}}}} +\end{picture}% diff --git a/graphics/epix/doc/ePiX.xp b/graphics/epix/doc/ePiX.xp new file mode 100644 index 0000000000..c39e6b2ac0 --- /dev/null +++ b/graphics/epix/doc/ePiX.xp @@ -0,0 +1,156 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +void emph(const std::string& prog) +{ + if (prog == "all") + black(); + else + { + bbold(Red()); + label_color(Blue()); + label_mask(Yellow(0.1)); + label_border(Red(), "0.1pt"); + } +} + +void restore(const std::string& prog) +{ + if (prog == "all") + emph(prog); + + else + { + plain(); + black(0.5); + label_mask(Neutral()); + } +} + +void diagram(const std::string& prog) +{ + font_size("footnotesize"); + arrow_width(1.5); + restore(prog); + + if (prog != "laps") + emph(prog); + + arrow(P(0,1), P(1,1)); + + dot(P(0,1), P(0,4), "\\texttt{xp}, \\texttt{flx}", t); + dot(P(1,1), P(2,4), "\\texttt{eepic}", t); + restore(prog); + + if (prog != "epix") + emph(prog); + + spline(P(1,1), P(1.2,1), P(1.3,0.5), P(1.5,0.5)); + arrow(P(1.5,0.5), P(2,0.5)); + arrow(P(2,0.5), P(3,0.5)); + + dot(P(2,0.5), P(0,4), "\\texttt{dvi}", t); + dot(P(3,0.5), P(-2,2), "\\texttt{ps}", tl); + restore(prog); + + if(prog == "laps") + emph(prog); + + spline(P(1,0), P(1.2,0), P(1.3,0.5), P(1.5,0.5)); + + dot(P(1,0), P(2,-4), "\\texttt{tex}", b); + + if (prog == "elaps") // and laps + emph(prog); + + arrow(P(3,0.5), P(3.5,0), P(4,0)); + + dot(P(4,0), P(4,0), "\\texttt{pdf}", r); + restore(prog); + + if (prog == "elaps" || prog == "flix") + emph(prog); + + arrow(P(3,0.5), P(3.5,1), P(4,1)); + + dot(P(4,1), P(-2,4), "\\texttt{eps}", t); + restore(prog); + + if(prog == "flix") + emph(prog); + + arrow(P(4,1), P(5,1)); + + dot(P(5,1), P(4,0), + "\\begin{minipage}{0.225in}\\texttt{png mng gif}\\end{minipage}", r); + restore(prog); + + if (prog != "all") + { + font_size("Large"); + font_face("tt"); + label_color(Green(0.6)); + label(P(2.5,0), prog); + } + +} + +int main() +{ +#ifdef SHOW_ALL + picture(P(-0.5,0), P(5.75,10), "4 x 7.5 in"); +#else + picture(P(-0.5,2), P(5.75,10), "4 x 7.5 in"); +#endif + + begin(); + // border(); + + screen laps(P(0,0), P(5,1)); + activate(laps); + + diagram("laps"); + laps.v_scale(0.5, P(0,0.5)); + inset(laps, P(0,8), P(5,10)); + deactivate(laps); + + + screen epix(P(0,0), P(5,1)); + activate(epix); + + diagram("epix"); + epix.v_scale(0.5, P(0,0.5)); + inset(epix, P(0,6), P(5,8)); + deactivate(epix); + + + screen elaps(P(0,0), P(5,1)); + activate(elaps); + + diagram("elaps"); + elaps.v_scale(0.5, P(0,0.5)); + inset(elaps, P(0,4), P(5,6)); + deactivate(elaps); + + + screen flix(P(0,0), P(5,1)); + activate(flix); + + diagram("flix"); + flix.v_scale(0.5, P(0,0.5)); + inset(flix, P(0,2), P(5,4)); + deactivate(flix); + +#ifdef SHOW_ALL + screen all(P(0,0), P(5,1)); + activate(all); + + diagram("all"); + all.v_scale(0.5, P(0,0.5)); + inset(all, P(0,0), P(5,2)); + deactivate(all); +#endif + + end(); +} diff --git a/graphics/epix/doc/epix.info b/graphics/epix/doc/epix.info new file mode 100644 index 0000000000..3b30c42c39 --- /dev/null +++ b/graphics/epix/doc/epix.info @@ -0,0 +1,4696 @@ +This is epix.info, produced by makeinfo version 4.9 from epix.texi. + + This is the manual for ePiX, Version 1.2 Copyright (C) 2001, 2002, +2003, 2004, 2005, 2006, 2007 Andrew D. Hwang + + +File: epix.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) + +ePiX manual +*********** + +This is the manual for ePiX, Version 1.2 Copyright (C) 2001, 2002, +2003, 2004, 2005, 2006, 2007 Andrew D. Hwang + +* Menu: + +* Introduction :: +* Getting Started :: +* Reference Manual :: +* Advanced Topics :: +* Software Freedom:: +* Acknowledgments:: +* Function Index:: +* Concept Index:: + + --- The Detailed Node Listing --- + +Introduction + +* Changes in Version 1.2:: +* Software Dependencies:: +* Installation:: + +Getting Started + +* Running `ePiX':: +* The Drawing Model:: +* Tutorial:: +* `C++' Basics:: +* Animation:: +* Layout Tricks:: + +Reference Manual + +* File Structure:: +* Picture Size and Aspect Ratio:: +* Color:: +* Scene Attributes:: +* Drawing Attributes:: +* Creating and Drawing Objects:: +* More About `C++':: +* Attribute Quick Reference:: + +Advanced Topics + +* Hidden Object Removal:: +* Extensions:: +* Programmer's Guide:: + + +File: epix.info, Node: Introduction, Next: Getting Started, Prev: Top, Up: Top + +1 Introduction +************** + +`ePiX', a collection of batch utilities, creates mathematically +accurate figures, plots, and animations containing `LaTeX' typography. +The input syntax is easy to learn, and the user interface resembles +that of `LaTeX' itself: You prepare a scene description in a text +editor, then "compile" the input file into a picture. `LaTeX'- and +web-compatible output types include a `LaTeX' picture-like environment +written with `PSTricks', `tikz', or `eepic' macros; vector images +(`eps', `ps', and `pdf'); and bitmapped images and movies (`png', +`mng', and `gif'). + + `ePiX''s strengths include: + + * Quality of output: `ePiX' creates accurate, publication-quality + figures whose appearance matches that of `LaTeX'. Typography may + be put in a figure as easily as in an ordinary `LaTeX' document. + + * Ease of use: Figure objects and their attributes are specified + by simple, descriptive commands. + + * Flexibility: Objects are described by attributes and Cartesian + location; as in `LaTeX', printed appearance is determined when the + figure is compiled. A well-designed figure can be altered + dramatically, yet precisely, with command-line switches or minor + changes to the input file. + + * Power and extendibility: `ePiX' inherits the power of `C++' as a + programming language; variables, data structures, loops, and + recursion can be used to draw complicated plots and figures with + just a few lines of input. External code can be incorporated in a + figure with a command line option or by using a Makefile. + + * Economy of storage and transmission: For a document containing + many figures, a compressed tar file of the `LaTeX' sources and + `ePiX' files is typically a few percent the size of the compressed + PostScript file. + + * License: `ePiX' is _free software_. You are granted the right to + use the program for whatever purpose, and to inspect, modify, + and re-distribute the source code, so long as you do not + restrict the rights of others to do the same. In short, the + license is similar to the terms under which theorems are + published. + + + `ePiX' facilitates logical, as opposed to visual, structuring of +mathematical figures, analogous to the relationship between `LaTeX' and +a word processor. A few stylistic defaults streamline the creation of +simple figures, but there are few internal restrictions on the contents +or appearance of a figure; aesthetic and practical decisions are left +to you. + + If you are a: + + * Potential user, you may wish to skip immediately to "Software + Dependencies" before investing additional time. + + * New user, proceed from here until you have enough understanding + to run the software, then experiment with the samples files while + reading Chapter *Note chapter:started::, , or return to the + manual as needed. + + * More advanced user, browse at will, probably starting with + Chapter *Note chapter:ref-man::, . + + + This manual is relatively conversational, and occasionally redundant, +especially between portions meant for readers at different levels of +familiarity. Throughout, you are assumed to be familiar with `LaTeX' +and basic linear algebra: the description of points, vectors, lines, +and planes in three-dimensional space. Other material, such as `C++' +syntax, is introduced as needed. + +* Menu: + +* Changes in Version 1.2:: +* Software Dependencies:: +* Installation:: + + +File: epix.info, Node: Changes in Version 1.2, Next: Software Dependencies, Prev: Introduction, Up: Introduction + +1.1 Changes in Version 1.2 +========================== + +`ePiX' 1.2.x has been written almost entirely from scratch. The +conceptual model is unchanged, but there are a few changes of syntax. +If you're new to `ePiX', please skip straight to Section *Note +section:software_deps::, . + + + +Except as noted below, `ePiX' 1.0 files will compile under Version 1.2. +Generally, global variables have been deprecated or removed, and should +be replaced by function calls in new files. The following changes are +either required, or else strongly recommended (and may become +mandatory). + + * (Mandatory) The global variable tix in a `flix' file must be + manipulated through the function tix(). + + * (Mandatory) The command `use_pstricks()' is obsolete. PSTricks + output is obtained systematically as an output format. + + * (Mandatory) Deprecated "aliases" no longer exist: `triple' (for + the `P' class), `D' (for `Deriv'), and `I' (for `Integral'). + Lowercase trig function names conflicted with the standard + namespace and have been removed. + + * (Mandatory) Geometric object commands (`circle', `plane', + `segment', and `sphere'), which formerly created class objects, + now perform drawing just as `ellipse', `line', `rect', etc., do. + The classes are available with capitalized names (`Circle', + etc.). + + * (Mandatory) Camera orientation is controlled with functions + named `tilt', `pan', and `roll'; each rotates the camera about + an axis through the viewpoint, not through the target. + + * (Recommended) The global size variables x_min, x_max, y_min, + y_max, x_size, and y_size should be replaced by the function + calls xmin(), etc. (No underscores.) + + * (Suggested) The camera may be accessed through the function + `cam()'. + + * (Suggested) The size and bounding box are given in one command, + such as `picture(P(-1,0), P(1,1), "4x3in")'. The old syntax will + be retained indefinitely. + + + + + * Output is cleanly separated from the internal representation. + Figures may be written with a choice of macros--`PSTricks', + `tikz', and `eepic' at present--and new output types are easily + coded so long as the format supports arbitrary line segments, + color, and the ability to place a `LaTeX' box at a specified + location. + + * Colors are a manipulable data type, available in RGB, CMY, CMYK, + and Gray models. `xcolor'-style operations, such as color model + conversion, blending, superposition, and inversion are provided. + + The camera has a filter which affects the colors of all scene + elements. Filters performing CMYK separation are provided. + + * Color filling is controlled with declarations, similarly to line + colors in `ePiX' 1.0. Arrows and markers of type spot, dot, ddot, + and circ are now colored like other markers. Parametric surfaces + may be color-shaded. + + If a figure contains many shaded elements, a color-capable output + format (e.g.\ `PSTricks' or `tikz') should be used for + efficiency. Filled regions are implemented as fine hatching in + `eepic'. + + * An `axis' class provides coordinate axes with labels in a + variety of styles: decimals or scientific notation of specified + precision, fractions, trig fractions, logarithmic labels in + arbitrary (integer) base, and user-supplied styles. + + * `ePiX' 1.2.x performs page layout. Sub-figures may be manipulated + flexibly. The sample files give several applications. + + * Non-member intersection operators for circles, planes, spheres, + and segments are provided. A "non-generic" intersection does not + throw an exception, but instead returns an undrawable "malformed" + object. + + + +File: epix.info, Node: Software Dependencies, Next: Installation, Prev: Changes in Version 1.2, Up: Introduction + +1.2 Software Dependencies +========================= + +If you run GNU/Linux, a BSD, or Solaris, you probably have (and can +surely install) all the external software needed to use `ePiX'. On Mac +OS X, you will need the Apple developer tools and an X server (XCode +and XDarwin on the Tiger disks), and the free `fink' package manager to +build a GNU environment. For Windows, you'll need to install Cygwin +and several packages. Detailed instructions are given below. + + "Under the hood", an input file is successively converted to a +`LaTeX' picture; `dvi'; PostScript, `pdf' or `eps'; and if desired, to +a bitmapped image or movie. Four shell scripts--`epix', `laps', +`elaps', and `flix'--automate the various file format conversions. + + `ePiX' consists of a `C++' library, header, and shell scripts, and +requires GNU `bash' and a compiler _for normal use_. For complete +functionality, you need `g++' (Version 3.2 or later), `bash', a text +editor (`ePiX' works particularly well with `emacs'), a `LaTeX' +distribution, `Ghostscript', `gv' (or your favorite PS/PDF previewer), +and `ImageMagick'. GNU `grep' and `sed' are good to have. You may need +additional "developer packages" (`binutils', `make') in order to build +`ePiX'. The more up to date your software is, the better your +experience is likely to be, but bleeding edge versions are not +necessary, or even always desirable. + + Aside from their reliance on specific programs, `ePiX''s shell +scripts are written using Unix-style pathnames. Thus, the most +straightforward way to use `ePiX' is to install a GNU environment. + + Jay Belanger's `emacs' mode allows you to write, compile, and view +`ePiX' figures without leaving `emacs'. If you use another editor, +you'll want to create template source files so you don't have to type +boilerplate code each time you write a new figure. + + + +Cygwin can be used to run `ePiX' under Windows. Download `setup.exe' +from `http://www.cygwin.com', then install the packages you need. The +following are recommended, and sufficient for the actions described in +this manual. + +(Archive) bzip2, tar +(Devel) binutils, coreutils, gcc, gcc-g++, make, sed +(Editors) emacs, emacs-X11, vim +(Graphics) ImageMagick, ghostscript-base, ghostscript-x11, gv +(Publishing) tetex (all) +(Shells) bash, bash-completion +(X11) X-start-menu-icons, X-startup-scripts, + XFree86-lib-compat, xorg-x11-fscl, xorg-x11-fsrv + + + +File: epix.info, Node: Installation, Prev: Software Dependencies, Up: Introduction + +1.3 Installation +================ + +`ePiX' is distributed over the World-Wide Web as source code. Packages +may be found at `http://mathcs.holycross.edu/~ahwang/epix/ePiX.html' +The latest stable release is also on the CTAN mirrors, in the +`graphics' directory. (Some users of Red Hat have reported file +permission problems when unpacking the CTAN tarballs. If you encounter +this difficulty, please try downloading the sources from the project +main page.) Unpack the compressed tar file with the appropriate +command: + + tar -zxvf epix-x.y.z.tar.gz + tar -jxvf epix-x.y.z.tar.bz2 + (`x.y.z' is the version number) or, if your `tar' doesn't do +decompression, + + gunzip -c epix-x.y.z.tar.gz | tar -xvf - + bzcat epix-x.y.z.tar.bz2 | tar -xvf - + `cd' to the source directory, `epix-x.y.z'. The `INSTALL' file +contains detailed installation instructions. If you're impatient, the +short of it is `./configure [--options]; make; make install'. Run +`./configure --help' for a list of options. + + By default, `ePiX' installs in subdirectories of `/usr/local'; if +you want to install elsewhere, supply `./configure' with the +appropriate `--prefix'. You may also want to consult `POST-INSTALL' for +information on setting your `PATH' variable so your shell can find +`ePiX'. The manual and sample files are in `/usr/local/share/doc/epix'. + + + +There are two mailing lists, one for user questions, one for +development discussion. Please visit +`http://savannah.nongnu.org/mail/?group=epix' to subscribe. + + +File: epix.info, Node: Getting Started, Next: Reference Manual, Prev: Introduction, Up: Top + +2 Getting Started +***************** + +This chapter describes the basics of creating figures in `ePiX' for +readers familiar with `LaTeX' but completely new to `C++'. No detailed +knowledge of `C++' is needed to use `ePiX', only a bit of grammar that +is easily absorbed by example. + + Section *Note section:running::, describes the commands (shell +scripts) comprising `ePiX', and explains how to set up a graphical +environment using standard *nix programs. Section *Note +section:overview::, briefly describes figure creation. Section *Note +section:tutorial::, presents a few files side-by-side with their +output, and should be read at a computer so you can run the exercises. + +* Menu: + +* Running `ePiX':: +* The Drawing Model:: +* Tutorial:: +* `C++' Basics:: +* Animation:: +* Layout Tricks:: + + +File: epix.info, Node: Running `ePiX', Next: The Drawing Model, Prev: Getting Started, Up: Getting Started + +2.1 Running `ePiX' +================== + +An "input file" is a human-written figure specification containing +`ePiX' commands. An "output file" is machine-created, and is included +directly into a `LaTeX' document with the appropriate packages. + + Conversion ("compiling" a figure) is accomplished with four shell +scripts, `laps', `epix', `elaps', and `flix'. Each script has a +preferred extension for its input files, and is invoked with a command +of the form + + <script> [options] <input file(s)> + Often, no options are necessary. `<script> --help' describes +`<script>''s options. + + By default, output file names are constructed by replacing the input +extension with the (preferred) output extension. For brevity, +extensions may be omitted. If the script has doubts about your intent, +it proceeds with default behavior and prints a warning message. + + The author is a great fan of <TAB> completion, under which a shell, +based on what has been typed so far, automatically fills in a command +when the <TAB> key is pressed. `ePiX' comes with code snippets that +complete intelligently when the first part of a command is one of the +shell scripts. For example, if command completion is active, typing +`epix' <TAB> prints only names of `epix' input files. To use this +feature, you must install Ian MacDonald's `bash completion' package. +The `INSTALL' and `POST_INSTALL' files contain details. + + + +`laps' performs `LaTeX' to PostScript/PDF conversion, and is +independent of the rest of `ePiX'. By default, `laps' invokes `LaTeX' +and `dvips'. The option `--pdf' creates a PDF file by post-processing +the PostScript with `ps2pdf'. Other `TeX'-family processors +(`pslatex', `pdftex', etc.) may be used instead of `LaTeX' by invoking +`laps' with an appropriate option. + + + +`epix' compiles an input file into a `LaTeX' picture. The input file +should have extension `xp' (for eXtended Picture). Jay Belanger's +`emacs' mode is Highly Recommended; the installation procedure can be +found in the `POST_INSTALL' file. When this mode is active, `emacs' +automatically inserts a preamble template when a new `xp' file is +created. In addition, you can peruse `ePiX''s info file, or format, +compile, and preview files, all from within `emacs'. + + Output files from the script `epix' have extension `eepic', after +Conrad Kwok's enhancements to the `LaTeX' picture environment. In +Version 1.2, however, an output file need not contain `eepic' macros at +all. + + An output file is `input' directly into a `LaTeX' document whose +preamble contains appropriate `usepackage' lines. Rotated text +requires the `rotating' package. + + + +`elaps' creates stand-alone vector images (`eps' or `pdf') from `epix' +input files or `eepic' figures, even those not produced with `epix'. +`elaps' automatically loads the `LaTeX' packages needed for features +described in this manual. Additional `LaTeX' packages and `dvips' +options may be specified on the command line. + + + +`flix' creates bitmapped images and movies, Section *Note +section:animation::, . Input files should have extension `flx', and +must contain a valid `epix' header as well as additional code. Jay +Belanger's `emacs' mode facilitates creation of `flix' files. + + +File: epix.info, Node: The Drawing Model, Next: Tutorial, Prev: Running `ePiX', Up: Getting Started + +2.2 The Drawing Model +===================== + +To draw a figure manually, you select a sheet of paper of appropriate +size and add paths, markers, and labels. These scene elements have +attributes (line color, line width, fill color, font size, etc.) +affecting their appearance. + + `ePiX''s drawing model behaves similarly. A `picture' command sets +the _canvas_ (or logical drawing area, a Cartesian rectangle) and the +true size of the final figure. A `begin' command initializes the +"virtual paper" for drawing. Subsequent _drawing commands_ add objects +to the scene: lines, curves, function plots, labels, and the like. The +printed appearance of scene elements is determined by the current +"attribute state" and controlled by _style declaration_ which remain in +effect until superseded. Finally, an `end' command closes the figure and +prints it to the output file. + + In this manual, command descriptions follow a few conventions. +Optional arguments are enclosed in square brackets. A `len' argument is +either a number (representing a length in `pt') or a double-quoted +string containing a number and a two-letter `LaTeX' length unit, such +as `"1.5pt"' or `"6cm"'. A `color' argument is a named primary +(`Red()', `Cyan()', `White()', etc.), or a `Color' specified by +densities (`RGB(r,g,b)', `CMY(c,m,y)', etc.) + + * Fill color: `fill(color)', `nofill()'. + + * Line color and width: `plain([color])', `bold([color])'. + + * Text size: `font_size([size])', returns to `normalsize' if no + argument is given. + + + \noindent A complete list of style commands is found in Section +*Note section:quickref::, , starting on page *Note section:quickref::. + + To handle three-dimensional scenes, a `camera' performs point +projection from a selected spatial location to the canvas. As a user, +you'll need to control relatively few of the `camera''s parameters. +Keep in mind, however, that elements are added to a scene in the same +order their commands appear in the output file, and that later elements +generally cover earlier ones. Some three-dimensional scenes require +manual ordering of the input file; such ordering is dependent on the +`camera''s location. + + By default, `ePiX' draws thin, solid, black lines, performs no +filling of regions, prints text in a 12 pt Roman font, and looks down +the z axis from a large distance, giving orthogonal projection on the +(x,y) plane. When the `camera' is moved, the z axis points vertically +up on the page. + + +File: epix.info, Node: Tutorial, Next: `C++' Basics, Prev: The Drawing Model, Up: Getting Started + +2.3 Tutorial +============ + +This section presents sample input files side-by-side with their output +so you can compare what you write with what you'll see on the screen or +page. `ePiX' provides standard drawing capabilities, but like all +software has its own idioms and personality. The basic syntax, which +comes from `C'/`C++', should be mostly self-explanatory. One-line +comments begin with the string "//". + + To use the sample files interactively, you'll need working software: +`bash', `emacs', `ePiX', `g++', `gv', and a running X server. To +complete your "GUI", start `gv' and select "Watch file" from the "State" +menu. The loaded file will update automatically when it changes. + + Create a "scratch" directory, `cd' into it, and run the command + + tar -zxf /usr/local/share/doc/epix/sample_src.tar.gz + (Change the path as appropriate for your installation.) This unpacks +copies of the sample files into your scratch directory, including all +the files mentioned in this manual. The `README' file serves as a table +of contents. + + Open a sample file in `emacs', compile it from the drop-down menu +(or with the keyboard command), then open the `EPS' file in `gv'. Now +you're ready to follow the tutorial interactively. A few suggested +exercises are included with each file. Naturally, as you study more +files, you'll be able to make more interesting changes on your own. + + + +The first sample, `hello.xp', contains code needed to specify the +figure's size, followed by the classic greeting. The `border' command +draws a box around the figure in the specified color and width, and +serves here merely to delimit the output from the surrounding page. + +/* -*-ePiX-*- */ +#include "epix.h" // These lines are analogous +using namespace ePiX; // to a usepackage command. + +int main() +{ + picture(P(-1,-1), P(1,1), "2 x 1in"); // corners, true size + + begin(); // ---- Figure body starts here ---- + + border(Black(), "1pt"); // color, line width + + font_size("Huge"); // May be any font size, e.g. "scriptsize" + label(P(0,0), "Hello, world!"); + + end(); // ---- End figure; write output file ---- +} + + +[Image] + + * Change the color and width of the border. (`RGB(r,g,b);' creates + an RGB color, CMY colors are analogous. Named primaries are + available. The densities should be between 0 and 1 for + "expected" behavior.) + + * Add `backing(Cyan());' after the `border' command. + + * Put the command `crop_ellipse();' before the `border' command. + Permute the `crop_ellipse' command with the `border' and + `backing' lines, and note how the attribute (`crop') affects + objects (`border', `backing'). + + + + +Our next file uses simple objects to draw a 2-D house-and-sun scene. + + +int main() +{ + picture(P(0,0), P(5,2), "3.75 x 1.5in"); + + begin(); + + triangle(P(0.9, 1), P(3.1, 1), P(2, 1.5)); // vertices + circle(P(4,1.5), 0.25); // center and radius + + rect(P(1,0), P(3,1)); // opposite corners + + fill(Black(0.1)); // light gray + rect(P(2.3,0), P(2.7,0.8)); // the door + nofill(); + + bold(); // draw thicker lines + grid(P(1.4, 0.2), P(2, 0.6), 2, 2); // corners, number of squares + + line(P(xmin(), 0), P(xmax(), 0)); // endpoints + + end(); +} + + +[Image] + + * Add declarations such as `bold(RGB(1,0.9,0.5))' or + `fill(Yellow())' to color the scene. (Color and filling are + orthogonal attributes.) + + \noindent The sample file `house.flx' uses loops to draw gradient +fills of the lawn, sky, and sun, and animates a sunset. + + + +Plotted functions must be defined in the "preamble", before `main'. +"High-level" elements--coordinate axes and grids, axis labels, and +graphs--are drawn with mnemonically-named commands. + +// double = double-precision floating point +double f(double x) { return 0.75*Sin(x) - 0.25*Sin(2*x); } + +int main() +{ + picture(P(-2,-1), P(2,1), "5 x 1in"); // [-2,2] x [-1,1] + + begin(); + revolutions(); // set angle units, [0,1] = one turn + + h_axis(16); // axes w/default endpts + v_axis(4); + h_axis_labels(4, P(0,-4), b); // shift down 4pt, align below + + plain(Red()); + plot(f, xmin(), xmax(), 120); // use 120 intervals + + end(); +} + + +[Image] + + * Define and plot some different functions; adjust the bounding + box as necessary. (Use repeated multiplication for polynomials. + The `polarplot' command graphs r=f(\theta).) + + * Change the arguments to `h_axis_labels'. The first specifies the + number of intervals to label; the second gives the label offset + in `pt'. The last puts each label below (`b') its Cartesian + location. + + + + +Functions of two or three variables are defined just like functions of +one variable, but for plotting the return type must be a point (`P'), +not a real number (`double'). The `domain' class specifies the set of +inputs to plot. + + +P f(double r, double th) +{ + return P(r*Cos(th), r*Sin(th), pow(r, 3)*Cos(3*th)); +} + +int main() +{ + picture(P(-1,-1), P(1, 1), "2 x 1in"); + begin(); + pst_format(); // use PSTricks macros for output + + // corners ([0,1] x [0,2\pi]) and fineness + // (8x40 rectangles, plotted at 16x120 resolution) + domain R(P(0,0), P(1, 2*M_PI), mesh(8,40), mesh(16,120)); + + camera.at(P(3,1,2)); // set the viewpoint + arrow(P(0,0,0), P(1.25,0,0)); // coordinate axes + arrow(P(0,0,0), P(0,1.25,0)); + + plain(Blue(1.2)); // line color and width + fill(Yellow()); // shading color + surface(f, R); + + end(); +} + + +[Image] + + + +A function can be defined by an arbitrary algorithm, and a `domain' may +be used to plot a family of functions for several values of one +variable. + + +P sin_n(double x, double n) // Taylor polynomial of sin x +{ + const int N((int) floor(n)); // convert n to an index bound + const double sqx(-pow(x, 2)); // -x^2 + double val(x), summand(x); + + for (int i=1; i <= 2*N+1; i += 2) + { + summand *= (sqx/((i+1)*(i+2))); // (-1)^i x^{2i+1}/(2i+1)! + val += summand; + } + + return P(x, val); // return (x, y) +} + +int main() +{ + picture(P(0, -1), P(6*M_PI, 1), "5 x 1in"); + + begin(); + + set_crop(); + bold(Green()); + plot(Sin, 0, xmax(), 120); + + domain R(P(0,1), P(6*M_PI, 41), mesh(60, 40), mesh(120, 40)); + for (int i=3; 0 <= i; --i) // print in descending degree + { + bold(RGB(0.25*i, 0, 1-0.25*i)); // degree-dependent color + plot(sin_n, R.slice2(5*i+1)); // plot for n = 5i+1 + } + end(); +} + + +[Image] + + + +Page layout can be composed from sub-pages with `screen' objects. In +the loop body below, objects are added to the "active" `screen', then +`inset' into the "canvas", the screen representing the entire figure. + + +P f(double u, double v) +{ + return P((u-v)*(u+v), 2*u*v, u); +} + +int main() +{ + picture(P(0,0), P(2,3), "5x7.5in"); // overall size + + begin(); + + domain R(P(-1,-1), P(1,1), mesh(12,12), mesh(24,24)); + + for (int i=0; i<2; ++i) + for (int j=0; j<3; ++j) + { + screen my(P(-3,-3), P(3,3)); + activate(my); + border(Red(0.6), "1pt"); + // frame-dependent viewpoint + camera.at(sph(10, (2*j+i+1)*M_PI/8, M_PI/6)); + + plot(f, R); + arrow(P(0,0,0), 2*E_1); + arrow(P(0,0,0), 2*E_2); + // SW corner at (i, 2-j), padded by 0.05 on all sides + inset(P(i+0.05,2.05-j), P(i+0.95,2.95-j)); + } + + end(); +} + + +[Image] + + +File: epix.info, Node: `C++' Basics, Next: Animation, Prev: Tutorial, Up: Getting Started + +2.4 `C++' Basics +================ + +An `ePiX' source file is a `C++' program. If you've successfully +modified and compiled the sample files, you know enough `C++' to use +`ePiX'. In the author's experience, `C' grammar suffices for most +applications. An excellent introduction to definitions of functions +and variables, control statements, and overall program structure is +Kernighan and Ritchie's _The `C' Programming Language_, second edition +`KnR'. + + + +Jay Belanger's `emacs' mode for `ePiX' inserts a file template when an +empty buffer is opened with the extension `xp'. This section explains +the purposes served by the template. A few additional remarks may help +you avoid basic syntax pitfalls. + + A `C++' file consists of "statements", analogous to ordinary +sentences. Common types include _declarations_ (which "register" a +function, variable, or type name with the compiler), _definitions_ +(which assign meaning to declared names), and _function calls_ (which +cause a named function to execute). Most statements in an `ePiX' input +file are function calls ("commands"). Plain declarations are +relatively rare in user files, since a definition serves to declare any +new names that it contains. + + Every statement ends with a semicolon, and conventionally a file +contains at most one statement per line. The compiler ignores nearly +all whitespace (spaces, tabs, and newlines), which should be used +freely to make files easy to read. Other punctuation (periods, commas, +(semi)colons, parentheses, braces, and quotes) dictates file parsing, +and must adhere stringently to grammar. + + An `ePiX' file always begins with the lines + +#include "epix.h" // N.B. pre-processor directive, no semicolon +using namespace ePiX; + The first line is analogous to a `LaTeX' `usepackage' command: It +loads the contents of the "header" file `epix.h', importing the names +of commands provided by `ePiX'. To avoid name conflicts, `ePiX''s +commands are enclosed in a "namespace". For example, the `label' +command is actually known to the compiler as `ePiX::label'. The second +line above tells the compiler to apply the prefix tacitly. + + + +Definitions of variables and functions play the same role in a figure +that macro definitions play in a `LaTeX' document: gathering and +organizing information on which the figure depends. A variable is +defined by supplying its type, name, and initial value. By far the most +common data types in `ePiX' are `double' (double-precision floating +point number), `P', and `int'. The name of a variable may consist +(only) of letters (including the underscore character) and digits, and +must begin with a letter: + +my_var, var2, MY_var, aLongVariableName; // valid +my-var, 2var, \v@@riable, $x, ${MY_VARIABLE}; // not valid + Variable names are case-sensitive, and numerous (non-universal) +conventions govern the significance of capitalization. Generally, make +names descriptive but not unwieldy, and avoid language keywords (such +as `const', `true', `double', `class', or `public') and names that +begin with an underscore. + + A function accepts "arguments" and "returns a value". To define a +function in `C++', you must specify the return type, the name of the +function, the types of the arguments, and the algorithm by which the +value is computed from the inputs. The code block + +double f(double x) +{ + return sqrt(1-x*x); +} + specifies the `double'-valued function f of one `double' variable +defined by the formula f(x)=\sqrt1-x^2. + + + +`C++' has two types of comments. `C'-style comments, which may span +several lines, are delimited by the strings `/*' and `*/'. One-line +comments, analogous to the `LaTeX' `\%', are begun with `//'. A +one-line comment may appear within a multi-line comment, but a +`C'-style comment may not; the compiler will mistake the first `*/' it +encounters as the end of the current multi-line comment. + + + +All the "action" in a `C++' program occurs inside the special function +`main'. Running a compiled `C++' program is viewed by the operating +system as calling the program's `main' function. The return value (an +`int') is the program's exit status. The contents of the output file +start with `begin()' and terminate with `end()'. Intervening +statements constitute the _body_ of the file. + + In `C++', a function may not be defined inside another function. +Thus, variables may be defined inside `main', but functions cannot be. + + + +In `C++', a `string' is a sequence of characters. Most `string's in +`ePiX' input files are _literals_, double-quoted `string's whose value +is read from the input. In a string literal, backslash is an escape +character; a single backslash is produced by a double backslash in the +input file. Certain letters have special meanings when +backslash-escaped, including "\n" (newline) and "\t" (<TAB>). Unlike +`LaTeX', `C++' does not require a space to separate an escape sequence +from following text; the string "\\textwidth" literally represents a +`LaTeX' command, while "\textwidth" is read "`TABextwidth'" by the +compiler. + + Though not commonly needed, raw text can be printed to the output +file. The functions `write', `pre_write', and `post_write' accept +`string' arguments. `write' prints its argument where the call appears +in the input file. The other functions print their arguments before or +after the completed picture, respectively. These commands must be in +the file body. As an application, a complete `LaTeX' `figure' +environment (with caption and label) can be produced by an `ePiX' file, +Figure *Note fig:captioned::, . + + +#include "epix.h" +using namespace ePiX; + +int main() +{ + picture(P(-1,-1), P(1,1), "10cm x 3in); + begin(); + pre_write("\@float Figure[hbt]"); // comes before the picture + + post_write("\@caption{A \@code{LaTeX}\ figure.}"); // and after + post_write("\@end float"); + + < ... other ePiX commands ... > + write("%% A comment near the end, but inside the picture."); + end(); +} // End of main() + +Figure: Generating a self-contained figure in `ePiX'. + + + +An algorithm's behavior usually depends on internal state. A +_conditional statement_ causes blocks of code to be executed according +to criteria. A _loop_ repeatedly executes a code block, usually +changing the values of variables in a predictable way, so that the loop +exits after finitely many traversals. + + +File: epix.info, Node: Animation, Next: Layout Tricks, Prev: `C++' Basics, Up: Getting Started + +2.5 Animation +============= + +`ePiX' is well-suited to the creation of mathematically accurate +animations: If a figure depends suitably upon a "time" parameter, then +a loop can be used to draw the entire figure for multiple time values, +yielding successive "snapshots" of the figure as time progresses. The +shell script `flix' automates the process of compiling a suitable input +file into a collection of `png's and assembling these frames into a +`mng' or `gif' animation. ImageMagick is the image-handling engine. + + A `flix' file is an `epix' file with two restrictions: + * The `double' variable `tix()' is used as "clock". + + * `main' accepts two command line arguments and sets `tix()' + accordingly. + Jay Belanger's `emacs' mode recognizes the file extension `.flx' and +inserts template code if an empty buffer is opened. Creation of `flix' +files is as easy as creation of `epix' files. The `samples' directory +contains a handful of `flix' files that may be consulted for ideas. + + By default, `flix' creates movies with 24 frames, in which `tix()' +runs from 0 to 1, and animates at 0.08 sec/frame. These and other +parameters can be changed with command-line options. + + A "typical" `.flx' file may take 30 seconds to a few minutes to +compile, depending on the number of frames and the complexity of each +frame. To facilitate debugging, `elaps' can be run on a `flix' file. +`elaps' runs in a fraction of the time, and if `elaps' can't produce a +viewable image, `flix' will surely fail. While running, `flix' prints +a progress bar counting the number of `eps' files that have been +created. There will be a delay of a few seconds (or more) after the +last frame is produced, during which ImageMagick's `convert' utility +assembles the movie. + + +File: epix.info, Node: Layout Tricks, Prev: Animation, Up: Getting Started + +2.6 Layout Tricks +================= + + + +Stereograms are created by drawing a single scene twice from slightly +different points of view. To create a stereogram with `ePiX', write a +"scene" function containing the necessary drawing commands, then set +the camera appropriately and call the scene function twice, once for +each frame. + + + +The sample files `lorenz.xp' and `twisted_cubic.xp' use page layout to +draw crossed-eyes stereograms. For each frame, create and activate a +`screen', set the camera, and call the scene function. The frames are +inset side by side in the final picture. For a crossed-eyes stereogram, +the frame from the "rightmost" camera position is placed on the left. + + + +The sample files `cube.flx' and `mirrorball.flx' contain animated +red-cyan stereograms, suitable for viewing with 3-D glasses. The +technique works best with black-and-white line drawings, but the basic +approach is the same as for crossed-eyes stereograms: Create a scene +function and call it twice, setting the camera appropriately. Layout is +unnecessary since the frames are superposed. Pen colors should be +close to red and cyan, but "optimal" choices depend on one's eyes and +3-D glasses. + + + +Either form of stereogram can be animated in a `.flx' file, but keeping +one's eyes properly crossed requires practice while most people can +instantly see depth with 3-D glasses. As always when using `flix', +debug the scene with `elaps' before compiling a movie. If a +stereoscopic effect is difficult to see in a still image, it will be +even harder to perceive in a movie. + + + +`ePiX' can place external images into a figure, similarly to Rolf +Niepraschk's `overpic' package. You provide the Cartesian center point, +the file name, and optionally the true height and/or width of the image: + + label(P(a,b), "\\includegraphics[width=w,height=h]{file}"); + This effect requires the `graphicx' package. When compiling a +stand-alone graphic containing an external image, you must specify the +`graphicx' package on the command line: `elaps -p graphicx <file>' + + +File: epix.info, Node: Reference Manual, Next: Advanced Topics, Prev: Getting Started, Up: Top + +3 Reference Manual +****************** + +This chapter details `ePiX''s capabilities, discussing attributes and +data types, and listing available commands in the form + + label(P posn, [P offset], string text, [align]); + circle(P ctr, double rad=1, normal=P(0,0,1)); + As in Chapter *Note chapter:started::, , function arguments are given +by type (`P', `double', `string', etc.)\ and name, or by name alone if +the type is clear. Optional arguments are enclosed in square brackets. +A few argument types, such as `[align]' above, admit only a small +number of values; these cases are explained when the corresponding +command is first introduced. + + A name followed by an equals sign and a value indicates a default +argument; if omitted in an input file, the compiler substitutes the +default value. Only trailing arguments may be specified this way. For +example, if the `rad' argument of the `circle' command is omitted, the +`normal' argument _must_ be omitted as well. + + In an input file, only an argument's value is given, not the type: + + label(P(0,0), P(0,-4), "Hello world", b); + circle(P(0,-0.25), sqrt(2)); // use default normal + + Generally, `len' signifies either a number (representing a length in +`pt') or a double-quoted string containing a number and a two-letter +`LaTeX' length unit, such as `"1.5pt"' or `"6cm"'. `color' represents a +`Color' object constructed from a named primary (`Blue()', +`Magenta(0.7)', etc.), a color specification (`RGB(r,g,b)', +`CMY(c,m,y)', etc.), or an operator applied to an existing `Color'. + +* Menu: + +* File Structure:: +* Picture Size and Aspect Ratio:: +* Color:: +* Scene Attributes:: +* Drawing Attributes:: +* Creating and Drawing Objects:: +* More About `C++':: +* Attribute Quick Reference:: + + +File: epix.info, Node: File Structure, Next: Picture Size and Aspect Ratio, Prev: Reference Manual, Up: Reference Manual + +3.1 File Structure +================== + +An `ePiX' input file constitutes a short `C++' program. When this +program is compiled and run by one of the shell scripts, it creates a +figure file suitable for inclusion in `LaTeX'. + + Like a `LaTeX' document, an `ePiX' file contains a _preamble_, which +sets up a drawing environment, and a _body_, which contains actual +figure-generating commands. The minimal file has the form + +#include "epix.h" // N.B. no semicolon +using namespace ePiX; + +int main() { + picture(P(a1,b1), P(a2,b2), "n1 [unit1] x n2 unit2"); + begin(); // end of preamble, start of body + end(); // end of body +} + `ePiX' commands are of four general types: drawing, attribute setting, +definitions (of data and functions), and operations on existing +objects. Except as noted below, drawing and attribute commands must +appear in the body, between `begin()' and `end()'. Function definitions +must come in the preamble, before `main()'. Data definitions may appear +in the preamble or body. + + + +The `end()' command writes the output file to `stdout', using `eepic' +macros by default. The shell scripts redirect `stdout' to an +appropriate disk file. + + The attribute-setting command `pst_format()' causes the output file +to be written using `PSTricks' macros when `end' is called. Similarly, +`tikz_format()' causes the file to be written using `tikz' macros, and +`eepic_format()' causes the file to be written using `eepic' macros. +These commands may appear anywhere in the figure body. There is no +reason for a file to contain more than one such command. + + The output format may be selected on the command line, overriding any +explicit request in the input file. Supplying `epix', `elaps', or +`flix' with one of the options `--pst', `--tikz', or `--eepic' is +tantamount to issuing a `pst_format()' (etc.)\ command just before the +end of the file. These options are listed in decreasing precedence. If +more than one is given, the "strongest" applies, regardless of the +command line order. + + A figure may be written directly to a specified disk file, in a +format unaffected by the command line flags above. The command + + print_eepic("file.tex"); + writes the figure to the named file using `eepic' macros. Analogous +commands exist for the formats `pst' and `tikz'. These commands perform +an immediate action. Consequently, the command's location in the input +file is significant, and multiple commands may appear in a single file, +so long as distinct file name arguments are provided. Applications +include writing the same figure in multiple formats, or creating +successive "snapshots" of a lengthy computation. + + +File: epix.info, Node: Picture Size and Aspect Ratio, Next: Color, Prev: File Structure, Up: Reference Manual + +3.2 Picture Size and Aspect Ratio +================================= + +The `picture' command specifies a figure's logical and true sizes. In +the "minimal file" snippet above, the _canvas_ is the Cartesian +rectangle [a_1,a_2]\times[b_1,b_2] whose corners are given. Either pair +of opposite corners is acceptable, but confusion is less likely when +the SW and NE corners are given, in this order. + + The true (printed) width and height are read from `picture''s third +argument, a "size `string'" such as "4cm x 1in", containing a number +and optional `LaTeX' length unit, an `x', another number, and a +mandatory length unit. Spaces may be used for legibility. The +mandatory length unit becomes the `LaTeX' `unitlength'. The argument +"4cm x 1in" creates a picture 4 cm wide and 1 in high, but internally +converts 4 cm to inches. Recognized length units are `pt' (points, the +default), `cm' (centimeters), `in' (inches), `mm' (millimeters), `pc' +(picas), and `bp' (big points). (`1in = 2.54cm = 72bp = 72.27pt', `1pc += 12pt'.) + + The logical and true sizes may be defined separately with the +commands + + bounding_box(P(a1,b1), P(a2,b2)); + picture(n1, n2); + unitlength(len); // len a length string, not a double + One way or another, the logical and true dimensions _must_ have +positive values when the `begin()' command is issued. + + `LaTeX' treats the contents of a picture environment as a single box, +aligned by default on its lower left corner. An `offset' command +accepts two `double' arguments or a size `string' and shifts the page +location accordingly. The command `offset("0.25 x -0.5cm")' shifts the +picture right 0.25 cm and down 0.5 cm. If the `unitlength' is 1 cm, +the command `offset(0.25, -0.5)' has the same effect. + + A non-zero `offset' causes a picture's contents to appear in a +location where `LaTeX' does not expect them. This can be useful in a +`LaTeX' document, but should be avoided when compiling a stand-alone +image, since `dvips' may crop according to rules of its own. + + The canvas's corners are `(xmin(),ymin())' and `(xmax(),ymax())', +while its width and height are `xsize()' and `ysize()'. The canvas is a +virtual, advisory data structure; its dimensions are not directly +related to the figure's printed size, and picture elements may lie +outside the canvas. Affine scaling maps the canvas to the page when the +output file is written. +[Image] + + The figure's aspect ratio is controlled by sizing the canvas. The +aspect ratio is "true" if the canvas and page rectangles are +geometrically similar, e.g., if both boxes are 1.5 times as wide as +they are tall. + + +File: epix.info, Node: Color, Next: Scene Attributes, Prev: Picture Size and Aspect Ratio, Up: Reference Manual + +3.3 Color +========= + +`ePiX' provides a `Color' data type. Four models are implemented: +`RGB', `CMY', `CMYK', and `Gray'. A `Color' holds primary color +"channels", each carrying an intensity between 0 (no color) and 1 (full +saturation). "No color" means black in `RGB' and `Gray', white in +`CMY(K)'. `RGB', `CMY', and `CMYK' colors are written to the output +file as commands in the corresponding model. `Gray' shades are written +in `RGB'. + + Operations on red-green-blue colors are described below. +Functionally, colors are converted to `RGB', operated upon, then +converted back to the original model. Conversions are as described in +Uwe Kern's `xcolor' manual `xcolor'. + + + +Each color model has a "constructor" creating a color of specified +densities. The `RGB' and `CMY' models have named "primary" +constructors; the density argument is optional and defaults to 1. + + // red-green-blue colors + RGB(double r=0, double g=0, double b=0); + Red(d=1); Green(d=1); Blue(d=1); + White(d=1); Black(d=1); + + + // cyan-magenta-yellow colors + CMY(double c=0, double m=0, double y=0); + Cyan(d=1); Magenta(d=1); Yellow(d=1); + CMY_White(d=1); CMY_Black(d=1); + + // gray + Gray(double d=0); // equivalent to RGB(d, d, d) + Each `CMY' constructor has a corresponding `CMYK' function, e.g.\ +`CyanK()' or `CMYK_White()'. + + Though color densities lie between 0 and 1, `ePiX''s primary color +constructors take arguments mod 4, viewed as elements of [-2,2]. +Consider `Red(d)', "red with density d". For integer values of d, the +constructor has the following meanings: `Red(0)' is black, `Red(1)' is +red, `Red(2)'=`Red(-2)' is white, and `Red(-1)' is anti-red, or cyan. +For non-integer d, the constructor interpolates between the bracketing +integer values, Figure *Note fig:densities::, . Other primary +constructors work analogously. + + +[Image] + +Figure[hbt] + + Let \delta:[-2,2]\to[0,1] be the piecewise-linear function that +converts real numbers to primary color densities, \clip:R\to[0,1] the +clipping function. The non-primary constructor `RGB(r, g, b)' computes +the density of the red channel as +\clip\bigl(\delta(r)+\delta(-g)+\delta(-b)\bigr); the green and blue +channel densities are computed similarly. Every color can be created +with arguments between 0 and 1, but the constructor accepts arbitrary +real arguments and returns colors varying "continuously and +periodically". + + Colors possess an "alpha-channel" for transparency. Except as +supported by the output format, this feature is a stub. + + + +Colors can be scaled, inverted, blended, superposed, and filtered. In +the code below, `tint' is a `Color'. The effect of each operation is +described in the `rgb' model; the visual result is the same in all +models. + + tint *= double c; // multiply channels by c, rebuild + tint.invert(); // (r, g, b) -> (1-r, 1-g, 1-b) + tint.blend(Color col, double t); // (1-t)*tint + t*col + tint.superpose(col); // add channels, then clip to [0,1] + tint.alpha(double d); // set alpha channel to clip(d) + + tint.filter(col); // return min density in each channel + Except for `filter', these operators modify their object. `filter' +simulates the effect of viewing `col' through a transparent sheet of +`tint', and returns a new `Color' object having the same model as +`tint' without modifying `tint' itself. + + +File: epix.info, Node: Scene Attributes, Next: Drawing Attributes, Prev: Color, Up: Reference Manual + +3.4 Scene Attributes +==================== + +Objects in a scene sit in 3-dimensional space. A _camera_ maps objects +to the _active screen_. The active `screen' may, in turn crop its +contents. Each drawing command creates an object, "photographs" it, and +adds the image to the active `screen'. This section describes the +`Camera' and `screen' classes and a few associated concepts. + + + +By default, angles are measured in `radian's. Two other angular modes +are available: `degrees' and `revolutions'. The angular mode is set +with a named command, `radians()', `degrees()', or `revolutions()'. The +current angular mode affects all trigonometric functions and operations. + + + +Three-dimensional scenes are drawn on flat paper by applying a +mathematical transformation. By default, `ePiX' uses _point +projection_, the technique used by art students when they trace on a +window with grease pencil, Figure *Note fig:camera::, . + + +[Image] + +Figure[hbt] + + `ePiX' depicts a Cartesian world by projecting mathematically to a +screen plane, then affinely scaling to a printed page. The camera, +which maps the world to the screen, consists of a _body_ (data that +determines the position and orientation of the camera), a _lens_ (the +actual mapping to the screen plane), and a _filter_ (a color through +which the scene is viewed). + + + +The camera's spatial orientation is described by a triple of mutually +perpendicular unit vectors. In memory of happy days at the beach, +these vectors are called _sea_, _sky_, and _eye_. The screen plane is +parallel to the sea-sky plane; the sea vector points horizontally to +the right, sky points vertically upward. The eye is their cross +product, which points directly at the viewer. + + The sea-sky-eye basis is located at the _viewpoint_, the camera's +spatial location. The _target_, the origin of the screen plane, lies on +the line through the viewpoint in the direction opposite the eye +vector. The distance from the viewpoint to the target is the _range_. +The _camera sphere_ is centered at the viewpoint and passes through the +target. The orientation, viewpoint, target, and range completely (and +redundantly) determine the camera's geometric situation in the world. + + + +A _lens_ maps the world to the screen. `ePiX' comes with four lenses: +_shadow_ (the default), _orthogonal_, _fisheye_, and _bubble_. Each +lens simulates the appearance of world objects as seen by an observer +at the viewpoint. The shadow lens is point projection from the +viewpoint to the screen plane. The orthogonal lens projects from +infinite distance. Each of the other lenses performs radial projection +to the camera sphere, then maps the sphere to the screen plane; the +fisheye lens does orthogonal projection (so the entire image lies +inside the disk centered at the target whose radius is the range) while +the bubble lens does stereographic projection from the target's +antipode. + + An input file normally uses a single camera, so a global object named +`camera' is defined automatically. At the start of a figure, the +`camera' looks down on the (x_1,x_2)-plane from a distant point on the +x_3-axis. The resulting view, essentially projection along the axis, is +suitable for 2-dimensional figures. + + The `camera' is manipulated similarly to a real camera: + + camera.at(P posn); // set viewpoint to posn + camera.look_at(P targ); // set target to targ + camera.range(double dist); // fix target, move viewpoint + camera.focus(double dist); // fix viewpoint, move target + camera.tilt(double angle); // rotate about the sea axis + camera.pan(double angle); // rotate about the sky axis + camera.roll(double angle); // rotate about the eye axis + camera.clip_range(dist); // cull scenery closer than dist + Explicitly setting the viewpoint or target makes the sky vector +parallel to the projection of the x_3 axis when possible; otherwise the +x_2-axis is used. Setting the range or focus moves the `camera' +parallel along the eye line. Each command re-sizes the image; note that +increasing the focus _enlarges_ the image. The three rotation +operations fix the viewpoint, but only roll fixes the target. + + + +The `camera' has a _filter_ through which all scene `Color's pass. For +uniformity, the filter should only be set at the start of the file +body, before any visible elements have been placed in the scene. The +filter has two primary uses--model conversion and color separation--but +can also be used for special effects. + + There is a `Neutral' color, for which filtering has no effect at +all. The `camera''s default filter is `Neutral'. In addition, each +color model has a _neutral_ representative, `RGB_Neutral', etc. Passing +`Color's through a neutral filter preserves their appearance but +converts them to the neutral `Color''s model. + + Filtering can be used to "split" a `Color' into primary +constituents. For `RGB' channels, the primaries themselves are suitable +filters. For `CMYK' channels, there are special _process_ filters, +named C_Process, etc. + + camera.filter(CMY_Neutral()); // convert all colors to CMY + camera.filter(Gray_Neutral()); // black and white photography + camera.filter(Green()); // the green channel + camera.filter(M_Process()); // the magenta channel + camera.filter(Red(1.4)); // la vie en rose? + + + + +Two operations handle elements lying far from the target. _Cropping_ +culls elements based on their screen location, and is described later. +_Clipping_ removes objects whose spatial location lies outside the +"clip region". + + Initially, the clip region is a very large box centered at the +origin. Commands are provided to resize this box, keeping the faces +parallel to coordinate planes. + + clip_box(P pt1, P pt2); // opposite corners + clip_box(P pt); // opposite corners pt and -pt + clip_to (P pt); // pt and P(0,0,0) + clip_box(); // very large box + Additional "clippers" may be added manually. Individual clipping +planes are specified by a point and inward-pointing normal vector. +Parallel planes cutting a "slice" or "slab" are described by a +location, direction, and a distance. The location lies halfway between +the clipping planes, and the planes' normals point toward the location. + + clip_face(P loc, P perp); // perp points inward + clip_slice(loc, perp); // very close parallel planes + clip_slice(loc, perp, dist); // planes separated by dist + clip_restore(); // remove manually-added clip planes + Like `clip_restore', the `clip_box' and `clip_to' commands remove all +user-specified half spaces. + + + +By default, drawing occurs in the Cartesian coordinate system of the +`canvas'. However, insets and subfigures are most naturally composed in +"local" coordinates, then placed into their final location as a unit, a +process called _layout_. `ePiX' implements layout with the `screen' +class. + + + +A `screen' is a Cartesian plane containing a distinguished coordinate +rectangle, its _bounding box_. The `canvas' of a figure is a `screen', +as is the internal representation of the printed page. At any point of +a file body, some `screen' is _active_, or "open for drawing". A new +`screen' is created from a pair of opposite corners, but is not used +until explicitly activated. + + screen subfig(P(a1,b1), P(a2,b2)); // [a1, a2] x [b1, b2] + activate(subfig); // open subfig for drawing + // commands to draw in subfig + deactivate(subfig); // re-activate the previous screen + + The `canvas' is automatically drawn at the `end' of the input file. +The contents of other `screen's must be incorporated into the `canvas' +explicitly with an `import' or `inset' command. `import' affinely +scales the bounding box of the "child" `screen' to the `canvas'. `inset' +specifies corners in the "parent" where the child is placed. + + import(); // active screen to canvas + import(subfig); // subfig to canvas + inset(P sw, P ne); // active screen to specified rectangle + inset(subfig, sw, ne); // subfig to specified rectangle + inset(subfig); // inset to subfig's corners + + + +The portion of a `screen' enclosed by a specified rectangle can be +_extracted_. Each of the commands + + subfig.extract(P sw, P ne); + canvas().extract(P sw, P ne); + returns the `screen' having stated corners and containing part of +`subfig' or the `canvas', respectively. Elliptical and diamond-shaped +portions of a `screen' may be extracted. The contents occupy the +ellipse or diamond inscribed in the given rectangle. + + subfig.extract_ellipse(sw, ne); + canvas().extract_diamond(sw, ne); + The `screen' returned by `extract' (or its variants) may be used just +like a manually-constructed `screen', for example to construct a +magnified inset. + + + +On occasion, it is necessary to draw at known page size, independently +of the unit length. For 2-dimensional drawing in the (x_1,x_2)-plane +with the `camera' in its default location, the coordinates (horizontal, +vertical, or both) of a `screen' may be interpreted as true pt offsets +relative to a specified point rather than as Cartesian coordinates. + + inlay(subfig, P loc); + inlay_horizontal(subfig, loc); + inlay_vertical(subfig, loc); + Each command maps the origin of `subfig' to the specified location in +the active `screen'. The first performs affine scaling so that one +Cartesian unit in `subfig' maps to one true pt on the page. The second +and third commands perform this scaling only in the named direction. + + The `inlay' functions are suitable only for 2-dimensional effects. +For 3-dimensional true-size drawing, the function `pt_to_screen' +converts a true length of 1 pt into Cartesian coordinates in the active +`screen'. For example, the command `line(P(0,0), +P(pt_to_screen(12),0))' draws a line segment 12 pt long with its left +endpoint at the Cartesian origin. True size drawing is unusual in an +input file, but has definite uses in library code; `ePiX''s right angle +marker is a typical application. + + Either type of true-size drawing works as described when drawing in +the `canvas', and _only_ when drawing in a `screen' imported to the +`canvas' at "true Cartesian" size (one `screen' unit maps to one +Cartesian unit in the `canvas'). In other situations, the true size +coordinate(s) will be scaled by additional affine transformation(s). + + + +A `screen' has a _crop mask_: rectangular (default), elliptical, or +diamond-shaped. If cropping is switched on in the active `screen', +added elements are cropped to the crop mask. For example, cropping by +the default crop mask in the `canvas' ensures the figure lies inside +the printed region allocated by `LaTeX'. + + The `crop' commands below affect the active `screen' only. Cropping +is not a "global" attribute, but must be set or unset explicitly for +each `screen'. By default, cropping is switched off. + + set_crop(); // activate cropping + set_crop(false); // deactivate cropping + crop_diamond(); // <>-shaped mask, set crop state + crop_ellipse(); // etc... + crop(); // crop active screen's contents + Normally the crop mask is inscribed in the `screen''s bounding box. +The commands `crop_diamond' and `crop_ellipse' also accept a pair of +`P' arguments, which are treated as corners of the crop box. + + The active `screen' may be decorated with a `border' (outline of +specified color and line width) and `backing' (solid fill color). The +crop mask determines the shape of the `border' and `backing'. + + border(color, len); + backing(color); + Identically-named member functions can be applied to an arbitrary +`screen' whether or not it is active: + + scr.crop_rectangle().backing(Blue(1.8)); + canvas().crop(); + + + +A _plane affine map_ has the form T(x) = Ax+b for some invertible +2\times2 matrix A and a constant vector b. `ePiX''s `affine' class +allows affine maps to be built and applied to `screen's' contents. + + An affine map is uniquely determined by the images of three +non-collinear points. The constructor returns the affine map sending +the points (1,0), (0,1), and (0,0) to `pt1', `pt2', and `pt0', +respectively. + + affine af(P pt1, P pt2, P pt0=P(0,0)); + To emphasize, the arguments are locations, not displacements, and the +image of the origin comes last. There is also a `void' constructor +(taking no arguments) which returns the identity map. + + To facilitate construction of affine maps, an existing `affine' may +be post-composed with a variety of "elementary" affine transformations. +In the commands below, `th' is an angle (in current units), `sc' is a +non-zero `double', and `ctr' is a point fixed by the composing +transformation. In each command, `ctr' defaults to (0,0). + + affine af; // the identity map + af.shift(P arg); // translate by arg + af.rotate(th, [ctr]); // counterclockwise rotation about ctr + af.reflect(th, [ctr]); // reflect across line through ctr + + af.h_scale(sc, [ctr]); // horizontal scaling + af.v_scale(sc, [ctr]); // vertical scaling + af.scale(sc, [ctr]); // dilatation + + af.h_shear(sc, [ctr]); // shear preserving horizontals + af.v_shear(sc, [ctr]); // shear preserving verticals + + af.invert(); // the inverse + af.postcomp(affine f); // post-compose with f + af(f); // pre-compose, af not modified + A non-invertible `affine' can be created _only_ by shearing or scaling +with an extremely large or extremely small argument, or by supplying +three collinear points to the constructor. Calling `invert' on a +non-invertible map merely issues a warning and performs no action. + + An `affine' may be applied to a `screen''s current contents. The +`screen' class has eight member functions (`shift' through `shear') +with syntax identical to the affine map functions. In addition, an +arbitrary `affine' may be applied to a `screen': + + scr.shift(arg); // shift scr's contents by arg; etc. + scr.apply(f); // apply f to scr's contents + To apply a composition of several maps to a `screen', it's best to +build an `affine' map by composition, then `apply' the map. Composing +`affine's is cheap; `apply'ing an `affine' is costly in proportion to +the number of elements in the `screen'. + + Applying an `affine' to a `screen' has no effect on the bounding +box, `border', or `backing', and may move elements outside the bounding +box even if cropping is active. To ensure a `screen''s contents lie +inside the bounding box, `crop' the `screen' _after_ `apply'ing the +`affine'(s). + + The sample file `inverse.xp' uses `affine' maps to depict branches +of inverse functions in one variable, `symmetry.xp' depicts the +permutation group S_3 by its action on a regular hexagon. + + +File: epix.info, Node: Drawing Attributes, Next: Creating and Drawing Objects, Prev: Scene Attributes, Up: Reference Manual + +3.5 Drawing Attributes +====================== + +`ePiX' maintains drawing states for filled regions, paths, and text +objects. + + + +Filling is either on or off. When filling is active, closed paths are +filled with the current _fill color_. + + fill(); // turn filling on + fill(color); // turn filling on, specify color + nofill(); // turn filling off, same as fill(false); + + + +Paths and borders of filled regions are drawn with two _pen_s, each +described by color and line width. The _line pen_ draws all path-like +objects. The _base pen_ does nothing unless it is wider then the line +pen, in which case it draws an "underlayer" or "border" on the line pen. + + pen(len); // set line pen width + pen(color); // set line color, keep width + pen(color, len); // set color and width + As usual, `len' may be either a length string or a `double', +interpreted as a width in `pt'. There are `base' functions with the +same signatures and analogous meanings for the base pen. + + The line width can be set with named declarations; the optional +argument sets the line color: + + plain([color]); // 0.4pt + bold([color]); // 0.8pt + bbold([color]); // 1.6pt + + + +By default, path-like objects are drawn with solid lines. Dashed, +dotted, and free-form path style patterns are also available. (The +`base' underlayer is always solid.) The page length of a pattern +defaults to 12 pt, but can be set. + + line_style(string); + dash_size(len=12); + The path style is set with a WYSIWYG string of dashes, spaces, and +periods, representing a pattern of dashes, gaps, and dots. In the +sample styles below, the repeating units have the same page size, 12 pt. +[Image] + + For brevity and uniformity, named commands are provided. + + solid(); "-" dashed(); "- -" dotted(); " . " + A sequence of n dashes, spaces, and dots corresponds to a dash/dot +pattern in an interval divided into n subintervals of equal length. If +the ith character is a dash or space, the ith subinterval is drawn +solid or empty, respectively. If the ith character is a period, a dot is +placed at the midpoint of the ith subinterval. + + This pattern is applied to a path-like object as follows. The page +length of each edge is divided by the current `dash_size' and the +ceiling (next largest integer) taken. This many copies of the current +path style are scaled onto the edge. The first and last characters are +adjacent in repeated units. + + There are three inequivalent ways to adjust the dash length/dot +spacing in a non-line path: Change the `dash_length', create a path +with a different number of points, or use a longer, repetitive pattern. +For best results, the style string should not be longer than about a +dozen characters. + + If you need several dashed/dotted line styles in multiple figures, +it's best to define a custom header instead of hard-coding line styles. +See Section *Note section:extensions::, for guidance. + + + +Two types of textual element may appear in a file: _labels_ (text +boxes) and _markers_ (`LaTeX' symbols). A marker occupies a box of zero +size, and is placed at a specified Cartesian location. A label has +typographical size, and is usually offset from its Cartesian location. +For placement, an _alignment point_ is attached to each label, and +Cartesian coordinates position the alignment point. + + + +A label is printed as a `LaTeX' box. By default, the alignment point +is its reference point, the intersection of the left edge and the +baseline, which is used by `LaTeX' to position the box on the +page:[Image] + + The alignment point may be _offset_ manually by a specified number +of `pt'. Additionally, a label's location with respect to the alignment +point can be chosen with an optional `LaTeX'-style alignment option. +This scheme allows labels to be placed easily where they will not +overlap other parts of the figure, and ensures labels stay properly +positioned when the size or aspect ratio of a figure changes. + + label(P posn, P offset, string msg, [align]); + label(posn, msg); + The first two components of the `offset' argument are numbers of `pt' +to shift the alignment point right and up. The optional `align' +argument may be one--or an appropriate pair--of `t', `b', `r', or `l' +(top, bottom, right, left), or `c' (center). These alignment options +specify the position of the label _relative to the Cartesian location_ +`posn', namely they work _opposite_ to the way they work in `LaTeX'. +[Image]\qquad [Image] + + The `msg' argument is usually a snippet of `LaTeX' code enclosed in +double quotes. `C++' treats "\" as an escape character, so a double +backslash is needed in the source to get a single backslash in the +output. For example, + + label(P(0,0), P(2,-1), "$\\rho = \\sin\\theta$", br); + positions an alignment point `2pt' right and `1pt' below the +(Cartesian) origin, and typesets the equation \rho=\sin\theta below and +to the right. + + Labels can be rotated; the (counterclockwise) angle is set in current +angle units with the command `label_angle(theta)'. For example, a +rotation angle of 90 degrees prints labels along a vertical axis. +Though label rotation has legitimate uses, it can make labels more +difficult to read, defeating their purpose. Do not use rotated labels +merely because they are available. As a practical matter, if an output +file contains rotated labels, the enclosing document must use the +`rotating' package. `elaps' automatically loads this package. + + An `affine' behaves moderately intelligently when acting on a marker +or label. The mapping is applied to the label's location, and the +"linear part" is used to adjust the offset and label angle. No attempt +is made to treat alignment. For best results, if a `screen' will have +an `affine' applied to it, label positions should be fine-tuned only +with offsets, not alignment arguments. In all situations, the font +itself is unchanged; no attempt is made to print sheared, scaled, or +reflected text. The sample file `inverse.xp' illustrates the effect of +affine maps on labels. + + + +By default, the font in an `ePiX' figure is that of the enclosing +document. The font size and face are changed with "declaration-style" +commands such as + +font_size("Large"); +font_face("sc"); + The argument of font_size is a valid `LaTeX' size. If no argument is +given, `normalsize' is understood. font_face accepts a two-letter +string, appended to the string "`text'" to give a `LaTeX' font +declaration command ("`textsc'" above). Finer-grained control is +accomplished by placing `LaTeX' commands into the label text. + + + +Each label command has a corresponding "mask" version (`masklabel') +that draws an opaque rectangle under the label text. The mask size +exceeds the label's size by an amount of _padding_, and the mask is +itself surrounded by a rectangular _border_, of specified color and +width. + + label_color(color); // set label text color + label_mask(color=White()); // set mask color + label_pad(string len); + + label_border(color, [len]); // set color (and line width) + label_border(len); // set line width only + no_label_border(); // turn off label borders + + + +`ePiX''s marker types, listed in Table *Note table:marker::, , are +obtained with the command marker(P pt, <MARKER TYPE>); Several +"dot-like" marker types are available by name: [Image] + + spot(P pt); dot(P pt); ddot(P pt); + --- box(P pt); bbox(P pt); + ring(P pt); circ(P pt); --- + A `circ' is filled with the current `mask_color', and a `ring' is +"hollow". Each dot-like marker can also be called with label syntax, +generating a labeled marker with one command. + + dot(P posn, offset=P(0,0), msg="", align=none); // etc. + + By default, `spot' and `ring' are 4 pt in diameter; `dot', `box', +and `circ' are 3 pt in diameter; `ddot' and `bbox' are 2 pt in +diameter. At arbitrary diameter, a `spot' is 4/3 the diameter of a `dot' +and a `ddot' is 2/3 the diameter. The command `dot_size(diam=3)' sets +the diameter of a `dot', and hence the size of all dot-like markers. + + +[Image] + +Table[tb] + + + +When constructing and placing a label, + * Offsets are specified in `pt' (true length), not Cartesian + units: A label's location relative to its alignment point should + not depend on the logical or printed size of the figure. + + * The label text is enclosed in double quotes (the single + character `"'), and contains the `LaTeX' code to generate the + label. Backslashes are doubled. + + + +Old-style color declarations set the fill color, line color, and text +color. + + rgb(r, g, b); cmyk(c, m, y, k); + rgb(P); cmyk(P); // for function-controlled colors + red(d); // similarly for other primaries + + + +File: epix.info, Node: Creating and Drawing Objects, Next: More About `C++', Prev: Drawing Attributes, Up: Reference Manual + +3.6 Creating and Drawing Objects +================================ + +Scene elements include geometric objects, coordinate grids, axis +labels, and function plots. A few commands create an object (a point, +line segment, circle, sphere, or plane) that can be used in subsequent +computations, but most drawing commands automatically create, draw, and +discard objects. + + + +The simplest object in the world, and by far the most common named data +structure, is `P', an ordered triple of real numbers (double-precision +floats). The function `P(x1,x2,x3)' creates the point (x_1,x_2,x_3). If +only two arguments are provided, x_3=0 by default. This convention +allows `ePiX' to treat 2- and 3-dimensional figures uniformly. The +standard basis is available: `E_1=P(1,0,0)', etc. + + Depending on context, a `P' may represent either a _location_ +(point) or a _displacement_ (vector). Almost all `ePiX' functions treat +a `P' as a point. However, algebraic operators and commands that plot +vector fields treat `P' arguments as displacements. + + Polar, cylindrical, and spherical coordinate `P' constructors are +sensitive to the current angular mode. + + P pt=polar(r,t); // (r*Cos(t), r*Sin(t), 0) + P pt=cis(t); // (Cos(t), Sin(t), 0) = polar(1, t) + P pt=cyl(r,t,z); // (r*Cos(t), r*Sin(t), z) + P pt=sph(r,t,phi); // polar(r,t)*Cos(phi) + (0,0,r*Sin(phi)) + + Algebraic operations--addition/subtraction, scalar multiplication; +scalar, cross, and componentwise products; orthogonalization--can be +performed on `P's. In compound expressions, the binary operators below +should be enclosed in parentheses, and scalars must be collected at +left, `P's at right. + + double u=pt.x1(); // first coordinate of pt, etc. + P(a,b,c)|P(x,y,z); // scalar product, ax+by+cz + P(a,b,c)&P(x,y,z); // componentwise product (ax, by, cz) + P(a,b,c)*P(x,y,z); // cross product (bz-cy, cx-az, ay-bx) + J(p); // quarter turn about the x3-axis + p%q; // orthogonalization, p (mod q) + Explicitly, `p\%q' is the unique vector `p+k*q' perpendicular to `q'. + + `P' operations express mathematical relationships, and therefore +imbue a figure with logical structure, making the input file easier to +read, modify, and maintain. Commonly, a file preamble will define a few +named points with hard-coded coordinates, then define additional points +of interest using `P' operators. + + + +In addition to `P', objects of type `Circle', `Plane', `Segment', and +`Sphere' can be used for Euclidean geometry constructions. Simple +affine operations are supplied for each type, as is a `draw()' +function, which represents the object as a path in the screen. + + obj.shift(P arg); // translate by arg + obj.move_to(P arg); // move center to arg + obj.scale(double c); // scale about center by c + obj.draw(); + A `Segment''s "center" is its midpoint. A `Plane' has no center; +`move_to' translates the `Plane' to pass through `arg', and `scale' has +no effect. + + A `Circle' data structure consists of a center, radius, and a +perpendicular unit vector. Three constructors are provided: + + Circle(center=P(0,0,0), double rad=1, normal=E_3); + Circle(P center, P point); + Circle(P p1, P p2, P p3); + The second constructor creates the `Circle' parallel to the (x_1,x_2) +plane, with given center, and radius equal to the distance between the +arguments. (A warning is printed if the second argument does not lie on +the circle, namely, if the arguments do not lie in a plane parallel to +the (x_1,x_2) plane.) The third returns the `Circle' passing through +the given points; the points must not be collinear. + + The data defining a `Circle' are recovered with member functions +named `center()', `radius()', and `perp()'. + + A `Plane' is specified by a point and normal vector, or by three +non-collinear points. The `draw()' function clips the plane and draws +the resulting polygon. Unless the clip box has been set manually, the +clipped polygon's vertices will have large coordinates. + + A `Segment' is constructed from its endpoints. The member function +`midpoint()' returns the center. + + A `Sphere' is specified by a point and a radius--by default the +origin and unity, or by the center and a point on the sphere. Member +functions `center()' and `radius()' return the defining data. +Capabilities specific to geography and spherical geometry are described +below, pp. *Note non-eucl::ff. + + The `draw()' function of a `Sphere' draws the horizon visible from +the current viewpoint. While this horizon is a circle in object space, +its image in the screen is generally an ellipse. Antipodal points are +not generally mapped to points symmetrically placed with respect to the +center of this ellipse. These effects are most pronounced when the +viewpoint is close to the `Sphere' and the center is not close to the +`target'. + + + +To facilitate geometric computation, `ePiX''s `Circle', `Plane', +`Segment', and `Sphere' classes can be intersected with the `*' +operator. + + A `Circle' has a center, radius, and unit normal; a `Plane' has a +distinguished point and unit normal; a `Segment' has two endpoints; a +`Sphere' has a center and radius. An object is _malformed_ if these +conditions are not met. The constructors return well-formed objects +with two exceptions: `Circle' and `Plane' create malformed objects if +called with three collinear points. The operator `*' returns a +malformed object if either argument is malformed, or if the operands +are disjoint, tangent, or coincident. Malformedness is benign: Calling +`draw()' on a malformed object does nothing. + + + +A `frame' comprises three mutually perpendicular unit vectors. The +constructor takes three vectors. The `frame''s third vector e_3 is +positively proportional to `v3', the second vector e_2 is positively +proportional to `v2\%v3', and the first is the cross product, +e_1=e_2\times e_3. Thus, a `frame' is right-handed, and does not depend +on `v1'. + + The elements of a `frame' are named `sea', `sky', and `eye', just as +for the `camera'. A `frame' can be rotated through an arbitrary angle +about any of its elements. + + frame(); // the standard basis {E_1, E_2, E_3} + frame fr(v1, v2, v3); // orthonormalize {v1, v2, v3} + fr.sea(); // the first element of fr, etc. + fr.rot1(theta); // rotate fr through theta about sea, etc. + + + +Basic path-like objects are drawn with named commands. Arguments of +polygon commands are endpoints/vertices. Except for `line' and `Line', +the following are subject to filling. + + line(P p1, P p2, [double expand]); + Line(p1, p2); // draw line through p1, p2 (crop required) + triangle(P p1, P p2, P p3); + rect(P p1, P p2); + quad(P p1, P p2, P p3, P p4); // quadrilateral + circle(ctr=P(0,0,0), rad=1, normal=E_3); + circle(ctr, pt); + circle(pt1, pt2, pt3); + The optional `line' argument is an expansion parameter: +`line(p1,p2,t);' draws a segment centered at the midpoint of `p1' and +`p2', with length scaled by 2^t/100. (Setting t=100 doubles the length, +while t=-100 halves the length.) The arguments of `rect()' must lie in +a plane parallel to a coordinate plane. The arguments to `circle' +commands are the same as for `Circle' constructors. + + Quadratic and cubic splines are described by their control points. A +list of `P' is drawn as a "natural" spline (the C^2 piecewise cubic +curve with vanishing second derivatives at the endpoints); the number +of points per cubic segment must be specified. Circular and elliptical +arcs are given by center, a basis, angular range, and an optional +number of intervals. + + spline(P p1, P p2, P p3, [int n]); // quadratic + spline(P p1, P p2, P p3, P p4, [int n]); // cubic + spline(vector<P>, int n); // natural spline + + arc(P ctr, rad, t_min, t_max); // parallel to (x1,x2)-plane + ellipse(P ctr, P v1, P v2); // in plane spanned by v1, v2 + ellipse(P ctr, P v1, P v2, t_min, t_max, [int n]); + If parameter bounds are omitted in an `ellipse' command, the entire +ellipse is drawn. When the angular range subtends one or more full +turns in an `arc' or `ellipse' the curve is subject to filling. + + Commands for planar (half-)ellipses remain from `ePiX''s early days: + + ellipse(P ctr, P radius); + ellipse_left(P ctr, P radius); + ellipse_right(P ctr, P radius); + ellipse_top(P ctr, P radius); + ellipse_bottom(P ctr, P radius); + If `radius' is `P(a,b)', these commands draw all or half of the +ellipse with given center in the (x_1,x_2) plane, axes parallel to the +coordinate axes, and axis lengths 2a and 2b. + + Two commands are available to mark off right angles or a subtended +angle. Each accepts a spatial location and two non-zero directions, and +draws a scene element in the plane spanned by the vectors. + + right_angle(P loc, P v1, P v2, scale=8); + arc_measure(P loc, P v1, P v2, scale=8); + arc_measure(P loc, P v1, P v2, offset, text, align, scale=8); + The `right_angle' command does not check its arguments for +perpendicularity. The `arc_measure' commands mark the _small_ angle +subtended by the directions; the label form places a label at the +midpoint of the arc. The (optional) `scale' argument is the true size +in `pt' of the marker. + + + +Consider a path made up of equal-length segments that can point at any +angle of the form 2\pi k/n radians, for 0\leq k<n, like spokes on a +wheel. A path is specified by a finite sequence of integers, taken +modulo n. For example, if n=6, then the sequence 0, 1, -1, 0 corresponds +to the ASCII path _/_. `ePiX''s fractal approximation starts with such +a "seed" then recursively (up to a specified depth) replaces each +segment with a scaled and rotated copy of the seed, Figure *Note +fig:fractal::, . The seed above generates the standard von Koch +snowflake fractal. In code: + + const int seed[] = {6, 4, 0, 1, -1, 0}; + fractal(P(a,b), P(c,d), depth, seed); + The first entry of `seed[]' (here 6) is the number of "spokes" n, the +second (4) is the number of terms in the seed, and the remaining +entries are the seed proper. The final path joins (a,b) to (c,d). The +number of segments in the final path grows exponentially in the depth, +so depths larger than 5 or 6 are likely to exceed the capabilities of +`LaTeX' and/or PostScript. + +[Image] + +Figure[hbt] + + + +Line segments, splines, and arcs can be drawn with arrowheads at one +end. In profile, an arrowhead's width is `3pt', and its height is 5.5 +times the width. The actual printed height depends on the head's +orientation with respect to the camera. By default, an arrowhead is a +filled triangle. The shape and size are adjusted with declarations: + + arrow_width(w=3); // width in pt + arrow_ratio(r=5.5); // height-to-width + arrow_inset(c=0); // base indent as frac of ht + [Image]\qquad [Image]\qquad [Image] \\ The `inset' must be between -1 +and 1. Each `arrow' command accepts an optional `scale' argument, which +scales the arrowhead. + + arrow(P tail, P tip, [scale]); + arrow(P p1, P p2, P p3, [scale]); // spline arrows + arrow(P p1, P p2, P p3, P p4, [scale]); + arrow(P ctr, P v1, P v2, t_min, t_max, [scale]); // ellipse + A few "special-purpose" commands are supplied: + + dart (P p1, P p2); // same as arrow(p1, p2, 0.5); + aarrow(P p1, P p2); // double-headed arrow <---> + arc_arrow(ctr, rad, t_min, t_max, [scale]); + If an `arc_arrow' is too short, nothing is drawn. + + + +`ePiX' provides an `axis' class for coordinate axes. Labels are +generated automatically in a variety of styles: decimal, scientific +notation, fraction, and trigonometric fraction. Logarithmic axes and +labels are available. Axis and labeling commands from Version 1.0 have +been retained. + + + +An `axis' consists of a line segment divided into a specified number of +equal-length subintervals by "major" (long) tick marks. Each +subinterval may be divided further by "minor" (short) tick marks. +Minor ticks may be equally-spaced ("Cartesian") or logarithmically +placed. Finally, a label is written at each major tick mark with +specified offset and alignment. Labels are generated automatically from +the endpoints, so the line should be parallel to a coordinate axis. +Label attributes (masking, borders, font size and face, rotation angle) +are determined by the current label style, not by the `axis'. + + The command + + axis(P tail, P head, int n, P offset=P(0,0), [align = none]); + creates an axis joining `tail' to `head', divided into `n' segments of +equal length, with a major tick mark and label at each division point +and endpoint. The `offset' and `align' arguments have the same meaning +as for ordinary labels. + + The number and length of minor ticks, and the alignment of ticks, are +controlled with member functions: + + axis Ax(P(a,c), P(b,c), n); + Ax.subdivide(n); // put n-1 minor ticks in each axis segment + Ax.tick_ratio(r); // minor length = r*major length + Ax.align(AL=c); // align all ticks; AL = t, b, l, r, or c + By default, major ticks are `6pt' long and twice the length of minor +ticks. The global declaration `tick_size(len)' sets the major length, +subject to "reasonable stylistic limits". For visual consistency, tick +lengths should not be changed casually. + + Labels on an `axis' may be drawn in several styles, selected with +member functions: + + Ax.dec(); // decimals (default) + Ax.frac(); // fractions, e.g. 0.5 -> \frac{1}{2} + Ax.trig(); // fractional multiples of \pi + Ax.sci(); // scientific notation, k\times base^N + + Ax.unmark(double); // remove label at selected location + Ax.precision(p); // set number of digits for decimal labels + Ax.align_labels(AL); // re-align labels + Arbitrary textual labels depending on one coordinate are obtained by +writing a `string'-valued function of `double' and "registering" it: + + // f represents x as a string in given precision and base + std::string f(double x, unsigned int prec, unsigned int base); + Ax.label_rep(f); + For example, textual tags can be printed instead of numeric labels. + + By default, an `axis' is Cartesian. The member function `log(int +b=10)' converts an `axis' to "log mode" with specified base; this +affects both tick marks and labeling. If `b' is at least 3, minor tick +marks appropriate for a logarithmic axis base `b' are drawn. Second, +labels are written in decimal or scientific notation appropriately for +a logarithmic axis; that is, "k\times b^N" (or its decimal value) is +written at location N+\log_b k. + + Minor ticks of a log `axis' may be labeled individually; again, this +is controlled with member functions: + + Ax.tag(d); // labels at N+log_b(d) + Ax.tag235(); // tag 2, 3, and 5 if b=10 + Ax.tags(); // tag 1, ..., b-1 + Ax.untag(); // remove all tags, including 1 + Ax.untag(double); // remove one tag, e.g. Ax.untag(9); + + For convenience, an `axis' object along an edge of the active +`screen' can be created with a named command: + + top_axis(n, offset, align); + bottom_axis(n, offset, align); + left_axis(n, offset, align); + right_axis(n, offset, align); + The ticks automatically point into the bounding box. + + The functions above create objects or set `axis' attributes, but +write no output. Tick marks and labels can be printed separately, or at +once: + + Ax.draw(); // axis, tick marks, and labels + Ax.draw_ticks(); // axis and ticks only + Ax.draw_labels(); + + + +`ePiX' formerly supplied commands for drawing simple axes and their +labels. These commands have been kept for compatibility. Horizontal +axes are generated with + + h_axis(p1, p2, n, align=c); // n subintervals (n+1 ticks) + h_log_axis(p1, p2, n, align=c, base=10); + For vertical axes, use `v_axis'. The style of tick mark is +appropriate for an axis of the given type. Horizontal axis tick marks +may be aligned `t' (above the axis) or `b' (below). Similarly, vertical +axis ticks may be aligned `r' or `l'. + + The endpoint arguments of a coordinate axis may be omitted, in which +case they default to p_1=(x_min,0) and p_2=(x_max,0) for a horizontal +axis, or to p_1=(0,y_min) and p_2=(0,y_max) for a vertical axis. If the +bounding box has integer width and/or height, omitting the number of +points draws tick marks one unit apart. + + Labels for a horizontal Cartesian or logarithmic axis are generated +with the commands + + h_axis_labels(P p1, P p2, int n, P offset, [align]); + h_axis_masklabels(p1, p2, n, offset, [align]); + h_axis_log_labels(p1, p2, [n], offset, [align], base=10); + h_axis_log_masklabels(p1, p2, [n], offset, [align], base=10); + Labels for a vertical axis are generated with `v_axis_labels', etc. +The labels are automatically generated to match their horizontal +location. The first puts (n+1) evenly-spaced labels on the segment +joining `p1' and `p2'. As with ordinary labels, the `offset' is in +`pt', and the optional `LaTeX'-style alignment option positions the +labels using their corners. The second command draws masked labels +according to the current label masking attributes. The third writes +labels in exponential notation, using the Cartesian coordinate as +exponent. + + As for coordinate axes, the initial and final points may be omitted +in an `axis_[mask]labels' command, with the same defaults. The +`offset' and number of labels must always be specified. + + + +Broken axes are best drawn using page layout, especially if axis labels +are to be drawn. To accomplish the task, create a screen for each piece +of axis, using appropriate Cartesian coordinates for the corners, then +`inset' the screens so the axis pieces are nearly end to end. A zig-zag +glyph signifies the break: + + axis_break(P, P, scale=12); + The `P' arguments are the screen coordinates of the ends to be joined; +the optional third argument is the true height and width in `pt' of the +glyph. The sample file `coord_tricks.xp' uses layout and axis breaks. + + + +Cartesian grids fill a coordinate rectangle, and have a specified +number of lines in each direction. A polar grid has specified radius, +and numbers of rings and sectors. + + grid(n1, n2); // fills the bounding box + grid(p1, p2, n1, n2); // fills the box with corners p1, p2 + polar_grid(r, n1, n2); + + Log and semi-log grids are drawn with analogous syntax: + + log_grid (p1, p2, n1, n2, [base1], [base2]); // log-log + log1_grid(p1, p2, n1, n2, [base]); // log-lin + log2_grid(p1, p2, n1, n2, [base]); // lin-log + The n_i arguments dictate the number of squares, namely the number of +orders of magnitude spanned in the logarithmic direction(s). The +(optional) base arguments default to 10, and control the number of +lines drawn per order of magnitude. As with Cartesian grids, the +corners are optional; if omitted, the grid fills the bounding box. + + Graph paper may be created by superimposing grids: + + pen(0.25); + grid(10*xsize(), 10*ysize()); + pen(0.5); + grid(2*xsize(), 2*ysize()); + pen(1); + grid(xsize(), ysize()); + + + +A `path' data structure is an ordered list of points that can be +cropped, clipped, mapped, concatenated, and drawn. The first four +constructors mirror polygon-drawing commands above. Function graphs +and parametric paths are built from a real- or `P'-valued function `f' +of one variable. + + path(p1, p2, expand=0); // line (endpoints) + path(p1, p2, p3, [n]); // quadratic spline + path(p1, p2, p3, p4, [n]); // cubic spline + path(p1, v1, v2, t_min, t_max, [n]); // ellipse + path(f, t_min, t_max, [n]); + + The member function `pt()' accepts a `P' or three (or two) doubles +and appends the specified point to a `path'. This snippet creates a +regular n-gon: + + path ngon; // declare new path + for (int i=0; i<=n; ++i) + ngon.pt(cis(i*full_turn()/n)); // works in all angle modes + Compound paths may be built by concatenation. If `path1' and `path2' +share an endpoint, the commands + + path1 += path2; + path1 -= path2; + replace `path1' with the result of traversing `path1' "forward", then +following `path2' in the forward or reverse direction (respectively). +For expected results, the first (or last) point on `path2' should be +the last point of `path1'. The notation suggests 1-dimensional homology +chains. The sample file `contour.xp' illustrates path creation and +manipulation. + + A `path' is a data structure, and must be drawn explicitly to create +visible output. By default a `path' is not a closed loop (even if the +first and last points are the same), and is not filled when drawn. +Member functions perform these tasks. Continuing the n-gon snippet +above, + + ngon.close(); // mark path as closed + ngon.fill(); // draw filled region if filling is active + ngon.draw(); // print to the screen + `path::close()' adds a closing edge if necessary. Once a `path' is +closed, no more points can be added. A closed path clips and crops +differently than an open `path' with the same data. `path::fill()' has +no effect on an unclosed `path'. + + + +The noun "map" refers to a `C++' function that accepts one or more +`double' arguments and returns a `double' or a `P'. Mathematically, a +map can be depicted in two ways: as a graph (which retains information +about the domain), or as a parametrized curve or surface (which +discards domain information). `ePiX' assumes that `double'-valued maps +are graphed and `P'-valued maps are drawn parametrically. Either sort +of depiction is called a "plot". `ePiX' plots are either "wire mesh", +produced by a `plot' command, or "shaded", produced by a `surface' +command. + + + +For the moment, "function" means "function of one variable" (precisely, +a `double'-valued function of a `double' variable). A function graph +depends on the domain and the number of points to use. Each of the +commands + + plot(f, t_min, t_max, n); + polarplot(f, t_min, t_max, n); + shadeplot(f, t_min, t_max, n); + graphs the function `f' on the interval `[t_min, t_max]' by dividing +the interval into `n' subintervals of equal length. The first gives a +Cartesian plot, the second a polar plot with bounds in current angular +units, the third shades the region between the graph and the horizontal +axis. If two functions are given to `shadeplot', the region between +their graphs is shaded. + + + +An `ePiX' `domain' is a coordinate box of dimension one, two, or three, +specified by a pair of opposite corners and two _meshes_ ("coarse" and +"fine", respectively) which specify the amount of data to be plotted. +Plotting is explained in detail below. + + // [a1,a2] x [b1,b2]: n1 x n2 rectangles, m1 x m2 intervals + domain R2(P(a1,b1), P(a2,b2), mesh(n1,n2), [mesh(m1,m2)]); + + // [a1,a2] x [b1,b2] x [c1,c2] divided analogously + domain R3(P(a1,b1,c1), P(a2,b2,c2), + mesh(n1,n2,n3), [mesh(m1,m2,m3)]); + If unspecified, the fine mesh is the same as the coarse mesh. For +expected behavior, the coarse mesh should "divide" the fine mesh, in +that m_i should be a (usually small) integer multiple of n_i for each i. + + A `domain' may be _resized_ in any coordinate for which the +thickness is positive, and can be _sliced_ by setting one variable to a +constant. The result of slicing is a `domain' whose dimension is one +smaller than the original. Finally, "`slices'" operators return the +list of `domain's obtained by setting one variable to evenly-spaced +constants. By default, the number of slices is specified by the coarse +mesh. An optional argument specifies the number of slices. This +argument need not be related to the coarse mesh. + + R2.resize2(a,b); // [a1,b1] x [a,b] + R2.slice1(t); // set x1 = t + R3.slices3([n]); // (n+1) domains with x3 = const +[Image] + + \smallskip When possible, resizing preserves grid square sizes. +Generally, though, integer truncation occurs: If `R=domain(P(0,0), +P(1,1), mesh(10,6))', then `R.resize1(0,0.25)' is the rectangle +[0,0.25]\times[0,1] subdivided into 2\times6 subrectangles, since +10\div4=2 in integer arithmetic. For expected behavior, choose mesh +sizes to avoid integer truncation. + + The arguments of a `plot' command are a map, followed by either a +domain or its logical equivalent. + + double f(double t) { return t*t; } + P F(double u, double v) { return P(u, v, exp(u)*Sin(v)); } + P G(double u, double v, double w) { return P(v*w, u*w, u*v); } + + plot(f, a, b, n); // f:[a,b] -> R, using n intervals + plot(F, R2); // graph of exp(u)*Sin(v) + plot(G, R3.slice2(0.5); // G: R^3 -> R^3 restricted to y=0.5 + By (compiler-enforced) convention, `plot' commands involving a +`P'-valued map accept a `domain' argument, as in the second and third +commands above. To plot a `double'-valued function, by contrast, supply +the logical equivalent of a `domain', usually the endpoints and the +number of intervals, as in the first `plot' command above. + + Resizing and slicing allow a map `F' to be plotted selectively over +parts of its domain. This can be used to emphasize parts of the image, +layer scene elements, patch surfaces together, and so forth. Resize +and slice(s) commands may be used directly in a `plot' command: + + plot(F, R2.resize1(0,0.5)); + plot(F, R2.slices1()); + + + +The `P' arguments of a `domain' are a pair of opposite corners. The +first `mesh' argument, the _coarse_ mesh, specifies the number of +subdivisions in each coordinate direction. The second `mesh', the +_fine_ mesh, determines the number of points used in each direction +when plotting. + + Separating the roles of coarse and fine meshes allows a plot to +conform closely to a surface without using a fine grid of curves. Both +parts of Figure *Note fig:plot::, are drawn with a 6\times20 coarse +mesh. In the first picture, the fine mesh is also 6\times20, while in +the second, the fine mesh is 12\times60. + + +[Image] [Image] + +Figure[hbt] + + The coarse mesh is significant only for domains of dimension at +least 2. The coarse mesh's size determines the number of curves or +surfaces plotted _perpendicularly_ to a coordinate direction, while the +fine mesh's size determines the number of segments used _along_ that +direction. For predictable results, the fine mesh should be a small +multiple of the coarse mesh. + + Plotting works analogously for 3-dimensional `domain's and maps +depending on three variables: The "one-dimensional skeleton" of the +`domain''s image is drawn. A `P'-valued map of three variables can be +plotted over a 1- or 2-dimensional `domain'. (The effect may be +unexpected unless the domain arises by slicing, however.) A map +depending on one or two variables cannot be plotted over a +3-dimensional `domain'. + + + +`ePiX''s shaded surface plotting implements a degree of hidden surface +removal. The algorithm breaks a surface into mesh fragments, sorts them +in decreasing (approximate) distance to the camera, and prints them. +If filling is active, a mesh fragment is shaded according to the angle +between the normal vector and the direction to the camera, simulating +constant ambient lighting; otherwise, the current fill color is used. +This technique works fairly well for surfaces without intersection, and +even acceptably handles intersecting surfaces for which mesh elements +intersect only along boundaries. + + The syntax of a `surface' command is identical to a `plot' command +when only a single surface is drawn. For example, + + surface(F, R, cull=0); + plots the `P'-valued function `F' over the domain `R', the shaded +equivalent of the corresponding `plot' command. The optional `cull' +argument removes elements that point toward (`cull=-1') or away from +(`cull=1') the camera. Naturally, orientation of mesh elements depends +on the parametrization `F', not merely on the surface. Culling reduces +the output file size, but is useful mostly for closed, convex surfaces. + + There are special commands for surfaces of rotation; each accepts a +final `cull' argument. + + surface_rev(f, t_min, t_max, n_lats, n_longs); + surface_rev(f, g, t_min, t_max, n_lats, n_longs=24); + surface_rev(f, g, R, frame coords); + The first revolves the graph of f about the x-axis, the second uses +the parametric curve t\mapsto\bigl(f(t),g(t)\bigr) as profile. In each +case, the parameter interval [t_min,t_max] is divided into n_lats +equal-length subintervals, n_longs copies of the profile curve are +drawn, and the complete surface (one full turn) is drawn. + + The third form uses a `domain' to control the range of longitudes, +and draws a surface of rotation in the Cartesian coordinate system +defined by the orthonormal basis `coords', by default the standard +basis. The arguments `f' and `g' define a parametric curve in the plane +spanned by the first two elements of `coords', and the first element is +the axis of rotation. + + As in wire mesh plotting, the fine mesh is used to draw the +boundaries of surface patches; this tends to make surfaces look +smoother for modest-sized coarse meshes. If the coarse mesh is too +coarse, however, two visually undesirable effects can occur. First, +adjacent regions of the surface may be shaded very differently, since +shading is constant over patches defined by the coarse mesh. Second, a +patch nearly tangent to a line of sight may be drawn badly if the patch +bends back on itself, since the boundary of the _patch_ is drawn, not +the visible edge of the mathematical surface. See +`samples/artifacts.xp'. + + + +A scene containing two or more shaded surfaces cannot generally be +built up one surface at a time. Instead, multiple surfaces must be +assembled into a single data structure before they can be drawn. +Multiple surfaces are built from one or more maps and one or more +2-dimensional `domain's. In the code snippets below, `F' and `G' are +`P'-valued functions of 3 variables, and `R' is a 3-dimensional +`domain'. + + To plot the images of several `domain's under a _single map_, +assemble the `domain's into a list if necessary, then issue a `surface' +command: + + surface(F, R.slices3(), cull=0); + + domain_list DL(R.slice1(0)); // build domain list + DL.add(R.slice2(0.5)); // add a domain, etc. + surface(G, DL, cull=0); // draw + For multiple maps, `ePiX' provides the `scenery' class. Conceptually, +`scenery' is an agglomeration of shaded surfaces, built one surface at +a time from maps and 2-dimensional `domain's. The `add' function +accepts two arguments--a map, and either a `domain' or a list of +`domain's--and contributes its data to the `scenery' rather than +plotting immediately. Completed `scenery' is drawn manually. + + scenery S(F, R.slice3(0.25)); // S contains one surface + S.add(F, R.slice2(0)); // S contains two surfaces + S.add(G, R.slices1(3)); // S contains six surfaces + S.draw(cull=0); + Complete examples are included in the `samples' directory: +`spherical.xp' and `minkowski.xp'. + + In principle, a scene may contain arbitrarily many surfaces. However, +figures that contain many objects tend to tax `LaTeX''s internal +stacks. Frequent color changes exacerbate the problem. Even if you use +`hugelatex' (or increase `LaTeX''s memory), a figure containing more +than a few thousand mesh elements is unlikely to compile. At moderate +resolution, a surface can easily contain 1000 patches. Each shell +script has a command-line option to invoke `hugelatex'; your mileage +may vary. + + + +By default, a `surface' or `scenery' is colored according to the +current fill color. For finer control, each `surface', `surface_rev', +and `scenery' command accepts an optional position-dependent `color' +specification. + + surface(F, R, color, cull=0); + surface_rev(f, [g], t_min, t_max, n_lats, n_longs, color); + surface_rev(f, g, R, color, [coords]); + + scenery S(F, R, color); + S.add(F, R, color); + The `color' argument is a `P'-valued function of two or three +`double's whose output is interpreted as a set of `RGB' densities. If +`color' takes two arguments, they are `domain' coordinates, and the +surface is colored according to parameter values. If `color' takes +three arguments, they are Cartesian coordinates, and the surface is +colored according to spatial location. Please see the sample files +`surface_shade.xp' and `S2_harmonics.xp'. + + + +`ePiX' provides high-level commands for plotting derivatives and +definite integrals, Riemann sums, tangent lines, slope- and vector +fields, and solutions of planar and spatial systems of differential +equations. + + In this section, `f' and `g' are `double'-valued functions of one +variable. + + + + + sup(f, a, b); // max/min of f on [a,b] + inf(f, a, b); + newton(f, g, x0); // find approximate crossing point + Newton's method returns the crossing point of the given functions, +starting from the specified seed, which should be reasonably close to +the expected solution. If a critical point is hit or 5 iterations pass, +a warning is issued and the current result (probably incorrect) is +returned. The second function g defaults to the zero function if +omitted. + + + +The classes `Deriv' and `Integral' are used to calculate values of +derivatives and integrals, and to plot these functions. + + Deriv df(f); // function object: df(x) = f'(x) + df.eval(t); // return f'(t) + df.left(t); // deriv from left at t: (f(t)-f(t-dt))/dt + df.right(t); // deriv from right at t: (f(t+dt)-f(t))/dt + + Integral prim(f,a); // function object: prim(x) = int_a^x f + prim.eval(b); // numerical integral of f over [a,b] + double val(Integral(f).eval(1)); // val = \int_0^1 f + The lower limit on an integral is 0 by default. `Deriv's and +`Integral's can be used directly in a `plot' command: + + plot(Deriv(f), a, b, n); // plot f' over [a,b] + plot(Integral(f, x0), a, b, n); + riemann_sum(f, a, b, n, TYPE); + The second graphs the definite integral x\mapsto\int_x_0^x f(t)\,dt +over [a,b]. As above, x_0 defaults to 0. The third draws rectangles or +trapezoids whose area approximates the definite integral of f over +[a,b]. The `TYPE' may be `UPPER', `LOWER', `LEFT', `RIGHT', `MIDPT', or +`TRAP'. + + Tangent lines and envelopes (families of tangent lines) are drawn +with + + tan_line(f, t); // f real- or vector-valued + envelope(f, t_min, t_max, n); // family of tangent lines + tan_field(f, g, t_min, t_max, n); // field of tangents + The sample files `conic.xp' and `lissajous.xp' illustrate these +features. + + + +Let `F' be a `P'-valued function of two or three variables. + + ode_plot(F, p_0, t_min, t_max, n); + flow(F, p_0, t_max, n); + The first plots the solution curve of the initial-value problem +\dotx=F(x), x(0)=p_0, over the specified time interval. If t_min is +omitted, its value is 0, so the curve starts at p_0. With manual +calculation to rotate a planar field a quarter turn, `ode_plot' can be +used to draw level curves (isobars) of a function of two variables; see +the sample file `dipole.xp'. The `flow' function returns the result of +starting at p_0 and flowing by F for time t_max, using Euler's method +with n time steps. This is useful for placing markers or arrowheads +precisely along a flow line. + + A planar or spatial vector field itself may be plotted over a domain +`R' in three styles: + + vector_field(F, R, [scale]); // true length + dart_field (F, R, [scale]); // const length + slope_field (F, R, [scale]); // const length + The field is sampled at the grid points of the coarse mesh. If the +domain is 2-dimensional, the plot is a planar slice of the field, even +if the field depends on three variables. If the domain is +3-dimensional, the field is drawn in successive slices x_3=const, +starting at the height of the first corner of `R' and ending at the +height of the second corner. + + The optional final argument, which defaults to 1, scales the +arrowheads in a vector field, and scales the (constant) length of field +elements for slope and dart fields. The sample files `layout2.xp', +`lorenz.xp', `slopefield.xp', and `vfield.xp' illustrate usage. + + In each field-plotting command, the domain argument may be replaced +by two points, representing corners of a coordinate rectangle, and two +integers, the number of grid intervals in the selected coordinate +directions. Only planar slices of a vector field can be plotted using +the alternative syntax. + + + +`ePiX' provides limited features for spherical and hyperbolic geometry: +the ability to draw lines in the half-plane and Poincar\'e disk models +of the hyperbolic plane, and to draw latitudes, longitudes, great +circle arcs, spherical triangles, regular polyhedra, and parametrized +curves on a sphere. + + Hyperbolic line segments are specified by their endpoints in the +upper half space or ball (Poincar\'e) models. In each case there is no +output if either endpoint lies outside the model. + + hyperbolic_line(p, q); + disk_line(p, q); + For compatibility with 2-dimensional hyperbolic space, the half-space +model is the set \(x_1,x_2,x_3)\mid x_2>0\. + + A `frame' determines geographical coordinates on a `Sphere': the +first element points toward longitude 0 on the equator, the third +element points to the north pole. A latitude line depends on a +`Sphere', a `frame', the numerical latitude, and a range of longitudes. +A longitude line is described similarly. + + latitude(lat, long_min, long_max, Sphere S, frame coords); + longitude(lngtd, lat_min, lat_max, Sphere S, frame coords); + By default, `coords' is the standard `frame' and `S' is the unit +sphere. These commands draw only the portion of the curve that is +visible from the current viewpoint. The function `back_latitude' draws +the invisible portion of a latitude line. + + Spherical arcs and triangles are described by their endpoints. Only +the direction vector from the center of the sphere to an endpoint is +significant; if a sphere is scaled or moved, the same function call +will draw the corresponding object on the new sphere. + + The following draw the visible (front) portions of great circle arcs: + + front_arc(p1, p2, S); // short arc on S from p1 to p2 + front_arc2(p1, p2, S); // arc from p1 to -p1 through p2 + front_line(p1, p2, S); // great circle through p1 and p2 + Triangles and regular (Platonic) polyhedra are provided. The sample +file `sample/polyhedra.xp' illustrates usage. + + front_triangle(p1, p2, p3, S); // spherical triangle + front_tetra(S, coords); // regular tetrahedron + front_cube(S, coords); // hexahedron + front_octa(S, coords); // octahedron + front_dodeca(S, coords); // dodecahedron + front_icosa(S, coords); // icosahedron + Each function has a `back' version, which draws the hidden portion. +The tetrahedron, cube, and octahedron are (up to scale) inscribed in +the cube of side length 2 centered at the origin whose sides are +parallel to `frame'. The point (1,1,1) is a vertex of the tetrahedron. + + Up to scale, the icosahedron's vertices lie on the golden rectangle +with vertices (\pm\gamma,0,\pm1) and its images under cyclic +permutation of coordinates. The dodecahedron is dual to the icosahedron. + + + +Parametrized paths on a `Sphere S' (by default the unit sphere) can be +specified either by radial projection of a `P'-valued curve, or by +stereographic projection of a plane curve given as a pair of +`double'-valued functions: + + frontplot_R(phi, t_min, t_max, n, [S]); // radial + frontplot_N(f1, f2, t_min, t_max, n, [S]); // from north pole + frontplot_S(f1, f2, t_min, t_max, n, [S]); // from south pole + Attempts to perform radial projection on a path through the origin +will generate division-by-zero errors. Stereographic projection maps +the equatorial plane \x_3=0\ to the unit sphere by projection from the +corresponding pole: N=(0,0,1), S=(0,0,-1). + + Each spherical plot command has a `back' version that prints only +the portion of the path invisible from the current viewpoint. Because +of the way `ePiX' layers output, it is generally best to put hidden +portions of the input before visible portions, with line width and/or +style that suggests hidden lines. + + + +Files of numerical data can be created, manipulated, analyzed, plotted +(paths, scatter plots, and histograms), read, and written. The format +for a data file is one or more floating-point numbers per line, with +the same number of entries per line. Anything that appears on a line +after the `LaTeX' comment character `\%' is a comment. + + `ePiX' provides two `plot' commands for file data. The first +facilitates plotting selected columns; the second simplifies plotting +the first two columns with one or both scales logarithmic. Either form +can be used to plot selected columns logarithmically. + + The general commands read numbers from two or three columns of a +specified file, pass them as arguments to a `P'-valued function `F', +and plot the resulting points: + + plot("filename", STYLE, [i_1], [i_2], [i_3], [F]); + plot("filename", STYLE, F, [i_1], [i_2], [i_3]); + The first argument is the name of the data file. The `STYLE' may be +`PATH', which joins the points in the order they appear, or any of the +marker types in Table *Note table:marker::, . The integers i_k specify +columns from which to extract data; these default, respectively, to the +first column, second column, and null (a column of zeroes). If the +"coordinate system" `F' is omitted in the first command, it defaults to +the Cartesian point constructor. The function `F' is mandatory in the +second form; useful choices include `log_log', `log_lin', and +`lin_log', which plot the corresponding coordinate logarithmically. + + + +For more elaborate analysis, the `data_file' class presents an +interface to a file as an ordered list of columns. There are two +general ways to create a `data_file': read in an external file, or +generate data (up to three columns) using specified `double'-valued +functions. In the constructors below, each function `fi' is a +`double'-valued function of one variable. + + data_file DF("my_data"); // read data from disk file + data_file DF(f1, t_min, t_max, num_pts); // values of f1 + data_file DF(f1, f2, t_min, t_max, num_pts); + data_file DF(f1, f2, f3, t_min, t_max, num_pts); + data_file DF(3); // create empty data_file with 3 columns + DF.read("file1"); // read a disk file + + Columns of a `data_file' can be transformed by a user-specified +function, averaged, correlated, extracted (for use by other code), +scatter plotted, and written to a disk file at specified precision. +Below, the function `f' is a `double'-valued function of one variable +and `F' is a `P'-valued function of two or three variables, whose +components are written back to the selected columns. + + DF.transform(f, i); // apply f to selected column(s) + DF.transform(F, i=1, j=2); + DF.transform(F, i, j, k); + Basic statistical operations on columns are provided. + + DF.dot(i,j); // dot product of columns i, j + DF.avg(i); // mean of column i + DF.var(i); // population variance + DF.covar(i,j); // covariance + DF.regression(i,j); // plot regression line + A `data_file' is scatter plotted using syntax as described above. % +The output is cropped automatically to the bounding box. + + DF.plot(STYLE, [i1], [i2], [i3], [F]); + DF.plot(STYLE, F, [i1], [i2], [i3]); + Histograms and bar charts are described below. + + A `data_file' can be written to a disk file as raw data, or in +specified format. Below, `fmt' denotes a `string'-valued formatting +function of two variables and `myfile' is the name of the disk file to +be written. + + DF.precision(4); // set to 4 significant figures + DF.write("myfile"); // write as tab-separated columns + DF.write("myfile", fmt, [i1], [i2]); // apply fmt to cols + A column can be extracted as a `C++' `vector' for use by another +function. + + DF.column(i); // i-th column + DF.column(f, i); // i-th column, transformed by f + + + +`ePiX' provides a `data_mask' class for culling data from a file +according to the values in a specified column, and a `data_bins' class +for sorting data by value. + + A `data_mask' consists of an interval of numbers and a "filter" +function. The (closed, open, or half-open) interval is given as a +string in standard mathematical notation, or by its endpoints (for a +closed interval). The filter is a `double'-valued function of +`double', by default the identity, f(x)=x. + + data_mask dm("[a, b]", [f]); + data_mask dm(a, b, [f]); + A `data_mask' "passes" inputs x if f(x) lies in the interval. The +member function `reverse()' inverts this logical test. + + The `data_file' class has `prune' functions to cull rows for which a +specified column's entry satisfies a `data_mask''s criterion. + + DF.prune(dm, i); // remove row if i-th column entry fails + DF.prune(a, b, i); // remove row if i-th column outside [a,b] + + A `data_bins' object models an interval divided at specified +locations into "bins", not necessarily of equal length. Numerical data +is read in and the number of points in each bin counted. The lifetime +of a `data_bins' object has two stages. First, "cuts" (endpoints of +subintervals) are added. Then, once data is read, the cuts are "locked" +and cannot subsequently be changed. + + // [xmin, xmax] divided into n equal intervals, 1 by default + data_bins db(xmin, xmax, [n]); + db.cut(x); // add a cut at x (if x is in bounds) + db.read(vector<double>); // read data, lock bins + + A `data_bins' object can be plotted as a histogram (rectangles' +_area_ is proportional to the bin population), bar chart (rectangles' +_height_ is proportional to the bin population), or spline +interpolation of a bar chart. + + db.histogram(c=1); // c = vertical scale factor + db.bar_chart(c=1); + db.plot(c=1); + By default (`c=1'), the height of a bar chart rectangle is the +fraction of the total population contained in the bin; thus, the height +is always between 0 and 1. For a histogram, the height of a rectangle +is the fraction of the population per horizontal unit in the bin; thus, +the total area over an interval [a,b] does not depend on how [a,b] has +been subdivided. The sample files `dataplot.xp' and `histogram.xp' +illustrate use. + + Statistical convention dictates cuts be chosen distinctly from data +values; that is, values should all fall strictly within a bin, not at a +boundary point. With large, unknown data sets, this convention may be +difficult to uphold. `ePiX' attempts to handle anomalous data +intelligently, by keeping counts of values "out-of-range" or "on-cut". + + In detail, if x<a or x>b is a data value, it is counted as +out-of-range and does not contribute to the histogram population. If +x=a or x=b, the value counts as both out-of-range and on-cut but is +added to the population of the lowest or highest bin, respectively. Any +other cut appearing as a data input is flagged as on-cut, and +increments the population of each adjacent bin by one-half. When a +histogram or bar chart is written, `ePiX' prints a warning message +summarizing the number of anomalous data seen. + + + +Simple horizontal and vertical error bars are provided. The final +(optional) argument is the true height or width (respectively) in pt. + + h_error_bar(P location, double error, <mark type>, ht=6); + v_error_bar(P location, double error, <mark type>, wd=6); + + To create more complex elements, such as asymmetric bars, whisker +plots, labeled error bars, and the like, write a custom function using +true-size drawing, see page *Note truesize::. For example, a fillable, +labeled, asymmetric, vertical rectangular error bar can be implemented +(entirely in `ePiX') like this: + + void error_bar(P loc, double lo, double hi, P offset, + std::string text, align, double wd=6) + { + const double width(pt_to_screen(0.5*wd)); // converts to 3pt + rect(loc - P(width, lo), loc + P(width, hi)); + line(loc - P(width, 0), loc + P(width, 0)); + label(loc + P(width, 0), offset, text, align); + } + For stylistic uniformity, functions such as this should be put into a +library and used systematically. Section *Note section:extensions::, +outlines the process of writing, compiling, and using a custom library. + + + +A `legend' systematically labels different parts of a plot by +associating visual "keys" with explanatory text. This tends to be most +useful for plots containing several distinct but conceptually related +graphs requiring contrast. + + Visually, a `legend' is represented as an aligned list of rows, each +containing a box (the key), a gap (the label skip), and some text. +These rows are printed in a (usually large) masked label. By default, +keys are `12pt' squares bordered in black, the label skip is `6pt', the +background is white, and the border is plain black. These attributes +are controlled (simultaneously for all items) with member functions. +Parameters of type `double' represent lengths in `pt'. + + legend L; + L.backing(color); // set background + L.border(color, [double]); // set border color [and width] + L.border(double); // border width + + L.item_border(color, [double]); + L.item_border(double); // same, for item borders + + L.label_skip(double); + L.key_size(double); + + + +There are three types of legend key, representing filled regions, +paths, and markers. Fill and path keys get their visual attributes from +the current drawing state. A mark key must be told the marker type. +Each is created by specifying the item text. + + L.fill_item(text); + L.path_item(text); + L.mark_item(<mark type>, text); + Keys in the printed legend appear in the same order they are created +in the input file. + + + +Normally, a `legend' is defined near the start of a file, and an item +is added at the point in the file where the corresponding object or +plot is drawn, so that the item receives the correct attributes. A +`legend' is placed into the figure with the `draw' function. The +arguments have the same meaning as for ordinary `label's. + + L.draw(P location, P offset, align); + All three arguments are mandatory. "Global" `legend' settings +(border, backing, etc.) may be changed anywhere between the `legend''s +creation and `draw' function. The sample file `legend.xp' revisits the +example on page *Note taylor_poly::, including a trig-labeled axis and a +legend. The file `shadeplot.xp' contains filled keys, and `dataplot.xp' +contains a `legend' with items of mixed type. + + +File: epix.info, Node: More About `C++', Next: Attribute Quick Reference, Prev: Creating and Drawing Objects, Up: Reference Manual + +3.7 More About `C++' +==================== + +A textbook or similarly detailed reference is essential for serious +study of `C' or `C++'. _The `C' Programming Language_, second edition, +by Kernighan and Ritchie `KnR', is an excellent, manageable resource +for the basics of procedural programming. _C++ Primer Plus_, by Stephen +Prata `Prata', clearly lays out the extensive details of `C++'. +Marshall Cline's _`C++' FAQ Lite_ `Cline' engagingly discusses common +points of confusion and furnishes tips on good design and programming. + + `C++' is a powerful, complex language whose syntax is similar to that +of `C', or to the scripting languages of Maple and Mathematica. An +`ePiX' input file is source code for a `C++' program that writes a +`LaTeX' picture as output. `ePiX' may be viewed as an extension to +`C++'; in the same way that `LaTeX' furnishes a high-level interface to +`TeX', `ePiX' provides a high-level bridge between the computational +power of `C++' and the `LaTeX' `picture' environment. + + Like all high-level programming languages, `C++' provides variables, +functions, and control structures. Variables hold pieces of data such +as numerical values and geometric locations, while functions operate on +data. A control structure, such as a loop or conditional statement, +affects the program's course according to the program's current state. +A source file is composed primarily of "statements", which perform +actions ranging from defining variables and functions to setting figure +attributes, performing calculations, and writing objects to the output +file. + + + +Names of variables and functions may consist (only) of letters, digits, +and the underscore character. The first character of a name must not be +a digit, and the language standard reserves names starting with +underscore for library authors. Names are case-sensitive, but it's +usually a bad idea to use a single name capitalized and uncapitalized +in a single file. Numerous capitalization conventions are used +informally; this document uses uncapitalized words separated by +underscores for variables and functions, and occasionally uses all +capitals for constants. As with names of `LaTeX' macros, primary +considerations are clarity (of meaning), readability, and consistency. + + Every variable in `C++' has a "type", such as integer (`int'), +double-precision floating point (`double'), or Boolean (`bool', true or +false). `ePiX' provides additional types, the most common of which is +`P', for point. The construct `P(x,y,z)' creates (x,y,z), while +`P(x,y)' gives (x,y,0), which is effectively the pair (x,y). A variable +is defined by giving its type, its name, and an initializing expression. + + In `C' and `C++', a _pointer_ variable holds the memory address of +another variable. Pointers are useful for manipulating (possibly large) +data structures through "handles" of fixed small size. `C++' also +provides _references_, which bind an additional name to an existing +object and allow the object to be manipulated through this alias. The +statements + + double x=1; // ordinary variable definition + double& rx=x; // bind a reference, signified by & + define a variable `x' having the value 1, and bind a reference +variable `rx' to it. As long as `rx' exists, it refers to `x'. If the +value of `x' changes, the value of `rx' does as well. Conversely, the +value of `x' can be altered by assigning to `rx'. However, `rx' is the +size of a pointer, regardless of the size of `x', so `rx' can be passed +efficiently in a function call. + + + +In a programming language, the term "function" refers to a block of +code that is executable by name. A `C++' function takes a list of +"arguments", and has a "return value". This information, together with +the function's name, must be provided when a function is defined. A +function may not be defined inside another function. However, a +function may call other functions (including itself) as part of its +execution: + + int factorial(unsigned int n) + { + if (n == 0) return 1; + else return n*factorial(n-1); + } + + The special type `void' represents a "null type". A function that +performs an action but does not return a value has return type `void'. +A function that takes no arguments may be viewed as taking a single +`void' argument. + + Every `C++' program has a special function `main()', which is called +by the operating system when the program is run. The arguments of +`main()' are command-line arguments, and the return type is an integer +that signals success or failure. User-specified functions must be +defined before the call to `main()' or in a separately-compiled file. + + Functions in `C++' may be as simple as an algebraic formula or as +complex as an arbitrary algorithm. Greatest common divisors, finite +sums, numerical derivatives and integrals, solutions of differential +equations, recursively generated fractal curves, and curves of best fit +are a few applications in `ePiX'. Several sample files contain +user-level algorithms, which do not require knowledge of `ePiX''s +internal data structures. The source file `functions.cc' contains +simple functions defined by algorithms, and `functions.h' illustrates +the use of `C++' templates. Other source files, such as `plots.cc', may +be consulted for Simpson's rule, Euler's method, and the like. + + + +`C++' knows several familiar mathematical functions by name: + + sqrt exp log log10 ceil floor fabs + (`fabs' is the absolute value for a floating-point argument.) `ePiX' +provides trig and inverse trig functions sensitive to angular mode: + + Cos Sin Tan + Sec Csc Cot + Acos Asin Atan + The inverse functions are principle branches. + + The function `pow(x,y)' returns x^y when x>0, and `atan2(y,x)' (N.B. +argument order) returns Arg(x+iy)\in(-\pi,\pi], the principle branch of +arg. `C++' knows many constants to 20 decimal places, such as `M_PI', +`M_PI_2', and `M_E' for \pi, \pi/2, and e respectively. `ePiX' defines +a few additional functions: + + sgn zero sinx cb + `sgn' is the signum function; `zero' is the constant function; `sinx' +is the function x\mapsto \sin(x)/x with the discontinuity removed; `cb' +(for "Charlie Brown") is the period-2 extension of the absolute value +function on [-1,1]. + + The GNU `C++' library defines other functions, including inverse +hyperbolic functions (`acosh', etc.), `log' and `exp' with base 2, 10, +or arbitrary b (`log2', etc.), the error and gamma functions (`erf' and +`tgamma' [sic], respectively), and Bessel functions of first and second +kind: `j0', `j1', `y0', etc. Use, e.g., `jn(5, )' to get higher +indices. The GNU `C' library reference manual `GNUC' describes these +and other functions in detail. + + Functions may be used in subsequent definitions, and functions of two +(or more) variables are defined in direct analogy to functions of one +variable: + +double f(double t) { return t*t*log(t*t); } // t^2 \ln(t^2) +double g(double s, double t) { return exp(2*s)*Sin(t); } + + + + +Unlike `C', `C++' supports "object-oriented programming". In a +nutshell, a _class_ is an abstraction in computer code of some concept, +such as a point, a sphere, a mapping that can be plotted, or a camera. +Classes allow a programmer to separate an object's _interface_ (the set +of meaningful operations) from its _implementation_ (the data +structures and algorithms that realize the interface). + + A class implementation consists of _members_ (named data elements) +and _member functions_ (functions that belong to the class and have +free access to members). `C++' classes enforce access permissions on +their members, protecting data from being manipulated except as +promised by the interface. + + An ideal interface looks like a black box: It hides the +implementation completely. In order to cooperate, two classes need +only know each other's interfaces. This separation of form and function +modularizes a program, and facilitates debugging, code reuse, and +overall maintainability, particularly in large programs. + + In simple programming, classes may be treated like built-in types. +Each class object has its own member functions, whose call syntax +differs from standard function calls: + + Circle C1(P(1,0), 1.5); // circle of given center and radius + C1.draw(); // member function Circle::draw(); + Naturally, this call draws the circle `C1'. Generally, a member +function call consists of a class object's name, a period, and the name +of the member function. Arguments, if any, go in the parentheses after +the member function name, just as in a regular function call. + + A few short paragraphs cannot do more than scratch the surface of +classes and object-oriented programming. For more details, please +consult a book, such as Prata `Prata' or Stroustrup `S', or Cline's +on-line FAQ `Cline'. + + + +`C' and `C++' are "call by value" languages. Variables are not passed +to a function; instead a copy of the value is made, and the function +operates only on the copy. Though this feature causes occasional +inconvenience, it prevents an object from being altered unexpectedly by +a function call in a different part of the program. Calling by value +helps localize the logic of a program, and circumvents easy-to-write +but extremely hard-to-find bugs. + + In `C++', a function may accept reference arguments. Passing an +object by reference grants the calling function access to the object +itself, not to a copy. There are two common applications: The object is +a large data structure for which copying is "expensive", or the +function _needs_ to modify its arguments (e.g., a function `swap(x,y)' +that exchanges the values of `x' and `y'). + + For the first situation, `C++' provides the `const' keyword, which +ensures the function does not modify its arguments, but accepts a +reference merely for efficiency. Any attempt to modify a `const' +argument will be caught by the compiler. Most `ePiX' commands accept +`const' reference arguments. + + The ability to pass function arguments by reference is sometimes +touted as a feature in `C++' texts. However, the technique circumvents +the data encapsulation of calling by value, and should be avoided +unless absolutely necessary. If a function merely "updates" the value +of a variable, probably the variable should be of class type, and the +update should be performed by a member function. + + A function declaration must indicate that its arguments are +references. The declarations below have the indicated idiomatic +meanings. + + class matrix; + double det(matrix); // call by value, perhaps inefficient + matrix& transpose(matrix&); // probably changes its argument + double trace(const matrix&); // does not change its argument + Unlike pointer arguments, reference arguments impose no syntactic +burden on the user. If `A' is a `matrix', then `transpose(A);' and +`trace(A);' will compile. You need not declare explicit reference +variables and pass those to the function. + + + +`C++' provides "overloading": Multiple functions can be given the same +name, so long as the number and/or type of their arguments differ. (It +is _not_ enough for the return types alone to differ. The compiler +must be able to select a function from its calling syntax.) To the +user, the appearance is that a single function intelligently handles +multiple argument lists. Naturally, overloaded names should refer to +functions that are conceptually related. + + + +A `C++' statement ends with a semicolon. A collection of statements +enclosed by curly braces is a "code block", and may be viewed as a +single logical statement. Curly braces determine a "scope", inside +which variable names may be re-used without ambiguity. Function bodies +are code blocks, as are the alternatives associated to control +statements. A variable defined between curly braces is said to be +_local_ to the scope in which it is defined; its value cannot be used +out of scope. Variables should be declared in the smallest scope +possible. + + The compiler is not picky about spaces, tabs, and newlines, so an +input file should be formatted to make local scopes visually apparent. +`emacs' automatically indents code to reflect scope, though the default +behavior does not please all users. As with variable naming, clarity +and consistency are paramount. + + + +A `C++' source file is compiled in multiple stages that occur +transparently to the user. The first step, pre-processing, involves +simple text replacement for file inclusion, macro expansion and +conditional compilation. Next, the source is compiled and assembled: +Human-readable language instructions are parsed, then represented in +assembly language. Finally, the object files are linked: Function calls +are resolved to hard-coded file offsets, possibly involving external +library files, and the program instructions are packaged into an +executable binary that the operating system can run. + + Pre-processing is used much less in `C++' than in `C'; the language +itself supports safer and more featureful alternatives to macros, such +as `const' variables and inline functions. File inclusion and +conditional compilation are the chief uses of the pre-processor. Lines +of the form + + #include <iostream> + #include "epix.h" + cause the contents of a _header file_ to be read into the source file. +A header file contains variable and function _declarations_, statements +that specify types and names but do not define actual data. +Declarations tell the compiler just enough to resolve expressions and +function calls without knowing specific values or function definitions. + + Conditional compilation is similar to conditional `LaTeX' code. For +example, a file might produce either color or monochrome output as +follows: + +#ifdef COLOR + ... // code for generating color figure +#endif /* COLOR */ +#ifndef COLOR + ... // monochrome code +#endif /* undef COLOR */ + The "compiler symbol" `COLOR' is an ordinary `C++' name. To control +compilation, either put a `\#define COLOR' line in the file, or +(better) supply the flag on the command line: \\ epix -DCOLOR +<file.xp> \\ Every `\#ifdef' must have a matching `\#endif'. Commenting +the `\#endif' is a good habit; in a realistic file, the start and end +of a conditional block may be separated by more than one screen. + + + +As a programming language, `C++' provides certain features common to +all languages (such as `LaTeX', MetaPost, Perl, Lisp\ldots) and adheres +to rules of grammar. Salient differences between `LaTeX' and `C++' +include: + + 1. Every `C++' statement and function call must end with a + semicolon. An omitted semicolon may result in a cryptic error + message from the compiler. Pre-processor directives, which start + with a `\#', do not end with a semicolon. + + 2. Backslash is an escape character in `C++': + // Put label $y=\sin x$ at (2,1) + // Note single ^ backslash in output + label(P(2,1), P(0,0), "$y=\\sin x$"); + // Double backslash ^^ in source + + 3. Variable and function names may contain letters (including + underscore) and digits _only_, are case sensitive, and must + begin with a letter. + + 4. Variables in `C++' must have a declared _type_, such as `int' + (integer) or `double' (double-precision floating point). If a + variable has global scope and its value does not change, the + definition should probably come in the preamble or at the + beginning of `main'. Local variables should be defined in the + smallest possible scope. Unlike `C', `C++' allows variables to be + defined where they first appear. + + 5. `C++' requires explicit use of `*' to denote multiplication; + juxtaposition is not enough. `C++' does not support the use of ^ + for exponentiation, e.g., t^2 is invalid. Instead, use `t*t' or + `pow(t,2)'. + + 6. `C++' has single- and multi-line comments. Everything between a + double slash and the next newline is ignored, while the strings + /* and */ delimit multi-line comments. A single-line comment may + appear within a multi-line comment, but the compiler does not + nest multi-line comments. + + + Between them, `C' and `C++' have about 100 reserved keywords which +cannot be used as function or variable names. + + +File: epix.info, Node: Attribute Quick Reference, Prev: More About `C++', Up: Reference Manual + +3.8 Attribute Quick Reference +============================= + +In the body of an input file, the "drawing state" determines the +figure's appearance. Attributes are declarations, set by commands that +accept arguments of the stated type. + + A `len' argument is a double-quoted string containing a number and a +two-letter `LaTeX' length unit, such as `"1.5pt"' or `"6cm"'. A `color' +argument is a named primary (`Red()', `Cyan()', `White()', etc.), a +`Color' specified by densities (`RGB(...)', `CMYK(...)', etc.), or a +`Color' object. Using `Neutral()' as a `Color' argument generally turns +off the corresponding attribute. + + * Angular mode: `radians()', `degrees()', or `revolutions()'. + + The angular mode affects all trigonometric operations, including + camera rotations, the drawing of arcs and ellipses, polar plotting, + label angle, and the trig functions themselves. Angle-sensitive + trig functions are capitalized, e.g., `Cos', `Tan'. + + * Fill style: `fill(color)', `fill(bool)', `nofill()'. + + * Path style: + + * Width: `plain()', `bold()', `bbold()', `pen(len)'. + + * Line style: `line_style(string)'. The argument is a + WYSIWYG sequence of dashes, spaces, and periods. + `dash_size(double)' and `dot_sep(double)' set the + (approximate) length in `pt' of the pattern. The commands + `solid()', `dashed()', `dotted()' define "standard" + defaults for brevity. + + * Path color: Paths can be drawn using _two_ pens, one atop + the other. When the "base" pen is white (or the + background color) and wider than the "line" pen, a path + masks parts of the figure it crosses. A 3-D effect may be + obtained by making the base pen a darker shade than the + "line" pen. + + `pen(color,[len])', `base(color,[len])' + + Standard widths: `plain(color)', `bold(color)', + `bbold(color)' + + + * Text attributes: + + * Color: `label_color(color)' + + * Mask: `label_mask(color)', `label_pad(len)' + + * Border: `label_border(color, [len])', + `label_border(len)'. The command `no_label_border()' + turns off label borders. + + * Font size: `font_size(LaTeX size)', no argument means + `normalsize'. + + * Font face: `font_face(LaTeX font)', two-letter font + selection string, default is `rm'. + + * Rotation: `label_angle(double)' + + + + Do not confuse `Color' constructors with the similarly-named +(deprecated) lowercase attribute-setting commands, `rgb(r,g,b)', +`cmyk(c,m,y,k)', `red(d)', etc. These commands affect text, paths, and +filled regions. For example, the single command `red()' has the same +effect as the three commands `pen(Red())', `fill(Red())', and +`label_color(Red())'. + + +File: epix.info, Node: Advanced Topics, Next: Software Freedom, Prev: Reference Manual, Up: Top + +4 Advanced Topics +***************** + +This chapter covers _ad hoc_ tricks and open-ended techniques that +require relatively more programming sophistication. You will almost +surely need an external `C++' reference if you do not speak the +language. + +* Menu: + +* Hidden Object Removal:: +* Extensions:: +* Programmer's Guide:: + + +File: epix.info, Node: Hidden Object Removal, Next: Extensions, Prev: Advanced Topics, Up: Advanced Topics + +4.1 Hidden Object Removal +========================= + +`ePiX' writes the output file in the same order that objects appear in +the input. The order is significant because PostScript builds a figure +in layers: Objects are drawn over objects that come earlier in the +file. Shaded polygons can be used to obtain surprisingly effective +hidden object removal in surface meshes. This section describes the +data structures defined in the source files `surface.*'. + + The basic idea is to create a shaded polygon class that knows its +approximate distance to the camera. For computational simplicity, a +mesh "facet" is treated as a quadrilateral, located at the arithmetic +mean of its vertices. A facet's boundary is created from a map and a +domain by tracing a fine mesh rectangle counterclockwise. + + To draw a parametrized surface, facets are stored in a `C++' vector, +sorted in decreasing order of distance to the camera, and printed to +the output file. If filling is active, the gray density of a facet +depends on the cosine of the angle between the normal vector and the +vector from the camera to the element. + + This simple algorithm works surprisingly well when mesh elements +intersect at most along complete edges. To incorporate line-like +elements (e.g., coordinate axes, wire-mesh plots) with shaded surfaces, +the best technique is often to order high-level scene elements +manually, breaking up shaded surfaces (for example, with domain +resizing or clipping) as necessary. The sample file `saddle.xp' +illustrates possible techniques. + + Shaded surfaces can be decorated with a bit of hackery. For example, +the `facet::draw' function in `facet.cc' can be modified easily to draw +line elements, tangents, or normal vectors along with the facet itself. +The sample file `decorate.xp' contains a couple of ideas. (The +decorations are activated by compiler flags; please consult the file +itself for information on compiling.) + + +File: epix.info, Node: Extensions, Next: Programmer's Guide, Prev: Hidden Object Removal, Up: Advanced Topics + +4.2 Extensions +============== + +Thanks to a suggestion of Andrew Sterian, `ePiX' is extensible. User +extensions span a spectrum, from header files that require only basic +knowledge of `C++' to separately compiled libraries that add +substantial new features. The structure of the source code is outlined +in Section *Note section:programmers::, . + + + +A `C++' header file conventionally has suffix `.h', as in `myheader.h'. +To use this custom header, put a line `\#include "myheader.h"' in your +source file. + + User definitions can be easily and robustly implemented with "inline +functions". Inline functions are superficially similar to macros, but +are far more safe and featureful (since they are handled by the +compiler rather than by the pre-processor). Examples are + + inline void Bold() { pen(1.6); } + inline void purple() { rgb(0.5, 0, 0.7); } + inline void draw_square(double s) { rect(P(-s,-s),P(s,s)); } + inline double cube(double x) { return pow(x,3); // x^3 } + The keyword `void' signifies a function that does not return a value, +or (when used as an implicit parameter) a function that does not accept +arguments. Inline function definitions are syntactically identical to +ordinary function definitions, but _must_ occur in a header file or in +the source file where they are used. The examples above might be used +in an input file as follows: + + Bold(); + draw_square(cube(1.25)); + + + +The next few sections outline the creation of a "static library" on +GNU/Linux, and explain how to incorporate custom features at runtime. +The extensively-commented sample files `std_F.cc' and `std_F.h' +illustrate the techniques described below, and may be used for guidance +and experimentation. + + A small library is usually written as a _header_ file, which +contains class and function declarations (also called "prototypes"), +and a _source_ file, which contains the actual code. Conventionally +(under *nix), these files have extension `.h' and `.cc' respectively. +Header and source files may "include" other header files, to +incorporate additional functionality. + +/* my_code.h */ +#ifndef MY_CODE +#define MY_CODE +#include <cmath> // standard library math header +#include "epix.h" // ePiX header +using ePiX::P; + +namespace Mine { // to avoid name conflicts + // functions for special relativity + double lorentz_norm(const P&); + bool spacelike(const P&); +} // end of namespace +#endif /* MY_CODE */ + This file exhibits two "safety features". The three `MY_CODE' lines +prevent the file from being included multiple times. In a file of this +size, inclusion protection is overkill, but as your code base grows and +the number of header files increases, this protection is essential. +Second, the header introduces a "Mine" namespace. Inside this +namespace, two functions are declared as prototypes, giving the +function's return type, name, and argument type(s). A header file +should be commented fairly liberally, so that a year or two from now +you'll be able to decipher the file's contents. For a longer file, +version and contact information, an overall comment describing the +file's features, and license information are appropriate. + + Next, the corresponding source file; definitions are also placed into +the namespace, and must match their prototypes from the header file +exactly. + +/* my_code.cc */ +#include "my_code.h" +using namespace ePiX; + +namespace Mine { + double lorentz_norm(const P& arg) + { + double x(arg.x1()), y(arg.x2()), z(arg.x3()); // extract coords + return (y-x)*(y+x) + z*z; // -x^2 + y^2 + z^2 + } + bool spacelike(const P& arg) + { + return (lorentz_norm(arg) > 0); // true if inequality is + } +} // end of namespace + Copies of these files are included with the source code so you can +experiment with them. Next, the source file must be "compiled", +"archived", and "indexed". In the commands below, the percent sign is +the prompt. + +% g++ -c my_code.cc +% ar -ru libcustom.a my_code.o +% ranlib libcustom.a + Please see your system documentation for details on command options +and what each step does. For linking (below), the name of the library +file must begin "lib" and have the extension `.a'. Once these steps are +successfully completed, put the library `libcustom.a' and header file +`my_code.h' in your project directory. You're ready to use the code in +an `ePiX' figure. + + + +The script `epix' allows input files to be linked with external +libraries at run time, when the input file is compiled into a temporary +executable. + + `epix' recognizes command line options and passes them verbatim to +the compiler. The most commonly used options are those of the form + + -I<include> -L<libdir> -l<lib> + For example, to link `figure.xp' against `mylibs/libcustom.a', run the +command + + epix -Lmylibs -lcustom figure + The options `-I. -L.' tell the compiler to look in the current +directory for header and library files. Compiler options may appear in +any order, but must come before the name of the input file(s). + + Compiler options may be placed in the configuration file +`\$HOME/.epixrc', with syntax as above. A line in the config file that +contains a pound sign (`\#') is a comment, no matter where in the line +the `\#' appears. If any non-comment line fails to start with a dash, +the rest of the file is silently discarded. Command-line options are +read before the config file. + + + +The script `epix' links by default against the `C' math library +`libm.a' and the `ePiX' library `libepix.a'. The command option +`--no-defaults' clears the header and include paths and removes +`libepix.a' from the link list. The script may therefore be used with +multiple versions of `ePiX', a potentially useful feature if you +regularly need to compile old source files, or simply prefer the syntax +of an older version. + + To install and use (say) Version 1.0.0, build the package according +to its `INSTALL' instructions, but _do not use the makefile to +install_. Instead, manually install the header and library only, using +their version number: + +# install -m 644 epix.h /usr/local/include/epix-1.0.h +# install -m 644 libepix.a /usr/local/lib/libepix-1.0.a + A non-system directory may be used instead of `/usr/local'. To use +the old version, a source file must `include' the appropriate header +file (which is identified by its version number). To compile, issue a +command such as + +epix --no-defaults -I/usr/local -L/usr/local -lepix-1.0 file.xp + + +File: epix.info, Node: Programmer's Guide, Prev: Extensions, Up: Advanced Topics + +4.3 Programmer's Guide +====================== + +This section briefly surveys `ePiX''s implementation, and is intended +for (potential) programmers. The source code is divided into modules +with small, well-defined responsibilities, but the user interface is +mostly compatible with the syntax of Version 1.0. These constraints +demanded a degree of implementation hiding. For example, the +user-visible classes defined in `Color.h', `path.h', and `screen.h' +contain only a pointer to the implementation class, and style data is +hidden behind global commands. + + Functionally, the code consists of the user interface; implementation +class\-es comprising drawing attributes, spatial objects, screens and +representations of their elements, and output; and miscellaneous +utility functions. The headers in each group, and their contents, are +described in Section *Note section:interface::, . + + The user interface headers are assembled into a single file, +`epix.h', and installed in `/usr/local/include' by default. In normal +use, the shell scripts read only the user interface header. The +individual headers, including the components of `epix.h', are installed +in `/usr/local/include/epix'. These are provided for authors of +external libraries, who may need access to implementation details. + + + +`ePiX' harnesses the computational power of `C++' to the typographical +capabilities of `LaTeX'. Consequently, `ePiX' should be viewed in part +as a framework for expressing numerical data visually. + + In the course of your work, you may develop specialized code filling +a gap in `ePiX''s functionality. If your code seems likely to be of +interest to other users, please consider bundling it as an external +package and notifying the `ePiX' community so your work can be linked +from the project pages and distributed to interested users. + + There are no formal requirements for external packages, but in the +interest of uniformity contributed code should follow the GNU Coding +Standards `GNUCoding'. At a minimum, an external package should build +with the standard `./configure; make; make install' commands, and the +`configure' script should accept an option `--with-epix' for the user +to specify a non-default `ePiX' install directory. + + If an external package builds a static library, it should provide a +single header containing all the package's entry points, and enclose +its interface in a namespace. Entry points should not collide with +`ePiX' functions. Naming the package "`epix-<...>'" is a good idea, but +not essential. For example, a package providing textual nodes and +diagram layout might be named `epix-nodes'. Input files would use the +package with the lines + + #include "epix-nodes.h" + using namespace ePiX-nodes; + and be compiled with + + epix -lepix-nodes <file> + + The user and internal interfaces of `ePiX'-1.2 are not likely to +change. Still, it's prudent to rely only on the user interface in +contributed code whenever possible. Doing so also simplifies your work +as an author; your library can simply `include' the user header file, +and deal only with high-level objects and drawing attributes. + + + +These files (in order) comprise the global header `epix.h'. + + `enums.h' Marker, alignment, Riemann integral, and vector field +types. + + `length.h' Physical lengths, conceptually a number and two-letter +`LaTeX' length unit. + + `interval.h' Closed, open, and half-open interval ranges for data +culling. + + `triples.h' The `P' class. + + `functions.h' Angle-sensitive trig functions, miscellaneous utility +functions, the `Deriv' and `Integral' classes. + + `pairs.h' Screen locations and displacements, with complex +arithmetic operations. + + `Color.h' The Color class interface, named primaries and +constructors. + + `state.h' Angle mode; clipping and cropping; label styles; filling; +arrow head style; dot and tick sizes, dash length; line style; line and +base pen attributes; color-setting commands. + + `frame.h' Orthonormal bases. + + `domain.h' Coordinate boxes for function plotting. + + `camera.h' The camera. + + `screen.h' The screen class. + + `picture.h' Dimension-setting, offset, layout, decoration, verbatim +text, and output format commands. + + `markers.h' Point markers, axis labels, and coordinate axes. + + `axis.h' Coordinate axes and labels in various styles. + + `legend.h' Plot legends. + + `path.h' The path class. + + `curves.h' Polygons, arrows, ellipses, arcs, splines, coordinate +grids, and recursive fractal curves. + + `circle.h' The `Circle' shape object class. + + `plane.h' The `Plane' shape object class. + + `segment.h' The `Segment' shape object class. + + `sphere.h' The `Sphere' shape object class. + + `intersections.h' Shape object intersection operators. + + `plots.h' Plotting commands. + + `surface.h' Shaded surface plots. + + `data_mask.h' Helper class for data pruning. + + `data_file.h' Class for storing and representing data. + + `data_bins.h' Class for sorting and counting data. + + `geometry.h' Latitudes and longitudes; spherical plotting, arcs, +polygons, and polyhedra; hyperbolic arcs. + + + +`Color_Base.h' The Color implementation interface. + + `Color_CMY.h' The CMY color model. + + `Color_CMYK.h' The CMYK color model. + + `Color_Gray.h' The Gray color model. + + `Color_Neutral.h' Each color class has a "Neutral" member that +converts colors to that model by filtering. This file defines the +unique "model-less" Neutral color for which filtering performs no +action. + + `Color_RGB.h' The RGB color model. + + `Color_Sep.h' Classes for CMYK separation. + + `active_screen.h' Simple manipulator for the active screen. + + `picture_data.h' Picture implementation: two `screen' s +(representing the `canvas' and the output page), true dimensions and +offsets, pointer to output format, list of colors, and lists of +verbatim text to write before and after printing the `picture' +environment in the output file. For simplicity, the `screen's and +dimensions are public; encapsulation from the user results from +"hiding" this header. + + + +Declaration-style attributes are maintained with functions returning +static references: `the_angle_style()', `the_arrowhead_style()', +`the_label_style()', `the_mark_size()', `the_paint_style()', and +`the_path_style()'. Each function is declared in the analogously-named +header. + + `angle_units.h' Angular modes: `radians' , `revolutions', and +`degrees'. + + `arrow_style.h' Arrow head style data: width, ratio, and inset. + + `label_style.h' Text object style: Label and mask colors, padding, +border color and width, alignment, font size, font face, and angle. + + `marker_style.h' Dot and tick sizes. + + `paint_style.h' Line and base pens, fill color. + + `path_style.h' Solid, dashed, dotted lines. + + `pen_data.h' The pen class. + + + +`arrow_data.h' Arrow representation. + + `facet.h' Shaded surface elements. + + `label_data.h' Text (label and marker) objects. + + `legend_item.h' Items for `legend' s. + + `path_data.h' Path implementation. + + `spline.h' The natural spline class. + + `spline_data.h' Templates for quadratic and cubic splines. + + + +Elements in a `screen' are represented polymorphically as "`tile's", of +which there are six types: `glyph' (textual elements), `pen_arrow' +(arrows), `pen_fill' (filled regions), `pen_line' (path-like elements), +`verbatim' (raw text), and `legend_tile' (legends). + + Border and background shape are dictated by the `screen_mask' class. +The cropping algorithm assumes the contour of a screen mask is convex. + + `affine.h' Affine maps. + + `cropping.h' Screen mask cropping. + + `glyph.h' Markers and labels. + + `legend_tile.h' Screen representation of a `legend' . + + `mask_diamond.h' Screen diamond mask. + + `mask_ellipse.h' Screen elliptical mask. + + `mask_rectangle.h' Screen rectangular mask. + + `pen_arrow.h' Arrows. + + `pen_fill.h' Filled regions. + + `pen_line.h' Paths. + + `screen_data.h' Screen implementation class. + + `screen_mask.h' Screen mask interface. + + `tile.h' Screen element interface. + + `verbatim.h' Text in output stream. + + + +Output is divided into a couple of high-level operations and several +"atomic" low-level operations. To create a new output format, one need +only implement the `format' interface for the desired file type. Paths +and filled regions may be implemented however the output type dictates. + + `eepic.h' eepic macros. + + `fmt_template.h' "skeleton" header for new output formats. + + `format.h' The output interface. + + `pst.h' PSTricks macros. + + `tikz.h' tikz macros. + + + +`Color_Utils.h' Functions for setting color channel densities. + + `clipping.h' The clip box. + + `constants.h' Global constants: Line widths; dot, tick, and dash +sizes; arrowhead parameters; miscellaneous numerical constants and +internal parameters. + + `crop_algorithms.h' Path and loop clipping templates. + + `deriv.h' Finite difference template. + + `edge_data.h' Path element representation template. + + `errors.h' Warning and error messages. + + `frac.h' Rational numbers and operators. + + `halfspace.h' Halfspace cutting. + + `hatching.h' Filling regions in eepic. + + `lens.h' Camera lenses. + + `map.h' Wrappers for templated plotting. + + `plot_algorithms.h' Plotting templates. + + `screen_crop.h' Crop paths and loops. + + `utils.h' Truncation, date and time, line breaking. + + +File: epix.info, Node: Software Freedom, Next: Acknowledgments, Prev: Advanced Topics, Up: Top + +Appendix A Software Freedom +*************************** + +Academics in general, and mathematicians in particular, depend on free +exchange of information. We prove theorems or establish experimental +results, write up formal accounts, place preprints on public file +servers, and submit papers to peer-reviewed journals. If accepted, the +results--data, techniques, methods of reasoning, citations, and +conclusions--are published in print and become part of the public +record, governed by copyright law. Libraries purchase journal +subscriptions, but researchers and scholars may use ideas from the +literature merely by giving appropriate citations in their own work. +"Theft" arises from false claims of authorship. + + Carried over to software, the academic process would guarantee rights +similar to those provided by the GNU General Public License (GPL): + + * (GPL 0) To run a program for any purpose. + + * (GPL 1) To study how the program works, and adapt it to your + needs. + + * (GPL 2) To redistribute copies of the program. + + * (GPL 3) To improve the program, and release improvements to the + public, so that the whole community benefits. + + + In reality, attitudes toward software differ markedly. Most academics +work on a proprietary platform, use proprietary software for research +and teaching, and share information with colleagues and students in +proprietary, even obfuscated, data formats. Contrary to the academic +ethic, proprietary software licenses restrict access to information: +preventing users from learning how a program works internally ("reverse +engineering"), limiting the number of users who may run a piece of +software, and forbidding users from running (or sometimes even +installing) a purchased copy on multiple machines. + + Restrictions on use aside, if one cannot examine a program's source +code, one cannot fully trust the output, any more than one can trust +(for purposes of scientific publication) results of a commercial +testing lab. + + Consider a hypothetical future world in which scholarly results are +disseminated like software. Instead of subscriptions, journals sell +licenses granting readership to a specified number of individuals. +Photocopying an article for a class or research seminar constitutes +"piracy", though if the institution has purchased a sufficiently large +site license the teacher or speaker may bring the physical volume to +class and project the pages onto a screen. + + Of course, reading an article is scarcely enlightening. Mathematics +papers contain only the statements of theorems. Merely opening the +journal binds the reader to a lengthy legal agreement, stating that +theorems be used only for specific purposes and threatening serious +legal consequences for attempting to discover the author's proofs. + + The actions of a single student, employee, or faculty member can +expose an institution to a costly "journal audit" from the Mathematical +Society of America (MSA), with the institution responsible for legal +costs if the audit reveals license violations anywhere in the +organization. + + Mathematicians who long for the Old Days when papers contained +proofs and were shared freely are dismissed as idealistic cranks or +labeled anti-business communists. Common knowledge asserts the obvious +superiority of proprietary journals, and the necessity of licenses for +keeping mathematicians gainfully employed. + + Back in our world, some vendors have attempted to placate opponents +of closed source with "shared source" licenses, under which one may +sign a non-disclosure agreement and subsequently examine source code. +In the future world analogy, a shared source agreement would allow +journal licensees to sign an NDA, then see the proofs of theorems. +Readers could thereby correct errors in proofs (benefitting the +publisher by improving the reliability of the journal), but would be +legally forbidden from using the ideas elsewhere (denying benefit to +other mathematicians). + + Legally and conceptually codifying software as a commodity ignores a +fundamental reality: Like an idea or recipe, software can be copied +without loss of the original. The perception of "theft" by copying +arises from an artificial belief that software has an owner who must be +monetarily compensated each time a person acquires a copy. The nature +of software does not enforce the "sale" model in the way services and +physical commodities do. It therefore seems philosophically +inappropriate to treat software as a commodity, and perilous to conform +the legal system to the enforcement of such a model. + + At its best, software enhances our productivity and creativity. +Sharing software, like sharing ideas, benefits a larger number of +people without detriment to existing users. I hope this modest program +is, in conjunction with the much larger efforts of others (especially +Donald Knuth, Richard Stallman, and the many people who have +contributed to the authorship of `LaTeX' and its packages), useful to +you in your mathematical work. + + Please visit the Free Software Foundation, at `http://www.fsf.org', +to learn more about free software and how you can contribute to its +development and adoption. + + +File: epix.info, Node: Acknowledgments, Next: Function Index, Prev: Software Freedom, Up: Top + +Appendix B Acknowledgments +************************** + +`ePiX' is built on the work of many people (unfortunately, most of whom +I am unaware). The following people have contributed, sometimes +unknowingly but always generously: + + *Infrastructure* Donald Knuth, Conrad Kwok, Leslie Lamport, Tim +Morgan, Piet van Oostrum, Sunil Podar, Richard Stallman, Till Tantau, +Herbert Voss, Timothy van Zandt + + *Enhancements* Jay Belanger, Robin Blume-Kohout, Julian Gilbey, +Marcus Hanwell, Yvon Henel, Svend Daugaard Pedersen, Andrew Sterian + + *Porting and packaging* Julian Gilbey (Debian); Tsuguru Kato +(FreeBSD); Markus Dittrich, Danny van Dyk, Christian Faulhammer, +Olivier Fisette, Chris Gianelloni, Michael Hanselmann, Marcus Hanwell, +David Holm, Peter Johanson, Patrick Kursawe, Tobias Scherbaum, Markus +Ullmann (Gentoo); Guido Gonzato (RPM); Rene Rebe (T2) + + *Debugging, advice, and other assistance* Jay Belanger, Felipe Paulo +Guazzi Bergo, Karl Berry, Robin Blume-Kohout, Patrick Cousot, Stephen +Gibson, Julian Gilbey, Dov Grobgeld, Bob Grover, Jim Hefferon, Jacques +L'helgoual, Yvon Henel, Hartmut Henkel, Herng-Jeng Jou, Walter +Kehowski, Kevin McCormick, Ross Moore, Thorsten Riess, Alan Sill, Neel +Smith, Michael Somos, Andrew Sterian, Ryszard Tanas, Kai Trukenmueller, +Torbjorn Vik, Wenguang Wang, Gabe Weaver, Mariusz Wodzicki + + +File: epix.info, Node: Function Index, Next: Concept Index, Prev: Acknowledgments, Up: Top + +Function Index +************** + + +* Menu: + +* aarrow: Creating and Drawing Objects. + (line 248) +* Acos: More About C++. (line 112) +* activate: Scene Attributes. (line 161) +* affine: Scene Attributes. (line 271) +* apply: Scene Attributes. (line 307) +* arc: Creating and Drawing Objects. + (line 167) +* arc_arrow: Creating and Drawing Objects. + (line 248) +* arc_measure: Creating and Drawing Objects. + (line 193) +* arrow: Creating and Drawing Objects. + (line 242) +* arrow_inset: Creating and Drawing Objects. + (line 235) +* arrow_ratio: Creating and Drawing Objects. + (line 235) +* arrow_width: Creating and Drawing Objects. + (line 235) +* Asin: More About C++. (line 112) +* Atan: More About C++. (line 112) +* axis: Creating and Drawing Objects. + (line 275) +* axis.align: Creating and Drawing Objects. + (line 284) +* axis.align_labels: Creating and Drawing Objects. + (line 296) +* axis.dec: Creating and Drawing Objects. + (line 296) +* axis.draw: Creating and Drawing Objects. + (line 342) +* axis.draw_labels: Creating and Drawing Objects. + (line 342) +* axis.draw_ticks: Creating and Drawing Objects. + (line 342) +* axis.frac: Creating and Drawing Objects. + (line 296) +* axis.label_rep: Creating and Drawing Objects. + (line 307) +* axis.precision: Creating and Drawing Objects. + (line 296) +* axis.sci: Creating and Drawing Objects. + (line 296) +* axis.subdivide: Creating and Drawing Objects. + (line 284) +* axis.tag: Creating and Drawing Objects. + (line 323) +* axis.tag235: Creating and Drawing Objects. + (line 323) +* axis.tags: Creating and Drawing Objects. + (line 323) +* axis.tick_ratio: Creating and Drawing Objects. + (line 284) +* axis.trig: Creating and Drawing Objects. + (line 296) +* axis.unmark: Creating and Drawing Objects. + (line 296) +* axis.untag: Creating and Drawing Objects. + (line 323) +* axis_break: Creating and Drawing Objects. + (line 394) +* back_arc: Creating and Drawing Objects. + (line 851) +* back_arc2: Creating and Drawing Objects. + (line 851) +* back_cube: Creating and Drawing Objects. + (line 857) +* back_dodeca: Creating and Drawing Objects. + (line 857) +* back_icosa: Creating and Drawing Objects. + (line 857) +* back_latitude: Creating and Drawing Objects. + (line 837) +* back_line: Creating and Drawing Objects. + (line 851) +* back_longitude: Creating and Drawing Objects. + (line 837) +* back_octa: Creating and Drawing Objects. + (line 857) +* back_tetra: Creating and Drawing Objects. + (line 857) +* back_triangle: Creating and Drawing Objects. + (line 857) +* backing: Scene Attributes. (line 252) +* backplot_N: Creating and Drawing Objects. + (line 879) +* backplot_R: Creating and Drawing Objects. + (line 879) +* backplot_S: Creating and Drawing Objects. + (line 879) +* bbold: Drawing Attributes. (line 33) +* bbox: Drawing Attributes. (line 174) +* begin: File Structure. (line 12) +* Black: Color. (line 23) +* Blue: Color. (line 23) +* bold: Drawing Attributes. (line 33) +* border: Scene Attributes. (line 252) +* bottom_axis: Creating and Drawing Objects. + (line 332) +* bounding_box: Picture Size and Aspect Ratio. + (line 24) +* box: Drawing Attributes. (line 174) +* Camera.at: Scene Attributes. (line 75) +* Camera.clip_range: Scene Attributes. (line 75) +* Camera.focus: Scene Attributes. (line 75) +* Camera.look_at: Scene Attributes. (line 75) +* Camera.pan: Scene Attributes. (line 75) +* Camera.range: Scene Attributes. (line 75) +* Camera.roll: Scene Attributes. (line 75) +* Camera.tilt: Scene Attributes. (line 75) +* canvas: Scene Attributes. (line 183) +* cb: More About C++. (line 123) +* circ: Drawing Attributes. (line 174) +* circle: Creating and Drawing Objects. + (line 145) +* Circle: Creating and Drawing Objects. + (line 70) +* cis: Creating and Drawing Objects. + (line 27) +* clip_box: Scene Attributes. (line 127) +* clip_face: Scene Attributes. (line 137) +* clip_restore: Scene Attributes. (line 137) +* clip_slice: Scene Attributes. (line 137) +* clip_to: Scene Attributes. (line 127) +* CMY: Color. (line 29) +* CMY_Black: Color. (line 29) +* CMY_White: Color. (line 29) +* cmyk: Drawing Attributes. (line 210) +* CMYK: Color. (line 29) +* Color.alpha: Color. (line 73) +* Color.blend: Color. (line 73) +* Color.filter: Color. (line 73) +* Color.invert: Color. (line 73) +* Color.superpose: Color. (line 73) +* Cos: More About C++. (line 112) +* Cot: More About C++. (line 112) +* crop: Scene Attributes. (line 239) +* crop_diamond: Scene Attributes. (line 239) +* crop_ellipse: Scene Attributes. (line 239) +* Csc: More About C++. (line 112) +* Cyan: Color. (line 29) +* cyl: Creating and Drawing Objects. + (line 27) +* dart: Creating and Drawing Objects. + (line 248) +* dart_field: Creating and Drawing Objects. + (line 793) +* dash_size: Drawing Attributes. (line 44) +* dashed: Drawing Attributes. (line 53) +* data_bins: Creating and Drawing Objects. + (line 1006) +* data_bins.bar_chart: Creating and Drawing Objects. + (line 1016) +* data_bins.cut: Creating and Drawing Objects. + (line 1006) +* data_bins.histogram: Creating and Drawing Objects. + (line 1016) +* data_bins.plot: Creating and Drawing Objects. + (line 1016) +* data_bins.read: Creating and Drawing Objects. + (line 1006) +* data_file: Creating and Drawing Objects. + (line 931) +* data_file.avg: Creating and Drawing Objects. + (line 950) +* data_file.column: Creating and Drawing Objects. + (line 973) +* data_file.covar: Creating and Drawing Objects. + (line 950) +* data_file.dot: Creating and Drawing Objects. + (line 950) +* data_file.plot: Creating and Drawing Objects. + (line 958) +* data_file.precision: Creating and Drawing Objects. + (line 967) +* data_file.read: Creating and Drawing Objects. + (line 931) +* data_file.regression: Creating and Drawing Objects. + (line 950) +* data_file.transform: Creating and Drawing Objects. + (line 945) +* data_file.var: Creating and Drawing Objects. + (line 950) +* data_file.write: Creating and Drawing Objects. + (line 967) +* data_mask: Creating and Drawing Objects. + (line 988) +* data_mask.prune: Creating and Drawing Objects. + (line 996) +* ddot: Drawing Attributes. (line 174) +* deactivate: Scene Attributes. (line 161) +* Deriv: Creating and Drawing Objects. + (line 745) +* Deriv.eval: Creating and Drawing Objects. + (line 745) +* Deriv.left: Creating and Drawing Objects. + (line 745) +* Deriv.right: Creating and Drawing Objects. + (line 745) +* disk_line: Creating and Drawing Objects. + (line 826) +* domain: Creating and Drawing Objects. + (line 512) +* domain.resize: Creating and Drawing Objects. + (line 531) +* domain.slice: Creating and Drawing Objects. + (line 531) +* domain.slices: Creating and Drawing Objects. + (line 531) +* domain_list: Creating and Drawing Objects. + (line 668) +* domain_list.add: Creating and Drawing Objects. + (line 668) +* dot: Drawing Attributes. (line 174) +* dot_size: Drawing Attributes. (line 185) +* dotted: Drawing Attributes. (line 53) +* draw: Creating and Drawing Objects. + (line 59) +* ellipse: Creating and Drawing Objects. + (line 167) +* ellipse_bottom: Creating and Drawing Objects. + (line 180) +* ellipse_left: Creating and Drawing Objects. + (line 180) +* ellipse_right: Creating and Drawing Objects. + (line 180) +* ellipse_top: Creating and Drawing Objects. + (line 180) +* end: File Structure. (line 12) +* envelope: Creating and Drawing Objects. + (line 768) +* extract: Scene Attributes. (line 183) +* extract_diamond: Scene Attributes. (line 190) +* extract_ellipse: Scene Attributes. (line 190) +* fill: Drawing Attributes. (line 12) +* flow: Creating and Drawing Objects. + (line 778) +* font_face: Drawing Attributes. (line 144) +* font_size: Drawing Attributes. (line 144) +* fractal: Creating and Drawing Objects. + (line 214) +* frame: Creating and Drawing Objects. + (line 134) +* front_arc: Creating and Drawing Objects. + (line 851) +* front_arc2: Creating and Drawing Objects. + (line 851) +* front_cube: Creating and Drawing Objects. + (line 857) +* front_dodeca: Creating and Drawing Objects. + (line 857) +* front_icosa: Creating and Drawing Objects. + (line 857) +* front_line: Creating and Drawing Objects. + (line 851) +* front_octa: Creating and Drawing Objects. + (line 857) +* front_tetra: Creating and Drawing Objects. + (line 857) +* front_triangle: Creating and Drawing Objects. + (line 857) +* frontplot_N: Creating and Drawing Objects. + (line 879) +* frontplot_R: Creating and Drawing Objects. + (line 879) +* frontplot_S: Creating and Drawing Objects. + (line 879) +* Gray: Color. (line 29) +* Green: Color. (line 23) +* grid: Creating and Drawing Objects. + (line 405) +* h_axis: Creating and Drawing Objects. + (line 352) +* h_axis_labels: Creating and Drawing Objects. + (line 368) +* h_axis_log_labels: Creating and Drawing Objects. + (line 368) +* h_axis_log_masklabels: Creating and Drawing Objects. + (line 368) +* h_axis_masklabels: Creating and Drawing Objects. + (line 368) +* h_error_bar: Creating and Drawing Objects. + (line 1047) +* h_log_axis: Creating and Drawing Objects. + (line 352) +* h_scale: Scene Attributes. (line 282) +* h_shear: Scene Attributes. (line 282) +* hyperbolic_line: Creating and Drawing Objects. + (line 826) +* import: Scene Attributes. (line 172) +* include: C++ Basics. (line 37) +* inf: Creating and Drawing Objects. + (line 731) +* inlay: Scene Attributes. (line 204) +* inlay_horizontal: Scene Attributes. (line 204) +* inlay_vertical: Scene Attributes. (line 204) +* inset: Scene Attributes. (line 172) +* Integral: Creating and Drawing Objects. + (line 745) +* Integral.eval: Creating and Drawing Objects. + (line 745) +* J: Creating and Drawing Objects. + (line 38) +* label <1>: Drawing Attributes. (line 99) +* label: Layout Tricks. (line 46) +* label_border: Drawing Attributes. (line 160) +* label_color: Drawing Attributes. (line 160) +* label_mask: Drawing Attributes. (line 160) +* label_pad: Drawing Attributes. (line 160) +* latitude: Creating and Drawing Objects. + (line 837) +* left_axis: Creating and Drawing Objects. + (line 332) +* legend: Creating and Drawing Objects. + (line 1083) +* legend.backing: Creating and Drawing Objects. + (line 1083) +* legend.border: Creating and Drawing Objects. + (line 1083) +* legend.draw: Creating and Drawing Objects. + (line 1115) +* legend.fill_item: Creating and Drawing Objects. + (line 1101) +* legend.item_border: Creating and Drawing Objects. + (line 1083) +* legend.key_size: Creating and Drawing Objects. + (line 1083) +* legend.label_skip: Creating and Drawing Objects. + (line 1083) +* legend.mark_item: Creating and Drawing Objects. + (line 1101) +* legend.path_item: Creating and Drawing Objects. + (line 1101) +* Line: Creating and Drawing Objects. + (line 145) +* line: Creating and Drawing Objects. + (line 145) +* line_style: Drawing Attributes. (line 44) +* log1_grid: Creating and Drawing Objects. + (line 411) +* log2_grid: Creating and Drawing Objects. + (line 411) +* log_grid: Creating and Drawing Objects. + (line 411) +* longitude: Creating and Drawing Objects. + (line 837) +* Magenta: Color. (line 29) +* move_to: Creating and Drawing Objects. + (line 59) +* newton: Creating and Drawing Objects. + (line 731) +* no_label_border: Drawing Attributes. (line 160) +* nofill: Drawing Attributes. (line 12) +* ode_plot: Creating and Drawing Objects. + (line 778) +* P: Creating and Drawing Objects. + (line 27) +* P.x1: Creating and Drawing Objects. + (line 38) +* P.x2: Creating and Drawing Objects. + (line 38) +* P.x3: Creating and Drawing Objects. + (line 38) +* path: Creating and Drawing Objects. + (line 437) +* path.close: Creating and Drawing Objects. + (line 468) +* path.draw: Creating and Drawing Objects. + (line 468) +* path.fill: Creating and Drawing Objects. + (line 468) +* pen <1>: Creating and Drawing Objects. + (line 422) +* pen: Drawing Attributes. (line 23) +* picture <1>: Picture Size and Aspect Ratio. + (line 24) +* picture: File Structure. (line 12) +* plain: Drawing Attributes. (line 33) +* Plane: Creating and Drawing Objects. + (line 85) +* plot: Creating and Drawing Objects. + (line 495) +* polar: Creating and Drawing Objects. + (line 27) +* polar_grid: Creating and Drawing Objects. + (line 405) +* polarplot: Creating and Drawing Objects. + (line 495) +* post_write: C++ Basics. (line 122) +* postcomp: Scene Attributes. (line 282) +* pre_write: C++ Basics. (line 122) +* pt_to_screen: Scene Attributes. (line 214) +* quad: Creating and Drawing Objects. + (line 145) +* rect: Creating and Drawing Objects. + (line 145) +* Red: Color. (line 23) +* reflect: Scene Attributes. (line 282) +* rgb: Drawing Attributes. (line 210) +* RGB: Color. (line 23) +* riemann_sum: Creating and Drawing Objects. + (line 756) +* right_angle: Creating and Drawing Objects. + (line 193) +* right_axis: Creating and Drawing Objects. + (line 332) +* ring: Drawing Attributes. (line 174) +* rotate: Scene Attributes. (line 282) +* scale <1>: Creating and Drawing Objects. + (line 59) +* scale: Scene Attributes. (line 282) +* scenery: Creating and Drawing Objects. + (line 680) +* scenery.add: Creating and Drawing Objects. + (line 680) +* scenery.draw: Creating and Drawing Objects. + (line 680) +* Sec: More About C++. (line 112) +* Segment: Creating and Drawing Objects. + (line 90) +* set_crop: Scene Attributes. (line 239) +* sgn: More About C++. (line 123) +* shadeplot: Creating and Drawing Objects. + (line 495) +* shift <1>: Creating and Drawing Objects. + (line 59) +* shift: Scene Attributes. (line 282) +* Sin: More About C++. (line 112) +* sinx: More About C++. (line 123) +* slope_field: Creating and Drawing Objects. + (line 793) +* solid: Drawing Attributes. (line 53) +* sph: Creating and Drawing Objects. + (line 27) +* Sphere: Creating and Drawing Objects. + (line 93) +* spline: Creating and Drawing Objects. + (line 167) +* spot: Drawing Attributes. (line 174) +* sup: Creating and Drawing Objects. + (line 731) +* surface: Creating and Drawing Objects. + (line 616) +* surface_rev: Creating and Drawing Objects. + (line 627) +* Tan: More About C++. (line 112) +* tan_field: Creating and Drawing Objects. + (line 768) +* tan_line: Creating and Drawing Objects. + (line 768) +* top_axis: Creating and Drawing Objects. + (line 332) +* triangle: Creating and Drawing Objects. + (line 145) +* unitlength: Picture Size and Aspect Ratio. + (line 24) +* v_axis: Creating and Drawing Objects. + (line 352) +* v_axis_labels: Creating and Drawing Objects. + (line 368) +* v_axis_log_labels: Creating and Drawing Objects. + (line 368) +* v_axis_log_masklabels: Creating and Drawing Objects. + (line 368) +* v_axis_masklabels: Creating and Drawing Objects. + (line 368) +* v_error_bar: Creating and Drawing Objects. + (line 1047) +* v_log_axis: Creating and Drawing Objects. + (line 352) +* v_scale: Scene Attributes. (line 282) +* v_shear: Scene Attributes. (line 282) +* vector_field: Creating and Drawing Objects. + (line 793) +* White: Color. (line 23) +* write: C++ Basics. (line 122) +* Yellow: Color. (line 29) +* zero: More About C++. (line 123) + + +File: epix.info, Node: Concept Index, Prev: Function Index, Up: Top + +Concept Index +************* + + +* Menu: + +* Affine map: Scene Attributes. (line 264) +* Affine map!action on labels: Drawing Attributes. (line 130) +* Angle units <1>: Drawing Attributes. (line 121) +* Angle units: Scene Attributes. (line 14) +* Angular mode <1>: More About C++. (line 112) +* Angular mode: Creating and Drawing Objects. + (line 27) +* Animation: Animation. (line 6) +* Arrow: Creating and Drawing Objects. + (line 231) +* Axes: Creating and Drawing Objects. + (line 257) +* Axes!broken: Creating and Drawing Objects. + (line 390) +* Axes!labeling: Creating and Drawing Objects. + (line 257) +* Axes!logarithmic: Creating and Drawing Objects. + (line 350) +* Bar Charts: Creating and Drawing Objects. + (line 1013) +* Bounding box: Scene Attributes. (line 156) +* Camera <1>: Hidden Object Removal. + (line 13) +* Camera: Scene Attributes. (line 21) +* Camera!color separation: Scene Attributes. (line 94) +* Camera!lens: Scene Attributes. (line 57) +* Camera!manipulation: Scene Attributes. (line 69) +* Camera!manipulation of: Scene Attributes. (line 116) +* Camera!viewpoint: Scene Attributes. (line 31) +* canvas: The Drawing Model. (line 11) +* Circle: Creating and Drawing Objects. + (line 69) +* Classes: More About C++. (line 149) +* Clipping: Scene Attributes. (line 120) +* Color <1>: Drawing Attributes. (line 215) +* Color: Color. (line 6) +* Color!separation: Scene Attributes. (line 94) +* Color!surface plotting: Creating and Drawing Objects. + (line 700) +* Color!transparency: Color. (line 65) +* Conditional statement: More About C++. (line 22) +* Cplusplus@C++ <1>: More About C++. (line 6) +* Cplusplus@C++: C++ Basics. (line 6) +* Cropping: Scene Attributes. (line 231) +* Data plotting: Creating and Drawing Objects. + (line 897) +* Domain: Creating and Drawing Objects. + (line 509) +* Emacs@emacs <1>: Animation. (line 19) +* Emacs@emacs <2>: C++ Basics. (line 16) +* Emacs@emacs <3>: Running ePiX. (line 50) +* Emacs@emacs: Software Dependencies. + (line 36) +* Error bars: Creating and Drawing Objects. + (line 1046) +* Filling: Drawing Attributes. (line 11) +* Fonts: Drawing Attributes. (line 142) +* Free software <1>: Software Freedom. (line 6) +* Free software: Introduction. (line 42) +* Function: More About C++. (line 22) +* Function!call syntax: More About C++. (line 186) +* Function!class member: More About C++. (line 156) +* Function!mathematical: More About C++. (line 108) +* Function!overloaded: More About C++. (line 229) +* Function!returning void: More About C++. (line 84) +* Graph paper: Creating and Drawing Objects. + (line 422) +* Graphical interface: Tutorial. (line 13) +* Hidden object removal: Hidden Object Removal. + (line 6) +* Histograms: Creating and Drawing Objects. + (line 1013) +* Input file!comment in: More About C++. (line 337) +* Input file!conditional compilation: More About C++. (line 281) +* Installation <1>: Installation. (line 31) +* Installation: Software Dependencies. + (line 6) +* Intersection: Creating and Drawing Objects. + (line 109) +* Labels <1>: More About C++. (line 310) +* Labels: Drawing Attributes. (line 80) +* Labels!alignment: Drawing Attributes. (line 80) +* Labels!axis: Creating and Drawing Objects. + (line 257) +* Labels!backslash in: Drawing Attributes. (line 205) +* Labels!fonts in: Drawing Attributes. (line 142) +* Labels!in double quotes: Drawing Attributes. (line 205) +* Labels!rotated: Drawing Attributes. (line 121) +* Layout <1>: Scene Attributes. (line 148) +* Layout: Layout Tricks. (line 6) +* Legends: Creating and Drawing Objects. + (line 1072) +* Mac OS X: Software Dependencies. + (line 6) +* Marker types: Drawing Attributes. (line 172) +* Output format: File Structure. (line 31) +* Path: Drawing Attributes. (line 11) +* Path!class: Creating and Drawing Objects. + (line 433) +* Path!filled: Drawing Attributes. (line 11) +* Path!fractal: Creating and Drawing Objects. + (line 206) +* Path!style: Drawing Attributes. (line 41) +* Picture!aspect ratio: Picture Size and Aspect Ratio. + (line 44) +* Picture!bounding box: Picture Size and Aspect Ratio. + (line 44) +* Picture!offset: Picture Size and Aspect Ratio. + (line 6) +* Picture!size: Picture Size and Aspect Ratio. + (line 6) +* Plane: Creating and Drawing Objects. + (line 85) +* Plotting: Creating and Drawing Objects. + (line 480) +* Plotting!calculus: Creating and Drawing Objects. + (line 721) +* Plotting!data: Creating and Drawing Objects. + (line 897) +* Plotting!spherical: Creating and Drawing Objects. + (line 833) +* Plotting!surface: Creating and Drawing Objects. + (line 605) +* Point: Creating and Drawing Objects. + (line 14) +* Pointer: More About C++. (line 52) +* post_write: C++ Basics. (line 122) +* pre_write: C++ Basics. (line 122) +* Preamble: File Structure. (line 10) +* Screen: Scene Attributes. (line 21) +* Screen!active: Scene Attributes. (line 148) +* Segment: Creating and Drawing Objects. + (line 90) +* Sphere: Creating and Drawing Objects. + (line 93) +* Stereograms: Layout Tricks. (line 8) +* Variable!local: More About C++. (line 239) +* Variable!names: More About C++. (line 34) +* Variable!pointer: More About C++. (line 52) +* Variable!reference: More About C++. (line 186) +* Variable!type of: More About C++. (line 45) +* Viewpoint: Scene Attributes. (line 31) +* Windows operating system: Software Dependencies. + (line 40) +* write: C++ Basics. (line 122) + + + +Tag Table: +Node: Top185 +Node: Introduction1105 +Node: Changes in Version 1.24664 +Node: Software Dependencies8541 +Ref: section:software_deps8714 +Node: Installation11086 +Node: Getting Started12670 +Ref: chapter:started12806 +Node: Running `ePiX'13556 +Ref: section:running13709 +Node: The Drawing Model16861 +Ref: section:overview17013 +Node: Tutorial19428 +Ref: section:tutorial19560 +Ref: taylor_poly24927 +Node: `C++' Basics26756 +Ref: fig:captioned32767 +Node: Animation33131 +Ref: section:animation33262 +Node: Layout Tricks34998 +Ref: section:layout35116 +Node: Reference Manual37114 +Ref: chapter:ref-man37255 +Node: File Structure38952 +Node: Picture Size and Aspect Ratio41705 +Ref: page:scaling44202 +Node: Color44417 +Ref: section:color44557 +Ref: fig:densities46382 +Node: Scene Attributes47847 +Ref: fig:camera48882 +Ref: truesize56642 +Node: Drawing Attributes62495 +Ref: table:marker70626 +Node: Creating and Drawing Objects71285 +Ref: fig:fractal81596 +Ref: fig:plot96868 +Ref: non-eucl107182 +Node: More About `C++'121128 +Ref: references130049 +Node: Attribute Quick Reference137418 +Ref: section:quickref137580 +Node: Advanced Topics140341 +Ref: chapter:adv140481 +Node: Hidden Object Removal140765 +Ref: section:hidden140932 +Node: Extensions142805 +Ref: section:extensions142953 +Node: Programmer's Guide149302 +Ref: section:programmers149436 +Ref: section:interface152502 +Node: Software Freedom158743 +Node: Acknowledgments164009 +Node: Function Index165447 +Node: Concept Index200200 + +End Tag Table diff --git a/graphics/epix/doc/graphpaper.eepic b/graphics/epix/doc/graphpaper.eepic new file mode 100644 index 0000000000..94a18e8085 --- /dev/null +++ b/graphics/epix/doc/graphpaper.eepic @@ -0,0 +1,101 @@ +%% Generated from graphpaper.xp on Tue Jan 4 15:32:14 EST 2005 by +%% ePiX-1.0.3 +%% +%% Cartesian bounding box: [-2,2] x [-1,1] +%% Actual size: 2in x 1in +%% Figure offset: right by 0in, up by 0in +%% +\setlength{\unitlength}{0.01in} +\begin{picture}(200,100)(-0,-0) +%% --- +\allinethickness{0.25pt}% +\path(0,0)(0,100) +\path(5,0)(5,100) +\path(10,0)(10,100) +\path(15,0)(15,100) +\path(20,0)(20,100) +\path(25,0)(25,100) +\path(30,0)(30,100) +\path(35,0)(35,100) +\path(40,0)(40,100) +\path(45,0)(45,100) +\path(50,0)(50,100) +\path(55,0)(55,100) +\path(60,0)(60,100) +\path(65,0)(65,100) +\path(70,0)(70,100) +\path(75,0)(75,100) +\path(80,0)(80,100) +\path(85,0)(85,100) +\path(90,0)(90,100) +\path(95,0)(95,100) +\path(100,0)(100,100) +\path(105,0)(105,100) +\path(110,0)(110,100) +\path(115,0)(115,100) +\path(120,0)(120,100) +\path(125,0)(125,100) +\path(130,0)(130,100) +\path(135,0)(135,100) +\path(140,0)(140,100) +\path(145,0)(145,100) +\path(150,0)(150,100) +\path(155,0)(155,100) +\path(160,0)(160,100) +\path(165,0)(165,100) +\path(170,0)(170,100) +\path(175,0)(175,100) +\path(180,0)(180,100) +\path(185,0)(185,100) +\path(190,0)(190,100) +\path(195,0)(195,100) +\path(200,0)(200,100) +\path(0,0)(200,0) +\path(0,5)(200,5) +\path(0,10)(200,10) +\path(0,15)(200,15) +\path(0,20)(200,20) +\path(0,25)(200,25) +\path(0,30)(200,30) +\path(0,35)(200,35) +\path(0,40)(200,40) +\path(0,45)(200,45) +\path(0,50)(200,50) +\path(0,55)(200,55) +\path(0,60)(200,60) +\path(0,65)(200,65) +\path(0,70)(200,70) +\path(0,75)(200,75) +\path(0,80)(200,80) +\path(0,85)(200,85) +\path(0,90)(200,90) +\path(0,95)(200,95) +\path(0,100)(200,100) +%% --- +\allinethickness{0.5pt}% +\path(0,0)(0,100) +\path(25,0)(25,100) +\path(50,0)(50,100) +\path(75,0)(75,100) +\path(100,0)(100,100) +\path(125,0)(125,100) +\path(150,0)(150,100) +\path(175,0)(175,100) +\path(200,0)(200,100) +\path(0,0)(200,0) +\path(0,25)(200,25) +\path(0,50)(200,50) +\path(0,75)(200,75) +\path(0,100)(200,100) +%% --- +\allinethickness{1pt}% +\path(0,0)(0,100) +\path(50,0)(50,100) +\path(100,0)(100,100) +\path(150,0)(150,100) +\path(200,0)(200,100) +\path(0,0)(200,0) +\path(0,50)(200,50) +\path(0,100)(200,100) +%% --- +\end{picture} diff --git a/graphics/epix/doc/graphpaper.xp b/graphics/epix/doc/graphpaper.xp new file mode 100644 index 0000000000..795c499d4d --- /dev/null +++ b/graphics/epix/doc/graphpaper.xp @@ -0,0 +1,24 @@ +/* -*-ePiX-*- */ +/* graphpaper.c -- July 6, 2002 */ +#include "epix.h" +using namespace ePiX; + +int main() +{ + bounding_box(P(-2,-1), P(2,1)); + picture(P(200,100)); + unitlength("0.01in"); + + begin(); + + pen(0.25); + grid(10*x_size, 10*y_size); + + pen(0.5); + grid(2*x_size, 2*y_size); + + pen(1); + grid(x_size, y_size); + + end(); +} diff --git a/graphics/epix/doc/hello.eepic b/graphics/epix/doc/hello.eepic new file mode 100644 index 0000000000..9b58fefc81 --- /dev/null +++ b/graphics/epix/doc/hello.eepic @@ -0,0 +1,15 @@ +%% Generated from hello.xp on Thu Jun 28 11:33:40 EDT 2007 by +%% ePiX-1.1.6 +%% +%% Cartesian bounding box: [-1,1] x [-1,1] +%% Actual size: 2 x 1in +%% Figure offset: left by 0in, down by 0in +%% +\xdefinecolor{rgb_000000}{rgb}{0,0,0} +\setlength{\unitlength}{1in} +\begin{picture}(2,1)(-0,-0) +\put(1,0.5){\makebox(0,0)[c]{{\Huge Hello, world!}}} +\allinethickness{1pt}% +\path(2,0)(2,1)(0,1)(0,0)(2,0) +%% +\end{picture} diff --git a/graphics/epix/doc/hello.xp b/graphics/epix/doc/hello.xp new file mode 100644 index 0000000000..c8bd3739b9 --- /dev/null +++ b/graphics/epix/doc/hello.xp @@ -0,0 +1,20 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +int main() +{ + picture(P(-1,-1),P(1,1), "2x1in"); + + begin(); + + // uncomment and permute these lines + // crop_ellipse(); + // backing(Yellow()); + border(Black(), "1pt"); + + font_size("Huge"); + label(P(0,0), "Hello, world!"); + + end(); +} diff --git a/graphics/epix/doc/koch.eepic b/graphics/epix/doc/koch.eepic new file mode 100644 index 0000000000..1f949958c0 --- /dev/null +++ b/graphics/epix/doc/koch.eepic @@ -0,0 +1,160 @@ +%% Generated from koch.xp on Tue Jan 4 15:32:16 EST 2005 by +%% ePiX-1.0.3 +%% +%% Cartesian bounding box: [0,3] x [0,0.5] +%% Actual size: 3in x 0.5in +%% Figure offset: right by 0in, up by 0.25in +%% +\setlength{\unitlength}{1in} +\begin{picture}(3,0.5)(-0,-0.25) +%% --- +\path(0,0)(0.25,0)(0.25,0.25)(0.5,0.25)(0.5,0)(0.5,-0.25)(0.75,-0.25) + (0.75,0)(1,0) +%% --- +\path(1,0)(1.0625,0)(1.0625,0.0625)(1.125,0.0625)(1.125,0)(1.125,-0.0625) + (1.1875,-0.0625)(1.1875,0)(1.25,0)(1.25,0.0625)(1.1875,0.0625) + (1.1875,0.125)(1.25,0.125)(1.3125,0.125)(1.3125,0.1875)(1.25,0.1875) + (1.25,0.25)(1.3125,0.25)(1.3125,0.3125)(1.375,0.3125)(1.375,0.25) + (1.375,0.1875)(1.4375,0.1875)(1.4375,0.25)(1.5,0.25)(1.5,0.1875) + (1.5625,0.1875)(1.5625,0.125)(1.5,0.125)(1.4375,0.125)(1.4375,0.0625) + (1.5,0.0625)(1.5,0)(1.5,-0.0625)(1.5625,-0.0625)(1.5625,-0.125) + (1.5,-0.125)(1.4375,-0.125)(1.4375,-0.1875)(1.5,-0.1875)(1.5,-0.25) + (1.5625,-0.25)(1.5625,-0.1875)(1.625,-0.1875)(1.625,-0.25)(1.625,-0.3125) + (1.6875,-0.3125)(1.6875,-0.25)(1.75,-0.25)(1.75,-0.1875)(1.6875,-0.1875) + (1.6875,-0.125)(1.75,-0.125)(1.8125,-0.125)(1.8125,-0.0625)(1.75,-0.0625) + (1.75,0)(1.8125,0)(1.8125,0.0625)(1.875,0.0625)(1.875,0) +\path(1.875,0)(1.875,-0.0625)(1.9375,-0.0625)(1.9375,0)(2,0) +%% --- +\path(2,0)(2.01562,0)(2.01562,0.015625)(2.03125,0.015625)(2.03125,0) + (2.03125,-0.015625)(2.04688,-0.015625)(2.04688,0)(2.0625,0) + (2.0625,0.015625)(2.04688,0.015625)(2.04688,0.03125)(2.0625,0.03125) + (2.07812,0.03125)(2.07812,0.046875)(2.0625,0.046875)(2.0625,0.0625) + (2.07812,0.0625)(2.07812,0.078125)(2.09375,0.078125)(2.09375,0.0625) + (2.09375,0.046875)(2.10938,0.046875)(2.10938,0.0625)(2.125,0.0625) + (2.125,0.046875)(2.14062,0.046875)(2.14062,0.03125)(2.125,0.03125) + (2.10938,0.03125)(2.10938,0.015625)(2.125,0.015625)(2.125,0) + (2.125,-0.015625)(2.14062,-0.015625)(2.14062,-0.03125)(2.125,-0.03125) + (2.10938,-0.03125)(2.10938,-0.046875)(2.125,-0.046875)(2.125,-0.0625) + (2.14062,-0.0625)(2.14062,-0.046875)(2.15625,-0.046875)(2.15625,-0.0625) + (2.15625,-0.078125)(2.17188,-0.078125)(2.17188,-0.0625)(2.1875,-0.0625) + (2.1875,-0.046875)(2.17188,-0.046875)(2.17188,-0.03125)(2.1875,-0.03125) + (2.20312,-0.03125)(2.20312,-0.015625)(2.1875,-0.015625)(2.1875,0) + (2.20312,0)(2.20312,0.015625)(2.21875,0.015625)(2.21875,0) +\path(2.21875,0)(2.21875,-0.015625)(2.23438,-0.015625)(2.23438,0)(2.25,0) + (2.25,0.015625)(2.23438,0.015625)(2.23438,0.03125)(2.25,0.03125) + (2.26562,0.03125)(2.26562,0.046875)(2.25,0.046875)(2.25,0.0625) + (2.23438,0.0625)(2.23438,0.046875)(2.21875,0.046875)(2.21875,0.0625) + (2.21875,0.078125)(2.20312,0.078125)(2.20312,0.0625)(2.1875,0.0625) + (2.1875,0.078125)(2.17188,0.078125)(2.17188,0.09375)(2.1875,0.09375) + (2.20312,0.09375)(2.20312,0.109375)(2.1875,0.109375)(2.1875,0.125) + (2.20312,0.125)(2.20312,0.140625)(2.21875,0.140625)(2.21875,0.125) + (2.21875,0.109375)(2.23438,0.109375)(2.23438,0.125)(2.25,0.125) + (2.26562,0.125)(2.26562,0.140625)(2.28125,0.140625)(2.28125,0.125) + (2.28125,0.109375)(2.29688,0.109375)(2.29688,0.125)(2.3125,0.125) + (2.3125,0.140625)(2.29688,0.140625)(2.29688,0.15625)(2.3125,0.15625) + (2.32812,0.15625)(2.32812,0.171875)(2.3125,0.171875)(2.3125,0.1875) + (2.29688,0.1875)(2.29688,0.171875)(2.28125,0.171875)(2.28125,0.1875) + (2.28125,0.203125)(2.26562,0.203125)(2.26562,0.1875) +\path(2.26562,0.1875)(2.25,0.1875)(2.25,0.203125)(2.23438,0.203125) + (2.23438,0.21875)(2.25,0.21875)(2.26562,0.21875)(2.26562,0.234375) + (2.25,0.234375)(2.25,0.25)(2.26562,0.25)(2.26562,0.265625) + (2.28125,0.265625)(2.28125,0.25)(2.28125,0.234375)(2.29688,0.234375) + (2.29688,0.25)(2.3125,0.25)(2.3125,0.265625)(2.29688,0.265625) + (2.29688,0.28125)(2.3125,0.28125)(2.32812,0.28125)(2.32812,0.296875) + (2.3125,0.296875)(2.3125,0.3125)(2.32812,0.3125)(2.32812,0.328125) + (2.34375,0.328125)(2.34375,0.3125)(2.34375,0.296875)(2.35938,0.296875) + (2.35938,0.3125)(2.375,0.3125)(2.375,0.296875)(2.39062,0.296875) + (2.39062,0.28125)(2.375,0.28125)(2.35938,0.28125)(2.35938,0.265625) + (2.375,0.265625)(2.375,0.25)(2.375,0.234375)(2.39062,0.234375) + (2.39062,0.21875)(2.375,0.21875)(2.35938,0.21875)(2.35938,0.203125) + (2.375,0.203125)(2.375,0.1875)(2.39062,0.1875)(2.39062,0.203125) + (2.40625,0.203125)(2.40625,0.1875)(2.40625,0.171875)(2.42188,0.171875) + (2.42188,0.1875)(2.4375,0.1875)(2.4375,0.203125)(2.42188,0.203125) +\path(2.42188,0.203125)(2.42188,0.21875)(2.4375,0.21875)(2.45312,0.21875) + (2.45312,0.234375)(2.4375,0.234375)(2.4375,0.25)(2.45312,0.25) + (2.45312,0.265625)(2.46875,0.265625)(2.46875,0.25)(2.46875,0.234375) + (2.48438,0.234375)(2.48438,0.25)(2.5,0.25)(2.5,0.234375) + (2.51562,0.234375)(2.51562,0.21875)(2.5,0.21875)(2.48438,0.21875) + (2.48438,0.203125)(2.5,0.203125)(2.5,0.1875)(2.51562,0.1875) + (2.51562,0.203125)(2.53125,0.203125)(2.53125,0.1875)(2.53125,0.171875) + (2.54688,0.171875)(2.54688,0.1875)(2.5625,0.1875)(2.5625,0.171875) + (2.57812,0.171875)(2.57812,0.15625)(2.5625,0.15625)(2.54688,0.15625) + (2.54688,0.140625)(2.5625,0.140625)(2.5625,0.125)(2.54688,0.125) + (2.54688,0.109375)(2.53125,0.109375)(2.53125,0.125)(2.53125,0.140625) + (2.51562,0.140625)(2.51562,0.125)(2.5,0.125)(2.48438,0.125) + (2.48438,0.109375)(2.46875,0.109375)(2.46875,0.125)(2.46875,0.140625) + (2.45312,0.140625)(2.45312,0.125)(2.4375,0.125)(2.4375,0.109375) + (2.45312,0.109375)(2.45312,0.09375)(2.4375,0.09375)(2.42188,0.09375) +\path(2.42188,0.09375)(2.42188,0.078125)(2.4375,0.078125)(2.4375,0.0625) + (2.45312,0.0625)(2.45312,0.078125)(2.46875,0.078125)(2.46875,0.0625) + (2.46875,0.046875)(2.48438,0.046875)(2.48438,0.0625)(2.5,0.0625) + (2.5,0.046875)(2.51562,0.046875)(2.51562,0.03125)(2.5,0.03125) + (2.48438,0.03125)(2.48438,0.015625)(2.5,0.015625)(2.5,0)(2.5,-0.015625) + (2.51562,-0.015625)(2.51562,-0.03125)(2.5,-0.03125)(2.48438,-0.03125) + (2.48438,-0.046875)(2.5,-0.046875)(2.5,-0.0625)(2.51562,-0.0625) + (2.51562,-0.046875)(2.53125,-0.046875)(2.53125,-0.0625) + (2.53125,-0.078125)(2.54688,-0.078125)(2.54688,-0.0625)(2.5625,-0.0625) + (2.5625,-0.078125)(2.57812,-0.078125)(2.57812,-0.09375)(2.5625,-0.09375) + (2.54688,-0.09375)(2.54688,-0.109375)(2.5625,-0.109375)(2.5625,-0.125) + (2.54688,-0.125)(2.54688,-0.140625)(2.53125,-0.140625)(2.53125,-0.125) + (2.53125,-0.109375)(2.51562,-0.109375)(2.51562,-0.125)(2.5,-0.125) + (2.48438,-0.125)(2.48438,-0.140625)(2.46875,-0.140625)(2.46875,-0.125) + (2.46875,-0.109375)(2.45312,-0.109375)(2.45312,-0.125)(2.4375,-0.125) +\path(2.4375,-0.125)(2.4375,-0.140625)(2.45312,-0.140625)(2.45312,-0.15625) + (2.4375,-0.15625)(2.42188,-0.15625)(2.42188,-0.171875)(2.4375,-0.171875) + (2.4375,-0.1875)(2.45312,-0.1875)(2.45312,-0.171875)(2.46875,-0.171875) + (2.46875,-0.1875)(2.46875,-0.203125)(2.48438,-0.203125)(2.48438,-0.1875) + (2.5,-0.1875)(2.5,-0.203125)(2.51562,-0.203125)(2.51562,-0.21875) + (2.5,-0.21875)(2.48438,-0.21875)(2.48438,-0.234375)(2.5,-0.234375) + (2.5,-0.25)(2.51562,-0.25)(2.51562,-0.234375)(2.53125,-0.234375) + (2.53125,-0.25)(2.53125,-0.265625)(2.54688,-0.265625)(2.54688,-0.25) + (2.5625,-0.25)(2.5625,-0.234375)(2.54688,-0.234375)(2.54688,-0.21875) + (2.5625,-0.21875)(2.57812,-0.21875)(2.57812,-0.203125)(2.5625,-0.203125) + (2.5625,-0.1875)(2.57812,-0.1875)(2.57812,-0.171875)(2.59375,-0.171875) + (2.59375,-0.1875)(2.59375,-0.203125)(2.60938,-0.203125)(2.60938,-0.1875) + (2.625,-0.1875)(2.625,-0.203125)(2.64062,-0.203125)(2.64062,-0.21875) + (2.625,-0.21875)(2.60938,-0.21875)(2.60938,-0.234375)(2.625,-0.234375) + (2.625,-0.25)(2.625,-0.265625)(2.64062,-0.265625)(2.64062,-0.28125) +\path(2.64062,-0.28125)(2.625,-0.28125)(2.60938,-0.28125) + (2.60938,-0.296875)(2.625,-0.296875)(2.625,-0.3125)(2.64062,-0.3125) + (2.64062,-0.296875)(2.65625,-0.296875)(2.65625,-0.3125) + (2.65625,-0.328125)(2.67188,-0.328125)(2.67188,-0.3125)(2.6875,-0.3125) + (2.6875,-0.296875)(2.67188,-0.296875)(2.67188,-0.28125)(2.6875,-0.28125) + (2.70312,-0.28125)(2.70312,-0.265625)(2.6875,-0.265625)(2.6875,-0.25) + (2.70312,-0.25)(2.70312,-0.234375)(2.71875,-0.234375)(2.71875,-0.25) + (2.71875,-0.265625)(2.73438,-0.265625)(2.73438,-0.25)(2.75,-0.25) + (2.75,-0.234375)(2.73438,-0.234375)(2.73438,-0.21875)(2.75,-0.21875) + (2.76562,-0.21875)(2.76562,-0.203125)(2.75,-0.203125)(2.75,-0.1875) + (2.73438,-0.1875)(2.73438,-0.203125)(2.71875,-0.203125)(2.71875,-0.1875) + (2.71875,-0.171875)(2.70312,-0.171875)(2.70312,-0.1875)(2.6875,-0.1875) + (2.6875,-0.171875)(2.67188,-0.171875)(2.67188,-0.15625)(2.6875,-0.15625) + (2.70312,-0.15625)(2.70312,-0.140625)(2.6875,-0.140625)(2.6875,-0.125) + (2.70312,-0.125)(2.70312,-0.109375)(2.71875,-0.109375)(2.71875,-0.125) + (2.71875,-0.140625)(2.73438,-0.140625) +\path(2.73438,-0.140625)(2.73438,-0.125)(2.75,-0.125)(2.76562,-0.125) + (2.76562,-0.109375)(2.78125,-0.109375)(2.78125,-0.125)(2.78125,-0.140625) + (2.79688,-0.140625)(2.79688,-0.125)(2.8125,-0.125)(2.8125,-0.109375) + (2.79688,-0.109375)(2.79688,-0.09375)(2.8125,-0.09375)(2.82812,-0.09375) + (2.82812,-0.078125)(2.8125,-0.078125)(2.8125,-0.0625)(2.79688,-0.0625) + (2.79688,-0.078125)(2.78125,-0.078125)(2.78125,-0.0625) + (2.78125,-0.046875)(2.76562,-0.046875)(2.76562,-0.0625)(2.75,-0.0625) + (2.75,-0.046875)(2.73438,-0.046875)(2.73438,-0.03125)(2.75,-0.03125) + (2.76562,-0.03125)(2.76562,-0.015625)(2.75,-0.015625)(2.75,0)(2.76562,0) + (2.76562,0.015625)(2.78125,0.015625)(2.78125,0)(2.78125,-0.015625) + (2.79688,-0.015625)(2.79688,0)(2.8125,0)(2.8125,0.015625) + (2.79688,0.015625)(2.79688,0.03125)(2.8125,0.03125)(2.82812,0.03125) + (2.82812,0.046875)(2.8125,0.046875)(2.8125,0.0625)(2.82812,0.0625) + (2.82812,0.078125)(2.84375,0.078125)(2.84375,0.0625)(2.84375,0.046875) + (2.85938,0.046875)(2.85938,0.0625)(2.875,0.0625)(2.875,0.046875) +\path(2.875,0.046875)(2.89062,0.046875)(2.89062,0.03125)(2.875,0.03125) + (2.85938,0.03125)(2.85938,0.015625)(2.875,0.015625)(2.875,0) + (2.875,-0.015625)(2.89062,-0.015625)(2.89062,-0.03125)(2.875,-0.03125) + (2.85938,-0.03125)(2.85938,-0.046875)(2.875,-0.046875)(2.875,-0.0625) + (2.89062,-0.0625)(2.89062,-0.046875)(2.90625,-0.046875)(2.90625,-0.0625) + (2.90625,-0.078125)(2.92188,-0.078125)(2.92188,-0.0625)(2.9375,-0.0625) + (2.9375,-0.046875)(2.92188,-0.046875)(2.92188,-0.03125)(2.9375,-0.03125) + (2.95312,-0.03125)(2.95312,-0.015625)(2.9375,-0.015625)(2.9375,0) + (2.95312,0)(2.95312,0.015625)(2.96875,0.015625)(2.96875,0) + (2.96875,-0.015625)(2.98438,-0.015625)(2.98438,0)(3,0) +%% --- +\end{picture} diff --git a/graphics/epix/doc/koch.xp b/graphics/epix/doc/koch.xp new file mode 100644 index 0000000000..d1a04e1c0f --- /dev/null +++ b/graphics/epix/doc/koch.xp @@ -0,0 +1,24 @@ +/* -*-ePiX-*- */ +/* koch.c -- Simple fractal "curve" generation. -- June 6, 2002 */ + +#include "epix.h" +using namespace ePiX; + +// const int koch_seed[] = {6, 4, 0, 1, -1, 0}; +const int seed[] = {4, 8, 0, 1, 0, 3, 3, 0, 1, 0}; + +int main() +{ + bounding_box(P(0,0), P(3, 0.5)); + picture(P(3, 0.5)); + unitlength("1in"); + offset(P(0,0.25)); + + begin(); + + for (int i=1; i <= 3; ++i) + fractal(P(i-1,0), P(i,0), i, seed); + + end(); +} + diff --git a/graphics/epix/doc/layout.eepic b/graphics/epix/doc/layout.eepic new file mode 100644 index 0000000000..07eec3fcb6 --- /dev/null +++ b/graphics/epix/doc/layout.eepic @@ -0,0 +1,1511 @@ +%% Generated from layout.xp on Sat Jun 30 12:16:41 EDT 2007 by +%% ePiX-1.1.6 +%% +%% Cartesian bounding box: [0,2] x [0,3] +%% Actual size: 5 x 7.5in +%% Figure offset: left by 0in, down by 0in +%% +\xdefinecolor{rgb_000000}{rgb}{0,0,0} +\xdefinecolor{rgb_980000}{rgb}{0.596078,0,0} +\setlength{\unitlength}{1in} +\begin{picture}(5,7.5)(-0,-0) +\path(1.95438,5.77398)(1.9095,5.84756)(1.86459,5.91634) + (1.81949,5.98073)(1.77406,6.04108)(1.72817,6.09772) + (1.68169,6.15093)(1.63449,6.20095)(1.58643,6.24802) + (1.53738,6.29233)(1.4872,6.33406)(1.43575,6.37337)(1.38287,6.41039) + (1.32843,6.44527)(1.27224,6.4781)(1.21415,6.50899)(1.15394,6.53802) + (1.09144,6.56528)(1.02641,6.59083)(0.958625,6.61472) + (0.887817,6.63701)(0.813702,6.65773)(0.735966,6.67692) + (0.654259,6.69459)(0.568192,6.71076) +%% +\path(1.7999,5.73751)(1.76689,5.81018)(1.7333,5.87809) + (1.69903,5.94164)(1.66399,6.00118)(1.6281,6.05703)(1.59125,6.10945) + (1.55336,6.15868)(1.51431,6.20496)(1.47401,6.24846) + (1.43234,6.28936)(1.38918,6.32782)(1.34441,6.36396) + (1.29789,6.39792)(1.24946,6.4298)(1.19898,6.45968)(1.14626,6.48766) + (1.09112,6.5138)(1.03334,6.53816)(0.972699,6.5608) + (0.908939,6.58175)(0.841779,6.60103)(0.770903,6.61868) + (0.69596,6.6347)(0.616556,6.64908) +%% +\path(1.64758,5.71257)(1.62656,5.78375)(1.60445,5.85027) + (1.5812,5.91251)(1.55677,5.97079)(1.53112,6.02543)(1.50418,6.07667) + (1.4759,6.12475)(1.4462,6.16989)(1.41501,6.21226)(1.38225,6.25204) + (1.34781,6.28935)(1.31159,6.32435)(1.27348,6.35712) + (1.23334,6.38779)(1.19104,6.41643)(1.14642,6.44311)(1.09929,6.4679) + (1.04947,6.49085)(0.996736,6.512)(0.940842,6.53138)(0.881517,6.549) + (0.818452,6.56488)(0.7513,6.579)(0.679669,6.59135) +%% +\path(1.49959,5.69983)(1.49052,5.76899)(1.47988,5.83363) + (1.46769,5.89408)(1.45395,5.95068)(1.43865,6.00371)(1.42178,6.0534) + (1.4033,6.09999)(1.38319,6.14367)(1.36138,6.18461)(1.33782,6.22297) + (1.31245,6.25888)(1.28517,6.29246)(1.2559,6.32381)(1.22453,6.35304) + (1.19093,6.3802)(1.15497,6.40538)(1.11648,6.42861)(1.0753,6.44994) + (1.03121,6.4694)(0.983998,6.48701)(0.933394,6.50277) + (0.879107,6.51667)(0.820805,6.52869)(0.758105,6.53879) +%% +\path(1.35808,5.69964)(1.36071,5.7663)(1.36137,5.82859) + (1.36012,5.88685)(1.35701,5.94137)(1.35206,5.99243) + (1.34528,6.04024)(1.33669,6.08502)(1.32628,6.12695) + (1.31402,6.16618)(1.29989,6.20287)(1.28384,6.23713)(1.2658,6.26908) + (1.24573,6.2988)(1.22352,6.32638)(1.19908,6.35188)(1.17229,6.37536) + (1.14301,6.39686)(1.1111,6.41641)(1.07637,6.43402)(1.03861,6.4497) + (0.997597,6.46343)(0.953048,6.47519)(0.904656,6.48495)(0.852063,6.49264) +%% +\path(1.22499,5.71201)(1.23894,5.77574)(1.25058,5.83529) + (1.26001,5.89099)(1.26732,5.94311)(1.27257,5.99188) + (1.27581,6.03753)(1.27707,6.08023)(1.27637,6.12016) + (1.27372,6.15746)(1.26912,6.19226)(1.26255,6.22468)(1.25398,6.2548) + (1.24336,6.28272)(1.23063,6.30849)(1.21572,6.33218) + (1.19853,6.35383)(1.17897,6.37346)(1.1569,6.3911)(1.13216,6.40674) + (1.10459,6.42038)(1.07398,6.43198)(1.04008,6.44151) + (1.00263,6.44891)(0.961291,6.45409) +%% +\path(1.10205,5.73661)(1.12678,5.79705)(1.14894,5.85356) + (1.16867,5.90641)(1.18608,5.95585)(1.20126,6.00209)(1.2143,6.04534) + (1.22526,6.08575)(1.23418,6.12348)(1.2411,6.15867)(1.24604,6.19142) + (1.24901,6.22184)(1.25,6.25)(1.249,6.27598)(1.24597,6.29984) + (1.24087,6.32162)(1.23364,6.34134)(1.22419,6.35903) + (1.21243,6.37468)(1.19825,6.3883)(1.1815,6.39984)(1.16202,6.40927) + (1.13961,6.41653)(1.11404,6.42153)(1.08505,6.42418) +%% +\path(0.990653,5.77275)(1.02551,5.82968)(1.05762,5.88291) + (1.08714,5.93269)(1.11422,5.97925)(1.13897,6.02279)(1.1615,6.06346) + (1.18189,6.10143)(1.20023,6.13683)(1.21656,6.16978) + (1.23095,6.20036)(1.24341,6.22868)(1.25398,6.2548)(1.26266,6.27878) + (1.26945,6.30066)(1.27433,6.32047)(1.27727,6.33823) + (1.27824,6.35395)(1.27716,6.36761)(1.27397,6.37919) + (1.26857,6.38865)(1.26084,6.39593)(1.25063,6.40095) + (1.23778,6.40361)(1.22209,6.40378) +%% +\path(0.891818,5.81952)(0.936069,5.87276)(0.977467,5.92257) + (1.01619,5.96916)(1.05241,6.01272)(1.08626,6.05343) + (1.11788,6.09143)(1.14736,6.12687)(1.17482,6.15986) + (1.20032,6.19049)(1.22395,6.21886)(1.24576,6.24504)(1.2658,6.26908) + (1.28412,6.29103)(1.30073,6.31092)(1.31565,6.32877) + (1.32889,6.34458)(1.34044,6.35836)(1.35028,6.37006) + (1.35839,6.37967)(1.36472,6.38712)(1.3692,6.39234)(1.37176,6.39522) + (1.3723,6.39566)(1.37069,6.39349) +%% +\path(0.806183,5.87573)(0.85904,5.92524)(0.909007,5.97156) + (0.956284,6.01489)(1.00105,6.0554)(1.04347,6.09324) + (1.08369,6.12855)(1.12183,6.16142)(1.15802,6.19198) + (1.19236,6.22029)(1.22494,6.24644)(1.25585,6.27048) + (1.28517,6.29246)(1.31296,6.31241)(1.33928,6.33035) + (1.36418,6.34629)(1.3877,6.36022)(1.40988,6.37214)(1.43074,6.38199) + (1.4503,6.38973)(1.46858,6.3953)(1.48558,6.3986)(1.50128,6.39953) + (1.51567,6.39793)(1.52872,6.39365) +%% +\path(0.734,5.94009)(0.794644,5.98587)(0.852427,6.02873) + (0.907559,6.06882)(0.960235,6.1063)(1.01063,6.14129) + (1.05891,6.17391)(1.10521,6.20425)(1.14968,6.2324)(1.19244,6.25843) + (1.23361,6.28241)(1.27329,6.30437)(1.31159,6.32435)(1.3486,6.34237) + (1.38441,6.35845)(1.41911,6.37258)(1.45277,6.38474) + (1.48548,6.39492)(1.5173,6.40305)(1.54832,6.40909)(1.57859,6.41296) + (1.6082,6.41454)(1.63721,6.41373)(1.6657,6.41035)(1.69373,6.40423) +%% +\path(0.675166,6.01119)(0.742777,6.05334)(0.807609,6.09281) + (0.869881,6.12974)(0.929796,6.16426)(0.987543,6.19647) + (1.0433,6.22648)(1.09722,6.25436)(1.14946,6.28019)(1.20016,6.30402) + (1.24947,6.32591)(1.29751,6.34588)(1.34441,6.36396) + (1.39029,6.38017)(1.43528,6.39451)(1.47948,6.40696)(1.52302,6.4175) + (1.56602,6.42609)(1.60861,6.43269)(1.65091,6.43722)(1.69305,6.4396) + (1.73517,6.4397)(1.77744,6.43741)(1.82002,6.43255)(1.86308,6.42493) +%% +\path(0.62927,6.08763)(0.703045,6.12629)(0.774167,6.1625) + (0.842861,6.1964)(0.909337,6.22808)(0.973792,6.25763) + (1.03641,6.28514)(1.09737,6.31068)(1.15683,6.3343)(1.21496,6.35605) + (1.27191,6.37597)(1.32783,6.39408)(1.38287,6.41039) + (1.43719,6.42493)(1.49093,6.43766)(1.54425,6.44859) + (1.59729,6.45768)(1.65023,6.46488)(1.70324,6.47014) + (1.75649,6.47337)(1.81019,6.4745)(1.86455,6.47339)(1.9198,6.46991) + (1.97622,6.46388)(2.03409,6.4551) +%% +\path(1.95438,5.77398)(1.877,5.75436)(1.7999,5.73751) + (1.72333,5.72355)(1.64758,5.71257)(1.57291,5.70464) + (1.49959,5.69983)(1.4279,5.69816)(1.35808,5.69964)(1.29037,5.70427) + (1.22499,5.71201)(1.16216,5.72282)(1.10205,5.73661) + (1.04484,5.75329)(0.990653,5.77275)(0.939616,5.79488) + (0.891818,5.81952)(0.847326,5.84652)(0.806183,5.87573) + (0.768408,5.90698)(0.734,5.94009)(0.702933,5.97489) + (0.675166,6.01119)(0.650637,6.04883)(0.62927,6.08763) +%% +\path(1.86459,5.91634)(1.79875,5.89596)(1.7333,5.87809) + (1.66845,5.86282)(1.60445,5.85027)(1.54151,5.84052) + (1.47988,5.83363)(1.41976,5.82964)(1.36137,5.82859) + (1.30491,5.83047)(1.25058,5.83529)(1.19853,5.843)(1.14894,5.85356) + (1.10193,5.86689)(1.05762,5.88291)(1.01611,5.90151) + (0.977467,5.92257)(0.941756,5.94597)(0.909007,5.97156) + (0.879232,5.9992)(0.852427,6.02873)(0.828566,6.05999) + (0.807609,6.09281)(0.789499,6.12704)(0.774167,6.1625) +%% +\path(1.77406,6.04108)(1.71877,6.02)(1.66399,6.00118) + (1.60993,5.98475)(1.55677,5.97079)(1.50471,5.95942) + (1.45395,5.95068)(1.40465,5.94465)(1.35701,5.94137) + (1.31118,5.94086)(1.26732,5.94311)(1.22558,5.94812) + (1.18608,5.95585)(1.14892,5.96625)(1.11422,5.97925) + (1.08203,5.99478)(1.05241,6.01272)(1.02541,6.03297)(1.00105,6.0554) + (0.97933,6.07989)(0.960235,6.1063)(0.943738,6.13447) + (0.929796,6.16426)(0.918352,6.19551)(0.909337,6.22808) +%% +\path(1.68169,6.15093)(1.63613,6.12916)(1.59125,6.10945) + (1.54721,6.09191)(1.50418,6.07667)(1.46232,6.0638)(1.42178,6.0534) + (1.38272,6.04553)(1.34528,6.04024)(1.3096,6.03757)(1.27581,6.03753) + (1.24401,6.04012)(1.2143,6.04534)(1.18677,6.05313)(1.1615,6.06346) + (1.13852,6.07626)(1.11788,6.09143)(1.0996,6.1089)(1.08369,6.12855) + (1.07013,6.15026)(1.05891,6.17391)(1.04998,6.19936)(1.0433,6.22648) + (1.0388,6.25512)(1.03641,6.28514) +%% +\path(1.58643,6.24802)(1.54994,6.22555)(1.51431,6.20496) + (1.47969,6.18637)(1.4462,6.16989)(1.41399,6.15563)(1.38319,6.14367) + (1.35391,6.13409)(1.32628,6.12695)(1.3004,6.12229)(1.27637,6.12016) + (1.25427,6.12056)(1.23418,6.12348)(1.21615,6.12892) + (1.20023,6.13683)(1.18644,6.14717)(1.17482,6.15986) + (1.16535,6.17483)(1.15802,6.19198)(1.15281,6.21121)(1.14968,6.2324) + (1.14858,6.25544)(1.14946,6.28019)(1.15223,6.30652)(1.15683,6.3343) +%% +\path(1.4872,6.33406)(1.45923,6.31085)(1.43234,6.28936) + (1.40664,6.26972)(1.38225,6.25204)(1.35927,6.23642) + (1.33782,6.22297)(1.318,6.21176)(1.29989,6.20287)(1.28357,6.19636) + (1.26912,6.19226)(1.2566,6.19061)(1.24604,6.19142)(1.23748,6.19468) + (1.23095,6.20036)(1.22644,6.20844)(1.22395,6.21886) + (1.22346,6.23156)(1.22494,6.24644)(1.22834,6.26342) + (1.23361,6.28241)(1.24068,6.30328)(1.24947,6.32591) + (1.25991,6.35018)(1.27191,6.37597) +%% +\path(1.38287,6.41039)(1.36299,6.38639)(1.34441,6.36396) + (1.32725,6.34324)(1.31159,6.32435)(1.29754,6.30738) + (1.28517,6.29246)(1.27457,6.27966)(1.2658,6.26908)(1.25892,6.26077) + (1.25398,6.2548)(1.251,6.2512)(1.25,6.25)(1.251,6.2512) + (1.25398,6.2548)(1.25892,6.26077)(1.2658,6.26908)(1.27457,6.27966) + (1.28517,6.29246)(1.29754,6.30738)(1.31159,6.32435) + (1.32725,6.34324)(1.34441,6.36396)(1.36299,6.38639)(1.38287,6.41039) +%% +\path(1.27224,6.4781)(1.26007,6.45322)(1.24946,6.4298) + (1.24053,6.40794)(1.23334,6.38779)(1.22799,6.36945) + (1.22453,6.35304)(1.22302,6.33865)(1.22352,6.32638) + (1.22604,6.31631)(1.23063,6.30849)(1.23727,6.30299) + (1.24597,6.29984)(1.25671,6.29906)(1.26945,6.30066) + (1.28414,6.30462)(1.30073,6.31092)(1.31913,6.31951) + (1.33928,6.33035)(1.36108,6.34335)(1.38441,6.35845) + (1.40918,6.37553)(1.43528,6.39451)(1.46257,6.41526)(1.49093,6.43766) +%% +\path(1.15394,6.53802)(1.14916,6.51218)(1.14626,6.48766) + (1.14532,6.46459)(1.14642,6.44311)(1.14962,6.42333) + (1.15497,6.40538)(1.16252,6.38935)(1.17229,6.37536)(1.18429,6.3635) + (1.19853,6.35383)(1.21499,6.34643)(1.23364,6.34134)(1.25442,6.3386) + (1.27727,6.33823)(1.30213,6.34023)(1.32889,6.34458) + (1.35745,6.35126)(1.3877,6.36022)(1.41952,6.37141)(1.45277,6.38474) + (1.48732,6.40014)(1.52302,6.4175)(1.55973,6.43672)(1.59729,6.45768) +%% +\path(1.02641,6.59083)(1.02876,6.56389)(1.03334,6.53816) + (1.04022,6.51377)(1.04947,6.49085)(1.06115,6.46953)(1.0753,6.44994) + (1.09195,6.4322)(1.1111,6.41641)(1.13276,6.40268)(1.1569,6.3911) + (1.18348,6.38175)(1.21243,6.37468)(1.24369,6.36996) + (1.27716,6.36761)(1.31274,6.36764)(1.35028,6.37006) + (1.38967,6.37486)(1.43074,6.38199)(1.47334,6.39141)(1.5173,6.40305) + (1.56245,6.41685)(1.60861,6.43269)(1.6556,6.45049)(1.70324,6.47014) +%% +\path(0.887817,6.63701)(0.897069,6.60884)(0.908939,6.58175) + (0.923508,6.55588)(0.940842,6.53138)(0.960994,6.50838) + (0.983998,6.48701)(1.00987,6.46741)(1.03861,6.4497)(1.0702,6.43398) + (1.10459,6.42038)(1.14172,6.40897)(1.1815,6.39984)(1.22383,6.39305) + (1.26857,6.38865)(1.31559,6.38667)(1.36472,6.38712) + (1.41578,6.39001)(1.46858,6.3953)(1.52292,6.40297)(1.57859,6.41296) + (1.63537,6.42519)(1.69305,6.4396)(1.75139,6.45607)(1.81019,6.4745) +%% +\path(0.735966,6.67692)(0.7519,6.64732)(0.770903,6.61868) + (0.793063,6.59115)(0.818452,6.56488)(0.847122,6.54) + (0.879107,6.51667)(0.91442,6.49502)(0.953048,6.47519) + (0.994955,6.45732)(1.04008,6.44151)(1.08834,6.42788) + (1.13961,6.41653)(1.19376,6.40753)(1.25063,6.40095) + (1.31003,6.39684)(1.37176,6.39522)(1.43559,6.39612) + (1.50128,6.39953)(1.56857,6.40541)(1.63721,6.41373) + (1.70692,6.42442)(1.77744,6.43741)(1.84849,6.45261)(1.9198,6.46991) +%% +\path(0.568192,6.71076)(0.590579,6.67951)(0.616556,6.64908) + (0.646225,6.61965)(0.679669,6.59135)(0.716949,6.56435) + (0.758105,6.53879)(0.803148,6.51484)(0.852063,6.49264) + (0.904803,6.47235)(0.961291,6.45409)(1.02142,6.43799) + (1.08505,6.42418)(1.15201,6.41274)(1.22209,6.40378) + (1.29507,6.39734)(1.37069,6.39349)(1.44868,6.39226) + (1.52872,6.39365)(1.61052,6.39765)(1.69373,6.40423) + (1.77803,6.41335)(1.86308,6.42493)(1.94854,6.43888)(2.03409,6.4551) +%% +\path(1.25,6.25)(0.90831,5.83754) +%% +\path(0.929086,5.88702)(0.940008,5.90021) +\path(0.922161,5.87053)(0.944004,5.8969) +\path(0.915235,5.85404)(0.947999,5.89359) +\path(0.90831,5.83754)(0.951995,5.89028) +\path(0.923227,5.84742)(0.955991,5.88697) +\path(0.938144,5.85729)(0.959987,5.88366) +\path(0.953061,5.86716)(0.963983,5.88035) +\path(0.951995,5.89028)(0.936012,5.90352)(0.90831,5.83754) + (0.967979,5.87704)(0.951995,5.89028) +%% +\path(1.25,6.25)(1.9921,6.09631) +%% +\path(1.90984,6.09745)(1.88348,6.10291) +\path(1.93726,6.09707)(1.88453,6.10799) +\path(1.96468,6.09669)(1.88558,6.11307) +\path(1.9921,6.09631)(1.88663,6.11815) +\path(1.96678,6.10685)(1.88768,6.12323) +\path(1.94147,6.11739)(1.88874,6.12831) +\path(1.91616,6.12793)(1.88979,6.13339) +\path(1.88663,6.11815)(1.88242,6.09782)(1.9921,6.09631) + (1.89084,6.13847)(1.88663,6.11815) +%% +\allinethickness{1pt}% +\color{rgb_980000}% +\path(2.375,5.125) + (2.375,7.375)(0.125,7.375)(0.125,5.125)(2.375,5.125) +%% +\allinethickness{0.4pt}% +\color{rgb_000000}% +\path(1.57249,2.99581) + (1.60208,3.08238)(1.62568,3.16486)(1.6436,3.24353)(1.65613,3.31869) + (1.66348,3.39059)(1.66589,3.45945)(1.66353,3.52548) + (1.65656,3.58888)(1.64515,3.64982)(1.6294,3.70847)(1.60943,3.76497) + (1.58534,3.81945)(1.5572,3.87205)(1.52509,3.92289)(1.48905,3.97206) + (1.44912,4.01968)(1.40534,4.06584)(1.35773,4.11062)(1.3063,4.15411) + (1.25104,4.19638)(1.19195,4.23751)(1.129,4.27756)(1.06218,4.3166)(0.991435,4.35469) +%% +\path(1.39706,3.04908)(1.43364,3.12654)(1.46419,3.20061) + (1.48899,3.27155)(1.50828,3.33955)(1.52226,3.40482) + (1.53114,3.46754)(1.53508,3.52788)(1.53423,3.58598)(1.5287,3.64199) + (1.51863,3.69603)(1.50409,3.74824)(1.48518,3.79871) + (1.46195,3.84755)(1.43447,3.89487)(1.40276,3.94074) + (1.36687,3.98526)(1.3268,4.02851)(1.28256,4.07055)(1.23414,4.11145) + (1.18153,4.1513)(1.12471,4.19013)(1.06363,4.22802) + (0.998248,4.26502)(0.928503,4.30119) +%% +\path(1.24877,3.10605)(1.29092,3.17474)(1.32712,3.24068) + (1.3576,3.30403)(1.38257,3.36496)(1.40221,3.42363)(1.41669,3.48018) + (1.42614,3.53473)(1.43068,3.5874)(1.43043,3.6383)(1.42548,3.68755) + (1.4159,3.73523)(1.40174,3.78143)(1.38307,3.82624)(1.35991,3.86973) + (1.33228,3.91199)(1.3002,3.95308)(1.26366,3.99306)(1.22265,4.03201) + (1.17713,4.06997)(1.12708,4.107)(1.07245,4.14315)(1.01316,4.17848) + (0.94915,4.21303)(0.88033,4.24685) +%% +\path(1.12691,3.16617)(1.17344,3.22652)(1.21419,3.28463) + (1.24934,3.34063)(1.27907,3.39466)(1.30353,3.44682) + (1.32285,3.49721)(1.33713,3.54595)(1.34648,3.59312) + (1.35097,3.63881)(1.35067,3.68311)(1.34564,3.72607)(1.3359,3.76779) + (1.32149,3.80832)(1.30242,3.84773)(1.27869,3.88608) + (1.25028,3.92343)(1.21716,3.95982)(1.17931,3.99531) + (1.13666,4.02995)(1.08914,4.06378)(1.0367,4.09685)(0.979215,4.1292) + (0.916597,4.16087)(0.848721,4.19189) +%% +\path(1.03051,3.22888)(1.08046,3.28136)(1.12486,3.33203) + (1.16386,3.38098)(1.1976,3.42832)(1.22618,3.47411)(1.24971,3.51846) + (1.26827,3.56143)(1.28193,3.60309)(1.29073,3.64351) + (1.29472,3.68275)(1.29392,3.72088)(1.28835,3.75794)(1.27801,3.794) + (1.26288,3.82909)(1.24294,3.86327)(1.21815,3.89658) + (1.18844,3.92907)(1.15376,3.96077)(1.11403,3.99173) + (1.06914,4.02198)(1.01898,4.05155)(0.963433,4.08048) + (0.902342,4.10881)(0.835544,4.13656) +%% +\path(0.958412,3.29368)(1.01103,3.3388)(1.05838,3.38244) + (1.10059,3.42468)(1.13773,3.4656)(1.1699,3.50525)(1.19715,3.54369) + (1.21956,3.58099)(1.23714,3.61719)(1.24993,3.65234)(1.25794,3.6865) + (1.26117,3.7197)(1.25961,3.75199)(1.25324,3.78341)(1.242,3.814) + (1.22584,3.84379)(1.20471,3.87282)(1.1785,3.90111)(1.14713,3.92871) + (1.11049,3.95563)(1.06842,3.98191)(1.02079,4.00758) + (0.967431,4.03266)(0.90814,4.05717)(0.842708,4.08114) +%% +\path(0.909289,3.36006)(0.964025,3.39834)(1.01381,3.43541) + (1.05873,3.47132)(1.09883,3.50614)(1.13418,3.5399)(1.16481,3.57265) + (1.19075,3.60442)(1.212,3.63526)(1.22857,3.66521)(1.24045,3.69429) + (1.2476,3.72255)(1.25,3.75)(1.24758,3.77668)(1.24029,3.80262) + (1.22803,3.82784)(1.21071,3.85236)(1.18821,3.87622)(1.1604,3.89941) + (1.12714,3.92198)(1.08825,3.94394)(1.04353,3.9653) + (0.992768,3.98607)(0.935726,4.00629)(0.872128,4.02595) +%% +\path(0.881704,3.42756)(0.938175,3.45953)(0.990033,3.4905) + (1.03733,3.5205)(1.08009,3.54957)(1.11835,3.57774)(1.15212,3.60504) + (1.1814,3.63149)(1.20618,3.65713)(1.22644,3.68198)(1.24213,3.70606) + (1.25321,3.72939)(1.25961,3.75199)(1.26127,3.77388) + (1.25808,3.79508)(1.24993,3.8156)(1.2367,3.83545)(1.21824,3.85464) + (1.19439,3.87319)(1.16495,3.89111)(1.12973,3.9084)(1.08847,3.92506) + (1.04091,3.94111)(0.986766,3.95654)(0.92569,3.97136) +%% +\path(0.874138,3.49573)(0.93211,3.52194)(0.985819,3.54729) + (1.03529,3.5718)(1.08054,3.5955)(1.12156,3.61841)(1.15836,3.64055) + (1.19091,3.66193)(1.21917,3.68256)(1.24311,3.70247) + (1.26267,3.72167)(1.27778,3.74015)(1.28835,3.75794) + (1.29429,3.77504)(1.29547,3.79146)(1.29177,3.80719) + (1.28303,3.82225)(1.26907,3.83662)(1.2497,3.85032)(1.22469,3.86333) + (1.1938,3.87564)(1.15674,3.88726)(1.1132,3.89816)(1.06282,3.90834)(1.0052,3.91777) +%% +\path(0.885031,3.56419)(0.944391,3.58516)(0.999849,3.60537) + (1.05141,3.62484)(1.09907,3.64357)(1.14282,3.66157) + (1.18263,3.67886)(1.21846,3.69544)(1.25027,3.71131)(1.278,3.72648) + (1.30157,3.74095)(1.32091,3.75472)(1.3359,3.76779)(1.34643,3.78015) + (1.35237,3.7918)(1.35356,3.80272)(1.34982,3.81291)(1.34096,3.82236) + (1.32674,3.83103)(1.30692,3.83893)(1.28121,3.84601) + (1.24929,3.85226)(1.21078,3.85763)(1.16529,3.8621)(1.11235,3.86562) +%% +\path(0.912807,3.63258)(0.973544,3.64883)(1.03075,3.66437) + (1.0844,3.67923)(1.1345,3.69339)(1.18102,3.70686)(1.22391,3.71963) + (1.26313,3.73171)(1.29863,3.74309)(1.33033,3.75376) + (1.35815,3.76372)(1.38199,3.77294)(1.40174,3.78143) + (1.41728,3.78915)(1.42844,3.7961)(1.43507,3.80224)(1.43696,3.80755) + (1.43391,3.812)(1.42567,3.81556)(1.41195,3.81818)(1.39244,3.81982) + (1.36679,3.82042)(1.33458,3.81993)(1.29537,3.81827)(1.24863,3.81537) +%% +\path(0.955906,3.70059)(1.01809,3.7126)(1.0771,3.72394) + (1.13294,3.73461)(1.18557,3.74461)(1.23497,3.75392) + (1.28108,3.76253)(1.32387,3.77044)(1.36326,3.77762) + (1.39918,3.78406)(1.43155,3.78974)(1.46025,3.79463) + (1.48518,3.79871)(1.5062,3.80194)(1.52314,3.8043)(1.53585,3.80574) + (1.54411,3.80622)(1.54771,3.80568)(1.54637,3.80407) + (1.53982,3.80133)(1.52771,3.79737)(1.50967,3.79211) + (1.48526,3.78546)(1.45399,3.7773)(1.4153,3.76751) +%% +\path(1.0128,3.76793)(1.07655,3.77617)(1.13751,3.78375) + (1.19566,3.79067)(1.25098,3.7969)(1.30343,3.80242)(1.35296,3.80723) + (1.39954,3.81129)(1.44308,3.81459)(1.48353,3.81709) + (1.52079,3.81875)(1.55477,3.81956)(1.58534,3.81945) + (1.61238,3.81839)(1.63574,3.81633)(1.65524,3.8132)(1.67069,3.80894) + (1.68186,3.80347)(1.68849,3.79671)(1.6903,3.78856)(1.68695,3.77892) + (1.67805,3.76764)(1.66317,3.7546)(1.64178,3.73963)(1.61332,3.72254) +%% +\path(1.57249,2.99581)(1.48135,3.02195)(1.39706,3.04908) + (1.31956,3.07714)(1.24877,3.10605)(1.1846,3.13575)(1.12691,3.16617) + (1.0756,3.19723)(1.03051,3.22888)(0.991504,3.26105) + (0.958412,3.29368)(0.931066,3.3267)(0.909289,3.36006) + (0.892898,3.3937)(0.881704,3.42756)(0.875516,3.46158) + (0.874138,3.49573)(0.877376,3.52995)(0.885031,3.56419) + (0.896906,3.59842)(0.912807,3.63258)(0.932537,3.66665) + (0.955906,3.70059)(0.982723,3.73436)(1.0128,3.76793) +%% +\path(1.62568,3.16486)(1.54188,3.18217)(1.46419,3.20061) + (1.39261,3.22013)(1.32712,3.24068)(1.26766,3.26219) + (1.21419,3.28463)(1.16661,3.30793)(1.12486,3.33203) + (1.08882,3.35689)(1.05838,3.38244)(1.03343,3.40863) + (1.01381,3.43541)(0.999398,3.46271)(0.990033,3.4905) + (0.985561,3.51871)(0.985819,3.54729)(0.990638,3.57619) + (0.999849,3.60537)(1.01328,3.63478)(1.03075,3.66437) + (1.05208,3.69411)(1.0771,3.72394)(1.10564,3.75384)(1.13751,3.78375) +%% +\path(1.65613,3.31869)(1.57945,3.32854)(1.50828,3.33955) + (1.44265,3.3517)(1.38257,3.36496)(1.32805,3.37929)(1.27907,3.39466) + (1.2356,3.41101)(1.1976,3.42832)(1.165,3.44653)(1.13773,3.4656) + (1.11571,3.48548)(1.09883,3.50614)(1.087,3.52752)(1.08009,3.54957) + (1.07798,3.57225)(1.08054,3.5955)(1.08762,3.61929)(1.09907,3.64357) + (1.11475,3.66828)(1.1345,3.69339)(1.15816,3.71885)(1.18557,3.74461) + (1.21656,3.77064)(1.25098,3.7969) +%% +\path(1.66589,3.45945)(1.59601,3.46292)(1.53114,3.46754) + (1.47135,3.4733)(1.41669,3.48018)(1.36718,3.48816)(1.32285,3.49721) + (1.2837,3.50732)(1.24971,3.51846)(1.22088,3.53059)(1.19715,3.54369) + (1.17849,3.55772)(1.16481,3.57265)(1.15605,3.58843) + (1.15212,3.60504)(1.15293,3.62242)(1.15836,3.64055)(1.1683,3.65937) + (1.18263,3.67886)(1.20121,3.69896)(1.22391,3.71963) + (1.25058,3.74084)(1.28108,3.76253)(1.31526,3.78468)(1.35296,3.80723) +%% +\path(1.65656,3.58888)(1.59309,3.58689)(1.53423,3.58598) + (1.48007,3.58615)(1.43068,3.5874)(1.38614,3.58973)(1.34648,3.59312) + (1.31173,3.59758)(1.28193,3.60309)(1.25706,3.60963) + (1.23714,3.61719)(1.22213,3.62574)(1.212,3.63526)(1.2067,3.64574) + (1.20618,3.65713)(1.21037,3.66942)(1.21917,3.68256) + (1.23251,3.69654)(1.25027,3.71131)(1.27235,3.72684) + (1.29863,3.74309)(1.32898,3.76003)(1.36326,3.77762) + (1.40135,3.79582)(1.44308,3.81459) +%% +\path(1.6294,3.70847)(1.57186,3.70176)(1.51863,3.69603) + (1.4698,3.69129)(1.42548,3.68755)(1.38575,3.68482)(1.35067,3.68311) + (1.32031,3.68242)(1.29472,3.68275)(1.27392,3.68411)(1.25794,3.6865) + (1.24679,3.68989)(1.24045,3.69429)(1.23891,3.69969) + (1.24213,3.70606)(1.25007,3.71339)(1.26267,3.72167) + (1.27987,3.73086)(1.30157,3.74095)(1.3277,3.75191)(1.35815,3.76372) + (1.3928,3.77634)(1.43155,3.78974)(1.47426,3.80389)(1.52079,3.81875) +%% +\path(1.58534,3.81945)(1.53323,3.80866)(1.48518,3.79871) + (1.44131,3.78962)(1.40174,3.78143)(1.36658,3.77414)(1.3359,3.76779) + (1.3098,3.76239)(1.28835,3.75794)(1.27161,3.75448)(1.25961,3.75199) + (1.25241,3.7505)(1.25,3.75)(1.25241,3.7505)(1.25961,3.75199) + (1.27161,3.75448)(1.28835,3.75794)(1.3098,3.76239)(1.3359,3.76779) + (1.36658,3.77414)(1.40174,3.78143)(1.44131,3.78962) + (1.48518,3.79871)(1.53323,3.80866)(1.58534,3.81945) +%% +\path(1.52509,3.92289)(1.47784,3.90853)(1.43447,3.89487) + (1.39512,3.88192)(1.35991,3.86973)(1.32897,3.85833) + (1.30242,3.84773)(1.28036,3.83798)(1.26288,3.82909) + (1.25007,3.82109)(1.242,3.814)(1.23872,3.80784)(1.24029,3.80262) + (1.24673,3.79836)(1.25808,3.79508)(1.27433,3.79277) + (1.29547,3.79146)(1.3215,3.79113)(1.35237,3.7918)(1.38804,3.79345) + (1.42844,3.7961)(1.47351,3.79972)(1.52314,3.8043)(1.57726,3.80985)(1.63574,3.81633) +%% +\path(1.44912,4.01968)(1.40612,4.00221)(1.36687,3.98526) + (1.33151,3.96887)(1.3002,3.95308)(1.27308,3.93792)(1.25028,3.92343) + (1.23193,3.90964)(1.21815,3.89658)(1.20904,3.8843)(1.20471,3.87282) + (1.20524,3.86216)(1.21071,3.85236)(1.22118,3.84345)(1.2367,3.83545) + (1.25731,3.82837)(1.28303,3.82225)(1.31387,3.81709) + (1.34982,3.81291)(1.39086,3.80973)(1.43696,3.80755) + (1.48807,3.80638)(1.54411,3.80622)(1.60502,3.80707)(1.67069,3.80894) +%% +\path(1.35773,4.11062)(1.31832,4.09041)(1.28256,4.07055) + (1.25061,4.05107)(1.22265,4.03201)(1.19883,4.01341) + (1.17931,3.99531)(1.16424,3.97775)(1.15376,3.96077) + (1.14802,3.94441)(1.14713,3.92871)(1.15123,3.91369)(1.1604,3.89941) + (1.17476,3.8859)(1.19439,3.87319)(1.21935,3.86132)(1.2497,3.85032) + (1.28549,3.84021)(1.32674,3.83103)(1.37347,3.82281) + (1.42567,3.81556)(1.48331,3.80931)(1.54637,3.80407) + (1.61479,3.79987)(1.68849,3.79671) +%% +\path(1.25104,4.19638)(1.2145,4.17376)(1.18153,4.1513) + (1.15234,4.12903)(1.12708,4.107)(1.10596,4.08523)(1.08914,4.06378) + (1.07681,4.04268)(1.06914,4.02198)(1.06629,4.00171) + (1.06842,3.98191)(1.07569,3.96264)(1.08825,3.94394) + (1.10622,3.92584)(1.12973,3.9084)(1.15889,3.89165)(1.1938,3.87564) + (1.23455,3.86042)(1.28121,3.84601)(1.33383,3.83246) + (1.39244,3.81982)(1.45707,3.80811)(1.52771,3.79737) + (1.60435,3.78763)(1.68695,3.77892) +%% +\path(1.129,4.27756)(1.09455,4.25281)(1.06363,4.22802) + (1.03643,4.20324)(1.01316,4.17848)(0.994019,4.15379) + (0.979215,4.1292)(0.968952,4.10475)(0.963433,4.08048) + (0.96286,4.05644)(0.967431,4.03266)(0.977337,4.00919) + (0.992768,3.98607)(1.0139,3.96337)(1.04091,3.94111) + (1.07396,3.91936)(1.1132,3.89816)(1.15877,3.87757)(1.21078,3.85763) + (1.26936,3.8384)(1.33458,3.81993)(1.40653,3.80226)(1.48526,3.78546) + (1.5708,3.76955)(1.66317,3.7546) +%% +\path(0.991435,4.35469)(0.958234,4.32805)(0.928503,4.30119) + (0.902461,4.27411)(0.88033,4.24685)(0.862339,4.21944) + (0.848721,4.19189)(0.83971,4.16426)(0.835544,4.13656) + (0.836464,4.10884)(0.842708,4.08114)(0.854517,4.05349) + (0.872128,4.02595)(0.895776,3.99856)(0.92569,3.97136) + (0.962093,3.94442)(1.0052,3.91777)(1.05522,3.89149) + (1.11235,3.86562)(1.17676,3.84023)(1.24863,3.81537)(1.3281,3.79111) + (1.4153,3.76751)(1.51034,3.74463)(1.61332,3.72254) +%% +\path(1.25,3.75)(0.507902,3.59631) +%% +\path(0.583844,3.62793)(0.610211,3.63339) +\path(0.55853,3.61739)(0.611263,3.62831) +\path(0.533216,3.60685)(0.612315,3.62323) +\path(0.507902,3.59631)(0.613368,3.61815) +\path(0.535321,3.59669)(0.61442,3.61307) +\path(0.56274,3.59707)(0.615472,3.60799) +\path(0.590158,3.59745)(0.616525,3.60291) +\path(0.613368,3.61815)(0.609159,3.63847)(0.507902,3.59631) + (0.617577,3.59782)(0.613368,3.61815) +%% +\path(1.25,3.75)(1.59169,3.33754) +%% +\path(1.54694,3.36716)(1.53602,3.38035) +\path(1.56186,3.35729)(1.54001,3.38366) +\path(1.57677,3.34742)(1.54401,3.38697) +\path(1.59169,3.33754)(1.548,3.39028) +\path(1.58476,3.35404)(1.552,3.39359) +\path(1.57784,3.37053)(1.556,3.3969) +\path(1.57091,3.38702)(1.55999,3.40021) +\path(1.548,3.39028)(1.53202,3.37704)(1.59169,3.33754) + (1.56399,3.40352)(1.548,3.39028) +%% +\allinethickness{1pt}% +\color{rgb_980000}% +\path(2.375,2.625) + (2.375,4.875)(0.125,4.875)(0.125,2.625)(2.375,2.625) +%% +\allinethickness{0.4pt}% +\color{rgb_000000}% +\path + (0.927506,0.495809)(1.01757,0.548834)(1.10157,0.602843) + (1.17947,0.657739)(1.25125,0.713425)(1.3169,0.769804) + (1.37643,0.826777)(1.42989,0.884247)(1.47732,0.94212) + (1.51879,1.0003)(1.55438,1.0587)(1.58419,1.11722)(1.60833,1.17579) + (1.62692,1.23431)(1.64008,1.2927)(1.64797,1.35089)(1.65074,1.40881) + (1.64854,1.46638)(1.64154,1.52354)(1.62991,1.58023) + (1.61383,1.63639)(1.59347,1.69196)(1.56902,1.7469)(1.54066,1.80115)(1.50857,1.85469) +%% +\path(0.8777,0.611715)(0.959433,0.655571)(1.03581,0.700614) + (1.10675,0.74677)(1.17219,0.793961)(1.2321,0.842109) + (1.28645,0.891132)(1.33522,0.940947)(1.37842,0.991473) + (1.41609,1.04262)(1.44824,1.09432)(1.47494,1.14647)(1.49626,1.199) + (1.51227,1.25182)(1.52307,1.30486)(1.52876,1.35804) + (1.52946,1.41127)(1.52529,1.46449)(1.51639,1.51763)(1.5029,1.57062) + (1.48496,1.62339)(1.46273,1.67588)(1.43637,1.72802) + (1.40604,1.77978)(1.37192,1.83108) +%% +\path(0.850911,0.713606)(0.924836,0.749547)(0.993963,0.786789) + (1.05819,0.825281)(1.11743,0.864964)(1.17161,0.905781) + (1.22068,0.947667)(1.26458,0.990557)(1.3033,1.03438) + (1.33682,1.07908)(1.36514,1.12456)(1.38829,1.17077) + (1.40628,1.21763)(1.41917,1.26507)(1.42702,1.313)(1.42989,1.36136) + (1.42787,1.41007)(1.42105,1.45906)(1.40954,1.50826) + (1.39346,1.55759)(1.37292,1.607)(1.34805,1.6564)(1.31901,1.70574) + (1.28592,1.75496)(1.24895,1.80399) +%% +\path(0.844563,0.803527)(0.911256,0.832549)(0.97359,0.862922) + (1.03145,0.894614)(1.08472,0.927588)(1.13332,0.961802) + (1.17715,0.997213)(1.21616,1.03377)(1.25029,1.07143) + (1.27949,1.11013)(1.30374,1.14982)(1.32302,1.19043) + (1.33734,1.23191)(1.3467,1.27419)(1.35115,1.31721)(1.35071,1.3609) + (1.34544,1.40519)(1.33541,1.45002)(1.32069,1.49531) + (1.30138,1.54101)(1.27758,1.58703)(1.24938,1.63332)(1.21692,1.6798) + (1.18032,1.72642)(1.13972,1.7731) +%% +\path(0.856643,0.883119)(0.916712,0.906022)(0.972764,0.930277) + (1.02467,0.955868)(1.0723,0.982778)(1.11556,1.01098) + (1.15433,1.04046)(1.18853,1.07117)(1.21807,1.10309) + (1.24291,1.13617)(1.26297,1.17038)(1.27822,1.20567)(1.28864,1.242) + (1.2942,1.27931)(1.29492,1.31754)(1.29079,1.35666)(1.28185,1.39658) + (1.26815,1.43727)(1.24972,1.47865)(1.22664,1.52067) + (1.19897,1.56326)(1.16682,1.60635)(1.13027,1.64988) + (1.08945,1.69379)(1.04445,1.73802) +%% +\path(0.885577,0.953717)(0.93965,0.971145)(0.989968,0.989888) + (1.03639,1.00995)(1.07878,1.03132)(1.11702,1.05399) + (1.15098,1.07797)(1.18055,1.10322)(1.20565,1.12975) + (1.22618,1.15751)(1.24206,1.1865)(1.25323,1.21667)(1.25963,1.24801) + (1.26123,1.28046)(1.258,1.314)(1.24993,1.34858)(1.23701,1.38415) + (1.21926,1.42067)(1.1967,1.45809)(1.16937,1.49635)(1.13734,1.5354) + (1.10065,1.57517)(1.0594,1.61562)(1.01366,1.65667)(0.963551,1.69828) +%% +\path(0.930139,1.01641)(0.97886,1.02889)(1.02402,1.04261) + (1.06548,1.05759)(1.10308,1.07385)(1.13669,1.09139) + (1.16618,1.11021)(1.19141,1.13032)(1.21227,1.15172)(1.22866,1.1744) + (1.24046,1.19834)(1.2476,1.22355)(1.25,1.25)(1.24758,1.27767) + (1.2403,1.30654)(1.22812,1.33658)(1.211,1.36775)(1.18893,1.40004) + (1.16191,1.43338)(1.12996,1.46775)(1.0931,1.50311)(1.05137,1.53939) + (1.00483,1.57655)(0.95355,1.61455)(0.897604,1.65331) +%% +\path(0.989383,1.07211)(1.03341,1.08005)(1.07402,1.08915) + (1.11107,1.09943)(1.14439,1.11092)(1.17383,1.12362) + (1.19925,1.13757)(1.22049,1.15278)(1.23743,1.16926) + (1.24993,1.18702)(1.25787,1.20606)(1.26114,1.22639) + (1.25963,1.24801)(1.25325,1.2709)(1.24192,1.29508)(1.22557,1.32052) + (1.20414,1.3472)(1.17758,1.37511)(1.14587,1.40423)(1.10898,1.43452) + (1.06692,1.46596)(1.0197,1.49852)(0.967353,1.53214) + (0.909912,1.5668)(0.84744,1.60244) +%% +\path(1.0626,1.12156)(1.1026,1.12531)(1.1393,1.1301) + (1.17253,1.13598)(1.20212,1.14296)(1.22791,1.15108) + (1.24973,1.16037)(1.26742,1.17086)(1.28083,1.18256)(1.2898,1.19551) + (1.29418,1.20972)(1.29384,1.22521)(1.28864,1.242)(1.27846,1.26009) + (1.26319,1.27949)(1.24272,1.30021)(1.21697,1.32225)(1.18585,1.3456) + (1.14931,1.37026)(1.10728,1.39622)(1.05973,1.42347) + (1.00664,1.45198)(0.948007,1.48173)(0.883841,1.51269)(0.81417,1.54484) +%% +\path(1.14927,1.16539)(1.18593,1.16521)(1.21938,1.16596) + (1.24942,1.16766)(1.27589,1.17035)(1.2986,1.17407)(1.31737,1.17886) + (1.33202,1.18475)(1.34238,1.19178)(1.34825,1.19998) + (1.34948,1.20938)(1.3459,1.22002)(1.33734,1.23191)(1.32364,1.2451) + (1.30466,1.25959)(1.28026,1.27541)(1.2503,1.29259)(1.21467,1.31112) + (1.17326,1.33103)(1.12598,1.35233)(1.07274,1.375)(1.01349,1.39906) + (0.948177,1.4245)(0.876769,1.45131)(0.799255,1.47948) +%% +\path(1.24904,1.20411)(1.28307,1.20023)(1.31396,1.19712) + (1.3415,1.19483)(1.3655,1.19339)(1.38577,1.19284)(1.4021,1.19323) + (1.41431,1.19461)(1.42218,1.197)(1.42551,1.20046)(1.4241,1.20502) + (1.41776,1.21074)(1.40628,1.21763)(1.38947,1.22576) + (1.36714,1.23514)(1.33911,1.24583)(1.3052,1.25784)(1.26524,1.27122) + (1.21907,1.28599)(1.16656,1.30219)(1.10756,1.31982) + (1.04196,1.33891)(0.969654,1.35948)(0.890556,1.38154)(0.804598,1.4051) +%% +\path(1.3617,1.23817)(1.39385,1.23075)(1.4229,1.22394) + (1.44865,1.21779)(1.47089,1.21232)(1.48943,1.2076)(1.50402,1.20365) + (1.51446,1.20053)(1.52052,1.19829)(1.52196,1.19696) + (1.51856,1.19661)(1.51007,1.19727)(1.49626,1.199)(1.47689,1.20184) + (1.45173,1.20585)(1.42053,1.21107)(1.38308,1.21755) + (1.33914,1.22534)(1.28849,1.23448)(1.23092,1.24502) + (1.16623,1.25701)(1.09423,1.27047)(1.01474,1.28546) + (0.927602,1.30199)(0.83267,1.32012) +%% +\path(1.4872,1.26793)(1.51821,1.2571)(1.5462,1.2467) + (1.57093,1.23677)(1.5922,1.22735)(1.60978,1.21849)(1.62342,1.21022) + (1.63288,1.20259)(1.6379,1.19565)(1.63823,1.18945)(1.6336,1.18404) + (1.62373,1.17947)(1.60833,1.17579)(1.58713,1.17306) + (1.55982,1.17134)(1.52613,1.17068)(1.48574,1.17114) + (1.43836,1.17279)(1.3837,1.17569)(1.32146,1.17988)(1.25135,1.18545) + (1.17308,1.19243)(1.08639,1.20091)(0.99101,1.21092)(0.886683,1.22254) +%% +\path(0.927506,0.495809)(0.899539,0.55566)(0.8777,0.611715) + (0.861604,0.664274)(0.850911,0.713606)(0.845319,0.759952) + (0.844563,0.803527)(0.848407,0.844524)(0.856643,0.883119) + (0.869088,0.919469)(0.885577,0.953717)(0.90597,0.985993) + (0.930139,1.01641)(0.957975,1.04509)(0.989383,1.07211) + (1.02428,1.09758)(1.0626,1.12156)(1.10428,1.14414)(1.14927,1.16539) + (1.19753,1.18536)(1.24904,1.20411)(1.30377,1.2217)(1.3617,1.23817) + (1.42285,1.25356)(1.4872,1.26793) +%% +\path(1.10157,0.602843)(1.06552,0.653288)(1.03581,0.700614) + (1.01206,0.745046)(0.993963,0.786789)(0.981224,0.826026) + (0.97359,0.862922)(0.970837,0.897627)(0.972764,0.930277) + (0.979193,0.960993)(0.989968,0.989888)(1.00495,1.01706) + (1.02402,1.04261)(1.04708,1.06661)(1.07402,1.08915) + (1.10479,1.11029)(1.1393,1.1301)(1.17751,1.14864)(1.21938,1.16596) + (1.26487,1.1821)(1.31396,1.19712)(1.36664,1.21106)(1.4229,1.22394) + (1.48275,1.23581)(1.5462,1.2467) +%% +\path(1.25125,0.713425)(1.20852,0.754966)(1.17219,0.793961) + (1.14193,0.830577)(1.11743,0.864964)(1.09844,0.89726) + (1.08472,0.927588)(1.07607,0.95606)(1.0723,0.982778) + (1.07325,1.00784)(1.07878,1.03132)(1.08876,1.0533)(1.10308,1.07385) + (1.12165,1.09304)(1.14439,1.11092)(1.17123,1.12754) + (1.20212,1.14296)(1.23702,1.15721)(1.27589,1.17035) + (1.31872,1.18239)(1.3655,1.19339)(1.41622,1.20335)(1.47089,1.21232) + (1.52955,1.22032)(1.5922,1.22735) +%% +\path(1.37643,0.826777)(1.32827,0.85999)(1.28645,0.891132) + (1.25067,0.920321)(1.22068,0.947667)(1.19624,0.973268) + (1.17715,0.997213)(1.16324,1.01959)(1.15433,1.04046) + (1.15028,1.0599)(1.15098,1.07797)(1.15631,1.09472)(1.16618,1.11021) + (1.18051,1.12448)(1.19925,1.13757)(1.22233,1.14953) + (1.24973,1.16037)(1.28142,1.17014)(1.31737,1.17886)(1.3576,1.18655) + (1.4021,1.19323)(1.4509,1.19893)(1.50402,1.20365)(1.56151,1.20741)(1.62342,1.21022) +%% +\path(1.47732,0.94212)(1.42478,0.967642)(1.37842,0.991473) + (1.338,1.01369)(1.3033,1.03438)(1.27412,1.05361)(1.25029,1.07143) + (1.23165,1.08791)(1.21807,1.10309)(1.20944,1.11702) + (1.20565,1.12975)(1.20662,1.1413)(1.21227,1.15172)(1.22256,1.16103) + (1.23743,1.16926)(1.25686,1.17643)(1.28083,1.18256) + (1.30933,1.18768)(1.34238,1.19178)(1.37998,1.19488)(1.42218,1.197) + (1.469,1.19814)(1.52052,1.19829)(1.57679,1.19746)(1.6379,1.19565) +%% +\path(1.55438,1.0587)(1.49833,1.07721)(1.44824,1.09432) + (1.4039,1.11009)(1.36514,1.12456)(1.3318,1.13779)(1.30374,1.14982) + (1.28083,1.16067)(1.26297,1.17038)(1.25007,1.17898)(1.24206,1.1865) + (1.23887,1.19294)(1.24046,1.19834)(1.2468,1.20271)(1.25787,1.20606) + (1.27366,1.20839)(1.29418,1.20972)(1.31944,1.21005) + (1.34948,1.20938)(1.38435,1.20771)(1.4241,1.20502)(1.46881,1.20133) + (1.51856,1.19661)(1.57345,1.19085)(1.6336,1.18404) +%% +\path(1.60833,1.17579)(1.54946,1.18798)(1.49626,1.199) + (1.44858,1.20887)(1.40628,1.21763)(1.36924,1.22531) + (1.33734,1.23191)(1.3105,1.23747)(1.28864,1.242)(1.2717,1.24551) + (1.25963,1.24801)(1.25241,1.2495)(1.25,1.25)(1.25241,1.2495) + (1.25963,1.24801)(1.2717,1.24551)(1.28864,1.242)(1.3105,1.23747) + (1.33734,1.23191)(1.36924,1.22531)(1.40628,1.21763) + (1.44858,1.20887)(1.49626,1.199)(1.54946,1.18798)(1.60833,1.17579) +%% +\path(1.64008,1.2927)(1.5789,1.29929)(1.52307,1.30486) + (1.47248,1.30943)(1.42702,1.313)(1.3866,1.31559)(1.35115,1.31721) + (1.3206,1.31786)(1.29492,1.31754)(1.27406,1.31626)(1.258,1.314) + (1.24675,1.31076)(1.2403,1.30654)(1.23868,1.30132)(1.24192,1.29508) + (1.25007,1.28781)(1.26319,1.27949)(1.28135,1.27009) + (1.30466,1.25959)(1.33321,1.24795)(1.36714,1.23514) + (1.40659,1.22112)(1.45173,1.20585)(1.50274,1.18927)(1.55982,1.17134) +%% +\path(1.65074,1.40881)(1.5876,1.4105)(1.52946,1.41127) + (1.47624,1.41113)(1.42787,1.41007)(1.38428,1.40809) + (1.34544,1.40519)(1.3113,1.40136)(1.28185,1.39658)(1.25709,1.39085) + (1.23701,1.38415)(1.22163,1.37646)(1.211,1.36775)(1.20515,1.35801) + (1.20414,1.3472)(1.20805,1.33529)(1.21697,1.32225)(1.23101,1.30803) + (1.2503,1.29259)(1.27497,1.27588)(1.3052,1.25784)(1.34116,1.23842) + (1.38308,1.21755)(1.43118,1.19515)(1.48574,1.17114) +%% +\path(1.64154,1.52354)(1.57665,1.52102)(1.51639,1.51763) + (1.4607,1.51338)(1.40954,1.50826)(1.36288,1.50224)(1.32069,1.49531) + (1.28297,1.48746)(1.24972,1.47865)(1.22095,1.46887)(1.1967,1.45809) + (1.177,1.44627)(1.16191,1.43338)(1.15151,1.41938)(1.14587,1.40423) + (1.14509,1.38787)(1.14931,1.37026)(1.15864,1.35134) + (1.17326,1.33103)(1.19333,1.30928)(1.21907,1.28599)(1.2507,1.26109) + (1.28849,1.23448)(1.33271,1.20605)(1.3837,1.17569) +%% +\path(1.61383,1.63639)(1.54727,1.6303)(1.48496,1.62339) + (1.42684,1.61563)(1.37292,1.607)(1.32316,1.59747)(1.27758,1.58703) + (1.23617,1.57563)(1.19897,1.56326)(1.16601,1.54986)(1.13734,1.5354) + (1.11301,1.51983)(1.0931,1.50311)(1.0777,1.48517)(1.06692,1.46596) + (1.06088,1.44542)(1.05973,1.42347)(1.06362,1.40002)(1.07274,1.375) + (1.08731,1.3483)(1.10756,1.31982)(1.13377,1.28943)(1.16623,1.25701) + (1.20529,1.2224)(1.25135,1.18545) +%% +\path(1.56902,1.7469)(1.50078,1.73787)(1.43637,1.72802) + (1.37578,1.71732)(1.31901,1.70574)(1.26605,1.69325)(1.21692,1.6798) + (1.17165,1.66536)(1.13027,1.64988)(1.09284,1.63332)(1.0594,1.61562) + (1.03003,1.59672)(1.00483,1.57655)(0.983899,1.55505) + (0.967353,1.53214)(0.955336,1.50773)(0.948007,1.48173) + (0.945551,1.45402)(0.948177,1.4245)(0.956122,1.39304) + (0.969654,1.35948)(0.989078,1.32368)(1.01474,1.28546) + (1.04703,1.24461)(1.08639,1.20091) +%% +\path(1.50857,1.85469)(1.43853,1.8433)(1.37192,1.83108) + (1.30872,1.81799)(1.24895,1.80399)(1.1926,1.78904)(1.13972,1.7731) + (1.09032,1.75611)(1.04445,1.73802)(1.00217,1.71876) + (0.963551,1.69828)(0.928663,1.67649)(0.897604,1.65331) + (0.870487,1.62866)(0.84744,1.60244)(0.828611,1.57454) + (0.81417,1.54484)(0.80431,1.5132)(0.799255,1.47948) + (0.799255,1.44351)(0.804598,1.4051)(0.815612,1.36405) + (0.83267,1.32012)(0.856198,1.27305)(0.886683,1.22254) +%% +\path(1.25,1.25)(0.600163,1.38459) +%% +\path(0.68242,1.38345)(0.708786,1.37799) +\path(0.655001,1.38383)(0.707734,1.37291) +\path(0.627582,1.38421)(0.706681,1.36782) +\path(0.600163,1.38459)(0.705629,1.36274) +\path(0.625477,1.37404)(0.704577,1.35766) +\path(0.650792,1.3635)(0.703524,1.35258) +\path(0.676106,1.35296)(0.702472,1.3475) +\path(0.705629,1.36274)(0.709838,1.38307)(0.600163,1.38459) + (0.70142,1.34242)(0.705629,1.36274) +%% +\path(1.25,1.25)(0.90831,0.837544) +%% +\path(0.929086,0.887024)(0.940008,0.900207) +\path(0.922161,0.870531)(0.944004,0.896897) +\path(0.915235,0.854037)(0.947999,0.893587) +\path(0.90831,0.837544)(0.951995,0.890277) +\path(0.923227,0.847417)(0.955991,0.886966) +\path(0.938144,0.85729)(0.959987,0.883656) +\path(0.953061,0.867163)(0.963983,0.880346) +\path(0.951995,0.890277)(0.936012,0.903518)(0.90831,0.837544) + (0.967979,0.877035)(0.951995,0.890277) +%% +\allinethickness{1pt}% +\color{rgb_980000}% +\path(2.375,0.125) + (2.375,2.375)(0.125,2.375)(0.125,0.125)(2.375,0.125) +%% +\allinethickness{0.4pt}% +\color{rgb_000000}% +\path(4.32177,5.61398) + (4.31023,5.69921)(4.29571,5.77929)(4.27832,5.85466) + (4.25813,5.92574)(4.23521,5.99286)(4.20959,6.05635)(4.1813,6.11649) + (4.15036,6.17352)(4.11676,6.22769)(4.0805,6.27919)(4.04155,6.32822) + (3.99986,6.37493)(3.9554,6.41949)(3.90809,6.46204)(3.85786,6.50269) + (3.80463,6.54158)(3.7483,6.5788)(3.68874,6.61445)(3.62584,6.64863) + (3.55945,6.68142)(3.48941,6.71289)(3.41554,6.74311) + (3.33764,6.77214)(3.25551,6.80006) +%% +\path(4.13841,5.61911)(4.13845,5.69921)(4.13499,5.7746) + (4.12815,5.84568)(4.11806,5.91278)(4.10479,5.97624) + (4.08842,6.03631)(4.06899,6.09326)(4.04655,6.14732) + (4.02109,6.19867)(3.99263,6.24751)(3.96116,6.29401) + (3.92663,6.33832)(3.88902,6.38056)(3.84826,6.42088) + (3.80428,6.45939)(3.75699,6.49618)(3.70631,6.53136) + (3.65209,6.56502)(3.59422,6.59722)(3.53254,6.62806) + (3.46687,6.65758)(3.39703,6.68587)(3.32279,6.71296)(3.24391,6.73891) +%% +\path(3.97074,5.63438)(3.98145,5.70897)(3.98827,5.77929) + (3.99133,5.84568)(3.99078,5.90844)(3.98672,5.96784) + (3.97923,6.02413)(3.96839,6.07752)(3.95423,6.12822) + (3.93678,6.17639)(3.91605,6.22222)(3.89204,6.26583) + (3.86473,6.30736)(3.83407,6.34695)(3.80002,6.38469)(3.7625,6.42068) + (3.72142,6.45502)(3.67668,6.4878)(3.62816,6.51909)(3.57571,6.54895) + (3.51917,6.57745)(3.45835,6.60465)(3.39303,6.63059) + (3.32299,6.65533)(3.24794,6.6789) +%% +\path(3.82031,5.65946)(3.84076,5.72828)(3.85704,5.79325) + (3.8693,5.85466)(3.87769,5.91278)(3.88234,5.96784)(3.88333,6.02004) + (3.88074,6.06957)(3.87462,6.1166)(3.86501,6.16129)(3.85192,6.20378) + (3.83536,6.24419)(3.81529,6.28265)(3.79169,6.31924) + (3.76451,6.35408)(3.73366,6.38723)(3.69906,6.41879) + (3.66061,6.44883)(3.61816,6.47739)(3.57157,6.50455) + (3.52065,6.53035)(3.46521,6.55484)(3.40502,6.57805) + (3.33981,6.60002)(3.26928,6.62077) +%% +\path(3.68828,5.69383)(3.71752,5.75673)(3.74242,5.81619) + (3.76316,5.87245)(3.77989,5.92574)(3.79272,5.97624) + (3.80176,6.02413)(3.80708,6.06957)(3.80875,6.1127)(3.80678,6.15367) + (3.80122,6.19257)(3.79205,6.22953)(3.77926,6.26463) + (3.76282,6.29797)(3.74266,6.32962)(3.71872,6.35966) + (3.69089,6.38814)(3.65907,6.41512)(3.62312,6.44066) + (3.58287,6.46478)(3.53814,6.48754)(3.4887,6.50895)(3.43432,6.52905) + (3.37469,6.54785)(3.3095,6.56536) +%% +\path(3.57536,5.73678)(3.61246,5.79374)(3.64519,5.84764) + (3.6737,5.89868)(3.69814,5.94703)(3.71864,5.99286)(3.73529,6.03631) + (3.74816,6.07752)(3.75733,6.1166)(3.76282,6.15367)(3.76466,6.18881) + (3.76284,6.22212)(3.75735,6.25368)(3.74816,6.28355)(3.7352,6.3118) + (3.71839,6.33848)(3.69766,6.36364)(3.67286,6.38731) + (3.64387,6.40955)(3.6105,6.43036)(3.57256,6.44976)(3.52982,6.46778) + (3.48202,6.48442)(3.42884,6.49968)(3.36994,6.51354) +%% +\path(3.48182,5.78746)(3.52593,5.83858)(3.5657,5.88698) + (3.6013,5.93282)(3.63287,5.97624)(3.66052,6.01738)(3.68434,6.05635) + (3.70443,6.09326)(3.72082,6.12822)(3.73357,6.16129) + (3.74268,6.19257)(3.74817,6.22212)(3.75,6.25)(3.74815,6.27626) + (3.74256,6.30096)(3.73315,6.32411)(3.71983,6.34577) + (3.70247,6.36595)(3.68092,6.38466)(3.65502,6.40193) + (3.62455,6.41774)(3.58928,6.43209)(3.54893,6.44498) + (3.50317,6.45637)(3.45165,6.46623) +%% +\path(3.40754,5.84494)(3.45785,5.89041)(3.50396,5.93346) + (3.54601,5.97421)(3.58414,6.0128)(3.61846,6.04931)(3.64906,6.08384) + (3.67601,6.11649)(3.69937,6.14732)(3.71917,6.17639) + (3.73544,6.20378)(3.74817,6.22953)(3.75735,6.25368) + (3.76295,6.27626)(3.76491,6.29732)(3.76315,6.31686)(3.75758,6.3349) + (3.74809,6.35145)(3.73451,6.36651)(3.71669,6.38006)(3.69441,6.3921) + (3.66744,6.40258)(3.63549,6.41148)(3.59823,6.41875)(3.55529,6.42432) +%% +\path(3.352,5.90822)(3.40781,5.9483)(3.45961,5.98623) + (3.50754,6.0221)(3.55172,6.05601)(3.59226,6.08804)(3.62924,6.11826) + (3.66274,6.14674)(3.69281,6.17352)(3.71948,6.19867) + (3.74278,6.22222)(3.76271,6.24419)(3.77926,6.26463)(3.7924,6.28355) + (3.80208,6.30096)(3.80823,6.31686)(3.81077,6.33125) + (3.80957,6.34412)(3.8045,6.35546)(3.79539,6.36522)(3.78206,6.37338) + (3.76426,6.37987)(3.74171,6.38464)(3.7141,6.3876)(3.68106,6.38866) +%% +\path(3.31441,5.97626)(3.37509,6.01129)(3.432,6.04439) + (3.48528,6.07564)(3.53504,6.10512)(3.58139,6.13288)(3.6244,6.15897) + (3.66415,6.18345)(3.70069,6.20635)(3.73405,6.22769) + (3.76427,6.24751)(3.79135,6.26583)(3.81529,6.28265) + (3.83606,6.29797)(3.85363,6.3118)(3.86794,6.32411)(3.8789,6.3349) + (3.88643,6.34412)(3.89039,6.35175)(3.89064,6.35772) + (3.88701,6.36198)(3.87927,6.36444)(3.86717,6.36501) + (3.85042,6.36359)(3.82865,6.36003) +%% +\path(3.29368,6.04807)(3.35869,6.07842)(3.42021,6.10703) + (3.47839,6.13398)(3.53332,6.1593)(3.5851,6.18306)(3.63381,6.20527) + (3.67954,6.22597)(3.72232,6.24518)(3.7622,6.26292)(3.79922,6.27919) + (3.8334,6.29401)(3.86473,6.30736)(3.89321,6.31924)(3.91881,6.32962) + (3.94149,6.33848)(3.9612,6.34577)(3.97785,6.35145)(3.99135,6.35546) + (4.00158,6.35772)(4.00838,6.35815)(4.01158,6.35663) + (4.01096,6.35306)(4.00627,6.34727)(3.99719,6.33908) +%% +\path(3.28857,6.12268)(3.35743,6.14874)(3.42314,6.17324) + (3.4858,6.19622)(3.54552,6.21772)(3.60241,6.23776)(3.65653,6.25637) + (3.70797,6.27356)(3.75678,6.28934)(3.80302,6.30372) + (3.84672,6.31668)(3.88792,6.32822)(3.92663,6.33832) + (3.96287,6.34695)(3.99662,6.35408)(4.02787,6.35966) + (4.05658,6.36364)(4.08272,6.36595)(4.10621,6.36651) + (4.12697,6.36522)(4.14491,6.36198)(4.15988,6.35663) + (4.17173,6.34904)(4.18026,6.33901)(4.18525,6.32631) +%% +\path(3.29768,6.19917)(3.37001,6.22136)(3.43952,6.24213) + (3.50631,6.26151)(3.57051,6.27953)(3.63219,6.29619) + (3.69145,6.31151)(3.74836,6.32549)(3.80299,6.33812)(3.85541,6.3494) + (3.90567,6.35932)(3.95381,6.36784)(3.99986,6.37493) + (4.04387,6.38056)(4.08585,6.38469)(4.1258,6.38723)(4.16374,6.38814) + (4.19966,6.38731)(4.23353,6.38466)(4.26532,6.38006) + (4.29499,6.37338)(4.32247,6.36444)(4.34769,6.35306) + (4.37053,6.33901)(4.39086,6.32202) +%% +\path(4.32177,5.61398)(4.22824,5.61526)(4.13841,5.61911) + (4.0525,5.62549)(3.97074,5.63438)(3.89329,5.64572)(3.82031,5.65946) + (3.75194,5.67553)(3.68828,5.69383)(3.6294,5.71428)(3.57536,5.73678) + (3.52617,5.76121)(3.48182,5.78746)(3.4423,5.81541)(3.40754,5.84494) + (3.37747,5.87592)(3.352,5.90822)(3.33103,5.94171)(3.31441,5.97626) + (3.30201,6.01176)(3.29368,6.04807)(3.28926,6.08509) + (3.28857,6.12268)(3.29144,6.16074)(3.29768,6.19917) +%% +\path(4.29571,5.77929)(4.2137,5.77577)(4.13499,5.7746) + (4.05978,5.77577)(3.98827,5.77929)(3.92064,5.78512) + (3.85704,5.79325)(3.79759,5.80362)(3.74242,5.81619)(3.6916,5.83089) + (3.64519,5.84764)(3.60322,5.86637)(3.5657,5.88698)(3.53263,5.90938) + (3.50396,5.93346)(3.47965,5.95911)(3.45961,5.98623) + (3.44377,6.01469)(3.432,6.04439)(3.42419,6.07521)(3.42021,6.10703) + (3.41991,6.13974)(3.42314,6.17324)(3.42973,6.2074)(3.43952,6.24213) +%% +\path(4.25813,5.92574)(4.18659,5.9182)(4.11806,5.91278) + (4.05273,5.90952)(3.99078,5.90844)(3.93239,5.90952) + (3.87769,5.91278)(3.82683,5.9182)(3.77989,5.92574)(3.73697,5.93537) + (3.69814,5.94703)(3.66343,5.96068)(3.63287,5.97624) + (3.60644,5.99364)(3.58414,6.0128)(3.56592,6.03362)(3.55172,6.05601) + (3.54146,6.07988)(3.53504,6.10512)(3.53237,6.13163)(3.53332,6.1593) + (3.53775,6.18804)(3.54552,6.21772)(3.55649,6.24825)(3.57051,6.27953) +%% +\path(4.20959,6.05635)(4.1476,6.04537)(4.08842,6.03631) + (4.03224,6.02922)(3.97923,6.02413)(3.92955,6.02106) + (3.88333,6.02004)(3.8407,6.02106)(3.80176,6.02413)(3.7666,6.02922) + (3.73529,6.03631)(3.70786,6.04537)(3.68434,6.05635)(3.66475,6.0692) + (3.64906,6.08384)(3.63724,6.10022)(3.62924,6.11826) + (3.62499,6.13787)(3.6244,6.15897)(3.62738,6.18147)(3.63381,6.20527) + (3.64358,6.23027)(3.65653,6.25637)(3.67254,6.28349)(3.69145,6.31151) +%% +\path(4.15036,6.17352)(4.0971,6.15956)(4.04655,6.14732) + (3.99887,6.13685)(3.95423,6.12822)(3.91277,6.12146)(3.87462,6.1166) + (3.83992,6.11368)(3.80875,6.1127)(3.7812,6.11368)(3.75733,6.1166) + (3.7372,6.12146)(3.72082,6.12822)(3.70822,6.13685)(3.69937,6.14732) + (3.69425,6.15956)(3.69281,6.17352)(3.69498,6.18914) + (3.70069,6.20635)(3.70984,6.22505)(3.72232,6.24518) + (3.73801,6.26664)(3.75678,6.28934)(3.77849,6.3132)(3.80299,6.33812) +%% +\path(4.0805,6.27919)(4.03524,6.26259)(3.99263,6.24751) + (3.95285,6.23403)(3.91605,6.22222)(3.88236,6.21212) + (3.85192,6.20378)(3.82484,6.19726)(3.80122,6.19257) + (3.78114,6.18975)(3.76466,6.18881)(3.75183,6.18975) + (3.74268,6.19257)(3.73722,6.19726)(3.73544,6.20378) + (3.73731,6.21212)(3.74278,6.22222)(3.7518,6.23403)(3.76427,6.24751) + (3.78012,6.26259)(3.79922,6.27919)(3.82147,6.29725) + (3.84672,6.31668)(3.87484,6.3374)(3.90567,6.35932) +%% +\path(3.99986,6.37493)(3.96191,6.35595)(3.92663,6.33832) + (3.89419,6.32209)(3.86473,6.30736)(3.83839,6.29419) + (3.81529,6.28265)(3.79555,6.27278)(3.77926,6.26463) + (3.76651,6.25825)(3.75735,6.25368)(3.75184,6.25092)(3.75,6.25) + (3.75184,6.25092)(3.75735,6.25368)(3.76651,6.25825) + (3.77926,6.26463)(3.79555,6.27278)(3.81529,6.28265) + (3.83839,6.29419)(3.86473,6.30736)(3.89419,6.32209) + (3.92663,6.33832)(3.96191,6.35595)(3.99986,6.37493) +%% +\path(3.90809,6.46204)(3.8768,6.44088)(3.84826,6.42088) + (3.82261,6.40212)(3.80002,6.38469)(3.78061,6.36864) + (3.76451,6.35408)(3.75182,6.34105)(3.74266,6.32962)(3.7371,6.31986) + (3.7352,6.3118)(3.73701,6.30549)(3.74256,6.30096)(3.75186,6.29823) + (3.76491,6.29732)(3.78166,6.29823)(3.80208,6.30096)(3.8261,6.30549) + (3.85363,6.3118)(3.88457,6.31986)(3.91881,6.32962)(3.9562,6.34105) + (3.99662,6.35408)(4.03989,6.36864)(4.08585,6.38469) +%% +\path(3.80463,6.54158)(3.77938,6.5184)(3.75699,6.49618) + (3.73762,6.47503)(3.72142,6.45502)(3.70853,6.43625) + (3.69906,6.41879)(3.69315,6.40273)(3.69089,6.38814) + (3.69237,6.37509)(3.69766,6.36364)(3.7068,6.35385)(3.71983,6.34577) + (3.73676,6.33944)(3.75758,6.3349)(3.78227,6.33216)(3.81077,6.33125) + (3.84301,6.33216)(3.8789,6.3349)(3.91834,6.33944)(3.9612,6.34577) + (4.00733,6.35385)(4.05658,6.36364)(4.10878,6.37509)(4.16374,6.38814) +%% +\path(3.68874,6.61445)(3.66891,6.58934)(3.65209,6.56502) + (3.63846,6.54157)(3.62816,6.51909)(3.62135,6.49766) + (3.61816,6.47739)(3.61871,6.45836)(3.62312,6.44066) + (3.63148,6.42436)(3.64387,6.40955)(3.66033,6.39629) + (3.68092,6.38466)(3.70565,6.37472)(3.73451,6.36651) + (3.76748,6.36008)(3.8045,6.35546)(3.8455,6.35268)(3.89039,6.35175) + (3.93905,6.35268)(3.99135,6.35546)(4.04713,6.36008) + (4.10621,6.36651)(4.16841,6.37472)(4.23353,6.38466) +%% +\path(3.55945,6.68142)(3.54439,6.65444)(3.53254,6.62806) + (3.52408,6.60236)(3.51917,6.57745)(3.51798,6.55341) + (3.52065,6.53035)(3.52733,6.50836)(3.53814,6.48754) + (3.55319,6.46798)(3.57256,6.44976)(3.59633,6.43299) + (3.62455,6.41774)(3.65725,6.40408)(3.69441,6.3921)(3.73603,6.38184) + (3.78206,6.37338)(3.83242,6.36674)(3.88701,6.36198) + (3.94571,6.35911)(4.00838,6.35815)(4.07484,6.35911) + (4.14491,6.36198)(4.21837,6.36674)(4.29499,6.37338) +%% +\path(3.41554,6.74311)(3.40457,6.71429)(3.39703,6.68587) + (3.39312,6.65793)(3.39303,6.63059)(3.39694,6.60393) + (3.40502,6.57805)(3.41743,6.55306)(3.43432,6.52905) + (3.45581,6.50614)(3.48202,6.48442)(3.51304,6.464)(3.54893,6.44498) + (3.58974,6.42744)(3.63549,6.41148)(3.68616,6.39719) + (3.74171,6.38464)(3.80208,6.37389)(3.86717,6.36501) + (3.93685,6.35806)(4.01096,6.35306)(4.08932,6.35005) + (4.17173,6.34904)(4.25793,6.35005)(4.34769,6.35306) +%% +\path(3.25551,6.80006)(3.24787,6.76939)(3.24391,6.73891) + (3.24387,6.70872)(3.24794,6.6789)(3.25635,6.64955)(3.26928,6.62077) + (3.28694,6.59267)(3.3095,6.56536)(3.33712,6.53894)(3.36994,6.51354) + (3.40808,6.48927)(3.45165,6.46623)(3.5007,6.44454)(3.55529,6.42432) + (3.61541,6.40566)(3.68106,6.38866)(3.75217,6.37343) + (3.82865,6.36003)(3.91038,6.34856)(3.99719,6.33908) + (4.08889,6.33165)(4.18525,6.32631)(4.286,6.32309)(4.39086,6.32202) +%% +\path(3.75,6.25)(3.14565,5.94783) +%% +\path(3.19923,5.99202)(3.21941,6.00211) +\path(3.18137,5.97729)(3.22173,5.99747) +\path(3.16351,5.96256)(3.22405,5.99283) +\path(3.14565,5.94783)(3.22637,5.98819) +\path(3.16815,5.95328)(3.22869,5.98355) +\path(3.19065,5.95872)(3.23101,5.9789) +\path(3.21315,5.96417)(3.23333,5.97426) +\path(3.22637,5.98819)(3.21709,6.00675)(3.14565,5.94783) + (3.23565,5.96962)(3.22637,5.98819) +%% +\path(3.75,6.25)(4.35435,5.94783) +%% +\path(4.28685,5.96417)(4.26667,5.97426) +\path(4.30935,5.95872)(4.26899,5.9789) +\path(4.33185,5.95328)(4.27131,5.98355) +\path(4.35435,5.94783)(4.27363,5.98819) +\path(4.33649,5.96256)(4.27595,5.99283) +\path(4.31863,5.97729)(4.27827,5.99747) +\path(4.30077,5.99202)(4.28059,6.00211) +\path(4.27363,5.98819)(4.26435,5.96962)(4.35435,5.94783) + (4.28291,6.00675)(4.27363,5.98819) +%% +\allinethickness{1pt}% +\color{rgb_980000}% +\path(4.875,5.125) + (4.875,7.375)(2.625,7.375)(2.625,5.125)(4.875,5.125) +%% +\allinethickness{0.4pt}% +\color{rgb_000000}% +\path(3.75,2.95191) + (3.81752,3.02689)(3.87769,3.10015)(3.93077,3.17175) + (3.97698,3.24175)(4.01655,3.3102)(4.04971,3.37715)(4.07667,3.44266) + (4.09761,3.50676)(4.11274,3.5695)(4.12223,3.63093)(4.12626,3.69108) + (4.125,3.75)(4.11861,3.80772)(4.10725,3.86428)(4.09106,3.91971) + (4.07018,3.97405)(4.04476,4.02733)(4.01493,4.07958) + (3.98081,4.13082)(3.94252,4.1811)(3.90018,4.23043)(3.85391,4.27884) + (3.80382,4.32635)(3.75,4.373) +%% +\path(3.62348,3.04636)(3.69014,3.11055)(3.75,3.17364) + (3.80325,3.23566)(3.85004,3.29665)(3.89055,3.35662)(3.92492,3.4156) + (3.9533,3.47361)(3.97585,3.53068)(3.9927,3.58684)(4.00399,3.64209) + (4.00986,3.69647)(4.01042,3.75)(4.0058,3.80269)(3.99613,3.85457) + (3.98152,3.90564)(3.96208,3.95594)(3.93793,4.00548) + (3.90916,4.05428)(3.87589,4.10235)(3.8382,4.1497)(3.79621,4.19636) + (3.75,4.24234)(3.69967,4.28766)(3.64529,4.33232) +%% +\path(3.52707,3.13497)(3.59209,3.1895)(3.65084,3.24339) + (3.70344,3.29667)(3.75,3.34934)(3.79061,3.40141)(3.82538,3.45289) + (3.85441,3.5038)(3.87779,3.55414)(3.89561,3.60392)(3.90797,3.65315) + (3.91496,3.70184)(3.91667,3.75)(3.91317,3.79764)(3.90456,3.84476) + (3.89092,3.89138)(3.87233,3.93749)(3.84887,3.98312) + (3.82061,4.02827)(3.78763,4.07294)(3.75,4.11715)(3.7078,4.16089) + (3.6611,4.20419)(3.60997,4.24703)(3.55447,4.28944) +%% +\path(3.45806,3.21828)(3.52096,3.26413)(3.57809,3.30969) + (3.6295,3.35496)(3.67526,3.39995)(3.71541,3.44466)(3.75,3.4891) + (3.77909,3.53325)(3.80273,3.57714)(3.82096,3.62075)(3.83384,3.6641) + (3.84142,3.70718)(3.84375,3.75)(3.84087,3.79256)(3.83283,3.83486) + (3.81967,3.8769)(3.80146,3.91869)(3.77822,3.96024)(3.75,4.00153) + (3.71685,4.04257)(3.67882,4.08337)(3.63594,4.12393) + (3.58827,4.16425)(3.53583,4.20433)(3.47868,4.24417) +%% +\path(3.41407,3.29673)(3.47461,3.33478)(3.52983,3.37277) + (3.57974,3.41071)(3.62435,3.44861)(3.66367,3.48645) + (3.69771,3.52425)(3.72649,3.56199)(3.75,3.59969)(3.76826,3.63734) + (3.78129,3.67494)(3.78909,3.7125)(3.79167,3.75)(3.78904,3.78746) + (3.78121,3.82486)(3.76819,3.86222)(3.75,3.89953)(3.72664,3.9368) + (3.69812,3.97401)(3.66445,4.01118)(3.62564,4.0483)(3.58171,4.08537) + (3.53265,4.1224)(3.47849,4.15938)(3.41923,4.19631) +%% +\path(3.39296,3.37075)(3.4511,3.40176)(3.50433,3.43287) + (3.55261,3.46409)(3.59592,3.49541)(3.63424,3.52685) + (3.66754,3.55839)(3.69579,3.59005)(3.71897,3.62182) + (3.73705,3.65369)(3.75,3.68568)(3.7578,3.71779)(3.76042,3.75) + (3.75783,3.78233)(3.75,3.81477)(3.73691,3.84733)(3.71853,3.88) + (3.69483,3.91279)(3.66578,3.9457)(3.63135,3.97872)(3.59152,4.01186) + (3.54625,4.04512)(3.49552,4.0785)(3.43929,4.112)(3.37755,4.14562) +%% +\path(3.39286,3.44071)(3.44871,3.46535)(3.5,3.49019) + (3.54669,3.51523)(3.58871,3.54048)(3.62601,3.56593) + (3.65854,3.59158)(3.68622,3.61745)(3.70902,3.64352) + (3.72685,3.66981)(3.73967,3.69632)(3.74741,3.72305)(3.75,3.75) + (3.74738,3.77718)(3.7395,3.80458)(3.72627,3.83222)(3.70763,3.86009) + (3.68351,3.8882)(3.65385,3.91654)(3.61856,3.94513)(3.57759,3.97397) + (3.53084,4.00306)(3.47826,4.0324)(3.41976,4.062)(3.35526,4.09185) +%% +\path(3.41207,3.50691)(3.46585,3.5258)(3.51542,3.54493) + (3.56068,3.56429)(3.60155,3.58389)(3.63797,3.60374) + (3.66983,3.62385)(3.69705,3.6442)(3.71955,3.66482)(3.73723,3.6857) + (3.75,3.70686)(3.75776,3.72829)(3.76042,3.75)(3.75786,3.772) + (3.75,3.79429)(3.73672,3.81688)(3.71791,3.83978)(3.69345,3.86299) + (3.66325,3.88651)(3.62716,3.91036)(3.58508,3.93454) + (3.53687,3.95906)(3.48241,3.98392)(3.42157,4.00914)(3.3542,4.03471) +%% +\path(3.44909,3.56967)(3.50114,3.58335)(3.54927,3.59725) + (3.59338,3.61138)(3.63338,3.62575)(3.66914,3.64036) + (3.70058,3.65523)(3.72757,3.67034)(3.75,3.68572)(3.76775,3.70137) + (3.7807,3.71729)(3.78871,3.7335)(3.79167,3.75)(3.78942,3.7668) + (3.78182,3.7839)(3.76873,3.80132)(3.75,3.81907)(3.72546,3.83715) + (3.69495,3.85557)(3.6583,3.87434)(3.61533,3.89348)(3.56585,3.91299) + (3.50967,3.93289)(3.4466,3.95318)(3.37642,3.97388) +%% +\path(3.50255,3.62924)(3.55328,3.63818)(3.60037,3.64731) + (3.6437,3.65662)(3.68317,3.66613)(3.71864,3.67584)(3.75,3.68576) + (3.7771,3.69589)(3.79982,3.70624)(3.81799,3.71682)(3.83148,3.72763) + (3.84012,3.73869)(3.84375,3.75)(3.8422,3.76157)(3.83527,3.77341) + (3.8228,3.78553)(3.80457,3.79794)(3.78037,3.81064)(3.75,3.82366) + (3.71321,3.837)(3.66978,3.85067)(3.61944,3.8647)(3.56192,3.87908) + (3.49696,3.89383)(3.42425,3.90898) +%% +\path(3.57125,3.68585)(3.62111,3.6905)(3.66761,3.69525) + (3.71062,3.70012)(3.75,3.70511)(3.78562,3.71023)(3.81734,3.71548) + (3.84501,3.72086)(3.86847,3.72638)(3.88754,3.73205) + (3.90206,3.73787)(3.91183,3.74385)(3.91667,3.75)(3.91636,3.75632) + (3.91068,3.76281)(3.89941,3.7695)(3.8823,3.77637)(3.85908,3.78346) + (3.82949,3.79075)(3.79324,3.79827)(3.75,3.80602)(3.69946,3.81401) + (3.64125,3.82226)(3.57502,3.83078)(3.50036,3.83958) +%% +\path(3.65406,3.73974)(3.70358,3.74046)(3.75,3.74121) + (3.79318,3.74198)(3.833,3.74276)(3.86929,3.74358)(3.90191,3.74441) + (3.93068,3.74527)(3.95544,3.74616)(3.976,3.74708)(3.99216,3.74802) + (4.0037,3.74899)(4.01042,3.75)(4.01206,3.75104)(4.00837,3.75211) + (3.99908,3.75322)(3.9839,3.75437)(3.96252,3.75556)(3.9346,3.75679) + (3.89979,3.75807)(3.8577,3.75939)(3.80792,3.76076)(3.75,3.76219) + (3.68346,3.76367)(3.60778,3.76522) +%% +\path(3.75,3.79107)(3.79972,3.78823)(3.84661,3.7853) + (3.89054,3.78228)(3.93135,3.77916)(3.9689,3.77593)(4.00301,3.7726) + (4.03353,3.76915)(4.06025,3.76559)(4.08298,3.7619)(4.10151,3.75807) + (4.1156,3.75411)(4.125,3.75)(4.12945,3.74573)(4.12867,3.7413) + (4.12234,3.7367)(4.11013,3.73191)(4.09167,3.72692)(4.06658,3.72172) + (4.03443,3.71631)(3.99475,3.71065)(3.94705,3.70474) + (3.89077,3.69857)(3.8253,3.6921)(3.75,3.68532) +%% +\path(3.75,2.95191)(3.68279,2.9999)(3.62348,3.04636) + (3.57169,3.09136)(3.52707,3.13497)(3.4893,3.17726)(3.45806,3.21828) + (3.43308,3.25809)(3.41407,3.29673)(3.40078,3.33428) + (3.39296,3.37075)(3.39039,3.40622)(3.39286,3.44071) + (3.40015,3.47426)(3.41207,3.50691)(3.42844,3.5387)(3.44909,3.56967) + (3.47384,3.59984)(3.50255,3.62924)(3.53507,3.6579)(3.57125,3.68585) + (3.61095,3.71312)(3.65406,3.73974)(3.70045,3.76571)(3.75,3.79107) +%% +\path(3.87769,3.10015)(3.81014,3.13738)(3.75,3.17364) + (3.69699,3.20897)(3.65084,3.24339)(3.61129,3.27696) + (3.57809,3.30969)(3.55101,3.34161)(3.52983,3.37277) + (3.51434,3.40318)(3.50433,3.43287)(3.49961,3.46187)(3.5,3.49019) + (3.50533,3.51787)(3.51542,3.54493)(3.53012,3.57138) + (3.54927,3.59725)(3.57273,3.62255)(3.60037,3.64731) + (3.63203,3.67153)(3.66761,3.69525)(3.70697,3.71847)(3.75,3.74121) + (3.79658,3.76348)(3.84661,3.7853) +%% +\path(3.97698,3.24175)(3.91004,3.26948)(3.85004,3.29665) + (3.79676,3.32326)(3.75,3.34934)(3.70956,3.3749)(3.67526,3.39995) + (3.64691,3.42452)(3.62435,3.44861)(3.60741,3.47223) + (3.59592,3.49541)(3.58974,3.51816)(3.58871,3.54048) + (3.59269,3.56239)(3.60155,3.58389)(3.61516,3.60501) + (3.63338,3.62575)(3.65609,3.64612)(3.68317,3.66613) + (3.71451,3.68579)(3.75,3.70511)(3.78953,3.7241)(3.833,3.74276) + (3.8803,3.76111)(3.93135,3.77916) +%% +\path(4.04971,3.37715)(3.98409,3.39652)(3.92492,3.4156) + (3.87206,3.43439)(3.82538,3.45289)(3.78474,3.47113)(3.75,3.4891) + (3.72103,3.5068)(3.69771,3.52425)(3.67992,3.54144)(3.66754,3.55839) + (3.66045,3.57511)(3.65854,3.59158)(3.6617,3.60783)(3.66983,3.62385) + (3.68282,3.63964)(3.70058,3.65523)(3.723,3.6706)(3.75,3.68576) + (3.78148,3.70072)(3.81734,3.71548)(3.85752,3.73004) + (3.90191,3.74441)(3.95043,3.7586)(4.00301,3.7726) +%% +\path(4.09761,3.50676)(4.03372,3.51878)(3.97585,3.53068) + (3.9239,3.54247)(3.87779,3.55414)(3.83742,3.56569)(3.80273,3.57714) + (3.77361,3.58847)(3.75,3.59969)(3.73181,3.61081)(3.71897,3.62182) + (3.7114,3.63272)(3.70902,3.64352)(3.71176,3.65422)(3.71955,3.66482) + (3.73232,3.67532)(3.75,3.68572)(3.77252,3.69603)(3.79982,3.70624) + (3.83182,3.71636)(3.86847,3.72638)(3.90969,3.73632) + (3.95544,3.74616)(4.00565,3.75592)(4.06025,3.76559) +%% +\path(4.12223,3.63093)(4.06031,3.63652)(4.00399,3.64209) + (3.95323,3.64764)(3.90797,3.65315)(3.86819,3.65864)(3.83384,3.6641) + (3.80489,3.66953)(3.78129,3.67494)(3.76301,3.68033)(3.75,3.68568) + (3.74223,3.69101)(3.73967,3.69632)(3.74227,3.7016)(3.75,3.70686) + (3.76282,3.71209)(3.7807,3.71729)(3.8036,3.72248)(3.83148,3.72763) + (3.86431,3.73277)(3.90206,3.73787)(3.94468,3.74296) + (3.99216,3.74802)(4.04444,3.75306)(4.10151,3.75807) +%% +\path(4.125,3.75)(4.0651,3.75)(4.01042,3.75)(3.96094,3.75) + (3.91667,3.75)(3.8776,3.75)(3.84375,3.75)(3.8151,3.75) + (3.79167,3.75)(3.77344,3.75)(3.76042,3.75)(3.7526,3.75)(3.75,3.75) + (3.7526,3.75)(3.76042,3.75)(3.77344,3.75)(3.79167,3.75) + (3.8151,3.75)(3.84375,3.75)(3.8776,3.75)(3.91667,3.75) + (3.96094,3.75)(4.01042,3.75)(4.0651,3.75)(4.125,3.75) +%% +\path(4.10725,3.86428)(4.04926,3.85943)(3.99613,3.85457) + (3.94789,3.84967)(3.90456,3.84476)(3.8662,3.83982)(3.83283,3.83486) + (3.80449,3.82987)(3.78121,3.82486)(3.76304,3.81983)(3.75,3.81477) + (3.74214,3.80969)(3.7395,3.80458)(3.7421,3.79945)(3.75,3.79429) + (3.76323,3.78911)(3.78182,3.7839)(3.80582,3.77867)(3.83527,3.77341) + (3.87021,3.76812)(3.91068,3.76281)(3.95672,3.75748) + (4.00837,3.75211)(4.06567,3.74672)(4.12867,3.7413) +%% +\path(4.07018,3.97405)(4.01387,3.96504)(3.96208,3.95594) + (3.91488,3.94676)(3.87233,3.93749)(3.8345,3.92814)(3.80146,3.91869) + (3.77327,3.90916)(3.75,3.89953)(3.73173,3.88982)(3.71853,3.88) + (3.71047,3.87009)(3.70763,3.86009)(3.71008,3.84998) + (3.71791,3.83978)(3.73119,3.82947)(3.75,3.81907)(3.77443,3.80855) + (3.80457,3.79794)(3.84049,3.78721)(3.8823,3.77637)(3.93007,3.76543) + (3.9839,3.75437)(4.04389,3.7432)(4.11013,3.73191) +%% +\path(4.01493,4.07958)(3.95994,4.06701)(3.90916,4.05428) + (3.86269,4.04136)(3.82061,4.02827)(3.78301,4.01499)(3.75,4.00153) + (3.72167,3.98787)(3.69812,3.97401)(3.67945,3.95996)(3.66578,3.9457) + (3.6572,3.93123)(3.65385,3.91654)(3.65582,3.90164)(3.66325,3.88651) + (3.67625,3.87116)(3.69495,3.85557)(3.71949,3.83974)(3.75,3.82366) + (3.78662,3.80733)(3.82949,3.79075)(3.87877,3.77391)(3.9346,3.75679) + (3.99715,3.7394)(4.06658,3.72172) +%% +\path(3.94252,4.1811)(3.8884,4.16554)(3.8382,4.1497) + (3.79203,4.13357)(3.75,4.11715)(3.71222,4.10042)(3.67882,4.08337) + (3.64992,4.066)(3.62564,4.0483)(3.60613,4.03026)(3.59152,4.01186) + (3.58195,3.9931)(3.57759,3.97397)(3.57857,3.95446)(3.58508,3.93454) + (3.59727,3.91422)(3.61533,3.89348)(3.63943,3.8723)(3.66978,3.85067) + (3.70656,3.82859)(3.75,3.80602)(3.8003,3.78296)(3.8577,3.75939) + (3.92244,3.73529)(3.99475,3.71065) +%% +\path(3.85391,4.27884)(3.80014,4.26079)(3.75,4.24234) + (3.70361,4.22348)(3.6611,4.20419)(3.62261,4.18445)(3.58827,4.16425) + (3.55823,4.14357)(3.53265,4.1224)(3.51169,4.10072)(3.49552,4.0785) + (3.48431,4.05574)(3.47826,4.0324)(3.47756,4.00847)(3.48241,3.98392) + (3.49304,3.95874)(3.50967,3.93289)(3.53255,3.90634) + (3.56192,3.87908)(3.59806,3.85106)(3.64125,3.82226) + (3.69179,3.79265)(3.75,3.76219)(3.81621,3.73084)(3.89077,3.69857) +%% +\path(3.75,4.373)(3.69598,4.35293)(3.64529,4.33232) + (3.59808,4.31117)(3.55447,4.28944)(3.51462,4.26712) + (3.47868,4.24417)(3.44683,4.22058)(3.41923,4.19631) + (3.39607,4.17133)(3.37755,4.14562)(3.36387,4.11914) + (3.35526,4.09185)(3.35196,4.06372)(3.3542,4.03471)(3.36226,4.00478) + (3.37642,3.97388)(3.39698,3.94196)(3.42425,3.90898) + (3.45859,3.87487)(3.50036,3.83958)(3.54995,3.80305) + (3.60778,3.76522)(3.6743,3.726)(3.75,3.68532) +%% +\path(3.75,3.75)(3,3.75) +%% +\path(3.08562,3.76557)(3.11416,3.76557) +\path(3.05708,3.76038)(3.11416,3.76038) +\path(3.02854,3.75519)(3.11416,3.75519) +\path(3,3.75)(3.11416,3.75) +\path(3.02854,3.74481)(3.11416,3.74481) +\path(3.05708,3.73962)(3.11416,3.73962) +\path(3.08562,3.73443)(3.11416,3.73443) +\path(3.11416,3.75)(3.11416,3.77076)(3,3.75)(3.11416,3.72924)(3.11416,3.75) +%% +\path(3.75,3.75)(3.75,3.29644) +%% +\path(3.73443,3.33925)(3.73443,3.35352) +\path(3.73962,3.32498)(3.73962,3.35352) +\path(3.74481,3.31071)(3.74481,3.35352) +\path(3.75,3.29644)(3.75,3.35352) +\path(3.75519,3.31071)(3.75519,3.35352) +\path(3.76038,3.32498)(3.76038,3.35352) +\path(3.76557,3.33925)(3.76557,3.35352) +\path(3.75,3.35352)(3.72924,3.35352)(3.75,3.29644)(3.77076,3.35352)(3.75,3.35352) +%% +\allinethickness{1pt}% +\color{rgb_980000}% +\path(4.875,2.625) + (4.875,4.875)(2.625,4.875)(2.625,2.625)(4.875,2.625) +%% +\allinethickness{0.4pt}% +\color{rgb_000000}% +\path(3.17823,0.61398) + (3.2696,0.641697)(3.35808,0.672175)(3.44338,0.705355) + (3.52526,0.741164)(3.60346,0.779511)(3.67777,0.820294) + (3.748,0.863394)(3.81395,0.908683)(3.87549,0.956019) + (3.93248,1.00525)(3.98483,1.05622)(4.03246,1.10877) + (4.07534,1.16272)(4.11344,1.2179)(4.14676,1.27413)(4.17536,1.33125) + (4.19927,1.38908)(4.21858,1.44744)(4.23339,1.50617) + (4.24381,1.56512)(4.24998,1.62413)(4.25204,1.68304) + (4.25015,1.74173)(4.24449,1.80006) +%% +\path(3.20899,0.72735)(3.28831,0.749673)(3.36501,0.774599) + (3.43887,0.802101)(3.50964,0.832134)(3.57711,0.86464) + (3.64108,0.899549)(3.70136,0.936774)(3.75778,0.976219) + (3.8102,1.01777)(3.85849,1.06132)(3.90256,1.10672)(3.94232,1.15384) + (3.97773,1.20253)(4.00875,1.25265)(4.03538,1.30404) + (4.05764,1.35653)(4.07557,1.40997)(4.08922,1.46419) + (4.09868,1.51905)(4.10405,1.57438)(4.10544,1.63004) + (4.10297,1.68587)(4.0968,1.74173)(4.08706,1.79749) +%% +\path(3.25032,0.823133)(3.31889,0.840786)(3.38504,0.860893) + (3.44855,0.883449)(3.50922,0.908436)(3.56683,0.935822) + (3.62121,0.965564)(3.67218,0.997604)(3.7196,1.03187) + (3.76331,1.06829)(3.8032,1.10676)(3.83917,1.14717)(3.87115,1.18943) + (3.89907,1.23339)(3.92291,1.27893)(3.94265,1.32592) + (3.95829,1.37421)(3.96988,1.42366)(3.97745,1.47411) + (3.98107,1.52542)(3.98083,1.57745)(3.97684,1.63004)(3.9692,1.68304) + (3.95805,1.73632)(3.94353,1.78975) +%% +\path(3.30152,0.904095)(3.36048,0.917621)(3.41712,0.933458) + (3.47125,0.951621)(3.52267,0.972112)(3.5712,0.994925) + (3.61667,1.02004)(3.65892,1.04742)(3.6978,1.07702)(3.73319,1.10879) + (3.76496,1.14265)(3.79303,1.17853)(3.81732,1.21634) + (3.83777,1.25597)(3.85434,1.29732)(3.86702,1.34026) + (3.87582,1.38467)(3.88074,1.43043)(3.88184,1.47739) + (3.87918,1.52542)(3.87283,1.57438)(3.8629,1.62413)(3.84948,1.67451) + (3.83271,1.72541)(3.81271,1.77667) +%% +\path(3.36219,0.972363)(3.41251,0.982168)(3.46056,0.994146) + (3.50614,1.00833)(3.54909,1.02474)(3.58923,1.04339)(3.6264,1.06427) + (3.66046,1.08739)(3.69125,1.1127)(3.71867,1.14019)(3.74261,1.16981) + (3.76296,1.20149)(3.77966,1.23517)(3.79266,1.27077)(3.8019,1.3082) + (3.80739,1.34736)(3.80911,1.38814)(3.80708,1.43043) + (3.80136,1.47411)(3.79199,1.51905)(3.77905,1.56512) + (3.76263,1.61219)(3.74284,1.66012)(3.71979,1.70877)(3.69363,1.75801) +%% +\path(3.43214,1.02959)(3.4747,1.03597)(3.51496,1.04439) + (3.55275,1.0549)(3.58792,1.06753)(3.6203,1.08231)(3.64973,1.09927) + (3.67607,1.1184)(3.6992,1.13971)(3.71899,1.16319)(3.73534,1.18881) + (3.74816,1.21653)(3.75738,1.24631)(3.76294,1.27809)(3.7648,1.3118) + (3.76296,1.34736)(3.7574,1.38467)(3.74815,1.42366)(3.73525,1.46419) + (3.71875,1.50617)(3.69874,1.54948)(3.67529,1.59398) + (3.64852,1.63955)(3.61855,1.68606)(3.58552,1.73338) +%% +\path(3.51138,1.07706)(3.54694,1.08023)(3.58016,1.0853) + (3.61086,1.09235)(3.63888,1.10142)(3.66407,1.11255) + (3.68628,1.12577)(3.70537,1.14113)(3.72121,1.15862) + (3.73369,1.17827)(3.74271,1.20006)(3.74817,1.22398)(3.75,1.25) + (3.74815,1.27809)(3.74259,1.3082)(3.73328,1.34026)(3.72024,1.37421) + (3.70349,1.40997)(3.68306,1.44744)(3.65901,1.48653) + (3.63142,1.52713)(3.60039,1.56912)(3.56602,1.61239) + (3.52843,1.65681)(3.48778,1.70226) +%% +\path(3.60007,1.11578)(3.62936,1.11587)(3.65621,1.11774) + (3.68045,1.12147)(3.70192,1.1271)(3.72047,1.13471)(3.73595,1.14434) + (3.74823,1.15603)(3.75716,1.16982)(3.76264,1.18573) + (3.76456,1.20378)(3.76283,1.22398)(3.75738,1.24631) + (3.74815,1.27077)(3.73509,1.29732)(3.7182,1.32592)(3.69748,1.35653) + (3.67293,1.38908)(3.6446,1.42349)(3.61256,1.4597)(3.57688,1.49759) + (3.53766,1.53708)(3.49501,1.57805)(3.44908,1.62039)(3.40001,1.66397) +%% +\path(3.69855,1.14651)(3.72225,1.14361)(3.74337,1.14236) + (3.76176,1.14283)(3.77726,1.14511)(3.78969,1.14925) + (3.79892,1.15533)(3.8048,1.16341)(3.80719,1.17352)(3.80598,1.18573) + (3.80105,1.20006)(3.7923,1.21653)(3.77966,1.23517)(3.76307,1.25597) + (3.74248,1.27893)(3.71787,1.30404)(3.68923,1.33125) + (3.65659,1.36053)(3.61998,1.39183)(3.57947,1.42509) + (3.53514,1.46021)(3.48708,1.49713)(3.43543,1.53574) + (3.38033,1.57593)(3.32194,1.6176) +%% +\path(3.80729,1.16986)(3.82604,1.16398)(3.84208,1.15962) + (3.85522,1.15685)(3.86529,1.15577)(3.87214,1.15645)(3.8756,1.15897) + (3.87551,1.16341)(3.87174,1.16982)(3.86415,1.17827) + (3.85261,1.18881)(3.83704,1.20149)(3.81732,1.21634)(3.7934,1.23339) + (3.76522,1.25265)(3.73275,1.27413)(3.69598,1.29782) + (3.65492,1.32371)(3.60961,1.35175)(3.56011,1.3819)(3.50651,1.41411) + (3.4489,1.44831)(3.38744,1.48442)(3.32226,1.52235)(3.25354,1.56199) +%% +\path(3.92693,1.18624)(3.94139,1.17736)(3.95296,1.16985) + (3.96145,1.1638)(3.96668,1.1593)(3.96848,1.15645)(3.96666,1.15533) + (3.96105,1.15603)(3.95151,1.15862)(3.93788,1.16319) + (3.92002,1.16981)(3.89781,1.17853)(3.87115,1.18943) + (3.83994,1.20253)(3.80413,1.2179)(3.76366,1.23554)(3.71851,1.25549) + (3.66869,1.27773)(3.61423,1.30227)(3.55518,1.32909) + (3.49162,1.35815)(3.42367,1.38939)(3.35146,1.42277) + (3.27515,1.45821)(3.19494,1.49562) +%% +\path(4.05827,1.19595)(4.06911,1.18399)(4.07686,1.17324) + (4.08133,1.1638)(4.08232,1.15577)(4.07962,1.14925)(4.07305,1.14434) + (4.06242,1.14113)(4.04754,1.13971)(4.02825,1.14019) + (4.00437,1.14265)(3.97577,1.14717)(3.94232,1.15384)(3.9039,1.16272) + (3.86043,1.17387)(3.81183,1.18736)(3.75806,1.20321) + (3.69912,1.22147)(3.63501,1.24216)(3.56578,1.26527)(3.4915,1.29081) + (3.41229,1.31874)(3.32827,1.34904)(3.23963,1.38165)(3.14657,1.4165) +%% +\path(4.20232,1.19917)(4.21023,1.18399)(4.21485,1.16985) + (4.21597,1.15685)(4.21335,1.14511)(4.20679,1.13471) + (4.19606,1.12577)(4.18094,1.1184)(4.16122,1.1127)(4.1367,1.10879) + (4.10719,1.10676)(4.07249,1.10672)(4.03246,1.10877)(3.98694,1.113) + (3.93582,1.11951)(3.87898,1.12838)(3.81635,1.13966)(3.7479,1.15344) + (3.67361,1.16975)(3.59351,1.18864)(3.50765,1.21013) + (3.41613,1.23423)(3.31908,1.26093)(3.21668,1.2902)(3.10914,1.32202) +%% +\path(3.17823,0.61398)(3.19224,0.673067)(3.20899,0.72735) + (3.22838,0.77725)(3.25032,0.823133)(3.27472,0.865321) + (3.30152,0.904095)(3.33069,0.939703)(3.36219,0.972363) + (3.39601,1.00227)(3.43214,1.02959)(3.47059,1.05448) + (3.51138,1.07706)(3.55453,1.09746)(3.60007,1.11578)(3.64806,1.1321) + (3.69855,1.14651)(3.7516,1.15908)(3.80729,1.16986)(3.8657,1.1789) + (3.92693,1.18624)(3.99108,1.19191)(4.05827,1.19595) + (4.12864,1.19837)(4.20232,1.19917) +%% +\path(3.35808,0.672175)(3.35983,0.72558)(3.36501,0.774599) + (3.37347,0.819598)(3.38504,0.860893)(3.39963,0.898765) + (3.41712,0.933458)(3.43745,0.965188)(3.46056,0.994146) + (3.4864,1.0205)(3.51496,1.04439)(3.54621,1.06595)(3.58016,1.0853) + (3.61682,1.10254)(3.65621,1.11774)(3.69838,1.13099) + (3.74337,1.14236)(3.79125,1.15188)(3.84208,1.15962)(3.89595,1.1656) + (3.95296,1.16985)(4.01323,1.17239)(4.07686,1.17324) + (4.14402,1.17239)(4.21485,1.16985) +%% +\path(3.52526,0.741164)(3.51545,0.788632)(3.50964,0.832134) + (3.50762,0.871978)(3.50922,0.908436)(3.51427,0.941744) + (3.52267,0.972112)(3.5343,0.999723)(3.54909,1.02474) + (3.56698,1.0473)(3.58792,1.06753)(3.61189,1.08554)(3.63888,1.10142) + (3.66888,1.11525)(3.70192,1.1271)(3.73803,1.13704)(3.77726,1.14511) + (3.81965,1.15134)(3.86529,1.15577)(3.91427,1.15842)(3.96668,1.1593) + (4.02266,1.15842)(4.08232,1.15577)(4.14583,1.15134)(4.21335,1.14511) +%% +\path(3.67777,0.820294)(3.65721,0.861701)(3.64108,0.899549) + (3.62915,0.934095)(3.62121,0.965564)(3.6171,0.994154) + (3.61667,1.02004)(3.6198,1.04337)(3.6264,1.06427)(3.6364,1.08287) + (3.64973,1.09927)(3.66636,1.11354)(3.68628,1.12577) + (3.70947,1.13602)(3.73595,1.14434)(3.76576,1.15076) + (3.79892,1.15533)(3.83551,1.15806)(3.8756,1.15897)(3.91928,1.15806) + (3.96666,1.15533)(4.01786,1.15076)(4.07305,1.14434) + (4.13239,1.13602)(4.19606,1.12577) +%% +\path(3.81395,0.908683)(3.7835,0.944037)(3.75778,0.976219) + (3.73655,1.00544)(3.7196,1.03187)(3.70673,1.05569)(3.6978,1.07702) + (3.69268,1.09599)(3.69125,1.1127)(3.69345,1.12725)(3.6992,1.13971) + (3.70846,1.15015)(3.72121,1.15862)(3.73744,1.16517) + (3.75716,1.16982)(3.7804,1.1726)(3.80719,1.17352)(3.83761,1.1726) + (3.87174,1.16982)(3.90966,1.16517)(3.95151,1.15862) + (3.99741,1.15015)(4.04754,1.13971)(4.10207,1.12725)(4.16122,1.1127) +%% +\path(3.93248,1.00525)(3.89302,1.03469)(3.85849,1.06132) + (3.82862,1.08529)(3.8032,1.10676)(3.78203,1.12584)(3.76496,1.14265) + (3.75186,1.15728)(3.74261,1.16981)(3.73712,1.1803)(3.73534,1.18881) + (3.73721,1.19538)(3.74271,1.20006)(3.75182,1.20285) + (3.76456,1.20378)(3.78095,1.20285)(3.80105,1.20006) + (3.82491,1.19538)(3.85261,1.18881)(3.88428,1.1803)(3.92002,1.16981) + (3.95999,1.15728)(4.00437,1.14265)(4.05336,1.12584)(4.10719,1.10676) +%% +\path(4.03246,1.10877)(3.9849,1.13255)(3.94232,1.15384) + (3.90448,1.17276)(3.87115,1.18943)(3.84215,1.20393) + (3.81732,1.21634)(3.79653,1.22673)(3.77966,1.23517) + (3.76664,1.24168)(3.75738,1.24631)(3.75184,1.24908)(3.75,1.25) + (3.75184,1.24908)(3.75738,1.24631)(3.76664,1.24168) + (3.77966,1.23517)(3.79653,1.22673)(3.81732,1.21634) + (3.84215,1.20393)(3.87115,1.18943)(3.90448,1.17276) + (3.94232,1.15384)(3.9849,1.13255)(4.03246,1.10877) +%% +\path(4.11344,1.2179)(4.05862,1.23638)(4.00875,1.25265) + (3.96358,1.26681)(3.92291,1.27893)(3.88655,1.28908) + (3.85434,1.29732)(3.82617,1.30368)(3.8019,1.3082)(3.78147,1.3109) + (3.7648,1.3118)(3.75185,1.3109)(3.74259,1.3082)(3.737,1.30368) + (3.73509,1.29732)(3.73691,1.28908)(3.74248,1.27893) + (3.75189,1.26681)(3.76522,1.25265)(3.78259,1.23638)(3.80413,1.2179) + (3.83001,1.1971)(3.86043,1.17387)(3.89561,1.14806)(3.93582,1.11951) +%% +\path(4.17536,1.33125)(4.1141,1.34487)(4.05764,1.35653) + (4.00578,1.36629)(3.95829,1.37421)(3.91502,1.38033) + (3.87582,1.38467)(3.84055,1.38727)(3.80911,1.38814) + (3.78141,1.38727)(3.7574,1.38467)(3.73702,1.38033)(3.72024,1.37421) + (3.70706,1.36629)(3.69748,1.35653)(3.69152,1.34487) + (3.68923,1.33125)(3.69069,1.3156)(3.69598,1.29782)(3.70521,1.27783) + (3.71851,1.25549)(3.73607,1.23067)(3.75806,1.20321) + (3.78473,1.17295)(3.81635,1.13966) +%% +\path(4.21858,1.44744)(4.1516,1.45669)(4.08922,1.46419) + (4.03123,1.46999)(3.97745,1.47411)(3.9277,1.47657)(3.88184,1.47739) + (3.83976,1.47657)(3.80136,1.47411)(3.76654,1.46999) + (3.73525,1.46419)(3.70743,1.45669)(3.68306,1.44744) + (3.66212,1.43639)(3.6446,1.42349)(3.63055,1.40867)(3.61998,1.39183) + (3.61298,1.3729)(3.60961,1.35175)(3.60998,1.32826)(3.61423,1.30227) + (3.62251,1.27364)(3.63501,1.24216)(3.65195,1.20761)(3.67361,1.16975) +%% +\path(4.24381,1.56512)(4.17177,1.57053)(4.10405,1.57438) + (4.04046,1.57668)(3.98083,1.57745)(3.925,1.57668)(3.87283,1.57438) + (3.82422,1.57053)(3.77905,1.56512)(3.73724,1.55811) + (3.69874,1.54948)(3.66348,1.53917)(3.63142,1.52713) + (3.60256,1.51329)(3.57688,1.49759)(3.5544,1.47993)(3.53514,1.46021) + (3.51915,1.43832)(3.50651,1.41411)(3.49729,1.38745) + (3.49162,1.35815)(3.48963,1.32601)(3.4915,1.29081)(3.49742,1.25228)(3.50765,1.21013) +%% +\path(4.25204,1.68304)(4.1755,1.68516)(4.10297,1.68587) + (4.03426,1.68516)(3.9692,1.68304)(3.90765,1.6795)(3.84948,1.67451) + (3.79458,1.66806)(3.74284,1.66012)(3.69417,1.65063) + (3.64852,1.63955)(3.60582,1.62683)(3.56602,1.61239) + (3.52909,1.59616)(3.49501,1.57805)(3.46379,1.55795) + (3.43543,1.53574)(3.40997,1.51128)(3.38744,1.48442) + (3.36791,1.45499)(3.35146,1.42277)(3.3382,1.38755)(3.32827,1.34904) + (3.32183,1.30695)(3.31908,1.26093) +%% +\path(4.24449,1.80006)(4.16396,1.79942)(4.08706,1.79749) + (4.01364,1.79428)(3.94353,1.78975)(3.87659,1.78389) + (3.81271,1.77667)(3.75175,1.76806)(3.69363,1.75801) + (3.63824,1.74647)(3.58552,1.73338)(3.53538,1.71867) + (3.48778,1.70226)(3.44267,1.68406)(3.40001,1.66397) + (3.35977,1.64186)(3.32194,1.6176)(3.28653,1.59104)(3.25354,1.56199) + (3.22299,1.53026)(3.19494,1.49562)(3.16944,1.4578)(3.14657,1.4165) + (3.12642,1.37138)(3.10914,1.32202) +%% +\path(3.75,1.25)(3.27753,1.48623) +%% +\path(3.34504,1.46989)(3.36522,1.4598) +\path(3.32254,1.47533)(3.3629,1.45515) +\path(3.30004,1.48078)(3.36058,1.45051) +\path(3.27753,1.48623)(3.35825,1.44587) +\path(3.29539,1.4715)(3.35593,1.44123) +\path(3.31325,1.45677)(3.35361,1.43659) +\path(3.33111,1.44204)(3.35129,1.43195) +\path(3.35825,1.44587)(3.36754,1.46444)(3.27753,1.48623) + (3.34897,1.42731)(3.35825,1.44587) +%% +\path(3.75,1.25)(3.14565,0.947826) +%% +\path(3.19923,0.99202)(3.21941,1.00211) +\path(3.18137,0.977289)(3.22173,0.997469) +\path(3.16351,0.962557)(3.22405,0.992827) +\path(3.14565,0.947826)(3.22637,0.988186) +\path(3.16815,0.953275)(3.22869,0.983545) +\path(3.19065,0.958724)(3.23101,0.978904) +\path(3.21315,0.964173)(3.23333,0.974263) +\path(3.22637,0.988186)(3.21709,1.00675)(3.14565,0.947826) + (3.23565,0.969622)(3.22637,0.988186) +%% +\allinethickness{1pt}% +\color{rgb_980000}% +\path(4.875,0.125) + (4.875,2.375)(2.625,2.375)(2.625,0.125)(4.875,0.125) +%% +\end{picture} diff --git a/graphics/epix/doc/layout.xp b/graphics/epix/doc/layout.xp new file mode 100644 index 0000000000..cd3e201011 --- /dev/null +++ b/graphics/epix/doc/layout.xp @@ -0,0 +1,36 @@ +/* -*-ePiX-*- */ +/* layout.xp -- June 27, 2007 */ +#include "epix.h" +using namespace ePiX; + +const double a(sqrt(3)); +P f(double u, double v) +{ + return P((u-v)*(u+v), 2*u*v, u); //u*(u-a*v)*(u+a*v)); +} + +int main() +{ + picture(P(0,0), P(2,3), "5x7.5in"); + + begin(); + + domain R(P(-1,-1), P(1,1), mesh(12,12), mesh(24,24)); + + for (int i=0; i<2; ++i) + for (int j=0; j<3; ++j) + { + screen my(P(-3,-3), P(3,3)); + activate(my); + border(Red(0.6), "1pt"); + camera.at(sph(10, (2*j+i+1)*M_PI/8, M_PI/6)); + + plot(f, R); + arrow(P(0,0,0), 2*E_1); + arrow(P(0,0,0), 2*E_2); + inset(P(i+0.05,2.05-j), P(i+0.95,2.95-j)); + } + + end(); +} + diff --git a/graphics/epix/doc/manual.pdf b/graphics/epix/doc/manual.pdf Binary files differnew file mode 100644 index 0000000000..bd8fc76619 --- /dev/null +++ b/graphics/epix/doc/manual.pdf diff --git a/graphics/epix/doc/manual.tex b/graphics/epix/doc/manual.tex new file mode 100644 index 0000000000..71aa59aa97 --- /dev/null +++ b/graphics/epix/doc/manual.tex @@ -0,0 +1,5030 @@ +%% Version 1.2.0 +\documentclass[12pt]{book} +\usepackage{amsmath,latexsym,epic,eepic,pstricks,xcolor,comment} +\usepackage[dvips,hyperref]{hyperref} + +\usepackage{makeidx} +\makeindex + +\renewcommand{\thefigure}{\arabic{chapter}.\arabic{figure}} + +\newcommand{\code}[1]{\texttt{#1}} +\newcommand{\filename}[1]{\texttt{#1}} +\newcommand{\Key}[1]{\texttt{#1}} +\newcommand{\URL}[1]{\texttt{#1}} + +%% \setlength{\topmargin}{0.5in} +\newcommand{\ePiX}{\code{ePiX}} +\newcommand{\ext}{\code{ePiX\_ext}} +\newcommand{\epix}{\code{epix}} +\newcommand{\eepic}{\code{eepic}} +\newcommand{\C}{\code{C}} +\newcommand{\CXX}{\code{C++}} +\newcommand{\pyepix}{\code{Pyepix}} + +\DeclareMathOperator{\clip}{clip} + +\newcommand{\Header}[1]{\smallskip\noindent\texttt{#1}% + \index{Header file!{#1}@\texttt{#1}}\quad} + +%% Substitution commands easily removable by sed for texinfo: +%% Remove recalcitrant chunks, +\newcommand{\texicomment}{} +\newcommand{\texicommentend}{} + +%% mark simple math, +\newcommand{\teximath}[1]{$#1$} +%% make function index entries, +\newcommand{\findex}[1]{} + +%% top-level division (first argument for texinfo node name) +\newcommand{\texinfochapter}[2]{\chapter{#2}} +\newcommand{\texinfoappendix}[2]{\chapter{#2}} + +%%\renewcommand{\subsection*}[1]{\subsection{#1}} + +\title{ \ePiX\ Tutorial and \\ Reference Manual} +\author{Andrew D. Hwang \\ + Department\ of Math and CS \\ + College of the Holy Cross} +\date{Version 1.2, September, 2007} + +\begin{document} + +\maketitle + +\tableofcontents + +\texinfochapter{1}{Introduction} + +\ePiX, a collection of batch utilities, creates mathematically +accurate figures, plots, and animations containing \LaTeX\ typography. +The input syntax is easy to learn, and the user interface resembles +that of \LaTeX\ itself: You prepare a scene description in a text +editor, then ``compile'' the input file into a picture. \LaTeX- and +web-compatible output types include a \LaTeX\ picture-like environment +written with \code{PSTricks}, \code{tikz}, or \code{eepic} macros; +vector images (\code{eps}, \code{ps}, and~\code{pdf}); and bitmapped +images and movies (\code{png}, \code{mng}, and~\code{gif}). + +\ePiX's strengths include: + +\begin{itemize} +\item Quality of output: \ePiX\ creates accurate, publication-quality + figures whose appearance matches that of \LaTeX. Typography may be + put in a figure as easily as in an ordinary \LaTeX\ document. + +\item Ease of use: Figure objects and their attributes are specified + by simple, descriptive commands. + +\item Flexibility: Objects are described by attributes and Cartesian + location; as in \LaTeX, printed appearance is determined when the + figure is compiled. A well-designed figure can be altered + dramatically, yet precisely, with command-line switches or minor + changes to the input file. + +\item Power and extendibility: \ePiX\ inherits the power of \CXX\ as a + programming language; variables, data structures, loops, and + recursion can be used to draw complicated plots and figures with + just a few lines of input. External code can be incorporated in a + figure with a command line option or by using a Makefile. + +\item Economy of storage and transmission: For a document containing + many figures, a compressed tar file of the \LaTeX\ sources and + \ePiX\ files is typically a few percent the size of the compressed + PostScript file. + +\item License: \ePiX\ is \emph{free software}.\index{Free software} + You are granted the right to use the program for whatever purpose, + and to inspect, modify, and re-distribute the source code, so long + as you do not restrict the rights of others to do the same. In + short, the license is similar to the terms under which theorems are + published. + +\end{itemize} + + +\ePiX\ facilitates logical, as opposed to visual, structuring of +mathematical figures, analogous to the relationship between \LaTeX\ +and a word processor. A few stylistic defaults streamline the creation +of simple figures, but there are few internal restrictions on the +contents or appearance of a figure; aesthetic and practical decisions +are left to you. + +If you are a: + +\begin{itemize} + +\item Potential user, you may wish to skip immediately to ``Software + Dependencies'' before investing additional time. + +\item New user, proceed from here until you have enough understanding + to run the software, then experiment with the samples files while + reading Chapter~\ref{chapter:started}, or return to the manual as + needed. + +\item More advanced user, browse at will, probably starting with + Chapter~\ref{chapter:ref-man}. + +\end{itemize} + +This manual is relatively conversational, and occasionally redundant, +especially between portions meant for readers at different levels of +familiarity. Throughout, you are assumed to be familiar with \LaTeX\ +and basic linear algebra: the description of points, vectors, lines, +and planes in three-dimensional space. Other material, such as \CXX\ +syntax, is introduced as needed. + + +\section{Changes in Version~1.2} + +\ePiX~1.2.x has been written almost entirely from scratch. The +conceptual model is unchanged, but there are a few changes of +syntax. If you're new to~\ePiX, please skip straight to +Section~\ref{section:software_deps}. + + +\subsection{Syntax Changes} + +Except as noted below, \ePiX~1.0 files will compile under +Version~1.2. Generally, global variables have been deprecated or +removed, and should be replaced by function calls in new files. The +following changes are either required, or else strongly recommended +(and may become mandatory). + +\begin{itemize} + +\item (Mandatory) The global variable \verb+tix+ in a \filename{flix} + file must be manipulated through the function \verb+tix()+. + +\item (Mandatory) The command \code{use\_pstricks()} is obsolete. + PSTricks output is obtained systematically as an output format. + +\item (Mandatory) Deprecated ``aliases'' no longer exist: + \code{triple} (for the \code{P} class), \code{D}~(for \code{Deriv}), + and \code{I}~(for \code{Integral}). Lowercase trig function names + conflicted with the standard namespace and have been removed. + +\item (Mandatory) Geometric object commands (\code{circle}, + \code{plane}, \code{segment}, and~\code{sphere}), which formerly + created class objects, now perform drawing just as \code{ellipse}, + \code{line}, \code{rect}, etc., do. The classes are available with + capitalized names (\code{Circle}, etc.). + +\item (Mandatory) Camera orientation is controlled with functions + named \code{tilt}, \code{pan}, and~\code{roll}; each rotates + the camera about an axis through the viewpoint, not through the + target. + +\item (Recommended) The global size variables \verb+x_min+, + \verb+x_max+, \verb+y_min+, \verb+y_max+, \verb+x_size+, and + \verb+y_size+ should be replaced by the function calls + \verb+xmin()+, etc. (No underscores.) + +\item (Suggested) The camera may be accessed through the function + \code{cam()}. + +\item (Suggested) The size and bounding box are given in one command, + such as \code{picture(P(-1,0), P(1,1), "4x3in")}. The old syntax + will be retained indefinitely. + +\end{itemize} + + +\subsection{New Features} + +\begin{itemize} + +\item Output is cleanly separated from the internal representation. + Figures may be written with a choice of macros---\code{PSTricks}, + \code{tikz}, and \code{eepic} at present---and new output types + are easily coded so long as the format supports arbitrary line + segments, color, and the ability to place a \LaTeX\ box at a + specified location. + +\item Colors are a manipulable data type, available in RGB, CMY, CMYK, + and Gray models. \filename{xcolor}-style operations, such as color + model conversion, blending, superposition, and inversion are + provided. + + The camera has a filter which affects the colors of all scene + elements. Filters performing CMYK separation are provided. + +\item Color filling is controlled with declarations, similarly to line + colors in \ePiX~1.0. Arrows and markers of type spot, dot, ddot, + and~circ are now colored like other markers. Parametric surfaces + may be color-shaded. + + If a figure contains many shaded elements, a color-capable output + format (e.g.\ \code{PSTricks}~or \code{tikz}) should be used for + efficiency. Filled regions are implemented as fine hatching in + \filename{eepic}. + +\item An \code{axis} class provides coordinate axes with labels in a + variety of styles: decimals or scientific notation of specified + precision, fractions, trig fractions, logarithmic labels in + arbitrary (integer) base, and user-supplied styles. + +\item \ePiX~1.2.x performs page layout. Sub-figures may be manipulated + flexibly. The sample files give several applications. + +\item Non-member intersection operators for circles, planes, spheres, + and segments are provided. A ``non-generic'' intersection does not + throw an exception, but instead returns an undrawable ``malformed'' + object. + +\end{itemize} + + +\section{Software Dependencies} +\label{section:software_deps} + +\index{Installation|(} +\index{Mac OS X} + +If you run GNU/Linux, a BSD, or Solaris, you probably have (and can +surely install) all the external software needed to use \ePiX. On +Mac~OS~X, you will need the Apple developer tools and an X~server +(XCode and XDarwin on the Tiger disks), and the free~\code{fink} +package manager to build a GNU environment. For Windows, you'll need +to install Cygwin and several packages. Detailed instructions are +given below. + +``Under the hood'', an input file is successively converted to a +\LaTeX\ picture; \code{dvi}; PostScript, \code{pdf}~or \code{eps}; and +if desired, to a bitmapped image or movie. Four shell +scripts---\epix, \code{laps}, \code{elaps}, and~\code{flix}---automate +the various file format conversions. + +\ePiX\ consists of a \CXX\ library, header, and shell scripts, and +requires GNU \code{bash} and a compiler \emph{for normal use}. For +complete functionality, you need \code{g++} (Version~3.2 or later), +\code{bash}, a text editor (\ePiX\ works particularly well with +\code{emacs}), a \LaTeX\ distribution, \code{Ghostscript}, \code{gv} +(or your favorite PS/PDF previewer), and \code{ImageMagick}. GNU +\code{grep} and \code{sed} are good to have. You may need additional +``developer packages'' (\code{binutils}, \code{make}) in order to +build \ePiX. The more up to date your software is, the better your +experience is likely to be, but bleeding edge versions are not +necessary, or even always desirable. + +Aside from their reliance on specific programs, \ePiX's shell scripts +are written using Unix-style pathnames. Thus, the most straightforward +way to use \ePiX\ is to install a GNU environment. + +Jay Belanger's \code{emacs} mode allows you to write, compile, and +view \ePiX\ figures without leaving \code{emacs}. If you use another +editor, you'll want to create template source files so you don't have +to type boilerplate code each time you write a new figure. +\index{Emacs@\code{emacs}} + + +\subsection{Setting up an Environment Under Windows} + +\index{Windows operating system|(} +\begin{comment} +Version~1.0.4 of \ePiX\ has been implemented in Python~2.2 by Andrew +Sterian, making \ePiX\ available on any platform that supports Python, +and without requiring a \CXX~compiler or~\code{bash}. Python is a +GPL-ed scripting language, and is available with a Windows installer +and detailed instructions. The easiest alternative for Windows users +is probably to install Python~2.2 or later (if necessary) and +\code{Pyepix}. The \code{pyepix} project home page is: +\URL{claymore.engineer.gvsu.edu/~steriana/Python/index.html} +\end{comment} + +Cygwin can be used to run \ePiX\ under Windows. Download +\filename{setup.exe} from \URL{www.cygwin.com}, then install the +packages you need. The following are recommended, and sufficient for +the actions described in this manual. +\begin{verbatim} +(Archive) bzip2, tar +(Devel) binutils, coreutils, gcc, gcc-g++, make, sed +(Editors) emacs, emacs-X11, vim +(Graphics) ImageMagick, ghostscript-base, ghostscript-x11, gv +(Publishing) tetex (all) +(Shells) bash, bash-completion +(X11) X-start-menu-icons, X-startup-scripts, + XFree86-lib-compat, xorg-x11-fscl, xorg-x11-fsrv +\end{verbatim} +\index{Windows operating system|)} + + +\section{Installation} + +\ePiX\ is distributed over the World-Wide Web as source code. Packages +may be found at \URL{mathcs.holycross.edu/\~{}ahwang/epix/ePiX.html} +The latest stable release is also on the CTAN mirrors, in the +\code{graphics} directory. (Some users of Red Hat have reported file +permission problems when unpacking the CTAN tarballs. If you encounter +this difficulty, please try downloading the sources from the project +main page.) Unpack the compressed tar file with the appropriate +command: +\begin{verbatim} + tar -zxvf epix-x.y.z.tar.gz + tar -jxvf epix-x.y.z.tar.bz2 +\end{verbatim} +(\code{x.y.z}~is the version number) or, if your \code{tar} +doesn't do decompression, +\begin{verbatim} + gunzip -c epix-x.y.z.tar.gz | tar -xvf - + bzcat epix-x.y.z.tar.bz2 | tar -xvf - +\end{verbatim} +\code{cd} to the source directory, \filename{epix-x.y.z}. The +\filename{INSTALL} file contains detailed installation instructions. +If you're impatient, the short of it is \code{./configure [--options]; + make; make install}. Run \code{./configure --help} for a list of +options. + +By default, \ePiX\ installs in subdirectories of +\filename{/usr/local}; if you want to install elsewhere, supply +\code{./configure} with the appropriate \code{--prefix}. You may also +want to consult \filename{POST-INSTALL} for information on setting +your \code{PATH} variable so your shell can find \ePiX. The manual +and sample files are in \filename{/usr/local/share/doc/epix}. +\index{Installation|)} + + +\subsection{Development} + +There are two mailing lists, one for user questions, one for +development discussion. Please visit +\URL{savannah.nongnu.org/mail/?group=epix} to subscribe. + + +\texinfochapter{2}{Getting Started} +\label{chapter:started} + +This chapter describes the basics of creating figures in \ePiX\ for +readers familiar with \LaTeX\ but completely new to~\CXX. No detailed +knowledge of~\CXX\ is needed to use \ePiX, only a bit of grammar that +is easily absorbed by example. + +Section~\ref{section:running} describes the commands (shell scripts) +comprising \ePiX, and explains how to set up a graphical environment +using standard *nix programs. Section~\ref{section:overview} briefly +describes figure creation. Section~\ref{section:tutorial} presents a +few files side-by-side with their output, and should be read at a +computer so you can run the exercises. + + +\section{Running \ePiX} +\label{section:running} + +An ``input file'' is a human-written figure specification containing +\ePiX\ commands. An ``output file'' is machine-created, and is +included directly into a \LaTeX\ document with the appropriate +packages. + +Conversion (``compiling'' a figure) is accomplished with four shell +scripts, \code{laps}, \code{epix}, \code{elaps}, and \code{flix}. +Each script has a preferred extension for its input files, and is +invoked with a command of the form +\begin{verbatim} + <script> [options] <input file(s)> +\end{verbatim} +Often, no options are necessary. \code{<script> --help} +describes \code{<script>}'s options. +\texicomment +Figure~\ref{fig:programs} (page~\pageref{fig:programs}) diagrams the +shell scripts and the file types they process. +\texicommentend + +By default, output file names are constructed by replacing the input +extension with the (preferred) output extension. For brevity, +extensions may be omitted. If the script has doubts about your intent, +it proceeds with default behavior and prints a warning message. + +The author is a great fan of \Key{TAB} completion, under which a +shell, based on what has been typed so far, automatically fills in a +command when the \Key{TAB} key is pressed. \ePiX\ comes with code +snippets that complete intelligently when the first part of a command +is one of the shell scripts. For example, if command completion is +active, typing \code{epix} \Key{TAB} prints only names of \code{epix} +input files. To use this feature, you must install Ian MacDonald's +\code{bash completion} package. The \filename{INSTALL} and +\filename{POST\_INSTALL} files contain details. + + +\subsubsection*{\code{laps}} + +\code{laps} performs \LaTeX\ to PostScript/PDF conversion, and is +independent of the rest of \ePiX. By default, \code{laps} invokes +\LaTeX~and \code{dvips}. The option \code{--pdf} creates a PDF~file by +post-processing the PostScript with~\code{ps2pdf}. Other \TeX-family +processors (\code{pslatex}, \code{pdftex}, etc.) may be used instead +of~\LaTeX\ by invoking \code{laps} with an appropriate option. + + +\subsubsection*{\code{epix}} + +\code{epix} compiles an input file into a \LaTeX\ picture. The input +file should have extension \filename{xp} (for eXtended Picture). Jay +Belanger's \code{emacs} mode is Highly Recommended; the installation +procedure can be found in the \filename{POST\_INSTALL} file. When this +mode is active, \code{emacs} automatically inserts a preamble template +when a new \filename{xp} file is created. In addition, you can peruse +\ePiX's info file, or format, compile, and preview files, all from +within \code{emacs}. +\index{Emacs@\code{emacs}} + +Output files from the script \code{epix} have extension +\filename{eepic}, after Conrad Kwok's enhancements to the \LaTeX\ +picture environment. In Version~1.2, however, an output file need not +contain \code{eepic} macros at all. + +An output file is \code{input} directly into a \LaTeX\ document whose +preamble contains appropriate \code{usepackage} lines. +\texicomment +\begin{center} + \begin{tabular}{cc} + Format & Required Package(s) \\ + \hline + \code{eepic} & \code{epic,eepic,xcolor} \\ + \code{pst} & \code{pstricks} \\ + \code{tikz} & \code{tikz} + \end{tabular} +\end{center} +\texicommentend +Rotated text requires the \code{rotating} package. + + +\subsubsection*{\code{elaps}} + +\code{elaps} creates stand-alone vector images (\filename{eps}~or +\filename{pdf}) from \code{epix} input files or \filename{eepic} +figures, even those not produced with \code{epix}. \code{elaps} +automatically loads the \LaTeX\ packages needed for features described +in this manual. Additional \LaTeX\ packages and \code{dvips} options +may be specified on the command line. + + +\subsubsection*{\code{flix}} + +\code{flix} creates bitmapped images and movies, +Section~\ref{section:animation}. Input files should have extension +\filename{flx}, and must contain a valid \code{epix} header as well as +additional code. Jay Belanger's \code{emacs} mode facilitates creation +of \code{flix} files. + + +\section{The Drawing Model} +\label{section:overview} + +To draw a figure manually, you select a sheet of paper of appropriate +size and add paths, markers, and labels. These scene elements have +attributes (line color, line width, fill color, font size, etc.) +affecting their appearance. + +\index{canvas} +\ePiX's drawing model behaves similarly. A \code{picture} command +sets the \emph{canvas} (or logical drawing area, a Cartesian +rectangle) and the true size of the final figure. A \code{begin} +command initializes the ``virtual paper'' for drawing. Subsequent +\emph{drawing commands} add objects to the scene: lines, curves, +function plots, labels, and the like. The printed appearance of scene +elements is determined by the current ``attribute state'' and +controlled by \emph{style declaration} which remain in effect until +superseded. Finally, an \code{end} command closes the figure and +prints it to the output file. + +In this manual, command descriptions follow a few +conventions. Optional arguments are enclosed in square brackets. A +\code{len} argument is either a number (representing a length in +\code{pt}) or a double-quoted string containing a number and a +two-letter \LaTeX\ length unit, such as \code{"1.5pt"} or +\code{"6cm"}. A \code{color} argument is a named primary +(\code{Red()}, \code{Cyan()}, \code{White()}, etc.), or a \code{Color} +specified by densities (\code{RGB(r,g,b)}, \code{CMY(c,m,y)}, etc.) + +\begin{itemize} + +\item Fill color: \code{fill(color)}, \code{nofill()}. + +\item Line color and width: \code{plain([color])}, + \code{bold([color])}. + +\item Text size: \code{font\_size([size])}, returns to + \code{normalsize} if no argument is given. + +\end{itemize} + +\noindent A complete list of style commands is found in +Section~\ref{section:quickref}, starting on +page~\pageref{section:quickref}. + +To handle three-dimensional scenes, a \code{camera} performs point +projection from a selected spatial location to the canvas. As a user, +you'll need to control relatively few of the \code{camera}'s +parameters. Keep in mind, however, that elements are added to a scene +in the same order their commands appear in the output file, and that +later elements generally cover earlier ones. Some three-dimensional +scenes require manual ordering of the input file; such ordering is +dependent on the \code{camera}'s location. + +By default, \ePiX\ draws thin, solid, black lines, performs no filling +of regions, prints text in a 12~pt Roman font, and looks down the +\teximath{z}~axis from a large distance, giving orthogonal projection +on the \teximath{(x,y)}~plane. When the \code{camera} is moved, the +\teximath{z}~axis points vertically up on the page. + + +\section{Tutorial} +\label{section:tutorial} + +This section presents sample input files side-by-side with their +output so you can compare what you write with what you'll see on the +screen or page. \ePiX\ provides standard drawing capabilities, but +like all software has its own idioms and personality. The basic +syntax, which comes from \code{C}/\CXX, should be mostly +self-explanatory. One-line comments begin with the +string~``\verb+//+''. + + +%%\index{Emacs@\code{emacs}} +\index{Graphical interface} +To use the sample files interactively, you'll need working software: +\filename{bash}, \filename{emacs}, \ePiX, \filename{g++}, +\filename{gv}, and a running X~server. To complete your ``GUI'', +start~\filename{gv} and select ``Watch file'' from the ``State'' +menu. The loaded file will update automatically when it changes. + +Create a ``scratch'' directory, \code{cd} into it, and run the command +\begin{verbatim} + tar -zxf /usr/local/share/doc/epix/sample_src.tar.gz +\end{verbatim} +(Change the path as appropriate for your installation.) This unpacks +copies of the sample files into your scratch directory, including all +the files mentioned in this manual. The \filename{README} file serves +as a table of contents. + +Open a sample file in \filename{emacs}, compile it from the drop-down +menu (or with the keyboard command), then open the \filename{EPS} file +in~\filename{gv}. Now you're ready to follow the tutorial +interactively. A few suggested exercises are included with each +file. Naturally, as you study more files, you'll be able to make more +interesting changes on your own. + + +\subsubsection*{Basic Drawing} + +The first sample, \filename{hello.xp}, contains code needed to specify +the figure's size, followed by the classic greeting. The \code{border} +command draws a box around the figure in the specified color and +width, and serves here merely to delimit the output from the +surrounding page. +\begin{verbatim} +/* -*-ePiX-*- */ +#include "epix.h" // These lines are analogous +using namespace ePiX; // to a usepackage command. + +int main() +{ + picture(P(-1,-1), P(1,1), "2 x 1in"); // corners, true size + + begin(); // ---- Figure body starts here ---- + + border(Black(), "1pt"); // color, line width + + font_size("Huge"); // May be any font size, e.g. "scriptsize" + label(P(0,0), "Hello, world!"); + + end(); // ---- End figure; write output file ---- +} +\end{verbatim} + +\begin{center} + \input{hello.eepic} +\end{center} + +\begin{itemize} + +\item Change the color and width of the + border. (\code{RGB(r,g,b);} creates an RGB color, CMY colors are + analogous. Named primaries are available. The densities should be + between \teximath{0}~and \teximath{1} for ``expected'' behavior.) + +\item Add \code{backing(Cyan());} after the \code{border} command. + +\item Put the command \code{crop\_ellipse();} before the \code{border} + command. Permute the \code{crop\_ellipse} command with the + \code{border} and \code{backing} lines, and note how the attribute + (\code{crop}) affects objects (\code{border}, \code{backing}). + +\end{itemize} + + +\subsubsection*{Geometric Objects} + +Our next file uses simple objects to draw a 2-D house-and-sun scene. + +\begin{verbatim} +int main() +{ + picture(P(0,0), P(5,2), "3.75 x 1.5in"); + + begin(); + + triangle(P(0.9, 1), P(3.1, 1), P(2, 1.5)); // vertices + circle(P(4,1.5), 0.25); // center and radius + + rect(P(1,0), P(3,1)); // opposite corners + + fill(Black(0.1)); // light gray + rect(P(2.3,0), P(2.7,0.8)); // the door + nofill(); + + bold(); // draw thicker lines + grid(P(1.4, 0.2), P(2, 0.6), 2, 2); // corners, number of squares + + line(P(xmin(), 0), P(xmax(), 0)); // endpoints + + end(); +} +\end{verbatim} + +\begin{center} + \input{objects.eepic} +\end{center} + +\begin{itemize} + +\item Add declarations such as \code{bold(RGB(1,0.9,0.5))} or + \code{fill(Yellow())} to color the scene. (Color and filling are + orthogonal attributes.) +\end{itemize} + +\noindent The sample file \filename{house.flx} uses loops to draw +gradient fills of the lawn, sky, and sun, and animates a sunset. + + +\subsubsection*{Function Plotting} + +Plotted functions must be defined in the ``preamble'', before +\code{main}. ``High-level'' elements---coordinate axes and grids, axis +labels, and graphs---are drawn with mnemonically-named commands. +\begin{verbatim} +// double = double-precision floating point +double f(double x) { return 0.75*Sin(x) - 0.25*Sin(2*x); } + +int main() +{ + picture(P(-2,-1), P(2,1), "5 x 1in"); // [-2,2] x [-1,1] + + begin(); + revolutions(); // set angle units, [0,1] = one turn + + h_axis(16); // axes w/default endpts + v_axis(4); + h_axis_labels(4, P(0,-4), b); // shift down 4pt, align below + + plain(Red()); + plot(f, xmin(), xmax(), 120); // use 120 intervals + + end(); +} +\end{verbatim} + +\begin{center} + \input{plotting.eepic} +\end{center} + +\begin{itemize} + +\item Define and plot some different functions; adjust the bounding + box as necessary. (Use repeated multiplication for polynomials. + The \code{polarplot} command graphs \teximath{r=f(\theta)}.) + +\item Change the arguments to \code{h\_axis\_labels}. The first + specifies the number of intervals to label; the second gives the + label offset in~\code{pt}. The last puts each label below~(\code{b}) + its Cartesian location. + +\end{itemize} + + +\subsubsection*{Multivariable Plotting} + +Functions of two or three variables are defined just like functions of +one variable, but for plotting the return type must be a +point~(\code{P}), not a real number~(\code{double}). The \code{domain} +class specifies the set of inputs to plot. + +\begin{verbatim} +P f(double r, double th) +{ + return P(r*Cos(th), r*Sin(th), pow(r, 3)*Cos(3*th)); +} + +int main() +{ + picture(P(-1,-1), P(1, 1), "2 x 1in"); + begin(); + pst_format(); // use PSTricks macros for output + + // corners ([0,1] x [0,2\pi]) and fineness + // (8x40 rectangles, plotted at 16x120 resolution) + domain R(P(0,0), P(1, 2*M_PI), mesh(8,40), mesh(16,120)); + + camera.at(P(3,1,2)); // set the viewpoint + arrow(P(0,0,0), P(1.25,0,0)); // coordinate axes + arrow(P(0,0,0), P(0,1.25,0)); + + plain(Blue(1.2)); // line color and width + fill(Yellow()); // shading color + surface(f, R); + + end(); +} +\end{verbatim} + +\begin{center} + \input{plotting2.eepic} +\end{center} + + +\subsubsection*{Loops and Control Structures} +\label{taylor_poly} + +A function can be defined by an arbitrary algorithm, and a +\code{domain} may be used to plot a family of functions for several +values of one variable. + +\begin{footnotesize} +\begin{verbatim} +P sin_n(double x, double n) // Taylor polynomial of sin x +{ + const int N((int) floor(n)); // convert n to an index bound + const double sqx(-pow(x, 2)); // -x^2 + double val(x), summand(x); + + for (int i=1; i <= 2*N+1; i += 2) + { + summand *= (sqx/((i+1)*(i+2))); // (-1)^i x^{2i+1}/(2i+1)! + val += summand; + } + + return P(x, val); // return (x, y) +} + +int main() +{ + picture(P(0, -1), P(6*M_PI, 1), "5 x 1in"); + + begin(); + + set_crop(); + bold(Green()); + plot(Sin, 0, xmax(), 120); + + domain R(P(0,1), P(6*M_PI, 41), mesh(60, 40), mesh(120, 40)); + for (int i=3; 0 <= i; --i) // print in descending degree + { + bold(RGB(0.25*i, 0, 1-0.25*i)); // degree-dependent color + plot(sin_n, R.slice2(5*i+1)); // plot for n = 5i+1 + } + end(); +} +\end{verbatim} +\end{footnotesize} + +\begin{center} + \input{plotting3.eepic} +\end{center} + + +\subsubsection*{Page Layout} + +Page layout can be composed from sub-pages with \code{screen} objects. +In the loop body below, objects are added to the ``active'' +\code{screen}, then \code{inset} into the ``canvas'', the screen +representing the entire figure. + +\begin{verbatim} +P f(double u, double v) +{ + return P((u-v)*(u+v), 2*u*v, u); +} + +int main() +{ + picture(P(0,0), P(2,3), "5x7.5in"); // overall size + + begin(); + + domain R(P(-1,-1), P(1,1), mesh(12,12), mesh(24,24)); + + for (int i=0; i<2; ++i) + for (int j=0; j<3; ++j) + { + screen my(P(-3,-3), P(3,3)); + activate(my); + border(Red(0.6), "1pt"); + // frame-dependent viewpoint + camera.at(sph(10, (2*j+i+1)*M_PI/8, M_PI/6)); + + plot(f, R); + arrow(P(0,0,0), 2*E_1); + arrow(P(0,0,0), 2*E_2); + // SW corner at (i, 2-j), padded by 0.05 on all sides + inset(P(i+0.05,2.05-j), P(i+0.95,2.95-j)); + } + + end(); +} +\end{verbatim} + +\begin{center} + \input{layout.eepic} +\end{center} + + +\section{\CXX\ Basics} + +\index{Cplusplus@\CXX|(} +An \ePiX\ source file is a \CXX~program. If you've successfully +modified and compiled the sample files, you know enough~\CXX\ to use +\ePiX. In the author's experience, \code{C}~grammar suffices for most +applications. An excellent introduction to definitions of functions +and variables, control statements, and overall program structure is +Kernighan~and Ritchie's \emph{The \code{C} Programming Language}, +second edition~\cite{KnR}. + + +\subsection{File Format} + +\index{Emacs@\code{emacs}} +Jay Belanger's \code{emacs} mode for \code{ePiX} inserts a file +template when an empty buffer is opened with the extension~\code{xp}. +This section explains the purposes served by the template. A few +additional remarks may help you avoid basic syntax pitfalls. + +A \CXX\ file consists of ``statements'', analogous to ordinary +sentences. Common types include \emph{declarations} (which +``register'' a function, variable, or type name with the compiler), +\emph{definitions} (which assign meaning to declared names), and +\emph{function calls} (which cause a named function to execute). Most +statements in an \ePiX\ input file are function calls (``commands''). +Plain declarations are relatively rare in user files, since a +definition serves to declare any new names that it contains. + +Every statement ends with a semicolon, and conventionally a file +contains at most one statement per line. The compiler ignores +nearly all whitespace (spaces, tabs, and newlines), which should be +used freely to make files easy to read. Other punctuation +(periods, commas, (semi)colons, parentheses, braces, and quotes) +dictates file parsing, and must adhere stringently to grammar. + +An \ePiX\ file always begins with the lines +\findex{include} +\begin{verbatim} +#include "epix.h" // N.B. pre-processor directive, no semicolon +using namespace ePiX; +\end{verbatim} +The first line is analogous to a \LaTeX\ \code{usepackage} command: It +loads the contents of the ``header'' file \filename{epix.h}, importing +the names of commands provided by~\ePiX. To avoid name conflicts, +\ePiX's commands are enclosed in a ``namespace''. For example, the +\code{label} command is actually known to the compiler as +\code{ePiX::label}. The second line above tells the compiler to apply +the prefix tacitly. + + +\subsection{Variables and Functions} +%% \index{Variable}\index{Variable!names} +%% \index{Function}\index{Function!names} + +Definitions of variables and functions play the same role in a figure +that macro definitions play in a \LaTeX\ document: gathering and +organizing information on which the figure depends. A variable is +defined by supplying its type, name, and initial value. By far the +most common data types in~\ePiX\ are \code{double} (double-precision +floating point number), \code{P}, and \code{int}. The name of a +variable may consist (only) of letters (including the underscore +character) and digits, and must begin with a letter: +\begin{verbatim} +my_var, var2, MY_var, aLongVariableName; // valid +my-var, 2var, \v@riable, $x, ${MY_VARIABLE}; // not valid +\end{verbatim} +Variable names are case-sensitive, and numerous (non-universal) +conventions govern the significance of capitalization. Generally, make +names descriptive but not unwieldy, and avoid language keywords (such +as \code{const}, \code{true}, \code{double}, \code{class}, or +\code{public}) and names that begin with an underscore. + +A function accepts ``arguments'' and ``returns a value''. To define a +function in~\CXX, you must specify the return type, the name of the +function, the types of the arguments, and the algorithm by which the +value is computed from the inputs. The code block +\begin{verbatim} +double f(double x) +{ + return sqrt(1-x*x); +} +\end{verbatim} +specifies the \code{double}-valued function~\teximath{f} of one \code{double} +variable defined by the formula \teximath{f(x)=\sqrt{1-x^2}}. + + +\subsection{Comments} + +\CXX\ has two types of comments. \code{C}-style comments, which may +span several lines, are delimited by the strings \code{/*}~and +\code{*/}. One-line comments, analogous to the \LaTeX~\code{\%}, are +begun with \code{//}. A one-line comment may appear within a multi-line +comment, but a \code{C}-style comment may not; the compiler will +mistake the first~\code{*/} it encounters as the end of the current +multi-line comment. + + +\subsection{Program Execution} + +All the ``action'' in a \CXX\ program occurs inside the special +function~\code{main}. Running a compiled \CXX~program is viewed by the +operating system as calling the program's \code{main} function. The +return value (an \code{int}) is the program's exit status. The +contents of the output file start with \code{begin()} and terminate +with \code{end()}. Intervening statements constitute the \emph{body} +of the file. + +In \CXX, a function may not be defined inside another function. Thus, +variables may be defined inside \code{main}, but functions cannot be. + + +\subsection{Strings and Raw Output} + +In \CXX, a \code{string} is a sequence of characters. Most +\code{string}s in \ePiX\ input files are \emph{literals}, +double-quoted \code{string}s whose value is read from the input. In a +string literal, backslash is an escape character; a single backslash +is produced by a double backslash in the input file. Certain letters +have special meanings when backslash-escaped, including ``\verb+\n+'' +(newline) and ``\verb+\t+'' (\Key{TAB}). Unlike~\LaTeX, \CXX~does not +require a space to separate an escape sequence from following text; +the string ``\verb+\\textwidth+'' literally represents a \LaTeX\ +command, while ``\verb+\textwidth+'' is read ``\code{TABextwidth}'' by +the compiler. + +Though not commonly needed, raw text can be printed to the output +file. The functions \code{write}, \code{pre\_write}, and +\code{post\_write} accept \code{string} arguments. \code{write} prints +its argument where the call appears in the input file. The other +functions print their arguments before or after the completed picture, +respectively. These commands must be in the file body. As an +application, a complete \LaTeX\ \code{figure} environment (with +caption and label) can be produced by an \ePiX\ file, +Figure~\ref{fig:captioned}. + +\index{pre\_write} +\index{post\_write} +\index{write} +\findex{pre\_write} +\findex{post\_write} +\findex{write} +\begin{figure} +\begin{footnotesize} +\begin{verbatim} +#include "epix.h" +using namespace ePiX; + +int main() +{ + picture(P(-1,-1), P(1,1), "10cm x 3in); + begin(); + pre_write("\\begin{figure}[hbt]"); // comes before the picture + + post_write("\\caption{A \\LaTeX\\ figure.}"); // and after + post_write("\\end{figure}"); + + < ... other ePiX commands ... > + write("%% A comment near the end, but inside the picture."); + end(); +} // End of main() +\end{verbatim} +\end{footnotesize} +\caption{Generating a self-contained figure in \ePiX.} +\label{fig:captioned} +\end{figure} + + +\subsection{Conditionals and Loops} + +An algorithm's behavior usually depends on internal state. A +\emph{conditional statement} causes blocks of code to be executed +according to criteria. A \emph{loop} repeatedly executes a code +block, usually changing the values of variables in a predictable way, +so that the loop exits after finitely many traversals. + +\texicomment +Figure~\ref{fig:gcd} illustrates conditionals and loops with +Euclid's algorithm for the greatest common divisor. Three pieces of +notation require explanation: \code{j\%i} means~``\teximath{j\pmod i}'', +\code{||} is logical~``or'', and \code{==} is ``test for equality''. +(A single~``\code{=}'' is the assignment operator.) + +\index{Function!Euclidean algorithm} +\begin{figure}[hbt] +\begin{footnotesize} +\begin{verbatim} +int gcd (int i, int j) +{ + int temp(i); // initialization syntax + if (i==0 || j==0) + return i+j; // define gcd(k,0) = k + + else { + if (j < i) // swap them + { + temp = j; + j = i; + i = temp; + } + // the work is done here... + while (0 != (temp = j%i)) // assign temp, test for zero + { + j = i; + i = temp; + } + return i; + } +} +\end{verbatim} +\end{footnotesize} +\caption{Euclid's division algorithm in~\CXX.} +\label{fig:gcd} +\end{figure} +\texicommentend + +%% \noindent For details on conditionals, or for more advanced techniques +%% of \CXX\ programming, please consult a textbook or online tutorial. +\index{Cplusplus@\CXX|)} + +%% Force previous two figures onto the same page +%%\clearpage + +\section{Animation} +\label{section:animation} + +\index{Animation|(} +\ePiX\ is well-suited to the creation of mathematically accurate +animations: If a figure depends suitably upon a ``time'' parameter, +then a loop can be used to draw the entire figure for multiple time +values, yielding successive ``snapshots'' of the figure as time +progresses. The shell script~\code{flix} automates the process of +compiling a suitable input file into a collection of \filename{png}s +and assembling these frames into a \filename{mng}~or \filename{gif} +animation. ImageMagick is the image-handling engine. + +A \code{flix} file is an \code{epix} file with two restrictions: +\begin{itemize} + \item The \code{double} variable \code{tix()} is used as + ``clock''. + + \item \code{main} accepts two command line arguments and sets + \code{tix()} accordingly. +\end{itemize} +\index{Emacs@\code{emacs}} +Jay Belanger's \code{emacs} mode recognizes the file +extension~\filename{.flx} and inserts template code if an empty buffer +is opened. Creation of \code{flix} files is as easy as creation of +\code{epix} files. The \filename{samples} directory contains a +handful of \code{flix} files that may be consulted for ideas. + +By default, \code{flix} creates movies with 24~frames, in which +\code{tix()} runs from~0 to~1, and animates at +\teximath{0.08}~sec/frame. These and other parameters can be changed +with command-line options. + +A ``typical'' \code{.flx} file may take 30~seconds to a few minutes to +compile, depending on the number of frames and the complexity of each +frame. To facilitate debugging, \code{elaps} can be run on a +\code{flix} file. \code{elaps} runs in a fraction of the time, and if +\code{elaps} can't produce a viewable image, \code{flix} will surely +fail. While running, \code{flix} prints a progress bar counting the +number of \filename{eps} files that have been created. There will be +a delay of a few seconds (or more) after the last frame is produced, +during which ImageMagick's \code{convert} utility assembles the movie. +\index{Animation|)} + + +\section{Layout Tricks} +\label{section:layout} +\index{Layout} + +\subsection{Stereograms} +\index{Stereograms} +Stereograms are created by drawing a single scene twice from slightly +different points of view. To create a stereogram with \ePiX, write a +``scene'' function containing the necessary drawing commands, then set +the camera appropriately and call the scene function twice, once for +each frame. + +\subsubsection*{Crossed-Eyes Stereograms} + +The sample files \filename{lorenz.xp}~and \filename{twisted\_cubic.xp} +use page layout to draw crossed-eyes stereograms. For each frame, +create and activate a \code{screen}, set the camera, and call the +scene function. The frames are inset side by side in the final +picture. For a crossed-eyes stereogram, the frame from the +``rightmost'' camera position is placed on the left. + +\subsubsection*{Bi-Color Stereograms} + +The sample files \filename{cube.flx}~and \filename{mirrorball.flx} +contain animated red-cyan stereograms, suitable for viewing with 3-D +glasses. The technique works best with black-and-white line drawings, +but the basic approach is the same as for crossed-eyes stereograms: +Create a scene function and call it twice, setting the camera +appropriately. Layout is unnecessary since the frames are superposed. +Pen colors should be close to red and cyan, but ``optimal'' choices +depend on one's eyes and 3-D glasses. + +\subsubsection*{Stereographic Movies} + +Either form of stereogram can be animated in a \code{.flx} file, but +keeping one's eyes properly crossed requires practice while most +people can instantly see depth with 3-D glasses. As always when using +\code{flix}, debug the scene with \code{elaps} before compiling a +movie. If a stereoscopic effect is difficult to see in a still image, +it will be even harder to perceive in a movie. + + +\subsection{Inset Images} + +\ePiX\ can place external images into a figure, similarly to +Rolf Niepraschk's \code{overpic} package. You provide the Cartesian +center point, the file name, and optionally the true height and/or +width of the image: +\findex{label} +\begin{verbatim} + label(P(a,b), "\\includegraphics[width=w,height=h]{file}"); +\end{verbatim} +This effect requires the \filename{graphicx} package. When compiling a +stand-alone graphic containing an external image, you must specify the +\filename{graphicx} package on the command line: \code{elaps -p +graphicx <file>} + +\texicomment +\begin{figure}[hbt] + \begin{center} + \input{ePiX.eepic} + \end{center} + \caption{Visual guide to \ePiX's shell scripts} + \label{fig:programs} +\end{figure} +\texicommentend + + +\texinfochapter{3}{Reference Manual} +\label{chapter:ref-man} + +This chapter details \ePiX's capabilities, discussing attributes and +data types, and listing available commands in the form +\begin{verbatim} + label(P posn, [P offset], string text, [align]); + circle(P ctr, double rad=1, normal=P(0,0,1)); +\end{verbatim} +As in Chapter~\ref{chapter:started}, function arguments are given by +type (\code{P}, \code{double}, \code{string}, etc.)\ and name, or by +name alone if the type is clear. Optional arguments are enclosed in +square brackets. A few argument types, such as \code{[align]} above, +admit only a small number of values; these cases are explained when +the corresponding command is first introduced. + +A name followed by an equals sign and a value indicates a default +argument; if omitted in an input file, the compiler substitutes the +default value. Only trailing arguments may be specified this way. For +example, if the \code{rad} argument of the \code{circle} command is +omitted, the \code{normal} argument \emph{must} be omitted as well. + +In an input file, only an argument's value is given, not the type: +\begin{verbatim} + label(P(0,0), P(0,-4), "Hello world", b); + circle(P(0,-0.25), sqrt(2)); // use default normal +\end{verbatim} + +Generally, \code{len} signifies either a number (representing a length +in \code{pt}) or a double-quoted string containing a number and a +two-letter \LaTeX\ length unit, such as \code{"1.5pt"} or +\code{"6cm"}. \code{color} represents a \code{Color} object +constructed from a named primary (\code{Blue()}, \code{Magenta(0.7)}, +etc.), a color specification (\code{RGB(r,g,b)}, \code{CMY(c,m,y)}, +etc.), or an operator applied to an existing \code{Color}. + + +\section{File Structure} + +An \ePiX\ input file constitutes a short \CXX\ program. When this +program is compiled and run by one of the shell scripts, it creates a +figure file suitable for inclusion in \LaTeX. + +\index{Preamble} +Like a \LaTeX\ document, an \ePiX\ file contains a \emph{preamble}, +which sets up a drawing environment, and a \emph{body}, which contains +actual figure-generating commands. The minimal file has the form +\findex{picture} +\findex{begin} +\findex{end} +\begin{verbatim} +#include "epix.h" // N.B. no semicolon +using namespace ePiX; + +int main() { + picture(P(a1,b1), P(a2,b2), "n1 [unit1] x n2 unit2"); + begin(); // end of preamble, start of body + end(); // end of body +} +\end{verbatim} +\ePiX\ commands are of four general types: drawing, attribute setting, +definitions (of data and functions), and operations on existing +objects. Except as noted below, drawing and attribute commands must +appear in the body, between \code{begin()}~and \code{end()}. Function +definitions must come in the preamble, before \code{main()}. Data +definitions may appear in the preamble or body. + + +\subsubsection*{Output Format} +\index{Output format} + +The \code{end()} command writes the output file to \code{stdout}, +using \code{eepic} macros by default. The shell scripts redirect +\code{stdout} to an appropriate disk file. + +The attribute-setting command \code{pst\_format()} causes the output +file to be written using \code{PSTricks} macros when \code{end} is +called. Similarly, \code{tikz\_format()} causes the file to be written +using \code{tikz} macros, and \code{eepic\_format()} causes the file +to be written using \code{eepic} macros. These commands may appear +anywhere in the figure body. There is no reason for a file to contain +more than one such command. + +The output format may be selected on the command line, overriding any +explicit request in the input file. Supplying \code{epix}, +\code{elaps}, or \code{flix} with one of the options \code{--pst}, +\code{--tikz}, or \code{--eepic} is tantamount to issuing a +\code{pst\_format()} (etc.)\ command just before the end of the +file. These options are listed in decreasing precedence. If more than +one is given, the ``strongest'' applies, regardless of the command +line order. + +A figure may be written directly to a specified disk file, in a format +unaffected by the command line flags above. The command +\begin{verbatim} + print_eepic("file.tex"); +\end{verbatim} +writes the figure to the named file using \code{eepic} +macros. Analogous commands exist for the formats \code{pst}~and +\code{tikz}. These commands perform an immediate action. Consequently, +the command's location in the input file is significant, and multiple +commands may appear in a single file, so long as distinct file name +arguments are provided. Applications include writing the same figure +in multiple formats, or creating successive ``snapshots'' of a lengthy +computation. + + +\section{Picture Size and Aspect Ratio} + +\index{Picture!size} +\index{Picture!offset} +The \code{picture} command specifies a figure's logical and true +sizes. In the ``minimal file'' snippet above, the \emph{canvas} is the +Cartesian rectangle \teximath{[a_1,a_2]\times[b_1,b_2]} whose corners +are given. Either pair of opposite corners is acceptable, but +confusion is less likely when the SW~and NE corners are given, in this +order. + +The true (printed) width and height are read from \code{picture}'s +third argument, a ``size \code{string}'' such as \verb+"4cm x 1in"+, +containing a number and optional \LaTeX\ length unit, an~\code{x}, +another number, and a mandatory length unit. Spaces may be used for +legibility. The mandatory length unit becomes the \LaTeX\ +\code{unitlength}. The argument \verb+"4cm x 1in"+ creates a picture +4~cm wide and 1~in high, but internally converts 4~cm to inches. +Recognized length units are \code{pt} (points, the default), \code{cm} +(centimeters), \code{in} (inches), \code{mm} (millimeters), \code{pc} +(picas), and \code{bp} (big points). +(\code{1in = 2.54cm = 72bp = 72.27pt}, \code{1pc = 12pt}.) + +The logical and true sizes may be defined separately with the commands +\findex{bounding\_box} +\findex{picture} +\findex{unitlength} +\begin{verbatim} + bounding_box(P(a1,b1), P(a2,b2)); + picture(n1, n2); + unitlength(len); // len a length string, not a double +\end{verbatim} +One way or another, the logical and true dimensions \emph{must} have +positive values when the \code{begin()} command is issued. + +\LaTeX\ treats the contents of a picture environment as a single box, +aligned by default on its lower left corner. An \code{offset} command +accepts two \code{double} arguments or a size \code{string} and shifts +the page location accordingly. The command +\code{offset("0.25 x -0.5cm")} shifts the picture right +\teximath{0.25}~cm and down \teximath{0.5}~cm. If the +\code{unitlength} is 1~cm, the command \code{offset(0.25, -0.5)} has +the same effect. + +A non-zero \code{offset} causes a picture's contents to appear in a +location where \LaTeX\ does not expect them. This can be useful in a +\LaTeX\ document, but should be avoided when compiling a stand-alone +image, since \code{dvips} may crop according to rules of its own. + + +\index{Picture!aspect ratio} +\index{Picture!bounding box} +The canvas's corners are \code{(xmin(),ymin())} and +\code{(xmax(),ymax())}, while its width and height are +\code{xsize()}~and \code{ysize()}. The canvas is a virtual, advisory +data structure; its dimensions are not directly related to the +figure's printed size, and picture elements may lie outside the +canvas. Affine scaling maps the canvas to the page when the output +file is written. +\begin{center} +\input{scaling.eepic} +\end{center} +\label{page:scaling} +The figure's aspect ratio is controlled by sizing the canvas. The +aspect ratio is ``true'' if the canvas and page rectangles are +geometrically similar, e.g., if both boxes are 1.5~times as wide as +they are tall. + + +\section{Color} +\label{section:color} + +\index{Color|(} +\ePiX\ provides a \code{Color} data type. Four models are implemented: +\code{RGB}, \code{CMY}, \code{CMYK}, and \code{Gray}. A \code{Color} +holds primary color ``channels'', each carrying an intensity between +0~(no color) and~1 (full saturation). ``No color'' means black in +\code{RGB} and \code{Gray}, white in \code{CMY(K)}. \code{RGB}, +\code{CMY}, and~\code{CMYK} colors are written to the output file as +commands in the corresponding model. \code{Gray} shades are written +in~\code{RGB}. + +Operations on red-green-blue colors are described below. Functionally, +colors are converted to~\code{RGB}, operated upon, then converted back +to the original model. Conversions are as described in Uwe Kern's +\filename{xcolor} manual~\cite{xcolor}. + + +\subsection{Constructors} + +Each color model has a ``constructor'' creating a color of specified +densities. The \code{RGB}~and \code{CMY} models have named ``primary'' +constructors; the density argument is optional and defaults to~1. +\findex{RGB} +\findex{Red} +\findex{Green} +\findex{Blue} +\findex{White} +\findex{Black} +\begin{verbatim} + // red-green-blue colors + RGB(double r=0, double g=0, double b=0); + Red(d=1); Green(d=1); Blue(d=1); + White(d=1); Black(d=1); +\end{verbatim} +\findex{CMY} +\findex{Cyan} +\findex{Magenta} +\findex{Yellow} +\findex{CMY\_White} +\findex{CMY\_Black} +\findex{CMYK} +\findex{Gray} +\begin{verbatim} + // cyan-magenta-yellow colors + CMY(double c=0, double m=0, double y=0); + Cyan(d=1); Magenta(d=1); Yellow(d=1); + CMY_White(d=1); CMY_Black(d=1); + + // gray + Gray(double d=0); // equivalent to RGB(d, d, d) +\end{verbatim} +Each \code{CMY} constructor has a corresponding \code{CMYK} function, +e.g.\ \code{CyanK()}~or \code{CMYK\_White()}. + +Though color densities lie between 0~and 1, \ePiX's primary color +constructors take arguments mod~4, viewed as elements +of~\teximath{[-2,2]}. Consider \code{Red(d)}, ``red with +density~\teximath{d}''. For integer values of~\teximath{d}, the +constructor has the following meanings: \code{Red(0)}~is black, +\code{Red(1)}~is red, \code{Red(2)}=\code{Red(-2)}~is white, and +\code{Red(-1)}~is anti-red, or cyan. For non-integer~\teximath{d}, the +constructor interpolates between the bracketing integer values, +Figure~\ref{fig:densities}. Other primary constructors work +analogously. + +\begin{figure}[hbt] + \begin{center} + \input{color_density.eepic} + \end{center} + \caption{The red primary constructor.} +\label{fig:densities} +\end{figure} + +Let \teximath{\delta:[-2,2]\to[0,1]} be the piecewise-linear function +that converts real numbers to primary color densities, +\teximath{\clip:\mathbf{R}\to[0,1]} the clipping function. The +non-primary constructor \code{RGB(r, g, b)} computes the density of +the red channel as +\teximath{\clip\bigl(\delta(r)+\delta(-g)+\delta(-b)\bigr)}; the green +and blue channel densities are computed similarly. Every color can be +created with arguments between 0~and 1, but the constructor accepts +arbitrary real arguments and returns colors varying ``continuously and +periodically''. + +\index{Color!transparency} +Colors possess an ``alpha-channel'' for transparency. Except as +supported by the output format, this feature is a stub. + + +\subsection{Color Operations} + +Colors can be scaled, inverted, blended, superposed, and filtered. In +the code below, \code{tint}~is a \code{Color}. The effect of each +operation is described in the \code{rgb} model; the visual result is +the same in all models. +\findex{Color.invert} +\findex{Color.blend} +\findex{Color.superpose} +\findex{Color.alpha} +\findex{Color.filter} +\begin{verbatim} + tint *= double c; // multiply channels by c, rebuild + tint.invert(); // (r, g, b) -> (1-r, 1-g, 1-b) + tint.blend(Color col, double t); // (1-t)*tint + t*col + tint.superpose(col); // add channels, then clip to [0,1] + tint.alpha(double d); // set alpha channel to clip(d) + + tint.filter(col); // return min density in each channel +\end{verbatim} +Except for \code{filter}, these operators modify their object. +\code{filter} simulates the effect of viewing \code{col} +through a transparent sheet of \code{tint}, and returns a new +\code{Color} object having the same model as \code{tint} without +modifying \code{tint} itself. + + +\section{Scene Attributes} + +Objects in a scene sit in 3-dimensional space. A \emph{camera} +maps objects to the \emph{active screen}. The active \code{screen} +may, in turn crop its contents. Each drawing command creates an +object, ``photographs'' it, and adds the image to the active +\code{screen}. This section describes the \code{Camera} and +\code{screen} classes and a few associated concepts. + + +\subsection{Angular Mode} +\index{Angle units} + +By default, angles are measured in \code{radian}s. Two other angular +modes are available: \code{degrees}~and \code{revolutions}. The +angular mode is set with a named command, \code{radians()}, +\code{degrees()}, or \code{revolutions()}. The current angular mode +affects all trigonometric functions and operations. + + +\subsection{The Camera} +\index{Camera|(emph} +\index{Screen|(} + +Three-dimensional scenes are drawn on flat paper by applying a +mathematical transformation. By default, \ePiX\ uses \emph{point +projection}, the technique used by art students when they trace on a +window with grease pencil, Figure~\ref{fig:camera}. + +\begin{figure}[hbt] + \begin{center} + \input{camera.eepic} + \end{center} + \vspace*{-0.25in} + \caption{Point projection.} + \label{fig:camera} +\end{figure} + +\index{Camera!viewpoint} +\index{Viewpoint} +\ePiX\ depicts a Cartesian world by projecting mathematically to a +screen plane, then affinely scaling to a printed page. The camera, +which maps the world to the screen, consists of a \emph{body} (data +that determines the position and orientation of the camera), a +\emph{lens} (the actual mapping to the screen plane), and a +\emph{filter} (a color through which the scene is viewed). + + +\subsubsection*{Body} + +The camera's spatial orientation is described by a triple of mutually +perpendicular unit vectors. In memory of happy days at the beach, +these vectors are called \emph{sea}, \emph{sky}, and~\emph{eye}. The +screen plane is parallel to the sea-sky plane; the sea vector points +horizontally to the right, sky points vertically upward. The eye is +their cross product, which points directly at the viewer. + +The sea-sky-eye basis is located at the \emph{viewpoint}, the camera's +spatial location. The \emph{target}, the origin of the screen plane, +lies on the line through the viewpoint in the direction opposite the +eye vector. The distance from the viewpoint to the target is the +\emph{range}. The \emph{camera sphere} is centered at the viewpoint +and passes through the target. The orientation, viewpoint, target, +and range completely (and redundantly) determine the camera's +geometric situation in the world. + + +\subsubsection*{The Lens} +\index{Camera!lens} + +A \emph{lens} maps the world to the screen. \ePiX\ comes with four +lenses: \emph{shadow} (the default), \emph{orthogonal}, +\emph{fisheye}, and \emph{bubble}. Each lens simulates the appearance +of world objects as seen by an observer at the viewpoint. The shadow +lens is point projection from the viewpoint to the screen plane. The +orthogonal lens projects from infinite distance. Each of the other +lenses performs radial projection to the camera sphere, then maps the +sphere to the screen plane; the fisheye lens does orthogonal +projection (so the entire image lies inside the disk centered at the +target whose radius is the range) while the bubble lens does +stereographic projection from the target's antipode. +\index{Screen|)} + + +\index{Camera!manipulation|(} +An input file normally uses a single camera, so a global object named +\code{camera} is defined automatically. At the start of a figure, the +\code{camera} looks down on the \teximath{(x_1,x_2)}-plane from a +distant point on the \teximath{x_3}-axis. The resulting view, +essentially projection along the axis, is suitable for 2-dimensional +figures. + +The \code{camera} is manipulated similarly to a real camera: +\findex{Camera.at} +\findex{Camera.look\_at} +\findex{Camera.range} +\findex{Camera.focus} +\findex{Camera.tilt} +\findex{Camera.pan} +\findex{Camera.roll} +\findex{Camera.clip\_range} +\begin{verbatim} + camera.at(P posn); // set viewpoint to posn + camera.look_at(P targ); // set target to targ + camera.range(double dist); // fix target, move viewpoint + camera.focus(double dist); // fix viewpoint, move target + camera.tilt(double angle); // rotate about the sea axis + camera.pan(double angle); // rotate about the sky axis + camera.roll(double angle); // rotate about the eye axis + camera.clip_range(dist); // cull scenery closer than dist +\end{verbatim} +Explicitly setting the viewpoint or target makes the sky vector +parallel to the projection of the \teximath{x_3}~axis when possible; +otherwise the \teximath{x_2}-axis is used. Setting the range or focus +moves the \code{camera} parallel along the eye line. Each command +re-sizes the image; note that increasing the focus \emph{enlarges} the +image. The three rotation operations fix the viewpoint, but only roll +fixes the target. + + +\subsubsection*{Filtering and Color Separation} +\index{Color!separation} +\index{Camera!color separation} + +The \code{camera} has a \emph{filter} through which all scene +\code{Color}s pass. For uniformity, the filter should only be set at +the start of the file body, before any visible elements have been +placed in the scene. The filter has two primary uses---model +conversion and color separation---but can also be used for special +effects. + +There is a \code{Neutral} color, for which filtering has no effect at +all. The \code{camera}'s default filter is \code{Neutral}. In +addition, each color model has a \emph{neutral} representative, +\code{RGB\_Neutral}, etc. Passing \code{Color}s through a neutral +filter preserves their appearance but converts them to the neutral +\code{Color}'s model. + +Filtering can be used to ``split'' a \code{Color} into primary +constituents. For \code{RGB} channels, the primaries themselves are +suitable filters. For \code{CMYK} channels, there are special +\emph{process} filters, named \verb+C_Process+, etc. +\begin{verbatim} + camera.filter(CMY_Neutral()); // convert all colors to CMY + camera.filter(Gray_Neutral()); // black and white photography + camera.filter(Green()); // the green channel + camera.filter(M_Process()); // the magenta channel + camera.filter(Red(1.4)); // la vie en rose? +\end{verbatim} +\index{Camera!manipulation of|)} +\index{Camera|)} + + +\subsection{Clipping} + +\index{Clipping|(} + +Two operations handle elements lying far from the target. +\emph{Cropping} culls elements based on their screen location, and is +described later. \emph{Clipping} removes objects whose spatial +location lies outside the ``clip region''. + +Initially, the clip region is a very large box centered at the +origin. Commands are provided to resize this box, keeping the faces +parallel to coordinate planes. +\findex{clip\_box} +\findex{clip\_to} +\begin{verbatim} + clip_box(P pt1, P pt2); // opposite corners + clip_box(P pt); // opposite corners pt and -pt + clip_to (P pt); // pt and P(0,0,0) + clip_box(); // very large box +\end{verbatim} +Additional ``clippers'' may be added manually. Individual clipping +planes are specified by a point and inward-pointing normal vector. +Parallel planes cutting a ``slice'' or ``slab'' are described by a +location, direction, and a distance. The location lies halfway between +the clipping planes, and the planes' normals point toward the location. +\findex{clip\_face} +\findex{clip\_slice} +\findex{clip\_restore} +\begin{verbatim} + clip_face(P loc, P perp); // perp points inward + clip_slice(loc, perp); // very close parallel planes + clip_slice(loc, perp, dist); // planes separated by dist + clip_restore(); // remove manually-added clip planes +\end{verbatim} +Like \code{clip\_restore}, the \code{clip\_box} and \code{clip\_to} +commands remove all user-specified half spaces. +\index{Clipping|)} + + +\subsection{Screens and Page Layout} +\index{Screen|(} +\index{Screen!active} +\index{Layout} + +By default, drawing occurs in the Cartesian coordinate system of the +\code{canvas}. However, insets and subfigures are most naturally +composed in ``local'' coordinates, then placed into their final +location as a unit, a process called \emph{layout}. \ePiX\ implements +layout with the \code{screen} class. + + +\subsubsection*{Screens} +\index{Bounding box} + +A \code{screen} is a Cartesian plane containing a distinguished +coordinate rectangle, its \emph{bounding box}. The \code{canvas} of a +figure is a \code{screen}, as is the internal representation of the +printed page. At any point of a file body, some \code{screen} is +\emph{active}, or ``open for drawing''. A new \code{screen} is created +from a pair of opposite corners, but is not used until explicitly +activated. +\findex{activate} +\findex{deactivate} +\begin{verbatim} + screen subfig(P(a1,b1), P(a2,b2)); // [a1, a2] x [b1, b2] + activate(subfig); // open subfig for drawing + // commands to draw in subfig + deactivate(subfig); // re-activate the previous screen +\end{verbatim} + +The \code{canvas} is automatically drawn at the \code{end} of the +input file. The contents of other \code{screen}s must be incorporated +into the \code{canvas} explicitly with an \code{import}~or +\code{inset} command. \code{import} affinely scales the bounding box +of the ``child'' \code{screen} to the \code{canvas}. \code{inset} +specifies corners in the ``parent'' where the child is +placed. +\findex{import} +\findex{inset} +\begin{verbatim} + import(); // active screen to canvas + import(subfig); // subfig to canvas + inset(P sw, P ne); // active screen to specified rectangle + inset(subfig, sw, ne); // subfig to specified rectangle + inset(subfig); // inset to subfig's corners +\end{verbatim} + + +\subsubsection*{Extracting} + +The portion of a \code{screen} enclosed by a specified rectangle can +be \emph{extracted}. Each of the commands +\findex{extract} +\findex{canvas} +\begin{verbatim} + subfig.extract(P sw, P ne); + canvas().extract(P sw, P ne); +\end{verbatim} +returns the \code{screen} having stated corners and containing part of +\code{subfig} or the \code{canvas}, respectively. Elliptical and +diamond-shaped portions of a \code{screen} may be extracted. The +contents occupy the ellipse or diamond inscribed in the given +rectangle. +\findex{extract\_diamond} +\findex{extract\_ellipse} +\begin{verbatim} + subfig.extract_ellipse(sw, ne); + canvas().extract_diamond(sw, ne); +\end{verbatim} +The \code{screen} returned by \code{extract} (or its variants) may be +used just like a manually-constructed \code{screen}, for example to +construct a magnified inset. + + +\subsubsection*{True-Size Drawing} +\label{truesize} + +On occasion, it is necessary to draw at known page size, independently +of the unit length. For 2-dimensional drawing in the +\teximath{(x_1,x_2)}-plane with the \code{camera} in its default +location, the coordinates (horizontal, vertical, or both) of a +\code{screen} may be interpreted as true~pt offsets relative to a +specified point rather than as Cartesian coordinates. +\findex{inlay} +\findex{inlay\_horizontal} +\findex{inlay\_vertical} +\begin{verbatim} + inlay(subfig, P loc); + inlay_horizontal(subfig, loc); + inlay_vertical(subfig, loc); +\end{verbatim} +Each command maps the origin of \code{subfig} to the specified +location in the active \code{screen}. The first performs affine +scaling so that one Cartesian unit in \code{subfig} maps to one +true~pt on the page. The second and third commands perform this +scaling only in the named direction. + +\findex{pt\_to\_screen} +The \code{inlay} functions are suitable only for 2-dimensional +effects. For 3-dimensional true-size drawing, the function +\code{pt\_to\_screen} converts a true length of 1~pt into Cartesian +coordinates in the active \code{screen}. For example, the command +\code{line(P(0,0), P(pt\_to\_screen(12),0))} draws a line segment +12~pt long with its left endpoint at the Cartesian origin. True size +drawing is unusual in an input file, but has definite uses in library +code; \ePiX's right angle marker is a typical application. + +Either type of true-size drawing works as described when drawing in +the \code{canvas}, and \emph{only} when drawing in a \code{screen} +imported to the \code{canvas} at ``true Cartesian'' size (one +\code{screen} unit maps to one Cartesian unit in the \code{canvas}). +In other situations, the true size coordinate(s) will be scaled by +additional affine transformation(s). + + +\subsubsection*{Cropping and Decorations} + +\index{Cropping} +A \code{screen} has a \emph{crop mask}: rectangular (default), +elliptical, or diamond-shaped. If cropping is switched on in the +active \code{screen}, added elements are cropped to the crop mask. +For example, cropping by the default crop mask in the \code{canvas} +ensures the figure lies inside the printed region allocated by +\LaTeX. + +The \code{crop} commands below affect the active \code{screen} +only. Cropping is not a ``global'' attribute, but must be set or unset +explicitly for each \code{screen}. By default, cropping is switched +off. +\findex{crop} +\findex{crop\_ellipse} +\findex{crop\_diamond} +\findex{set\_crop} +\begin{verbatim} + set_crop(); // activate cropping + set_crop(false); // deactivate cropping + crop_diamond(); // <>-shaped mask, set crop state + crop_ellipse(); // etc... + crop(); // crop active screen's contents +\end{verbatim} +Normally the crop mask is inscribed in the \code{screen}'s bounding +box. The commands \code{crop\_diamond} and \code{crop\_ellipse} also +accept a pair of \code{P}~arguments, which are treated as corners of +the crop box. + +The active \code{screen} may be decorated with a \code{border} +(outline of specified color and line width) and \code{backing} (solid +fill color). The crop mask determines the shape of the \code{border} +and \code{backing}. +\findex{border} +\findex{backing} +\begin{verbatim} + border(color, len); + backing(color); +\end{verbatim} +Identically-named member functions can be applied to an arbitrary +\code{screen} whether or not it is active: +\begin{verbatim} + scr.crop_rectangle().backing(Blue(1.8)); + canvas().crop(); +\end{verbatim} + + +\subsubsection*{Affine Maps} +\index{Affine map} + +A \emph{plane affine map} has the form \teximath{T(x) = Ax+b} for some +invertible \teximath{2\times2} matrix~\teximath{A} and a constant +vector~\teximath{b}. \ePiX's \code{affine} class allows affine maps to +be built and applied to \code{screen}s' contents. + +An affine map is uniquely determined by the images of three +non-collinear points. The constructor returns the affine map sending +the points \teximath{(1,0)}, \teximath{(0,1)}, and~\teximath{(0,0)} to +\code{pt1}, \code{pt2}, and~\code{pt0}, respectively. +\findex{affine} +\begin{verbatim} + affine af(P pt1, P pt2, P pt0=P(0,0)); +\end{verbatim} +To emphasize, the arguments are locations, not displacements, and the +image of the origin comes last. There is also a \code{void} +constructor (taking no arguments) which returns the identity map. + +To facilitate construction of affine maps, an existing \code{affine} +may be post-composed with a variety of ``elementary'' affine +transformations. In the commands below, \code{th} is an angle (in +current units), \code{sc} is a non-zero \code{double}, and \code{ctr} +is a point fixed by the composing transformation. In each command, +\code{ctr} defaults to \teximath{(0,0)}. +\findex{shift} +\findex{rotate} +\findex{reflect} +\findex{h\_scale} +\findex{v\_scale} +\findex{scale} +\findex{h\_shear} +\findex{v\_shear} +\findex{postcomp} +\begin{verbatim} + affine af; // the identity map + af.shift(P arg); // translate by arg + af.rotate(th, [ctr]); // counterclockwise rotation about ctr + af.reflect(th, [ctr]); // reflect across line through ctr + + af.h_scale(sc, [ctr]); // horizontal scaling + af.v_scale(sc, [ctr]); // vertical scaling + af.scale(sc, [ctr]); // dilatation + + af.h_shear(sc, [ctr]); // shear preserving horizontals + af.v_shear(sc, [ctr]); // shear preserving verticals + + af.invert(); // the inverse + af.postcomp(affine f); // post-compose with f + af(f); // pre-compose, af not modified +\end{verbatim} +A non-invertible \code{affine} can be created \emph{only} by shearing +or scaling with an extremely large or extremely small argument, or by +supplying three collinear points to the constructor. Calling +\code{invert} on a non-invertible map merely issues a warning and +performs no action. + +An \code{affine} may be applied to a \code{screen}'s current contents. +The \code{screen} class has eight member functions (\code{shift} +through \code{shear}) with syntax identical to the affine map +functions. In addition, an arbitrary \code{affine} may be applied to a +\code{screen}: +\findex{apply} +\begin{verbatim} + scr.shift(arg); // shift scr's contents by arg; etc. + scr.apply(f); // apply f to scr's contents +\end{verbatim} +To apply a composition of several maps to a \code{screen}, it's best +to build an \code{affine} map by composition, then \code{apply} the +map. Composing \code{affine}s is cheap; \code{apply}ing an +\code{affine} is costly in proportion to the number of elements in the +\code{screen}. + +Applying an \code{affine} to a \code{screen} has no effect on the +bounding box, \code{border}, or \code{backing}, and may move elements +outside the bounding box even if cropping is active. To ensure a +\code{screen}'s contents lie inside the bounding box, \code{crop} the +\code{screen} \emph{after} \code{apply}ing the \code{affine}(s). + +The sample file \filename{inverse.xp} uses \code{affine} maps to +depict branches of inverse functions in one variable, +\filename{symmetry.xp} depicts the permutation group~\teximath{S_3} +by its action on a regular hexagon. +\index{Screen|)} + + +\section{Drawing Attributes} + +\ePiX\ maintains drawing states for filled regions, paths, and text +objects. + + +\subsection{Filled Regions} + +\index{Filling} +\index{Path|(} +\index{Path!filled} +Filling is either on or off. When filling is active, closed paths are +filled with the current \emph{fill color}. +\findex{fill} +\findex{nofill} +\begin{verbatim} + fill(); // turn filling on + fill(color); // turn filling on, specify color + nofill(); // turn filling off, same as fill(false); +\end{verbatim} + + +\subsection{Paths} + +Paths and borders of filled regions are drawn with two \emph{pen}s, +each described by color and line width. The \emph{line pen} draws +all path-like objects. The \emph{base pen} does nothing unless it is +wider then the line pen, in which case it draws an ``underlayer'' or +``border'' on the line pen. +\findex{pen} +\begin{verbatim} + pen(len); // set line pen width + pen(color); // set line color, keep width + pen(color, len); // set color and width +\end{verbatim} +As usual, \code{len} may be either a length string or a \code{double}, +interpreted as a width in~\code{pt}. There are \code{base} functions +with the same signatures and analogous meanings for the base pen. + +The line width can be set with named declarations; the optional +argument sets the line color: +\findex{plain} +\findex{bold} +\findex{bbold} +\begin{verbatim} + plain([color]); // 0.4pt + bold([color]); // 0.8pt + bbold([color]); // 1.6pt +\end{verbatim} + + +\subsubsection*{Path Style} + +\index{Path!style} +By default, path-like objects are drawn with solid lines. Dashed, +dotted, and free-form path style patterns are also available. (The +\code{base} underlayer is always solid.) The page length of a pattern +defaults to 12~pt, but can be set. +\findex{line\_style} +\findex{dash\_size} +\begin{verbatim} + line_style(string); + dash_size(len=12); +\end{verbatim} +The path style is set with a WYSIWYG string of dashes, spaces, and +periods, representing a pattern of dashes, gaps, and dots. In the +sample styles below, the repeating units have the same page size, +12~pt. +\begin{center} + \input{pathstyle.eepic} +\end{center} +For brevity and uniformity, named commands are provided. +\findex{solid} +\findex{dashed} +\findex{dotted} +\begin{verbatim} + solid(); "-" dashed(); "- -" dotted(); " . " +\end{verbatim} +A sequence of \teximath{n}~dashes, spaces, and dots corresponds to a +dash/dot pattern in an interval divided into \teximath{n}~subintervals +of equal length. If the \teximath{i}th character is a dash or space, +the \teximath{i}th~subinterval is drawn solid or empty, +respectively. If the \teximath{i}th~character is a period, a dot is +placed at the midpoint of the \teximath{i}th~subinterval. + +This pattern is applied to a path-like object as follows. The page +length of each edge is divided by the current \code{dash\_size} and +the ceiling (next largest integer) taken. This many copies of the +current path style are scaled onto the edge. The first and last +characters are adjacent in repeated units. + +There are three inequivalent ways to adjust the dash length/dot +spacing in a non-line path: Change the \code{dash\_length}, create a +path with a different number of points, or use a longer, repetitive +pattern. For best results, the style string should not be longer than +about a dozen characters. + +If you need several dashed/dotted line styles in multiple figures, +it's best to define a custom header instead of hard-coding line +styles. See Section~\ref{section:extensions} for guidance. +\index{Path|)} + + +\subsection{Text Objects} + +\index{Labels|(emph} +\index{Labels!alignment} + +Two types of textual element may appear in a file: \emph{labels} (text +boxes) and \emph{markers} (\LaTeX\ symbols). A marker occupies a box +of zero size, and is placed at a specified Cartesian location. A label +has typographical size, and is usually offset from its Cartesian +location. For placement, an \emph{alignment point} is attached to each +label, and Cartesian coordinates position the alignment point. + +\subsubsection*{Labels} + +A label is printed as a \LaTeX\ box. By default, the alignment point +is its reference point, the intersection of the left edge and the +baseline, which is used by \LaTeX\ to position the box on the +page:\input{basepoint.eepic} + +\index{Labels!alignment|(} +The alignment point may be \emph{offset} manually by a specified +number of \code{pt}. Additionally, a label's location with respect to +the alignment point can be chosen with an optional \LaTeX-style +alignment option. This scheme allows labels to be placed easily where +they will not overlap other parts of the figure, and ensures labels +stay properly positioned when the size or aspect ratio of a figure +changes. +\findex{label} +\begin{verbatim} + label(P posn, P offset, string msg, [align]); + label(posn, msg); +\end{verbatim} +The first two components of the \code{offset} argument are numbers +of~\code{pt} to shift the alignment point right and up. The optional +\code{align} argument may be one---or an appropriate pair---of +\code{t}, \code{b}, \code{r}, or~\code{l} (top, bottom, right, left), +or~\code{c} (center). These alignment options specify the position of +the label \emph{relative to the Cartesian location}~\code{posn}, +namely they work \emph{opposite} to the way they work in \LaTeX. +\begin{center} + \input{alignment_lr.eepic}\qquad + \input{alignment.eepic} +\end{center} +\index{Labels!alignment|)} + +The \code{msg} argument is usually a snippet of \LaTeX\ code enclosed +in double quotes. \CXX~treats ``\verb+\+'' as an escape character, so +a double backslash is needed in the source to get a single backslash +in the output. For example, +\begin{verbatim} + label(P(0,0), P(2,-1), "$\\rho = \\sin\\theta$", br); +\end{verbatim} +positions an alignment point \code{2pt}~right and \code{1pt}~below the +(Cartesian) origin, and typesets the equation +\teximath{\rho=\sin\theta} below and to the right. + +\index{Labels!rotated} +\index{Angle units} +Labels can be rotated; the (counterclockwise) angle is set in current +angle units with the command \code{label\_angle(theta)}. For example, +a rotation angle of~90 degrees prints labels along a vertical +axis. Though label rotation has legitimate uses, it can make labels +more difficult to read, defeating their purpose. Do not use rotated +labels merely because they are available. As a practical matter, if an +output file contains rotated labels, the enclosing document must use +the \code{rotating} package. \code{elaps} automatically loads this +package. + +\index{Affine map!action on labels} +An \code{affine} behaves moderately intelligently when acting on a +marker or label. The mapping is applied to the label's location, and +the ``linear part'' is used to adjust the offset and label angle. No +attempt is made to treat alignment. For best results, if a +\code{screen} will have an \code{affine} applied to it, label +positions should be fine-tuned only with offsets, not alignment +arguments. In all situations, the font itself is unchanged; no +attempt is made to print sheared, scaled, or reflected text. The +sample file \filename{inverse.xp} illustrates the effect of affine +maps on labels. + + +\subsubsection*{Fonts and Type Size} + +\index{Fonts} +\index{Labels!fonts in} +By default, the font in an \ePiX\ figure is that of the enclosing +document. The font size and face are changed with +``declaration-style'' commands such as +\findex{font\_size} +\findex{font\_face} +\begin{verbatim} +font_size("Large"); +font_face("sc"); +\end{verbatim} +The argument of \verb+font_size+ is a valid \LaTeX\ size. If no +argument is given, \code{normalsize} is understood. \verb+font_face+ +accepts a two-letter string, appended to the string ``\code{text}'' to +give a \LaTeX\ font declaration command (``\code{textsc}'' above). +Finer-grained control is accomplished by placing \LaTeX\ commands +into the label text. + + +\subsubsection*{Label Attributes and Masked Labels} + +Each label command has a corresponding ``mask'' version +(\code{masklabel}) that draws an opaque rectangle under the label +text. The mask size exceeds the label's size by an amount of +\emph{padding}, and the mask is itself surrounded by a rectangular +\emph{border}, of specified color and width. +\findex{label\_color} +\findex{label\_mask} +\findex{label\_pad} +\findex{label\_border} +\findex{no\_label\_border} +\begin{verbatim} + label_color(color); // set label text color + label_mask(color=White()); // set mask color + label_pad(string len); + + label_border(color, [len]); // set color (and line width) + label_border(len); // set line width only + no_label_border(); // turn off label borders +\end{verbatim} + + +\subsubsection*{Markers} + +\index{Marker types|(} +\ePiX's marker types, listed in Table~\ref{table:marker}, are obtained +with the command \verb+marker(P pt, <MARKER TYPE>);+ Several +``dot-like'' marker types are available by name: \input{dots.eepic} +\findex{spot} +\findex{dot} +\findex{ddot} +\findex{box} +\findex{bbox} +\findex{ring} +\findex{circ} +\begin{verbatim} + spot(P pt); dot(P pt); ddot(P pt); + --- box(P pt); bbox(P pt); + ring(P pt); circ(P pt); --- +\end{verbatim} +A \code{circ} is filled with the current \code{mask\_color}, and a +\code{ring} is ``hollow''. Each dot-like marker can also be called +with label syntax, generating a labeled marker with one command. +\begin{verbatim} + dot(P posn, offset=P(0,0), msg="", align=none); // etc. +\end{verbatim} + +\findex{dot\_size} +By default, \code{spot}~and \code{ring} are 4~pt in diameter; +\code{dot}, \code{box}, and~\code{circ} are 3~pt in diameter; +\code{ddot}~and \code{bbox} are 2~pt in diameter. At arbitrary +diameter, a \code{spot} is \teximath{4/3}~the diameter of a~\code{dot} +and a~\code{ddot} is \teximath{2/3}~the diameter. The command +\code{dot\_size(diam=3)} sets the diameter of a \code{dot}, and hence +the size of all dot-like markers. + +\begin{table}[tb] + \begin{center} + \input{marker.eepic} + \end{center} + \caption{\ePiX's \code{marker} types.} + \label{table:marker} +\end{table} +\index{Marker types|)} + + + +\subsubsection*{Reminders} + +When constructing and placing a label, +\begin{itemize} +\item Offsets are specified in \code{pt} (true length), not Cartesian + units: A label's location relative to its alignment point should not + depend on the logical or printed size of the figure. + +\item The label text is enclosed in double quotes (the single + character~\code{"}), and contains the \LaTeX\ code to generate the + label. Backslashes are doubled. + \index{Labels!backslash in} + \index{Labels!in double quotes} +\end{itemize} +\index{Labels|)} + + +\subsection{Color Declarations} + +Old-style color declarations set the fill color, line color, and +text color. +\findex{rgb} +\findex{cmyk} +\begin{verbatim} + rgb(r, g, b); cmyk(c, m, y, k); + rgb(P); cmyk(P); // for function-controlled colors + red(d); // similarly for other primaries +\end{verbatim} +\index{Color|)} + + +\section{Creating and Drawing Objects} + +Scene elements include geometric objects, coordinate grids, axis +labels, and function plots. A few commands create an object (a point, +line segment, circle, sphere, or plane) that can be used in subsequent +computations, but most drawing commands automatically create, draw, +and discard objects. + + +\subsection{Geometric Data Structures} + +\index{Point|(} +The simplest object in the world, and by far the most common named +data structure, is~\code{P}, an ordered triple of real numbers +(double-precision floats). The function~\code{P(x1,x2,x3)} creates the +point~\teximath{(x_1,x_2,x_3)}. If only two arguments are provided, +\teximath{x_3=0} by default. This convention allows \ePiX\ to treat +2-~and 3-dimensional figures uniformly. The standard basis is +available: \code{E\_1=P(1,0,0)}, etc. + +Depending on context, a \code{P} may represent either a +\emph{location} (point) or a \emph{displacement} (vector). Almost all +\ePiX\ functions treat a~\code{P} as a point. However, algebraic +operators and commands that plot vector fields treat \code{P} +arguments as displacements. + +Polar, cylindrical, and spherical coordinate \code{P}~constructors are +sensitive to the current angular mode. +\index{Angular mode} +\findex{P} +\findex{polar} +\findex{cis} +\findex{cyl} +\findex{sph} +\begin{verbatim} + P pt=polar(r,t); // (r*Cos(t), r*Sin(t), 0) + P pt=cis(t); // (Cos(t), Sin(t), 0) = polar(1, t) + P pt=cyl(r,t,z); // (r*Cos(t), r*Sin(t), z) + P pt=sph(r,t,phi); // polar(r,t)*Cos(phi) + (0,0,r*Sin(phi)) +\end{verbatim} + +Algebraic operations---addition/subtraction, scalar multiplication; +scalar, cross, and componentwise products; orthogonalization---can +be performed on~\code{P}s. In compound expressions, the binary +operators below should be enclosed in parentheses, and scalars must be +collected at left, \code{P}s at right. +\findex{P.x1} +\findex{P.x2} +\findex{P.x3} +\findex{J} +\begin{verbatim} + double u=pt.x1(); // first coordinate of pt, etc. + P(a,b,c)|P(x,y,z); // scalar product, ax+by+cz + P(a,b,c)&P(x,y,z); // componentwise product (ax, by, cz) + P(a,b,c)*P(x,y,z); // cross product (bz-cy, cx-az, ay-bx) + J(p); // quarter turn about the x3-axis + p%q; // orthogonalization, p (mod q) +\end{verbatim} +Explicitly, \code{p\%q}~is the unique vector \code{p+k*q} +perpendicular to~\code{q}. + +\code{P}~operations express mathematical relationships, and therefore +imbue a figure with logical structure, making the input file easier to +read, modify, and maintain. Commonly, a file preamble will define a +few named points with hard-coded coordinates, then define additional +points of interest using \code{P}~operators. +\index{Point|)} + + +\subsubsection*{Other Geometric Classes} + +In addition to~\code{P}, objects of type \code{Circle}, \code{Plane}, +\code{Segment}, and \code{Sphere} can be used for Euclidean geometry +constructions. Simple affine operations are supplied for each type, as +is a \code{draw()} function, which represents the object as a path in +the screen. +\findex{shift} +\findex{move\_to} +\findex{scale} +\findex{draw} +\begin{verbatim} + obj.shift(P arg); // translate by arg + obj.move_to(P arg); // move center to arg + obj.scale(double c); // scale about center by c + obj.draw(); +\end{verbatim} +A \code{Segment}'s ``center'' is its midpoint. A \code{Plane} has no +center; \code{move\_to} translates the \code{Plane} to pass through +\code{arg}, and \code{scale} has no effect. + +\index{Circle} +A \code{Circle} data structure consists of a center, radius, and a +perpendicular unit vector. Three constructors are provided: +\findex{Circle} +\begin{verbatim} + Circle(center=P(0,0,0), double rad=1, normal=E_3); + Circle(P center, P point); + Circle(P p1, P p2, P p3); +\end{verbatim} +The second constructor creates the \code{Circle} parallel to the +\teximath{(x_1,x_2)}~plane, with given center, and radius equal to the distance +between the arguments. (A warning is printed if the second argument +does not lie on the circle, namely, if the arguments do not lie in a +plane parallel to the \teximath{(x_1,x_2)}~plane.) The third returns the +\code{Circle} passing through the given points; the points must not be +collinear. + +The data defining a \code{Circle} are recovered with member functions +named \code{center()}, \code{radius()}, and \code{perp()}. + +\index{Plane} +\findex{Plane} +A \code{Plane} is specified by a point and normal vector, or by three +non-collinear points. The \code{draw()} function clips the plane and +draws the resulting polygon. Unless the clip box has been set +manually, the clipped polygon's vertices will have large coordinates. + +\index{Segment} +\findex{Segment} +A \code{Segment} is constructed from its endpoints. The member +function \code{midpoint()} returns the center. + +\index{Sphere} +\findex{Sphere} +A \code{Sphere} is specified by a point and a radius---by default the +origin and unity, or by the center and a point on the sphere. Member +functions \code{center()}~and \code{radius()} return the defining +data. Capabilities specific to geography and spherical geometry are +described below, pp.~\pageref{non-eucl}ff. + +The \code{draw()} function of a \code{Sphere} draws the horizon +visible from the current viewpoint. While this horizon is a circle in +object space, its image in the screen is generally an ellipse. +Antipodal points are not generally mapped to points symmetrically +placed with respect to the center of this ellipse. These effects are +most pronounced when the viewpoint is close to the \code{Sphere} and +the center is not close to the \code{target}. + + +\subsubsection*{Intersection} + +\index{Intersection} + +To facilitate geometric computation, \ePiX's \code{Circle}, +\code{Plane}, \code{Segment}, and \code{Sphere} classes can be +intersected with the \code{*}~operator. +\texicomment +Table~\ref{table:intersect} +lists the return types for each pair of arguments. Intersection is +commutative, so only the top half of the table is shown. For purposes +of intersection, a \code{Segment} is extended into a line. +The sample file \filename{pascal.xp} gives typical applications of +objects and intersection. +\findex{intersection} +\begin{table}[hbt] +\begin{center} + \begin{tabular}{c|cccc} + \code{*} & + \code{Segment} & \code{Circle} & \code{Plane} & \code{Sphere} \\ + \hline + \code{Segment} & \code{P} & \code{Segment} & \code{P} & \code{Segment} \\ + \code{Circle} & & \code{Segment} & \code{Segment} & \code{Segment} \\ + \code{Plane} & & & \code{Segment} & \code{Circle} \\ + \code{Sphere} & & & & \code{Circle} + \end{tabular} + \caption{Object intersection types.} + \label{table:intersect} +\end{center} +\end{table} +\texicommentend + +A \code{Circle} has a center, radius, and unit normal; a \code{Plane} +has a distinguished point and unit normal; a \code{Segment} has two +endpoints; a \code{Sphere} has a center and radius. An object is +\emph{malformed} if these conditions are not met. The constructors +return well-formed objects with two exceptions: \code{Circle} and +\code{Plane} create malformed objects if called with three collinear +points. The operator~\code{*} returns a malformed object if either +argument is malformed, or if the operands are disjoint, tangent, or +coincident. Malformedness is benign: Calling \code{draw()} on a +malformed object does nothing. + + +\subsubsection*{Orthonormal Frames} + +A \code{frame} comprises three mutually perpendicular unit +vectors. The constructor takes three vectors. The \code{frame}'s third +vector~\teximath{e_3} is positively proportional to~\code{v3}, the +second vector~\teximath{e_2} is positively proportional to +\code{v2\%v3}, and the first is the cross product, +\teximath{e_1=e_2\times e_3}. Thus, a \code{frame} is right-handed, +and does not depend on~\code{v1}. + +The elements of a \code{frame} are named \code{sea}, \code{sky}, and +\code{eye}, just as for the \code{camera}. A \code{frame} can be +rotated through an arbitrary angle about any of its elements. +\findex{frame} +\begin{verbatim} + frame(); // the standard basis {E_1, E_2, E_3} + frame fr(v1, v2, v3); // orthonormalize {v1, v2, v3} + fr.sea(); // the first element of fr, etc. + fr.rot1(theta); // rotate fr through theta about sea, etc. +\end{verbatim} + + +\subsection{Path-Like Elements} + +Basic path-like objects are drawn with named commands. Arguments of +polygon commands are endpoints/vertices. Except for \code{line}~and +\code{Line}, the following are subject to filling. +\findex{line} +\findex{Line} +\findex{triangle} +\findex{rect} +\findex{quad} +\findex{circle} +\begin{verbatim} + line(P p1, P p2, [double expand]); + Line(p1, p2); // draw line through p1, p2 (crop required) + triangle(P p1, P p2, P p3); + rect(P p1, P p2); + quad(P p1, P p2, P p3, P p4); // quadrilateral + circle(ctr=P(0,0,0), rad=1, normal=E_3); + circle(ctr, pt); + circle(pt1, pt2, pt3); +\end{verbatim} +The optional \code{line} argument is an expansion parameter: +\code{line(p1,p2,t);} draws a segment centered at the midpoint of +\code{p1}~and \code{p2}, with length scaled +by~\teximath{2^{t/100}}. (Setting \teximath{t=100} doubles the length, +while \teximath{t=-100} halves the length.) The arguments of +\code{rect()} must lie in a plane parallel to a coordinate plane. The +arguments to \code{circle} commands are the same as for \code{Circle} +constructors. + +Quadratic and cubic splines are described by their control points. A +list of~\code{P} is drawn as a ``natural'' spline (the \teximath{C^2} +piecewise cubic curve with vanishing second derivatives at the +endpoints); the number of points per cubic segment must be specified. +Circular and elliptical arcs are given by center, a basis, angular +range, and an optional number of intervals. +\findex{spline} +\findex{arc} +\findex{ellipse} +\begin{verbatim} + spline(P p1, P p2, P p3, [int n]); // quadratic + spline(P p1, P p2, P p3, P p4, [int n]); // cubic + spline(vector<P>, int n); // natural spline + + arc(P ctr, rad, t_min, t_max); // parallel to (x1,x2)-plane + ellipse(P ctr, P v1, P v2); // in plane spanned by v1, v2 + ellipse(P ctr, P v1, P v2, t_min, t_max, [int n]); +\end{verbatim} +\texicomment +Mathematically, these commands draw parametric paths +\begin{align*} + \text{Spline:}\quad&(1-t)^2 p_1 + 2(1-t)t p_2 + t^2 p_3, + && t\in[0,1] \\ + \text{Spline:}\quad&(1-t)^3 p_1 + 3(1-t)^2t p_2 + 3(1-t)t^2 p_3 + t^3p_4, + && t\in[0,1] \\ + \text{Arc:}\quad&\mathrm{ctr} + (\cos t)(\mathrm{rad},0,0) + + (\sin t)(0,\mathrm{rad},0), + && t\in[t_\mathrm{min}, t_\mathrm{max}] \\ + \text{Ellipse:}\quad&\mathrm{ctr} + (\cos t)v_1 + (\sin t)v_2, + && t\in[t_\mathrm{min}, t_\mathrm{max}]. +\end{align*} +\texicommentend +If parameter bounds are omitted in an \code{ellipse} command, the +entire ellipse is drawn. When the angular range subtends one or more +full turns in an \code{arc}~or \code{ellipse} the curve is subject to +filling. + +Commands for planar (half-)ellipses remain from \ePiX's early days: +\findex{ellipse} +\findex{ellipse\_left} +\findex{ellipse\_right} +\findex{ellipse\_top} +\findex{ellipse\_bottom} +\begin{verbatim} + ellipse(P ctr, P radius); + ellipse_left(P ctr, P radius); + ellipse_right(P ctr, P radius); + ellipse_top(P ctr, P radius); + ellipse_bottom(P ctr, P radius); +\end{verbatim} +If \code{radius} is \code{P(a,b)}, these commands draw all or half of +the ellipse with given center in the \teximath{(x_1,x_2)} plane, axes +parallel to the coordinate axes, and axis lengths \teximath{2a}~and +\teximath{2b}. + +Two commands are available to mark off right angles or a subtended +angle. Each accepts a spatial location and two non-zero directions, +and draws a scene element in the plane spanned by the vectors. +\findex{right\_angle} +\findex{arc\_measure} +\begin{verbatim} + right_angle(P loc, P v1, P v2, scale=8); + arc_measure(P loc, P v1, P v2, scale=8); + arc_measure(P loc, P v1, P v2, offset, text, align, scale=8); +\end{verbatim} +The \code{right\_angle} command does not check its arguments for +perpendicularity. The \code{arc\_measure} commands mark the +\emph{small} angle subtended by the directions; the label form places +a label at the midpoint of the arc. The (optional) \code{scale} +argument is the true size in~\code{pt} of the marker. + + +\subsubsection*{Recursive Fractal Curves} + +\index{Path!fractal} +Consider a path made up of equal-length segments that can point at any +angle of the form~\teximath{2\pi k/n} radians, for \teximath{0\leq +k<n}, like spokes on a wheel. A path is specified by a finite sequence +of integers, taken modulo~\teximath{n}. For example, if +\teximath{n=6}, then the sequence \teximath{0, 1, -1, 0} corresponds +to the ASCII path \verb+_/\_+. \ePiX's fractal approximation starts +with such a ``seed'' then recursively (up to a specified depth) +replaces each segment with a scaled and rotated copy of the seed, +Figure~\ref{fig:fractal}. The seed above generates the standard +von~Koch snowflake fractal. In code: +\findex{fractal} +\begin{verbatim} + const int seed[] = {6, 4, 0, 1, -1, 0}; + fractal(P(a,b), P(c,d), depth, seed); +\end{verbatim} +The first entry of \code{seed[]} (here~6) is the number of +``spokes''~\teximath{n}, the second~(4) is the number of terms in the +seed, and the remaining entries are the seed proper. The final path +joins \teximath{(a,b)}~to \teximath{(c,d)}. The number of segments in +the final path grows exponentially in the depth, so depths larger than +5~or 6 are likely to exceed the capabilities of \LaTeX\ and/or +PostScript. +\begin{figure}[hbt] + \begin{center} + \input{koch.eepic} + \end{center} + \caption{Successive iterations of \{\code{4,8,0,1,0,3,3,0,1,0}\}} + \label{fig:fractal} +\end{figure} + + +\subsubsection*{Arrows} + +\index{Arrow} +Line segments, splines, and arcs can be drawn with arrowheads at one +end. In profile, an arrowhead's width is \code{3pt}, and its height +is 5.5~times the width. The actual printed height depends on the +head's orientation with respect to the camera. By default, an +arrowhead is a filled triangle. The shape and size are adjusted with +declarations: +\findex{arrow\_width} +\findex{arrow\_ratio} +\findex{arrow\_inset} +\begin{verbatim} + arrow_width(w=3); // width in pt + arrow_ratio(r=5.5); // height-to-width + arrow_inset(c=0); // base indent as frac of ht +\end{verbatim} +\input{arrow.eepic} Inset\teximath{=0}\qquad +\input{arrow25.eepic} Inset\teximath{=0.25}\qquad +\input{arrow50.eepic} Inset\teximath{=0.5} \\ +The \code{inset} must be between \teximath{-1}~and \teximath{1}. Each +\code{arrow} command accepts an optional \code{scale} argument, which +scales the arrowhead. +\findex{arrow} +\begin{verbatim} + arrow(P tail, P tip, [scale]); + arrow(P p1, P p2, P p3, [scale]); // spline arrows + arrow(P p1, P p2, P p3, P p4, [scale]); + arrow(P ctr, P v1, P v2, t_min, t_max, [scale]); // ellipse +\end{verbatim} +A few ``special-purpose'' commands are supplied: +\findex{dart} +\findex{aarrow} +\findex{arc\_arrow} +\begin{verbatim} + dart (P p1, P p2); // same as arrow(p1, p2, 0.5); + aarrow(P p1, P p2); // double-headed arrow <---> + arc_arrow(ctr, rad, t_min, t_max, [scale]); +\end{verbatim} +If an \code{arc\_arrow} is too short, nothing is drawn. + + +\subsection{Coordinate Axes and Labels} + +\index{Labels!axis|(} +\index{Axes!labeling} +\index{Axes|(} +\ePiX\ provides an \code{axis} class for coordinate axes. Labels are +generated automatically in a variety of styles: decimal, scientific +notation, fraction, and trigonometric fraction. Logarithmic axes and +labels are available. Axis and labeling commands from Version~1.0 have +been retained. + + +\subsubsection*{The \code{axis} Class} + +An \code{axis} consists of a line segment divided into a specified +number of equal-length subintervals by ``major'' (long) tick marks. +Each subinterval may be divided further by ``minor'' (short) tick +marks. Minor ticks may be equally-spaced (``Cartesian'') or +logarithmically placed. Finally, a label is written at each major tick +mark with specified offset and alignment. Labels are generated +automatically from the endpoints, so the line should be parallel to a +coordinate axis. Label attributes (masking, borders, font size and +face, rotation angle) are determined by the current label style, not +by the \code{axis}. + +The command +\findex{axis} +\begin{verbatim} + axis(P tail, P head, int n, P offset=P(0,0), [align = none]); +\end{verbatim} +creates an axis joining \code{tail} to \code{head}, divided into +\code{n}~segments of equal length, with a major tick mark and label at +each division point and endpoint. The \code{offset} and \code{align} +arguments have the same meaning as for ordinary labels. + +The number and length of minor ticks, and the alignment of ticks, are +controlled with member functions: +\findex{axis.subdivide} +\findex{axis.tick\_ratio} +\findex{axis.align} +\begin{verbatim} + axis Ax(P(a,c), P(b,c), n); + Ax.subdivide(n); // put n-1 minor ticks in each axis segment + Ax.tick_ratio(r); // minor length = r*major length + Ax.align(AL=c); // align all ticks; AL = t, b, l, r, or c +\end{verbatim} +By default, major ticks are \code{6pt}~long and twice the length of +minor ticks. The global declaration \code{tick\_size(len)} sets the +major length, subject to ``reasonable stylistic limits''. For visual +consistency, tick lengths should not be changed casually. + +\index{Axes!labeling} +Labels on an \code{axis} may be drawn in several styles, selected with +member functions: +\findex{axis.dec} +\findex{axis.frac} +\findex{axis.trig} +\findex{axis.sci} +\findex{axis.unmark} +\findex{axis.precision} +\findex{axis.align\_labels} +\begin{verbatim} + Ax.dec(); // decimals (default) + Ax.frac(); // fractions, e.g. 0.5 -> \frac{1}{2} + Ax.trig(); // fractional multiples of \pi + Ax.sci(); // scientific notation, k\times base^N + + Ax.unmark(double); // remove label at selected location + Ax.precision(p); // set number of digits for decimal labels + Ax.align_labels(AL); // re-align labels +\end{verbatim} +Arbitrary textual labels depending on one coordinate are obtained by +writing a \code{string}-valued function of~\code{double} and +``registering'' it: +\findex{axis.label\_rep} +\begin{verbatim} + // f represents x as a string in given precision and base + std::string f(double x, unsigned int prec, unsigned int base); + Ax.label_rep(f); +\end{verbatim} +For example, textual tags can be printed instead of numeric labels. + +By default, an \code{axis} is Cartesian. The member function +\code{log(int b=10)} converts an \code{axis} to ``log mode'' with +specified base; this affects both tick marks and labeling. If \code{b} +is at least~3, minor tick marks appropriate for a logarithmic axis +base~\code{b} are drawn. Second, labels are written in decimal or +scientific notation appropriately for a logarithmic axis; that is, +``\teximath{k\times b^N}'' (or its decimal value) is written at +location \teximath{N+\log_b k}. + +Minor ticks of a log \code{axis} may be labeled individually; again, +this is controlled with member functions: +\findex{axis.tag} +\findex{axis.tag235} +\findex{axis.tags} +\findex{axis.untag} +\begin{verbatim} + Ax.tag(d); // labels at N+log_b(d) + Ax.tag235(); // tag 2, 3, and 5 if b=10 + Ax.tags(); // tag 1, ..., b-1 + Ax.untag(); // remove all tags, including 1 + Ax.untag(double); // remove one tag, e.g. Ax.untag(9); +\end{verbatim} + +For convenience, an \code{axis} object along an edge of the active +\code{screen} can be created with a named command: +\findex{top\_axis} +\findex{bottom\_axis} +\findex{left\_axis} +\findex{right\_axis} +\begin{verbatim} + top_axis(n, offset, align); + bottom_axis(n, offset, align); + left_axis(n, offset, align); + right_axis(n, offset, align); +\end{verbatim} +The ticks automatically point into the bounding box. + +The functions above create objects or set \code{axis} attributes, but +write no output. Tick marks and labels can be printed separately, or +at once: +\findex{axis.draw} +\findex{axis.draw\_ticks} +\findex{axis.draw\_labels} +\begin{verbatim} + Ax.draw(); // axis, tick marks, and labels + Ax.draw_ticks(); // axis and ticks only + Ax.draw_labels(); +\end{verbatim} + + +\subsubsection*{Other Axis-Drawing Commands} + +\index{Axes!logarithmic} +\ePiX\ formerly supplied commands for drawing simple axes and their +labels. These commands have been kept for compatibility. Horizontal +axes are generated with +\findex{h\_axis} +\findex{h\_log\_axis} +\findex{v\_axis} +\findex{v\_log\_axis} +\begin{verbatim} + h_axis(p1, p2, n, align=c); // n subintervals (n+1 ticks) + h_log_axis(p1, p2, n, align=c, base=10); +\end{verbatim} +For vertical axes, use \code{v\_axis}. The style of tick mark is +appropriate for an axis of the given type. Horizontal axis tick marks +may be aligned \code{t}~(above the axis) or~\code{b} +(below). Similarly, vertical axis ticks may be aligned \code{r}~or +\code{l}. + +The endpoint arguments of a coordinate axis may be omitted, in which +case they default to \teximath{p_1=(x_\mathrm{min},0)} and +\teximath{p_2=(x_\mathrm{max},0)} for a horizontal axis, or to +\teximath{p_1=(0,y_\mathrm{min})} and +\teximath{p_2=(0,y_\mathrm{max})} for a vertical axis. If the bounding +box has integer width and/or height, omitting the number of points +draws tick marks one unit apart. + +Labels for a horizontal Cartesian or logarithmic axis are generated +with the commands +\findex{h\_axis\_labels} +\findex{h\_axis\_masklabels} +\findex{h\_axis\_log\_labels} +\findex{h\_axis\_log\_masklabels} +\findex{v\_axis\_labels} +\findex{v\_axis\_masklabels} +\findex{v\_axis\_log\_labels} +\findex{v\_axis\_log\_masklabels} +\begin{verbatim} + h_axis_labels(P p1, P p2, int n, P offset, [align]); + h_axis_masklabels(p1, p2, n, offset, [align]); + h_axis_log_labels(p1, p2, [n], offset, [align], base=10); + h_axis_log_masklabels(p1, p2, [n], offset, [align], base=10); +\end{verbatim} +Labels for a vertical axis are generated with \code{v\_axis\_labels}, +etc. The labels are automatically generated to match their horizontal +location. The first puts \teximath{(n+1)}~evenly-spaced labels on the segment +joining \code{p1}~and \code{p2}. As with ordinary labels, the +\code{offset} is in~\code{pt}, and the optional \LaTeX-style alignment +option positions the labels using their corners. The second command +draws masked labels according to the current label masking +attributes. The third writes labels in exponential notation, using the +Cartesian coordinate as exponent. + +As for coordinate axes, the initial and final points may be omitted in +an \code{axis\_[mask]labels} command, with the same defaults. The +\code{offset} and number of labels must always be specified. + + +\subsubsection*{Broken Axes} +\index{Axes!broken} + +Broken axes are best drawn using page layout, especially if axis +labels are to be drawn. To accomplish the task, create a screen for +each piece of axis, using appropriate Cartesian coordinates for the +corners, then \code{inset} the screens so the axis pieces are nearly +end to end. A zig-zag glyph signifies the break: +\findex{axis\_break} +\begin{verbatim} + axis_break(P, P, scale=12); +\end{verbatim} +The \code{P} arguments are the screen coordinates of the ends to be +joined; the optional third argument is the true height and width +in~\code{pt} of the glyph. The sample file \filename{coord\_tricks.xp} +uses layout and axis breaks. + + +\subsubsection*{Coordinate Grids} + +Cartesian grids fill a coordinate rectangle, and have a specified +number of lines in each direction. A polar grid has specified radius, +and numbers of rings and sectors. +\findex{grid} +\findex{polar\_grid} +\begin{verbatim} + grid(n1, n2); // fills the bounding box + grid(p1, p2, n1, n2); // fills the box with corners p1, p2 + polar_grid(r, n1, n2); +\end{verbatim} + +Log and semi-log grids are drawn with analogous syntax: +\findex{log\_grid} +\findex{log1\_grid} +\findex{log2\_grid} +\begin{verbatim} + log_grid (p1, p2, n1, n2, [base1], [base2]); // log-log + log1_grid(p1, p2, n1, n2, [base]); // log-lin + log2_grid(p1, p2, n1, n2, [base]); // lin-log +\end{verbatim} +The~\teximath{n_i} arguments dictate the number of squares, namely the number +of orders of magnitude spanned in the logarithmic direction(s). The +(optional) base arguments default to~10, and control the number of +lines drawn per order of magnitude. As with Cartesian grids, the +corners are optional; if omitted, the grid fills the bounding box. + +\index{Graph paper} +Graph paper may be created by superimposing grids: +\texicomment +\begin{center} + \begin{minipage}[b]{2.5in} + \begin{footnotesize} +\texicommentend +\findex{pen} +\findex{grid} +\begin{verbatim} + pen(0.25); + grid(10*xsize(), 10*ysize()); + pen(0.5); + grid(2*xsize(), 2*ysize()); + pen(1); + grid(xsize(), ysize()); +\end{verbatim} +\texicomment + \end{footnotesize} + \end{minipage} + \qquad + \input{graphpaper.eepic} +\end{center} +\index{Axes|)} +\texicommentend + +\subsection{The Path Class} + +\index{Path!class} +A \code{path} data structure is an ordered list of points that can be +cropped, clipped, mapped, concatenated, and drawn. The first four +constructors mirror polygon-drawing commands above. Function graphs +and parametric paths are built from a real- or \code{P}-valued +function~\code{f} of one variable. +\findex{path} +\begin{verbatim} + path(p1, p2, expand=0); // line (endpoints) + path(p1, p2, p3, [n]); // quadratic spline + path(p1, p2, p3, p4, [n]); // cubic spline + path(p1, v1, v2, t_min, t_max, [n]); // ellipse + path(f, t_min, t_max, [n]); +\end{verbatim} + +The member function \code{pt()} accepts a~\code{P} or three (or two) +doubles and appends the specified point to a \code{path}. This +snippet creates a regular \teximath{n}-gon: +\begin{verbatim} + path ngon; // declare new path + for (int i=0; i<=n; ++i) + ngon.pt(cis(i*full_turn()/n)); // works in all angle modes +\end{verbatim} +Compound paths may be built by concatenation. If \code{path1}~and +\code{path2} share an endpoint, the commands +\begin{verbatim} + path1 += path2; + path1 -= path2; +\end{verbatim} +replace \code{path1} with the result of traversing \code{path1} +``forward'', then following \code{path2} in the forward or reverse +direction (respectively). For expected results, the first +(or last) point on~\code{path2} should be the last point +of~\code{path1}. The notation suggests 1-dimensional homology +chains. The sample file \filename{contour.xp} illustrates path +creation and manipulation. + +A \code{path} is a data structure, and must be drawn explicitly to +create visible output. By default a \code{path} is not a closed loop +(even if the first and last points are the same), and is not filled +when drawn. Member functions perform these tasks. Continuing the +\teximath{n}-gon snippet above, +\findex{path.close} +\findex{path.fill} +\findex{path.draw} +\begin{verbatim} + ngon.close(); // mark path as closed + ngon.fill(); // draw filled region if filling is active + ngon.draw(); // print to the screen +\end{verbatim} +\code{path::close()} adds a closing edge if necessary. Once a +\code{path} is closed, no more points can be added. A closed path +clips and crops differently than an open \code{path} with the same +data. \code{path::fill()} has no effect on an unclosed \code{path}. + + +\subsection{Function Plotting} + +\index{Plotting|(} +The noun ``map'' refers to a \CXX\ function that accepts one or +more \code{double} arguments and returns a \code{double}~or +a~\code{P}. Mathematically, a map can be depicted in two ways: as a +graph (which retains information about the domain), or as a +parametrized curve or surface (which discards domain +information). \ePiX\ assumes that \code{double}-valued maps are +graphed and \code{P}-valued maps are drawn parametrically. Either sort +of depiction is called a ``plot''. \ePiX\ plots are either ``wire +mesh'', produced by a \code{plot} command, or ``shaded'', produced by +a \code{surface} command. + + +\subsubsection*{Basic Plotting} + +For the moment, ``function'' means ``function of one variable'' +(precisely, a \code{double}-valued function of a \code{double} +variable). A function graph depends on the domain and the number of +points to use. Each of the commands +\findex{plot} +\findex{polarplot} +\findex{shadeplot} +\begin{verbatim} + plot(f, t_min, t_max, n); + polarplot(f, t_min, t_max, n); + shadeplot(f, t_min, t_max, n); +\end{verbatim} +graphs the function~\code{f} on the interval \code{[t\_min, t\_max]} +by dividing the interval into \code{n}~subintervals of equal length. +The first gives a Cartesian plot, the second a polar plot with bounds +in current angular units, the third shades the region between the +graph and the horizontal axis. If two functions are given to +\code{shadeplot}, the region between their graphs is shaded. + + +\subsubsection*{Domains and Wiremesh Plots} + +\index{Domain|(} +An \ePiX\ \code{domain} is a coordinate box of dimension one, two, or +three, specified by a pair of opposite corners and two \emph{meshes} +(``coarse'' and ``fine'', respectively) which specify the amount of +data to be plotted. Plotting is explained in detail below. +\findex{domain} +\begin{verbatim} + // [a1,a2] x [b1,b2]: n1 x n2 rectangles, m1 x m2 intervals + domain R2(P(a1,b1), P(a2,b2), mesh(n1,n2), [mesh(m1,m2)]); + + // [a1,a2] x [b1,b2] x [c1,c2] divided analogously + domain R3(P(a1,b1,c1), P(a2,b2,c2), + mesh(n1,n2,n3), [mesh(m1,m2,m3)]); +\end{verbatim} +If unspecified, the fine mesh is the same as the coarse mesh. For +expected behavior, the coarse mesh should ``divide'' the fine mesh, in +that \teximath{m_i}~should be a (usually small) integer multiple +of~\teximath{n_i} for each~\teximath{i}. + +A \code{domain} may be \emph{resized} in any coordinate for which the +thickness is positive, and can be \emph{sliced} by setting one +variable to a constant. The result of slicing is a \code{domain} whose +dimension is one smaller than the original. Finally, +``\code{slices}'' operators return the list of \code{domain}s obtained +by setting one variable to evenly-spaced constants. By default, the +number of slices is specified by the coarse mesh. An optional argument +specifies the number of slices. This argument need not be related to +the coarse mesh. +\findex{domain.resize} +\findex{domain.slice} +\findex{domain.slices} +\begin{verbatim} + R2.resize2(a,b); // [a1,b1] x [a,b] + R2.slice1(t); // set x1 = t + R3.slices3([n]); // (n+1) domains with x3 = const +\end{verbatim} +\begin{center} + \input{slices.eepic} +\end{center} +\smallskip +When possible, resizing preserves grid square sizes. Generally, +though, integer truncation occurs: If \code{R=domain(P(0,0), P(1,1), +mesh(10,6))}, then \code{R.resize1(0,0.25)} is the rectangle +\teximath{[0,0.25]\times[0,1]} subdivided into \teximath{2\times6} +subrectangles, since \teximath{10\div4=2} in integer arithmetic. For +expected behavior, choose mesh sizes to avoid integer truncation. + + +The arguments of a \code{plot} command are a map, followed by either a +domain or its logical equivalent. +\findex{plot} +\begin{verbatim} + double f(double t) { return t*t; } + P F(double u, double v) { return P(u, v, exp(u)*Sin(v)); } + P G(double u, double v, double w) { return P(v*w, u*w, u*v); } + + plot(f, a, b, n); // f:[a,b] -> R, using n intervals + plot(F, R2); // graph of exp(u)*Sin(v) + plot(G, R3.slice2(0.5); // G: R^3 -> R^3 restricted to y=0.5 +\end{verbatim} +By (compiler-enforced) convention, \code{plot} commands involving a +\code{P}-valued map accept a \code{domain} argument, as in the second +and third commands above. To plot a \code{double}-valued function, by +contrast, supply the logical equivalent of a \code{domain}, usually +the endpoints and the number of intervals, as in the first \code{plot} +command above. + +Resizing and slicing allow a map~\code{F} to be plotted selectively +over parts of its domain. This can be used to emphasize parts of the +image, layer scene elements, patch surfaces together, and so forth. +Resize and slice(s) commands may be used directly in a \code{plot} +command: +\findex{plot} +\begin{verbatim} + plot(F, R2.resize1(0,0.5)); + plot(F, R2.slices1()); +\end{verbatim} + + +\subsubsection*{Meshes and Plotting} + +The \code{P}~arguments of a \code{domain} are a pair of opposite +corners. The first \code{mesh} argument, the \emph{coarse} mesh, +specifies the number of subdivisions in each coordinate direction. +The second \code{mesh}, the \emph{fine} mesh, determines the number of +points used in each direction when plotting. + +\begin{comment} +Suppose the \code{domain}~\code{R2} is, as above, the rectangle +\teximath{[0,3]\times[-1,2]}. The argument \code{mesh(12,6)} divides the +rectangle a \teximath{12\times6}~array of subrectangles known as the +\emph{coarse mesh}. A \code{P}-valued map~\code{F} of two variables is +plotted over the edges of the coarse mesh. Rather than drawing +quadrilaterals, however, \ePiX\ draws the image curves at the +resolution specified by the argument \code{mesh(60,60)}, the +\emph{fine mesh}. In this example, the curves in each direction are +drawn using 60~line segments. +\end{comment} + +Separating the roles of coarse and fine meshes allows a plot to +conform closely to a surface without using a fine grid of curves. +Both parts of Figure~\ref{fig:plot} are drawn with a +\teximath{6\times20} coarse mesh. In the first picture, the fine mesh +is also \teximath{6\times20}, while in the second, the fine mesh is +\teximath{12\times60}. + +\begin{figure}[hbt] + \begin{center} + \input{plot_a.eepic}\hspace*{0.5in} + \input{plot_b.eepic} + \caption{Coarse and fine meshes.} + \label{fig:plot} + \end{center} +\end{figure} + +The coarse mesh is significant only for domains of dimension at +least~2. The coarse mesh's size determines the number of curves or +surfaces plotted \emph{perpendicularly} to a coordinate direction, +while the fine mesh's size determines the number of segments used +\emph{along} that direction. For predictable results, the fine mesh +should be a small multiple of the coarse mesh. + +Plotting works analogously for 3-dimensional \code{domain}s and maps +depending on three variables: The ``one-dimensional skeleton'' of the +\code{domain}'s image is drawn. A \code{P}-valued map of +three variables can be plotted over a 1-~or 2-dimensional +\code{domain}. (The effect may be unexpected unless the domain arises +by slicing, however.) A map depending on one or two variables cannot +be plotted over a 3-dimensional \code{domain}. +\index{Domain|)} + + +\subsubsection*{Shaded Surfaces} + +\index{Plotting!surface|(} + +\ePiX's shaded surface plotting implements a degree of hidden surface +removal. The algorithm breaks a surface into mesh fragments, sorts +them in decreasing (approximate) distance to the camera, and prints +them. If filling is active, a mesh fragment is shaded according to +the angle between the normal vector and the direction to the camera, +simulating constant ambient lighting; otherwise, the current fill +color is used. This technique works fairly well for surfaces without +intersection, and even acceptably handles intersecting surfaces for +which mesh elements intersect only along boundaries. + +The syntax of a \code{surface} command is identical to a \code{plot} +command when only a single surface is drawn. For example, +\findex{surface} +\begin{verbatim} + surface(F, R, cull=0); +\end{verbatim} +plots the \code{P}-valued function~\code{F} over the domain~\code{R}, +the shaded equivalent of the corresponding \code{plot} command. The +optional \code{cull} argument removes elements that point toward +(\code{cull=-1}) or away from (\code{cull=1}) the camera. Naturally, +orientation of mesh elements depends on the parametrization~\code{F}, +not merely on the surface. Culling reduces the output file size, but +is useful mostly for closed, convex surfaces. + +There are special commands for surfaces of rotation; each accepts a +final \code{cull} argument. +\findex{surface\_rev} +\begin{verbatim} + surface_rev(f, t_min, t_max, n_lats, n_longs); + surface_rev(f, g, t_min, t_max, n_lats, n_longs=24); + surface_rev(f, g, R, frame coords); +\end{verbatim} +The first revolves the graph of~\teximath{f} about the +\teximath{x}-axis, the second uses the parametric curve +\teximath{t\mapsto\bigl(f(t),g(t)\bigr)} as profile. In each case, the +parameter interval \verb+[t_min,t_max]+ is divided into \verb+n_lats+ +equal-length subintervals, \verb+n_longs+ copies of the profile curve +are drawn, and the complete surface (one full turn) is drawn. + +The third form uses a \code{domain} to control the range of +longitudes, and draws a surface of rotation in the Cartesian +coordinate system defined by the orthonormal basis \code{coords}, by +default the standard basis. The arguments \code{f}~and \code{g} define +a parametric curve in the plane spanned by the first two elements +of~\code{coords}, and the first element is the axis of rotation. + +As in wire mesh plotting, the fine mesh is used to draw the boundaries +of surface patches; this tends to make surfaces look smoother for +modest-sized coarse meshes. If the coarse mesh is too coarse, however, +two visually undesirable effects can occur. First, adjacent regions of +the surface may be shaded very differently, since shading is constant +over patches defined by the coarse mesh. Second, a patch nearly +tangent to a line of sight may be drawn badly if the patch bends back +on itself, since the boundary of the \emph{patch} is drawn, not the +visible edge of the mathematical surface. See +\filename{samples/artifacts.xp}. + + +\subsubsection*{Multiple Domains and/or Maps} + +A scene containing two or more shaded surfaces cannot generally be +built up one surface at a time. Instead, multiple surfaces must be +assembled into a single data structure before they can be drawn. +Multiple surfaces are built from one or more maps and one or more +2-dimensional \code{domain}s. In the code snippets below, \code{F}~and +\code{G} are \code{P}-valued functions of 3~variables, and~\code{R} is +a 3-dimensional \code{domain}. + +To plot the images of several \code{domain}s under a \emph{single +map}, assemble the \code{domain}s into a list if necessary, then issue +a \code{surface} command: +\findex{surface} +\findex{domain\_list} +\findex{domain\_list.add} +\begin{verbatim} + surface(F, R.slices3(), cull=0); + + domain_list DL(R.slice1(0)); // build domain list + DL.add(R.slice2(0.5)); // add a domain, etc. + surface(G, DL, cull=0); // draw +\end{verbatim} +For multiple maps, \ePiX\ provides the \code{scenery} +class. Conceptually, \code{scenery} is an agglomeration of shaded +surfaces, built one surface at a time from maps and 2-dimensional +\code{domain}s. The \code{add} function accepts two arguments---a map, +and either a \code{domain} or a list of \code{domain}s---and +contributes its data to the \code{scenery} rather than plotting +immediately. Completed \code{scenery} is drawn manually. +\findex{scenery} +\findex{scenery.add} +\findex{scenery.draw} +\begin{verbatim} + scenery S(F, R.slice3(0.25)); // S contains one surface + S.add(F, R.slice2(0)); // S contains two surfaces + S.add(G, R.slices1(3)); // S contains six surfaces + S.draw(cull=0); +\end{verbatim} +Complete examples are included in the \filename{samples} directory: +\filename{spherical.xp}~and \filename{minkowski.xp}. + +In principle, a scene may contain arbitrarily many surfaces. However, +figures that contain many objects tend to tax \LaTeX's internal +stacks. Frequent color changes exacerbate the problem. Even if you +use \filename{hugelatex} (or increase \LaTeX's memory), a figure +containing more than a few thousand mesh elements is unlikely to +compile. At moderate resolution, a surface can easily contain +1000~patches. Each shell script has a command-line option to invoke +\filename{hugelatex}; your mileage may vary. + + +\subsubsection*{User-Specified Color Shading} + +\index{Color!surface plotting} +By default, a \code{surface} or \code{scenery} is colored according to +the current fill color. For finer control, each \code{surface}, +\code{surface\_rev}, and \code{scenery} command accepts an optional +position-dependent \code{color} specification. +\findex{surface} +\findex{surface\_rev} +\findex{scenery} +\findex{scenery.add} +\begin{verbatim} + surface(F, R, color, cull=0); + surface_rev(f, [g], t_min, t_max, n_lats, n_longs, color); + surface_rev(f, g, R, color, [coords]); + + scenery S(F, R, color); + S.add(F, R, color); +\end{verbatim} +The \code{color} argument is a \code{P}-valued function of two or +three \code{double}s whose output is interpreted as a set of +\code{RGB}~densities. If \code{color} takes two arguments, they are +\code{domain} coordinates, and the surface is colored according to +parameter values. If \code{color} takes three arguments, they are +Cartesian coordinates, and the surface is colored according to spatial +location. Please see the sample files +\filename{surface\_shade.xp}~and \filename{S2\_harmonics.xp}. +\index{Plotting!surface|)} + + +\subsection{Calculus Plotting} +\index{Plotting!calculus|(} + +\ePiX\ provides high-level commands for plotting derivatives and +definite integrals, Riemann sums, tangent lines, slope- and vector +fields, and solutions of planar and spatial systems of differential +equations. + +In this section, \code{f}~and \code{g} are \code{double}-valued +functions of one variable. + +\subsubsection*{Utility Functions} + +\findex{sup} +\findex{inf} +\findex{newton} +\begin{verbatim} + sup(f, a, b); // max/min of f on [a,b] + inf(f, a, b); + newton(f, g, x0); // find approximate crossing point +\end{verbatim} +Newton's method returns the crossing point of the given functions, +starting from the specified seed, which should be reasonably close to +the expected solution. If a critical point is hit or 5~iterations +pass, a warning is issued and the current result (probably incorrect) +is returned. The second function~\teximath{g} defaults to the zero function if +omitted. + +\subsubsection*{Derivatives and Integrals} + +The classes \code{Deriv}~and \code{Integral} are used to calculate +values of derivatives and integrals, and to plot these functions. +\findex{Deriv} +\findex{Deriv.eval} +\findex{Deriv.left} +\findex{Deriv.right} +\findex{Integral} +\findex{Integral.eval} +\begin{verbatim} + Deriv df(f); // function object: df(x) = f'(x) + df.eval(t); // return f'(t) + df.left(t); // deriv from left at t: (f(t)-f(t-dt))/dt + df.right(t); // deriv from right at t: (f(t+dt)-f(t))/dt + + Integral prim(f,a); // function object: prim(x) = int_a^x f + prim.eval(b); // numerical integral of f over [a,b] + double val(Integral(f).eval(1)); // val = \int_0^1 f +\end{verbatim} +The lower limit on an integral is~0 by default. \code{Deriv}s and +\code{Integral}s can be used directly in a \code{plot} command: +\findex{plot} +\findex{riemann\_sum} +\begin{verbatim} + plot(Deriv(f), a, b, n); // plot f' over [a,b] + plot(Integral(f, x0), a, b, n); + riemann_sum(f, a, b, n, TYPE); +\end{verbatim} +The second graphs the definite integral \teximath{x\mapsto\int_{x_0}^x +f(t)\,dt} over~\teximath{[a,b]}. As above, \teximath{x_0}~defaults +to~0. The third draws rectangles or trapezoids whose area approximates +the definite integral of~\teximath{f} over~\teximath{[a,b]}. The +\code{TYPE} may be \code{UPPER}, \code{LOWER}, \code{LEFT}, +\code{RIGHT}, \code{MIDPT}, or~\code{TRAP}. + +Tangent lines and envelopes (families of tangent lines) are drawn with +\findex{tan\_line} +\findex{envelope} +\findex{tan\_field} +\begin{verbatim} + tan_line(f, t); // f real- or vector-valued + envelope(f, t_min, t_max, n); // family of tangent lines + tan_field(f, g, t_min, t_max, n); // field of tangents +\end{verbatim} +The sample files \filename{conic.xp}~and \filename{lissajous.xp} +illustrate these features. + + +\subsubsection*{Systems of Differential Equations} + +Let \code{F}~be a \code{P}-valued function of two or three variables. +\findex{ode\_plot} +\findex{flow} +\begin{verbatim} + ode_plot(F, p_0, t_min, t_max, n); + flow(F, p_0, t_max, n); +\end{verbatim} +The first plots the solution curve of the initial-value problem +\teximath{\dot{x}=F(x)}, \teximath{x(0)=p_0}, over the specified time +interval. If \teximath{t_\mathrm{min}} is omitted, its value is~0, so +the curve starts at~\teximath{p_0}. With manual calculation to rotate +a planar field a quarter turn, \code{ode\_plot} can be used to draw +level curves (isobars) of a function of two variables; see the sample +file \filename{dipole.xp}. The \code{flow} function returns the +result of starting at~\teximath{p_0} and flowing by~\teximath{F} for +time~\teximath{t_\mathrm{max}}, using Euler's method with~\teximath{n} +time steps. This is useful for placing markers or arrowheads precisely +along a flow line. + +A planar or spatial vector field itself may be plotted over a +domain~\code{R} in three styles: +\findex{vector\_field} +\findex{dart\_field} +\findex{slope\_field} +\begin{verbatim} + vector_field(F, R, [scale]); // true length + dart_field (F, R, [scale]); // const length + slope_field (F, R, [scale]); // const length +\end{verbatim} +The field is sampled at the grid points of the coarse mesh. If the +domain is 2-dimensional, the plot is a planar slice of the field, even +if the field depends on three variables. If the domain is +3-dimensional, the field is drawn in successive slices +\teximath{x_3=\mathrm{const}}, starting at the height of the first +corner of~\code{R} and ending at the height of the second corner. + +The optional final argument, which defaults to~\teximath{1}, scales the +arrowheads in a vector field, and scales the (constant) length of +field elements for slope and dart fields. The sample files +\filename{layout2.xp}, \filename{lorenz.xp}, \filename{slopefield.xp}, +and \filename{vfield.xp} illustrate usage. + +In each field-plotting command, the domain argument may be replaced by +two points, representing corners of a coordinate rectangle, and two +integers, the number of grid intervals in the selected coordinate +directions. Only planar slices of a vector field can be plotted using +the alternative syntax. +\index{Plotting|)} + + +\subsection{Non-Euclidean Geometry} +\label{non-eucl} + +\ePiX\ provides limited features for spherical and hyperbolic +geometry: the ability to draw lines in the half-plane and Poincar\'e +disk models of the hyperbolic plane, and to draw latitudes, +longitudes, great circle arcs, spherical triangles, regular polyhedra, +and parametrized curves on a sphere. + +Hyperbolic line segments are specified by their endpoints in the upper +half space or ball (Poincar\'e) models. In each case there is no +output if either endpoint lies outside the model. +\findex{hyperbolic\_line} +\findex{disk\_line} +\begin{verbatim} + hyperbolic_line(p, q); + disk_line(p, q); +\end{verbatim} +For compatibility with 2-dimensional hyperbolic space, the half-space +model is the set \teximath{\{(x_1,x_2,x_3)\mid x_2>0\}}. + +\index{Plotting!spherical|(} +A \code{frame} determines geographical coordinates on a \code{Sphere}: +the first element points toward longitude~0 on the equator, the third +element points to the north pole. A latitude line depends on a +\code{Sphere}, a \code{frame}, the numerical latitude, and a range of +longitudes. A longitude line is described similarly. +\findex{latitude} +\findex{longitude} +\findex{back\_latitude} +\findex{back\_longitude} +\begin{verbatim} + latitude(lat, long_min, long_max, Sphere S, frame coords); + longitude(lngtd, lat_min, lat_max, Sphere S, frame coords); +\end{verbatim} +By default, \code{coords} is the standard \code{frame} and \code{S} is +the unit sphere. These commands draw only the portion of the curve +that is visible from the current viewpoint. The function +\code{back\_latitude} draws the invisible portion of a latitude line. + +Spherical arcs and triangles are described by their endpoints. Only +the direction vector from the center of the sphere to an endpoint is +significant; if a sphere is scaled or moved, the same function call +will draw the corresponding object on the new sphere. + +The following draw the visible (front) portions of great circle arcs: +\findex{front\_arc} +\findex{front\_arc2} +\findex{front\_line} +\findex{back\_arc} +\findex{back\_arc2} +\findex{back\_line} +\begin{verbatim} + front_arc(p1, p2, S); // short arc on S from p1 to p2 + front_arc2(p1, p2, S); // arc from p1 to -p1 through p2 + front_line(p1, p2, S); // great circle through p1 and p2 +\end{verbatim} +Triangles and regular (Platonic) polyhedra are provided. The sample +file \filename{sample/polyhedra.xp} illustrates usage. +\findex{front\_triangle} +\findex{front\_tetra} +\findex{front\_cube} +\findex{front\_octa} +\findex{front\_dodeca} +\findex{front\_icosa} +\findex{back\_triangle} +\findex{back\_tetra} +\findex{back\_cube} +\findex{back\_octa} +\findex{back\_dodeca} +\findex{back\_icosa} +\begin{verbatim} + front_triangle(p1, p2, p3, S); // spherical triangle + front_tetra(S, coords); // regular tetrahedron + front_cube(S, coords); // hexahedron + front_octa(S, coords); // octahedron + front_dodeca(S, coords); // dodecahedron + front_icosa(S, coords); // icosahedron +\end{verbatim} +Each function has a \code{back} version, which draws the hidden +portion. The tetrahedron, cube, and octahedron are (up to scale) +inscribed in the cube of side length~\teximath{2} centered at the origin whose +sides are parallel to~\code{frame}. The point \teximath{(1,1,1)} is a vertex of +the tetrahedron. + +Up to scale, the icosahedron's vertices lie on the golden rectangle +with vertices \teximath{(\pm\gamma,0,\pm1)} and its images under cyclic +permutation of coordinates. The dodecahedron is dual to the +icosahedron. + +\subsubsection*{Spherical Plotting} + +Parametrized paths on a \code{Sphere~S} (by default the unit sphere) +can be specified either by radial projection of a \code{P}-valued +curve, or by stereographic projection of a plane curve given as a pair +of \code{double}-valued functions: +\findex{frontplot\_R} +\findex{frontplot\_N} +\findex{frontplot\_S} +\findex{backplot\_R} +\findex{backplot\_N} +\findex{backplot\_S} +\begin{verbatim} + frontplot_R(phi, t_min, t_max, n, [S]); // radial + frontplot_N(f1, f2, t_min, t_max, n, [S]); // from north pole + frontplot_S(f1, f2, t_min, t_max, n, [S]); // from south pole +\end{verbatim} +Attempts to perform radial projection on a path through the origin +will generate division-by-zero errors. Stereographic projection maps +the equatorial plane \teximath{\{x_3=0\}} to the unit sphere by +projection from the corresponding pole: \teximath{N=(0,0,1)}, +\teximath{S=(0,0,-1)}. + +Each spherical plot command has a \code{back} version that prints only +the portion of the path invisible from the current viewpoint. +Because of the way \ePiX\ layers output, it is generally best to put +hidden portions of the input before visible portions, with line width +and/or style that suggests hidden lines. + + +\subsection{Data Plotting} +\index{Plotting!data|(} +\index{Data plotting|(} + +Files of numerical data can be created, manipulated, analyzed, +plotted (paths, scatter plots, and histograms), read, and written. +The format for a data file is one or more floating-point +numbers per line, with the same number of entries per line. Anything +that appears on a line after the \LaTeX\ comment character~\code{\%} +is a comment. + +\ePiX\ provides two \code{plot} commands for file data. The first +facilitates plotting selected columns; the second simplifies plotting +the first two columns with one or both scales logarithmic. Either form +can be used to plot selected columns logarithmically. + +The general commands read numbers from two or three columns of a +specified file, pass them as arguments to a \code{P}-valued +function~\code{F}, and plot the resulting points: +\findex{plot} +\begin{verbatim} + plot("filename", STYLE, [i_1], [i_2], [i_3], [F]); + plot("filename", STYLE, F, [i_1], [i_2], [i_3]); +\end{verbatim} +The first argument is the name of the data file. The \code{STYLE} may +be \code{PATH}, which joins the points in the order they appear, or +any of the marker types in Table~\ref{table:marker}. The +integers~\teximath{i_k} specify columns from which to extract data; these +default, respectively, to the first column, second column, and null (a +column of zeroes). If the ``coordinate system''~\code{F} is omitted in +the first command, it defaults to the Cartesian point constructor. The +function~\code{F} is mandatory in the second form; useful choices +include \code{log\_log}, \code{log\_lin}, and~\code{lin\_log}, which +plot the corresponding coordinate logarithmically. + + +\subsubsection*{Data Files} + +For more elaborate analysis, the \code{data\_file} class presents an +interface to a file as an ordered list of columns. There are two +general ways to create a \code{data\_file}: read in an external file, +or generate data (up to three columns) using specified +\code{double}-valued functions. In the constructors below, each +function~\code{fi} is a \code{double}-valued function of one variable. +\findex{data\_file} +\findex{data\_file.read} +\begin{verbatim} + data_file DF("my_data"); // read data from disk file + data_file DF(f1, t_min, t_max, num_pts); // values of f1 + data_file DF(f1, f2, t_min, t_max, num_pts); + data_file DF(f1, f2, f3, t_min, t_max, num_pts); + data_file DF(3); // create empty data_file with 3 columns + DF.read("file1"); // read a disk file +\end{verbatim} + +Columns of a \code{data\_file} can be transformed by a user-specified +function, averaged, correlated, extracted (for use by other code), +scatter plotted, and written to a disk file at specified +precision. Below, the function~\code{f} is a \code{double}-valued +function of one variable and~\code{F} is a \code{P}-valued function of +two or three variables, whose components are written back to the +selected columns. +\findex{data\_file.transform} +\begin{verbatim} + DF.transform(f, i); // apply f to selected column(s) + DF.transform(F, i=1, j=2); + DF.transform(F, i, j, k); +\end{verbatim} +Basic statistical operations on columns are provided. +\findex{data\_file.dot} +\findex{data\_file.avg} +\findex{data\_file.var} +\findex{data\_file.covar} +\findex{data\_file.regression} +\begin{verbatim} + DF.dot(i,j); // dot product of columns i, j + DF.avg(i); // mean of column i + DF.var(i); // population variance + DF.covar(i,j); // covariance + DF.regression(i,j); // plot regression line +\end{verbatim} +A \code{data\_file} is scatter plotted using syntax as described above. +% The output is cropped automatically to the bounding box. +\findex{data\_file.plot} +\begin{verbatim} + DF.plot(STYLE, [i1], [i2], [i3], [F]); + DF.plot(STYLE, F, [i1], [i2], [i3]); +\end{verbatim} +Histograms and bar charts are described below. + +A \code{data\_file} can be written to a disk file as raw data, or in +specified format. Below, \code{fmt} denotes a \code{string}-valued +formatting function of two variables and \filename{myfile} is the +name of the disk file to be written. +\findex{data\_file.precision} +\findex{data\_file.write} +\begin{verbatim} + DF.precision(4); // set to 4 significant figures + DF.write("myfile"); // write as tab-separated columns + DF.write("myfile", fmt, [i1], [i2]); // apply fmt to cols +\end{verbatim} +A column can be extracted as a \code{C++}~\code{vector} for use by +another function. +\findex{data\_file.column} +\begin{verbatim} + DF.column(i); // i-th column + DF.column(f, i); // i-th column, transformed by f +\end{verbatim} + + +\subsubsection*{Data Containers} + +\ePiX\ provides a \code{data\_mask} class for culling data from a file +according to the values in a specified column, and a \code{data\_bins} +class for sorting data by value. + +A \code{data\_mask} consists of an interval of numbers and a +``filter'' function. The (closed, open, or half-open) interval is +given as a string in standard mathematical notation, or by its +endpoints (for a closed interval). The filter is a +\code{double}-valued function of \code{double}, by default the +identity, \teximath{f(x)=x}. +\findex{data\_mask} +\begin{verbatim} + data_mask dm("[a, b]", [f]); + data_mask dm(a, b, [f]); +\end{verbatim} +A \code{data\_mask} ``passes'' inputs~\teximath{x} if~\teximath{f(x)} +lies in the interval. The member function \code{reverse()} inverts +this logical test. + +The \code{data\_file} class has \code{prune} functions to cull +rows for which a specified column's entry satisfies a +\code{data\_mask}'s criterion. +\findex{data\_mask.prune} +\begin{verbatim} + DF.prune(dm, i); // remove row if i-th column entry fails + DF.prune(a, b, i); // remove row if i-th column outside [a,b] +\end{verbatim} + +A \code{data\_bins} object models an interval divided at specified +locations into ``bins'', not necessarily of equal length. Numerical +data is read in and the number of points in each bin counted. The +lifetime of a \code{data\_bins} object has two stages. First, ``cuts'' +(endpoints of subintervals) are added. Then, once data is read, the +cuts are ``locked'' and cannot subsequently be changed. +\findex{data\_bins} +\findex{data\_bins.cut} +\findex{data\_bins.read} +\begin{verbatim} + // [xmin, xmax] divided into n equal intervals, 1 by default + data_bins db(xmin, xmax, [n]); + db.cut(x); // add a cut at x (if x is in bounds) + db.read(vector<double>); // read data, lock bins +\end{verbatim} + +\index{Histograms} +\index{Bar Charts} +A \code{data\_bins} object can be plotted as a histogram (rectangles' +\emph{area} is proportional to the bin population), bar chart +(rectangles' \emph{height} is proportional to the bin population), or +spline interpolation of a bar chart. +\findex{data\_bins.histogram} +\findex{data\_bins.bar\_chart} +\findex{data\_bins.plot} +\begin{verbatim} + db.histogram(c=1); // c = vertical scale factor + db.bar_chart(c=1); + db.plot(c=1); +\end{verbatim} +By default (\code{c=1}), the height of a bar chart rectangle is the +fraction of the total population contained in the bin; thus, the +height is always between 0~and 1. For a histogram, the height of a +rectangle is the fraction of the population per horizontal unit in the +bin; thus, the total area over an interval~\teximath{[a,b]} does not +depend on how~\teximath{[a,b]} has been subdivided. The sample files +\filename{dataplot.xp}~and \filename{histogram.xp} illustrate use. + +Statistical convention dictates cuts be chosen distinctly from data +values; that is, values should all fall strictly within a bin, not at +a boundary point. With large, unknown data sets, this convention may +be difficult to uphold. \ePiX\ attempts to handle anomalous data +intelligently, by keeping counts of values ``out-of-range'' or +``on-cut''. + +In detail, if \teximath{x<a} or \teximath{x>b} is a data value, it is +counted as out-of-range and does not contribute to the histogram +population. If \teximath{x=a} or \teximath{x=b}, the value counts as +both out-of-range and on-cut but is added to the population of the +lowest or highest bin, respectively. Any other cut appearing as a data +input is flagged as on-cut, and increments the population of each +adjacent bin by one-half. When a histogram or bar chart is written, +\ePiX\ prints a warning message summarizing the number of anomalous +data seen. + + +\subsubsection*{Error Bars} +\index{Error bars} + +Simple horizontal and vertical error bars are provided. The final +(optional) argument is the true height or width (respectively) in pt. +\findex{h\_error\_bar} +\findex{v\_error\_bar} +\begin{verbatim} + h_error_bar(P location, double error, <mark type>, ht=6); + v_error_bar(P location, double error, <mark type>, wd=6); +\end{verbatim} + +To create more complex elements, such as asymmetric bars, whisker +plots, labeled error bars, and the like, write a custom function using +true-size drawing, see page~\pageref{truesize}. For example, a +fillable, labeled, asymmetric, vertical rectangular error bar can be +implemented (entirely in \ePiX) like this: +\begin{verbatim} + void error_bar(P loc, double lo, double hi, P offset, + std::string text, align, double wd=6) + { + const double width(pt_to_screen(0.5*wd)); // converts to 3pt + rect(loc - P(width, lo), loc + P(width, hi)); + line(loc - P(width, 0), loc + P(width, 0)); + label(loc + P(width, 0), offset, text, align); + } +\end{verbatim} +For stylistic uniformity, functions such as this should be put into a +library and used systematically. Section~\ref{section:extensions} +outlines the process of writing, compiling, and using a custom +library. +\index{Plotting!data|)} +\index{Data plotting|)} + + +\subsection{Legends} +\index{Legends} + +A \code{legend} systematically labels different parts of a plot by +associating visual ``keys'' with explanatory text. This tends to be +most useful for plots containing several distinct but conceptually +related graphs requiring contrast. + +Visually, a \code{legend} is represented as an aligned list of rows, +each containing a box (the key), a gap (the label skip), and some +text. These rows are printed in a (usually large) masked label. By +default, keys are \code{12pt}~squares bordered in black, the label +skip is~\code{6pt}, the background is white, and the border is plain +black. These attributes are controlled (simultaneously for all items) +with member functions. Parameters of type \code{double} represent +lengths in~\code{pt}. +\findex{legend} +\findex{legend.backing} +\findex{legend.border} +\findex{legend.item\_border} +\findex{legend.label\_skip} +\findex{legend.key\_size} +\begin{verbatim} + legend L; + L.backing(color); // set background + L.border(color, [double]); // set border color [and width] + L.border(double); // border width + + L.item_border(color, [double]); + L.item_border(double); // same, for item borders + + L.label_skip(double); + L.key_size(double); +\end{verbatim} + + +\subsubsection*{Legend Keys} + +There are three types of legend key, representing filled regions, +paths, and markers. Fill and path keys get their visual attributes +from the current drawing state. A mark key must be told the marker +type. Each is created by specifying the item text. +\findex{legend.fill\_item} +\findex{legend.path\_item} +\findex{legend.mark\_item} +\begin{verbatim} + L.fill_item(text); + L.path_item(text); + L.mark_item(<mark type>, text); +\end{verbatim} +Keys in the printed legend appear in the same order they are created +in the input file. + + +\subsubsection*{Creating a Legend} + +Normally, a \code{legend} is defined near the start of a file, and an +item is added at the point in the file where the corresponding object +or plot is drawn, so that the item receives the correct attributes. A +\code{legend} is placed into the figure with the \code{draw} +function. The arguments have the same meaning as for ordinary +\code{label}s. +\findex{legend.draw} +\begin{verbatim} + L.draw(P location, P offset, align); +\end{verbatim} +All three arguments are mandatory. ``Global'' \code{legend} settings +(border, backing, etc.) may be changed anywhere between the +\code{legend}'s creation and \code{draw} function. The sample file +\filename{legend.xp} revisits the example on +page~\pageref{taylor_poly}, including a trig-labeled axis and a +legend. The file \filename{shadeplot.xp} contains filled keys, and +\filename{dataplot.xp} contains a \code{legend} with items of mixed +type. + + +\section{More About \CXX} +\index{Cplusplus@\CXX|(emph} + +A textbook or similarly detailed reference is essential for serious +study of~\code{C} or~\CXX. \emph{The \code{C} Programming Language}, +second edition, by Kernighan~and Ritchie~\cite{KnR}, is an excellent, +manageable resource for the basics of procedural +programming. \emph{C++ Primer Plus}, by Stephen Prata~\cite{Prata}, +clearly lays out the extensive details of~\CXX. Marshall Cline's +\emph{\CXX\ FAQ Lite}~\cite{Cline} engagingly discusses common points +of confusion and furnishes tips on good design and programming. + +\CXX\ is a powerful, complex language whose syntax is similar to that +of~\C, or to the scripting languages of Maple~and Mathematica. An +\ePiX\ input file is source code for a \CXX~program that writes a +\LaTeX\ picture as output. \ePiX\ may be viewed as an extension +to~\CXX; in the same way that \LaTeX\ furnishes a high-level interface +to~\TeX, \ePiX\ provides a high-level bridge between the computational +power of~\CXX\ and the \LaTeX\ \code{picture} environment. + +\index{Function} +\index{Conditional statement} +Like all high-level programming languages, \CXX\ provides variables, +functions, and control structures. Variables hold pieces of data such +as numerical values and geometric locations, while functions operate +on data. A control structure, such as a loop or conditional statement, +affects the program's course according to the program's current state. +A source file is composed primarily of ``statements'', which perform +actions ranging from defining variables and functions to setting +figure attributes, performing calculations, and writing objects to the +output file. + +\subsection{Names and Types} + +\index{Variable!names|(} +Names of variables and functions may consist (only) of letters, +digits, and the underscore character. The first character of a name +must not be a digit, and the language standard reserves names starting +with underscore for library authors. Names are case-sensitive, but +it's usually a bad idea to use a single name capitalized and +uncapitalized in a single file. Numerous capitalization conventions +are used informally; this document uses uncapitalized words separated +by underscores for variables and functions, and occasionally uses all +capitals for constants. As with names of \LaTeX\ macros, primary +considerations are clarity (of meaning), readability, and consistency. +\index{Variable!names|)} + +\index{Variable!type of} +Every variable in \CXX\ has a ``type'', +such as integer (\code{int}), double-precision floating point +(\code{double}), or Boolean (\code{bool}, true~or false). \ePiX\ +provides additional types, the most common of which is~\code{P}, for +point. The construct \code{P(x,y,z)} creates~\teximath{(x,y,z)}, while +\code{P(x,y)} gives~\teximath{(x,y,0)}, which is effectively the +pair~\teximath{(x,y)}. A variable is defined by giving its type, its +name, and an initializing expression. + +\index{Variable!pointer} +\index{Pointer} +In~\code{C} and~\CXX, a \emph{pointer} variable holds the memory +address of another variable. Pointers are useful for manipulating +(possibly large) data structures through ``handles'' of fixed small +size. \CXX\ also provides \emph{references}, which bind an additional +name to an existing object and allow the object to be manipulated +through this alias. The statements +\begin{verbatim} + double x=1; // ordinary variable definition + double& rx=x; // bind a reference, signified by & +\end{verbatim} +define a variable~\code{x} having the value~1, and bind a reference +variable~\code{rx} to it. As long as~\code{rx} exists, it refers +to~\code{x}. If the value of~\code{x} changes, the value of~\code{rx} +does as well. Conversely, the value of~\code{x} can be altered by +assigning to~\code{rx}. However,~\code{rx} is the size of a pointer, +regardless of the size of~\code{x}, so~\code{rx} can be passed +efficiently in a function call. +\texicomment +Some applications are discussed on page~\pageref{references}. +\texicommentend + + +\subsection{Functions} + +\index{Function|(} +In a programming language, the term ``function'' refers to a block of +code that is executable by name. A \CXX\ function takes a list of +``arguments'', and has a ``return value''. This information, together +with the function's name, must be provided when a function is defined. +A function may not be defined inside another function. However, a +function may call other functions (including itself) as part of its +execution: +\begin{verbatim} + int factorial(unsigned int n) + { + if (n == 0) return 1; + else return n*factorial(n-1); + } +\end{verbatim} + +\index{Function!returning \code{void}} +The special type~\code{void} represents a ``null type''. A function +that performs an action but does not return a value has return type +\code{void}. A function that takes no arguments may be viewed as +taking a single \code{void} argument. + +Every \CXX\ program has a special function~\code{main()}, which is +called by the operating system when the program is run. The arguments +of~\code{main()} are command-line arguments, and the return type is an +integer that signals success or failure. User-specified functions must +be defined before the call to \code{main()} or in a +separately-compiled file. + +Functions in~\CXX\ may be as simple as an algebraic formula or as +complex as an arbitrary algorithm. Greatest common divisors, finite +sums, numerical derivatives and integrals, solutions of differential +equations, recursively generated fractal curves, and curves of best +fit are a few applications in \ePiX. Several sample files contain +user-level algorithms, which do not require knowledge of \ePiX's +internal data structures. The source file \filename{functions.cc} +contains simple functions defined by algorithms, and +\filename{functions.h} illustrates the use of \CXX\ templates. Other +source files, such as \filename{plots.cc}, may be consulted for +Simpson's rule, Euler's method, and the like. + + +\subsection{Mathematical Functions} + +\index{Function!mathematical|(} +\CXX~knows several familiar mathematical functions by name: +\begin{verbatim} + sqrt exp log log10 ceil floor fabs +\end{verbatim} +(\code{fabs} is the absolute value for a floating-point argument.) +\ePiX\ provides trig and inverse trig functions sensitive to angular +mode: +\index{Angular mode} +\findex{Cos} +\findex{Sin} +\findex{Tan} +\findex{Sec} +\findex{Csc} +\findex{Cot} +\findex{Acos} +\findex{Asin} +\findex{Atan} +\begin{verbatim} + Cos Sin Tan + Sec Csc Cot + Acos Asin Atan +\end{verbatim} +The inverse functions are principle branches. + +The function \code{pow(x,y)} returns~\teximath{x^y} when +\teximath{x>0}, and \code{atan2(y,x)} (N.B. argument order) returns +\teximath{\mathrm{Arg}(x+iy)\in(-\pi,\pi]}, the principle branch of +arg. \CXX~knows many constants to 20~decimal places, such as +\code{M\_PI}, \code{M\_PI\_2}, and \code{M\_E} for~\teximath{\pi}, +\teximath{\pi/2}, and~\teximath{e} respectively. \ePiX\ defines a few +additional functions: +\findex{sgn} +\findex{zero} +\findex{sinx} +\findex{cb} +\begin{verbatim} + sgn zero sinx cb +\end{verbatim} +\texicomment +\begin{center} + \input{sgn.eepic}\qquad + \input{sinx.eepic}\qquad + \input{cb.eepic} +\end{center} +\medskip +\texicommentend +\code{sgn} is the signum function; \code{zero} is the constant +function; \code{sinx} is the function \teximath{x\mapsto \sin(x)/x} +with the discontinuity removed; \code{cb} (for ``Charlie Brown'') is +the period-2 extension of the absolute value function +on~\teximath{[-1,1]}. + +The GNU \CXX\ library defines other functions, including inverse +hyperbolic functions (\code{acosh}, etc.), \code{log}~and \code{exp} +with base~2, 10, or arbitrary~\teximath{b} (\code{log2}, etc.), the +error and gamma functions (\code{erf}~and \code{tgamma} [sic], +respectively), and Bessel functions of first and second kind: +\code{j0}, \code{j1}, \code{y0}, etc. Use, e.g., \code{jn(5,~)} to get +higher indices. The GNU \C~library reference manual~\cite{GNUC} +describes these and other functions in detail. + +Functions may be used in subsequent definitions, and functions of two +(or more) variables are defined in direct analogy to functions of one +variable: +\begin{verbatim} +double f(double t) { return t*t*log(t*t); } // t^2 \ln(t^2) +double g(double s, double t) { return exp(2*s)*Sin(t); } +\end{verbatim} +\index{Function!mathematical|)} + + +\subsection{Basics of Classes} + +\index{Classes|(} +Unlike~\code{C}, \CXX\ supports ``object-oriented programming''. In a +nutshell, a \emph{class} is an abstraction in computer code of some +concept, such as a point, a sphere, a mapping that can be plotted, or +a camera. Classes allow a programmer to separate an object's +\emph{interface} (the set of meaningful operations) from its +\emph{implementation} (the data structures and algorithms that realize +the interface). + +\index{Function!class member} +A class implementation consists of \emph{members} (named data +elements) and \emph{member functions} (functions that belong to the +class and have free access to members). \CXX\ classes enforce access +permissions on their members, protecting data from being manipulated +except as promised by the interface. + +An ideal interface looks like a black box: It hides the implementation +completely. In order to cooperate, two classes need only know each +other's interfaces. This separation of form and function modularizes a +program, and facilitates debugging, code reuse, and overall +maintainability, particularly in large programs. + +In simple programming, classes may be treated like built-in types. +Each class object has its own member functions, whose call syntax +differs from standard function calls: +\begin{verbatim} + Circle C1(P(1,0), 1.5); // circle of given center and radius + C1.draw(); // member function Circle::draw(); +\end{verbatim} +Naturally, this call draws the circle~\code{C1}. Generally, a member +function call consists of a class object's name, a period, and the +name of the member function. Arguments, if any, go in the parentheses +after the member function name, just as in a regular function call. + +A few short paragraphs cannot do more than scratch the surface of +classes and object-oriented programming. For more details, please +consult a book, such as Prata~\cite{Prata} or Stroustrup~\cite{S}, or +Cline's on-line FAQ~\cite{Cline}. +\index{Classes|)} + + +\subsection{References and Function Arguments} + +\index{Function!call syntax} +\index{Variable!reference} +\label{references} +\code{C}~and \CXX\ are ``call by value'' languages. Variables are not +passed to a function; instead a copy of the value is made, and the +function operates only on the copy. Though this feature causes +occasional inconvenience, it prevents an object from being altered +unexpectedly by a function call in a different part of the program. +Calling by value helps localize the logic of a program, and +circumvents easy-to-write but extremely hard-to-find bugs. + +In \CXX, a function may accept reference arguments. Passing an object +by reference grants the calling function access to the object itself, +not to a copy. There are two common applications: The object is a +large data structure for which copying is ``expensive'', or the +function \emph{needs} to modify its arguments (e.g., a function +\code{swap(x,y)} that exchanges the values of \code{x}~and +\code{y}). + +For the first situation, \CXX\ provides the \code{const} keyword, +which ensures the function does not modify its arguments, but accepts +a reference merely for efficiency. Any attempt to modify a +\code{const} argument will be caught by the compiler. Most \ePiX\ +commands accept \code{const} reference arguments. + +The ability to pass function arguments by reference is sometimes +touted as a feature in \CXX\ texts. However, the technique circumvents +the data encapsulation of calling by value, and should be avoided +unless absolutely necessary. If a function merely ``updates'' the +value of a variable, probably the variable should be of class type, +and the update should be performed by a member function. + +A function declaration must indicate that its arguments are +references. The declarations below have the indicated idiomatic +meanings. +\begin{verbatim} + class matrix; + double det(matrix); // call by value, perhaps inefficient + matrix& transpose(matrix&); // probably changes its argument + double trace(const matrix&); // does not change its argument +\end{verbatim} +Unlike pointer arguments, reference arguments impose no syntactic +burden on the user. If~\code{A} is a~\code{matrix}, then +\code{transpose(A);} and \code{trace(A);} will compile. You need not +declare explicit reference variables and pass those to the function. + + +\subsection{Overloading} + +\index{Function!overloaded} +\CXX\ provides ``overloading'': Multiple functions can be given the +same name, so long as the number and/or type of their arguments +differ. (It is \emph{not} enough for the return types alone to differ. +The compiler must be able to select a function from its calling +syntax.) To the user, the appearance is that a single function +intelligently handles multiple argument lists. Naturally, overloaded +names should refer to functions that are conceptually related. +\index{Function|)} + + +\subsection{Scope} + +\index{Variable!local} +A \CXX\ statement ends with a semicolon. A collection of statements +enclosed by curly braces is a ``code block'', and may be viewed as a +single logical statement. Curly braces determine a ``scope'', inside +which variable names may be re-used without ambiguity. Function +bodies are code blocks, as are the alternatives associated to control +statements. A variable defined between curly braces is said to be +\emph{local} to the scope in which it is defined; its value cannot +be used out of scope. Variables should be declared in the smallest +scope possible. + +The compiler is not picky about spaces, tabs, and newlines, so an +input file should be formatted to make local scopes visually +apparent. \code{emacs} automatically indents code to reflect scope, +though the default behavior does not please all users. As with +variable naming, clarity and consistency are paramount. + + +\subsection{Headers and Pre-Processing} + +A \CXX\ source file is compiled in multiple stages that occur +transparently to the user. The first step, pre-processing, involves +simple text replacement for file inclusion, macro expansion and +conditional compilation. Next, the source is compiled and assembled: +Human-readable language instructions are parsed, then represented in +assembly language. Finally, the object files are linked: Function +calls are resolved to hard-coded file offsets, possibly involving +external library files, and the program instructions are packaged into +an executable binary that the operating system can run. + +Pre-processing is used much less in~\CXX\ than in~\code{C}; the +language itself supports safer and more featureful alternatives to +macros, such as \code{const} variables and inline functions. File +inclusion and conditional compilation are the chief uses of the +pre-processor. Lines of the form +\begin{verbatim} + #include <iostream> + #include "epix.h" +\end{verbatim} +cause the contents of a \emph{header file} to be read into the source +file. A header file contains variable and function +\emph{declarations}, statements that specify types and names but do +not define actual data. Declarations tell the compiler just enough +to resolve expressions and function calls without knowing specific +values or function definitions. + +\index{Input file!conditional compilation} +Conditional compilation is similar to conditional \LaTeX\ code. For +example, a file might produce either color or monochrome output as +follows: +\begin{verbatim} +#ifdef COLOR + ... // code for generating color figure +#endif /* COLOR */ +#ifndef COLOR + ... // monochrome code +#endif /* undef COLOR */ +\end{verbatim} +The ``compiler symbol'' \code{COLOR} is an ordinary \CXX\ name. To +control compilation, either put a \code{\#define COLOR} line in the +file, or (better) supply the flag on the command line: \\ +\verb+ epix -DCOLOR <file.xp>+ \\ +Every \code{\#ifdef} must have a matching \code{\#endif}. Commenting +the \code{\#endif} is a good habit; in a realistic file, the start and +end of a conditional block may be separated by more than one screen. + + +\subsection{Comparison with \LaTeX\ Syntax} + +As a programming language, \CXX\ provides certain features common to +all languages (such as \LaTeX, MetaPost, Perl, Lisp\ldots) and adheres +to rules of grammar. Salient differences between \LaTeX\ and \CXX\ +include: + +\begin{enumerate} +\item Every \CXX\ statement and function call must end with a + semicolon. An omitted semicolon may result in a cryptic error + message from the compiler. Pre-processor directives, which start + with a~\code{\#}, do not end with a semicolon. + +\item Backslash is an escape character in \CXX: + \index{Labels} +\begin{verbatim} + // Put label $y=\sin x$ at (2,1) + // Note single ^ backslash in output + label(P(2,1), P(0,0), "$y=\\sin x$"); + // Double backslash ^^ in source +\end{verbatim} + +\item Variable and function names may contain letters (including + underscore) and digits \emph{only}, are case sensitive, and must + begin with a letter. + +\item Variables in \CXX\ must have a declared \emph{type}, such as + \code{int} (integer) or \code{double} (double-precision floating + point). If a variable has global scope and its value does not + change, the definition should probably come in the preamble or at + the beginning of \code{main}. Local variables should be defined in + the smallest possible scope. Unlike~\C, \CXX\ allows variables to be + defined where they first appear. + +\item \CXX~requires explicit use of~\code{*} to denote multiplication; + juxtaposition is not enough. \CXX~does not support the use of + \verb+^+ for exponentiation, e.g., \verb+t^2+ is invalid. Instead, + use \code{t*t}~or \code{pow(t,2)}. + +\item \CXX\ has single- and multi-line comments. Everything between a + double slash and the next newline is ignored, while the strings + \verb+/*+~and \verb+*/+ delimit multi-line comments. A single-line + comment may appear within a multi-line comment, but the compiler + does not nest multi-line comments. + \index{Input file!comment in} + +\end{enumerate} + +Between them, \C~and \CXX~have about 100~reserved keywords which +cannot be used as function or variable names. +\index{Cplusplus@\CXX|)} + + +\section{Attribute Quick Reference} +\label{section:quickref} + +In the body of an input file, the ``drawing state'' determines the +figure's appearance. Attributes are declarations, set by commands that +accept arguments of the stated type. + +A \code{len} argument is a double-quoted string containing a number +and a two-letter \LaTeX\ length unit, such as \code{"1.5pt"} or +\code{"6cm"}. A \code{color} argument is a named primary +(\code{Red()}, \code{Cyan()}, \code{White()}, etc.), a \code{Color} +specified by densities (\code{RGB(...)}, \code{CMYK(...)}, etc.), or a +\code{Color} object. Using \code{Neutral()} as a \code{Color} argument +generally turns off the corresponding attribute. + +\begin{itemize} + +\item Angular mode: \code{radians()}, \code{degrees()}, or + \code{revolutions()}. + + The angular mode affects all trigonometric operations, including + camera rotations, the drawing of arcs and ellipses, polar plotting, + label angle, and the trig functions themselves. Angle-sensitive trig + functions are capitalized, e.g., \code{Cos}, \code{Tan}. + +\item Fill style: \code{fill(color)}, \code{fill(bool)}, + \code{nofill()}. + +\item Path style: + + \begin{itemize} + + \item Width: \code{plain()}, \code{bold()}, \code{bbold()}, + \code{pen(len)}. + + \item Line style: \code{line\_style(string)}. The argument is a + WYSIWYG sequence of dashes, spaces, and periods. + \code{dash\_size(double)} and \code{dot\_sep(double)} set the + (approximate) length in~\code{pt} of the pattern. The commands + \code{solid()}, \code{dashed()}, \code{dotted()} define + ``standard'' defaults for brevity. + + \item Path color: + Paths can be drawn using \emph{two} pens, one atop the other. When + the ``base'' pen is white (or the background color) and wider than + the ``line'' pen, a path masks parts of the figure it crosses. A + 3-D effect may be obtained by making the base pen a darker shade + than the ``line'' pen. + + \code{pen(color,[len])}, \code{base(color,[len])} + + Standard widths: \code{plain(color)}, \code{bold(color)}, + \code{bbold(color)} + + \end{itemize} + +\item Text attributes: + + \begin{itemize} + + \item Color: \code{label\_color(color)} + + \item Mask: \code{label\_mask(color)}, \code{label\_pad(len)} + + \item Border: \code{label\_border(color, [len])}, + \code{label\_border(len)}. The command \code{no\_label\_border()} + turns off label borders. + + \item Font size: \code{font\_size(LaTeX size)}, no argument means + \code{normalsize}. + + \item Font face: \code{font\_face(LaTeX font)}, two-letter font + selection string, default is \code{rm}. + + \item Rotation: \code{label\_angle(double)} + + \end{itemize} + +\end{itemize} + +Do not confuse \code{Color} constructors with the similarly-named +(deprecated) lowercase attribute-setting commands, \code{rgb(r,g,b)}, +\code{cmyk(c,m,y,k)}, \code{red(d)}, etc. These commands affect text, +paths, and filled regions. For example, the single command +\code{red()} has the same effect as the three commands +\code{pen(Red())}, \code{fill(Red())}, and \code{label\_color(Red())}. + + +\texinfochapter{4}{Advanced Topics} +\label{chapter:adv} + +This chapter covers \emph{ad hoc} tricks and open-ended techniques +that require relatively more programming sophistication. You will +almost surely need an external \CXX\ reference if you do not speak the +language. + + +\section{Hidden Object Removal} +\label{section:hidden} + +\index{Hidden object removal|(} +\ePiX\ writes the output file in the same order that objects appear in +the input. The order is significant because PostScript builds a figure +in layers: Objects are drawn over objects that come earlier in the +file. Shaded polygons can be used to obtain surprisingly effective +hidden object removal in surface meshes. This section describes the +data structures defined in the source files \code{surface.*}. + +\index{Camera} +The basic idea is to create a shaded polygon class that knows its +approximate distance to the camera. For computational simplicity, a +mesh ``facet'' is treated as a quadrilateral, located at the +arithmetic mean of its vertices. A facet's boundary is created from a +map and a domain by tracing a fine mesh rectangle counterclockwise. + +To draw a parametrized surface, facets are stored in a \CXX\ vector, +sorted in decreasing order of distance to the camera, and printed to +the output file. If filling is active, the gray density of a facet +depends on the cosine of the angle between the normal vector and the +vector from the camera to the element. + +This simple algorithm works surprisingly well when mesh elements +intersect at most along complete edges. To incorporate line-like +elements (e.g., coordinate axes, wire-mesh plots) with shaded +surfaces, the best technique is often to order high-level scene +elements manually, breaking up shaded surfaces (for example, with +domain resizing or clipping) as necessary. The sample file +\filename{saddle.xp} illustrates possible techniques. + +Shaded surfaces can be decorated with a bit of hackery. For example, +the \code{facet::draw} function in \filename{facet.cc} can be +modified easily to draw line elements, tangents, or normal vectors +along with the facet itself. The sample file +\filename{decorate.xp} contains a couple of ideas. (The +decorations are activated by compiler flags; please consult the file +itself for information on compiling.) +\index{Hidden object removal|)} + + +\section{Extensions} +\label{section:extensions} + +Thanks to a suggestion of Andrew Sterian, \ePiX\ is extensible. User +extensions span a spectrum, from header files that require only basic +knowledge of~\CXX\ to separately compiled libraries that add +substantial new features. The structure of the source code is +outlined in Section~\ref{section:programmers}. + + +\subsection{Header Files} + +A \CXX~header file conventionally has suffix~\filename{.h}, as in +\filename{myheader.h}. To use this custom header, put a line +\code{\#include "myheader.h"} in your source file. + +User definitions can be easily and robustly implemented with ``inline +functions''. Inline functions are superficially similar to macros, but +are far more safe and featureful (since they are handled by the +compiler rather than by the pre-processor). Examples are +\begin{verbatim} + inline void Bold() { pen(1.6); } + inline void purple() { rgb(0.5, 0, 0.7); } + inline void draw_square(double s) { rect(P(-s,-s),P(s,s)); } + inline double cube(double x) { return pow(x,3); // x^3 } +\end{verbatim} +The keyword \code{void} signifies a function that does not return a +value, or (when used as an implicit parameter) a function that does +not accept arguments. Inline function definitions are syntactically +identical to ordinary function definitions, but \emph{must} occur in a +header file or in the source file where they are used. The examples +above might be used in an input file as follows: +\begin{verbatim} + Bold(); + draw_square(cube(1.25)); +\end{verbatim} + + +\subsection{Compiling} + +The next few sections outline the creation of a ``static library'' on +GNU/Linux, and explain how to incorporate custom features at runtime. +The extensively-commented sample files \filename{std\_F.cc}~and +\filename{std\_F.h} illustrate the techniques described below, and may +be used for guidance and experimentation. + +A small library is usually written as a \emph{header} file, which +contains class and function declarations (also called ``prototypes''), +and a \emph{source} file, which contains the actual +code. Conventionally (under *nix), these files have extension +\filename{.h}~and \filename{.cc} respectively. Header and source files +may ``include'' other header files, to incorporate additional +functionality. +\begin{verbatim} +/* my_code.h */ +#ifndef MY_CODE +#define MY_CODE +#include <cmath> // standard library math header +#include "epix.h" // ePiX header +using ePiX::P; + +namespace Mine { // to avoid name conflicts + // functions for special relativity + double lorentz_norm(const P&); + bool spacelike(const P&); +} // end of namespace +#endif /* MY_CODE */ +\end{verbatim} +This file exhibits two ``safety features''. The three \code{MY\_CODE} +lines prevent the file from being included multiple times. In a file +of this size, inclusion protection is overkill, but as your code base +grows and the number of header files increases, this protection is +essential. Second, the header introduces a ``Mine'' namespace. Inside +this namespace, two functions are declared as prototypes, giving the +function's return type, name, and argument type(s). A header file +should be commented fairly liberally, so that a year or two from now +you'll be able to decipher the file's contents. For a longer file, +version and contact information, an overall comment describing the +file's features, and license information are appropriate. + +Next, the corresponding source file; definitions are also placed into +the namespace, and must match their prototypes from the header file +exactly. +\begin{verbatim} +/* my_code.cc */ +#include "my_code.h" +using namespace ePiX; + +namespace Mine { + double lorentz_norm(const P& arg) + { + double x(arg.x1()), y(arg.x2()), z(arg.x3()); // extract coords + return (y-x)*(y+x) + z*z; // -x^2 + y^2 + z^2 + } + bool spacelike(const P& arg) + { + return (lorentz_norm(arg) > 0); // true if inequality is + } +} // end of namespace +\end{verbatim} +Copies of these files are included with the source code so you can +experiment with them. Next, the source file must be ``compiled'', +``archived'', and ``indexed''. In the commands below, the percent sign +is the prompt. +\begin{verbatim} +% g++ -c my_code.cc +% ar -ru libcustom.a my_code.o +% ranlib libcustom.a +\end{verbatim} +Please see your system documentation for details on command options +and what each step does. For linking (below), the name of the library +file must begin ``lib'' and have the extension~\filename{.a}. Once these +steps are successfully completed, put the library \filename{libcustom.a} +and header file \filename{my\_code.h} in your project directory. You're +ready to use the code in an \ePiX\ figure. + + +\subsection{Runtime Linking} + +The script~\epix\ allows input files to be linked with external +libraries at run time, when the input file is compiled into a +temporary executable. + +\epix\ recognizes command line options and passes them verbatim to the +compiler. The most commonly used options are those of the form +\begin{verbatim} + -I<include> -L<libdir> -l<lib> +\end{verbatim} +For example, to link \filename{figure.xp} against +\filename{mylibs/libcustom.a}, run the command +\begin{verbatim} + epix -Lmylibs -lcustom figure +\end{verbatim} +The options \code{-I. -L.} tell the compiler to look in the current +directory for header and library files. Compiler options may appear +in any order, but must come before the name of the input file(s). + +Compiler options may be placed in the configuration file +\filename{\$HOME/.epixrc}, with syntax as above. A line in the config +file that contains a pound sign~(\code{\#}) is a comment, no matter +where in the line the~\code{\#} appears. If any non-comment line +fails to start with a dash, the rest of the file is silently +discarded. Command-line options are read before the config file. + + +\subsection{Using Multiple Versions} + +The script \filename{epix}~links by default against the \code{C}~math +library \code{libm.a}~and the \ePiX\ library \code{libepix.a}. The +command option \code{--no-defaults} clears the header and include +paths and removes \code{libepix.a} from the link list. The script may +therefore be used with multiple versions of \ePiX, a potentially +useful feature if you regularly need to compile old source files, or +simply prefer the syntax of an older version. + +To install and use (say) Version~1.0.0, build the package according to +its \filename{INSTALL} instructions, but \emph{do not use the makefile + to install}. Instead, manually install the header and library only, +using their version number: +\begin{verbatim} +# install -m 644 epix.h /usr/local/include/epix-1.0.h +# install -m 644 libepix.a /usr/local/lib/libepix-1.0.a +\end{verbatim} +A non-system directory may be used instead of \filename{/usr/local}. +To use the old version, a source file must \code{include} the +appropriate header file (which is identified by its version number). +To compile, issue a command such as +\begin{verbatim} +epix --no-defaults -I/usr/local -L/usr/local -lepix-1.0 file.xp +\end{verbatim} + + +\section{Programmer's Guide} +\label{section:programmers} + +This section briefly surveys \ePiX's implementation, and is intended +for (potential) programmers. The source code is divided into modules +with small, well-defined responsibilities, but the user interface is +mostly compatible with the syntax of Version~1.0. These constraints +demanded a degree of implementation hiding. For example, the +user-visible classes defined in \filename{Color.h}, \filename{path.h}, +and~\filename{screen.h} contain only a pointer to the implementation +class, and style data is hidden behind global commands. + +Functionally, the code consists of the user interface; implementation +class\-es comprising drawing attributes, spatial objects, screens and +representations of their elements, and output; and miscellaneous +utility functions. The headers in each group, and their contents, are +described in Section~\ref{section:interface}. + +The user interface headers are assembled into a single file, +\filename{epix.h}, and installed in \filename{/usr/local/include} by +default. In normal use, the shell scripts read only the user interface +header. The individual headers, including the components of +\filename{epix.h}, are installed in +\filename{/usr/local/include/epix}. These are provided for authors of +external libraries, who may need access to implementation details. + + +\subsection{External Packages} + +\ePiX\ harnesses the computational power of~\CXX\ to the typographical +capabilities of \LaTeX. Consequently, \ePiX\ should be viewed in part +as a framework for expressing numerical data visually. + +In the course of your work, you may develop specialized code filling a +gap in \ePiX's functionality. If your code seems likely to be of +interest to other users, please consider bundling it as an external +package and notifying the \ePiX\ community so your work can be linked +from the project pages and distributed to interested users. + +There are no formal requirements for external packages, but in the +interest of uniformity contributed code should follow the GNU Coding +Standards~\cite{GNUCoding}. At a minimum, an external package should +build with the standard \code{./configure; make; make install} +commands, and the \code{configure} script should accept an option +\code{--with-epix} for the user to specify a non-default \ePiX\ +install directory. + +If an external package builds a static library, it should provide a +single header containing all the package's entry points, and enclose +its interface in a namespace. Entry points should not collide with +\ePiX\ functions. Naming the package ``\filename{epix-<...>}'' is a +good idea, but not essential. For example, a package providing textual +nodes and diagram layout might be named \filename{epix-nodes}. Input +files would use the package with the lines +\begin{verbatim} + #include "epix-nodes.h" + using namespace ePiX-nodes; +\end{verbatim} +and be compiled with +\begin{verbatim} + epix -lepix-nodes <file> +\end{verbatim} + +The user and internal interfaces of \ePiX-1.2 are not likely to +change. Still, it's prudent to rely only on the user interface in +contributed code whenever possible. Doing so also simplifies your work +as an author; your library can simply \code{include} the user header +file, and deal only with high-level objects and drawing attributes. + + +\subsection{User Interface} +\label{section:interface} + +These files (in order) comprise the global header \filename{epix.h}. + +\Header{enums.h} Marker, alignment, Riemann integral, and vector field +types. + +\Header{length.h} Physical lengths, conceptually a number and +two-letter \LaTeX\ length unit. + +\Header{interval.h} Closed, open, and half-open interval ranges for +data culling. + +\Header{triples.h} The \code{P} class. + +\Header{functions.h} Angle-sensitive trig functions, miscellaneous +utility functions, the \code{Deriv}~and \code{Integral} classes. + +\Header{pairs.h} Screen locations and displacements, with complex +arithmetic operations. + +\Header{Color.h} The Color class interface, named +primaries and constructors. + +\Header{state.h} Angle mode; clipping and cropping; label styles; +filling; arrow head style; dot and tick sizes, dash length; line +style; line and base pen attributes; color-setting commands. + +\Header{frame.h} Orthonormal bases. + +\Header{domain.h} Coordinate boxes for function plotting. + +\Header{camera.h} The camera. + +\Header{screen.h} The screen class. + +\Header{picture.h} Dimension-setting, offset, layout, decoration, +verbatim text, and output format commands. + +\Header{markers.h} Point markers, axis labels, and coordinate axes. + +\Header{axis.h} Coordinate axes and labels in various styles. + +\Header{legend.h} Plot legends. + +\Header{path.h} The path class. + +\Header{curves.h} Polygons, arrows, ellipses, arcs, splines, +coordinate grids, and recursive fractal curves. + +\Header{circle.h} The \code{Circle} shape object class. + +\Header{plane.h} The \code{Plane} shape object class. + +\Header{segment.h} The \code{Segment} shape object class. + +\Header{sphere.h} The \code{Sphere} shape object class. + +\Header{intersections.h} Shape object intersection operators. + +\Header{plots.h} Plotting commands. + +\Header{surface.h} Shaded surface plots. + +\Header{data\_mask.h} Helper class for data pruning. + +\Header{data\_file.h} Class for storing and representing data. + +\Header{data\_bins.h} Class for sorting and counting data. + +\Header{geometry.h} Latitudes and longitudes; spherical plotting, +arcs, polygons, and polyhedra; hyperbolic arcs. + + +\subsection{Implementation Classes} + +\Header{Color\_Base.h} The Color implementation interface. + +\Header{Color\_CMY.h} The CMY color model. + +\Header{Color\_CMYK.h} The CMYK color model. + +\Header{Color\_Gray.h} The Gray color model. + +\Header{Color\_Neutral.h} Each color class has a ``Neutral'' member +that converts colors to that model by filtering. This file defines the +unique ``model-less'' Neutral color for which filtering performs no +action. + +\Header{Color\_RGB.h} The RGB color model. + +\Header{Color\_Sep.h} Classes for CMYK separation. + +\Header{active\_screen.h} Simple manipulator for the active screen. + +\Header{picture\_data.h} Picture implementation: two \code{screen}s +(representing the \code{canvas}~and the output page), true dimensions +and offsets, pointer to output format, list of colors, and lists of +verbatim text to write before and after printing the \code{picture} +environment in the output file. For simplicity, the \code{screen}s and +dimensions are public; encapsulation from the user results from +``hiding'' this header. + + +\subsubsection*{Style Attributes} + +Declaration-style attributes are maintained with functions returning +static references: \code{the\_angle\_style()}, +\code{the\_arrowhead\_style()}, \code{the\_label\_style()}, +\code{the\_mark\_size()}, \code{the\_paint\_style()}, and +\code{the\_path\_style()}. Each function is declared in the +analogously-named header. + +\Header{angle\_units.h} Angular modes: \code{radians}, +\code{revolutions}, and \code{degrees}. + +\Header{arrow\_style.h} Arrow head style data: width, ratio, and +inset. + +\Header{label\_style.h} Text object style: Label and mask colors, +padding, border color and width, alignment, font size, font face, and +angle. + +\Header{marker\_style.h} Dot and tick sizes. + +\Header{paint\_style.h} Line and base pens, fill color. + +\Header{path\_style.h} Solid, dashed, dotted lines. + +\Header{pen\_data.h} The pen class. + + +\subsubsection*{Objects} + +\Header{arrow\_data.h} Arrow representation. + +\Header{facet.h} Shaded surface elements. + +\Header{label\_data.h} Text (label and marker) objects. + +\Header{legend\_item.h} Items for \code{legend}s. + +\Header{path\_data.h} Path implementation. + +\Header{spline.h} The natural spline class. + +\Header{spline\_data.h} Templates for quadratic and cubic splines. + + +\subsubsection*{Screen Representation} + +Elements in a \code{screen} are represented polymorphically as +``\code{tile}s'', of which there are six types: \code{glyph} (textual +elements), \code{pen\_arrow} (arrows), \code{pen\_fill} (filled +regions), \code{pen\_line} (path-like elements), \code{verbatim} +(raw text), and \code{legend\_tile} (legends). + +Border and background shape are dictated by the \code{screen\_mask} +class. The cropping algorithm assumes the contour of a screen mask is +convex. + +\Header{affine.h} Affine maps. + +\Header{cropping.h} Screen mask cropping. + +\Header{glyph.h} Markers and labels. + +\Header{legend\_tile.h} Screen representation of a \code{legend}. + +\Header{mask\_diamond.h} Screen diamond mask. + +\Header{mask\_ellipse.h} Screen elliptical mask. + +\Header{mask\_rectangle.h} Screen rectangular mask. + +\Header{pen\_arrow.h} Arrows. + +\Header{pen\_fill.h} Filled regions. + +\Header{pen\_line.h} Paths. + +\Header{screen\_data.h} Screen implementation class. + +\Header{screen\_mask.h} Screen mask interface. + +\Header{tile.h} Screen element interface. + +\Header{verbatim.h} Text in output stream. + + +\subsubsection*{Output} + +Output is divided into a couple of high-level operations and several +``atomic'' low-level operations. To create a new output +format, one need only implement the \code{format} interface for the +desired file type. Paths and filled regions may be implemented however +the output type dictates. + +\Header{eepic.h} eepic macros. + +\Header{fmt\_template.h} ``skeleton'' header for new output formats. + +\Header{format.h} The output interface. + +\Header{pst.h} PSTricks macros. + +\Header{tikz.h} tikz macros. + + +\subsubsection*{Utilities} + +\Header{Color\_Utils.h} Functions for setting color channel densities. + +\Header{clipping.h} The clip box. + +\Header{constants.h} Global constants: Line widths; dot, tick, and +dash sizes; arrowhead parameters; miscellaneous numerical constants +and internal parameters. + +\Header{crop\_algorithms.h} Path and loop clipping templates. + +\Header{deriv.h} Finite difference template. + +\Header{edge\_data.h} Path element representation template. + +\Header{errors.h} Warning and error messages. + +\Header{frac.h} Rational numbers and operators. + +\Header{halfspace.h} Halfspace cutting. + +\Header{hatching.h} Filling regions in eepic. + +\Header{lens.h} Camera lenses. + +\Header{map.h} Wrappers for templated plotting. + +\Header{plot\_algorithms.h} Plotting templates. + +\Header{screen\_crop.h} Crop paths and loops. + +\Header{utils.h} Truncation, date and time, line breaking. + + +\appendix +\texinfoappendix{A}{Software Freedom} +\index{Free software|(} + +Academics in general, and mathematicians in particular, depend on free +exchange of information. We prove theorems or establish experimental +results, write up formal accounts, place preprints on public file +servers, and submit papers to peer-reviewed journals. If accepted, the +results---data, techniques, methods of reasoning, citations, and +conclusions---are published in print and become part of the public +record, governed by copyright law. Libraries purchase journal +subscriptions, but researchers and scholars may use ideas from the +literature merely by giving appropriate citations in their own +work. ``Theft'' arises from false claims of authorship. + +Carried over to software, the academic process would guarantee rights +similar to those provided by the GNU General Public License (GPL): + +\begin{itemize} + +\item (GPL~0) To run a program for any purpose. + +\item (GPL~1) To study how the program works, and adapt it to your + needs. + +\item (GPL~2) To redistribute copies of the program. + +\item (GPL~3) To improve the program, and release improvements to the + public, so that the whole community benefits. + +\end{itemize} + +In reality, attitudes toward software differ markedly. Most academics +work on a proprietary platform, use proprietary software for research +and teaching, and share information with colleagues and students in +proprietary, even obfuscated, data formats. Contrary to the academic +ethic, proprietary software licenses restrict access to information: +preventing users from learning how a program works internally +(``reverse engineering''), limiting the number of users who may run a +piece of software, and forbidding users from running (or sometimes +even installing) a purchased copy on multiple machines. + +Restrictions on use aside, if one cannot examine a program's source +code, one cannot fully trust the output, any more than one can trust +(for purposes of scientific publication) results of a commercial +testing lab. + +\texicomment +\noindent$\phantom{.}$\hfil\vbox{\hrule width 4in}\hfil +\texicommentend + +Consider a hypothetical future world in which scholarly results are +disseminated like software. Instead of subscriptions, journals +sell licenses granting readership to a specified number of +individuals. Photocopying an article for a class or research seminar +constitutes ``piracy'', though if the institution has purchased a +sufficiently large site license the teacher or speaker may bring the +physical volume to class and project the pages onto a screen. + +Of course, reading an article is scarcely enlightening. Mathematics +papers contain only the statements of theorems. Merely opening the +journal binds the reader to a lengthy legal agreement, stating that +theorems be used only for specific purposes and threatening serious +legal consequences for attempting to discover the author's proofs. + +The actions of a single student, employee, or faculty member can +expose an institution to a costly ``journal audit'' from the +Mathematical Society of America (MSA), with the institution +responsible for legal costs if the audit reveals license violations +anywhere in the organization. + +Mathematicians who long for the Old Days when papers contained +proofs and were shared freely are dismissed as idealistic cranks +or labeled anti-business communists. Common knowledge asserts the +obvious superiority of proprietary journals, and the necessity of +licenses for keeping mathematicians gainfully employed. + +\texicomment +\noindent$\phantom{.}$\hfil\vbox{\hrule width 4in}\hfil +\texicommentend + +Back in our world, some vendors have attempted to placate opponents of +closed source with ``shared source'' licenses, under which one may +sign a non-disclosure agreement and subsequently examine source +code. In the future world analogy, a shared source agreement would +allow journal licensees to sign an NDA, then see the proofs of +theorems. Readers could thereby correct errors in proofs (benefitting +the publisher by improving the reliability of the journal), but would +be legally forbidden from using the ideas elsewhere (denying benefit +to other mathematicians). + +Legally and conceptually codifying software as a commodity ignores a +fundamental reality: Like an idea or recipe, software can be copied +without loss of the original. The perception of ``theft'' by copying +arises from an artificial belief that software has an owner who must +be monetarily compensated each time a person acquires a copy. The +nature of software does not enforce the ``sale'' model in the way +services and physical commodities do. It therefore seems +philosophically inappropriate to treat software as a commodity, and +perilous to conform the legal system to the enforcement of such a +model. + +At its best, software enhances our productivity and +creativity. Sharing software, like sharing ideas, benefits a larger +number of people without detriment to existing users. I hope this +modest program is, in conjunction with the much larger efforts of +others (especially Donald Knuth, Richard Stallman, and the many people +who have contributed to the authorship of \LaTeX\ and its packages), +useful to you in your mathematical work. + +Please visit the Free Software Foundation, at +\URL{www.fsf.org}, to learn more about free software and how +you can contribute to its development and adoption. +\index{Free software|)} + +\texinfoappendix{B}{Acknowledgments} + +\ePiX\ is built on the work of many people (unfortunately, most of +whom I am unaware). The following people have contributed, sometimes +unknowingly but always generously: + +\paragraph{Infrastructure} Donald Knuth, Conrad Kwok, Leslie Lamport, +Tim Morgan, Piet van~Oostrum, Sunil Podar, Richard Stallman, Till +Tantau, Herbert Voss, Timothy van~Zandt + +\paragraph{Enhancements} Jay Belanger, Robin Blume-Kohout, Julian +Gilbey, Marcus Hanwell, Yvon Henel, Svend Daug{\aa}rd Pedersen, Andrew +Sterian + +\paragraph{Porting and packaging} Julian Gilbey (Debian); Tsuguru Kato +(FreeBSD); Markus Dittrich, Danny van Dyk, Christian Faulhammer, +Olivier Fisette, Chris Gianelloni, Michael Hanselmann, Marcus Hanwell, +David Holm, Peter Johanson, Patrick Kursawe, Tobias Scherbaum, Markus +Ullmann (Gentoo); Guido Gonzato (RPM); Rene Rebe (T2) + +\paragraph{Debugging, advice, and other assistance} Jay Belanger, +Felipe Paulo Guazzi Bergo, Karl Berry, Robin Blume-Kohout, Patrick +Cousot, Stephen Gibson, Julian Gilbey, Dov Grobgeld, Bob Grover, Jim +Hefferon, Jacques L'helgoual, Yvon Henel, Hartmut Henkel, Herng-Jeng +Jou, Walter Kehowski, Kevin McCormick, Ross Moore, Thorsten Riess, +Alan Sill, Neel Smith, Michael Somos, Andrew Sterian, Ryszard Tanas, +Kai Trukenmueller, Torbjorn Vik, Wenguang Wang, Gabe Weaver, Mariusz +Wodzicki + +\texicomment +\begin{thebibliography}{9} +% +\bibitem{Cline} Marshall Cline, \emph{\CXX\ FAQ Lite}, \\ + \URL{http://www.parashift.com/c++-faq-lite/} +% +\bibitem{xcolor} Uwe Kern, \emph{Extending \LaTeX's color facilities: + the \code{xcolor} package}, white paper, Jan.~21, 2007 +% +\bibitem{KnR} Brian Kernighan and Dennis Ritchie, \emph{The \code{C} + Programming Language}, Second Ed., Prentice-Hall Software Series, + 1988 +% +\bibitem{GNUC} Sandra Loosemore, Richard M. Stallman, et.\ al., + \emph{The GNU \code{C}~Library Reference Manual}, GNU Press, + 2004 +% +\bibitem{Prata} Stephen Prata, \emph{\CXX\ Primer Plus}, Sams, 2002 +% +\bibitem{R} Keith Reckdahl, \emph{Using Imported Graphics in + \LaTeX2e}, Version~2.0, white paper, Dec.~15, 1997 +% +\bibitem{GNUCoding} Richard M. Stallman, et.\ al., \emph{The GNU + Coding Standards}, \\ + \URL{http://www.gnu.org/prep/standards/} +% +\bibitem{S} Bjarne Stroustrup, \emph{The \CXX\ Programming Language}, + Special Ed., Addison-Wesley, 1997 +% +\bibitem{Z} Timothy van~Zandt, \emph{PSTricks: PostScript Macros for + Generic \TeX}, Version~0.93a, white paper, Mar.~12, 1993 +% +\end{thebibliography} + +\clearpage + +\printindex + +\end{document} + +\texicommentend diff --git a/graphics/epix/doc/marker.eepic b/graphics/epix/doc/marker.eepic new file mode 100644 index 0000000000..5ee5923a3b --- /dev/null +++ b/graphics/epix/doc/marker.eepic @@ -0,0 +1,39 @@ +%% Generated from marker.xp on Tue Jan 4 15:32:18 EST 2005 by +%% ePiX-1.0.3 +%% +%% Cartesian bounding box: [0,5] x [0,1] +%% Actual size: 3.75in x 1in +%% Figure offset: right by 0in, up by 0in +%% +\setlength{\unitlength}{0.25in} +\begin{picture}(15,4)(-0,-0) +%% --- +\put(0.664176,3.77861){{\tt{CIRC}}} +\whiten\put(0,4){\makebox(0,0)[c]{{\circle{0.166044}}}} +\put(4.41418,3.77861){{\tt{SPOT}}} +\put(3.75,4){\makebox(0,0)[c]{{\circle*{0.249066}}}} +\put(8.16418,3.77861){{\tt{RING}}} +\put(7.5,4){\makebox(0,0)[c]{{\circle{0.249066}}}} +\put(11.9142,3.77861){{\tt{DOT}}} +\put(11.25,4){\makebox(0,0)[c]{{\circle*{0.166044}}}} +\put(15.6642,3.77861){{\tt{DDOT}}} +\put(15,4){\makebox(0,0)[c]{{\circle*{0.110696}}}} +\put(0.664176,1.77861){{\tt{PLUS}}} +\put(0,2){\makebox(0,0)[c]{+}} +\put(4.41418,1.77861){{\tt{OPLUS}}} +\put(3.75,2){\makebox(0,0)[c]{$\oplus$}} +\put(8.16418,1.77861){{\tt{TIMES}}} +\put(7.5,2){\makebox(0,0)[c]{$\times$}} +\put(11.9142,1.77861){{\tt{OTIMES}}} +\put(11.25,2){\makebox(0,0)[c]{$\otimes$}} +\put(0.664176,-0.221392){{\tt{DIAMOND}}} +\put(0,0){\makebox(0,0)[c]{$\diamond$}} +\put(4.41418,-0.221392){{\tt{UP}}} +\put(3.75,0){\makebox(0,0)[c]{$\bigtriangleup$}} +\put(8.16418,-0.221392){{\tt{DOWN}}} +\put(7.5,0){\makebox(0,0)[c]{$\bigtriangledown$}} +\put(11.9142,-0.221392){{\tt{BOX}}} +\put(11.25,0){\makebox(0,0)[c]{\rule{3pt}{3pt}}} +\put(15.6642,-0.221392){{\tt{BBOX}}} +\put(15,0){\makebox(0,0)[c]{\rule{2pt}{2pt}}} +\end{picture} diff --git a/graphics/epix/doc/marker.xp b/graphics/epix/doc/marker.xp new file mode 100644 index 0000000000..f1569c1476 --- /dev/null +++ b/graphics/epix/doc/marker.xp @@ -0,0 +1,68 @@ +/* -*-ePiX-*- */ +/* marker.c -- types of marker */ +#include "epix.h" +using namespace ePiX; + +int main() +{ + unitlength("0.25in"); + picture(P(15,4)); + bounding_box(P(0,0), P(5,1)); + // offset(P(-1,0)); + + begin(); + + double x1 = x_min; + double x2 = x_min + x_size/4; + double x3 = x_min + 2*x_size/4; + double x4 = x_min + 3*x_size/4; + double x5 = x_max; + + double y1 = y_min; + double y2 = y_min + y_size/2; + double y3 = y_max; + + label(P(x1,y3), P(12,-4), "{\\tt{CIRC}}"); + circ(P(x1,y3)); + + label(P(x2,y3), P(12,-4), "{\\tt{SPOT}}"); + spot(P(x2,y3)); + + label(P(x3,y3), P(12,-4), "{\\tt{RING}}"); + ring(P(x3,y3)); + + label(P(x4,y3), P(12,-4), "{\\tt{DOT}}"); + dot(P(x4,y3)); + + label(P(x5,y3), P(12,-4), "{\\tt{DDOT}}"); + ddot(P(x5,y3)); + + label(P(x1,y2), P(12,-4), "{\\tt{PLUS}}"); + marker(P(x1,y2), PLUS); + + label(P(x2,y2), P(12,-4), "{\\tt{OPLUS}}"); + marker(P(x2,y2), OPLUS); + + label(P(x3,y2), P(12,-4), "{\\tt{TIMES}}"); + marker(P(x3,y2), TIMES); + + label(P(x4,y2), P(12,-4), "{\\tt{OTIMES}}"); + marker(P(x4,y2), OTIMES); + + label(P(x1,y1), P(12,-4), "{\\tt{DIAMOND}}"); + marker(P(x1,y1), DIAMOND); + + label(P(x2,y1), P(12,-4), "{\\tt{UP}}"); + marker(P(x2,y1),UP); + + label(P(x3,y1), P(12,-4), "{\\tt{DOWN}}"); + marker(P(x3,y1), DOWN); + + label(P(x4,y1), P(12,-4), "{\\tt{BOX}}"); + marker(P(x4,y1), BOX); + + label(P(x5,y1), P(12,-4), "{\\tt{BBOX}}"); + marker(P(x5,y1), BBOX); + + end(); +} diff --git a/graphics/epix/doc/my_code.cc b/graphics/epix/doc/my_code.cc new file mode 100644 index 0000000000..b7365fa63c --- /dev/null +++ b/graphics/epix/doc/my_code.cc @@ -0,0 +1,15 @@ +/* my_code.cc */ +#include "my_code.h" +using namespace ePiX; + +namespace Mine { + double lorentz_norm(P arg) + { + double x=arg.x1(), y=arg.x2(), z=arg.x3(); // extract coords + return -x*x + y*y + z*z; + } + bool spacelike(P arg) + { + return (lorentz_norm(arg) > 0); + } +} // end of namespace diff --git a/graphics/epix/doc/my_code.h b/graphics/epix/doc/my_code.h new file mode 100644 index 0000000000..229e80dbf4 --- /dev/null +++ b/graphics/epix/doc/my_code.h @@ -0,0 +1,10 @@ +/* my_code.h */ +#include <cmath> // standard library math header +#include "epix.h" // ePiX header +using ePiX::P; + +namespace Mine { // to avoid name conflicts + // functions for special relativity + double lorentz_norm(P); + bool spacelike(P); +} // end of namespace diff --git a/graphics/epix/doc/objects.eepic b/graphics/epix/doc/objects.eepic new file mode 100644 index 0000000000..9b17600895 --- /dev/null +++ b/graphics/epix/doc/objects.eepic @@ -0,0 +1,412 @@ +%% Generated from objects.xp on Thu Jun 28 14:55:45 EDT 2007 by +%% ePiX-1.1.6 +%% +%% Cartesian bounding box: [0,5] x [0,2] +%% Actual size: 3.75 x 1.5in +%% Figure offset: left by 0in, down by 0in +%% +\xdefinecolor{rgb_000000}{rgb}{0,0,0} +\xdefinecolor{rgb_e5e5e5}{rgb}{0.898039,0.898039,0.898039} +\xdefinecolor{rgb_ffffff}{rgb}{1,1,1} +\setlength{\unitlength}{1in} +\begin{picture}(3.75,1.5)(-0,-0) +\path(0.675,0.75)(2.325,0.75)(1.5,1.125)(0.675,0.75) +%% +\path(3.1875,1.125)(3.18724,1.13481)(3.18647,1.1446) + (3.18519,1.15433)(3.1834,1.16398)(3.18111,1.17353)(3.17832,1.18294) + (3.17505,1.19219)(3.17129,1.20126)(3.16706,1.21012) + (3.16238,1.21875)(3.15725,1.22712)(3.15169,1.23521)(3.14571,1.243) + (3.13934,1.25046)(3.13258,1.25758)(3.12546,1.26434)(3.118,1.27071) + (3.11021,1.27669)(3.10212,1.28225)(3.09375,1.28738) + (3.08512,1.29206)(3.07626,1.29629)(3.06719,1.30005) + (3.05794,1.30332)(3.04853,1.30611)(3.03898,1.3084)(3.02933,1.31019) + (3.0196,1.31147)(3.00981,1.31224)(3,1.3125)(2.99019,1.31224) + (2.9804,1.31147)(2.97067,1.31019)(2.96102,1.3084)(2.95147,1.30611) + (2.94206,1.30332)(2.93281,1.30005)(2.92374,1.29629) + (2.91488,1.29206)(2.90625,1.28738)(2.89788,1.28225) + (2.88979,1.27669)(2.882,1.27071)(2.87454,1.26434)(2.86742,1.25758) + (2.86066,1.25046)(2.85429,1.243)(2.84831,1.23521)(2.84275,1.22712) + (2.83762,1.21875)(2.83294,1.21012)(2.82871,1.20126) + (2.82495,1.19219)(2.82168,1.18294)(2.81889,1.17353)(2.8166,1.16398) + (2.81481,1.15433)(2.81353,1.1446)(2.81276,1.13481)(2.8125,1.125) + (2.81276,1.11519)(2.81353,1.1054)(2.81481,1.09567)(2.8166,1.08602) + (2.81889,1.07647)(2.82168,1.06706)(2.82495,1.05781) + (2.82871,1.04874)(2.83294,1.03988)(2.83762,1.03125) + (2.84275,1.02288)(2.84831,1.01479)(2.85429,1.007)(2.86066,0.999538) + (2.86742,0.992417)(2.87454,0.98566)(2.882,0.979285) + (2.88979,0.973309)(2.89788,0.967749)(2.90625,0.96262) + (2.91488,0.957936)(2.92374,0.95371)(2.93281,0.949954) + (2.94206,0.946677)(2.95147,0.943889)(2.96102,0.941597) + (2.97067,0.939808)(2.9804,0.938527)(2.99019,0.937757)(3,0.9375) + (3.00981,0.937757)(3.0196,0.938527)(3.02933,0.939808) + (3.03898,0.941597)(3.04853,0.943889)(3.05794,0.946677) + (3.06719,0.949954)(3.07626,0.95371)(3.08512,0.957936) + (3.09375,0.96262)(3.10212,0.967749)(3.11021,0.973309) + (3.118,0.979285)(3.12546,0.98566)(3.13258,0.992417) + (3.13934,0.999538)(3.14571,1.007)(3.15169,1.01479)(3.15725,1.02288) + (3.16238,1.03125)(3.16706,1.03988)(3.17129,1.04874) + (3.17505,1.05781)(3.17832,1.06706)(3.18111,1.07647)(3.1834,1.08602) + (3.18519,1.09567)(3.18647,1.1054)(3.18724,1.11519)(3.1875,1.125) +%% +\path(0.75,0)(2.25,0)(2.25,0.75)(0.75,0.75)(0.75,0) +%% +\color{rgb_e5e5e5}% +\path(2.025,0.00550459)(1.725,0.00550459) +\path(2.025,0.0110092)(1.725,0.0110092) +\path(2.025,0.0165138)(1.725,0.0165138) +\path(2.025,0.0220183)(1.725,0.0220183) +\path(2.025,0.0275229)(1.725,0.0275229) +\path(2.025,0.0330275)(1.725,0.0330275) +\path(2.025,0.0385321)(1.725,0.0385321) +\path(2.025,0.0440367)(1.725,0.0440367) +\path(2.025,0.0495413)(1.725,0.0495413) +\path(2.025,0.0550459)(1.725,0.0550459) +\path(2.025,0.0605505)(1.725,0.0605505) +\path(2.025,0.066055)(1.725,0.066055) +\path(2.025,0.0715596)(1.725,0.0715596) +\path(2.025,0.0770642)(1.725,0.0770642) +\path(2.025,0.0825688)(1.725,0.0825688) +\path(2.025,0.0880734)(1.725,0.0880734) +\path(2.025,0.093578)(1.725,0.093578) +\path(2.025,0.0990826)(1.725,0.0990826) +\path(2.025,0.104587)(1.725,0.104587) +\path(2.025,0.110092)(1.725,0.110092) +\path(2.025,0.115596)(1.725,0.115596) +\path(2.025,0.121101)(1.725,0.121101) +\path(2.025,0.126606)(1.725,0.126606) +\path(2.025,0.13211)(1.725,0.13211) +\path(2.025,0.137615)(1.725,0.137615) +\path(2.025,0.143119)(1.725,0.143119) +\path(2.025,0.148624)(1.725,0.148624) +\path(2.025,0.154128)(1.725,0.154128) +\path(2.025,0.159633)(1.725,0.159633) +\path(2.025,0.165138)(1.725,0.165138) +\path(2.025,0.170642)(1.725,0.170642) +\path(2.025,0.176147)(1.725,0.176147) +\path(2.025,0.181651)(1.725,0.181651) +\path(2.025,0.187156)(1.725,0.187156) +\path(2.025,0.192661)(1.725,0.192661) +\path(2.025,0.198165)(1.725,0.198165) +\path(2.025,0.20367)(1.725,0.20367) +\path(2.025,0.209174)(1.725,0.209174) +\path(2.025,0.214679)(1.725,0.214679) +\path(2.025,0.220183)(1.725,0.220183) +\path(2.025,0.225688)(1.725,0.225688) +\path(2.025,0.231193)(1.725,0.231193) +\path(2.025,0.236697)(1.725,0.236697) +\path(2.025,0.242202)(1.725,0.242202) +\path(2.025,0.247706)(1.725,0.247706) +\path(2.025,0.253211)(1.725,0.253211) +\path(2.025,0.258716)(1.725,0.258716) +\path(2.025,0.26422)(1.725,0.26422) +\path(2.025,0.269725)(1.725,0.269725) +\path(2.025,0.275229)(1.725,0.275229) +\path(2.025,0.280734)(1.725,0.280734) +\path(2.025,0.286239)(1.725,0.286239) +\path(2.025,0.291743)(1.725,0.291743) +\path(2.025,0.297248)(1.725,0.297248) +\path(2.025,0.302752)(1.725,0.302752) +\path(2.025,0.308257)(1.725,0.308257) +\path(2.025,0.313761)(1.725,0.313761) +\path(2.025,0.319266)(1.725,0.319266) +\path(2.025,0.324771)(1.725,0.324771) +\path(2.025,0.330275)(1.725,0.330275) +\path(2.025,0.33578)(1.725,0.33578) +\path(2.025,0.341284)(1.725,0.341284) +\path(2.025,0.346789)(1.725,0.346789) +\path(2.025,0.352294)(1.725,0.352294) +\path(2.025,0.357798)(1.725,0.357798) +\path(2.025,0.363303)(1.725,0.363303) +\path(2.025,0.368807)(1.725,0.368807) +\path(2.025,0.374312)(1.725,0.374312) +\path(2.025,0.379817)(1.725,0.379817) +\path(2.025,0.385321)(1.725,0.385321) +\path(2.025,0.390826)(1.725,0.390826) +\path(2.025,0.39633)(1.725,0.39633) +\path(2.025,0.401835)(1.725,0.401835) +\path(2.025,0.407339)(1.725,0.407339) +\path(2.025,0.412844)(1.725,0.412844) +\path(2.025,0.418349)(1.725,0.418349) +\path(2.025,0.423853)(1.725,0.423853) +\path(2.025,0.429358)(1.725,0.429358) +\path(2.025,0.434862)(1.725,0.434862) +\path(2.025,0.440367)(1.725,0.440367) +\path(2.025,0.445872)(1.725,0.445872) +\path(2.025,0.451376)(1.725,0.451376) +\path(2.025,0.456881)(1.725,0.456881) +\path(2.025,0.462385)(1.725,0.462385) +\path(2.025,0.46789)(1.725,0.46789) +\path(2.025,0.473394)(1.725,0.473394) +\path(2.025,0.478899)(1.725,0.478899) +\path(2.025,0.484404)(1.725,0.484404) +\path(2.025,0.489908)(1.725,0.489908) +\path(2.025,0.495413)(1.725,0.495413) +\path(2.025,0.500917)(1.725,0.500917) +\path(2.025,0.506422)(1.725,0.506422) +\path(2.025,0.511927)(1.725,0.511927) +\path(2.025,0.517431)(1.725,0.517431) +\path(2.025,0.522936)(1.725,0.522936) +\path(2.025,0.52844)(1.725,0.52844) +\path(2.025,0.533945)(1.725,0.533945) +\path(2.025,0.53945)(1.725,0.53945) +\path(2.025,0.544954)(1.725,0.544954) +\path(2.025,0.550459)(1.725,0.550459) +\path(2.025,0.555963)(1.725,0.555963) +\path(2.025,0.561468)(1.725,0.561468) +\path(2.025,0.566972)(1.725,0.566972) +\path(2.025,0.572477)(1.725,0.572477) +\path(2.025,0.577982)(1.725,0.577982) +\path(2.025,0.583486)(1.725,0.583486) +\path(2.025,0.588991)(1.725,0.588991) +\path(2.025,0.594495)(1.725,0.594495) +\path(2.01955,0.6)(2.01955,0) +\path(2.01409,0.6)(2.01409,0) +\path(2.00864,0.6)(2.00864,0) +\path(2.00318,0.6)(2.00318,0) +\path(1.99773,0.6)(1.99773,0) +\path(1.99227,0.6)(1.99227,0) +\path(1.98682,0.6)(1.98682,0) +\path(1.98136,0.6)(1.98136,0) +\path(1.97591,0.6)(1.97591,0) +\path(1.97045,0.6)(1.97045,0) +\path(1.965,0.6)(1.965,0) +\path(1.95955,0.6)(1.95955,0) +\path(1.95409,0.6)(1.95409,0) +\path(1.94864,0.6)(1.94864,0) +\path(1.94318,0.6)(1.94318,0) +\path(1.93773,0.6)(1.93773,0) +\path(1.93227,0.6)(1.93227,0) +\path(1.92682,0.6)(1.92682,0) +\path(1.92136,0.6)(1.92136,0) +\path(1.91591,0.6)(1.91591,0) +\path(1.91045,0.6)(1.91045,0) +\path(1.905,0.6)(1.905,0) +\path(1.89955,0.6)(1.89955,0) +\path(1.89409,0.6)(1.89409,0) +\path(1.88864,0.6)(1.88864,0) +\path(1.88318,0.6)(1.88318,0) +\path(1.87773,0.6)(1.87773,0) +\path(1.87227,0.6)(1.87227,0) +\path(1.86682,0.6)(1.86682,0) +\path(1.86136,0.6)(1.86136,0) +\path(1.85591,0.6)(1.85591,0) +\path(1.85045,0.6)(1.85045,0) +\path(1.845,0.6)(1.845,0) +\path(1.83955,0.6)(1.83955,0) +\path(1.83409,0.6)(1.83409,0) +\path(1.82864,0.6)(1.82864,0) +\path(1.82318,0.6)(1.82318,0) +\path(1.81773,0.6)(1.81773,0) +\path(1.81227,0.6)(1.81227,0) +\path(1.80682,0.6)(1.80682,0) +\path(1.80136,0.6)(1.80136,0) +\path(1.79591,0.6)(1.79591,0) +\path(1.79045,0.6)(1.79045,0) +\path(1.785,0.6)(1.785,0) +\path(1.77955,0.6)(1.77955,0) +\path(1.77409,0.6)(1.77409,0) +\path(1.76864,0.6)(1.76864,0) +\path(1.76318,0.6)(1.76318,0) +\path(1.75773,0.6)(1.75773,0) +\path(1.75227,0.6)(1.75227,0) +\path(1.74682,0.6)(1.74682,0) +\path(1.74136,0.6)(1.74136,0) +\path(1.73591,0.6)(1.73591,0) +\path(1.73045,0.6)(1.73045,0) +\color{rgb_000000}% +\path(1.725,0)(2.025,0)(2.025,0.6)(1.725,0.6)(1.725,0) +%% +\color{rgb_ffffff}% +\path(1.4941,0.45)(1.5,0.434819) +\path(1.48819,0.45)(1.5,0.419637) +\path(1.48229,0.45)(1.5,0.404456) +\path(1.47639,0.45)(1.5,0.389275) +\path(1.47049,0.45)(1.5,0.374093) +\path(1.46458,0.45)(1.5,0.358912) +\path(1.45868,0.45)(1.5,0.343731) +\path(1.45278,0.45)(1.5,0.32855) +\path(1.44688,0.45)(1.5,0.313368) +\path(1.44097,0.45)(1.5,0.298187) +\path(1.43507,0.45)(1.5,0.283006) +\path(1.42917,0.45)(1.5,0.267824) +\path(1.42327,0.45)(1.5,0.252643) +\path(1.41736,0.45)(1.5,0.237462) +\path(1.41146,0.45)(1.5,0.22228) +\path(1.40556,0.45)(1.5,0.207099) +\path(1.39966,0.45)(1.5,0.191918) +\path(1.39375,0.45)(1.5,0.176737) +\path(1.38785,0.45)(1.5,0.161555) +\path(1.38195,0.45)(1.49859,0.15) +\path(1.37605,0.45)(1.49269,0.15) +\path(1.37014,0.45)(1.48679,0.15) +\path(1.36424,0.45)(1.48088,0.15) +\path(1.35834,0.45)(1.47498,0.15) +\path(1.35244,0.45)(1.46908,0.15) +\path(1.34653,0.45)(1.46318,0.15) +\path(1.34063,0.45)(1.45727,0.15) +\path(1.33473,0.45)(1.45137,0.15) +\path(1.32883,0.45)(1.44547,0.15) +\path(1.32292,0.45)(1.43957,0.15) +\path(1.31702,0.45)(1.43366,0.15) +\path(1.31112,0.45)(1.42776,0.15) +\path(1.30522,0.45)(1.42186,0.15) +\path(1.29931,0.45)(1.41596,0.15) +\path(1.29341,0.45)(1.41005,0.15) +\path(1.28751,0.45)(1.40415,0.15) +\path(1.28161,0.45)(1.39825,0.15) +\path(1.2757,0.45)(1.39235,0.15) +\path(1.2698,0.45)(1.38644,0.15) +\path(1.2639,0.45)(1.38054,0.15) +\path(1.258,0.45)(1.37464,0.15) +\path(1.25209,0.45)(1.36874,0.15) +\path(1.24619,0.45)(1.36283,0.15) +\path(1.24029,0.45)(1.35693,0.15) +\path(1.23439,0.45)(1.35103,0.15) +\path(1.22848,0.45)(1.34513,0.15) +\path(1.22258,0.45)(1.33922,0.15) +\path(1.21668,0.45)(1.33332,0.15) +\path(1.21078,0.45)(1.32742,0.15) +\path(1.20487,0.45)(1.32152,0.15) +\path(1.19897,0.45)(1.31561,0.15) +\path(1.19307,0.45)(1.30971,0.15) +\path(1.18717,0.45)(1.30381,0.15) +\path(1.18126,0.45)(1.29791,0.15) +\path(1.17536,0.45)(1.292,0.15) +\path(1.16946,0.45)(1.2861,0.15) +\path(1.16356,0.45)(1.2802,0.15) +\path(1.15765,0.45)(1.2743,0.15) +\path(1.15175,0.45)(1.26839,0.15) +\path(1.14585,0.45)(1.26249,0.15) +\path(1.13995,0.45)(1.25659,0.15) +\path(1.13404,0.45)(1.25069,0.15) +\path(1.12814,0.45)(1.24478,0.15) +\path(1.12224,0.45)(1.23888,0.15) +\path(1.11634,0.45)(1.23298,0.15) +\path(1.11043,0.45)(1.22708,0.15) +\path(1.10453,0.45)(1.22117,0.15) +\path(1.09863,0.45)(1.21527,0.15) +\path(1.09273,0.45)(1.20937,0.15) +\path(1.08682,0.45)(1.20347,0.15) +\path(1.08092,0.45)(1.19756,0.15) +\path(1.07502,0.45)(1.19166,0.15) +\path(1.06912,0.45)(1.18576,0.15) +\path(1.06321,0.45)(1.17986,0.15) +\path(1.05731,0.45)(1.17395,0.15) +\path(1.05141,0.45)(1.16805,0.15) +\path(1.05,0.438445)(1.16215,0.15) +\path(1.05,0.423263)(1.15625,0.15) +\path(1.05,0.408082)(1.15034,0.15) +\path(1.05,0.392901)(1.14444,0.15) +\path(1.05,0.37772)(1.13854,0.15) +\path(1.05,0.362538)(1.13264,0.15) +\path(1.05,0.347357)(1.12673,0.15) +\path(1.05,0.332176)(1.12083,0.15) +\path(1.05,0.316994)(1.11493,0.15) +\path(1.05,0.301813)(1.10903,0.15) +\path(1.05,0.286632)(1.10312,0.15) +\path(1.05,0.27145)(1.09722,0.15) +\path(1.05,0.256269)(1.09132,0.15) +\path(1.05,0.241088)(1.08542,0.15) +\path(1.05,0.225907)(1.07951,0.15) +\path(1.05,0.210725)(1.07361,0.15) +\path(1.05,0.195544)(1.06771,0.15) +\path(1.05,0.180363)(1.06181,0.15) +\path(1.05,0.165181)(1.0559,0.15) +\path(1.05,0.444063)(1.06527,0.45) +\path(1.05,0.438126)(1.08054,0.45) +\path(1.05,0.432189)(1.09581,0.45) +\path(1.05,0.426252)(1.11108,0.45) +\path(1.05,0.420315)(1.12635,0.45) +\path(1.05,0.414378)(1.14162,0.45) +\path(1.05,0.408441)(1.15689,0.45) +\path(1.05,0.402504)(1.17216,0.45) +\path(1.05,0.396567)(1.18743,0.45) +\path(1.05,0.39063)(1.2027,0.45) +\path(1.05,0.384693)(1.21797,0.45) +\path(1.05,0.378756)(1.23324,0.45) +\path(1.05,0.372819)(1.24851,0.45) +\path(1.05,0.366882)(1.26378,0.45) +\path(1.05,0.360945)(1.27905,0.45) +\path(1.05,0.355008)(1.29432,0.45) +\path(1.05,0.349071)(1.30959,0.45) +\path(1.05,0.343134)(1.32486,0.45) +\path(1.05,0.337197)(1.34013,0.45) +\path(1.05,0.33126)(1.3554,0.45) +\path(1.05,0.325323)(1.37067,0.45) +\path(1.05,0.319386)(1.38594,0.45) +\path(1.05,0.313449)(1.40121,0.45) +\path(1.05,0.307512)(1.41648,0.45) +\path(1.05,0.301575)(1.43175,0.45) +\path(1.05,0.295638)(1.44702,0.45) +\path(1.05,0.289701)(1.46229,0.45) +\path(1.05,0.283764)(1.47756,0.45) +\path(1.05,0.277827)(1.49283,0.45) +\path(1.05,0.27189)(1.5,0.44685) +\path(1.05,0.265953)(1.5,0.440913) +\path(1.05,0.260016)(1.5,0.434976) +\path(1.05,0.254079)(1.5,0.429039) +\path(1.05,0.248142)(1.5,0.423102) +\path(1.05,0.242205)(1.5,0.417165) +\path(1.05,0.236268)(1.5,0.411228) +\path(1.05,0.230331)(1.5,0.405291) +\path(1.05,0.224394)(1.5,0.399354) +\path(1.05,0.218457)(1.5,0.393417) +\path(1.05,0.21252)(1.5,0.38748) +\path(1.05,0.206583)(1.5,0.381543) +\path(1.05,0.200646)(1.5,0.375606) +\path(1.05,0.194709)(1.5,0.369669) +\path(1.05,0.188772)(1.5,0.363732) +\path(1.05,0.182835)(1.5,0.357795) +\path(1.05,0.176898)(1.5,0.351858) +\path(1.05,0.170961)(1.5,0.345921) +\path(1.05,0.165024)(1.5,0.339984) +\path(1.05,0.159087)(1.5,0.334047) +\path(1.05,0.15315)(1.5,0.32811) +\path(1.05717,0.15)(1.5,0.322173) +\path(1.07244,0.15)(1.5,0.316236) +\path(1.08771,0.15)(1.5,0.310299) +\path(1.10298,0.15)(1.5,0.304362) +\path(1.11825,0.15)(1.5,0.298425) +\path(1.13352,0.15)(1.5,0.292488) +\path(1.14879,0.15)(1.5,0.286551) +\path(1.16406,0.15)(1.5,0.280614) +\path(1.17933,0.15)(1.5,0.274677) +\path(1.1946,0.15)(1.5,0.26874) +\path(1.20987,0.15)(1.5,0.262803) +\path(1.22514,0.15)(1.5,0.256866) +\path(1.24041,0.15)(1.5,0.250929) +\path(1.25568,0.15)(1.5,0.244992) +\path(1.27095,0.15)(1.5,0.239055) +\path(1.28622,0.15)(1.5,0.233118) +\path(1.30149,0.15)(1.5,0.227181) +\path(1.31676,0.15)(1.5,0.221244) +\path(1.33203,0.15)(1.5,0.215307) +\path(1.3473,0.15)(1.5,0.20937) +\path(1.36257,0.15)(1.5,0.203433) +\path(1.37784,0.15)(1.5,0.197496) +\path(1.39311,0.15)(1.5,0.191559) +\path(1.40838,0.15)(1.5,0.185622) +\path(1.42365,0.15)(1.5,0.179685) +\path(1.43892,0.15)(1.5,0.173748) +\path(1.45419,0.15)(1.5,0.167811) +\path(1.46946,0.15)(1.5,0.161874) +\path(1.48473,0.15)(1.5,0.155937) +\color{rgb_000000}% +\path(1.05,0.15)(1.5,0.15)(1.5,0.45)(1.05,0.45)(1.05,0.15) +%% +\allinethickness{0.8pt}% +\path(1.05,0.15)(1.05,0.45) +%% +\path(1.275,0.15)(1.275,0.45) +%% +\path(1.5,0.15)(1.5,0.45) +%% +\path(1.05,0.15)(1.5,0.15) +%% +\path(1.05,0.3)(1.5,0.3) +%% +\path(1.05,0.45)(1.5,0.45) +%% +\path(0,0)(3.75,0) +%% +\end{picture} diff --git a/graphics/epix/doc/objects.xp b/graphics/epix/doc/objects.xp new file mode 100644 index 0000000000..d0828f0b94 --- /dev/null +++ b/graphics/epix/doc/objects.xp @@ -0,0 +1,33 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +int main() +{ + picture(P(0,0), P(5,2), "3.75 x 1.5in"); + + begin(); + + // roof + triangle(P(0.9, 1), P(3.1, 1), P(2, 1.5)); // vertices + + // sun + circle(P(4,1.5), 0.25); // center and radius + + // house + rect(P(1,0), P(3,1)); // opposite corners + // grid(P(1,0), P(3,1), 1, 10); // corners, numbers of subdivisions + + // door + fill(Black(0.1)); + rect(P(2.3,0), P(2.7,0.8)); // corners + + fill(White()); + // window + rect(P(1.4,0.2), P(2, 0.6)); + bold(); + grid(P(1.4,0.2), P(2, 0.6), 2, 2); + + line(P(xmin(),0), P(xmax(),0)); + end(); +} diff --git a/graphics/epix/doc/pathstyle.eepic b/graphics/epix/doc/pathstyle.eepic new file mode 100644 index 0000000000..531523bf45 --- /dev/null +++ b/graphics/epix/doc/pathstyle.eepic @@ -0,0 +1,225 @@ +%% Generated from pathstyle.xp on Tue Jul 17 15:01:22 EDT 2007 by +%% ePiX-1.1.8 +%% +%% Cartesian bounding box: [0,4] x [0,4] +%% Actual size: 4 x 1in +%% Figure offset: left by 0in, down by 0in +%% +\xdefinecolor{rgb_000000}{rgb}{0,0,0} +\setlength{\unitlength}{1in} +\begin{picture}(4,1)(-0,-0) +\path(0,1)(0.0394737,1) +\path(0.118421,1)(0.157895,1) +\path(0.157895,1)(0.197368,1) +\path(0.276316,1)(0.315789,1) +\path(0.315789,1)(0.355263,1) +\path(0.434211,1)(0.473684,1) +\path(0.473684,1)(0.513158,1) +\path(0.592105,1)(0.631579,1) +\path(0.631579,1)(0.671053,1) +\path(0.75,1)(0.789474,1) +\path(0.789474,1)(0.828947,1) +\path(0.907895,1)(0.947368,1) +\path(0.947368,1)(0.986842,1) +\path(1.06579,1)(1.10526,1) +\path(1.10526,1)(1.14474,1) +\path(1.22368,1)(1.26316,1) +\path(1.26316,1)(1.30263,1) +\path(1.38158,1)(1.42105,1) +\path(1.42105,1)(1.46053,1) +\path(1.53947,1)(1.57895,1) +\path(1.57895,1)(1.61842,1) +\path(1.69737,1)(1.73684,1) +\path(1.73684,1)(1.77632,1) +\path(1.85526,1)(1.89474,1) +\path(1.89474,1)(1.93421,1) +\path(2.01316,1)(2.05263,1) +\path(2.05263,1)(2.09211,1) +\path(2.17105,1)(2.21053,1) +\path(2.21053,1)(2.25,1) +\path(2.32895,1)(2.36842,1) +\path(2.36842,1)(2.40789,1) +\path(2.48684,1)(2.52632,1) +\path(2.52632,1)(2.56579,1) +\path(2.64474,1)(2.68421,1) +\path(2.68421,1)(2.72368,1) +\path(2.80263,1)(2.84211,1) +\path(2.84211,1)(2.88158,1) +\path(2.96053,1)(3,1) +\put(3.05535,1){\makebox(0,0)[l]{\code{line\_style("-\ \ -")}}} +\path(0,0.75)(0.0263158,0.75) +\path(0.131579,0.75)(0.157895,0.75) +\path(0.157895,0.75)(0.184211,0.75) +\path(0.289474,0.75)(0.315789,0.75) +\path(0.315789,0.75)(0.342105,0.75) +\path(0.447368,0.75)(0.473684,0.75) +\path(0.473684,0.75)(0.5,0.75) +\path(0.605263,0.75)(0.631579,0.75) +\path(0.631579,0.75)(0.657895,0.75) +\path(0.763158,0.75)(0.789474,0.75) +\path(0.789474,0.75)(0.815789,0.75) +\path(0.921053,0.75)(0.947368,0.75) +\path(0.947368,0.75)(0.973684,0.75) +\path(1.07895,0.75)(1.10526,0.75) +\path(1.10526,0.75)(1.13158,0.75) +\path(1.23684,0.75)(1.26316,0.75) +\path(1.26316,0.75)(1.28947,0.75) +\path(1.39474,0.75)(1.42105,0.75) +\path(1.42105,0.75)(1.44737,0.75) +\path(1.55263,0.75)(1.57895,0.75) +\path(1.57895,0.75)(1.60526,0.75) +\path(1.71053,0.75)(1.73684,0.75) +\path(1.73684,0.75)(1.76316,0.75) +\path(1.86842,0.75)(1.89474,0.75) +\path(1.89474,0.75)(1.92105,0.75) +\path(2.02632,0.75)(2.05263,0.75) +\path(2.05263,0.75)(2.07895,0.75) +\path(2.18421,0.75)(2.21053,0.75) +\path(2.21053,0.75)(2.23684,0.75) +\path(2.34211,0.75)(2.36842,0.75) +\path(2.36842,0.75)(2.39474,0.75) +\path(2.5,0.75)(2.52632,0.75) +\path(2.52632,0.75)(2.55263,0.75) +\path(2.65789,0.75)(2.68421,0.75) +\path(2.68421,0.75)(2.71053,0.75) +\path(2.81579,0.75)(2.84211,0.75) +\path(2.84211,0.75)(2.86842,0.75) +\path(2.97368,0.75)(3,0.75) +\put(3.05535,0.75){\makebox(0,0)[l]{\code{line\_style("-\ \ \ \ -")}}} +\put(0.0789474,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(0.236842,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(0.394737,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(0.552632,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(0.710526,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(0.868421,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(1.02632,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(1.18421,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(1.34211,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(1.5,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(1.65789,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(1.81579,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(1.97368,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(2.13158,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(2.28947,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(2.44737,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(2.60526,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(2.76316,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(2.92105,0.5){\makebox(0,0){\circle{0.0055348}}} +\put(3.05535,0.5){\makebox(0,0)[l]{\code{line\_style(" .\ ")}}} +\path(0,0.25)(0.0315789,0.25) +\put(0.0789474,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(0.126316,0.25)(0.157895,0.25) +\path(0.157895,0.25)(0.189474,0.25) +\put(0.236842,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(0.284211,0.25)(0.315789,0.25) +\path(0.315789,0.25)(0.347368,0.25) +\put(0.394737,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(0.442105,0.25)(0.473684,0.25) +\path(0.473684,0.25)(0.505263,0.25) +\put(0.552632,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(0.6,0.25)(0.631579,0.25) +\path(0.631579,0.25)(0.663158,0.25) +\put(0.710526,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(0.757895,0.25)(0.789474,0.25) +\path(0.789474,0.25)(0.821053,0.25) +\put(0.868421,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(0.915789,0.25)(0.947368,0.25) +\path(0.947368,0.25)(0.978947,0.25) +\put(1.02632,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(1.07368,0.25)(1.10526,0.25) +\path(1.10526,0.25)(1.13684,0.25) +\put(1.18421,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(1.23158,0.25)(1.26316,0.25) +\path(1.26316,0.25)(1.29474,0.25) +\put(1.34211,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(1.38947,0.25)(1.42105,0.25) +\path(1.42105,0.25)(1.45263,0.25) +\put(1.5,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(1.54737,0.25)(1.57895,0.25) +\path(1.57895,0.25)(1.61053,0.25) +\put(1.65789,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(1.70526,0.25)(1.73684,0.25) +\path(1.73684,0.25)(1.76842,0.25) +\put(1.81579,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(1.86316,0.25)(1.89474,0.25) +\path(1.89474,0.25)(1.92632,0.25) +\put(1.97368,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(2.02105,0.25)(2.05263,0.25) +\path(2.05263,0.25)(2.08421,0.25) +\put(2.13158,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(2.17895,0.25)(2.21053,0.25) +\path(2.21053,0.25)(2.24211,0.25) +\put(2.28947,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(2.33684,0.25)(2.36842,0.25) +\path(2.36842,0.25)(2.4,0.25) +\put(2.44737,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(2.49474,0.25)(2.52632,0.25) +\path(2.52632,0.25)(2.55789,0.25) +\put(2.60526,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(2.65263,0.25)(2.68421,0.25) +\path(2.68421,0.25)(2.71579,0.25) +\put(2.76316,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(2.81053,0.25)(2.84211,0.25) +\path(2.84211,0.25)(2.87368,0.25) +\put(2.92105,0.25){\makebox(0,0){\circle{0.0055348}}} +\path(2.96842,0.25)(3,0.25) +\put(3.05535,0.25){\makebox(0,0)[l]{\code{line\_style("-\ .\ -")}}} +\put(0.0157895,0){\makebox(0,0){\circle{0.0055348}}} +\path(0.0631579,0)(0.0947368,0) +\put(0.142105,0){\makebox(0,0){\circle{0.0055348}}} +\put(0.173684,0){\makebox(0,0){\circle{0.0055348}}} +\path(0.221053,0)(0.252632,0) +\put(0.3,0){\makebox(0,0){\circle{0.0055348}}} +\put(0.331579,0){\makebox(0,0){\circle{0.0055348}}} +\path(0.378947,0)(0.410526,0) +\put(0.457895,0){\makebox(0,0){\circle{0.0055348}}} +\put(0.489474,0){\makebox(0,0){\circle{0.0055348}}} +\path(0.536842,0)(0.568421,0) +\put(0.615789,0){\makebox(0,0){\circle{0.0055348}}} +\put(0.647368,0){\makebox(0,0){\circle{0.0055348}}} +\path(0.694737,0)(0.726316,0) +\put(0.773684,0){\makebox(0,0){\circle{0.0055348}}} +\put(0.805263,0){\makebox(0,0){\circle{0.0055348}}} +\path(0.852632,0)(0.884211,0) +\put(0.931579,0){\makebox(0,0){\circle{0.0055348}}} +\put(0.963158,0){\makebox(0,0){\circle{0.0055348}}} +\path(1.01053,0)(1.04211,0) +\put(1.08947,0){\makebox(0,0){\circle{0.0055348}}} +\put(1.12105,0){\makebox(0,0){\circle{0.0055348}}} +\path(1.16842,0)(1.2,0) +\put(1.24737,0){\makebox(0,0){\circle{0.0055348}}} +\put(1.27895,0){\makebox(0,0){\circle{0.0055348}}} +\path(1.32632,0)(1.35789,0) +\put(1.40526,0){\makebox(0,0){\circle{0.0055348}}} +\put(1.43684,0){\makebox(0,0){\circle{0.0055348}}} +\path(1.48421,0)(1.51579,0) +\put(1.56316,0){\makebox(0,0){\circle{0.0055348}}} +\put(1.59474,0){\makebox(0,0){\circle{0.0055348}}} +\path(1.64211,0)(1.67368,0) +\put(1.72105,0){\makebox(0,0){\circle{0.0055348}}} +\put(1.75263,0){\makebox(0,0){\circle{0.0055348}}} +\path(1.8,0)(1.83158,0) +\put(1.87895,0){\makebox(0,0){\circle{0.0055348}}} +\put(1.91053,0){\makebox(0,0){\circle{0.0055348}}} +\path(1.95789,0)(1.98947,0) +\put(2.03684,0){\makebox(0,0){\circle{0.0055348}}} +\put(2.06842,0){\makebox(0,0){\circle{0.0055348}}} +\path(2.11579,0)(2.14737,0) +\put(2.19474,0){\makebox(0,0){\circle{0.0055348}}} +\put(2.22632,0){\makebox(0,0){\circle{0.0055348}}} +\path(2.27368,0)(2.30526,0) +\put(2.35263,0){\makebox(0,0){\circle{0.0055348}}} +\put(2.38421,0){\makebox(0,0){\circle{0.0055348}}} +\path(2.43158,0)(2.46316,0) +\put(2.51053,0){\makebox(0,0){\circle{0.0055348}}} +\put(2.54211,0){\makebox(0,0){\circle{0.0055348}}} +\path(2.58947,0)(2.62105,0) +\put(2.66842,0){\makebox(0,0){\circle{0.0055348}}} +\put(2.7,0){\makebox(0,0){\circle{0.0055348}}} +\path(2.74737,0)(2.77895,0) +\put(2.82632,0){\makebox(0,0){\circle{0.0055348}}} +\put(2.85789,0){\makebox(0,0){\circle{0.0055348}}} +\path(2.90526,0)(2.93684,0) +\put(2.98421,0){\makebox(0,0){\circle{0.0055348}}} +\put(3.05535,0){\makebox(0,0)[l]{\code{line\_style(".\ - .")}}} +\end{picture} diff --git a/graphics/epix/doc/pathstyle.xp b/graphics/epix/doc/pathstyle.xp new file mode 100644 index 0000000000..47fe65e5e1 --- /dev/null +++ b/graphics/epix/doc/pathstyle.xp @@ -0,0 +1,24 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +void dash_sample(double ht, std::string pattern) +{ + line_style(pattern); + line(P(0,ht), P(3,ht)); + label(P(3, ht), P(4,0), "\\code{line\\_style(\""+pattern+"\")}", r); +} + +int main() { + picture(P(0,0), P(4,4), "4x1in"); + + begin(); + + dash_sample(4, "-\\ \\ -"); + dash_sample(3, "-\\ \\ \\ \\ -"); + dash_sample(2, " .\\ "); + dash_sample(1, "-\\ .\\ -"); + dash_sample(0, ".\\ - ."); + + end(); +} diff --git a/graphics/epix/doc/plot_a.eepic b/graphics/epix/doc/plot_a.eepic new file mode 100644 index 0000000000..bf0e6e787a --- /dev/null +++ b/graphics/epix/doc/plot_a.eepic @@ -0,0 +1,95 @@ +%% Generated from plot_a.xp on Tue Jul 3 00:20:34 EDT 2007 by +%% ePiX-1.0.25 +%% +%% Cartesian bounding box: [-1,1] x [-1,1] +%% Actual size: 1.5in x 1.5in +%% Figure offset: right by 0in, up by 0in +%% +\setlength{\unitlength}{1in} +\begin{picture}(1.5,1.5)(-0,-0) +%% --- +\path(0.75,0.75)(0.709403,0.666178)(0.666551,0.577699)(0.62125,0.484165) + (0.573284,0.385128)(0.522412,0.280089)(0.46836,0.168485) +\path(0.75,0.75)(0.749023,0.665974)(0.74798,0.585752)(0.746855,0.509046) + (0.745629,0.435587)(0.744277,0.365124)(0.742767,0.297412) +\path(0.75,0.75)(0.788831,0.67297)(0.830368,0.605884)(0.875481,0.548895) + (0.925286,0.502471)(0.981254,0.467495)(1.04539,0.445422) +\path(0.75,0.75)(0.824541,0.685618)(0.903621,0.632501)(0.988754,0.590989) + (1.08184,0.561798)(1.18533,0.546138)(1.30251,0.545884) +\path(0.75,0.75)(0.852385,0.702504)(0.959101,0.662234)(1.07131,0.62933) + (1.19037,0.604066)(1.31791,0.586882)(1.45594,0.578419) +\path(0.75,0.75)(0.869635,0.722554)(0.991406,0.694618)(1.11537,0.666178) + (1.24159,0.637221)(1.37013,0.607733)(1.50104,0.577699) +\path(0.75,0.75)(0.874862,0.74491)(0.998815,0.731016)(1.12092,0.708519) + (1.24029,0.677746)(1.35609,0.639142)(1.46759,0.593248) +\path(0.75,0.75)(0.867939,0.768582)(0.982511,0.77261)(1.09249,0.76265) + (1.19682,0.739556)(1.29466,0.704421)(1.38541,0.658506) +\path(0.75,0.75)(0.849863,0.792084)(0.945428,0.818543)(1.03584,0.830052) + (1.12046,0.827563)(1.1988,0.812243)(1.27061,0.785404) +\path(0.75,0.75)(0.822527,0.813279)(0.891435,0.864939)(0.956495,0.905455) + (1.01755,0.935412)(1.07452,0.955475)(1.12739,0.966366) +\path(0.75,0.75)(0.788515,0.829523)(0.825104,0.905071)(0.859908,0.976933) + (0.893055,1.04537)(0.924661,1.11063)(0.954829,1.17292) +\path(0.75,0.75)(0.750924,0.838139)(0.751807,0.93073)(0.752656,1.02814) + (0.753481,1.13079)(0.754288,1.23912)(0.755083,1.35363) +\path(0.75,0.75)(0.713174,0.837085)(0.677771,0.934566)(0.643292,1.043) + (0.609295,1.16316)(0.575368,1.29605)(0.541119,1.44293) +\path(0.75,0.75)(0.678756,0.825621)(0.609753,0.912727)(0.542063,1.01182) + (0.47484,1.12367)(0.40728,1.24929)(0.33859,1.39004) +\path(0.75,0.75)(0.650938,0.804706)(0.554306,0.866713)(0.459296,0.936218) + (0.365158,1.01352)(0.27118,1.09902)(0.176669,1.19323) +\path(0.75,0.75)(0.632446,0.776969)(0.516918,0.803473)(0.403366,0.829523) + (0.291738,0.855133)(0.181986,0.880311)(0.0740632,0.905071) +\path(0.75,0.75)(0.625191,0.746217)(0.501394,0.73363)(0.379543,0.712441) + (0.260522,0.68298)(0.145146,0.645689)(0.0341447,0.601107) +\path(0.75,0.75)(0.630074,0.71664)(0.509637,0.668642)(0.390202,0.606516) + (0.273258,0.531127)(0.160206,0.443655)(0.0523099,0.345536) +\path(0.75,0.75)(0.646869,0.69196)(0.541651,0.618018)(0.435639,0.528643) + (0.330189,0.424716)(0.22666,0.307508)(0.126363,0.178624) +\path(0.75,0.75)(0.674167,0.674761)(0.59542,0.587383)(0.514234,0.48787) + (0.431158,0.376427)(0.346809,0.253475)(0.261856,0.119648) +\path(0.75,0.75)(0.709403,0.666178)(0.666551,0.577699)(0.62125,0.484165) + (0.573284,0.385128)(0.522412,0.280089)(0.46836,0.168485) +\path(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75) + (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75) + (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75) + (0.75,0.75)(0.75,0.75)(0.75,0.75) +\path(0.709403,0.666178)(0.749023,0.665974)(0.788831,0.67297) + (0.824541,0.685618)(0.852385,0.702504)(0.869635,0.722554) + (0.874862,0.74491)(0.867939,0.768582)(0.849863,0.792084) + (0.822527,0.813279)(0.788515,0.829523)(0.750924,0.838139) + (0.713174,0.837085)(0.678756,0.825621)(0.650938,0.804706) + (0.632446,0.776969)(0.625191,0.746217)(0.630074,0.71664) + (0.646869,0.69196)(0.674167,0.674761)(0.709403,0.666178) +\path(0.666551,0.577699)(0.74798,0.585752)(0.830368,0.605884) + (0.903621,0.632501)(0.959101,0.662234)(0.991406,0.694618) + (0.998815,0.731016)(0.982511,0.77261)(0.945428,0.818543) + (0.891435,0.864939)(0.825104,0.905071)(0.751807,0.93073) + (0.677771,0.934566)(0.609753,0.912727)(0.554306,0.866713) + (0.516918,0.803473)(0.501394,0.73363)(0.509637,0.668642) + (0.541651,0.618018)(0.59542,0.587383)(0.666551,0.577699) +\path(0.62125,0.484165)(0.746855,0.509046)(0.875481,0.548895) + (0.988754,0.590989)(1.07131,0.62933)(1.11537,0.666178)(1.12092,0.708519) + (1.09249,0.76265)(1.03584,0.830052)(0.956495,0.905455)(0.859908,0.976933) + (0.752656,1.02814)(0.643292,1.043)(0.542063,1.01182)(0.459296,0.936218) + (0.403366,0.829523)(0.379543,0.712441)(0.390202,0.606516) + (0.435639,0.528643)(0.514234,0.48787)(0.62125,0.484165) +\path(0.573284,0.385128)(0.745629,0.435587)(0.925286,0.502471) + (1.08184,0.561798)(1.19037,0.604066)(1.24159,0.637221)(1.24029,0.677746) + (1.19682,0.739556)(1.12046,0.827563)(1.01755,0.935412)(0.893055,1.04537) + (0.753481,1.13079)(0.609295,1.16316)(0.47484,1.12367)(0.365158,1.01352) + (0.291738,0.855133)(0.260522,0.68298)(0.273258,0.531127) + (0.330189,0.424716)(0.431158,0.376427)(0.573284,0.385128) +\path(0.522412,0.280089)(0.744277,0.365124)(0.981254,0.467495) + (1.18533,0.546138)(1.31791,0.586882)(1.37013,0.607733)(1.35609,0.639142) + (1.29466,0.704421)(1.1988,0.812243)(1.07452,0.955475)(0.924661,1.11063) + (0.754288,1.23912)(0.575368,1.29605)(0.40728,1.24929)(0.27118,1.09902) + (0.181986,0.880311)(0.145146,0.645689)(0.160206,0.443655) + (0.22666,0.307508)(0.346809,0.253475)(0.522412,0.280089) +\path(0.46836,0.168485)(0.742767,0.297412)(1.04539,0.445422) + (1.30251,0.545884)(1.45594,0.578419)(1.50104,0.577699)(1.46759,0.593248) + (1.38541,0.658506)(1.27061,0.785404)(1.12739,0.966366)(0.954829,1.17292) + (0.755083,1.35363)(0.541119,1.44293)(0.33859,1.39004)(0.176669,1.19323) + (0.0740632,0.905071)(0.0341447,0.601107)(0.0523099,0.345536) + (0.126363,0.178624)(0.261856,0.119648)(0.46836,0.168485) +\end{picture} diff --git a/graphics/epix/doc/plot_a.xp b/graphics/epix/doc/plot_a.xp new file mode 100644 index 0000000000..4304d501d3 --- /dev/null +++ b/graphics/epix/doc/plot_a.xp @@ -0,0 +1,27 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; +P f(double u, double v) +{ + double x=u*Cos(v), y=u*Sin(v); + // return P(x, y, 0.25*x*(x*x-3*y*y)); + return P(x, y, x*y); +} + +domain R(P(0,0), P(1,1), mesh(6, 20), mesh(6, 20)); + +int main() +{ + bounding_box(P(-1,-1),P(1,1)); + unitlength("1in"); + picture(1.5,1.5); + + begin(); + revolutions(); + + camera.at(P(3, 1, 3)); + + plot(f, R); + + end(); +} diff --git a/graphics/epix/doc/plot_b.eepic b/graphics/epix/doc/plot_b.eepic new file mode 100644 index 0000000000..cf847bd346 --- /dev/null +++ b/graphics/epix/doc/plot_b.eepic @@ -0,0 +1,225 @@ +%% Generated from plot_b.xp on Tue Jul 3 00:20:46 EDT 2007 by +%% ePiX-1.0.25 +%% +%% Cartesian bounding box: [-1,1] x [-1,1] +%% Actual size: 1.5in x 1.5in +%% Figure offset: right by 0in, up by 0in +%% +\setlength{\unitlength}{1in} +\begin{picture}(1.5,1.5)(-0,-0) +%% --- +\path(0.75,0.75)(0.729972,0.708648)(0.709403,0.666178)(0.688271,0.622545) + (0.666551,0.577699)(0.64422,0.531591)(0.62125,0.484165) + (0.597615,0.435364)(0.573284,0.385128)(0.548228,0.333393) + (0.522412,0.280089)(0.495802,0.225146)(0.46836,0.168485) +\path(0.75,0.75)(0.749519,0.707493)(0.749023,0.665974)(0.74851,0.625406) + (0.74798,0.585752)(0.747429,0.546976)(0.746855,0.509046) + (0.746256,0.471927)(0.745629,0.435587)(0.744971,0.399997) + (0.744277,0.365124)(0.743544,0.330939)(0.742767,0.297412) +\path(0.75,0.75)(0.769125,0.71024)(0.788831,0.67297)(0.809212,0.638181) + (0.830368,0.605884)(0.852415,0.576107)(0.875481,0.548895) + (0.899715,0.524319)(0.925286,0.502471)(0.952389,0.483477) + (0.981254,0.467495)(1.01215,0.454726)(1.04539,0.445422) +\path(0.75,0.75)(0.786786,0.716409)(0.824541,0.685618)(0.863426,0.657638) + (0.903621,0.632501)(0.945323,0.610259)(0.988754,0.590989) + (1.03416,0.574791)(1.08184,0.561798)(1.1321,0.552178)(1.18533,0.546138) + (1.24196,0.543935)(1.30251,0.545884) +\path(0.75,0.75)(0.800717,0.725352)(0.852385,0.702504)(0.905133,0.68146) + (0.959101,0.662234)(1.01444,0.644848)(1.07131,0.62933)(1.12989,0.615719) + (1.19037,0.604066)(1.25297,0.594429)(1.31791,0.586882)(1.38547,0.581511) + (1.45594,0.578419) +\path(0.75,0.75)(0.809554,0.736337)(0.869635,0.722554)(0.93025,0.708648) + (0.991406,0.694618)(1.05311,0.680462)(1.11537,0.666178)(1.1782,0.651765) + (1.24159,0.637221)(1.30556,0.622545)(1.37013,0.607733)(1.43528,0.592786) + (1.50104,0.577699) +\path(0.75,0.75)(0.812485,0.748563)(0.874862,0.74491)(0.937011,0.739054) + (0.998815,0.731016)(1.06016,0.720825)(1.12092,0.708519)(1.181,0.694142) + (1.24029,0.677746)(1.29868,0.659392)(1.35609,0.639142)(1.41242,0.617069) + (1.46759,0.593248) +\path(0.75,0.75)(0.809307,0.761132)(0.867939,0.768582)(0.925727,0.772387) + (0.982511,0.77261)(1.03814,0.769331)(1.09249,0.76265)(1.14541,0.752681) + (1.19682,0.739556)(1.24659,0.723418)(1.29466,0.704421)(1.34095,0.682727) + (1.38541,0.658506) +\path(0.75,0.75)(0.800408,0.773024)(0.849863,0.792084)(0.89824,0.807232) + (0.945428,0.818543)(0.991325,0.826113)(1.03584,0.830052) + (1.07891,0.830488)(1.12046,0.827563)(1.16044,0.821428)(1.1988,0.812243) + (1.23553,0.800178)(1.27061,0.785404) +\path(0.75,0.75)(0.786698,0.783117)(0.822527,0.813279)(0.857449,0.840534) + (0.891435,0.864939)(0.924458,0.886556)(0.956495,0.905455) + (0.987531,0.921714)(1.01755,0.935412)(1.04655,0.946636)(1.07452,0.955475) + (1.10147,0.962021)(1.12739,0.966366) +\path(0.75,0.75)(0.769508,0.790278)(0.788515,0.829523)(0.807041,0.867775) + (0.825104,0.905071)(0.842721,0.941445)(0.859908,0.976933) + (0.876682,1.01156)(0.893055,1.04537)(0.909044,1.07838)(0.924661,1.11063) + (0.939918,1.14213)(0.954829,1.17292) +\path(0.75,0.75)(0.750468,0.793535)(0.750924,0.838139)(0.75137,0.883856) + (0.751807,0.93073)(0.752235,0.978809)(0.752656,1.02814)(0.753071,1.07878) + (0.753481,1.13079)(0.753886,1.18421)(0.754288,1.23912)(0.754687,1.29556) + (0.755083,1.35363) +\path(0.75,0.75)(0.731375,0.79227)(0.713174,0.837085)(0.695327,0.884497) + (0.677771,0.934566)(0.660445,0.98737)(0.643292,1.043)(0.62626,1.10155) + (0.609295,1.16316)(0.592347,1.22794)(0.575368,1.29605)(0.558309,1.36765) + (0.541119,1.44293) +\path(0.75,0.75)(0.714035,0.786396)(0.678756,0.825621)(0.644034,0.867713) + (0.609753,0.912727)(0.575798,0.960735)(0.542063,1.01182) + (0.508444,1.06609)(0.47484,1.12367)(0.441152,1.18468)(0.40728,1.24929) + (0.373126,1.31768)(0.33859,1.39004) +\path(0.75,0.75)(0.700112,0.776448)(0.650938,0.804706)(0.60237,0.834787) + (0.554306,0.866713)(0.506646,0.900512)(0.459296,0.936218) + (0.412163,0.973871)(0.365158,1.01352)(0.318192,1.05521)(0.27118,1.09902) + (0.224034,1.145)(0.176669,1.19323) +\path(0.75,0.75)(0.690966,0.763543)(0.632446,0.776969)(0.574432,0.790278) + (0.516918,0.803473)(0.459898,0.816554)(0.403366,0.829523) + (0.347314,0.842382)(0.291738,0.855133)(0.23663,0.867775) + (0.181986,0.880311)(0.127799,0.892743)(0.0740632,0.905071) +\path(0.75,0.75)(0.687529,0.749216)(0.625191,0.746217)(0.563106,0.741014) + (0.501394,0.73363)(0.440168,0.724093)(0.379543,0.712441) + (0.319626,0.69872)(0.260522,0.68298)(0.202331,0.665282) + (0.145146,0.645689)(0.089057,0.624272)(0.0341447,0.601107) +\path(0.75,0.75)(0.690195,0.735167)(0.630074,0.71664)(0.569825,0.694447) + (0.509637,0.668642)(0.4497,0.639299)(0.390202,0.606516) + (0.331328,0.570413)(0.273258,0.531127)(0.216163,0.488817) + (0.160206,0.443655)(0.105542,0.395829)(0.0523099,0.345536) +\path(0.75,0.75)(0.698772,0.72298)(0.646869,0.69196)(0.594442,0.656957) + (0.541651,0.618018)(0.488661,0.575214)(0.435639,0.528643) + (0.382758,0.478428)(0.330189,0.424716)(0.2781,0.367679)(0.22666,0.307508) + (0.176029,0.244413)(0.126363,0.178624) +\path(0.75,0.75)(0.712474,0.713891)(0.674167,0.674761)(0.63513,0.632594) + (0.59542,0.587383)(0.555099,0.539136)(0.514234,0.48787) + (0.472895,0.433619)(0.431158,0.376427)(0.389102,0.316355) + (0.346809,0.253475)(0.304364,0.187873)(0.261856,0.119648) +\path(0.75,0.75)(0.729972,0.708648)(0.709403,0.666178)(0.688271,0.622545) + (0.666551,0.577699)(0.64422,0.531591)(0.62125,0.484165) + (0.597615,0.435364)(0.573284,0.385128)(0.548228,0.333393) + (0.522412,0.280089)(0.495802,0.225146)(0.46836,0.168485) +\path(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75) + (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75) + (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75) + (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75) + (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75) + (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75) + (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75) + (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75) + (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75) + (0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75)(0.75,0.75) + (0.75,0.75) +\path(0.75,0.75) +\path(0.709403,0.666178)(0.722321,0.665223)(0.73558,0.665171) + (0.749023,0.665974)(0.762487,0.667581)(0.77581,0.669932) + (0.788831,0.67297)(0.801393,0.676634)(0.813343,0.680868) + (0.824541,0.685618)(0.834856,0.690836)(0.844172,0.696477) + (0.852385,0.702504)(0.859411,0.708879)(0.865178,0.715573) + (0.869635,0.722554)(0.872745,0.729792)(0.874488,0.737256) + (0.874862,0.74491)(0.873876,0.752715)(0.871555,0.760624) + (0.867939,0.768582)(0.863075,0.776527)(0.857026,0.784387) + (0.849863,0.792084)(0.841664,0.799529)(0.83252,0.806627) + (0.822527,0.813279)(0.811787,0.819381)(0.800411,0.82483) + (0.788515,0.829523)(0.776218,0.833364)(0.763645,0.836262) + (0.750924,0.838139)(0.738185,0.838931)(0.725558,0.83859) + (0.713174,0.837085)(0.701162,0.83441)(0.689648,0.830577) + (0.678756,0.825621)(0.668601,0.819601)(0.659294,0.812596) + (0.650938,0.804706)(0.643624,0.796048)(0.637436,0.786754) + (0.632446,0.776969)(0.628712,0.766846)(0.626283,0.756542) + (0.625191,0.746217)(0.625457,0.736026)(0.627088,0.72612) + (0.630074,0.71664)(0.634394,0.707713)(0.64001,0.699454)(0.646869,0.69196) + (0.654905,0.685309)(0.664036,0.679562)(0.674167,0.674761) + (0.685188,0.670929)(0.696978,0.668072)(0.709403,0.666178) +\path(0.709403,0.666178) +\path(0.666551,0.577699)(0.692974,0.578664)(0.720234,0.581422) + (0.74798,0.585752)(0.775839,0.591423)(0.80343,0.598206) + (0.830368,0.605884)(0.856279,0.614263)(0.880806,0.623178) + (0.903621,0.632501)(0.924433,0.642145)(0.942994,0.65206) + (0.959101,0.662234)(0.972601,0.672687)(0.98339,0.683461) + (0.991406,0.694618)(0.996632,0.706222)(0.999085,0.718337) + (0.998815,0.731016)(0.995896,0.74429)(0.990424,0.758164) + (0.982511,0.77261)(0.972282,0.787565)(0.959873,0.802924) + (0.945428,0.818543)(0.929098,0.834239)(0.911044,0.849789) + (0.891435,0.864939)(0.870449,0.879406)(0.848272,0.892888) + (0.825104,0.905071)(0.801155,0.915638)(0.776645,0.924286) + (0.751807,0.93073)(0.726882,0.934719)(0.702119,0.936048) + (0.677771,0.934566)(0.654093,0.930185)(0.631338,0.922887) + (0.609753,0.912727)(0.589573,0.899834)(0.571022,0.884408) + (0.554306,0.866713)(0.539611,0.847073)(0.527101,0.825857) + (0.516918,0.803473)(0.509181,0.780348)(0.503983,0.756921) + (0.501394,0.73363)(0.501461,0.710895)(0.504209,0.689112) + (0.509637,0.668642)(0.517723,0.649801)(0.528419,0.632855) + (0.541651,0.618018)(0.557321,0.605441)(0.575297,0.595218) + (0.59542,0.587383)(0.617495,0.581912)(0.641293,0.578726) + (0.666551,0.577699) +\path(0.666551,0.577699) +\path(0.62125,0.484165)(0.661714,0.489898)(0.703779,0.498369) + (0.746855,0.509046)(0.790294,0.521379)(0.833406,0.534828) + (0.875481,0.548895)(0.915825,0.563151)(0.953779,0.577259) + (0.988754,0.590989)(1.02025,0.604228)(1.04786,0.616974)(1.07131,0.62933) + (1.09041,0.641478)(1.10509,0.653667)(1.11537,0.666178)(1.12133,0.679307) + (1.12312,0.693337)(1.12092,0.708519)(1.11493,0.725052)(1.10538,0.743075) + (1.09249,0.76265)(1.07646,0.783756)(1.05751,0.806289)(1.03584,0.830052) + (1.01166,0.854761)(0.985141,0.880045)(0.956495,0.905455) + (0.925925,0.930468)(0.893649,0.954502)(0.859908,0.976933) + (0.824965,0.997111)(0.789108,1.01439)(0.752656,1.02814)(0.715955,1.0378) + (0.679371,1.04288)(0.643292,1.043)(0.608116,1.0379)(0.574243,1.02749) + (0.542063,1.01182)(0.511952,0.991116)(0.484258,0.965743) + (0.459296,0.936218)(0.437343,0.903175)(0.418635,0.867345) + (0.403366,0.829523)(0.391688,0.790542)(0.383719,0.751241) + (0.379543,0.712441)(0.379214,0.674923)(0.382764,0.639401) + (0.390202,0.606516)(0.401519,0.576814)(0.416683,0.550743) + (0.435639,0.528643)(0.458304,0.510741)(0.484558,0.497152) + (0.514234,0.48787)(0.547111,0.48278)(0.582903,0.481654)(0.62125,0.484165) +\path(0.62125,0.484165) +\path(0.573284,0.385128)(0.628255,0.398429)(0.685992,0.415579) + (0.745629,0.435587)(0.806153,0.457413)(0.866435,0.480025) + (0.925286,0.502471)(0.981521,0.523945)(1.03403,0.543843) + (1.08184,0.561798)(1.12417,0.577699)(1.16045,0.591675)(1.19037,0.604066) + (1.21379,0.615372)(1.23079,0.626204)(1.24159,0.637221)(1.24651,0.649085) + (1.24594,0.662413)(1.24029,0.677746)(1.22996,0.695523)(1.21536,0.716063) + (1.19682,0.739556)(1.17465,0.766054)(1.14912,0.795468)(1.12046,0.827563) + (1.08886,0.861958)(1.0545,0.89813)(1.01755,0.935412)(0.978193,0.973008) + (0.936617,1.01)(0.893055,1.04537)(0.847784,1.07804)(0.80113,1.10688) + (0.753481,1.13079)(0.705284,1.14872)(0.65704,1.15976)(0.609295,1.16316) + (0.562623,1.15839)(0.517613,1.14522)(0.47484,1.12367)(0.434852,1.09408) + (0.398146,1.05707)(0.365158,1.01352)(0.336248,0.964504) + (0.311704,0.911264)(0.291738,0.855133)(0.276497,0.797481) + (0.266074,0.739664)(0.260522,0.68298)(0.259863,0.628631) + (0.264107,0.577699)(0.273258,0.531127)(0.287318,0.489709) + (0.306294,0.454081)(0.330189,0.424716)(0.358995,0.401924) + (0.392679,0.38584)(0.431158,0.376427)(0.474277,0.373467) + (0.521781,0.37656)(0.573284,0.385128) +\path(0.573284,0.385128) +\path(0.522412,0.280089)(0.592255,0.303678)(0.666599,0.332557) + (0.744277,0.365124)(0.823805,0.399632)(0.903434,0.434308) + (0.981254,0.467495)(1.05533,0.497794)(1.12387,0.524191)(1.18533,0.546138) + (1.23857,0.563575)(1.28285,0.576899)(1.31791,0.586882)(1.34384,0.594557) + (1.36104,0.601102)(1.37013,0.607733)(1.37182,0.615613)(1.3669,0.625786) + (1.35609,0.639142)(1.34008,0.656388)(1.31944,0.67804)(1.29466,0.704421) + (1.26612,0.735658)(1.2341,0.771686)(1.1988,0.812243)(1.16038,0.856871) + (1.11892,0.904905)(1.07452,0.955475)(1.02726,1.0075)(0.977251,1.05971) + (0.924661,1.11063)(0.86973,1.15865)(0.812793,1.20206)(0.754288,1.23912) + (0.694765,1.26811)(0.634877,1.28752)(0.575368,1.29605)(0.517045,1.29277) + (0.460742,1.27718)(0.40728,1.24929)(0.35743,1.20959)(0.311875,1.15903) + (0.27118,1.09902)(0.235783,1.03125)(0.205991,0.95767)(0.181986,0.880311) + (0.163849,0.801232)(0.151584,0.722411)(0.145146,0.645689) + (0.144472,0.572724)(0.149503,0.504968)(0.160206,0.443655) + (0.17659,0.389804)(0.198709,0.344221)(0.22666,0.307508) + (0.260573,0.280059)(0.300586,0.26206)(0.346809,0.253475) + (0.39928,0.254024)(0.457909,0.263169)(0.522412,0.280089) +\path(0.522412,0.280089) +\path(0.46836,0.168485)(0.553304,0.204953)(0.645257,0.248719) + (0.742767,0.297412)(0.843765,0.348317)(0.945636,0.398569) + (1.04539,0.445422)(1.13995,0.486548)(1.22644,0.5203)(1.30251,0.545884) + (1.36653,0.563399)(1.41769,0.573743)(1.45594,0.578419)(1.48186,0.579303) + (1.49647,0.578408)(1.50104,0.577699)(1.49691,0.578964)(1.48538,0.583732) + (1.46759,0.593248)(1.44451,0.60847)(1.41692,0.63008)(1.38541,0.658506) + (1.35037,0.693935)(1.31206,0.736325)(1.27061,0.785404)(1.22604,0.840659) + (1.17832,0.901326)(1.12739,0.966366)(1.07317,1.03445)(1.01563,1.10395) + (0.954829,1.17292)(0.890909,1.23916)(0.824171,1.30025)(0.755083,1.35363) + (0.684297,1.39674)(0.612645,1.42719)(0.541119,1.44293)(0.470828,1.44243) + (0.402935,1.42483)(0.33859,1.39004)(0.278856,1.33875)(0.224644,1.27245) + (0.176669,1.19323)(0.135426,1.10367)(0.101196,1.00663) + (0.0740632,0.905071)(0.053964,0.801877)(0.0407306,0.699748) + (0.0341447,0.601107)(0.0339864,0.508057)(0.0400764,0.422378) + (0.0523099,0.345536)(0.0706802,0.278715)(0.0952918,0.222844) + (0.126363,0.178624)(0.164213,0.146543)(0.209236,0.126873) + (0.261856,0.119648)(0.322456,0.124628)(0.391288,0.141232) + (0.46836,0.168485) +\path(0.46836,0.168485) +\end{picture} diff --git a/graphics/epix/doc/plot_b.xp b/graphics/epix/doc/plot_b.xp new file mode 100644 index 0000000000..f7560071e9 --- /dev/null +++ b/graphics/epix/doc/plot_b.xp @@ -0,0 +1,27 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; +P f(double u, double v) +{ + double x=u*Cos(v), y=u*Sin(v); + // return P(x, y, 0.25*x*(x*x-3*y*y)); + return P(x, y, x*y); +} + +domain R(P(0,0), P(1,1), mesh(6, 20), mesh(12,60)); + +int main() +{ + bounding_box(P(-1,-1),P(1,1)); + unitlength("1in"); + picture(1.5,1.5); + + begin(); + revolutions(); + + camera.at(P(3, 1, 3)); + + plot(f, R); + + end(); +} diff --git a/graphics/epix/doc/plotting.eepic b/graphics/epix/doc/plotting.eepic new file mode 100644 index 0000000000..ca0911610b --- /dev/null +++ b/graphics/epix/doc/plotting.eepic @@ -0,0 +1,82 @@ +%% Generated from plotting.xp on Thu Jun 28 15:36:18 EDT 2007 by +%% ePiX-1.1.6 +%% +%% Cartesian bounding box: [-2,2] x [-1,1] +%% Actual size: 5 x 1in +%% Figure offset: left by 0in, down by 0in +%% +\xdefinecolor{rgb_000000}{rgb}{0,0,0} +\xdefinecolor{rgb_ff0000}{rgb}{1,0,0} +\setlength{\unitlength}{1in} +\begin{picture}(5,1)(-0,-0) +\path(0,0.5)(5,0.5) +%% +\put(0,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(0.3125,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(0.625,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(0.9375,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(1.25,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(1.5625,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(1.875,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(2.1875,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(2.5,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(2.8125,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(3.125,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(3.4375,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(3.75,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(4.0625,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(4.375,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(4.6875,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\put(5,0.5){\makebox(0,0){$\rule{0.5pt}{4pt}$}} +\path(2.5,0)(2.5,1) +%% +\put(2.5,0){\makebox(0,0){$\rule{4pt}{0.5pt}$}} +\put(2.5,0.25){\makebox(0,0){$\rule{4pt}{0.5pt}$}} +\put(2.5,0.5){\makebox(0,0){$\rule{4pt}{0.5pt}$}} +\put(2.5,0.75){\makebox(0,0){$\rule{4pt}{0.5pt}$}} +\put(2.5,1){\makebox(0,0){$\rule{4pt}{0.5pt}$}} +\put(0,0.444652){\makebox(0,0)[t]{$-2$}} +\put(1.25,0.444652){\makebox(0,0)[t]{$-1$}} +\put(2.5,0.444652){\makebox(0,0)[t]{$\phantom{-}0$}} +\put(3.75,0.444652){\makebox(0,0)[t]{$\phantom{-}1$}} +\put(5,0.444652){\makebox(0,0)[t]{$\phantom{-}2$}} +\color{rgb_ff0000}% +\path(0,0.5)(0.0416667,0.527125) + (0.0833333,0.559633)(0.125,0.601537)(0.166667,0.654364) + (0.208333,0.716506)(0.25,0.783173)(0.291667,0.846957) + (0.333333,0.898935)(0.375,0.930119)(0.416667,0.933013) + (0.458333,0.902995)(0.5,0.839302)(0.541667,0.745419) + (0.583333,0.628809)(0.625,0.5)(0.666667,0.371191) + (0.708333,0.254581)(0.75,0.160698)(0.791667,0.0970055) + (0.833333,0.0669873)(0.875,0.0698806)(0.916667,0.101065) + (0.958333,0.153043)(1,0.216827)(1.04167,0.283494)(1.08333,0.345636) + (1.125,0.398463)(1.16667,0.440367)(1.20833,0.472875)(1.25,0.5) + (1.29167,0.527125)(1.33333,0.559633)(1.375,0.601537) + (1.41667,0.654364)(1.45833,0.716506)(1.5,0.783173) + (1.54167,0.846957)(1.58333,0.898935)(1.625,0.930119) + (1.66667,0.933013)(1.70833,0.902995)(1.75,0.839302) + (1.79167,0.745419)(1.83333,0.628809)(1.875,0.5)(1.91667,0.371191) + (1.95833,0.254581)(2,0.160698)(2.04167,0.0970055) + (2.08333,0.0669873)(2.125,0.0698806)(2.16667,0.101065) + (2.20833,0.153043)(2.25,0.216827)(2.29167,0.283494) + (2.33333,0.345636)(2.375,0.398463)(2.41667,0.440367) + (2.45833,0.472875)(2.5,0.5)(2.54167,0.527125)(2.58333,0.559633) + (2.625,0.601537)(2.66667,0.654364)(2.70833,0.716506)(2.75,0.783173) + (2.79167,0.846957)(2.83333,0.898935)(2.875,0.930119) + (2.91667,0.933013)(2.95833,0.902995)(3,0.839302)(3.04167,0.745419) + (3.08333,0.628809)(3.125,0.5)(3.16667,0.371191)(3.20833,0.254581) + (3.25,0.160698)(3.29167,0.0970055)(3.33333,0.0669873) + (3.375,0.0698806)(3.41667,0.101065)(3.45833,0.153043)(3.5,0.216827) + (3.54167,0.283494)(3.58333,0.345636)(3.625,0.398463) + (3.66667,0.440367)(3.70833,0.472875)(3.75,0.5)(3.79167,0.527125) + (3.83333,0.559633)(3.875,0.601537)(3.91667,0.654364) + (3.95833,0.716506)(4,0.783173)(4.04167,0.846957)(4.08333,0.898935) + (4.125,0.930119)(4.16667,0.933013)(4.20833,0.902995)(4.25,0.839302) + (4.29167,0.745419)(4.33333,0.628809)(4.375,0.5)(4.41667,0.371191) + (4.45833,0.254581)(4.5,0.160698)(4.54167,0.0970055) + (4.58333,0.0669873)(4.625,0.0698806)(4.66667,0.101065) + (4.70833,0.153043)(4.75,0.216827)(4.79167,0.283494) + (4.83333,0.345636)(4.875,0.398463)(4.91667,0.440367) + (4.95833,0.472875)(5,0.5) +%% +\end{picture} diff --git a/graphics/epix/doc/plotting.xp b/graphics/epix/doc/plotting.xp new file mode 100644 index 0000000000..ad310f7b02 --- /dev/null +++ b/graphics/epix/doc/plotting.xp @@ -0,0 +1,26 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +double f(double x) +{ + return 0.75*Sin(x) - 0.25*Sin(2*x); +} + +int main() +{ + picture(P(-2,-1),P(2,1), "5x1in"); + + begin(); + + h_axis(16); + v_axis(4); + + h_axis_labels(4, P(0,-4), b); // shift labels down 4pt, align below + + revolutions(); // set angle units + red(); + plot(f, xmin(), xmax(), 120); // use 120 intervals + + end(); +} diff --git a/graphics/epix/doc/plotting2.eepic b/graphics/epix/doc/plotting2.eepic new file mode 100644 index 0000000000..5f56a743ec --- /dev/null +++ b/graphics/epix/doc/plotting2.eepic @@ -0,0 +1,1766 @@ +%% Generated from plotting2.xp on Tue Sep 25 00:02:47 EDT 2007 by +%% ePiX-1.2.0 +%% +%% Cartesian bounding box: [-1,1] x [-1,1] +%% Actual size: 2 x 1in +%% Figure offset: left by 0in, down by 0in +%% +%% usepackages pstricks +%% +\newcmykcolor{cmy_0000ff}{0 0 1 0}% +\newcmykcolor{cmy_0101ff}{0 0 0.996078 0.00392157}% +\newcmykcolor{cmy_0202ff}{0 0 0.992157 0.00784314}% +\newcmykcolor{cmy_0303ff}{0 0 0.988235 0.0117647}% +\newcmykcolor{cmy_0505ff}{0 0 0.980392 0.0196078}% +\newcmykcolor{cmy_0606ff}{0 0 0.976471 0.0235294}% +\newcmykcolor{cmy_0808ff}{0 0 0.968627 0.0313725}% +\newcmykcolor{cmy_0909ff}{0 0 0.964706 0.0352941}% +\newcmykcolor{cmy_0a0aff}{0 0 0.960784 0.0392157}% +\newcmykcolor{cmy_0b0bff}{0 0 0.956863 0.0431373}% +\newcmykcolor{cmy_0c0cff}{0 0 0.952941 0.0470588}% +\newcmykcolor{cmy_0d0dff}{0 0 0.94902 0.0509804}% +\newcmykcolor{cmy_0e0eff}{0 0 0.945098 0.054902}% +\newcmykcolor{cmy_0f0fff}{0 0 0.941176 0.0588235}% +\newcmykcolor{cmy_1111ff}{0 0 0.933333 0.0666667}% +\newcmykcolor{cmy_1313ff}{0 0 0.92549 0.0745098}% +\newcmykcolor{cmy_1515ff}{0 0 0.917647 0.0823529}% +\newcmykcolor{cmy_1616ff}{0 0 0.913725 0.0862745}% +\newcmykcolor{cmy_1818ff}{0 0 0.905882 0.0941176}% +\newcmykcolor{cmy_1919ff}{0 0 0.901961 0.0980392}% +\newcmykcolor{cmy_1b1bff}{0 0 0.894118 0.105882}% +\newcmykcolor{cmy_1c1cff}{0 0 0.890196 0.109804}% +\newcmykcolor{cmy_2020ff}{0 0 0.87451 0.12549}% +\newcmykcolor{cmy_2323ff}{0 0 0.862745 0.137255}% +\newcmykcolor{cmy_2525ff}{0 0 0.854902 0.145098}% +\newcmykcolor{cmy_2626ff}{0 0 0.85098 0.14902}% +\newcmykcolor{cmy_2828ff}{0 0 0.843137 0.156863}% +\newcmykcolor{cmy_2929ff}{0 0 0.839216 0.160784}% +\newcmykcolor{cmy_2a2aff}{0 0 0.835294 0.164706}% +\newcmykcolor{cmy_2d2dff}{0 0 0.823529 0.176471}% +\newcmykcolor{cmy_3030ff}{0 0 0.811765 0.188235}% +\newcmykcolor{cmy_3131ff}{0 0 0.807843 0.192157}% +\newcmykcolor{cmy_3232ff}{0 0 0.803922 0.196078}% +\newcmykcolor{cmy_3434ff}{0 0 0.796078 0.203922}% +\newcmykcolor{cmy_3535ff}{0 0 0.792157 0.207843}% +\newcmykcolor{cmy_3636ff}{0 0 0.788235 0.211765}% +\newcmykcolor{cmy_3737ff}{0 0 0.784314 0.215686}% +\newcmykcolor{cmy_3838ff}{0 0 0.780392 0.219608}% +\newcmykcolor{cmy_3939ff}{0 0 0.776471 0.223529}% +\newcmykcolor{cmy_3a3aff}{0 0 0.772549 0.227451}% +\newcmykcolor{cmy_3b3bff}{0 0 0.768627 0.231373}% +\newcmykcolor{cmy_3c3cff}{0 0 0.764706 0.235294}% +\newcmykcolor{cmy_3d3dff}{0 0 0.760784 0.239216}% +\newcmykcolor{cmy_3e3eff}{0 0 0.756863 0.243137}% +\newcmykcolor{cmy_3f3fff}{0 0 0.752941 0.247059}% +\newcmykcolor{cmy_4141ff}{0 0 0.745098 0.254902}% +\newcmykcolor{cmy_4343ff}{0 0 0.737255 0.262745}% +\newcmykcolor{cmy_4545ff}{0 0 0.729412 0.270588}% +\newcmykcolor{cmy_4848ff}{0 0 0.717647 0.282353}% +\newcmykcolor{cmy_4949ff}{0 0 0.713725 0.286275}% +\newcmykcolor{cmy_4a4aff}{0 0 0.709804 0.290196}% +\newcmykcolor{cmy_4b4bff}{0 0 0.705882 0.294118}% +\newcmykcolor{cmy_4c4cff}{0 0 0.701961 0.298039}% +\newcmykcolor{cmy_4d4dff}{0 0 0.698039 0.301961}% +\newcmykcolor{cmy_4e4eff}{0 0 0.694118 0.305882}% +\newcmykcolor{cmy_4f4fff}{0 0 0.690196 0.309804}% +\newcmykcolor{cmy_5050ff}{0 0 0.686275 0.313725}% +\newcmykcolor{cmy_5151ff}{0 0 0.682353 0.317647}% +\newcmykcolor{cmy_5252ff}{0 0 0.678431 0.321569}% +\newcmykcolor{cmy_5353ff}{0 0 0.67451 0.32549}% +\newcmykcolor{cmy_5454ff}{0 0 0.670588 0.329412}% +\newcmykcolor{cmy_5555ff}{0 0 0.666667 0.333333}% +\newcmykcolor{cmy_5656ff}{0 0 0.662745 0.337255}% +\newcmykcolor{cmy_5757ff}{0 0 0.658824 0.341176}% +\newcmykcolor{cmy_5858ff}{0 0 0.654902 0.345098}% +\newcmykcolor{cmy_5959ff}{0 0 0.65098 0.34902}% +\newcmykcolor{cmy_5a5aff}{0 0 0.647059 0.352941}% +\newcmykcolor{cmy_5b5bff}{0 0 0.643137 0.356863}% +\newcmykcolor{cmy_5c5cff}{0 0 0.639216 0.360784}% +\newcmykcolor{cmy_5d5dff}{0 0 0.635294 0.364706}% +\newcmykcolor{cmy_5e5eff}{0 0 0.631373 0.368627}% +\newcmykcolor{cmy_5f5fff}{0 0 0.627451 0.372549}% +\newcmykcolor{cmy_6060ff}{0 0 0.623529 0.376471}% +\newcmykcolor{cmy_6161ff}{0 0 0.619608 0.380392}% +\newcmykcolor{cmy_6262ff}{0 0 0.615686 0.384314}% +\newcmykcolor{cmy_6363ff}{0 0 0.611765 0.388235}% +\newcmykcolor{cmy_6464ff}{0 0 0.607843 0.392157}% +\newcmykcolor{cmy_6565ff}{0 0 0.603922 0.396078}% +\newcmykcolor{cmy_6666ff}{0 0 0.6 0.4}% +\newcmykcolor{cmy_6767ff}{0 0 0.596078 0.403922}% +\newcmykcolor{cmy_6868ff}{0 0 0.592157 0.407843}% +\newcmykcolor{cmy_6969ff}{0 0 0.588235 0.411765}% +\newcmykcolor{cmy_6a6aff}{0 0 0.584314 0.415686}% +\newcmykcolor{cmy_6b6bff}{0 0 0.580392 0.419608}% +\newcmykcolor{cmy_6c6cff}{0 0 0.576471 0.423529}% +\newcmykcolor{cmy_6d6dff}{0 0 0.572549 0.427451}% +\newcmykcolor{cmy_6e6eff}{0 0 0.568627 0.431373}% +\newcmykcolor{cmy_6f6fff}{0 0 0.564706 0.435294}% +\newcmykcolor{cmy_7070ff}{0 0 0.560784 0.439216}% +\newcmykcolor{cmy_7171ff}{0 0 0.556863 0.443137}% +\newcmykcolor{cmy_7272ff}{0 0 0.552941 0.447059}% +\newcmykcolor{cmy_7373ff}{0 0 0.54902 0.45098}% +\newcmykcolor{cmy_7474ff}{0 0 0.545098 0.454902}% +\newcmykcolor{cmy_7575ff}{0 0 0.541176 0.458824}% +\newcmykcolor{cmy_7676ff}{0 0 0.537255 0.462745}% +\newcmykcolor{cmy_7777ff}{0 0 0.533333 0.466667}% +\newcmykcolor{cmy_7878ff}{0 0 0.529412 0.470588}% +\newcmykcolor{cmy_7979ff}{0 0 0.52549 0.47451}% +\newcmykcolor{cmy_7a7aff}{0 0 0.521569 0.478431}% +\newcmykcolor{cmy_7b7bff}{0 0 0.517647 0.482353}% +\newcmykcolor{cmy_7c7cff}{0 0 0.513725 0.486275}% +\newcmykcolor{cmy_7d7dff}{0 0 0.509804 0.490196}% +\newcmykcolor{cmy_7e7eff}{0 0 0.505882 0.494118}% +\newcmykcolor{cmy_7f7fff}{0 0 0.501961 0.498039}% +\newrgbcolor{rgb_000000}{0 0 0}% +\newrgbcolor{rgb_19197f}{0.0980392 0.0980392 0.498039}% +\newrgbcolor{rgb_191980}{0.0980392 0.0980392 0.501961}% +\newrgbcolor{rgb_191981}{0.0980392 0.0980392 0.505882}% +\newrgbcolor{rgb_1a1a82}{0.101961 0.101961 0.509804}% +\newrgbcolor{rgb_1a1a83}{0.101961 0.101961 0.513725}% +\newrgbcolor{rgb_1a1a84}{0.101961 0.101961 0.517647}% +\newrgbcolor{rgb_1a1a85}{0.101961 0.101961 0.521569}% +\newrgbcolor{rgb_1a1a86}{0.101961 0.101961 0.52549}% +\newrgbcolor{rgb_1b1b87}{0.105882 0.105882 0.529412}% +\newrgbcolor{rgb_1b1b88}{0.105882 0.105882 0.533333}% +\newrgbcolor{rgb_1b1b89}{0.105882 0.105882 0.537255}% +\newrgbcolor{rgb_1b1b8a}{0.105882 0.105882 0.541176}% +\newrgbcolor{rgb_1b1b8b}{0.105882 0.105882 0.545098}% +\newrgbcolor{rgb_1c1c8c}{0.109804 0.109804 0.54902}% +\newrgbcolor{rgb_1c1c8d}{0.109804 0.109804 0.552941}% +\newrgbcolor{rgb_1c1c8e}{0.109804 0.109804 0.556863}% +\newrgbcolor{rgb_1c1c8f}{0.109804 0.109804 0.560784}% +\newrgbcolor{rgb_1c1c90}{0.109804 0.109804 0.564706}% +\newrgbcolor{rgb_1d1d91}{0.113725 0.113725 0.568627}% +\newrgbcolor{rgb_1d1d92}{0.113725 0.113725 0.572549}% +\newrgbcolor{rgb_1d1d93}{0.113725 0.113725 0.576471}% +\newrgbcolor{rgb_1d1d94}{0.113725 0.113725 0.580392}% +\newrgbcolor{rgb_1d1d95}{0.113725 0.113725 0.584314}% +\newrgbcolor{rgb_1e1e96}{0.117647 0.117647 0.588235}% +\newrgbcolor{rgb_1e1e97}{0.117647 0.117647 0.592157}% +\newrgbcolor{rgb_1e1e98}{0.117647 0.117647 0.596078}% +\newrgbcolor{rgb_1e1e99}{0.117647 0.117647 0.6}% +\newrgbcolor{rgb_1e1e9a}{0.117647 0.117647 0.603922}% +\newrgbcolor{rgb_1f1f9b}{0.121569 0.121569 0.607843}% +\newrgbcolor{rgb_1f1f9c}{0.121569 0.121569 0.611765}% +\newrgbcolor{rgb_1f1f9d}{0.121569 0.121569 0.615686}% +\newrgbcolor{rgb_1f1f9e}{0.121569 0.121569 0.619608}% +\newrgbcolor{rgb_1f1f9f}{0.121569 0.121569 0.623529}% +\newrgbcolor{rgb_2020a0}{0.12549 0.12549 0.627451}% +\newrgbcolor{rgb_2020a1}{0.12549 0.12549 0.631373}% +\newrgbcolor{rgb_2020a2}{0.12549 0.12549 0.635294}% +\newrgbcolor{rgb_2020a3}{0.12549 0.12549 0.639216}% +\newrgbcolor{rgb_2020a4}{0.12549 0.12549 0.643137}% +\newrgbcolor{rgb_2121a5}{0.129412 0.129412 0.647059}% +\newrgbcolor{rgb_2121a6}{0.129412 0.129412 0.65098}% +\newrgbcolor{rgb_2121a7}{0.129412 0.129412 0.654902}% +\newrgbcolor{rgb_2121a8}{0.129412 0.129412 0.658824}% +\newrgbcolor{rgb_2121a9}{0.129412 0.129412 0.662745}% +\newrgbcolor{rgb_2222aa}{0.133333 0.133333 0.666667}% +\newrgbcolor{rgb_2222ab}{0.133333 0.133333 0.670588}% +\newrgbcolor{rgb_2222ac}{0.133333 0.133333 0.67451}% +\newrgbcolor{rgb_2222ad}{0.133333 0.133333 0.678431}% +\newrgbcolor{rgb_2222ae}{0.133333 0.133333 0.682353}% +\newrgbcolor{rgb_2323af}{0.137255 0.137255 0.686275}% +\newrgbcolor{rgb_2323b0}{0.137255 0.137255 0.690196}% +\newrgbcolor{rgb_2323b1}{0.137255 0.137255 0.694118}% +\newrgbcolor{rgb_2323b2}{0.137255 0.137255 0.698039}% +\newrgbcolor{rgb_2323b3}{0.137255 0.137255 0.701961}% +\newrgbcolor{rgb_2424b4}{0.141176 0.141176 0.705882}% +\newrgbcolor{rgb_2424b5}{0.141176 0.141176 0.709804}% +\newrgbcolor{rgb_2424b6}{0.141176 0.141176 0.713725}% +\newrgbcolor{rgb_2525b9}{0.145098 0.145098 0.72549}% +\newrgbcolor{rgb_2525bb}{0.145098 0.145098 0.733333}% +\newrgbcolor{rgb_2525bd}{0.145098 0.145098 0.741176}% +\newrgbcolor{rgb_2626bf}{0.14902 0.14902 0.74902}% +\newrgbcolor{rgb_2626c0}{0.14902 0.14902 0.752941}% +\newrgbcolor{rgb_2626c1}{0.14902 0.14902 0.756863}% +\newrgbcolor{rgb_2626c2}{0.14902 0.14902 0.760784}% +\newrgbcolor{rgb_2727c3}{0.152941 0.152941 0.764706}% +\newrgbcolor{rgb_2727c4}{0.152941 0.152941 0.768627}% +\newrgbcolor{rgb_2727c5}{0.152941 0.152941 0.772549}% +\newrgbcolor{rgb_2727c6}{0.152941 0.152941 0.776471}% +\newrgbcolor{rgb_2727c7}{0.152941 0.152941 0.780392}% +\newrgbcolor{rgb_2828c8}{0.156863 0.156863 0.784314}% +\newrgbcolor{rgb_2828c9}{0.156863 0.156863 0.788235}% +\newrgbcolor{rgb_2828ca}{0.156863 0.156863 0.792157}% +\newrgbcolor{rgb_2828cc}{0.156863 0.156863 0.8}% +\newrgbcolor{rgb_2929cd}{0.160784 0.160784 0.803922}% +\newrgbcolor{rgb_2929ce}{0.160784 0.160784 0.807843}% +\newrgbcolor{rgb_2929d1}{0.160784 0.160784 0.819608}% +\newrgbcolor{rgb_2a2ad4}{0.164706 0.164706 0.831373}% +\newrgbcolor{rgb_2a2ad5}{0.164706 0.164706 0.835294}% +\newrgbcolor{rgb_2a2ad6}{0.164706 0.164706 0.839216}% +\newrgbcolor{rgb_2b2bd8}{0.168627 0.168627 0.847059}% +\newrgbcolor{rgb_2b2bd9}{0.168627 0.168627 0.85098}% +\newrgbcolor{rgb_2b2bdb}{0.168627 0.168627 0.858824}% +\newrgbcolor{rgb_2c2cde}{0.172549 0.172549 0.870588}% +\newrgbcolor{rgb_2d2de2}{0.176471 0.176471 0.886275}% +\newrgbcolor{rgb_2d2de3}{0.176471 0.176471 0.890196}% +\newrgbcolor{rgb_2d2de5}{0.176471 0.176471 0.898039}% +\newrgbcolor{rgb_2e2ee6}{0.180392 0.180392 0.901961}% +\newrgbcolor{rgb_2e2ee8}{0.180392 0.180392 0.909804}% +\newrgbcolor{rgb_2e2ee9}{0.180392 0.180392 0.913725}% +\newrgbcolor{rgb_2f2feb}{0.184314 0.184314 0.921569}% +\newrgbcolor{rgb_2f2fed}{0.184314 0.184314 0.929412}% +\newrgbcolor{rgb_2f2fef}{0.184314 0.184314 0.937255}% +\newrgbcolor{rgb_3030f0}{0.188235 0.188235 0.941176}% +\newrgbcolor{rgb_3030f1}{0.188235 0.188235 0.945098}% +\newrgbcolor{rgb_3030f2}{0.188235 0.188235 0.94902}% +\newrgbcolor{rgb_3030f3}{0.188235 0.188235 0.952941}% +\newrgbcolor{rgb_3030f4}{0.188235 0.188235 0.956863}% +\newrgbcolor{rgb_3131f5}{0.192157 0.192157 0.960784}% +\newrgbcolor{rgb_3131f6}{0.192157 0.192157 0.964706}% +\newrgbcolor{rgb_3131f8}{0.192157 0.192157 0.972549}% +\newrgbcolor{rgb_3131f9}{0.192157 0.192157 0.976471}% +\newrgbcolor{rgb_3232fb}{0.196078 0.196078 0.984314}% +\newrgbcolor{rgb_3232fc}{0.196078 0.196078 0.988235}% +\newrgbcolor{rgb_3232fd}{0.196078 0.196078 0.992157}% +\newrgbcolor{rgb_3232fe}{0.196078 0.196078 0.996078}% +\psset{unit=1in,linewidth=0.4pt}% +\begin{pspicture}(2,1)(0,0)% +\psline(1,0.5)(0.460099,0.0671161) +\psset{fillcolor=rgb_000000}% +\pspolygon[fillstyle=solid](0.513324,0.109791)(0.500341,0.125984) + (0.460099,0.0671161)(0.526308,0.093598)(0.513324,0.109791) +\psline(1,0.5)(2.30211,0.383998) +\pspolygon[fillstyle=solid](2.19255,0.39376)(2.1907,0.373086) + (2.30211,0.383998)(2.19439,0.414433)(2.19255,0.39376) +\psset{fillcolor=cmy_5e5eff}% +\psset{linecolor=rgb_2020a0}% +\pspolygon[fillstyle=solid](1.21563,0.452275)(1.23301,0.375451) + (1.17732,0.388446)(1.12142,0.416397)(1.11204,0.483169) + (1.164,0.462409)(1.21563,0.452275) +\psset{fillcolor=cmy_5858ff}% +\psset{linecolor=rgb_2121a6}% +\pspolygon[fillstyle=solid](1.31978,0.464555)(1.34701,0.395075) + (1.28931,0.377672)(1.23301,0.375451)(1.21563,0.452275) + (1.26742,0.453019)(1.31978,0.464555) +\psset{fillcolor=cmy_6969ff}% +\psset{linecolor=rgb_1d1d95}% +\pspolygon[fillstyle=solid](1.11204,0.483169)(1.12142,0.416397) + (1.0645,0.458716)(1.0058,0.514406)(1.0053,0.553791) + (1.05928,0.513957)(1.11204,0.483169) +\psset{fillcolor=cmy_5e5eff}% +\psset{linecolor=rgb_2020a0}% +\pspolygon[fillstyle=solid](1.42762,0.517893)(1.46924,0.473639) + (1.40679,0.427311)(1.34701,0.395075)(1.31978,0.464555) + (1.3731,0.486452)(1.42762,0.517893) +\psset{fillcolor=cmy_7676ff}% +\psset{linecolor=rgb_1b1b88}% +\pspolygon[fillstyle=solid](1.0053,0.553791)(1.0058,0.514406) + (0.944617,0.581935)(0.880444,0.659087)(0.892338,0.65446) + (0.949725,0.601259)(1.0053,0.553791) +\psset{fillcolor=cmy_6565ff}% +\psset{linecolor=rgb_1e1e99}% +\pspolygon[fillstyle=solid](1.19425,0.509734)(1.21563,0.452275) + (1.164,0.462409)(1.11204,0.483169)(1.10071,0.531856) + (1.14768,0.517332)(1.19425,0.509734) +\psset{fillcolor=cmy_6161ff}% +\psset{linecolor=rgb_1f1f9d}% +\pspolygon[fillstyle=solid](1.28699,0.515829)(1.31978,0.464555) + (1.26742,0.453019)(1.21563,0.452275)(1.19425,0.509734) + (1.24062,0.509263)(1.28699,0.515829) +\psset{fillcolor=cmy_6f6fff}% +\psset{linecolor=rgb_1c1c8f}% +\pspolygon[fillstyle=solid](1.10071,0.531856)(1.11204,0.483169) + (1.05928,0.513957)(1.0053,0.553791)(1.00473,0.579391) + (1.05312,0.552809)(1.10071,0.531856) +\psset{fillcolor=cmy_6666ff}% +\psset{linecolor=rgb_1e1e98}% +\pspolygon[fillstyle=solid](1.38015,0.548201)(1.42762,0.517893) + (1.3731,0.486452)(1.31978,0.464555)(1.28699,0.515829) + (1.33349,0.529041)(1.38015,0.548201) +\psset{fillcolor=cmy_6c6cff}% +\psset{linecolor=rgb_1d1d92}% +\pspolygon[fillstyle=solid](1.54036,0.603855)(1.60334,0.602838) + (1.53472,0.5328)(1.46924,0.473639)(1.42762,0.517893) + (1.48342,0.557617)(1.54036,0.603855) +\psset{fillcolor=cmy_7979ff}% +\psset{linecolor=rgb_1a1a85}% +\pspolygon[fillstyle=solid](1.00473,0.579391)(1.0053,0.553791) + (0.949725,0.601259)(0.892338,0.65446)(0.905094,0.644715) + (0.955399,0.610498)(1.00473,0.579391) +\psset{fillcolor=cmy_7f7fff}% +\psset{linecolor=rgb_19197f}% +\pspolygon[fillstyle=solid](0.892338,0.65446)(0.880444,0.659087) + (0.812994,0.742797)(0.742326,0.82905)(0.772133,0.767878) + (0.833083,0.710977)(0.892338,0.65446) +\psset{fillcolor=cmy_7070ff}% +\psset{linecolor=rgb_1c1c8e}% +\pspolygon[fillstyle=solid](1.1691,0.547312)(1.19425,0.509734) + (1.14768,0.517332)(1.10071,0.531856)(1.08754,0.562251) + (1.12854,0.552782)(1.1691,0.547312) +\psset{fillcolor=cmy_7777ff}% +\psset{linecolor=rgb_1b1b87}% +\pspolygon[fillstyle=solid](1.08754,0.562251)(1.10071,0.531856) + (1.05312,0.552809)(1.00473,0.579391)(1.00408,0.591586) + (1.04606,0.57537)(1.08754,0.562251) +\psset{fillcolor=cmy_6d6dff}% +\psset{linecolor=rgb_1d1d91}% +\pspolygon[fillstyle=solid](1.24902,0.548712)(1.28699,0.515829) + (1.24062,0.509263)(1.19425,0.509734)(1.1691,0.547312) + (1.20925,0.545979)(1.24902,0.548712) +\psset{fillcolor=cmy_7f7fff}% +\psset{linecolor=rgb_19197f}% +\pspolygon[fillstyle=solid](0.905094,0.644715)(0.892338,0.65446) + (0.833083,0.710977)(0.772133,0.767878)(0.801956,0.715411) + (0.853879,0.680337)(0.905094,0.644715) +\psset{fillcolor=cmy_7171ff}% +\psset{linecolor=rgb_1c1c8d}% +\pspolygon[fillstyle=solid](1.47358,0.599945)(1.54036,0.603855) + (1.48342,0.557617)(1.42762,0.517893)(1.38015,0.548201) + (1.42692,0.572286)(1.47358,0.599945) +\psset{fillcolor=cmy_7d7dff}% +\psset{linecolor=rgb_191981}% +\pspolygon[fillstyle=solid](1.00408,0.591586)(1.00473,0.579391) + (0.955399,0.610498)(0.905094,0.644715)(0.918709,0.630156) + (0.961612,0.610155)(1.00408,0.591586) +\psset{fillcolor=cmy_7171ff}% +\psset{linecolor=rgb_1c1c8d}% +\pspolygon[fillstyle=solid](1.32731,0.565028)(1.38015,0.548201) + (1.33349,0.529041)(1.28699,0.515829)(1.24902,0.548712) + (1.2884,0.555226)(1.32731,0.565028) +\psset{fillcolor=cmy_7878ff}% +\psset{linecolor=rgb_1a1a86}% +\pspolygon[fillstyle=solid](0.772133,0.767878)(0.742326,0.82905) + (0.668933,0.912872)(0.593817,0.988506)(0.647182,0.869075) + (0.709925,0.821791)(0.772133,0.767878) +\psset{fillcolor=cmy_7e7eff}% +\psset{linecolor=rgb_191980}% +\pspolygon[fillstyle=solid](0.918709,0.630156)(0.905094,0.644715) + (0.853879,0.680337)(0.801956,0.715411)(0.832163,0.670073) + (0.875495,0.650521)(0.918709,0.630156) +\psset{fillcolor=cmy_7b7bff}% +\psset{linecolor=rgb_1a1a83}% +\pspolygon[fillstyle=solid](1.14055,0.565734)(1.1691,0.547312) + (1.12854,0.552782)(1.08754,0.562251)(1.07271,0.575185) + (1.10684,0.569509)(1.14055,0.565734) +\psset{fillcolor=cmy_7979ff}% +\psset{linecolor=rgb_1a1a85}% +\pspolygon[fillstyle=solid](1.65578,0.705915)(1.74819,0.763081) + (1.67477,0.680906)(1.60334,0.602838)(1.54036,0.603855) + (1.59806,0.654266)(1.65578,0.705915) +\psset{fillcolor=cmy_7d7dff}% +\psset{linecolor=rgb_191981}% +\pspolygon[fillstyle=solid](1.07271,0.575185)(1.08754,0.562251) + (1.04606,0.57537)(1.00408,0.591586)(1.00338,0.591308) + (1.0382,0.582558)(1.07271,0.575185) +\psset{fillcolor=cmy_7575ff}% +\psset{linecolor=rgb_1b1b89}% +\pspolygon[fillstyle=solid](0.801956,0.715411)(0.772133,0.767878) + (0.709925,0.821791)(0.647182,0.869075)(0.697531,0.775355) + (0.749674,0.74781)(0.801956,0.715411) +\psset{fillcolor=cmy_7a7aff}% +\psset{linecolor=rgb_1a1a84}% +\pspolygon[fillstyle=solid](1.2064,0.564093)(1.24902,0.548712) + (1.20925,0.545979)(1.1691,0.547312)(1.14055,0.565734) + (1.17375,0.563943)(1.2064,0.564093) +\psset{fillcolor=cmy_7878ff}% +\psset{linecolor=rgb_1a1a86}% +\pspolygon[fillstyle=solid](1.40315,0.59151)(1.47358,0.599945) + (1.42692,0.572286)(1.38015,0.548201)(1.32731,0.565028) + (1.36563,0.577419)(1.40315,0.59151) +\psset{fillcolor=cmy_7f7fff}% +\psset{linecolor=rgb_19197f}% +\pspolygon[fillstyle=solid](1.00338,0.591308)(1.00408,0.591586) + (0.961612,0.610155)(0.918709,0.630156)(0.933183,0.611153) + (0.968339,0.601011)(1.00338,0.591308) +\psset{fillcolor=cmy_6c6cff}% +\psset{linecolor=rgb_1d1d92}% +\pspolygon[fillstyle=solid](0.189032,0.289372)(0.105002,0.195832) + (0.106173,0.133184)(0.107102,0.0871823)(0.187635,0.204779) + (0.187646,0.241139)(0.189032,0.289372) +\psset{fillcolor=cmy_7c7cff}% +\psset{linecolor=rgb_1a1a82}% +\pspolygon[fillstyle=solid](1.26963,0.569425)(1.32731,0.565028) + (1.2884,0.555226)(1.24902,0.548712)(1.2064,0.564093) + (1.23839,0.566016)(1.26963,0.569425) +\psset{fillcolor=cmy_7171ff}% +\psset{linecolor=rgb_1c1c8d}% +\pspolygon[fillstyle=solid](0.832163,0.670073)(0.801956,0.715411) + (0.749674,0.74781)(0.697531,0.775355)(0.746272,0.701846) + (0.788976,0.687585)(0.832163,0.670073) +\psset{fillcolor=cmy_7c7cff}% +\psset{linecolor=rgb_1a1a82}% +\pspolygon[fillstyle=solid](1.56495,0.658972)(1.65578,0.705915) + (1.59806,0.654266)(1.54036,0.603855)(1.47358,0.599945) + (1.51977,0.629498)(1.56495,0.658972) +\psset{fillcolor=cmy_4949ff}% +\psset{linecolor=rgb_2424b5}% +\pspolygon[fillstyle=solid](0.19769,0.416171)(0.10474,0.365653) + (0.104222,0.273918)(0.105002,0.195832)(0.189032,0.289372) + (0.192187,0.348273)(0.19769,0.416171) +\psset{fillcolor=cmy_7b7bff}% +\psset{linecolor=rgb_1a1a83}% +\pspolygon[fillstyle=solid](0.933183,0.611153)(0.918709,0.630156) + (0.875495,0.650521)(0.832163,0.670073)(0.863092,0.630402) + (0.898045,0.621157)(0.933183,0.611153) +\psset{fillcolor=cmy_5656ff}% +\psset{linecolor=rgb_2121a8}% +\pspolygon[fillstyle=solid](0.647182,0.869075)(0.593817,0.988506) + (0.518501,1.04983)(0.444947,1.09101)(0.524261,0.929508) + (0.584894,0.90608)(0.647182,0.869075) +\psset{fillcolor=cmy_5353ff}% +\psset{linecolor=rgb_2222ab}% +\pspolygon[fillstyle=solid](0.697531,0.775355)(0.647182,0.869075) + (0.584894,0.90608)(0.524261,0.929508)(0.596275,0.807827) + (0.646156,0.795963)(0.697531,0.775355) +\psset{fillcolor=cmy_7d7dff}% +\psset{linecolor=rgb_191981}% +\pspolygon[fillstyle=solid](0.187635,0.204779)(0.107102,0.0871823) + (0.107428,0.0586308)(0.107074,0.0480454)(0.191172,0.170524) + (0.188802,0.181093)(0.187635,0.204779) +\psset{fillcolor=cmy_7e7eff}% +\psset{linecolor=rgb_191980}% +\pspolygon[fillstyle=solid](1.32922,0.579024)(1.40315,0.59151) + (1.36563,0.577419)(1.32731,0.565028)(1.26963,0.569425) + (1.29996,0.573925)(1.32922,0.579024) +\psset{fillcolor=cmy_6c6cff}% +\psset{linecolor=rgb_1d1d92}% +\pspolygon[fillstyle=solid](0.863092,0.630402)(0.832163,0.670073) + (0.788976,0.687585)(0.746272,0.701846)(0.794552,0.644134) + (0.828519,0.638261)(0.863092,0.630402) +\psset{fillcolor=cmy_7f7fff}% +\psset{linecolor=rgb_19197f}% +\pspolygon[fillstyle=solid](1.109,0.566914)(1.14055,0.565734) + (1.10684,0.569509)(1.07271,0.575185)(1.05638,0.57247) + (1.08289,0.569392)(1.109,0.566914) +\psset{fillcolor=cmy_7e7eff}% +\psset{linecolor=rgb_191980}% +\pspolygon[fillstyle=solid](1.05638,0.57247)(1.07271,0.575185) + (1.0382,0.582558)(1.00338,0.591308)(1.00261,0.579992) + (1.02959,0.576053)(1.05638,0.57247) +\pspolygon[fillstyle=solid](1.47456,0.620443)(1.56495,0.658972) + (1.51977,0.629498)(1.47358,0.599945)(1.40315,0.59151) + (1.43958,0.606246)(1.47456,0.620443) +\psset{fillcolor=cmy_5050ff}% +\psset{linecolor=rgb_2222ae}% +\pspolygon[fillstyle=solid](0.746272,0.701846)(0.697531,0.775355) + (0.646156,0.795963)(0.596275,0.807827)(0.663929,0.71633) + (0.704444,0.711739)(0.746272,0.701846) +\psset{fillcolor=cmy_2323ff}% +\psset{linecolor=rgb_2b2bdb}% +\pspolygon[fillstyle=solid](0.218731,0.569601)(0.114562,0.578881) + (0.107723,0.468479)(0.10474,0.365653)(0.19769,0.416171) + (0.206264,0.490868)(0.218731,0.569601) +\psset{fillcolor=cmy_7b7bff}% +\psset{linecolor=rgb_1a1a83}% +\pspolygon[fillstyle=solid](1.00261,0.579992)(1.00338,0.591308) + (0.968339,0.601011)(0.933183,0.611153)(0.948523,0.588133) + (0.975553,0.584095)(1.00261,0.579992) +\psset{fillcolor=cmy_7f7fff}% +\psset{linecolor=rgb_19197f}% +\pspolygon[fillstyle=solid](1.1597,0.563866)(1.2064,0.564093) + (1.17375,0.563943)(1.14055,0.565734)(1.109,0.566914) + (1.13464,0.565078)(1.1597,0.563866) +\psset{fillcolor=cmy_7474ff}% +\psset{linecolor=rgb_1b1b8a}% +\pspolygon[fillstyle=solid](0.948523,0.588133)(0.933183,0.611153) + (0.898045,0.621157)(0.863092,0.630402)(0.895059,0.594987) + (0.921647,0.591852)(0.948523,0.588133) +\psset{fillcolor=cmy_2828ff}% +\psset{linecolor=rgb_2a2ad6}% +\pspolygon[fillstyle=solid](0.524261,0.929508)(0.444947,1.09101) + (0.375363,1.10732)(0.311925,1.09597)(0.413159,0.926478) + (0.466591,0.936797)(0.524261,0.929508) +\psset{fillcolor=cmy_7f7fff}% +\psset{linecolor=rgb_19197f}% +\pspolygon[fillstyle=solid](1.20765,0.562964)(1.26963,0.569425) + (1.23839,0.566016)(1.2064,0.564093)(1.1597,0.563866) + (1.18407,0.563204)(1.20765,0.562964) +\psset{fillcolor=cmy_4f4fff}% +\psset{linecolor=rgb_2323af}% +\pspolygon[fillstyle=solid](0.794552,0.644134)(0.746272,0.701846) + (0.704444,0.711739)(0.663929,0.71633)(0.729448,0.647866) + (0.761441,0.647482)(0.794552,0.644134) +\psset{fillcolor=cmy_2828ff}% +\psset{linecolor=rgb_2a2ad6}% +\pspolygon[fillstyle=solid](0.596275,0.807827)(0.524261,0.929508) + (0.466591,0.936797)(0.413159,0.926478)(0.504048,0.800507) + (0.548656,0.809592)(0.596275,0.807827) +\psset{fillcolor=cmy_2929ff}% +\psset{linecolor=rgb_2a2ad5}% +\pspolygon[fillstyle=solid](0.663929,0.71633)(0.596275,0.807827) + (0.548656,0.809592)(0.504048,0.800507)(0.58863,0.707203) + (0.625178,0.714938)(0.663929,0.71633) +\psset{fillcolor=cmy_3f3fff}% +\psset{linecolor=rgb_2626bf}% +\pspolygon[fillstyle=solid](0.298804,0.454436)(0.19769,0.416171) + (0.192187,0.348273)(0.189032,0.289372)(0.285765,0.364096) + (0.29087,0.406486)(0.298804,0.454436) +\psset{fillcolor=cmy_6666ff}% +\psset{linecolor=rgb_1e1e98}% +\pspolygon[fillstyle=solid](0.895059,0.594987)(0.863092,0.630402) + (0.828519,0.638261)(0.794552,0.644134)(0.84333,0.598464) + (0.868903,0.597273)(0.895059,0.594987) +\psset{fillcolor=cmy_7f7fff}% +\psset{linecolor=rgb_19197f}% +\pspolygon[fillstyle=solid](1.38364,0.588709)(1.47456,0.620443) + (1.43958,0.606246)(1.40315,0.59151)(1.32922,0.579024) + (1.35719,0.584157)(1.38364,0.588709) +\psset{fillcolor=cmy_6464ff}% +\psset{linecolor=rgb_1e1e9a}% +\pspolygon[fillstyle=solid](0.285765,0.364096)(0.189032,0.289372) + (0.187646,0.241139)(0.187635,0.204779)(0.282956,0.300896) + (0.283191,0.328573)(0.285765,0.364096) +\psset{fillcolor=cmy_0909ff}% +\psset{linecolor=rgb_3131f5}% +\pspolygon[fillstyle=solid](0.258703,0.72553)(0.145957,0.803098) + (0.126792,0.692284)(0.114562,0.578881)(0.218731,0.569601) + (0.235947,0.649066)(0.258703,0.72553) +\psset{fillcolor=cmy_7e7eff}% +\psset{linecolor=rgb_191980}% +\pspolygon[fillstyle=solid](1.2519,0.563022)(1.32922,0.579024) + (1.29996,0.573925)(1.26963,0.569425)(1.20765,0.562964) + (1.2303,0.562975)(1.2519,0.563022) +\psset{fillcolor=cmy_7f7fff}% +\psset{linecolor=rgb_19197f}% +\pspolygon[fillstyle=solid](1.76674,0.798575)(1.89443,0.91833) + (1.82212,0.844276)(1.74819,0.763081)(1.65578,0.705915) + (1.71247,0.755316)(1.76674,0.798575) +\psset{fillcolor=cmy_1b1bff}% +\psset{linecolor=rgb_2d2de3}% +\pspolygon[fillstyle=solid](0.324666,0.560164)(0.218731,0.569601) + (0.206264,0.490868)(0.19769,0.416171)(0.298804,0.454436) + (0.309934,0.506308)(0.324666,0.560164) +\psset{fillcolor=cmy_2d2dff}% +\psset{linecolor=rgb_2929d1}% +\pspolygon[fillstyle=solid](0.729448,0.647866)(0.663929,0.71633) + (0.625178,0.714938)(0.58863,0.707203)(0.669881,0.638666) + (0.698841,0.644979)(0.729448,0.647866) +\psset{fillcolor=cmy_0909ff}% +\psset{linecolor=rgb_3131f5}% +\pspolygon[fillstyle=solid](0.413159,0.926478)(0.311925,1.09597) + (0.256452,1.05661)(0.210141,0.991471)(0.323082,0.85378) + (0.36506,0.8984)(0.413159,0.926478) +\psset{fillcolor=cmy_0a0aff}% +\psset{linecolor=rgb_3030f4}% +\pspolygon[fillstyle=solid](0.504048,0.800507)(0.413159,0.926478) + (0.36506,0.8984)(0.323082,0.85378)(0.426348,0.750295) + (0.463108,0.78052)(0.504048,0.800507) +\psset{fillcolor=cmy_7f7fff}% +\psset{linecolor=rgb_19197f}% +\pspolygon[fillstyle=solid](1.6493,0.708781)(1.76674,0.798575) + (1.71247,0.755316)(1.65578,0.705915)(1.56495,0.658972) + (1.60841,0.686169)(1.6493,0.708781) +\psset{fillcolor=cmy_5050ff}% +\psset{linecolor=rgb_2222ae}% +\pspolygon[fillstyle=solid](0.84333,0.598464)(0.794552,0.644134) + (0.761441,0.647482)(0.729448,0.647866)(0.794573,0.596748) + (0.818499,0.598346)(0.84333,0.598464) +\psset{fillcolor=cmy_0d0dff}% +\psset{linecolor=rgb_3030f1}% +\pspolygon[fillstyle=solid](0.58863,0.707203)(0.504048,0.800507) + (0.463108,0.78052)(0.426348,0.750295)(0.523665,0.673044) + (0.554683,0.693119)(0.58863,0.707203) +\psset{fillcolor=cmy_0606ff}% +\psset{linecolor=rgb_3131f8}% +\pspolygon[fillstyle=solid](0.366464,0.664928)(0.258703,0.72553) + (0.235947,0.649066)(0.218731,0.569601)(0.324666,0.560164) + (0.343397,0.613816)(0.366464,0.664928) +\psset{fillcolor=cmy_0000ff}% +\psset{linecolor=rgb_3232fe}% +\pspolygon[fillstyle=solid](0.323082,0.85378)(0.210141,0.991471) + (0.173421,0.904998)(0.145957,0.803098)(0.258703,0.72553) + (0.287629,0.795046)(0.323082,0.85378) +\psset{fillcolor=cmy_7474ff}% +\psset{linecolor=rgb_1b1b8a}% +\pspolygon[fillstyle=solid](1.03875,0.556754)(1.05638,0.57247) + (1.02959,0.576053)(1.00261,0.579992)(1.00179,0.559495) + (1.02033,0.558175)(1.03875,0.556754) +\psset{fillcolor=cmy_7676ff}% +\psset{linecolor=rgb_1b1b88}% +\pspolygon[fillstyle=solid](1.07488,0.553783)(1.109,0.566914) + (1.08289,0.569392)(1.05638,0.57247)(1.03875,0.556754) + (1.05696,0.555279)(1.07488,0.553783) +\psset{fillcolor=cmy_7171ff}% +\psset{linecolor=rgb_1c1c8d}% +\pspolygon[fillstyle=solid](1.00179,0.559495)(1.00261,0.579992) + (0.975553,0.584095)(0.948523,0.588133)(0.964748,0.561577) + (0.983236,0.560652)(1.00179,0.559495) +\psset{fillcolor=cmy_0000ff}% +\psset{linecolor=rgb_3232fe}% +\pspolygon[fillstyle=solid](0.426348,0.750295)(0.323082,0.85378) + (0.287629,0.795046)(0.258703,0.72553)(0.366464,0.664928) + (0.394092,0.711151)(0.426348,0.750295) +\psset{fillcolor=cmy_7e7eff}% +\psset{linecolor=rgb_191980}% +\pspolygon[fillstyle=solid](1.53831,0.642183)(1.6493,0.708781) + (1.60841,0.686169)(1.56495,0.658972)(1.47456,0.620443) + (1.50763,0.632843)(1.53831,0.642183) +\psset{fillcolor=cmy_7777ff}% +\psset{linecolor=rgb_1b1b87}% +\pspolygon[fillstyle=solid](1.10948,0.550772)(1.1597,0.563866) + (1.13464,0.565078)(1.109,0.566914)(1.07488,0.553783) + (1.09241,0.552281)(1.10948,0.550772) +\psset{fillcolor=cmy_6a6aff}% +\psset{linecolor=rgb_1d1d94}% +\pspolygon[fillstyle=solid](0.964748,0.561577)(0.948523,0.588133) + (0.921647,0.591852)(0.895059,0.594987)(0.92836,0.562423) + (0.946423,0.562194)(0.964748,0.561577) +\psset{fillcolor=cmy_1515ff}% +\psset{linecolor=rgb_2e2ee9}% +\pspolygon[fillstyle=solid](0.669881,0.638666)(0.58863,0.707203) + (0.554683,0.693119)(0.523665,0.673044)(0.617846,0.615994) + (0.642811,0.628942)(0.669881,0.638666) +\psset{fillcolor=cmy_0101ff}% +\psset{linecolor=rgb_3232fd}% +\pspolygon[fillstyle=solid](0.523665,0.673044)(0.426348,0.750295) + (0.394092,0.711151)(0.366464,0.664928)(0.471308,0.617992) + (0.495823,0.647676)(0.523665,0.673044) +\psset{fillcolor=cmy_3838ff}% +\psset{linecolor=rgb_2727c6}% +\pspolygon[fillstyle=solid](0.794573,0.596748)(0.729448,0.647866) + (0.698841,0.644979)(0.669881,0.638666)(0.750078,0.58872) + (0.771713,0.593556)(0.794573,0.596748) +\psset{fillcolor=cmy_7b7bff}% +\psset{linecolor=rgb_1a1a83}% +\pspolygon[fillstyle=solid](1.29137,0.562256)(1.38364,0.588709) + (1.35719,0.584157)(1.32922,0.579024)(1.2519,0.563022) + (1.27231,0.562867)(1.29137,0.562256) +\psset{fillcolor=cmy_7e7eff}% +\psset{linecolor=rgb_191980}% +\pspolygon[fillstyle=solid](0.191172,0.170524)(0.107074,0.0480454) + (0.106268,0.0557124)(0.105573,0.08167)(0.20082,0.188793) + (0.195007,0.173177)(0.191172,0.170524) +\psset{fillcolor=cmy_7979ff}% +\psset{linecolor=rgb_1a1a85}% +\pspolygon[fillstyle=solid](0.282956,0.300896)(0.187635,0.204779) + (0.188802,0.181093)(0.191172,0.170524)(0.28937,0.271374) + (0.284992,0.281718)(0.282956,0.300896) +\psset{fillcolor=cmy_7676ff}% +\psset{linecolor=rgb_1b1b88}% +\pspolygon[fillstyle=solid](1.14185,0.547647)(1.20765,0.562964) + (1.18407,0.563204)(1.1597,0.563866)(1.10948,0.550772) + (1.12599,0.549239)(1.14185,0.547647) +\psset{fillcolor=cmy_0505ff}% +\psset{linecolor=rgb_3131f9}% +\pspolygon[fillstyle=solid](0.471308,0.617992)(0.366464,0.664928) + (0.343397,0.613816)(0.324666,0.560164)(0.432412,0.550565) + (0.450178,0.585184)(0.471308,0.617992) +\psset{fillcolor=cmy_6161ff}% +\psset{linecolor=rgb_1f1f9d}% +\pspolygon[fillstyle=solid](0.92836,0.562423)(0.895059,0.594987) + (0.868903,0.597273)(0.84333,0.598464)(0.893412,0.561425) + (0.910657,0.56219)(0.92836,0.562423) +\psset{fillcolor=cmy_1616ff}% +\psset{linecolor=rgb_2e2ee8}% +\pspolygon[fillstyle=solid](0.432412,0.550565)(0.324666,0.560164) + (0.309934,0.506308)(0.298804,0.454436)(0.406584,0.481275) + (0.417922,0.515489)(0.432412,0.550565) +\psset{fillcolor=cmy_7b7bff}% +\psset{linecolor=rgb_1a1a83}% +\pspolygon[fillstyle=solid](1.43089,0.593568)(1.53831,0.642183) + (1.50763,0.632843)(1.47456,0.620443)(1.38364,0.588709) + (1.40831,0.592049)(1.43089,0.593568) +\psset{fillcolor=cmy_0909ff}% +\psset{linecolor=rgb_3131f5}% +\pspolygon[fillstyle=solid](0.617846,0.615994)(0.523665,0.673044) + (0.495823,0.647676)(0.471308,0.617992)(0.574906,0.58195) + (0.595165,0.600168)(0.617846,0.615994) +\psset{fillcolor=cmy_3636ff}% +\psset{linecolor=rgb_2828c8}% +\pspolygon[fillstyle=solid](0.406584,0.481275)(0.298804,0.454436) + (0.29087,0.406486)(0.285765,0.364096)(0.392802,0.420142) + (0.398255,0.449137)(0.406584,0.481275) +\psset{fillcolor=cmy_2626ff}% +\psset{linecolor=rgb_2b2bd8}% +\pspolygon[fillstyle=solid](0.750078,0.58872)(0.669881,0.638666) + (0.642811,0.628942)(0.617846,0.615994)(0.711075,0.574268) + (0.729819,0.582261)(0.750078,0.58872) +\psset{fillcolor=cmy_5555ff}% +\psset{linecolor=rgb_2121a9}% +\pspolygon[fillstyle=solid](0.893412,0.561425)(0.84333,0.598464) + (0.818499,0.598346)(0.794573,0.596748)(0.860696,0.558086) + (0.876726,0.560071)(0.893412,0.561425) +\psset{fillcolor=cmy_7474ff}% +\psset{linecolor=rgb_1b1b8a}% +\pspolygon[fillstyle=solid](1.17127,0.54409)(1.2519,0.563022) + (1.2303,0.562975)(1.20765,0.562964)(1.14185,0.547647) + (1.15697,0.54595)(1.17127,0.54409) +\psset{fillcolor=cmy_0b0bff}% +\psset{linecolor=rgb_3030f3}% +\pspolygon[fillstyle=solid](0.574906,0.58195)(0.471308,0.617992) + (0.450178,0.585184)(0.432412,0.550565)(0.542015,0.540801) + (0.557169,0.561937)(0.574906,0.58195) +\psset{fillcolor=cmy_4848ff}% +\psset{linecolor=rgb_2424b6}% +\pspolygon[fillstyle=solid](0.860696,0.558086)(0.794573,0.596748) + (0.771713,0.593556)(0.750078,0.58872)(0.830997,0.552142) + (0.845422,0.555444)(0.860696,0.558086) +\psset{fillcolor=cmy_5a5aff}% +\psset{linecolor=rgb_2020a4}% +\pspolygon[fillstyle=solid](0.392802,0.420142)(0.285765,0.364096) + (0.283191,0.328573)(0.282956,0.300896)(0.390156,0.374904) + (0.390121,0.395173)(0.392802,0.420142) +\psset{fillcolor=cmy_7575ff}% +\psset{linecolor=rgb_1b1b89}% +\pspolygon[fillstyle=solid](1.32484,0.558669)(1.43089,0.593568) + (1.40831,0.592049)(1.38364,0.588709)(1.29137,0.562256) + (1.30893,0.560936)(1.32484,0.558669) +\psset{fillcolor=cmy_1c1cff}% +\psset{linecolor=rgb_2d2de2}% +\pspolygon[fillstyle=solid](0.711075,0.574268)(0.617846,0.615994) + (0.595165,0.600168)(0.574906,0.58195)(0.678618,0.554358) + (0.693971,0.564896)(0.711075,0.574268) +\psset{fillcolor=cmy_7171ff}% +\psset{linecolor=rgb_1c1c8d}% +\pspolygon[fillstyle=solid](1.19703,0.539628)(1.29137,0.562256) + (1.27231,0.562867)(1.2519,0.563022)(1.17127,0.54409) + (1.18465,0.542005)(1.19703,0.539628) +\psset{fillcolor=cmy_1818ff}% +\psset{linecolor=rgb_2e2ee6}% +\pspolygon[fillstyle=solid](0.542015,0.540801)(0.432412,0.550565) + (0.417922,0.515489)(0.406584,0.481275)(0.519554,0.497979) + (0.529474,0.519246)(0.542015,0.540801) +\psset{fillcolor=cmy_3d3dff}% +\psset{linecolor=rgb_2626c1}% +\pspolygon[fillstyle=solid](0.830997,0.552142)(0.750078,0.58872) + (0.729819,0.582261)(0.711075,0.574268)(0.805053,0.543639) + (0.817512,0.548194)(0.830997,0.552142) +\psset{fillcolor=cmy_6666ff}% +\psset{linecolor=rgb_1e1e98}% +\pspolygon[fillstyle=solid](1.01993,0.53134)(1.03875,0.556754) + (1.02033,0.558175)(1.00179,0.559495)(1.00092,0.532012) + (1.01046,0.531756)(1.01993,0.53134) +\psset{fillcolor=cmy_6565ff}% +\psset{linecolor=rgb_1e1e99}% +\pspolygon[fillstyle=solid](1.00092,0.532012)(1.00179,0.559495) + (0.983236,0.560652)(0.964748,0.561577)(0.98189,0.532011) + (0.991382,0.5321)(1.00092,0.532012) +\psset{fillcolor=cmy_6868ff}% +\psset{linecolor=rgb_1e1e96}% +\pspolygon[fillstyle=solid](1.03849,0.530055)(1.07488,0.553783) + (1.05696,0.555279)(1.03875,0.556754)(1.01993,0.53134) + (1.02929,0.53077)(1.03849,0.530055) +\psset{fillcolor=cmy_1c1cff}% +\psset{linecolor=rgb_2d2de2}% +\pspolygon[fillstyle=solid](0.678618,0.554358)(0.574906,0.58195) + (0.557169,0.561937)(0.542015,0.540801)(0.653524,0.530867) + (0.66511,0.542917)(0.678618,0.554358) +\psset{fillcolor=cmy_6262ff}% +\psset{linecolor=rgb_1f1f9c}% +\pspolygon[fillstyle=solid](0.98189,0.532011)(0.964748,0.561577) + (0.946423,0.562194)(0.92836,0.562423)(0.963262,0.531266) + (0.972499,0.531735)(0.98189,0.532011) +\psset{fillcolor=cmy_6868ff}% +\psset{linecolor=rgb_1e1e96}% +\pspolygon[fillstyle=solid](1.05617,0.528201)(1.10948,0.550772) + (1.09241,0.552281)(1.07488,0.553783)(1.03849,0.530055) + (1.04746,0.529197)(1.05617,0.528201) +\psset{fillcolor=cmy_5e5eff}% +\psset{linecolor=rgb_2020a0}% +\pspolygon[fillstyle=solid](0.963262,0.531266)(0.92836,0.562423) + (0.910657,0.56219)(0.893412,0.561425)(0.945465,0.52972) + (0.954234,0.530596)(0.963262,0.531266) +\psset{fillcolor=cmy_3232ff}% +\psset{linecolor=rgb_2828cc}% +\pspolygon[fillstyle=solid](0.519554,0.497979)(0.406584,0.481275) + (0.398255,0.449137)(0.392802,0.420142)(0.507551,0.458909) + (0.512249,0.477666)(0.519554,0.497979) +\psset{fillcolor=cmy_7575ff}% +\psset{linecolor=rgb_1b1b89}% +\pspolygon[fillstyle=solid](1.59029,0.647141)(1.71949,0.731475) + (1.68666,0.724552)(1.6493,0.708781)(1.53831,0.642183) + (1.56604,0.647284)(1.59029,0.647141) +\psset{fillcolor=cmy_6868ff}% +\psset{linecolor=rgb_1e1e96}% +\pspolygon[fillstyle=solid](1.07258,0.525802)(1.14185,0.547647) + (1.12599,0.549239)(1.10948,0.550772)(1.05617,0.528201) + (1.06456,0.527069)(1.07258,0.525802) +\psset{fillcolor=cmy_7070ff}% +\psset{linecolor=rgb_1c1c8e}% +\pspolygon[fillstyle=solid](1.46867,0.589042)(1.59029,0.647141) + (1.56604,0.647284)(1.53831,0.642183)(1.43089,0.593568) + (1.45111,0.592716)(1.46867,0.589042) +\psset{fillcolor=cmy_3737ff}% +\psset{linecolor=rgb_2727c7}% +\pspolygon[fillstyle=solid](0.805053,0.543639)(0.711075,0.574268) + (0.693971,0.564896)(0.678618,0.554358)(0.783529,0.532958) + (0.793701,0.538535)(0.805053,0.543639) +\psset{fillcolor=cmy_6c6cff}% +\psset{linecolor=rgb_1d1d92}% +\pspolygon[fillstyle=solid](1.21844,0.533751)(1.32484,0.558669) + (1.30893,0.560936)(1.29137,0.562256)(1.19703,0.539628) + (1.20832,0.536895)(1.21844,0.533751) +\psset{fillcolor=cmy_5959ff}% +\psset{linecolor=rgb_2121a5}% +\pspolygon[fillstyle=solid](0.945465,0.52972)(0.893412,0.561425) + (0.876726,0.560071)(0.860696,0.558086)(0.928911,0.52734) + (0.937007,0.528634)(0.945465,0.52972) +\psset{fillcolor=cmy_7878ff}% +\psset{linecolor=rgb_1a1a86}% +\pspolygon[fillstyle=solid](1.71949,0.731475)(1.86122,0.850819) + (1.81692,0.831665)(1.76674,0.798575)(1.6493,0.708781) + (1.68666,0.724552)(1.71949,0.731475) +\psset{fillcolor=cmy_6868ff}% +\psset{linecolor=rgb_1e1e96}% +\pspolygon[fillstyle=solid](1.08732,0.52286)(1.17127,0.54409) + (1.15697,0.54595)(1.14185,0.547647)(1.07258,0.525802) + (1.08018,0.524399)(1.08732,0.52286) +\psset{fillcolor=cmy_6a6aff}% +\psset{linecolor=rgb_1d1d94}% +\pspolygon[fillstyle=solid](1.35106,0.550511)(1.46867,0.589042) + (1.45111,0.592716)(1.43089,0.593568)(1.32484,0.558669) + (1.33893,0.555247)(1.35106,0.550511) +\psset{fillcolor=cmy_2525ff}% +\psset{linecolor=rgb_2b2bd9}% +\pspolygon[fillstyle=solid](0.653524,0.530867)(0.542015,0.540801) + (0.529474,0.519246)(0.519554,0.497979)(0.636366,0.506205) + (0.643926,0.518523)(0.653524,0.530867) +\psset{fillcolor=cmy_5454ff}% +\psset{linecolor=rgb_2222aa}% +\pspolygon[fillstyle=solid](0.928911,0.52734)(0.860696,0.558086) + (0.845422,0.555444)(0.830997,0.552142)(0.913992,0.524138) + (0.921223,0.525839)(0.928911,0.52734) +\psset{fillcolor=cmy_7373ff}% +\psset{linecolor=rgb_1b1b8b}% +\pspolygon[fillstyle=solid](0.390156,0.374904)(0.282956,0.300896) + (0.284992,0.281718)(0.28937,0.271374)(0.398466,0.350056) + (0.392913,0.35979)(0.390156,0.374904) +\psset{fillcolor=cmy_3636ff}% +\psset{linecolor=rgb_2828c8}% +\pspolygon[fillstyle=solid](0.783529,0.532958)(0.678618,0.554358) + (0.66511,0.542917)(0.653524,0.530867)(0.76699,0.520758) + (0.774605,0.526998)(0.783529,0.532958) +\psset{fillcolor=cmy_7979ff}% +\psset{linecolor=rgb_1a1a85}% +\pspolygon[fillstyle=solid](1.86122,0.850819)(2.0226,1.01759) + (1.96232,0.978383)(1.89443,0.91833)(1.76674,0.798575) + (1.81692,0.831665)(1.86122,0.850819) +\psset{fillcolor=cmy_6666ff}% +\psset{linecolor=rgb_1e1e98}% +\pspolygon[fillstyle=solid](1.10005,0.519369)(1.19703,0.539628) + (1.18465,0.542005)(1.17127,0.54409)(1.08732,0.52286) + (1.09396,0.521183)(1.10005,0.519369) +\psset{fillcolor=cmy_5050ff}% +\psset{linecolor=rgb_2222ae}% +\pspolygon[fillstyle=solid](0.913992,0.524138)(0.830997,0.552142) + (0.817512,0.548194)(0.805053,0.543639)(0.90107,0.520175) + (0.90726,0.522245)(0.913992,0.524138) +\psset{fillcolor=cmy_5151ff}% +\psset{linecolor=rgb_2222ad}% +\pspolygon[fillstyle=solid](0.507551,0.458909)(0.392802,0.420142) + (0.390121,0.395173)(0.390156,0.374904)(0.50598,0.427985) + (0.505457,0.442216)(0.507551,0.458909) +\psset{fillcolor=cmy_7f7fff}% +\psset{linecolor=rgb_19197f}% +\pspolygon[fillstyle=solid](0.28937,0.271374)(0.191172,0.170524) + (0.195007,0.173177)(0.20082,0.188793)(0.306183,0.276904) + (0.296309,0.269877)(0.28937,0.271374) +\psset{fillcolor=cmy_6363ff}% +\psset{linecolor=rgb_1f1f9b}% +\pspolygon[fillstyle=solid](1.23484,0.526055)(1.35106,0.550511) + (1.33893,0.555247)(1.32484,0.558669)(1.21844,0.533751) + (1.2273,0.530147)(1.23484,0.526055) +\psset{fillcolor=cmy_3737ff}% +\psset{linecolor=rgb_2727c7}% +\pspolygon[fillstyle=solid](0.636366,0.506205)(0.519554,0.497979) + (0.512249,0.477666)(0.507551,0.458909)(0.62752,0.482848) + (0.630886,0.49422)(0.636366,0.506205) +\psset{fillcolor=cmy_4d4dff}% +\psset{linecolor=rgb_2323b1}% +\pspolygon[fillstyle=solid](0.90107,0.520175)(0.805053,0.543639) + (0.793701,0.538535)(0.783529,0.532958)(0.890469,0.515566) + (0.895461,0.517942)(0.90107,0.520175) +\psset{fillcolor=cmy_6363ff}% +\psset{linecolor=rgb_1f1f9b}% +\pspolygon[fillstyle=solid](1.11043,0.515333)(1.21844,0.533751) + (1.20832,0.536895)(1.19703,0.539628)(1.10005,0.519369) + (1.10555,0.517419)(1.11043,0.515333) +\psset{fillcolor=cmy_3a3aff}% +\psset{linecolor=rgb_2727c4}% +\pspolygon[fillstyle=solid](0.76699,0.520758)(0.653524,0.530867) + (0.643926,0.518523)(0.636366,0.506205)(0.755889,0.507874) + (0.760736,0.514347)(0.76699,0.520758) +\psset{fillcolor=cmy_3c3cff}% +\psset{linecolor=rgb_2626c2}% +\pspolygon[fillstyle=solid](1.6438,0.0321256)(1.71591,-0.120081) + (1.76775,-0.074723)(1.81976,-0.0100767)(1.73326,0.116772) + (1.68934,0.0674669)(1.6438,0.0321256) +\psset{fillcolor=cmy_4b4bff}% +\psset{linecolor=rgb_2323b3}% +\pspolygon[fillstyle=solid](0.890469,0.515566)(0.783529,0.532958) + (0.774605,0.526998)(0.76699,0.520758)(0.882464,0.510471) + (0.886127,0.513068)(0.890469,0.515566) +\psset{fillcolor=cmy_5858ff}% +\psset{linecolor=rgb_2121a6}% +\pspolygon[fillstyle=solid](1.36891,0.536746)(1.49483,0.572133) + (1.48332,0.582232)(1.46867,0.589042)(1.35106,0.550511) + (1.36109,0.544356)(1.36891,0.536746) +\psset{fillcolor=cmy_5f5fff}% +\psset{linecolor=rgb_1f1f9f}% +\pspolygon[fillstyle=solid](1.1182,0.510778)(1.23484,0.526055) + (1.2273,0.530147)(1.21844,0.533751)(1.11043,0.515333) + (1.11466,0.513118)(1.1182,0.510778) +\psset{fillcolor=cmy_5b5bff}% +\psset{linecolor=rgb_2020a3}% +\pspolygon[fillstyle=solid](1.49483,0.572133)(1.62644,0.6285) + (1.61057,0.641013)(1.59029,0.647141)(1.46867,0.589042) + (1.48332,0.582232)(1.49483,0.572133) +\psset{fillcolor=cmy_5858ff}% +\psset{linecolor=rgb_2121a6}% +\pspolygon[fillstyle=solid](1.24569,0.516371)(1.36891,0.536746) + (1.36109,0.544356)(1.35106,0.550511)(1.23484,0.526055) + (1.24099,0.52146)(1.24569,0.516371) +\psset{fillcolor=cmy_5d5dff}% +\psset{linecolor=rgb_2020a1}% +\pspolygon[fillstyle=solid](1,0.5)(1.01993,0.53134) + (1.01046,0.531756)(1.00092,0.532012)(1,0.5) +\pspolygon[fillstyle=solid](1,0.5)(1.00092,0.532012) + (0.991382,0.5321)(0.98189,0.532011)(1,0.5) +\pspolygon[fillstyle=solid](1,0.5)(1.03849,0.530055) + (1.02929,0.53077)(1.01993,0.53134)(1,0.5) +\pspolygon[fillstyle=solid](1,0.5)(0.98189,0.532011) + (0.972499,0.531735)(0.963262,0.531266)(1,0.5) +\pspolygon[fillstyle=solid](1,0.5)(1.05617,0.528201) + (1.04746,0.529197)(1.03849,0.530055)(1,0.5) +\psset{fillcolor=cmy_5c5cff}% +\psset{linecolor=rgb_2020a2}% +\pspolygon[fillstyle=solid](1,0.5)(0.963262,0.531266) + (0.954234,0.530596)(0.945465,0.52972)(1,0.5) +\psset{fillcolor=cmy_4343ff}% +\psset{linecolor=rgb_2525bb}% +\pspolygon[fillstyle=solid](0.755889,0.507874)(0.636366,0.506205) + (0.630886,0.49422)(0.62752,0.482848)(0.750565,0.495176) + (0.752488,0.50145)(0.755889,0.507874) +\psset{fillcolor=cmy_5e5eff}% +\psset{linecolor=rgb_2020a0}% +\pspolygon[fillstyle=solid](1,0.5)(1.07258,0.525802) + (1.06456,0.527069)(1.05617,0.528201)(1,0.5) +\psset{fillcolor=cmy_5c5cff}% +\psset{linecolor=rgb_2020a2}% +\pspolygon[fillstyle=solid](1,0.5)(0.945465,0.52972) + (0.937007,0.528634)(0.928911,0.52734)(1,0.5) +\psset{fillcolor=cmy_4c4cff}% +\psset{linecolor=rgb_2323b2}% +\pspolygon[fillstyle=solid](0.882464,0.510471)(0.76699,0.520758) + (0.760736,0.514347)(0.755889,0.507874)(0.877275,0.505078) + (0.879506,0.507799)(0.882464,0.510471) +\pspolygon[fillstyle=solid](0.62752,0.482848)(0.507551,0.458909) + (0.505457,0.442216)(0.50598,0.427985)(0.627253,0.462871) + (0.6263,0.472334)(0.62752,0.482848) +\psset{fillcolor=cmy_5f5fff}% +\psset{linecolor=rgb_1f1f9f}% +\pspolygon[fillstyle=solid](1,0.5)(1.08732,0.52286) + (1.08018,0.524399)(1.07258,0.525802)(1,0.5) +\psset{fillcolor=cmy_5a5aff}% +\psset{linecolor=rgb_2020a4}% +\pspolygon[fillstyle=solid](1,0.5)(0.928911,0.52734) + (0.921223,0.525839)(0.913992,0.524138)(1,0.5) +\pspolygon[fillstyle=solid](1.12312,0.505768)(1.24569,0.516371) + (1.24099,0.52146)(1.23484,0.526055)(1.1182,0.510778) + (1.12103,0.508324)(1.12312,0.505768) +\psset{fillcolor=cmy_5e5eff}% +\psset{linecolor=rgb_2020a0}% +\pspolygon[fillstyle=solid](1.62644,0.6285)(1.76797,0.713246) + (1.74686,0.728005)(1.71949,0.731475)(1.59029,0.647141) + (1.61057,0.641013)(1.62644,0.6285) +\psset{fillcolor=cmy_6a6aff}% +\psset{linecolor=rgb_1d1d94}% +\pspolygon[fillstyle=solid](0.50598,0.427985)(0.390156,0.374904) + (0.392913,0.35979)(0.398466,0.350056)(0.515019,0.407859) + (0.509149,0.416487)(0.50598,0.427985) +\psset{fillcolor=cmy_5959ff}% +\psset{linecolor=rgb_2121a5}% +\pspolygon[fillstyle=solid](1,0.5)(0.913992,0.524138) + (0.90726,0.522245)(0.90107,0.520175)(1,0.5) +\psset{fillcolor=cmy_5f5fff}% +\psset{linecolor=rgb_1f1f9f}% +\pspolygon[fillstyle=solid](1,0.5)(1.10005,0.519369) + (1.09396,0.521183)(1.08732,0.52286)(1,0.5) +\psset{fillcolor=cmy_5252ff}% +\psset{linecolor=rgb_2222ac}% +\pspolygon[fillstyle=solid](1.54709,0.00607935)(1.61087,-0.15044) + (1.66387,-0.145468)(1.71591,-0.120081)(1.6438,0.0321256) + (1.59652,0.0115261)(1.54709,0.00607935) +\psset{fillcolor=cmy_5757ff}% +\psset{linecolor=rgb_2121a7}% +\pspolygon[fillstyle=solid](1,0.5)(0.90107,0.520175) + (0.895461,0.517942)(0.890469,0.515566)(1,0.5) +\psset{fillcolor=cmy_5e5eff}% +\psset{linecolor=rgb_2020a0}% +\pspolygon[fillstyle=solid](1,0.5)(1.11043,0.515333) + (1.10555,0.517419)(1.10005,0.519369)(1,0.5) +\psset{fillcolor=cmy_5050ff}% +\psset{linecolor=rgb_2222ae}% +\pspolygon[fillstyle=solid](0.877275,0.505078)(0.755889,0.507874) + (0.752488,0.50145)(0.750565,0.495176)(0.875059,0.499586) + (0.875788,0.502332)(0.877275,0.505078) +\psset{fillcolor=cmy_5656ff}% +\psset{linecolor=rgb_2121a8}% +\pspolygon[fillstyle=solid](1,0.5)(0.890469,0.515566) + (0.886127,0.513068)(0.882464,0.510471)(1,0.5) +\psset{fillcolor=cmy_5d5dff}% +\psset{linecolor=rgb_2020a1}% +\pspolygon[fillstyle=solid](1,0.5)(1.1182,0.510778) + (1.11466,0.513118)(1.11043,0.515333)(1,0.5) +\psset{fillcolor=cmy_2626ff}% +\psset{linecolor=rgb_2b2bd8}% +\pspolygon[fillstyle=solid](1.73326,0.116772)(1.81976,-0.0100767) + (1.87193,0.0727816)(1.92376,0.172159)(1.81542,0.25192) + (1.77544,0.178833)(1.73326,0.116772) +\psset{fillcolor=cmy_4b4bff}% +\psset{linecolor=rgb_2323b3}% +\pspolygon[fillstyle=solid](1.25055,0.504845)(1.37753,0.517385) + (1.37441,0.527719)(1.36891,0.536746)(1.24569,0.516371) + (1.24889,0.510816)(1.25055,0.504845) +\psset{fillcolor=cmy_5656ff}% +\psset{linecolor=rgb_2121a8}% +\pspolygon[fillstyle=solid](1,0.5)(0.882464,0.510471) + (0.879506,0.507799)(0.877275,0.505078)(1,0.5) +\psset{fillcolor=cmy_5b5bff}% +\psset{linecolor=rgb_2020a3}% +\pspolygon[fillstyle=solid](1,0.5)(1.12312,0.505768) + (1.12103,0.508324)(1.1182,0.510778)(1,0.5) +\psset{fillcolor=cmy_5454ff}% +\psset{linecolor=rgb_2222aa}% +\pspolygon[fillstyle=solid](1.12505,0.500414)(1.25055,0.504845) + (1.24889,0.510816)(1.24569,0.516371)(1.12312,0.505768) + (1.12447,0.503125)(1.12505,0.500414) +\psset{fillcolor=cmy_4f4fff}% +\psset{linecolor=rgb_2323af}% +\pspolygon[fillstyle=solid](0.750565,0.495176)(0.62752,0.482848) + (0.6263,0.472334)(0.627253,0.462871)(0.751245,0.483425) + (0.750144,0.489142)(0.750565,0.495176) +\psset{fillcolor=cmy_4141ff}% +\psset{linecolor=rgb_2525bd}% +\pspolygon[fillstyle=solid](1.37753,0.517385)(1.50776,0.542368) + (1.50301,0.558773)(1.49483,0.572133)(1.36891,0.536746) + (1.37441,0.527719)(1.37753,0.517385) +\psset{fillcolor=cmy_5757ff}% +\psset{linecolor=rgb_2121a7}% +\pspolygon[fillstyle=solid](1,0.5)(0.877275,0.505078) + (0.875788,0.502332)(0.875059,0.499586)(1,0.5) +\psset{fillcolor=cmy_5858ff}% +\psset{linecolor=rgb_2121a6}% +\pspolygon[fillstyle=solid](1,0.5)(1.12505,0.500414) + (1.12447,0.503125)(1.12312,0.505768)(1,0.5) +\psset{fillcolor=cmy_7e7eff}% +\psset{linecolor=rgb_191980}% +\pspolygon[fillstyle=solid](0.398466,0.350056)(0.28937,0.271374) + (0.296309,0.269877)(0.306183,0.276904)(0.418616,0.346439) + (0.406961,0.34569)(0.398466,0.350056) +\psset{fillcolor=cmy_5454ff}% +\psset{linecolor=rgb_2222aa}% +\pspolygon[fillstyle=solid](0.875059,0.499586)(0.750565,0.495176) + (0.750144,0.489142)(0.751245,0.483425)(0.875906,0.494186) + (0.875097,0.496864)(0.875059,0.499586) +\psset{fillcolor=cmy_5858ff}% +\psset{linecolor=rgb_2121a6}% +\pspolygon[fillstyle=solid](1,0.5)(0.875059,0.499586) + (0.875097,0.496864)(0.875906,0.494186)(1,0.5) +\psset{fillcolor=cmy_6161ff}% +\psset{linecolor=rgb_1f1f9d}% +\pspolygon[fillstyle=solid](1.76797,0.713246)(1.92548,0.836328) + (1.8979,0.852992)(1.86122,0.850819)(1.71949,0.731475) + (1.74686,0.728005)(1.76797,0.713246) +\psset{fillcolor=cmy_5656ff}% +\psset{linecolor=rgb_2121a8}% +\pspolygon[fillstyle=solid](1,0.5)(1.1239,0.494874) + (1.12486,0.497656)(1.12505,0.500414)(1,0.5) +\psset{fillcolor=cmy_3b3bff}% +\psset{linecolor=rgb_2727c3}% +\pspolygon[fillstyle=solid](1.50776,0.542368)(1.64384,0.584677) + (1.63759,0.609591)(1.62644,0.6285)(1.49483,0.572133) + (1.50301,0.558773)(1.50776,0.542368) +\psset{fillcolor=cmy_6161ff}% +\psset{linecolor=rgb_1f1f9d}% +\pspolygon[fillstyle=solid](0.627253,0.462871)(0.50598,0.427985) + (0.509149,0.416487)(0.515019,0.407859)(0.635784,0.447596) + (0.630406,0.4546)(0.627253,0.462871) +\psset{fillcolor=cmy_5a5aff}% +\psset{linecolor=rgb_2020a4}% +\pspolygon[fillstyle=solid](1,0.5)(0.875906,0.494186) + (0.877488,0.491574)(0.879836,0.489043)(1,0.5) +\psset{fillcolor=cmy_4e4eff}% +\psset{linecolor=rgb_2323b0}% +\pspolygon[fillstyle=solid](1.1239,0.494874)(1.24918,0.491962) + (1.25065,0.498531)(1.25055,0.504845)(1.12505,0.500414) + (1.12486,0.497656)(1.1239,0.494874) +\psset{fillcolor=cmy_5555ff}% +\psset{linecolor=rgb_2121a9}% +\pspolygon[fillstyle=solid](1,0.5)(1.11965,0.48934) + (1.12216,0.492093)(1.1239,0.494874)(1,0.5) +\psset{fillcolor=cmy_5c5cff}% +\psset{linecolor=rgb_2020a2}% +\pspolygon[fillstyle=solid](1,0.5)(0.879836,0.489043) + (0.882942,0.486608)(0.886789,0.484281)(1,0.5) +\psset{fillcolor=cmy_5555ff}% +\psset{linecolor=rgb_2121a9}% +\pspolygon[fillstyle=solid](1,0.5)(1.11239,0.484027) + (1.11639,0.486643)(1.11965,0.48934)(1,0.5) +\psset{fillcolor=cmy_3e3eff}% +\psset{linecolor=rgb_2626c0}% +\pspolygon[fillstyle=solid](1.24918,0.491962)(1.37644,0.493576) + (1.37822,0.505923)(1.37753,0.517385)(1.25055,0.504845) + (1.25065,0.498531)(1.24918,0.491962) +\psset{fillcolor=cmy_5e5eff}% +\psset{linecolor=rgb_2020a0}% +\pspolygon[fillstyle=solid](1,0.5)(0.886789,0.484281) + (0.89136,0.482071)(0.896629,0.479987)(1,0.5) +\psset{fillcolor=cmy_5959ff}% +\psset{linecolor=rgb_2121a5}% +\pspolygon[fillstyle=solid](0.875906,0.494186)(0.751245,0.483425) + (0.753877,0.478082)(0.758047,0.473156)(0.879836,0.489043) + (0.877488,0.491574)(0.875906,0.494186) +\psset{fillcolor=cmy_5656ff}% +\psset{linecolor=rgb_2121a8}% +\pspolygon[fillstyle=solid](1,0.5)(1.10226,0.479146) + (1.10767,0.48152)(1.11239,0.484027)(1,0.5) +\psset{fillcolor=cmy_5a5aff}% +\psset{linecolor=rgb_2020a4}% +\pspolygon[fillstyle=solid](0.751245,0.483425)(0.627253,0.462871) + (0.630406,0.4546)(0.635784,0.447596)(0.758047,0.473156) + (0.753877,0.478082)(0.751245,0.483425) +\psset{fillcolor=cmy_5e5eff}% +\psset{linecolor=rgb_2020a0}% +\pspolygon[fillstyle=solid](1,0.5)(0.896629,0.479987) + (0.902567,0.478033)(0.909139,0.476214)(1,0.5) +\psset{fillcolor=cmy_5757ff}% +\psset{linecolor=rgb_2121a7}% +\pspolygon[fillstyle=solid](1,0.5)(1.08949,0.474885) + (1.09619,0.476928)(1.10226,0.479146)(1,0.5) +\psset{fillcolor=cmy_4a4aff}% +\psset{linecolor=rgb_2424b4}% +\pspolygon[fillstyle=solid](1.11965,0.48934)(1.24148,0.478487) + (1.24612,0.485243)(1.24918,0.491962)(1.1239,0.494874) + (1.12216,0.492093)(1.11965,0.48934) +\psset{fillcolor=cmy_2a2aff}% +\psset{linecolor=rgb_2a2ad4}% +\pspolygon[fillstyle=solid](1.37644,0.493576)(1.50673,0.502132) + (1.50899,0.523306)(1.50776,0.542368)(1.37753,0.517385) + (1.37822,0.505923)(1.37644,0.493576) +\psset{fillcolor=cmy_5959ff}% +\psset{linecolor=rgb_2121a5}% +\pspolygon[fillstyle=solid](1,0.5)(1.07439,0.47139) + (1.08221,0.473035)(1.08949,0.474885)(1,0.5) +\psset{fillcolor=cmy_5e5eff}% +\psset{linecolor=rgb_2020a0}% +\pspolygon[fillstyle=solid](1,0.5)(0.909139,0.476214) + (0.916306,0.474532)(0.924023,0.47299)(1,0.5) +\psset{fillcolor=cmy_7878ff}% +\psset{linecolor=rgb_1a1a86}% +\pspolygon[fillstyle=solid](0.20082,0.188793)(0.105573,0.08167) + (0.105946,0.125602)(0.108805,0.186635)(0.221782,0.25564) + (0.209394,0.216686)(0.20082,0.188793) +\psset{fillcolor=cmy_3939ff}% +\psset{linecolor=rgb_2727c5}% +\pspolygon[fillstyle=solid](1.64384,0.584677)(1.78949,0.650223) + (1.78228,0.687084)(1.76797,0.713246)(1.62644,0.6285) + (1.63759,0.609591)(1.64384,0.584677) +\psset{fillcolor=cmy_5a5aff}% +\psset{linecolor=rgb_2020a4}% +\pspolygon[fillstyle=solid](1,0.5)(1.05734,0.468753) + (1.06608,0.469961)(1.07439,0.47139)(1,0.5) +\psset{fillcolor=cmy_5d5dff}% +\psset{linecolor=rgb_2020a1}% +\pspolygon[fillstyle=solid](1,0.5)(0.924023,0.47299) + (0.932243,0.471589)(0.940912,0.470334)(1,0.5) +\psset{fillcolor=cmy_5b5bff}% +\psset{linecolor=rgb_2020a3}% +\pspolygon[fillstyle=solid](1,0.5)(1.03876,0.46701) + (1.04821,0.467769)(1.05734,0.468753)(1,0.5) +\psset{fillcolor=cmy_5c5cff}% +\psset{linecolor=rgb_2020a2}% +\pspolygon[fillstyle=solid](1,0.5)(0.940912,0.470334) + (0.949975,0.469227)(0.959372,0.468273)(1,0.5) +\psset{fillcolor=cmy_6363ff}% +\psset{linecolor=rgb_1f1f9b}% +\pspolygon[fillstyle=solid](1.92548,0.836328)(2.1079,1.01222) + (2.07205,1.03012)(2.0226,1.01759)(1.86122,0.850819) + (1.8979,0.852992)(1.92548,0.836328) +\psset{fillcolor=cmy_5b5bff}% +\psset{linecolor=rgb_2020a3}% +\pspolygon[fillstyle=solid](1,0.5)(1.01915,0.466147) + (1.02906,0.466471)(1.03876,0.46701)(1,0.5) +\psset{fillcolor=cmy_5e5eff}% +\psset{linecolor=rgb_2020a0}% +\pspolygon[fillstyle=solid](0.879836,0.489043)(0.758047,0.473156) + (0.763749,0.468665)(0.770971,0.464613)(0.886789,0.484281) + (0.882942,0.486608)(0.879836,0.489043) +\psset{fillcolor=cmy_5b5bff}% +\psset{linecolor=rgb_2020a3}% +\pspolygon[fillstyle=solid](1,0.5)(0.959372,0.468273) + (0.969041,0.467478)(0.978917,0.466848)(1,0.5) +\psset{fillcolor=cmy_7878ff}% +\psset{linecolor=rgb_1a1a86}% +\pspolygon[fillstyle=solid](0.515019,0.407859)(0.398466,0.350056) + (0.406961,0.34569)(0.418616,0.346439)(0.535179,0.399064) + (0.523664,0.402099)(0.515019,0.407859) +\psset{fillcolor=cmy_5b5bff}% +\psset{linecolor=rgb_2020a3}% +\pspolygon[fillstyle=solid](1,0.5)(0.999023,0.466116) + (1.00912,0.466032)(1.01915,0.466147)(1,0.5) +\pspolygon[fillstyle=solid](1,0.5)(0.978917,0.466848) + (0.988933,0.466391)(0.999023,0.466116)(1,0.5) +\psset{fillcolor=cmy_3535ff}% +\psset{linecolor=rgb_2828c9}% +\pspolygon[fillstyle=solid](1.24148,0.478487)(1.36555,0.467434) + (1.37221,0.480637)(1.37644,0.493576)(1.24918,0.491962) + (1.24612,0.485243)(1.24148,0.478487) +\psset{fillcolor=cmy_4848ff}% +\psset{linecolor=rgb_2424b6}% +\pspolygon[fillstyle=solid](1.11239,0.484027)(1.22757,0.465351) + (1.23529,0.471816)(1.24148,0.478487)(1.11965,0.48934) + (1.11639,0.486643)(1.11239,0.484027) +\psset{fillcolor=cmy_1b1bff}% +\psset{linecolor=rgb_2d2de3}% +\pspolygon[fillstyle=solid](1.50673,0.502132)(1.64155,0.520244) + (1.64513,0.55453)(1.64384,0.584677)(1.50776,0.542368) + (1.50899,0.523306)(1.50673,0.502132) +\psset{fillcolor=cmy_2d2dff}% +\psset{linecolor=rgb_2929d1}% +\pspolygon[fillstyle=solid](1.56058,0.160334)(1.6438,0.0321256) + (1.68934,0.0674669)(1.73326,0.116772)(1.6364,0.222327) + (1.59977,0.186629)(1.56058,0.160334) +\psset{fillcolor=cmy_6464ff}% +\psset{linecolor=rgb_1e1e9a}% +\pspolygon[fillstyle=solid](0.758047,0.473156)(0.635784,0.447596) + (0.64341,0.441874)(0.653304,0.437383)(0.770971,0.464613) + (0.763749,0.468665)(0.758047,0.473156) +\psset{fillcolor=cmy_6f6fff}% +\psset{linecolor=rgb_1c1c8f}% +\pspolygon[fillstyle=solid](0.635784,0.447596)(0.515019,0.407859) + (0.523664,0.402099)(0.535179,0.399064)(0.653304,0.437383) + (0.64341,0.441874)(0.635784,0.447596) +\psset{fillcolor=cmy_1b1bff}% +\psset{linecolor=rgb_2d2de3}% +\pspolygon[fillstyle=solid](1.36555,0.467434)(1.49191,0.456177) + (1.501,0.479507)(1.50673,0.502132)(1.37644,0.493576) + (1.37221,0.480637)(1.36555,0.467434) +\psset{fillcolor=cmy_1919ff}% +\psset{linecolor=rgb_2d2de5}% +\pspolygon[fillstyle=solid](1.6364,0.222327)(1.73326,0.116772) + (1.77544,0.178833)(1.81542,0.25192)(1.7012,0.317458) + (1.67032,0.266403)(1.6364,0.222327) +\psset{fillcolor=cmy_6161ff}% +\psset{linecolor=rgb_1f1f9d}% +\pspolygon[fillstyle=solid](0.886789,0.484281)(0.770971,0.464613) + (0.779692,0.460981)(0.78988,0.457739)(0.896629,0.479987) + (0.89136,0.482071)(0.886789,0.484281) +\psset{fillcolor=cmy_4949ff}% +\psset{linecolor=rgb_2424b5}% +\pspolygon[fillstyle=solid](1.10226,0.479146)(1.20772,0.4535) + (1.21837,0.45921)(1.22757,0.465351)(1.11239,0.484027) + (1.10767,0.48152)(1.10226,0.479146) +\psset{fillcolor=cmy_1111ff}% +\psset{linecolor=rgb_2f2fed}% +\pspolygon[fillstyle=solid](1.81542,0.25192)(1.92376,0.172159) + (1.97421,0.285475)(2.02166,0.408983)(1.88544,0.421119) + (1.85244,0.33369)(1.81542,0.25192) +\psset{fillcolor=cmy_3030ff}% +\psset{linecolor=rgb_2929ce}% +\pspolygon[fillstyle=solid](1.22757,0.465351)(1.34511,0.441628) + (1.3565,0.454315)(1.36555,0.467434)(1.24148,0.478487) + (1.23529,0.471816)(1.22757,0.465351) +\psset{fillcolor=cmy_1313ff}% +\psset{linecolor=rgb_2f2feb}% +\pspolygon[fillstyle=solid](1.64155,0.520244)(1.78302,0.550882) + (1.78963,0.60413)(1.78949,0.650223)(1.64384,0.584677) + (1.64513,0.55453)(1.64155,0.520244) +\psset{fillcolor=cmy_3939ff}% +\psset{linecolor=rgb_2727c5}% +\pspolygon[fillstyle=solid](1.78949,0.650223)(1.94995,0.746725) + (1.94296,0.80048)(1.92548,0.836328)(1.76797,0.713246) + (1.78228,0.687084)(1.78949,0.650223) +\psset{fillcolor=cmy_0808ff}% +\psset{linecolor=rgb_3131f6}% +\pspolygon[fillstyle=solid](1.49191,0.456177)(1.62063,0.44471) + (1.63329,0.483148)(1.64155,0.520244)(1.50673,0.502132) + (1.501,0.479507)(1.49191,0.456177) +\psset{fillcolor=cmy_4c4cff}% +\psset{linecolor=rgb_2323b2}% +\pspolygon[fillstyle=solid](1.08949,0.474885)(1.18236,0.443736) + (1.1957,0.448317)(1.20772,0.4535)(1.10226,0.479146) + (1.09619,0.476928)(1.08949,0.474885) +\psset{fillcolor=cmy_6464ff}% +\psset{linecolor=rgb_1e1e9a}% +\pspolygon[fillstyle=solid](0.896629,0.479987)(0.78988,0.457739) + (0.801491,0.454842)(0.81447,0.452238)(0.909139,0.476214) + (0.902567,0.478033)(0.896629,0.479987) +\psset{fillcolor=cmy_7c7cff}% +\psset{linecolor=rgb_1a1a82}% +\pspolygon[fillstyle=solid](0.306183,0.276904)(0.20082,0.188793) + (0.209394,0.216686)(0.221782,0.25564)(0.336923,0.313416) + (0.319506,0.291774)(0.306183,0.276904) +\psset{fillcolor=cmy_1515ff}% +\psset{linecolor=rgb_2e2ee9}% +\pspolygon[fillstyle=solid](1.34511,0.441628)(1.46416,0.410519) + (1.47958,0.432922)(1.49191,0.456177)(1.36555,0.467434) + (1.3565,0.454315)(1.34511,0.441628) +\psset{fillcolor=cmy_0808ff}% +\psset{linecolor=rgb_3131f6}% +\pspolygon[fillstyle=solid](1.7012,0.317458)(1.81542,0.25192) + (1.85244,0.33369)(1.88544,0.421119)(1.75179,0.433026) + (1.72856,0.373711)(1.7012,0.317458) +\psset{fillcolor=cmy_5050ff}% +\psset{linecolor=rgb_2222ae}% +\pspolygon[fillstyle=solid](1.07439,0.47139)(1.15207,0.436591) + (1.16779,0.439816)(1.18236,0.443736)(1.08949,0.474885) + (1.08221,0.473035)(1.07439,0.47139) +\psset{fillcolor=cmy_6b6bff}% +\psset{linecolor=rgb_1d1d93}% +\pspolygon[fillstyle=solid](0.770971,0.464613)(0.653304,0.437383) + (0.665477,0.434016)(0.679931,0.431611)(0.78988,0.457739) + (0.779692,0.460981)(0.770971,0.464613) +\psset{fillcolor=cmy_3131ff}% +\psset{linecolor=rgb_2929cd}% +\pspolygon[fillstyle=solid](1.20772,0.4535)(1.31566,0.418861) + (1.33147,0.429708)(1.34511,0.441628)(1.22757,0.465351) + (1.21837,0.45921)(1.20772,0.4535) +\psset{fillcolor=cmy_4545ff}% +\psset{linecolor=rgb_2525b9}% +\pspolygon[fillstyle=solid](1.4744,0.138283)(1.54709,0.00607935) + (1.59652,0.0115261)(1.6438,0.0321256)(1.56058,0.160334) + (1.51884,0.144112)(1.4744,0.138283) +\psset{fillcolor=cmy_0101ff}% +\psset{linecolor=rgb_3232fd}% +\pspolygon[fillstyle=solid](1.62063,0.44471)(1.75179,0.433026) + (1.77018,0.49296)(1.78302,0.550882)(1.64155,0.520244) + (1.63329,0.483148)(1.62063,0.44471) +\psset{fillcolor=cmy_6464ff}% +\psset{linecolor=rgb_1e1e9a}% +\pspolygon[fillstyle=solid](0.909139,0.476214)(0.81447,0.452238) + (0.828748,0.449869)(0.844242,0.44768)(0.924023,0.47299) + (0.916306,0.474532)(0.909139,0.476214) +\psset{fillcolor=cmy_0505ff}% +\psset{linecolor=rgb_3131f9}% +\pspolygon[fillstyle=solid](1.46416,0.410519)(1.58342,0.369794) + (1.6039,0.406438)(1.62063,0.44471)(1.49191,0.456177) + (1.47958,0.432922)(1.46416,0.410519) +\psset{fillcolor=cmy_0202ff}% +\psset{linecolor=rgb_3232fc}% +\pspolygon[fillstyle=solid](1.58342,0.369794)(1.7012,0.317458) + (1.72856,0.373711)(1.75179,0.433026)(1.62063,0.44471) + (1.6039,0.406438)(1.58342,0.369794) +\psset{fillcolor=cmy_0e0eff}% +\psset{linecolor=rgb_3030f0}% +\pspolygon[fillstyle=solid](1.53245,0.306569)(1.6364,0.222327) + (1.67032,0.266403)(1.7012,0.317458)(1.58342,0.369794) + (1.55951,0.336116)(1.53245,0.306569) +\psset{fillcolor=cmy_6969ff}% +\psset{linecolor=rgb_1d1d95}% +\pspolygon[fillstyle=solid](1.43923,0.040527)(1.49747,-0.0982892) + (1.55585,-0.134733)(1.61087,-0.15044)(1.54709,0.00607935) + (1.49491,0.0158499)(1.43923,0.040527) +\psset{fillcolor=cmy_5555ff}% +\psset{linecolor=rgb_2121a9}% +\pspolygon[fillstyle=solid](1.05734,0.468753)(1.11756,0.432255) + (1.13529,0.434074)(1.15207,0.436591)(1.07439,0.47139) + (1.06608,0.469961)(1.05734,0.468753) +\psset{fillcolor=cmy_6464ff}% +\psset{linecolor=rgb_1e1e9a}% +\pspolygon[fillstyle=solid](0.924023,0.47299)(0.844242,0.44768) + (0.860857,0.44562)(0.878483,0.443646)(0.940912,0.470334) + (0.932243,0.471589)(0.924023,0.47299) +\psset{fillcolor=cmy_1818ff}% +\psset{linecolor=rgb_2e2ee6}% +\pspolygon[fillstyle=solid](1.31566,0.418861)(1.42461,0.371119) + (1.44579,0.3897)(1.46416,0.410519)(1.34511,0.441628) + (1.33147,0.429708)(1.31566,0.418861) +\psset{fillcolor=cmy_5959ff}% +\psset{linecolor=rgb_2121a5}% +\pspolygon[fillstyle=solid](1.03876,0.46701)(1.07968,0.43057) + (1.09898,0.431103)(1.11756,0.432255)(1.05734,0.468753) + (1.04821,0.467769)(1.03876,0.46701) +\psset{fillcolor=cmy_1111ff}% +\psset{linecolor=rgb_2f2fed}% +\pspolygon[fillstyle=solid](1.78302,0.550882)(1.93401,0.597589) + (1.94669,0.677812)(1.94995,0.746725)(1.78949,0.650223) + (1.78963,0.60413)(1.78302,0.550882) +\psset{fillcolor=cmy_7777ff}% +\psset{linecolor=rgb_1b1b87}% +\pspolygon[fillstyle=solid](0.653304,0.437383)(0.535179,0.399064) + (0.549666,0.398476)(0.567233,0.399933)(0.679931,0.431611) + (0.665477,0.434016)(0.653304,0.437383) +\psset{fillcolor=cmy_0101ff}% +\psset{linecolor=rgb_3232fd}% +\pspolygon[fillstyle=solid](1.75179,0.433026)(1.88544,0.421119) + (1.91311,0.510505)(1.93401,0.597589)(1.78302,0.550882) + (1.77018,0.49296)(1.75179,0.433026) +\psset{fillcolor=cmy_7f7fff}% +\psset{linecolor=rgb_19197f}% +\pspolygon[fillstyle=solid](0.418616,0.346439)(0.306183,0.276904) + (0.319506,0.291774)(0.336923,0.313416)(0.452538,0.361054) + (0.433703,0.351806)(0.418616,0.346439) +\psset{fillcolor=cmy_3737ff}% +\psset{linecolor=rgb_2727c7}% +\pspolygon[fillstyle=solid](1.18236,0.443736)(1.27784,0.401367) + (1.29775,0.409345)(1.31566,0.418861)(1.20772,0.4535) + (1.1957,0.448317)(1.18236,0.443736) +\psset{fillcolor=cmy_0c0cff}% +\psset{linecolor=rgb_3030f2}% +\pspolygon[fillstyle=solid](1.42461,0.371119)(1.53245,0.306569) + (1.55951,0.336116)(1.58342,0.369794)(1.46416,0.410519) + (1.44579,0.3897)(1.42461,0.371119) +\psset{fillcolor=cmy_2020ff}% +\psset{linecolor=rgb_2c2cde}% +\pspolygon[fillstyle=solid](1.46963,0.263451)(1.56058,0.160334) + (1.59977,0.186629)(1.6364,0.222327)(1.53245,0.306569) + (1.50244,0.282108)(1.46963,0.263451) +\psset{fillcolor=cmy_6363ff}% +\psset{linecolor=rgb_1f1f9b}% +\pspolygon[fillstyle=solid](0.940912,0.470334)(0.878483,0.443646) + (0.896998,0.44173)(0.916271,0.43986)(0.959372,0.468273) + (0.949975,0.469227)(0.940912,0.470334) +\psset{fillcolor=cmy_5d5dff}% +\psset{linecolor=rgb_2020a1}% +\pspolygon[fillstyle=solid](1.01915,0.466147)(1.03945,0.431091) + (1.05979,0.43059)(1.07968,0.43057)(1.03876,0.46701) + (1.02906,0.466471)(1.01915,0.466147) +\psset{fillcolor=cmy_7e7eff}% +\psset{linecolor=rgb_191980}% +\pspolygon[fillstyle=solid](0.535179,0.399064)(0.418616,0.346439) + (0.433703,0.351806)(0.452538,0.361054)(0.567233,0.399933) + (0.549666,0.398476)(0.535179,0.399064) +\psset{fillcolor=cmy_3939ff}% +\psset{linecolor=rgb_2727c5}% +\pspolygon[fillstyle=solid](1.94995,0.746725)(2.13284,0.884999) + (2.12834,0.963057)(2.1079,1.01222)(1.92548,0.836328) + (1.94296,0.80048)(1.94995,0.746725) +\psset{fillcolor=cmy_6262ff}% +\psset{linecolor=rgb_1f1f9c}% +\pspolygon[fillstyle=solid](0.959372,0.468273)(0.916271,0.43986) + (0.936157,0.438041)(0.956509,0.436296)(0.978917,0.466848) + (0.969041,0.467478)(0.959372,0.468273) +\psset{fillcolor=cmy_5f5fff}% +\psset{linecolor=rgb_1f1f9f}% +\pspolygon[fillstyle=solid](0.999023,0.466116)(0.997986,0.433208) + (1.0188,0.431991)(1.03945,0.431091)(1.01915,0.466147) + (1.00912,0.466032)(0.999023,0.466116) +\psset{fillcolor=cmy_6f6fff}% +\psset{linecolor=rgb_1c1c8f}% +\pspolygon[fillstyle=solid](0.78988,0.457739)(0.679931,0.431611) + (0.696648,0.429965)(0.71559,0.428845)(0.81447,0.452238) + (0.801491,0.454842)(0.78988,0.457739) +\psset{fillcolor=cmy_6161ff}% +\psset{linecolor=rgb_1f1f9d}% +\pspolygon[fillstyle=solid](0.978917,0.466848)(0.956509,0.436296) + (0.977171,0.434667)(0.997986,0.433208)(0.999023,0.466116) + (0.988933,0.466391)(0.978917,0.466848) +\psset{fillcolor=cmy_0303ff}% +\psset{linecolor=rgb_3232fb}% +\pspolygon[fillstyle=solid](1.88544,0.421119)(2.02166,0.408983) + (2.06392,0.537585)(2.09838,0.664828)(1.93401,0.597589) + (1.91311,0.510505)(1.88544,0.421119) +\psset{fillcolor=cmy_4141ff}% +\psset{linecolor=rgb_2525bd}% +\pspolygon[fillstyle=solid](1.15207,0.436591)(1.23246,0.39052) + (1.25605,0.395068)(1.27784,0.401367)(1.18236,0.443736) + (1.16779,0.439816)(1.15207,0.436591) +\psset{fillcolor=cmy_2323ff}% +\psset{linecolor=rgb_2b2bdb}% +\pspolygon[fillstyle=solid](1.27784,0.401367)(1.37438,0.342743) + (1.40077,0.355325)(1.42461,0.371119)(1.31566,0.418861) + (1.29775,0.409345)(1.27784,0.401367) +\psset{fillcolor=cmy_1b1bff}% +\psset{linecolor=rgb_2d2de3}% +\pspolygon[fillstyle=solid](1.37438,0.342743)(1.46963,0.263451) + (1.50244,0.282108)(1.53245,0.306569)(1.42461,0.371119) + (1.40077,0.355325)(1.37438,0.342743) +\psset{fillcolor=cmy_7171ff}% +\psset{linecolor=rgb_1c1c8d}% +\pspolygon[fillstyle=solid](0.81447,0.452238)(0.71559,0.428845) + (0.736691,0.427999)(0.759855,0.427181)(0.844242,0.44768) + (0.828748,0.449869)(0.81447,0.452238) +\psset{fillcolor=cmy_3939ff}% +\psset{linecolor=rgb_2727c5}% +\pspolygon[fillstyle=solid](1.39584,0.245193)(1.4744,0.138283) + (1.51884,0.144112)(1.56058,0.160334)(1.46963,0.263451) + (1.43409,0.251074)(1.39584,0.245193) +\psset{fillcolor=cmy_0f0fff}% +\psset{linecolor=rgb_2f2fef}% +\pspolygon[fillstyle=solid](1.93401,0.597589)(2.09838,0.664828) + (2.12222,0.783232)(2.13284,0.884999)(1.94995,0.746725) + (1.94669,0.677812)(1.93401,0.597589) +\psset{fillcolor=cmy_4e4eff}% +\psset{linecolor=rgb_2323b0}% +\pspolygon[fillstyle=solid](1.11756,0.432255)(1.18041,0.386614) + (1.20721,0.387725)(1.23246,0.39052)(1.15207,0.436591) + (1.13529,0.434074)(1.11756,0.432255) +\psset{fillcolor=cmy_7b7bff}% +\psset{linecolor=rgb_1a1a83}% +\pspolygon[fillstyle=solid](0.679931,0.431611)(0.567233,0.399933) + (0.587968,0.402922)(0.611934,0.40685)(0.71559,0.428845) + (0.696648,0.429965)(0.679931,0.431611) +\psset{fillcolor=cmy_3434ff}% +\psset{linecolor=rgb_2828ca}% +\pspolygon[fillstyle=solid](1.23246,0.39052)(1.31435,0.328195) + (1.34554,0.333655)(1.37438,0.342743)(1.27784,0.401367) + (1.25605,0.395068)(1.23246,0.39052) +\psset{fillcolor=cmy_3131ff}% +\psset{linecolor=rgb_2929cd}% +\pspolygon[fillstyle=solid](1.31435,0.328195)(1.39584,0.245193) + (1.43409,0.251074)(1.46963,0.263451)(1.37438,0.342743) + (1.34554,0.333655)(1.31435,0.328195) +\psset{fillcolor=cmy_5a5aff}% +\psset{linecolor=rgb_2020a4}% +\pspolygon[fillstyle=solid](1.07968,0.43057)(1.1228,0.388846) + (1.15222,0.387052)(1.18041,0.386614)(1.11756,0.432255) + (1.09898,0.431103)(1.07968,0.43057) +\psset{fillcolor=cmy_7272ff}% +\psset{linecolor=rgb_1c1c8c}% +\pspolygon[fillstyle=solid](0.844242,0.44768)(0.759855,0.427181) + (0.784951,0.42616)(0.811811,0.424741)(0.878483,0.443646) + (0.860857,0.44562)(0.844242,0.44768) +\psset{fillcolor=cmy_6060ff}% +\psset{linecolor=rgb_1f1f9e}% +\pspolygon[fillstyle=solid](1.3764,0.157338)(1.43923,0.040527) + (1.49491,0.0158499)(1.54709,0.00607935)(1.4744,0.138283) + (1.42703,0.142821)(1.3764,0.157338) +\psset{fillcolor=cmy_6363ff}% +\psset{linecolor=rgb_1f1f9b}% +\pspolygon[fillstyle=solid](1.03945,0.431091)(1.06103,0.395505) + (1.09234,0.391756)(1.1228,0.388846)(1.07968,0.43057) + (1.05979,0.43059)(1.03945,0.431091) +\psset{fillcolor=cmy_7272ff}% +\psset{linecolor=rgb_1c1c8c}% +\pspolygon[fillstyle=solid](0.878483,0.443646)(0.811811,0.424741) + (0.840235,0.422779)(0.869988,0.42019)(0.916271,0.43986) + (0.896998,0.44173)(0.878483,0.443646) +\psset{fillcolor=cmy_4a4aff}% +\psset{linecolor=rgb_2424b4}% +\pspolygon[fillstyle=solid](1.18041,0.386614)(1.24529,0.327916) + (1.2809,0.32634)(1.31435,0.328195)(1.23246,0.39052) + (1.20721,0.387725)(1.18041,0.386614) +\psset{fillcolor=cmy_7f7fff}% +\psset{linecolor=rgb_19197f}% +\pspolygon[fillstyle=solid](0.567233,0.399933)(0.452538,0.361054) + (0.47545,0.373217)(0.502743,0.387128)(0.611934,0.40685) + (0.587968,0.402922)(0.567233,0.399933) +\psset{fillcolor=cmy_6a6aff}% +\psset{linecolor=rgb_1d1d94}% +\pspolygon[fillstyle=solid](0.997986,0.433208)(0.996875,0.404353) + (1.02913,0.399802)(1.06103,0.395505)(1.03945,0.431091) + (1.0188,0.431991)(0.997986,0.433208) +\psset{fillcolor=cmy_7171ff}% +\psset{linecolor=rgb_1c1c8d}% +\pspolygon[fillstyle=solid](0.916271,0.43986)(0.869988,0.42019) + (0.900811,0.41696)(0.932427,0.413148)(0.956509,0.436296) + (0.936157,0.438041)(0.916271,0.43986) +\psset{fillcolor=cmy_6e6eff}% +\psset{linecolor=rgb_1c1c90}% +\pspolygon[fillstyle=solid](0.956509,0.436296)(0.932427,0.413148) + (0.964546,0.408882)(0.996875,0.404353)(0.997986,0.433208) + (0.977171,0.434667)(0.956509,0.436296) +\psset{fillcolor=cmy_7d7dff}% +\psset{linecolor=rgb_191981}% +\pspolygon[fillstyle=solid](0.71559,0.428845)(0.611934,0.40685) + (0.639145,0.411067)(0.669551,0.414914)(0.759855,0.427181) + (0.736691,0.427999)(0.71559,0.428845) +\psset{fillcolor=cmy_5656ff}% +\psset{linecolor=rgb_2121a8}% +\pspolygon[fillstyle=solid](1.31112,0.252497)(1.3764,0.157338) + (1.42703,0.142821)(1.4744,0.138283)(1.39584,0.245193) + (1.35487,0.24577)(1.31112,0.252497) +\psset{fillcolor=cmy_4e4eff}% +\psset{linecolor=rgb_2323b0}% +\pspolygon[fillstyle=solid](1.24529,0.327916)(1.31112,0.252497) + (1.35487,0.24577)(1.39584,0.245193)(1.31435,0.328195) + (1.2809,0.32634)(1.24529,0.327916) +\psset{fillcolor=cmy_5f5fff}% +\psset{linecolor=rgb_1f1f9f}% +\pspolygon[fillstyle=solid](1.1228,0.388846)(1.16806,0.339925) + (1.20762,0.332598)(1.24529,0.327916)(1.18041,0.386614) + (1.15222,0.387052)(1.1228,0.388846) +\psset{fillcolor=cmy_7c7cff}% +\psset{linecolor=rgb_1a1a82}% +\pspolygon[fillstyle=solid](0.452538,0.361054)(0.336923,0.313416) + (0.359168,0.34034)(0.38701,0.370633)(0.502743,0.387128) + (0.47545,0.373217)(0.452538,0.361054) +\psset{fillcolor=cmy_7d7dff}% +\psset{linecolor=rgb_191981}% +\pspolygon[fillstyle=solid](0.759855,0.427181)(0.669551,0.414914) + (0.703026,0.417762)(0.739356,0.419062)(0.811811,0.424741) + (0.784951,0.42616)(0.759855,0.427181) +\psset{fillcolor=cmy_6e6eff}% +\psset{linecolor=rgb_1c1c90}% +\pspolygon[fillstyle=solid](1.06103,0.395505)(1.08409,0.360109) + (1.1268,0.349318)(1.16806,0.339925)(1.1228,0.388846) + (1.09234,0.391756)(1.06103,0.395505) +\psset{fillcolor=cmy_7474ff}% +\psset{linecolor=rgb_1b1b8a}% +\pspolygon[fillstyle=solid](0.336923,0.313416)(0.221782,0.25564) + (0.239289,0.303779)(0.263419,0.358433)(0.38701,0.370633) + (0.359168,0.34034)(0.336923,0.313416) +\psset{fillcolor=cmy_6767ff}% +\psset{linecolor=rgb_1e1e97}% +\pspolygon[fillstyle=solid](1.16806,0.339925)(1.21527,0.281861) + (1.26458,0.264805)(1.31112,0.252497)(1.24529,0.327916) + (1.20762,0.332598)(1.16806,0.339925) +\psset{fillcolor=cmy_7e7eff}% +\psset{linecolor=rgb_191980}% +\pspolygon[fillstyle=solid](0.611934,0.40685)(0.502743,0.387128) + (0.53466,0.401467)(0.571331,0.414834)(0.669551,0.414914) + (0.639145,0.411067)(0.611934,0.40685) +\psset{fillcolor=cmy_6d6dff}% +\psset{linecolor=rgb_1d1d91}% +\pspolygon[fillstyle=solid](0.221782,0.25564)(0.108805,0.186635) + (0.116083,0.263023)(0.130252,0.351753)(0.263419,0.358433) + (0.239289,0.303779)(0.221782,0.25564) +\psset{fillcolor=cmy_7d7dff}% +\psset{linecolor=rgb_191981}% +\pspolygon[fillstyle=solid](0.811811,0.424741)(0.739356,0.419062) + (0.778241,0.418391)(0.819298,0.415485)(0.869988,0.42019) + (0.840235,0.422779)(0.811811,0.424741) +\psset{fillcolor=cmy_7676ff}% +\psset{linecolor=rgb_1b1b88}% +\pspolygon[fillstyle=solid](0.996875,0.404353)(0.99567,0.382977) + (1.04025,0.371574)(1.08409,0.360109)(1.06103,0.395505) + (1.02913,0.399802)(0.996875,0.404353) +\psset{fillcolor=cmy_7a7aff}% +\psset{linecolor=rgb_1a1a84}% +\pspolygon[fillstyle=solid](1.31393,0.130943)(1.36413,0.0350099) + (1.43413,-0.0414045)(1.49747,-0.0982892)(1.43923,0.040527) + (1.3792,0.0793428)(1.31393,0.130943) +\psset{fillcolor=cmy_7d7dff}% +\psset{linecolor=rgb_191981}% +\pspolygon[fillstyle=solid](0.869988,0.42019)(0.819298,0.415485) + (0.862077,0.410271)(0.906078,0.402876)(0.932427,0.413148) + (0.900811,0.41696)(0.869988,0.42019) +\psset{fillcolor=cmy_7b7bff}% +\psset{linecolor=rgb_1a1a83}% +\pspolygon[fillstyle=solid](0.932427,0.413148)(0.906078,0.402876) + (0.950781,0.393616)(0.99567,0.382977)(0.996875,0.404353) + (0.964546,0.408882)(0.932427,0.413148) +\psset{fillcolor=cmy_7070ff}% +\psset{linecolor=rgb_1c1c8e}% +\pspolygon[fillstyle=solid](1.21527,0.281861)(1.26407,0.212769) + (1.32218,0.181056)(1.3764,0.157338)(1.31112,0.252497) + (1.26458,0.264805)(1.21527,0.281861) +\psset{fillcolor=cmy_7676ff}% +\psset{linecolor=rgb_1b1b88}% +\pspolygon[fillstyle=solid](1.26407,0.212769)(1.31393,0.130943) + (1.3792,0.0793428)(1.43923,0.040527)(1.3764,0.157338) + (1.32218,0.181056)(1.26407,0.212769) +\psset{fillcolor=cmy_7777ff}% +\psset{linecolor=rgb_1b1b87}% +\pspolygon[fillstyle=solid](1.08409,0.360109)(1.10888,0.325677) + (1.1633,0.302583)(1.21527,0.281861)(1.16806,0.339925) + (1.1268,0.349318)(1.08409,0.360109) +\psset{fillcolor=cmy_7d7dff}% +\psset{linecolor=rgb_191981}% +\pspolygon[fillstyle=solid](0.669551,0.414914)(0.571331,0.414834) + (0.612735,0.425841)(0.658661,0.43323)(0.739356,0.419062) + (0.703026,0.417762)(0.669551,0.414914) +\psset{fillcolor=cmy_7676ff}% +\psset{linecolor=rgb_1b1b88}% +\pspolygon[fillstyle=solid](0.502743,0.387128)(0.38701,0.370633) + (0.42117,0.401992)(0.462221,0.431813)(0.571331,0.414834) + (0.53466,0.401467)(0.502743,0.387128) +\psset{fillcolor=cmy_7e7eff}% +\psset{linecolor=rgb_191980}% +\pspolygon[fillstyle=solid](0.99567,0.382977)(0.994341,0.37309) + (1.05238,0.34969)(1.10888,0.325677)(1.08409,0.360109) + (1.04025,0.371574)(0.99567,0.382977) +\psset{fillcolor=cmy_7d7dff}% +\psset{linecolor=rgb_191981}% +\pspolygon[fillstyle=solid](0.739356,0.419062)(0.658661,0.43323) + (0.708693,0.435991)(0.762219,0.433471)(0.819298,0.415485) + (0.778241,0.418391)(0.739356,0.419062) +\pspolygon[fillstyle=solid](1.10888,0.325677)(1.13571,0.293061) + (1.20191,0.250812)(1.26407,0.212769)(1.21527,0.281861) + (1.1633,0.302583)(1.10888,0.325677) +\psset{fillcolor=cmy_7f7fff}% +\psset{linecolor=rgb_19197f}% +\pspolygon[fillstyle=solid](0.906078,0.402876)(0.87651,0.412187) + (0.935442,0.394373)(0.994341,0.37309)(0.99567,0.382977) + (0.950781,0.393616)(0.906078,0.402876) +\psset{fillcolor=cmy_7e7eff}% +\psset{linecolor=rgb_191980}% +\pspolygon[fillstyle=solid](0.819298,0.415485)(0.762219,0.433471) + (0.818456,0.425453)(0.87651,0.412187)(0.906078,0.402876) + (0.862077,0.410271)(0.819298,0.415485) +\psset{fillcolor=cmy_6a6aff}% +\psset{linecolor=rgb_1d1d94}% +\pspolygon[fillstyle=solid](0.38701,0.370633)(0.263419,0.358433) + (0.295756,0.416063)(0.337777,0.472291)(0.462221,0.431813) + (0.42117,0.401992)(0.38701,0.370633) +\psset{fillcolor=cmy_7272ff}% +\psset{linecolor=rgb_1c1c8c}% +\pspolygon[fillstyle=solid](0.571331,0.414834)(0.462221,0.431813) + (0.51047,0.457371)(0.565855,0.476055)(0.658661,0.43323) + (0.612735,0.425841)(0.571331,0.414834) +\psset{fillcolor=cmy_7f7fff}% +\psset{linecolor=rgb_19197f}% +\pspolygon[fillstyle=solid](1.13571,0.293061)(1.16504,0.263219) + (1.2427,0.193231)(1.31393,0.130943)(1.26407,0.212769) + (1.20191,0.250812)(1.13571,0.293061) +\pspolygon[fillstyle=solid](0.994341,0.37309)(0.99284,0.379708) + (1.0658,0.336973)(1.13571,0.293061)(1.10888,0.325677) + (1.05238,0.34969)(0.994341,0.37309) +\pspolygon[fillstyle=solid](1.16504,0.263219)(1.19745,0.237271) + (1.28572,0.129037)(1.36413,0.0350099)(1.31393,0.130943) + (1.2427,0.193231)(1.16504,0.263219) +\psset{fillcolor=cmy_7272ff}% +\psset{linecolor=rgb_1c1c8c}% +\pspolygon[fillstyle=solid](0.658661,0.43323)(0.565855,0.476055) + (0.62787,0.485674)(0.695551,0.484744)(0.762219,0.433471) + (0.708693,0.435991)(0.658661,0.43323) +\psset{fillcolor=cmy_5d5dff}% +\psset{linecolor=rgb_2020a1}% +\pspolygon[fillstyle=solid](0.263419,0.358433)(0.130252,0.351753) + (0.154241,0.448121)(0.191195,0.545437)(0.337777,0.472291) + (0.295756,0.416063)(0.263419,0.358433) +\psset{fillcolor=cmy_7b7bff}% +\psset{linecolor=rgb_1a1a83}% +\pspolygon[fillstyle=solid](0.87651,0.412187)(0.842212,0.450088) + (0.917852,0.418332)(0.99284,0.379708)(0.994341,0.37309) + (0.935442,0.394373)(0.87651,0.412187) +\psset{fillcolor=cmy_7676ff}% +\psset{linecolor=rgb_1b1b88}% +\pspolygon[fillstyle=solid](0.762219,0.433471)(0.695551,0.484744) + (0.767541,0.472718)(0.842212,0.450088)(0.87651,0.412187) + (0.818456,0.425453)(0.762219,0.433471) +\psset{fillcolor=cmy_6262ff}% +\psset{linecolor=rgb_1f1f9c}% +\pspolygon[fillstyle=solid](0.462221,0.431813)(0.337777,0.472291) + (0.390602,0.522128)(0.454699,0.560441)(0.565855,0.476055) + (0.51047,0.457371)(0.462221,0.431813) +\psset{fillcolor=cmy_7c7cff}% +\psset{linecolor=rgb_1a1a82}% +\pspolygon[fillstyle=solid](0.99284,0.379708)(0.991097,0.4096) + (1.08095,0.336955)(1.16504,0.263219)(1.13571,0.293061) + (1.0658,0.336973)(0.99284,0.379708) +\psset{fillcolor=cmy_6262ff}% +\psset{linecolor=rgb_1f1f9c}% +\pspolygon[fillstyle=solid](0.565855,0.476055)(0.454699,0.560441) + (0.52964,0.582636)(0.613978,0.585437)(0.695551,0.484744) + (0.62787,0.485674)(0.565855,0.476055) +\psset{fillcolor=cmy_7474ff}% +\psset{linecolor=rgb_1b1b8a}% +\pspolygon[fillstyle=solid](0.842212,0.450088)(0.800716,0.529938) + (0.896933,0.475736)(0.991097,0.4096)(0.99284,0.379708) + (0.917852,0.418332)(0.842212,0.450088) +\psset{fillcolor=cmy_6a6aff}% +\psset{linecolor=rgb_1d1d94}% +\pspolygon[fillstyle=solid](0.695551,0.484744)(0.613978,0.585437) + (0.705338,0.567542)(0.800716,0.529938)(0.842212,0.450088) + (0.767541,0.472718)(0.695551,0.484744) +\psset{fillcolor=cmy_7878ff}% +\psset{linecolor=rgb_1a1a86}% +\pspolygon[fillstyle=solid](0.991097,0.4096)(0.989001,0.47266) + (1.09845,0.354344)(1.19745,0.237271)(1.16504,0.263219) + (1.08095,0.336955)(0.991097,0.4096) +\psset{fillcolor=cmy_4f4fff}% +\psset{linecolor=rgb_2323af}% +\pspolygon[fillstyle=solid](0.337777,0.472291)(0.191195,0.545437) + (0.244003,0.635089)(0.314618,0.707241)(0.454699,0.560441) + (0.390602,0.522128)(0.337777,0.472291) +\psset{fillcolor=cmy_6b6bff}% +\psset{linecolor=rgb_1d1d93}% +\pspolygon[fillstyle=solid](0.800716,0.529938)(0.747762,0.67368) + (0.870898,0.582631)(0.989001,0.47266)(0.991097,0.4096) + (0.896933,0.475736)(0.800716,0.529938) +\psset{fillcolor=cmy_4f4fff}% +\psset{linecolor=rgb_2323af}% +\pspolygon[fillstyle=solid](0.454699,0.560441)(0.314618,0.707241) + (0.403301,0.752297)(0.50809,0.762937)(0.613978,0.585437) + (0.52964,0.582636)(0.454699,0.560441) +\psset{fillcolor=cmy_5c5cff}% +\psset{linecolor=rgb_2020a2}% +\pspolygon[fillstyle=solid](0.613978,0.585437)(0.50809,0.762937) + (0.624809,0.736041)(0.747762,0.67368)(0.800716,0.529938) + (0.705338,0.567542)(0.613978,0.585437) +\end{pspicture}% diff --git a/graphics/epix/doc/plotting2.xp b/graphics/epix/doc/plotting2.xp new file mode 100644 index 0000000000..2a0ed661e5 --- /dev/null +++ b/graphics/epix/doc/plotting2.xp @@ -0,0 +1,29 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +P f(double r, double th) +{ + return P(r*Cos(th), r*Sin(th), pow(r, 3)*Cos(3*th)); +} + +int main() +{ + picture(P(-1,-1),P(1,1), "2x1in"); + + begin(); + + domain R(P(0,0), P(1, 2*M_PI), mesh(8,40), mesh(8,80)); + + camera.at(3,1,2); // set the viewpoint + + arrow(P(0,0,0), P(1.25,0,0)); + arrow(P(0,0,0), P(0,1.25,0)); + + plain(Blue(1.2)); + fill(Yellow()); // shade + surface(f, R); + + pst_format(); + end(); +} diff --git a/graphics/epix/doc/plotting3.eepic b/graphics/epix/doc/plotting3.eepic new file mode 100644 index 0000000000..d61bee76c4 --- /dev/null +++ b/graphics/epix/doc/plotting3.eepic @@ -0,0 +1,146 @@ +%% Generated from plotting3.xp on Tue Sep 25 18:08:09 EDT 2007 by +%% ePiX-1.2.0 +%% +%% Cartesian bounding box: [0,18.8496] x [-1,1] +%% Actual size: 5 x 1in +%% Figure offset: left by 0in, down by 0in +%% +%% usepackages epic,eepic,xcolor +%% +\xdefinecolor{rgb_000000}{rgb}{0,0,0}% +\xdefinecolor{rgb_0000ff}{rgb}{0,0,1}% +\xdefinecolor{rgb_00ff00}{rgb}{0,1,0}% +\xdefinecolor{rgb_3f00bf}{rgb}{0.247059,0,0.74902}% +\xdefinecolor{rgb_7f007f}{rgb}{0.498039,0,0.498039}% +\xdefinecolor{rgb_bf003f}{rgb}{0.74902,0,0.247059}% +\setlength{\unitlength}{1in}% +\begin{picture}(5,1)(0,0)% +\path(0,0.5)(2.5,0.5)(5,0.5) +\put(0,0.5){\makebox(0,0){\hbox{\color{rgb_000000}$\rule{0.5pt}{6pt}$}}} +\put(1.25,0.5){\makebox(0,0){\hbox{\color{rgb_000000}$\rule{0.5pt}{6pt}$}}} +\put(2.5,0.5){\makebox(0,0){\hbox{\color{rgb_000000}$\rule{0.5pt}{6pt}$}}} +\put(3.75,0.5){\makebox(0,0){\hbox{\color{rgb_000000}$\rule{0.5pt}{6pt}$}}} +\put(5,0.5){\makebox(0,0){\hbox{\color{rgb_000000}$\rule{0.5pt}{6pt}$}}} +\path(0,0)(0,0.5)(0,1) +\put(0,0){\makebox(0,0){\hbox{\color{rgb_000000}$\rule{6pt}{0.5pt}$}}} +\put(0,1){\makebox(0,0){\hbox{\color{rgb_000000}$\rule{6pt}{0.5pt}$}}} +\allinethickness{0.8pt}% +\color{rgb_00ff00}% +\path(0,0.5)(0.0416667,0.578217)(0.0833333,0.654508) + (0.125,0.726995)(0.166667,0.793893)(0.208333,0.853553) + (0.25,0.904508)(0.291667,0.945503)(0.333333,0.975528) + (0.375,0.993844)(0.416667,1)(0.458333,0.993844)(0.5,0.975528) + (0.541667,0.945503)(0.583333,0.904508)(0.625,0.853553) + (0.666667,0.793893)(0.708333,0.726995)(0.75,0.654508) + (0.791667,0.578217)(0.833333,0.5)(0.875,0.421783) + (0.916667,0.345492)(0.958333,0.273005)(1,0.206107) + (1.04167,0.146447)(1.08333,0.0954915)(1.125,0.0544967) + (1.16667,0.0244717)(1.20833,0.00615583)(1.25,0)(1.29167,0.00615583) + (1.33333,0.0244717)(1.375,0.0544967)(1.41667,0.0954915) + (1.45833,0.146447)(1.5,0.206107)(1.54167,0.273005) + (1.58333,0.345492)(1.625,0.421783)(1.66667,0.5)(1.70833,0.578217) + (1.75,0.654508)(1.79167,0.726995)(1.83333,0.793893)(1.875,0.853553) + (1.91667,0.904508)(1.95833,0.945503)(2,0.975528)(2.04167,0.993844) + (2.08333,1)(2.125,0.993844)(2.16667,0.975528)(2.20833,0.945503) + (2.25,0.904508)(2.29167,0.853553)(2.33333,0.793893)(2.375,0.726995) + (2.41667,0.654508)(2.45833,0.578217)(2.5,0.5)(2.54167,0.421783) + (2.58333,0.345492)(2.625,0.273005)(2.66667,0.206107) + (2.70833,0.146447)(2.75,0.0954915)(2.79167,0.0544967) + (2.83333,0.0244717)(2.875,0.00615583)(2.91667,0) + (2.95833,0.00615583)(3,0.0244717)(3.04167,0.0544967) + (3.08333,0.0954915)(3.125,0.146447)(3.16667,0.206107) + (3.20833,0.273005)(3.25,0.345492)(3.29167,0.421783)(3.33333,0.5) + (3.375,0.578217)(3.41667,0.654508)(3.45833,0.726995)(3.5,0.793893) + (3.54167,0.853553)(3.58333,0.904508)(3.625,0.945503) + (3.66667,0.975528)(3.70833,0.993844)(3.75,1)(3.79167,0.993844) + (3.83333,0.975528)(3.875,0.945503)(3.91667,0.904508) + (3.95833,0.853553)(4,0.793893)(4.04167,0.726995)(4.08333,0.654508) + (4.125,0.578217)(4.16667,0.5)(4.20833,0.421783)(4.25,0.345492) + (4.29167,0.273005)(4.33333,0.206107)(4.375,0.146447) + (4.41667,0.0954915)(4.45833,0.0544967)(4.5,0.0244717) + (4.54167,0.00615583)(4.58333,0)(4.625,0.00615583) + (4.66667,0.0244717)(4.70833,0.0544967)(4.75,0.0954915) + (4.79167,0.146447)(4.83333,0.206107)(4.875,0.273005) + (4.91667,0.345492)(4.95833,0.421783)(5,0.5) +\color{rgb_bf003f}% +\path(0,0.5)(0.0416667,0.578217)(0.0833333,0.654508) + (0.125,0.726995)(0.166667,0.793893)(0.208333,0.853553) + (0.25,0.904508)(0.291667,0.945503)(0.333333,0.975528) + (0.375,0.993844)(0.416667,1)(0.458333,0.993844)(0.5,0.975528) + (0.541667,0.945503)(0.583333,0.904508)(0.625,0.853553) + (0.666667,0.793893)(0.708333,0.726995)(0.75,0.654508) + (0.791667,0.578217)(0.833333,0.5)(0.875,0.421783) + (0.916667,0.345492)(0.958333,0.273005)(1,0.206107) + (1.04167,0.146447)(1.08333,0.0954915)(1.125,0.0544967) + (1.16667,0.0244717)(1.20833,0.00615583)(1.25,0)(1.29167,0.00615583) + (1.33333,0.0244717)(1.375,0.0544967)(1.41667,0.0954915) + (1.45833,0.146447)(1.5,0.206107)(1.54167,0.273005) + (1.58333,0.345492)(1.625,0.421783)(1.66667,0.5)(1.70833,0.578217) + (1.75,0.654508)(1.79167,0.726995)(1.83333,0.793893)(1.875,0.853553) + (1.91667,0.904508)(1.95833,0.945503)(2,0.975528)(2.04167,0.993844) + (2.08333,1)(2.125,0.993844)(2.16667,0.975528)(2.20833,0.945503) + (2.25,0.904508)(2.29167,0.853553)(2.33333,0.793893)(2.375,0.726995) + (2.41667,0.654508)(2.45833,0.578217)(2.5,0.5)(2.54167,0.421783) + (2.58333,0.345491)(2.625,0.273005)(2.66667,0.206107) + (2.70833,0.146446)(2.75,0.0954902)(2.79167,0.0544945) + (2.83333,0.0244679)(2.875,0.00614921)(2.91667,0) + (2.95833,0.00613686)(3,0.02444)(3.04167,0.054444) + (3.08333,0.0954044)(3.125,0.146304)(3.16667,0.205875) + (3.20833,0.272628)(3.25,0.344886)(3.29167,0.420815) + (3.33333,0.498463)(3.375,0.57579)(3.41667,0.650696) + (3.45833,0.721039)(3.5,0.78464)(3.54167,0.839253)(3.58333,0.882522) + (3.625,0.911868)(3.66667,0.924325)(3.70833,0.916271)(3.75,0.883026) + (3.79167,0.818266)(3.83333,0.713166)(3.875,0.555181) + (3.91667,0.326308)(3.95833,0.000641819)(3.95839,0) +\color{rgb_7f007f}% +\path(0,0.5)(0.0416667,0.578217)(0.0833333,0.654508) + (0.125,0.726995)(0.166667,0.793893)(0.208333,0.853553) + (0.25,0.904508)(0.291667,0.945503)(0.333333,0.975528) + (0.375,0.993844)(0.416667,1)(0.458333,0.993844)(0.5,0.975528) + (0.541667,0.945503)(0.583333,0.904508)(0.625,0.853553) + (0.666667,0.793893)(0.708333,0.726995)(0.75,0.654508) + (0.791667,0.578217)(0.833333,0.5)(0.875,0.421783) + (0.916667,0.345492)(0.958333,0.273005)(1,0.206107) + (1.04167,0.146447)(1.08333,0.0954915)(1.125,0.0544967) + (1.16667,0.0244717)(1.20833,0.00615583)(1.25,0)(1.29167,0.00615583) + (1.33333,0.0244717)(1.375,0.0544967)(1.41667,0.0954915) + (1.45833,0.146447)(1.5,0.206107)(1.54167,0.273005) + (1.58333,0.345492)(1.625,0.421783)(1.66667,0.5)(1.70833,0.578218) + (1.75,0.654509)(1.79167,0.726996)(1.83333,0.793895)(1.875,0.853557) + (1.91667,0.904515)(1.95833,0.945515)(2,0.975549)(2.04167,0.993881) + (2.08291,1) +\path(2.08376,1)(2.125,0.993951)(2.16667,0.975708) + (2.20833,0.945803)(2.25,0.905003)(2.29167,0.854363) + (2.33333,0.795206)(2.375,0.729106)(2.41667,0.657874) + (2.45833,0.583539)(2.5,0.50835)(2.54167,0.434785)(2.58333,0.365591) + (2.625,0.303858)(2.66667,0.253144)(2.70833,0.21768)(2.75,0.202677) + (2.79167,0.214776)(2.83333,0.262697)(2.875,0.358157) + (2.91667,0.51715)(2.95833,0.761732)(2.98586,1) +\color{rgb_3f00bf}% +\path(0,0.5)(0.0416667,0.578217)(0.0833333,0.654508) + (0.125,0.726995)(0.166667,0.793893)(0.208333,0.853553) + (0.25,0.904508)(0.291667,0.945503)(0.333333,0.975528) + (0.375,0.993844)(0.416667,1)(0.458333,0.993844)(0.5,0.975528) + (0.541667,0.945503)(0.583333,0.904508)(0.625,0.853553) + (0.666667,0.793893)(0.708333,0.726995)(0.75,0.654508) + (0.791667,0.578217)(0.833333,0.5)(0.875,0.421782)(0.916667,0.34549) + (0.958333,0.273001)(1,0.206099)(1.04167,0.14643)(1.08333,0.0954587) + (1.125,0.0544347)(1.16667,0.0243571)(1.20833,0.00594841) + (1.24757,0) +\path(1.2526,0)(1.29167,0.00551665)(1.33333,0.02338) + (1.375,0.0526628)(1.41667,0.0924591)(1.45833,0.141506) + (1.5,0.198171)(1.54167,0.260422)(1.58333,0.325792)(1.625,0.391305) + (1.66667,0.453377)(1.70833,0.507659)(1.75,0.548813) + (1.79167,0.570203)(1.83333,0.563454)(1.875,0.517876) + (1.91667,0.419672)(1.95833,0.250906)(1.99812,0) +\color{rgb_0000ff}% +\path(0,0.5)(0.0416667,0.578217)(0.0833333,0.654509) + (0.125,0.726996)(0.166667,0.793896)(0.208333,0.853572) + (0.25,0.904573)(0.291667,0.945693)(0.333333,0.976009) + (0.375,0.994933)(0.403805,1) +\path(0.439996,1)(0.458333,0.998222) + (0.5,0.983515)(0.541667,0.959373)(0.583333,0.927598) + (0.625,0.890616)(0.666667,0.851521)(0.708333,0.814127) + (0.75,0.783009)(0.791667,0.763557)(0.833333,0.762022) + (0.875,0.785563)(0.916667,0.842295)(0.958333,0.941339)(0.974464,1) +\end{picture}% diff --git a/graphics/epix/doc/plotting3.xp b/graphics/epix/doc/plotting3.xp new file mode 100644 index 0000000000..e5d1088978 --- /dev/null +++ b/graphics/epix/doc/plotting3.xp @@ -0,0 +1,43 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +P sin_n(double x, double n) // Taylor polynomial of sin x +{ + const int N((int) floor(n)); // convert y to an index bound + const double sqx(-pow(x, 2)); // store -x^2 for efficiency + double val(x), summand(x); // places to store results of evaluation + + // step through odd numbers from 1 to 2N+1 + for (int i=1; i <= 2*N+1; i += 2) + { + summand *= (sqx/((i+1)*(i+2))); // (-1)^i x^{2i+1}/(2i+1)! + val += summand; + } + + return P(x, val); +} + +int main() +{ + picture(P(0,-1),P(6*M_PI, 1), "5x1in"); + + begin(); + + set_crop(); + h_axis(4); + v_axis(1); + + bold(); + green(); + plot(Sin, 0, xmax(), 120); + + domain R(P(0,1), P(6*M_PI, 41), mesh(60, 40), mesh(120, 40)); + for (int i=3; 0 <= i; --i) + { + rgb(0.25*i, 0, 1-0.25*i); + plot(sin_n, R.slice2(5*i+1)); + } + + end(); +} diff --git a/graphics/epix/doc/scaling.eepic b/graphics/epix/doc/scaling.eepic new file mode 100644 index 0000000000..0b6231c4ee --- /dev/null +++ b/graphics/epix/doc/scaling.eepic @@ -0,0 +1,56 @@ +%% Generated from scaling.xp on Sat Sep 1 14:17:35 EDT 2007 by +%% ePiX-1.1.15 +%% +%% Cartesian bounding box: [0,4] x [0,1] +%% Actual size: 4 x 0.75in +%% Figure offset: left by 0in, down by 0in +%% +%% usepackages epic,eepic,xcolor +%% +\xdefinecolor{rgb_000000}{rgb}{0,0,0}% +\setlength{\unitlength}{1in}% +\begin{picture}(4,0.75)(0,0)% +\path(1.75,0.375)(2.75,0.375) +\path(2.63584,0.359433)(2.66438,0.359433) +\path(2.63584,0.364622)(2.69292,0.364622) +\path(2.63584,0.369811)(2.72146,0.369811) +\path(2.63584,0.375)(2.75,0.375) +\path(2.63584,0.380189)(2.72146,0.380189) +\path(2.63584,0.385378)(2.69292,0.385378) +\path(2.63584,0.390567)(2.66438,0.390567) +\path(2.74456,0.374012)(2.74456,0.375988) +\path(2.73913,0.373023)(2.73913,0.376977) +\path(2.73369,0.372035)(2.73369,0.377965) +\path(2.72826,0.371047)(2.72826,0.378953) +\path(2.72282,0.370058)(2.72282,0.379942) +\path(2.71738,0.36907)(2.71738,0.38093) +\path(2.71195,0.368081)(2.71195,0.381919) +\path(2.70651,0.367093)(2.70651,0.382907) +\path(2.70108,0.366105)(2.70108,0.383895) +\path(2.69564,0.365116)(2.69564,0.384884) +\path(2.6902,0.364128)(2.6902,0.385872) +\path(2.68477,0.36314)(2.68477,0.38686) +\path(2.67933,0.362151)(2.67933,0.387849) +\path(2.6739,0.361163)(2.6739,0.388837) +\path(2.66846,0.360175)(2.66846,0.389825) +\path(2.66302,0.359186)(2.66302,0.390814) +\path(2.65759,0.358198)(2.65759,0.391802) +\path(2.65215,0.35721)(2.65215,0.39279) +\path(2.64672,0.356221)(2.64672,0.393779) +\path(2.64128,0.355233)(2.64128,0.394767) +\path(2.63584,0.354244)(2.63584,0.395756) +\path(2.63584,0.375)(2.63584,0.354244)(2.75,0.375) + (2.63584,0.395756)(2.63584,0.375) +\put(0.027674,0.121424){\makebox(0,0)[bl]{\hbox{\color{rgb_000000}\scriptsize \hbox{\color{rgb_000000}\scriptsize $(x_\mathrm{min},y_\mathrm{min})$}}}} +\put(0,0.09375){\makebox(0,0){\hbox{\color{rgb_000000}\scriptsize $\circle{0.0069185}\circle{0.013837}\circle{0.0207555}\circle{0.027674}$}}} +\put(1.47233,0.722326){\makebox(0,0)[tr]{\hbox{\color{rgb_000000}\scriptsize \hbox{\color{rgb_000000}\scriptsize $(x_\mathrm{max},y_\mathrm{max})$}}}} +\put(1.5,0.75){\makebox(0,0){\hbox{\color{rgb_000000}\scriptsize $\circle{0.0069185}\circle{0.013837}\circle{0.0207555}\circle{0.027674}$}}} +\put(0.75,0.038402){\makebox(0,0)[t]{\hbox{\color{rgb_000000}\scriptsize \hbox{\color{rgb_000000}\scriptsize Canvas (virtual)}}}} +\path(1.5,0.09375)(1.5,0.75)(0,0.75)(0,0.09375)(1.5,0.09375) +\put(3.02767,0.121424){\makebox(0,0)[bl]{\hbox{\color{rgb_000000}\scriptsize \hbox{\color{rgb_000000}\scriptsize $(0,0)$}}}} +\put(3,0.09375){\makebox(0,0){\hbox{\color{rgb_000000}\scriptsize $\circle{0.0069185}\circle{0.013837}\circle{0.0207555}\circle{0.027674}$}}} +\put(3.97233,0.628576){\makebox(0,0)[tr]{\hbox{\color{rgb_000000}\scriptsize \hbox{\color{rgb_000000}\scriptsize $(h_\mathrm{size}, v_\mathrm{size})$}}}} +\put(4,0.65625){\makebox(0,0){\hbox{\color{rgb_000000}\scriptsize $\circle{0.0069185}\circle{0.013837}\circle{0.0207555}\circle{0.027674}$}}} +\put(3.5,0.038402){\makebox(0,0)[t]{\hbox{\color{rgb_000000}\scriptsize \hbox{\color{rgb_000000}\scriptsize Page (actual)}}}} +\path(4,0.09375)(4,0.65625)(3,0.65625)(3,0.09375)(4,0.09375) +\end{picture}% diff --git a/graphics/epix/doc/scaling.xp b/graphics/epix/doc/scaling.xp new file mode 100644 index 0000000000..7d243caabc --- /dev/null +++ b/graphics/epix/doc/scaling.xp @@ -0,0 +1,37 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +int main() +{ + picture(P(0,0), P(4,1), "4x0.75in"); + + begin(); + + font_size("scriptsize"); + + screen canv(P(0,0), P(1,1)); + activate(canv); + + border(); + ddot(canv.bl(), P(2,2), "$(x_\\mathrm{min},y_\\mathrm{min})$", tr); + ddot(canv.tr(), P(-2,-2), "$(x_\\mathrm{max},y_\\mathrm{max})$", bl); + label(canv.b(), P(0,-4), "Canvas (virtual)", b); + deactivate(canv); + + screen pg(P(0,0), P(1,1)); + activate(pg); + + border(); + ddot(pg.bl(), P(2,2), "$(0,0)$", tr); + ddot(pg.tr(), P(-2,-2), "$(h_\\mathrm{size}, v_\\mathrm{size})$", bl); + label(pg.b(), P(0,-4), "Page (actual)", b); + deactivate(pg); + + arrow(P(1.75, 0.5), P(2.75,0.5)); + + inset(canv, P(0,0.125), P(1.5, 1)); + inset(pg, P(3,0.125), P(4,0.875)); + + end(); +} diff --git a/graphics/epix/doc/sgn.eepic b/graphics/epix/doc/sgn.eepic new file mode 100644 index 0000000000..0aafc5d5af --- /dev/null +++ b/graphics/epix/doc/sgn.eepic @@ -0,0 +1,30 @@ +%% Generated from sgn.xp on Tue Jan 4 15:32:30 EST 2005 by +%% ePiX-1.0.3 +%% +%% Cartesian bounding box: [-2,2] x [-1,1] +%% Actual size: 1.5in x 0.75in +%% Figure offset: right by 0in, up by 0in +%% +\setlength{\unitlength}{1in} +\begin{picture}(1.5,0.75)(-0,-0) +%% --- +\path(0,0.375)(1.5,0.375) +\put(0,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}} +\put(0.375,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}} +\put(0.75,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}} +\put(1.125,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}} +\put(1.5,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}} +%% --- +\path(0.75,0)(0.75,0.75) +\put(0.75,0){\makebox(0,0)[c]{\rule{4pt}{0.5pt}}} +\put(0.75,0.75){\makebox(0,0)[c]{\rule{4pt}{0.5pt}}} +%% --- +\thicklines +\path(0,0)(0.75,0) +\path(1.5,0.75)(0.75,0.75) +\thinlines +\put(0.75,0.375){\makebox(0,0)[c]{{\circle*{0.041511}}}} +\whiten\put(0.75,0){\makebox(0,0)[c]{{\circle{0.041511}}}} +\whiten\put(0.75,0.75){\makebox(0,0)[c]{{\circle{0.041511}}}} +\put(0.75,-0.055348){\makebox(0,0)[t]{\code{sgn}}} +\end{picture} diff --git a/graphics/epix/doc/sgn.xp b/graphics/epix/doc/sgn.xp new file mode 100644 index 0000000000..5296973ba4 --- /dev/null +++ b/graphics/epix/doc/sgn.xp @@ -0,0 +1,28 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +int main() +{ + bounding_box(P(-2,-1),P(2,1)); + unitlength("1in"); + picture(1.5,0.75); + + begin(); + + h_axis(4); + v_axis(1); + + bold(); + line(P(x_min,-1), P(0,-1)); + line(P(x_max, 1), P(0, 1)); + + plain(); + dot(P(0,0)); + circ(P(0,-1)); + circ(P(0,1)); + + label(P(0,y_min), P(0,-4), "\\code{sgn}", b); + + end(); +} diff --git a/graphics/epix/doc/sinx.eepic b/graphics/epix/doc/sinx.eepic new file mode 100644 index 0000000000..c62bf19e00 --- /dev/null +++ b/graphics/epix/doc/sinx.eepic @@ -0,0 +1,40 @@ +%% Generated from sinx.xp on Tue Jan 4 15:32:32 EST 2005 by +%% ePiX-1.0.3 +%% +%% Cartesian bounding box: [-2,2] x [-1,1] +%% Actual size: 1.5in x 0.75in +%% Figure offset: right by 0in, up by 0in +%% +\setlength{\unitlength}{1in} +\begin{picture}(1.5,0.75)(-0,-0) +%% --- +\path(0,0.375)(1.5,0.375) +\put(0,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}} +\put(0.375,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}} +\put(0.75,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}} +\put(1.125,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}} +\put(1.5,0.375){\makebox(0,0)[c]{\rule{0.5pt}{4pt}}} +%% --- +\path(0.75,0)(0.75,0.75) +\put(0.75,0){\makebox(0,0)[c]{\rule{4pt}{0.5pt}}} +\put(0.75,0.75){\makebox(0,0)[c]{\rule{4pt}{0.5pt}}} +%% --- +\thicklines +\path(0,0.375)(0.025,0.362444)(0.05,0.351239)(0.075,0.343466)(0.1,0.340756) + (0.125,0.343988)(0.15,0.353074)(0.175,0.366907)(0.2,0.383461) + (0.225,0.400058)(0.25,0.413765)(0.275,0.42186)(0.3,0.422302) + (0.325,0.414135)(0.35,0.397758)(0.375,0.375)(0.4,0.348991) + (0.425,0.323823)(0.45,0.304047)(0.475,0.29406)(0.5,0.297469) + (0.525,0.316532)(0.55,0.351733)(0.575,0.40159)(0.6,0.462702) + (0.625,0.530061)(0.65,0.597586)(0.675,0.65881)(0.7,0.707649) + (0.725,0.73913)(0.75,0.75)(0.775,0.73913)(0.8,0.707649)(0.825,0.65881) + (0.85,0.597586)(0.875,0.530061)(0.9,0.462702)(0.925,0.40159) + (0.95,0.351733)(0.975,0.316532)(1,0.297469)(1.025,0.29406)(1.05,0.304047) + (1.075,0.323823)(1.1,0.348991)(1.125,0.375)(1.15,0.397758) + (1.175,0.414135)(1.2,0.422302)(1.225,0.42186)(1.25,0.413765) + (1.275,0.400058)(1.3,0.383461)(1.325,0.366907)(1.35,0.353074) + (1.375,0.343988)(1.4,0.340756)(1.425,0.343466)(1.45,0.351239) + (1.475,0.362444)(1.5,0.375) +\path(1.5,0.375) +\put(0.75,-0.055348){\makebox(0,0)[t]{\code{sinx}}} +\end{picture} diff --git a/graphics/epix/doc/sinx.xp b/graphics/epix/doc/sinx.xp new file mode 100644 index 0000000000..62c08bbc48 --- /dev/null +++ b/graphics/epix/doc/sinx.xp @@ -0,0 +1,23 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +int main() +{ + bounding_box(P(-2,-1),P(2,1)); + unitlength("1in"); + picture(1.5,0.75); + + begin(); + revolutions(); + + h_axis(4); + v_axis(1); + + bold(); + plot(sinx, x_min, x_max, 60); + + label(P(0,y_min), P(0,-4), "\\code{sinx}", b); + + end(); +} diff --git a/graphics/epix/doc/slices.eepic b/graphics/epix/doc/slices.eepic new file mode 100644 index 0000000000..4aebe69de4 --- /dev/null +++ b/graphics/epix/doc/slices.eepic @@ -0,0 +1,45 @@ +%% Generated from slices.xp on Sun Dec 31 13:11:11 EST 2006 by +%% ePiX-1.0.22 +%% +%% Cartesian bounding box: [0,7] x [0,2] +%% Actual size: 5in x 0.75in +%% Figure offset: right by 0in, up by 0in +%% +\setlength{\unitlength}{1in} +\begin{picture}(5,0.75)(-0,-0) +%% --- +\thicklines +\path(0,0)(0,0.75) +\path(0.178571,0)(0.178571,0.75) +\path(0.357143,0)(0.357143,0.75) +\path(0.535714,0)(0.535714,0.75) +\path(0.714286,0)(0.714286,0.75) +\path(0.892857,0)(0.892857,0.75) +\path(1.07143,0)(1.07143,0.75) +\path(1.25,0)(1.25,0.75) +\path(1.42857,0)(1.42857,0.75) +\path(0,0)(1.42857,0) +\path(0,0.107143)(1.42857,0.107143) +\path(0,0.214286)(1.42857,0.214286) +\path(0,0.321429)(1.42857,0.321429) +\path(0,0.428571)(1.42857,0.428571) +\path(0,0.535714)(1.42857,0.535714) +\path(0,0.642857)(1.42857,0.642857) +\path(0,0.75)(1.42857,0.75) +\put(0.714286,-0.055348){\makebox(0,0)[t]{\code{R}}} +\path(1.78571,0)(1.78571,0.75) +\path(1.96429,0)(1.96429,0.75) +\path(2.14286,0)(2.14286,0.75) +\path(2.32143,0)(2.32143,0.75) +\path(2.5,0)(2.5,0.75) +\path(2.67857,0)(2.67857,0.75) +\path(2.85714,0)(2.85714,0.75) +\path(3.03571,0)(3.03571,0.75) +\path(3.21429,0)(3.21429,0.75) +\put(2.5,-0.055348){\makebox(0,0)[t]{\code{R.slices1()}}} +\path(3.57143,0)(5,0) +\path(3.57143,0.25)(5,0.25) +\path(3.57143,0.5)(5,0.5) +\path(3.57143,0.75)(5,0.75) +\put(4.28571,-0.055348){\makebox(0,0)[t]{\code{R.slices2(3)}}} +\end{picture} diff --git a/graphics/epix/doc/slices.xp b/graphics/epix/doc/slices.xp new file mode 100644 index 0000000000..c67dddf876 --- /dev/null +++ b/graphics/epix/doc/slices.xp @@ -0,0 +1,39 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +void my_grid(const P& loc, int N1, int N2, std::string lab) +{ + if (0 < N1) + { + const double dx(1.0/N1); + for (int i=-N1; i<= N1; ++i) + line(loc+P(i*dx,0), loc+P(i*dx,2)); + } + + if (0 < N2) + { + const double dy(1.0/N2); + for (int i=0; i<= N2; ++i) + line(loc+P(-1,2*i*dy), loc+P(1,2*i*dy)); + } + + label(loc, P(0,-4), "\\code{"+lab+"}", b); +} + +int main() +{ + bounding_box(P(0,0),P(7,2)); + unitlength("1in"); + picture(5,0.75); + + begin(); + + bold(); + + my_grid(P(1,0), 4, 7, "R"); + my_grid(P(3.5,0), 4, 0, "R.slices1()"); + my_grid(P(6,0), 0, 3, "R.slices2(3)"); + + end(); +} diff --git a/graphics/epix/domain.cc b/graphics/epix/domain.cc new file mode 100644 index 0000000000..cbb86a4d42 --- /dev/null +++ b/graphics/epix/domain.cc @@ -0,0 +1,370 @@ +/* + * domain.cc -- ePiX domain slicing operations + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.10 + * Last Change: August09, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <cmath> +#include <list> +#include <iostream> + +#include "constants.h" +#include "triples.h" +#include "functions.h" + +#include "domain.h" + +namespace ePiX { + + typedef std::list<domain>::const_iterator dolci; + const double EPS(EPIX_EPSILON); + + mesh::mesh(int n1, int n2, int n3) + : n_1((int)max(1, fabs(n1))), + n_2((int)max(1, fabs(n2))), + n_3((int)max(1, fabs(n3))) { } + + mesh::mesh(int n) + : n_1((int)max(1, fabs(n))), + n_2((int)max(1, fabs(n))), + n_3((int)max(1, fabs(n))) { } + + mesh::mesh() : n_1(1), n_2(1), n_3(1) { } + + + domain::domain(const P& arg1, const P& arg2, const mesh& c, const mesh& f) + : m_corner1(arg1), m_corner2(arg2) + { + int c1(c.n1()), c2(c.n2()), c3(c.n3()); + int f1(f.n1()), f2(f.n2()), f3(f.n3()); + + if (m_corner1.x1() == m_corner2.x1()) { c1 = f1 = 1; } + if (m_corner1.x2() == m_corner2.x2()) { c2 = f2 = 1; } + if (m_corner1.x3() == m_corner2.x3()) { c3 = f3 = 1; } + + m_coarse = mesh(c1,c2,c3); + m_fine = mesh(f1,f2,f3); + } + + domain::domain(const P& arg1, const P& arg2, const mesh& c) + : m_corner1(arg1), m_corner2(arg2) + { + int c1(c.n1()), c2(c.n2()), c3(c.n3()); + + if (m_corner1.x1() == m_corner2.x1()) { c1 = 1; } + if (m_corner1.x2() == m_corner2.x2()) { c2 = 1; } + if (m_corner1.x3() == m_corner2.x3()) { c3 = 1; } + + m_coarse = mesh(c1,c2,c3); + m_fine = mesh(c1,c2,c3); + } + + // 1-dim'l domain + domain::domain(double t_min, double t_max, int num_pts) + : m_corner1(t_min), m_corner2(t_max), m_coarse(num_pts), m_fine(num_pts) + { } + + + int domain::dim() const + { + int D(0); + if (fabs(m_corner2.x1() - m_corner1.x1()) > EPIX_EPSILON) + ++D; + if (fabs(m_corner2.x2() - m_corner1.x2()) > EPIX_EPSILON) + ++D; + if (fabs(m_corner2.x3() - m_corner1.x3()) > EPIX_EPSILON) + ++D; + + return D; + } + + double domain::step1() const + { + return (m_corner2.x1() - m_corner1.x1())/m_coarse.n1(); + } + + double domain::step2() const + { + return (m_corner2.x2() - m_corner1.x2())/m_coarse.n2(); + } + + double domain::step3() const + { + return (m_corner2.x3() - m_corner1.x3())/m_coarse.n3(); + } + + double domain::dx1() const + { + return (m_corner2.x1() - m_corner1.x1())/m_fine.n1(); + } + + double domain::dx2() const + { + return (m_corner2.x2() - m_corner1.x2())/m_fine.n2(); + } + + double domain::dx3() const + { + return (m_corner2.x3() - m_corner1.x3())/m_fine.n3(); + } + + + // resizing attempts to preserve real resolution + domain domain::resize1(double a1, double b1) const + { + P new_corner1(a1, m_corner1.x2(), m_corner1.x3()); + P new_corner2(b1, m_corner2.x2(), m_corner2.x3()); + + // hack to avoid spurious round-down; should never cause round-up + double ratio((b1-a1)/(m_corner2.x1()-m_corner1.x1()) + EPS); + mesh new_c((int)floor(ratio*m_coarse.n1()), m_coarse.n2(), m_coarse.n3()); + mesh new_f((int)floor(ratio*m_fine.n1()), m_fine.n2(), m_fine.n3()); + + if (step1() == 0) + { + new_c = mesh(1, m_coarse.n2(), m_coarse.n3()); + new_f = mesh(1, m_fine.n2(), m_fine.n3()); + } + + return domain(new_corner1, new_corner2, new_c, new_f); + } + + domain domain::resize2(double a2, double b2) const + { + P new_corner1(m_corner1.x1(), a2, m_corner1.x3()); + P new_corner2(m_corner2.x1(), b2, m_corner2.x3()); + + double ratio((b2-a2)/(m_corner2.x2()-m_corner1.x2()) + EPS); + mesh new_c(m_coarse.n1(), (int)floor(ratio*m_coarse.n2()), m_coarse.n3()); + mesh new_f( m_fine.n1(), (int)floor(ratio*m_fine.n2()), m_fine.n3()); + + if (step2() == 0) + { + new_c = mesh(m_coarse.n1(), 1, m_coarse.n3()); + new_f = mesh( m_fine.n1(), 1, m_fine.n3()); + } + + return domain(new_corner1, new_corner2, new_c, new_f); + } + + domain domain::resize3(double a3, double b3) const + { + P new_corner1(m_corner1.x1(), m_corner1.x2(), a3); + P new_corner2(m_corner2.x1(), m_corner2.x2(), b3); + + double ratio((b3-a3)/(m_corner2.x3()-m_corner1.x3()) + EPS); + mesh new_c(m_coarse.n1(), m_coarse.n2(), (int)floor(ratio*m_coarse.n3())); + mesh new_f( m_fine.n1(), m_fine.n2(), (int)floor(ratio*m_fine.n3())); + + if (step3() == 0) + { + new_c = mesh(m_coarse.n1(), m_coarse.n2(), 1); + new_f = mesh( m_fine.n1(), m_fine.n2(), 1); + } + + return domain(new_corner1, new_corner2, new_c, new_f); + } + + + // "snip_to" is defined in functions.h and performs the "obvious" + // truncation: snip_to(x, a, b) = x, min(a,b), or max(a,b) + + // one slice + domain domain::slice1(double a1) const + { + a1 = snip_to(a1, m_corner1.x1(), m_corner2.x1()); + + return domain(P(a1, m_corner1.x2(), m_corner1.x3()), + P(a1, m_corner2.x2(), m_corner2.x3()), + mesh(1, m_coarse.n2(), m_coarse.n3()), + mesh(1, m_fine.n2(), m_fine.n3())); + } + + domain domain::slice2(double a2) const + { + a2 = snip_to(a2, m_corner1.x2(), m_corner2.x2()); + + return domain(P(m_corner1.x1(), a2, m_corner1.x3()), + P(m_corner2.x1(), a2, m_corner2.x3()), + mesh(m_coarse.n1(), 1, m_coarse.n3()), + mesh( m_fine.n1(), 1, m_fine.n3())); + } + + domain domain::slice3(double a3) const + { + a3 = snip_to(a3, m_corner1.x3(), m_corner2.x3()); + + return domain(P(m_corner1.x1(), m_corner1.x2(), a3), + P(m_corner2.x1(), m_corner2.x2(), a3), + mesh(m_coarse.n1(), m_coarse.n2(), 1), + mesh( m_fine.n1(), m_fine.n2(), 1)); + } + + + // coordinate slices + std::list<domain> domain::slices1(const unsigned int n) const + { + unsigned int N(m_coarse.n1()); + double du(step1()); + + if (n > 0) + { + du *= N*1.0/n; + N = n; + } + + std::list<domain> val; + + for (unsigned int i=0; i <= N; ++i) + val.push_back(slice1(m_corner1.x1() + i*du)); + + return val; + } + + std::list<domain> domain::slices2(const unsigned int n) const + { + unsigned int N(m_coarse.n2()); + double du(step2()); + + if (n > 0) + { + du *= N*1.0/n; + N = n; + } + + std::list<domain> val; + + for (unsigned int i=0; i <= N; ++i) + val.push_back(slice2(m_corner1.x2() + i*du)); + + return val; + } + + std::list<domain> domain::slices3(const unsigned int n) const + { + unsigned int N(m_coarse.n3()); + double du(step3()); + + if (n > 0) + { + du *= N*1.0/n; + N = n; + } + + std::list<domain> val; + + for (unsigned int i=0; i <= N; ++i) + val.push_back(slice3(m_corner1.x3() + i*du)); + + return val; + } + + P domain::corner1() const + { + return m_corner1; + } + P domain::corner2() const + { + return m_corner2; + } + + double domain::corner1_x1() const + { + return m_corner1.x1(); + } + double domain::corner1_x2() const + { + return m_corner1.x2(); + } + double domain::corner1_x3() const + { + return m_corner1.x3(); + } + + double domain::corner2_x1() const + { + return m_corner2.x1(); + } + double domain::corner2_x2() const + { + return m_corner2.x2(); + } + double domain::corner2_x3() const + { + return m_corner2.x3(); + } + + + int domain::coarse_n1() const + { + return m_coarse.n1(); + } + int domain::coarse_n2() const + { + return m_coarse.n2(); + } + int domain::coarse_n3() const + { + return m_coarse.n3(); + } + + int domain::fine_n1() const + { + return m_fine.n1(); + } + int domain::fine_n2() const + { + return m_fine.n2(); + } + int domain::fine_n3() const + { + return m_fine.n3(); + } + + + domain_list::domain_list(std::list<domain> arg) + : m_list(arg) { } + + domain_list& domain_list::add(const domain& arg) + { + m_list.push_back(arg); + return *this; + } + + domain_list& domain_list::add(const domain_list& arg) + { + // Less efficient than m_list.splice(m_list.end(), arg), but preserves arg + for (dolci p=arg.m_list.begin(); p != arg.m_list.end(); ++p) + m_list.push_back(*p); + + return *this; + } +} // end of namespace diff --git a/graphics/epix/domain.h b/graphics/epix/domain.h new file mode 100644 index 0000000000..d0b2bf70ea --- /dev/null +++ b/graphics/epix/domain.h @@ -0,0 +1,143 @@ +/* + * domain.h -- ePiX mesh and domain classes + * + * This file is part of ePiX, a preprocessor for creating high-quality + * line figures in LaTeX + * + * Version 1.1.6 + * Last Change: July 04, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_DOMAIN +#define EPIX_DOMAIN + +#include <list> + +#include "triples.h" +#include "functions.h" + +namespace ePiX { + + class mesh { + public: + mesh(int n1, int n2, int n3=1); + mesh(int n); // mesh(n, n, n); + mesh(); // mesh(1, 1, 1); + + int n1() const { return n_1; } + int n2() const { return n_2; } + int n3() const { return n_3; } + + private: + int n_1; + int n_2; + int n_3; + }; // end of class mesh + + // A domain is a gridded coordinate box with specified corners + // and coarse/fine meshes, used for plotting. The "coarse" step + // sizes are step1, etc., and the "fine" step sizes are dx1, etc. + // Steps may be negative. + // + // A domain may be "sliced" by setting one of its coordinates to + // a specified constant. + // + // Data members are public for convenience; each member ensures + // its own well-constructedness. + // + class domain { + public: + domain(const P& arg1, const P& arg2, const mesh& c, const mesh& f); + domain(const P& arg1, const P& arg2, const mesh& c); + + // 1-dim'l domain + domain(double t_min, double t_max, int num_pts); + + int dim() const; // dimension + + // big and small steps + double step1() const; + double step2() const; + double step3() const; + + double dx1() const; + double dx2() const; + double dx3() const; + + // resizing attempts to preserve real resolution + domain resize1(double a1, double b1) const; + domain resize2(double a2, double b2) const; + domain resize3(double a3, double b3) const; + + // coordinate slices + domain slice1(double a1) const; + domain slice2(double a2) const; + domain slice3(double a3) const; + + // "n=0": use number from coarse mesh + std::list<domain> slices1(const unsigned int n=0) const; + std::list<domain> slices2(const unsigned int n=0) const; + std::list<domain> slices3(const unsigned int n=0) const; + + // state functions for internal use + P corner1() const; + P corner2() const; + + double corner1_x1() const; + double corner1_x2() const; + double corner1_x3() const; + + double corner2_x1() const; + double corner2_x2() const; + double corner2_x3() const; + + int coarse_n1() const; + int coarse_n2() const; + int coarse_n3() const; + + int fine_n1() const; + int fine_n2() const; + int fine_n3() const; + + private: + P m_corner1; + P m_corner2; + mesh m_coarse; + mesh m_fine; + }; // end of class domain + + class domain_list { + public: + domain_list(std::list<domain>); // implicitly converts "slices" output + domain_list& add(const domain&); + domain_list& add(const domain_list&); + + std::list<domain> m_list; // public: we're a simple wrapper + }; // end of class domain_list +} // end of namespace + +#endif /* EPIX_DOMAIN */ diff --git a/graphics/epix/edge_data.h b/graphics/epix/edge_data.h new file mode 100644 index 0000000000..60d7a8bf56 --- /dev/null +++ b/graphics/epix/edge_data.h @@ -0,0 +1,75 @@ +/* + * edge_data.h -- ePiX::edge implementation classes for polyline/polygon + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * Last Change: September 13, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_EDGE_DATA +#define EPIX_EDGE_DATA +#include <algorithm> + +#include "triples.h" +#include "pairs.h" + +namespace ePiX { + + // basic edge data: ordered endpoints and visibility flag + template<typename T> class edge_data { + public: + edge_data(const T& fm, const T& to, bool seen) + : m_tail(fm), m_head(to), m_seen(seen) { } + + T tail() const { return m_tail; } + T head() const { return m_head; } + bool is_seen() const { return m_seen; } + bool is_null() const { return m_tail == m_head; } + + edge_data& reverse() + { + std::swap(m_tail, m_head); + return *this; + } + + double length() const + { + return norm(m_head - m_tail); + } + + void seen(bool S) { m_seen=S; } + + private: + T m_tail; + T m_head; + bool m_seen; + }; + + typedef edge_data<P> edge3d; + typedef edge_data<pair> edge2d; +} // end of namespace + +#endif /* EPIX_EDGE_DATA */ diff --git a/graphics/epix/eepic.cc b/graphics/epix/eepic.cc new file mode 100644 index 0000000000..eaed35a653 --- /dev/null +++ b/graphics/epix/eepic.cc @@ -0,0 +1,297 @@ +/* + * eepic.cc -- ePiX's eepic output format + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> +#include <list> + +#include <string> +#include <sstream> + +#include <set> // for pallet + +#include "constants.h" + +#include "functions.h" + +#include "pairs.h" +#include "edge_data.h" + +#include "Color.h" + +#include "path_style.h" +#include "pen_data.h" + +#include "hatching.h" + +#include "format.h" +#include "eepic.h" + +namespace ePiX { + + // rotate successive hatches this much to avoid parallelity + const double d_hatch_theta(111.24612); // ~90*(sqrt(5)-1) + + eepic::eepic() + : m_ink(Black()), m_nib(PLAIN_WIDTH), m_hatch(0) { } + + eepic* eepic::clone() const + { + return new eepic(*this); + } + + // Filled region with specified Cartesian edges, offset, and color + std::string eepic::print_fill(const std::list<edge2d>& edges, + const pair& offset, + const Color& fc, + const pen_data& line, + const std::string& len) const + { + std::stringstream obuf; + + // set angle + const double hatch_angle(m_hatch); + m_hatch += d_hatch_theta; + + // draw hatch lines separated by pen.width(), actual line width + // scaled by density + double dens(fc.alpha()); // transparency + if (dens < EPIX_EPSILON) + return ""; + + // else + length hatch_width(length(PLAIN_WIDTH).to(len)); + + path_state style; // solid + + if (EPIX_EPSILON < dens*hatch_width.magnitude()) + { + // Use fill color, draw thin lines to simulate transparency. + // Area covered by double-hatching is (supposed to be) dens. + pen_data fill_pen(fc, (1-sqrt(1-dens))*hatch_width); + + // draw hatch-filled edges + hatch_data bd1(hatch_angle, hatch_width.magnitude(), edges); + for (unsigned int i=0; i < bd1.data().size(); ++i) + obuf << format::print_line(bd1.data().at(i), offset, + fill_pen, style, std::string(""), len); + + // re-draw hatch lines at right angles... + hatch_data bd2(hatch_angle+90, hatch_width.magnitude(), edges); + for (unsigned int i=0; i < bd2.data().size(); ++i) + obuf << format::print_line(bd2.data().at(i), offset, + fill_pen, style, "", len); + } + + obuf << set_pen_state(line); + obuf << print_paths(edges, offset, "", len); + + return obuf.str(); + } // end of eepic::print_fill() + + + // may assume line is visible + std::string eepic::print_line(const std::list<edge2d>& edges, + const pair& offset, + const pen_data& line, + const pen_data& base, + const path_state& style, + const std::string& len) const + { + std::string value; + + // draw *solid* base first if necessary + if (line.width() < base.width() && !base.color().is_unset()) + value += format::print_line(edges, offset, base, path_state(), "", len); + + return value += format::print_line(edges, offset, line, style, "", len); + } + + + std::string eepic::print_color(const std::string& model, + const std::string& name, + double d1, double d2, double d3) const + { + return format::xdefinecolor(model, name, d1, d2, d3); + } + + std::string eepic::print_color(const std::string& model, + const std::string& name, + double d1, double d2, + double d3, double d4) const + { + return format::xdefinecolor(model, name, d1, d2, d3, d4); + } + + // one-line comment + std::string eepic::print_comment(const std::string& msg) const + { + std::stringstream obuf; + obuf << "%% " << msg << std::endl; + + return obuf.str(); + } + + // verbatim string, newline protected + std::string eepic::print_verbatim(const std::string& msg) const + { + std::stringstream obuf; + obuf << msg << "%" << std::endl; + + return obuf.str(); + } + + void eepic::reset_state() const + { + m_ink = Neutral(); + m_nib = length(0); + } + + + //// private member functions //// + std::string eepic::start_picture(const pair& sz, const pair& offset) const + { + std::stringstream obuf; + obuf << "\\begin{picture}" + << format::print(sz) << format::print(-offset) << "%" << std::endl; + + return obuf.str(); + } + + std::string eepic::end_picture() const + { + std::stringstream obuf; + obuf << "\\end{picture}%" << std::endl; + return obuf.str(); + } + + std::string eepic::set_unitlength(const std::string& len) const + { + std::stringstream obuf; + + obuf << "\\setlength{\\unitlength}{1" << len << "}%" << std::endl; + + return obuf.str(); + } + + + std::string eepic::usepackages() const + { + return "usepackages epic,eepic,xcolor"; + } + + // string argument for passing attributes local to this path/loop + std::string eepic::start_open_path(const std::string& attribs) const + { + return "\\path"; + } + + std::string eepic::end_open_path(const std::string& attribs) const + { + std::stringstream obuf; + obuf << std::endl; + return obuf.str(); + } + + std::string eepic::start_closed_path(const std::string& attribs) const + { + return "\\path"; + } + + std::string eepic::end_closed_path(const std::string& attribs) const + { + std::stringstream obuf; + obuf << std::endl; + return obuf.str(); + } + + std::string eepic::set_fill_state(const Color& col) const // unused + { + std::stringstream obuf; + + if (m_ink != col) + { + m_ink = col; + obuf << "\\color{" << m_ink.name() << "}%" << std::endl; + } + + return obuf.str(); + } + + std::string eepic::set_pen_state(const pen_data& pen) const + { + std::stringstream obuf; + + if (m_nib != pen.width()) + { + m_nib = pen.width(); + obuf << "\\allinethickness{" << m_nib.name() << "}%" << std::endl; + } + + if (m_ink != pen.color()) + { + m_ink = pen.color(); + obuf << "\\color{" << m_ink.name() << "}%" << std::endl; + } + + return obuf.str(); + } + + // place a LaTeX box of width zero (containing string) at location (pair) + std::string eepic::put_box(const pair& loc, const std::string& msg) const + { + std::stringstream obuf; + obuf << "\\put" << print(loc) << "{" << msg << "}" << std::endl; + + return obuf.str(); + } + + std::string eepic::print_circle_marker(const pair& here, double diam, + bool fill, const Color& color, + const std::string& len) const + { + std::stringstream obuf; + obuf << "\\put" << print(here) + << "{\\color{" << print(color) << "}$"; + + if (fill) + obuf << "\\allinethickness{" << 0.5*diam << len << "}" + << "\\circle{" << 0.5*diam << "}"; + + else + obuf << "\\circle{" << diam << "}"; + + obuf << "$}%" << std::endl; + + return obuf.str(); + } +} // end of namespace diff --git a/graphics/epix/eepic.h b/graphics/epix/eepic.h new file mode 100644 index 0000000000..08d37e4874 --- /dev/null +++ b/graphics/epix/eepic.h @@ -0,0 +1,127 @@ +/* + * eepic.h -- ePiX's eepic output format + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.15 + * Last Change: September 07, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_EEPIC +#define EPIX_EEPIC + +#include <string> +#include <list> +#include <set> + +#include "Color.h" +#include "length.h" + +#include "edge_data.h" +#include "format.h" + +namespace ePiX { + + class path_state; + class pen_data; + + class eepic : public format { + public: + eepic(); + + eepic* clone() const; + + // Filled region with specified Cartesian edges, offset, and color + std::string print_fill(const std::list<edge2d>& edges, + const pair& offset, + const Color& fill, + const pen_data& line, + const std::string& len) const; + + // Unfilled region, specified Cartesian edges. Should generally be + // trivially implemented using one-pen function (supplied). + std::string print_line(const std::list<edge2d>& edges, + const pair& offset, + const pen_data& line_pen, + const pen_data& base_pen, + const path_state& style, + const std::string& len) const; + + // Print color declaration strings: model, name, densities + std::string print_color(const std::string&, + const std::string&, + double, + double, + double) const; + + std::string print_color(const std::string&, + const std::string&, + double, + double, + double, + double) const; + + // One-line comment + std::string print_comment(const std::string&) const; + + // Verbatim output + std::string print_verbatim(const std::string&) const; + + void reset_state() const; + + private: + mutable Color m_ink; + mutable length m_nib; + mutable double m_hatch; + + std::string start_picture(const pair&, const pair&) const; + std::string end_picture() const; + + std::string set_unitlength(const std::string& len) const; + + std::string usepackages() const; + + // string argument for passing attributes local to this path/loop + std::string start_open_path(const std::string&) const; + std::string end_open_path(const std::string&) const; + + std::string start_closed_path(const std::string&) const; + std::string end_closed_path(const std::string&) const; + + // print declarations to set state of output format + std::string set_fill_state(const Color&) const; + std::string set_pen_state(const pen_data&) const; + + // place a LaTeX box of width zero (containing string) at location (pair) + std::string put_box(const pair&, const std::string&) const; + + std::string print_circle_marker(const pair& here, double diam, + bool fill, const Color& color, + const std::string& len) const; + }; // end of class eepic +} // end of namespace + +#endif /* EPIX_EEPIC */ diff --git a/graphics/epix/elaps.1 b/graphics/epix/elaps.1 new file mode 100644 index 0000000000..4430a02037 --- /dev/null +++ b/graphics/epix/elaps.1 @@ -0,0 +1 @@ +.so man1/epix.1 diff --git a/graphics/epix/elaps.in b/graphics/epix/elaps.in new file mode 100644 index 0000000000..6e8041f3d3 --- /dev/null +++ b/graphics/epix/elaps.in @@ -0,0 +1,485 @@ +#! /bin/bash +# +# elaps: Convert an epix file to encapsulated Postscript, i.e. epix2eps +# +# Options: --help for usage, --version for version and license +# +# Compiler flags may be specified on the command line or in the config +# file ~/.epixrc. The script attempts to deal intelligently with missing +# or multiple extensions. If the input file has a recognized extension, +# there's no issue. If only the root name <infile> is given, the script +# searches for completions in the order of preference dictated by the +# variable EPIX_EXTENSIONS. A warning is issued for multiple matches. +# +# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 +# Andrew D. Hwang <For address, do "elaps -V"> +# + +. "@pkglibdir@/epix-lib.sh" + +EPIX_CONFIG_FILE="$HOME/.epixrc" +# Search these extensions in order of preference +ELAPS_EXTENSIONS="eepic xp flx cc c C cpp" # or NULL +ELAPS_DOT_EXT=".${ELAPS_EXTENSIONS// /|.}" # for usage message + +# default options +ELAPS_PKGS="latexsym,amsmath,rotating" +declare ELAPS_PSTCOL +ELAPS_SIZE=12 # figure compiled in [12pt]{article} + +ELAPS_PDF="no" # Create PDF file? +ELAPS_PS="no" # Create PS file instead of EPS? + +declare -a EPIX_OPTS +declare -a DVIPS_OPTS + +LATEX_BIN=latex # elaps only uses [huge]latex, not pdflatex or pslatex +LATEX_INTERACT="scrollmode" + +# auxiliary programs +PS2EPS="ps2epsi" + +# internal filenames +PID=$$ +ELAPS_TEMP_EEPIC="$PROG-$PID".eepic +ELAPS_TEMP_LATEX="$PROG-$PID".tex +ELAPS_TEMP_DVI="$PROG-$PID".dvi +ELAPS_TEMP_PS="$PROG-$PID".ps +ELAPS_TEMP_EPSI="$PROG-$PID".epsi + +# globals to pass tokens +ELAPS_USER_OUT="no" # user specified output file? + +declare -a ELAPS_FILE_LIST +declare -a TMP_CMD + +declare -a TEMPFILES +trap '[ -n "${TEMPFILES[*]}" ] && rm -f "${TEMPFILES[@]}"' 0 1 2 3 7 10 13 15 + +TEMPFILES=("$ELAPS_TEMP_EEPIC" "$ELAPS_TEMP_LATEX" "$ELAPS_TEMP_DVI" \ + "$ELAPS_TEMP_PS" "$ELAPS_TEMP_EPSI" ) + +function elaps_help() +{ +cat <<"HELP" +Options: + -h, --help + Show this message and exit + + -V, --version, --gpl + Show version and license + + -v, --verbose + Show success/failure messages + + -H, --huge + Use hugelatex (if available) + + -i, --interactive + Run LaTeX interactively (implies verbose) + + -n, --no-config + Ignore $(HOME)/.dvipsrc + + -o, --output + Specify output file (ONLY for use with a single input file) + + --pst + Write eepic file using PSTricks macros + + --tikz + Write eepic file using tikz macros + + --eepic + Write eepic file using eepic macros + + -p, --pkg <LaTeX package> + Use an additional LaTeX package in the temporary LaTeX file, e.g. + "-p floatflt". Multiple packages are specified one per "-p" flag. + + -pdf, --pdf + Create PDF file instead of EPS + + -ps, --ps + Create standalone PostScript file (overrides --pdf) + + --pstcol + Use (obsolete) pstcol package instead of pstricks + + -P<printer> + dvips printer options, e.g. "-Pamz", may be given on the command + line. They are also read from ~/.dvipsrc if this file exists. + + --size + Set default font size: 10, 11, or 12 (default) + + Other options are passed to epix (q.v.). + +HELP +ePiX_bugreport + +} # End of elaps_help + +# Generate US letter-friendly LaTeX file +function elaps_make_latex () +{ + ALL_LATEX_PKGS="$ELAPS_PKGS" + +# Get LATEX_PKGS from input file + ePiX_usepackages $2 + if [ ! -z "$LATEX_PKGS" ]; then # should always be true... + ALL_LATEX_PKGS="$ALL_LATEX_PKGS,$LATEX_PKGS" + else # compatibility fallback + ALL_LATEX_PKGS="$ALL_LATEX_PKGS,epic,eepic,pstricks" + fi + +# Clear global + unset LATEX_PKGS + +# No effect unless file requires pstricks + if [ ! -z "$ELAPS_PSTCOL" ]; then + ALL_LATEX_PKGS="${ALL_LATEX_PKGS/pstricks/$ELAPS_PSTCOL/}" + fi + +cat <<LaTeX >> $1 +\documentclass[${ELAPS_SIZE}pt]{article} +\usepackage{$ALL_LATEX_PKGS} +\setlength{\textwidth}{7.5in} +\setlength{\textheight}{9.5in} +\setlength{\oddsidemargin}{-0.5in} +\setlength{\topmargin}{0in} +\pagestyle{empty} + +\begin{document} +\vfil +\begin{center} +\input{$2} +\end{center} +\vfil +\end{document} + +LaTeX +} # End of elaps_make_latex + + +function elaps_parse_options () +{ + while [ "$1" != "${1#-}" ]; do + case "$1" in + + -h|--help) + ePiX_usage elaps $ELAPS_DOT_EXT + elaps_help + exit 0 + ;; + + -H|--huge) + if [ $(which hugelatex 2> /dev/null) ]; then + LATEX_BIN=hugelatex + else + ePiX_warn " hugelatex not available, ignoring \"$1\" option" + fi + shift + ;; + + -i|--interactive) + EPIX_STDOUT="$SYSTEM_STDOUT" + LATEX_INTERACT="errorstopmode" + shift + ;; + + -n|--no-config) # do not use ~/.dvipsrc + export DVIPSRC="$SYSTEM_DEVNULL" + shift + ;; + + -o|--output) + if [ "$2" = "${2%%.eps}.eps" ]; then + EPIX_OUTROOT="${2%%.eps}" + + elif [ "$2" = "${2%%.pdf}.pdf" ]; then + ELAPS_PDF="yes" + EPIX_OUTROOT="${2%%.pdf}" + + else + EPIX_OUTROOT="$2" + fi + ELAPS_USER_OUT="yes" + shift 2 + ;; + + --pst) + EPIX_OPTS=("${EPIX_OPTS[@]}" "-DEPIX_FMT_PSTRICKS") + shift; continue + ;; + + --tikz) + EPIX_OPTS=("${EPIX_OPTS[@]}" "-DEPIX_FMT_TIKZ") + shift; continue + ;; + + --eepic) + EPIX_OPTS=("${EPIX_OPTS[@]}" "-DEPIX_FMT_EEPIC") + shift; continue + ;; + + -P) + DVIPS_OPTS=("${DVIPS_OPTS[@]}" "-P$2") + shift 2 + ;; + + -P*) + DVIPS_OPTS=("${DVIPS_OPTS[@]}" "$1") + shift + ;; + + -pdf|--pdf) + ELAPS_PDF="yes" + shift + ;; + + -ps|--ps) + ELAPS_PS="yes" + ELAPS_PDF="no" # redundant; enforced by logic later + shift + ;; + + --pstcol) + ELAPS_PSTCOL="pstcol,xcolor" + shift + ;; + + -p|--pkg) + if [ "$2" != "${2#-}" ]; then + ePiX_warn "\"$1\" cannot be followed by \"$2\"; skipping" + shift 1 + else + ELAPS_PKGS="$ELAPS_PKGS,$2" + shift 2 + fi + ;; + + -p*) + ELAPS_PKGS="$ELAPS_PKGS,${1#-p}" + shift + ;; + + # Deliberately undocumented; run silently, no log file + -q|--quiet) + EPIX_STDOUT="$SYSTEM_DEVNULL" + EPIX_STDERR="$SYSTEM_DEVNULL" + LATEX_INTERACT="batchmode" + shift; continue + ;; + + --size) + ELAPS_SIZE="$2" + shift 2 + ;; + + -V|--version|--gpl) + ePiX_version elaps + ePiX_license + exit 0 + ;; + + -v|--verbose) + if [ -z "$2" ]; then + echo "Please use -V for version" + exit 0 + fi + EPIX_STDOUT="$SYSTEM_STDOUT" + shift + ;; + + -vv) + echo "Discontinued option -vv; please use -v for verbose output" + exit 0 + ;; + + + # pass other options to epix + -i*|-u|-x|-I|-L|-l|-W) + EPIX_OPTS=("${EPIX_OPTS[@]}" "$1" "$2") + shift 2 + ;; + + -b) + ePiX_warn "Skipping option \"$1 $2\"" + shift 2 + ;; + + *) + EPIX_OPTS=("${EPIX_OPTS[@]}" "$1") + shift + ;; + esac + done + + # Assume remaining parameters are input files + INFILE_COUNT=$# + + if [ "$ELAPS_USER_OUT" = "yes" -a $INFILE_COUNT -gt 1 ]; then + shift $(($INFILE_COUNT - 1)) + ePiX_warn "Output file specified with multiple input files. Skipping all but \"$*\"" + fi + + ELAPS_FILE_LIST=("$@") +} # end of elaps_parse_options() + + +function elaps_process_files() +{ + if [ -z "$1" ]; then + ePiX_die "No input file specified" + fi + + # file counts + local processed=0 + local success=0 + local failure=0 + + for EPIX_INFILE in "${ELAPS_FILE_LIST[@]}"; do + + # sets EPIX_INROOT, EPIX_SUFFIX, EPIX_NOTFOUND, touches EPIX_LOGFILE + epix_parse_filename "$EPIX_INFILE" "$ELAPS_EXTENSIONS" + let processed=processed+1 + + if [ "$EPIX_NOTFOUND" = "yes" ]; then + let failure=failure+1 + continue + fi + + : ${EPIX_OUTROOT:=$EPIX_INROOT} + EPIX_OUTFILE="$EPIX_OUTROOT".eepic + + # Create eepic file if necessary + if [ "$EPIX_SUFFIX" != "eepic" ]; then + if [ -f "$EPIX_OUTFILE" ]; then # back up existing file + mv -f "$EPIX_OUTFILE" "${EPIX_OUTFILE}~" + fi + + TMP_CMD=(@bindir@/epix "${EPIX_OPTS[@]}" -o "$EPIX_OUTFILE" "$EPIX_INFILE") + + ePiX_command "${TMP_CMD[@]}" + echo "---" | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT" + + if [ "$EPIX_INFILE" -nt "$EPIX_OUTFILE" ]; then + ePiX_warn "\"${TMP_CMD[*]}\" failed" + unset EPIX_OUTFILE + unset EPIX_OUTROOT + let failure=failure+1 + continue + + else + ln -s "$EPIX_OUTFILE" "$ELAPS_TEMP_EEPIC" + fi + + else # we were passed an eepic file name + ln -s "$EPIX_INFILE" "$ELAPS_TEMP_EEPIC" + fi + + elaps_make_latex "$ELAPS_TEMP_LATEX" "$ELAPS_TEMP_EEPIC" + + # Create $ELAPS_TEMP_PS + TMP_CMD=($LATEX_BIN -interaction=$LATEX_INTERACT "$ELAPS_TEMP_LATEX") + + ePiX_command "${TMP_CMD[@]}" + + if [ "$ELAPS_TEMP_LATEX" -nt "$ELAPS_TEMP_DVI" ]; then + # Report informative (but fake) command line + ePiX_warn "\"$LATEX_BIN -interaction=$LATEX_INTERACT ${EPIX_INROOT}.tex\" failed" + rm -f "$ELAPS_TEMP_LATEX" "$ELAPS_TEMP_EEPIC" # clean temps + unset EPIX_OUTFILE + unset EPIX_OUTROOT + let failure=failure+1 + continue + else + echo "---" | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT" + fi + + TMP_CMD=(dvips "${DVIPS_OPTS[@]}" -f -o "$ELAPS_TEMP_PS" "$ELAPS_TEMP_DVI") + + ePiX_command "${TMP_CMD[@]}" + + if [ "$ELAPS_TEMP_DVI" -nt "$ELAPS_TEMP_PS" ]; then + # Report informative (but fake) command line + ePiX_warn "\"dvips ${DVIPS_OPTS[@]} -f -o ${EPIX_INROOT}.ps ${EPIX_INROOT}.dvi\" failed" + + unset EPIX_OUTFILE + unset EPIX_OUTROOT + let failure=failure+1 + continue + else + echo "---" | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT" + fi + + if [ "$ELAPS_PS" = "yes" ]; then + # fix title; can't conveniently put sed command into ePiX_command + echo -n "sed \"s/$PROG-$PID/$EPIX_INROOT/g\" \"$ELAPS_TEMP_PS\"" \ + | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT" + echo " > \"$EPIX_OUTROOT.ps\"" \ + | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT" + + sed "s/$PROG-$PID/$EPIX_INROOT/g" "$ELAPS_TEMP_PS" \ + > "$EPIX_OUTROOT.ps" + + else + # Create eps file, + TMP_CMD=("$PS2EPS" "$ELAPS_TEMP_PS") + ePiX_command "${TMP_CMD[@]}" + + # fix title, + echo -n "sed \"s/$PROG-$PID/$EPIX_INROOT/g\" \"$ELAPS_TEMP_EPSI\""\ + | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT" + echo " > \"$EPIX_OUTROOT.eps\"" \ + | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT" + + sed "s/$PROG-$PID/$EPIX_INROOT/g" \ + "$ELAPS_TEMP_EPSI" > "$EPIX_OUTROOT.eps" && + rm -f "$ELAPS_TEMP_EPSI" + + # create pdf if requested, + if [ "$ELAPS_PDF" = "yes" ]; then + echo -n "grep -v \"^%%Orientation:\" \"$EPIX_OUTROOT.eps\"" \ + | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT" + echo " | epstopdf --filter --outfile=\"$EPIX_OUTROOT.pdf\"" \ + | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT" + # avoid ghostscript rotation bug + grep -v "^%%Orientation:" "$EPIX_OUTROOT.eps" \ + | epstopdf --filter --outfile="$EPIX_OUTROOT.pdf" + rm -f "$EPIX_OUTROOT.eps" # clean up eps + fi + fi + + let success=success+1 + unset EPIX_OUTFILE + unset EPIX_OUTROOT + + # and clean up + rm -f "$ELAPS_TEMP_LATEX" "$ELAPS_TEMP_DVI" "$ELAPS_TEMP_PS" \ + "$ELAPS_TEMP_EEPIC" "$PROG-$PID.aux" "$PROG-$PID.log" + + echo -e "\nTranscript written on $EPIX_LOGFILE" > "$EPIX_STDOUT" + + done # for EPIX_INFILE in $INFILE_LIST + + if [ $processed -gt 1 ]; then + echo "$processed files processed: $success successfully, $failure failed" > "$EPIX_STDERR" + fi +} # elaps_process_files() + + +## Script proper starts here ## + +if [ $# -eq 0 ]; then + ePiX_usage elaps $ELAPS_DOT_EXT + elaps_help + exit 0 +fi + +elaps_parse_options "$@" + +elaps_process_files "${ELAPS_FILE_LIST[@]}" + +exit 0 diff --git a/graphics/epix/enums.h b/graphics/epix/enums.h new file mode 100644 index 0000000000..1da13b67b1 --- /dev/null +++ b/graphics/epix/enums.h @@ -0,0 +1,52 @@ +/* + * enums.h -- ePiX's user-visible enumeration types + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.0.23 + * Last Change: January 10, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_ENUMS +#define EPIX_ENUMS + +namespace ePiX { + + enum epix_mark_type {PATH, CIRC, SPOT, RING, DOT, DDOT, PLUS, OPLUS, + TIMES, OTIMES, DIAMOND, UP, DOWN, BOX, BBOX, + HTICK, VTICK, TEXT}; + + enum epix_label_posn {none, c, r, tr, rt, t, tl, lt, l, bl, lb, b, br, rb}; + + enum epix_integral_type {LEFT, RIGHT, UPPER, LOWER, TRAP, MIDPT}; + + enum epix_field_type {SLOPE, DART, VECTOR}; + +} // end of namespace + +#endif /* EPIX_ENUMS */ diff --git a/graphics/epix/epix-lib.sh b/graphics/epix/epix-lib.sh new file mode 100644 index 0000000000..422b2e7e16 --- /dev/null +++ b/graphics/epix/epix-lib.sh @@ -0,0 +1,179 @@ +# Common functions for ePiX's shell scripts +# +PROG=$(basename $0) + +# global variables for all scripts +EPIX_PID=$$ + +# Needn't be secure +EPIX_TEMPDIR=${PROG}-${EPIX_PID} + +# Caution: Common logfile name for all ${PROG} processes in cwd, +# used until we've parsed command-line options. Will assign a +# unique name once we have an input file name. +EPIX_LOGFILE=${PROG}.log +if [ -f "${EPIX_LOGFILE}" ]; then rm -f "${EPIX_LOGFILE}"; fi + +# These may need to be modified +declare -r SYSTEM_STDOUT=/dev/stdout +declare -r SYSTEM_STDERR=/dev/stderr +declare -r SYSTEM_DEVNULL=/dev/null + +EPIX_STDOUT=$SYSTEM_DEVNULL +EPIX_STDERR=$SYSTEM_STDERR + +declare EPIX_NOTFOUND + +declare LATEX_PKGS + +# in increasing order of severity +function ePiX_msg { + echo -e "$PROG: $@" | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT" +} + +function ePiX_warn { + echo -e "$PROG: WARNING: $@" | tee -a "$EPIX_LOGFILE" >"$EPIX_STDERR" +} + +function ePiX_fail { + echo -e "$PROG: WARNING: $@" | tee -a "$EPIX_LOGFILE" >"$EPIX_STDERR" + if [ "$EPIX_OUTROOT" = "$EPIX_INROOT" ]; then unset EPIX_OUTROOT; fi + let failure=failure+1 +} + +function ePiX_die { + echo -e "$PROG: ERROR: $@" | tee -a "$EPIX_LOGFILE" >"$EPIX_STDERR" + echo -e "Transcript written on ${EPIX_LOGFILE}\n" + exit 1; +} + +# Echo command to stderr/stdout and logfile, then run command +# +function ePiX_command { + ePiX_msg "$@" + ("$@" 2>&1) | tee -a "$EPIX_LOGFILE" > "$EPIX_STDOUT" +} + + +# epix_parse_filename EPIX_INFILE MY_EXTENSIONS: +# +# Attempt to decompose EPIX_INFILE into EPIX_INROOT.EPIX_SUFFIX, with +# EPIX_SUFFIX in MY_EXTENSIONS, then check for existence of file. +# If EPIX_INFILE has no suffix, the first match (if any) wins. +# If no file is found, EPIX_NOTFOUND="yes" +# +function epix_parse_filename { + EPIX_INFILE="$1" + shift; + MY_EXTENSIONS="$@" + + unset EPIX_INROOT + unset EPIX_SUFFIX + unset EPIX_NOTFOUND + + local FOUND_CT=0 + + # Check for recognized extension + for EXT in $MY_EXTENSIONS; do + TMP_ROOT="${EPIX_INFILE%.$EXT}" + if [ "$EPIX_INFILE" = "$TMP_ROOT.$EXT" ]; then + EPIX_INROOT="$TMP_ROOT" + EPIX_SUFFIX="$EXT" + break + fi + done + + # None found; were we given just the root? + if [ -z "$EPIX_SUFFIX" ]; then + EPIX_INROOT="${EPIX_INFILE%%.}" + + # Search for (and count) completions + for EXT in $MY_EXTENSIONS; do + if [ -f "$EPIX_INROOT.$EXT" ]; then + if [ $FOUND_CT -eq 0 ]; then # first match wins + EPIX_INFILE="$EPIX_INROOT.$EXT" + EPIX_SUFFIX="$EXT" + fi + + let FOUND_CT=FOUND_CT+1 + fi + done + + # no match + if [ $FOUND_CT -eq 0 ]; then EPIX_NOTFOUND="yes"; fi + + # Found suffix, check for input file + else + if [ -f "$EPIX_INFILE" ]; then + let FOUND_CT=FOUND_CT+1 + else + EPIX_NOTFOUND="yes" + fi + fi # if $EPIX_SUFFIX="" + + # initialize logfile + EPIX_LOGFILE="${EPIX_INROOT}_${EPIX_SUFFIX}.log" + if [ -f "$EPIX_LOGFILE" ]; then rm "$EPIX_LOGFILE"; fi + touch "$EPIX_LOGFILE" + + # Print status messages + ePiX_msg "Processing $EPIX_INFILE:" + + if [ $FOUND_CT -eq 0 ]; then + ePiX_warn " No completion of \"$EPIX_INROOT\" found" + + elif [ $FOUND_CT -ge 2 ]; then + ePiX_warn " Found $FOUND_CT completions of \"$EPIX_INROOT\", using $EPIX_INFILE" + + elif [ "$EPIX_NOTFOUND" = "yes" ]; then + ePiX_warn " \"$EPIX_INFILE\" not found" + fi +} # end of epix_parse_filename + + +# Get extra LaTeX package names from file +function ePiX_usepackages() +{ + TMP_PKGS=$(grep "%% usepackages " $1) + LATEX_PKGS=${TMP_PKGS#"%% usepackages "} +} + +function ePiX_usage() +{ +cat <<HELP +Usage: $1 [options] <file(s)>[$2] + +HELP +} + + +function ePiX_version() +{ +cat <<VERSION +$1 (ePiX 1.2.1) + +Copyright (C) 2007 Andrew D. Hwang + +VERSION +} + +function ePiX_license() +{ +cat <<LICENSE +License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html> +ePiX is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +LICENSE +} + +function ePiX_bugreport() +{ + my_decode="tr '[a-m][n-z]' '[n-z][a-m]'" # Mac OS X has no 'rot' + SPAMMY="<$(echo nujnat|$my_decode)@$(echo zngupf|$my_decode)." + SPAMMY="${SPAMMY}$(echo ubylpebff|$my_decode).$(echo rqh|$my_decode)>" + +cat <<BUG +Please report bugs to $SPAMMY +BUG +}
\ No newline at end of file diff --git a/graphics/epix/epix.1.in b/graphics/epix/epix.1.in new file mode 100644 index 0000000000..45c5085666 --- /dev/null +++ b/graphics/epix/epix.1.in @@ -0,0 +1,50 @@ +.TH ePiX 1 "January 06, 2004" +.LO 1 +.fi +.SH NAME +ePiX \- Utilities for creating mathematically accurate figures +.SH SYNOPSIS +.in +7n +.ti -7n +epix [options] file(s)[.xp] +.P +elaps [options] file(s)[.eepic|.xp] +.P +laps [options] file(s)[.tex] +.P +flix [options] file[.flx] +.in -7n +.P +All scripts have built-in (terse and verbose) help. +.P +.SH ONLINE RESOURCES +Project page: + + http://mathcs.holycross.edu/~ahwang/current/ePiX.html + +Public CVS server: + + https://savannah.nongnu.org/projects/epix + +CTAN: + + http://www.ctan.org/tex-archive/graphics/epix + +Mailing lists: + + http://lists.nongnu.org/mail/?group=epix + +.SH DOCUMENTATION +Sample files and an extensive tutorial introduction/reference manual +come with the source code. Please look in +.B @docdir@ +for these materials. The documentation can be downloaded separately. +Please consult the project page. + +.SH "AUTHOR" +.nf +.na +Andrew D. Hwang (ahwang -at- mathcs -dot- holycross -dot- edu) +Department of Mathematics and Computer Science +College of the Holy Cross +Worcester, MA 01610-2395, USA diff --git a/graphics/epix/epix.el.in b/graphics/epix/epix.el.in new file mode 100644 index 0000000000..19d69c2155 --- /dev/null +++ b/graphics/epix/epix.el.in @@ -0,0 +1,1068 @@ +;;; epix.el --- A major mode for working with ePiX files. + +;; Copyright (C) 2002, 2007 Jay Belanger + +;; Author: Jay Belanger +;; Maintainer: Jay Belanger <belanger@truman.edu> + +;; Keywords: epix + +;; 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 +;; +;; +;; Please send suggestions and bug reports to <belanger@truman.edu>. + +;;; Commentary: + +;; Quick intro + +;; epix-mode is an extension of c++-mode with some extra commands for +;; editing ePiX files. The commands are +;; C-cC-x run epix on the current file (x for epiX, I guess) +;; C-cC-l run elaps on the current file (l for eLaps) +;; The output of the run can be seen by +;; C-cC-r show the output buffer (r for Results) +;; and in case of errors, they can be jumped to, in sequence, with +;; C-c` go to the next error +;; The file created by elaps can be viewed with +;; C-cC-v view the output file (v for View) +;; By default, the output will be encapsulated postscript. This +;; can be changed by changing the customizable variable +;; `epix-elaps-output-format'. This can be changed for the current +;; emacs session with `C-cC-r'. +;; An unwanted ePiX process can be killed with +;; C-cC-k +;; A reminder of some ePiX commands will be given with +;; C-cC-h get help on ePiX +;; If the file extension is .flx, then there will also be the commands +;; C-cC-f run flix on the current file +;; C-cC-w view the mng file. +;; +;; To install, put both epix.el and epix.info in the emacs load path. +;; Adding the lines +;; (autoload 'epix-mode "epix" "ePiX editing mode" t) +;; (autoload 'flix-mode "epix" "flix editing mode" t) +;; to your .emacs file will ensure that the command is always available. +;; Adding the lines +;; (setq auto-mode-alist (cons '("\\.xp" . epix-mode) auto-mode-alist)) +;; (setq auto-mode-alist (cons '("\\.flx" . flix-mode) auto-mode-alist)) +;; will ensure that any file ending in .xp or .flx will be recognized as +;; an ePiX file or flix file, and started in the proper mode. +;; +;; Some variables that the user may wish to change (via customization +;; or otherwise) are +;; epix-postscript-viewer (default "gv") +;; The command used to view postscript files. +;; epix-mng-viewer (default "display") +;; The command used to view mng files. +;; epix-mark-files-as-epix (default nil) +;; Setting this to t will ensure that any file in ePiX mode +;; will be marked with a /* -*-ePiX-* */ so that next +;; time it is opened, it will be put in epix-mode. (This isn't necessary +;; if auto-mode-alist is set up properly.) +;; epix-mark-files-as-flix (default nil) +;; Setting this to t will ensure that any file in flix mode +;; will be marked with a /* -*-flix-* */ so that next +;; time it is opened, it will be put in flix-mode. (This isn't necessary +;; if auto-mode-alist is set up properly.) +;; epix-insert-template-in-empty-buffer (default nil) +;; Setting this to t will cause any empty buffer which is put in +;; ePiX mode to have a skeleton of commands inserted into it. +;; The skeleton can be inserted at any time with the command +;; epix-insert-template +;; epix-template +;; This is the skeleton which will inserted. +;; By default, it is +;; #include \"epix.h\" +;; using namespace ePiX; +;; +;; int main() +;; { +;; picture(P(,), P(,), \"\"); +;; +;; begin(); +;; +;; end(); +;; } +;; +;; epix-flix-template +;; This is the skeleton which will inserted. +;; By default, it is +;; #include \"epix.h\" +;; using namespace ePiX; +;; +;; int main(int argc, char* argv[]) +;; { +;; if (argc == 3) +;; { +;; char* arg; +;; double temp1, temp2; +;; temp1=strtod(argv[1], &arg); +;; temp2=strtod(argv[2], &arg); +;; +;; tix()=temp1/temp2; +;; } +;; picture(P(,), P(,), \"\"); +;; +;; begin(); +;; +;; end(); +;; } + +;;; Require +(require 'cc-mode) + +;;; Customization + +(defgroup epix nil + "ePiX mode" + :prefix "epix-" + :tag "ePiX") + +(defcustom epix-elaps-output-format 'eps + "The output format for elaps." + :group 'epix + :type '(choice (const :tag "EPS" eps) + (const :tag "PS" ps) + (const :tag "PDF" pdf))) + +(defcustom epix-info-file "@docdir@/epix.info.bz2" + "The info file for ePiX." + :group 'epix + :type 'file) + +(defcustom epix-mark-files-as-epix nil + "Non-nil means to make sure that any ePiX file is marked as such." + :group 'epix + :type 'boolean) + +(defcustom epix-mark-files-as-flix nil + "Non-nil means to make sure that any flix file is marked as such." + :group 'epix + :type 'boolean) + +(defcustom epix-template +"#include \"epix.h\" +using namespace ePiX; + +int main() +{ +picture(P(,), P(,), \"\"); + +begin(); + +end(); +} +" + "The information to enter into an empty ePiX buffer." + :group 'epix + :type 'string) + +(defcustom epix-template-start "P(" + "The place to start the point in the template." + :group 'epix + :type 'string) + +(defcustom epix-flix-template +"#include \"epix.h\" +using namespace ePiX; + +int main(int argc, char* argv[]) +{ + if (argc == 3) + { + char* arg; + double temp1(strtod(argv[1], &arg)), temp2(strtod(argv[2], &arg)); + + tix()=temp1/temp2; + } +picture(P(,), P(,), \"\"); + +begin(); + +end(); +} +" + "The information to enter into an empty ePiX buffer." + :group 'epix + :type 'string) + +(defcustom epix-flix-template-start "P(" + "The place to start the point in the template." + :group 'epix + :type 'string) + +(defcustom epix-insert-template-in-empty-buffer nil + "Non-nil means to insert the template into an empty ePiX buffer." + :group 'epix + :type 'boolean) + +(defcustom epix-command-name "epix" + "The name of the ePiX program." + :group 'epix + :type 'string) + +(defcustom epix-command-args "" + "Arguments to pass to epix" + :group 'epix + :type 'string) + +(defcustom epix-elaps-command-name "elaps" + "The name of the elaps program." + :group 'epix + :type 'string) + +(defcustom epix-elaps-command-args "" + "Arguments to pass to elaps" + :group 'epix + :type 'string) + +(defcustom epix-flix-command-name "flix" + "The name of the flix program." + :group 'epix + :type 'string) + +(defcustom epix-flix-command-args "" + "Arguments to pass to flix" + :group 'epix + :type 'string) + +(defcustom epix-postscript-viewer "gv" + "The name of the program used to view postscript files." + :group 'epix + :type 'string) + +(defcustom epix-pdf-viewer "xpdf" + "The name of the program used to view pdf files." + :group 'epix + :type 'string) + +(defcustom epix-mng-viewer "display" + "The name of the program used to view mng files." + :group 'epix + :type 'string) + +;;; Some utility variables + +(defvar epix-output-buffer nil) +(make-variable-buffer-local 'epix-output-buffer) + +(defvar epix-error-point nil) +(make-variable-buffer-local 'epix-error-point) + +(defvar epix-elaps-output-format-list + '((ps " -ps" ".ps") + (pdf " -pdf" ".pdf") + (eps "" ".eps"))) + +(defun epix-change-elaps-output-format () + "Change the output format for elaps." + (interactive) + (let ((newformat + (read-string + "New output format (ps,eps,pdf): "))) + (cond + ((string= newformat "pdf") + (setq epix-elaps-output-format 'pdf)) + ((string= newformat "ps") + (setq epix-elaps-output-format 'ps)) + ((string= newformat "eps") + (setq epix-elaps-output-format 'eps)) + (t + (message "Not an acceptable format."))))) + +;;; Functions to run epix and friends + +(defun epix-check-process () + "See if there is a process associated with the output buffer. +If there is and it is running, offer to kill it." + (let ((epp) + (epix-proc (get-buffer-process epix-output-buffer))) + (if epix-proc (setq epp t) (setq epp nil)) + (if (and + epix-proc + (y-or-n-p "There is an ePiX process running. Kill it? ")) + (progn + (kill-process epix-proc) + (setq epp nil))) + epp)) + +(defun epix-kill-process () + "Kill any epix process running." + (interactive) + (let ((epix-proc (get-buffer-process epix-output-buffer))) + (if (and + epix-proc + (y-or-n-p "Really kill ePiX process? ")) + (kill-process epix-proc)))) + + +(defun epix-check-buffer () + "See if the buffer has been modified since it was last saved. +If it has been, offer to save it." + (if (and + (buffer-modified-p) + (y-or-n-p (concat "Save file " (buffer-file-name) "?"))) + (save-buffer))) + +(defun epix-run-command (command file &optional args) + "Create a process to run COMMAND on FILE. +Return the new process." + (let ((buffer epix-output-buffer)) + (epix-check-buffer) + (unless (epix-check-process) + (set-buffer (get-buffer-create buffer)) + (setq epix-error-point nil) + (erase-buffer) + (insert "Running `" command "' on `" file "\n") + (message "Type `C-c C-r' to display results of compilation.") + (let ((process) + (cmd)) + (if (not (string= args "")) + (setq cmd + (append + (list 'start-process "ePiX" buffer "/bin/sh" command) + (split-string args) + (list file))) + (setq cmd (list 'start-process "ePiX" buffer "/bin/sh" command file))) + (setq process (eval cmd)) + (set-process-filter process 'epix-command-filter) + (set-process-sentinel process 'epix-command-sentinel) + (set-marker (process-mark process) (point-max)) + process)))) + +(defun epix-command-sentinel (process event) + (when (string-match "finished" event) + (message "ePiX process finished") + (set-buffer epix-output-buffer) + (goto-char (point-max)) + (insert "\nePiX process finished\n"))) + +(defun epix-command-filter (process string) + "Filter to process normal output." + (save-excursion + (set-buffer (process-buffer process)) + (save-excursion + (goto-char (process-mark process)) + (insert-before-markers string) + (set-marker (process-mark process) (point)))) + (if (string-match "Compilation failed" string) + (message (concat "ePiX errors in `" (buffer-name) + "'. Use C-c ` to display.")))) +(defun epix-run-epix () + "Run epix on the current file." + (interactive) + (let ((file (file-name-nondirectory (buffer-file-name)))) + (epix-run-command epix-command-name file epix-command-args))) + +(defun epix-run-elaps () + "Run elaps on the current file." + (interactive) + (let ((file (file-name-nondirectory (buffer-file-name)))) + (epix-run-command epix-elaps-command-name file + (concat + epix-elaps-command-args + (nth 1 (assoc epix-elaps-output-format + epix-elaps-output-format-list)))))) + +(defun epix-run-flix () + "Run flix on the current file." + (interactive) + (let ((file (file-name-nondirectory (buffer-file-name)))) + (epix-run-command epix-flix-command-name file epix-flix-command-args))) + +(defun epix-view-elaps-output () + "View the eps output of the file." + (interactive) + (let ((filename (file-name-nondirectory (buffer-file-name))) + (file nil) + (extension (nth 2 (assoc epix-elaps-output-format + epix-elaps-output-format-list)))) + (if (file-name-extension filename) + (setq file (concat (file-name-sans-extension filename) extension))) + (unless (file-exists-p file) + (setq file (concat filename extension))) + (message file) + (if (file-exists-p file) + (call-process + (if (eq epix-elaps-output-format 'pdf) + epix-pdf-viewer + epix-postscript-viewer) + nil epix-output-buffer nil file) + (message (concat "No file " file ". Run elaps first."))))) + +(defun epix-view-mng () + "View the mng output of the file." + (interactive) + (let ((filename (file-name-nondirectory (buffer-file-name))) + (file nil)) + (if (file-name-extension filename) + (setq file (concat (file-name-sans-extension filename) ".mng"))) + (unless (file-exists-p file) + (setq file (concat filename ".mng"))) + (message file) + (if (file-exists-p file) + (call-process epix-mng-viewer nil epix-output-buffer nil file) + (message (concat "No file " file ". Run flix first."))))) + +;;; Dealing with output + +(defun epix-show-output-buffer () + "Show the epix output buffer." + (interactive) + (let ((buf (current-buffer))) + (if (get-buffer epix-output-buffer) + (progn + (pop-to-buffer epix-output-buffer t) + (bury-buffer buf) + (goto-char (point-max)) + (recenter (/ (window-height) 2)) + (pop-to-buffer buf)) + (message "No output buffer.")))) + +(defun epix-find-error (arg) + "Go to the next ePiX error." + (interactive "P") + (if arg + (save-excursion + (set-buffer epix-output-buffer) + (setq epix-error-point nil))) + (let ((ln) + (col) + (epix-error-end) + (buf (current-buffer))) + (switch-to-buffer-other-window epix-output-buffer) + (widen) + (if epix-error-point + (goto-char epix-error-point) + (goto-char (point-min))) + (if (re-search-forward ":\\([0-9]+\\):\\([0-9]+\\):" (point-max) t) + (progn + (setq epix-error-point (point)) + (setq ln (string-to-int (match-string 1))) + (setq col (string-to-int (match-string 2))) + (save-excursion + (if (re-search-forward ":[0-9]+:[0-9]+:" (point-max) t) + (setq epix-error-end (line-beginning-position)) + (if (search-forward "Compilation failed" (point-max) t) + (setq epix-error-end (line-beginning-position)) + (setq epix-error-end (point-max))))) + (recenter) + (beginning-of-line) + (if (looking-at "epix: Compiling...") + (forward-char (length "epix: Compiling..."))) + (narrow-to-region (point) epix-error-end) + (switch-to-buffer-other-window buf) + (goto-line ln) + (move-to-column col)) + (switch-to-buffer-other-window buf) + (message "No more errors.")))) + + +;;; Auxiliary functions + +(defun epix-mark-file-as-epix () + "Mark the file as an ePiX buffer. +The next time the file is loaded, it will then be in ePiX mode" + (interactive) + (save-excursion + (goto-char (point-min)) + (unless (looking-at ".*-\\*-ePiX-\\*-") + (insert "/* -*-ePiX-*- */\n")))) + +(defun epix-mark-file-as-flix () + "Mark the file as a flix buffer. +The next time the file is loaded, it will then be in flix mode" + (interactive) + (save-excursion + (goto-char (point-min)) + (unless (looking-at ".*-\\*-flix-\\*-") + (insert "/* -*-flix-*- */\n")))) + +(defun epix-insert-epix-template () + "Insert a template." + (interactive) + (if (looking-at ".*-\\*-ePiX-\\*-") + (forward-line 1)) + (let ((beg (point))) + (insert epix-template) + (indent-region beg (point) nil) + (goto-char beg) + (search-forward epix-template-start))) + +(defun epix-insert-flix-template () + "Insert a template." + (interactive) + (if (looking-at ".*-\\*-flix-\\*-") + (forward-line 1)) + (let ((beg (point))) + (insert epix-flix-template) + (indent-region beg (point) nil) + (goto-char beg) + (search-forward epix-flix-template-start))) + +(defun epix-help () + "Read an ePiX info file" + (interactive) + (info-other-window epix-info-file)) + +(require 'info-look) +(info-lookup-maybe-add-help + :mode 'epix-mode + :ignore-case nil + :regexp "[_a-zA-Z0-9./+-]+" + :doc-spec (list + (list + (concat "(" + epix-info-file + ")Function Index")))) +; nil +; "^ -+ [^:]+:[ ]+\\(\\[[^=]*=[ ]+\\)?" nil))) + + +;;; To take care of the different types + +(defvar epix-preface +"int[ \t\n]*main()[ \t\n]*{") + +(defvar epix-flix-preface +"int main(int argc, char* argv[]) +{ + if (argc == 3) + { + char* arg; + double temp1(strtod(argv[1], &arg)), temp2(strtod(argv[2], &arg)); + + tix()=temp1/temp2; + }") + +(defun epix-epix-to-flix () + "Change some of the buffer to accomodate flix." + (interactive) + (save-excursion + (goto-char (point-min)) + (replace-regexp "-\\*-ePiX-\\*-" "-*-flix-*-") + (goto-char (point-min)) + (replace-regexp epix-preface epix-flix-preface)) + (flix-mode)) + +;;; ePiX mode + +(defvar epix-mode-map nil + "The keymap for ePiX mode.") + +(if epix-mode-map + nil + (let ((map (copy-keymap c++-mode-map))) + (define-key map "\C-c\C-k" 'epix-kill-process) + (define-key map "\C-c\C-x" 'epix-run-epix) + (define-key map "\C-c\C-l" 'epix-run-elaps) + (define-key map "\C-c\C-r" 'epix-show-output-buffer) + (define-key map "\C-c\C-v" 'epix-view-elaps-output) + (define-key map "\C-c\C-r" 'epix-change-elaps-output-format) + (define-key map "\C-c\C-h" 'epix-help) + (define-key map "\C-c\C-i" 'info-complete-symbol) + (define-key map "\C-c`" 'epix-find-error) + (setq epix-mode-map map))) + +(easy-menu-define epix-mode-menu epix-mode-map + "ePiX mode menu" + '("ePiX" + ["Run ePiX" epix-run-epix t] + ["Run elaps" epix-run-elaps t] + ["View the eps file" epix-view-elaps-output t] + ["Change the output format" epix-change-elaps-output-format t] + ["Get help on ePiX" epix-help t] + ["Show the output buffer" epix-show-output-buffer t])) + +(define-derived-mode epix-mode c++-mode "ePiX" + "ePiX mode is a major mode for editing ePiX files. +It is C++ mode with a couple of extra commands: + +Run epix on the file being visited: C-cC-x +Run elaps on the file being visited: C-cC-l +View the output: C-cC-v +Change the output format: C-cC-r +Get help on ePiX: C-cC-h +Complete the ePiX symbol under point: C-cTAB + +In the case of errors: +Go to the (next) error: C-c` + +SUMMARY OF EPIX COMMANDS +------------------------ + +Preamble +-------- +picture(P(a,b), P(c,d), \"height[dim] x width dim\"); + +The actual picture commands need to be between +begin(); +and +end(); + +Colors +------ +RGB(r,g,b); +Red(d); Green(d); Blue(d); Black(d); White(d); + +CMY(c,m,y); +Cyan(d); Magenta(d); Yellow(d); CMY_Black(d); CMY_White(d); + +CMYK(c,m,y,k); +CyanK(d); MagentaK(d); YellowK(d); CMYK_Black(d); CMYK_White(d); + +Primary densities interpolate linearly between anti-saturation (-1), +no color(0), full saturation (1), and saturation on all channels (2 +or -2). Densities are meaningful mod 4. Colors can be superposed, +blended, inverted, filtered, and scaled. + +Line and fill styles +----------- +Widths: plain([Color]); bold([Color]); bbold([Color]); + pen(Color, [len]); pen(len); + base(Color, [len]); base(len); +Styles: solid(); dashed(); dotted(); + line_style(string); +Fill: fill(Color); fill(bool); nofill(); + +The base pen draws an underlayer/border if wider than the line pen. +line_style accepts a WYSIWYG pattern of spaces, dashes, and periods. + +Lines +----- +line(P(a,b),P(c,d)); +Line(P(a,b),P(c,d)); +Line(P(a,b),m); + +The line goes from one point to the other, +the Line is that part of the entire line which lies inside the +bounding box. + +Polygons +-------- +triangle(P(a,b),P(c,d),P(e,f)); +rect(P(a,b),P(c,d)); +quad(P(a,b),P(c,d),P(e,f),P(g,h)); + +Axes +---- +h_axis(P(a,b),P(c,d),n); +v_axis(P(a,b),P(c,d),n); +h_log_axis(P(a,b),P(c,d),n); +v_log_axis(P(a,b),P(c,d),n); + +h_axis_labels(P(a,b),P(c,d),n,P(u,v)); +v_axis_labels(P(a,b),P(c,d),n,P(u,v)); +h_log_axis_labels(P(a,b),P(c,d),n,P(u,v)); +v_log_axis_labels(P(a,b),P(c,d),n,P(u,v)); + +h_axis_masklabels(P(a,b),P(c,d),n,P(u,v)); +v_axis_masklabels(P(a,b),P(c,d),n,P(u,v)); +h_log_axis_masklabels(P(a,b),P(c,d),n,P(u,v)); +v_log_axis_masklabels(P(a,b),P(c,d),n,P(u,v)); + +The axis commands will put n+1 evenly spaced tick marks on the line. +The labeling commands will put n+1 evenly spaced labels, +masklabels will put the label on an opaque white rectangle. + +Points +------ +spot(P(a,b)); dot(P(a,b)); ddot(P(a,b)); box(P(a,b)); bbox(P(a,b)); +circ(P(a,b)); +ring(P(a,b)); + +spot, dot and ddot are various sized (in decreasing order) dots. +A circ is a small circle with white interior. +A ring is a small circle with transparent interior. + +Arrows +------ +arrow(P(a,b),P(c,d)); +dart(P(a,b),P(c,d)); + +A dart is a small arrow. + +Labels +------ +label(P(a,b),P(u,v),\"label\"); +label(P(a,b),\"label\"); +label(P(a,b),P(u,v),\"label\",posn); +masklabel(P(a,b),P(u,v),\"label\"); +masklabel(P(a,b),\"label\"); +masklabel(P(a,b),P(u,v),\"label\",posn); + +These commands put a label at the point P(a,b). +P(u,v) is an offset (in true points). +posn will specify the position of the label relative to the basepoint, +and can be c(enter), l(eft), r(ight), t(op), b(ottom) or an +appropriate pair. + +Text attributes +--------------- +label_color(Color); label_mask(Color); label_pad(len); +label_border(Color, [len]); label_border(len); no_label_border(); +font_size(LaTeX size); font_face(face); +label_angle(theta); + +The LaTeX size is a string such as \"Huge\" or \"scriptsize\". The +font face is one of \"rm\" (default), \"bf\", \"sc\", or \"tt\". + +Curves +------ +ellipse(P(a,b),P(c,d),P(e,f),tmin,tmax); +circle(P(a,b),r); +circle(P(a,b),P(c,d),P(e,f)); + +Ellipse draws (a,b)+Cos(t)*(c,d)+Sin(t)*(e,f) for tmin <= t <= tmax. + +Arcs +---- +arc(P(a,b),r,theta1,theta2); +arc_arrow(P(a,b),r,theta1,theta2); + +The angles are measured in current angle units (radians by default). + +Splines +------- +spline(P(a,b),P(c,d),P(e,f)); +spline(P(a,b),P(c,d),P(e,f),P(g,h)); + +Plotting +-------- +plot(f,a,b,n); + +This plots the function f from a to b using n+1 evenly spaced points. +If f is P-valued, then this will be a parametric plot. + +Calc plotting +------------- +plot(Deriv(f),a,b,n); +plot(Integral(f),a,b,n); +plot(Integral(f),x0,a,b,n); + +plot(Deriv(f)...) plots f'. +plot(Integral(f)...) plots int_a^x f (or if x0 is given, int_x0^x f). + +Tangents +-------- +tan_line(f,t); +envelope(f,t_min,t_max,n); +tan_field(f,t_min,t_max,n); + +tan_line will plot the tangent Line to the graph. +envelope will plot n+1 tangent Lines. +tan_field will plot n+1 tangent vectors. +Here, as above, f can be P-valued. + +Vector fields +------------- +slope_field(F,P(a,b),P(c,d),n1,n2); +dart_field(F,P(a,b),P(c,d),n1,n2); +vector_field(F,P(a,b),P(c,d),n1,n2); + +The slope_field elements will have fixed length, no arrows. +The dart_field elements will have fixed length, small arrows. +The vector_field elements will have true length. + +Fractals +-------- +const int seed[] = {N, k1, k2, k3, ... , kn}; +fractal(P(a,b),P(c,d),D,seed); + +seed determines a path made up of equal space line segments, each of +which can point in the direction 2 pi k/N. Each integer after N in seed +will specify the direction of the next segment. +fractal will recursively replace each segment in seed by a copy of the +original, up to a depth of D, and draw it from P(a,b) to P(c,d)." + (setq font-lock-defaults + '((c++-font-lock-keywords + c++-font-lock-keywords-1 + c++-font-lock-keywords-2 + c++-font-lock-keywords-3) + nil nil ((?_ . "w")) beginning-of-defun + (font-lock-mark-block-function . mark-defun))) + (setq epix-output-buffer (concat "*" (buffer-file-name) " output*")) + (use-local-map epix-mode-map) + (if (and epix-insert-template-in-empty-buffer + (= (point-min) (point-max))) + (progn + (if epix-mark-files-as-epix + (epix-mark-file-as-epix)) + (epix-insert-epix-template)) + (if epix-mark-files-as-epix + (epix-mark-file-as-epix))) + (run-hooks 'epix-mode-hook)) + +;;; flix mode + +(defvar flix-mode-map nil + "The keymap for flix mode.") + +(if flix-mode-map + nil + (let ((map (copy-keymap c++-mode-map))) + (define-key map "\C-c\C-k" 'epix-kill-process) + (define-key map "\C-c\C-x" 'epix-run-epix) + (define-key map "\C-c\C-l" 'epix-run-elaps) + (define-key map "\C-c\C-r" 'epix-show-output-buffer) + (define-key map "\C-c\C-v" 'epix-view-elaps-output) + (define-key map "\C-c\C-h" 'epix-help) + (define-key map "\C-c`" 'epix-find-error) + (define-key map "\C-c\C-f" 'epix-run-flix) + (define-key map "\C-c\C-w" 'epix-view-mng) + (setq flix-mode-map map))) + +(easy-menu-define flix-mode-menu flix-mode-map + "flix mode menu" + '("flix" + ["Run flix" epix-run-flix t] + ["View the mng file" epix-view-mng t] + ["Get help on flix/ePiX" epix-help t] + ["Show the output buffer" epix-show-output-buffer t] + ("ePiX" + ["Run ePiX" epix-run-epix t] + ["Run elaps" epix-run-elaps t] + ["View the eps file" epix-view-elaps-output t]))) + +(define-derived-mode flix-mode c++-mode "flix" + "flix mode is a major mode for editing flix files. +It is C++ mode with a couple of extra commands: + +Run flix on the file being visited: C-cC-f +View the mng output: C-cC-w +Get help on flix: C-cC-h + +Since a flix file is a valid ePiX file, the +following commands are also available: +Run epix on the file being visited: C-cC-x +Run elaps on the file being visited: C-cC-l +View the postscript output: C-cC-v +In the case of errors: +Go to the (next) error: C-c` + +An ePiX file isn't necessarily a flix file, +but the command +M-x epix-epix-to-flix +will try to turn an ePiX file into a flix file. + +SUMMARY OF FLIX/EPIX COMMANDS +------------------------ + +Preamble +-------- +picture(P(a,b), P(c,d), \"height[dim] x width dim\"); + +The actual picture commands need to be between +begin(); +and +end(); + +Colors +------ +RGB(r,g,b); +Red(d); Green(d); Blue(d); Black(d); White(d); + +CMY(c,m,y); +Cyan(d); Magenta(d); Yellow(d); CMY_Black(d); CMY_White(d); + +CMYK(c,m,y,k); +CyanK(d); MagentaK(d); YellowK(d); CMYK_Black(d); CMYK_White(d); + +Primary densities interpolate linearly between anti-saturation (-1), +no color(0), full saturation (1), and saturation on all channels (2 +or -2). Densities are meaningful mod 4. Colors can be superposed, +blended, inverted, filtered, and scaled. + +Line and fill styles +----------- +Widths: plain([Color]); bold([Color]); bbold([Color]); + pen(Color, [len]); pen(len); + base(Color, [len]); base(len); +Styles: solid(); dashed(); dotted(); + line_style(string); +Fill: fill(Color); fill(bool); nofill(); + +The base pen draws an underlayer/border if wider than the line pen. +line_style accepts a WYSIWYG pattern of spaces, dashes, and periods. + +Lines +----- +line(P(a,b),P(c,d)); +Line(P(a,b),P(c,d)); +Line(P(a,b),m); + +The line goes from one point to the other, +the Line is that part of the entire line which lies inside the +bounding box. + +Polygons +-------- +triangle(P(a,b),P(c,d),P(e,f)); +rect(P(a,b),P(c,d)); +quad(P(a,b),P(c,d),P(e,f),P(g,h)); + +Axes +---- +h_axis(P(a,b),P(c,d),n); +v_axis(P(a,b),P(c,d),n); +h_log_axis(P(a,b),P(c,d),n); +v_log_axis(P(a,b),P(c,d),n); + +h_axis_labels(P(a,b),P(c,d),n,P(u,v)); +v_axis_labels(P(a,b),P(c,d),n,P(u,v)); +h_log_axis_labels(P(a,b),P(c,d),n,P(u,v)); +v_log_axis_labels(P(a,b),P(c,d),n,P(u,v)); + +h_axis_masklabels(P(a,b),P(c,d),n,P(u,v)); +v_axis_masklabels(P(a,b),P(c,d),n,P(u,v)); +h_log_axis_masklabels(P(a,b),P(c,d),n,P(u,v)); +v_log_axis_masklabels(P(a,b),P(c,d),n,P(u,v)); + +The axis commands will put n+1 evenly spaced tick marks on the line. +The labeling commands will put n+1 evenly spaced labels, +masklabels will put the label on an opaque white rectangle. + +Points +------ +spot(P(a,b)); dot(P(a,b)); ddot(P(a,b)); box(P(a,b)); bbox(P(a,b)); +circ(P(a,b)); +ring(P(a,b)); + +spot, dot and ddot are various sized (in decreasing order) dots. +A circ is a small circle with white interior. +A ring is a small circle with transparent interior. + +Arrows +------ +arrow(P(a,b),P(c,d)); +dart(P(a,b),P(c,d)); + +A dart is a small arrow. + +Labels +------ +label(P(a,b),P(u,v),\"label\"); +label(P(a,b),\"label\"); +label(P(a,b),P(u,v),\"label\",posn); +masklabel(P(a,b),P(u,v),\"label\"); +masklabel(P(a,b),\"label\"); +masklabel(P(a,b),P(u,v),\"label\",posn); + +These commands put a label at the point P(a,b). +P(u,v) is an offset (in true points). +posn will specify the position of the label relative to the basepoint, +and can be c(enter), l(eft), r(ight), t(op), b(ottom) or an +appropriate pair. + +Text attributes +--------------- +label_color(Color); label_mask(Color); label_pad(len); +label_border(Color, [len]); label_border(len); no_label_border(); +font_size(LaTeX size); font_face(face); +label_angle(theta); + +The LaTeX size is a string such as \"Huge\" or \"scriptsize\". The +font face is one of \"rm\" (default), \"bf\", \"sc\", or \"tt\". + +Curves +------ +ellipse(P(a,b),P(c,d),P(e,f),tmin,tmax); +circle(P(a,b),r); +circle(P(a,b),P(c,d),P(e,f)); + +Ellipse draws (a,b)+Cos(t)*(c,d)+Sin(t)*(e,f) for tmin <= t <= tmax. + +Arcs +---- +arc(P(a,b),r,theta1,theta2); +arc_arrow(P(a,b),r,theta1,theta2); + +The angles are measured in current angle units (radians by default). + +Splines +------- +spline(P(a,b),P(c,d),P(e,f)); +spline(P(a,b),P(c,d),P(e,f),P(g,h)); + +Plotting +-------- +plot(f,a,b,n); + +This plots the function f from a to b using n+1 evenly spaced points. +If f is P-valued, then this will be a parametric plot. + +Calc plotting +------------- +plot(Deriv(f),a,b,n); +plot(Integral(f),a,b,n); +plot(Integral(f),x0,a,b,n); + +plot(Deriv(f)...) plots f'. +plot(Integral(f)...) plots int_a^x f (or if x0 is given, int_x0^x f). + +Tangents +-------- +tan_line(f,t); +envelope(f,t_min,t_max,n); +tan_field(f,t_min,t_max,n); + +tan_line will plot the tangent Line to the graph. +envelope will plot n+1 tangent Lines. +tan_field will plot n+1 tangent vectors. +Here, as above, f can be P-valued. + +Vector fields +------------- +slope_field(F,P(a,b),P(c,d),n1,n2); +dart_field(F,P(a,b),P(c,d),n1,n2); +vector_field(F,P(a,b),P(c,d),n1,n2); + +The slope_field elements will have fixed length, no arrows. +The dart_field elements will have fixed length, small arrows. +The vector_field elements will have true length. + +Fractals +-------- +const int seed[] = {N, k1, k2, k3, ... , kn}; +fractal(P(a,b),P(c,d),D,seed); + +seed determines a path made up of equal space line segments, each of +which can point in the direction 2 pi k/N. Each integer after N in seed +will specify the direction of the next segment. +fractal will recursively replace each segment in seed by a copy of the +original, up to a depth of D, and draw it from P(a,b) to P(c,d)." + (setq font-lock-defaults + '((c++-font-lock-keywords + c++-font-lock-keywords-1 + c++-font-lock-keywords-2 + c++-font-lock-keywords-3) + nil nil ((?_ . "w")) beginning-of-defun + (font-lock-mark-block-function . mark-defun))) + (setq epix-output-buffer (concat "*" (buffer-file-name) " output*")) + (use-local-map flix-mode-map) + (if (and epix-insert-template-in-empty-buffer + (= (point-min) (point-max))) + (progn + (if epix-mark-files-as-epix + (epix-mark-file-as-flix)) + (epix-insert-flix-template)) + (if epix-mark-files-as-epix + (epix-mark-file-as-flix))) + (run-hooks 'epix-mode-hook) + (run-hooks 'flix-mode-hook)) + +(provide 'epix) diff --git a/graphics/epix/epix.in b/graphics/epix/epix.in new file mode 100644 index 0000000000..d5c302cbbb --- /dev/null +++ b/graphics/epix/epix.in @@ -0,0 +1,340 @@ +#! /bin/bash +# +# epix: wrapper script for ePiX +# +# Options: --help for usage, --version for version and license +# +# Compiler flags may be specified on the command line or in the config +# file ~/.epixrc. The script attempts to deal intelligently with missing +# or multiple extensions. If the input file has a recognized extension, +# there's no issue. If only the root name <infile> is given, the script +# searches for completions in the order of preference dictated by the +# variable EPIX_EXTENSIONS. A warning is issued for multiple matches. +# +# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 +# Andrew D. Hwang <For address, do "epix -V"> +# + +. "@pkglibdir@/epix-lib.sh" + +EPIX_CONFIG_FILE="$HOME/.epixrc" +# Search these extensions in order of preference +EPIX_EXTENSIONS="xp flx cc c C cpp" # or NULL +EPIX_DOT_EXT=".${EPIX_EXTENSIONS// /|.}" # for usage message + +# Default inc/lib directories and compiler +DEFAULT_INC="-I@includedir@" +DEFAULT_LIB="-L@pkglibdir@" +COMPILER="@RUNTIME_COMPILER@" + +# Use default library unless we're called by version number +LIBS="-lm" +POSTLIBS="-lepix" +EPIX_SRC_EXT=cc + +declare EPIX_MYINCLUDES +declare EPIX_MYLIBDIRS +declare EPIX_MYLIBS +declare EPIX_MYWARNS +declare EPIX_MYFLAGS + +declare -a EPIX_FILE_LIST + +declare -a TEMPFILES +trap '[ -n "${TEMPFILES[*]}" ] && rm -f "${TEMPFILES[@]}"' 0 1 2 3 7 10 13 15 + +function epix_help() +{ +cat <<"HELP" +Options: + -h, --help + Show this message and exit + + -V, --version + Show version and exit + + -v, --verbose + Show success/failure messages + + --gpl + Show license + + -o, --output + Specify output file name (ONLY for use with a single input file) + + --pst + Write output file using PSTricks macros + + --tikz + Write output file using tikz macros + + --eepic + Write output file using eepic macros + + -I<include> + Append include directory + + -L<library> + Append library directory + + -l<lib> + Link against lib + + --no-defaults + Do not use default include/library directories or libraries + + -cc, --compiler) + Specify the compiler (e.g., gcc) + + All other options are passed to the compiler. Valid options, + one per line, may be placed in $HOME/.epixrc. + +HELP +ePiX_bugreport + +} # End of epix_help + + +# Parse command line/config file for compiler flags/options +function epix_parse_options { +while [ "$1" != "${1#-}" ]; do + case "$1" in + + -I) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + EPIX_MYINCLUDES="$EPIX_MYINCLUDES -I$2"; shift 2; continue + ;; + + -L) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + EPIX_MYLIBDIRS="$EPIX_MYLIBDIRS -L$2"; shift 2; continue + ;; + + -l) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + EPIX_MYLIBS="$EPIX_MYLIBS -l$2"; shift 2; continue + ;; + + -W) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + EPIX_MYWARNS="$EPIX_MYWARNS -W$2"; shift 2; continue + ;; + + -I*) + EPIX_MYINCLUDES="$EPIX_MYINCLUDES $1"; shift; continue + ;; + + -L*) + EPIX_MYLIBDIRS="$EPIX_MYLIBDIRS $1"; shift; continue + ;; + + -l*) + EPIX_MYLIBS="$EPIX_MYLIBS $1"; shift; continue + ;; + + -W*) + EPIX_MYWARNS="$EPIX_MYWARNS $1"; shift; continue + ;; + + -i*|-u|-x) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + EPIX_MYFLAGS="$EPIX_MYFLAGS $1 $2"; shift 2; continue + ;; + + -b) + ePiX_warn "Skipping option \"$1 $2\"" + shift 2; continue + ;; + + -o|--output) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + EPIX_OUTFILE="$2" + EPIX_OUTROOT="${EPIX_OUTFILE%%.eepic}" + shift 2; continue + ;; + + --pst) + EPIX_MYFLAGS="$EPIX_MYFLAGS -DEPIX_FMT_PSTRICKS" + shift; continue + ;; + + --tikz) + EPIX_MYFLAGS="$EPIX_MYFLAGS -DEPIX_FMT_TIKZ" + shift; continue + ;; + + --eepic) + EPIX_MYFLAGS="$EPIX_MYFLAGS -DEPIX_FMT_EEPIC" + shift; continue + ;; + + # Deliberately undocumented + -q|--quiet) + EPIX_STDOUT="$SYSTEM_DEVNULL" + EPIX_STDERR="$SYSTEM_DEVNULL" + shift; continue + ;; + + -v|--verbose) + if [ -z "$2" ]; then + echo "Please use -V for version" + exit 0 + fi + EPIX_STDOUT="$SYSTEM_STDOUT" + EPIX_STDERR="$SYSTEM_STDERR" + shift; continue + ;; + + -vv) + echo "Discontinued option -vv; please use -v for verbose output" + exit 0 + ;; + + + -h|--help) + ePiX_usage epix $EPIX_DOT_EXT + epix_help + exit 0 + ;; + + -V|--version|--gpl) + ePiX_version epix + ePiX_license + exit 0 + ;; + + --no-defaults) + POSTLIBS= + DEFAULT_INC= + DEFAULT_LIB= + shift; continue + ;; + + -cc|--compiler) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + COMPILER=$2 + COMP_NAME=$(basename "$COMPILER") + if [ "${COMP_NAME: -2}" = cc ]; then EPIX_SRC_EXT=c; fi + shift 2; continue + ;; + + *) + EPIX_MYFLAGS="$EPIX_MYFLAGS $1"; shift; continue + ;; + esac + +done + +# Assume remaining parameters are input files +EPIX_FILE_LIST=("$@") +} # End of epix_parse_options + + +# Compile specified files to eepic +function epix_compile_files { + + if [ -z "$1" ]; then + ePiX_die "No input file specified" + fi + + mkdir "$EPIX_TEMPDIR" || ePiX_die "Can't create \"${EPIX_TEMPDIR}\"" + + # file counts + local processed=0 + local success=0 + local failure=0 + + for EPIX_INFILE in "${EPIX_FILE_LIST[@]}"; do + + # sets EPIX_INROOT, EPIX_SUFFIX, EPIX_NOTFOUND, touches EPIX_LOGFILE + epix_parse_filename "$EPIX_INFILE" "$EPIX_EXTENSIONS" + let processed=processed+1 + + if [ "$EPIX_NOTFOUND" = "yes" ]; then ePiX_fail && continue; fi + + : ${EPIX_OUTROOT:=$EPIX_INROOT} + EPIX_OUTFILE="$EPIX_OUTROOT".eepic + + { TEMP_BIN="$EPIX_INROOT" && + touch "${EPIX_TEMPDIR}/$TEMP_BIN" && + TEMPFILES=("{TEMPFILES[@]}" "${EPIX_TEMPDIR}/$TEMP_BIN") ; } || + { ePiX_fail "Couldn't create \"$EPIX_TEMPDIR/$TEMP_BIN\"" && continue;} + + # Create symlink to input file with appropriate extension for compiler + TEMP_INPUT="${TEMP_BIN}-tmp.$EPIX_SRC_EXT" + + TEMPFILES=("{TEMPFILES[@]}" "${EPIX_TEMPDIR}/$TEMP_INPUT") + + { cd ${EPIX_TEMPDIR} && \ + ln -s "../$EPIX_INFILE" "$TEMP_INPUT" && cd .. ; } || + { ePiX_fail "Couldn't create \"${EPIX_TEMPDIR}/$TEMP_INPUT\"" && \ + continue; } + + # Log message, and compile executable + TMP_CMD=($COMPILER "${EPIX_TEMPDIR}/${TEMP_INPUT}" $EPIX_MYWARNS \ + -o "${EPIX_TEMPDIR}/${TEMP_BIN}" \ + $EPIX_MYFLAGS $EPIX_MYINCLUDES $DEFAULT_INC $EPIX_MYLIBDIRS \ + $DEFAULT_LIB $LIBS $EPIX_MYLIBS $POSTLIBS) + + ePiX_command "${TMP_CMD[@]}" + + # Write eepic file + if [ -x "$EPIX_TEMPDIR/$TEMP_BIN" ]; then + echo "%% Generated from $EPIX_INFILE on $(date) by" \ + > "$EPIX_OUTFILE" + ePiX_msg "Writing eepic file: ./$EPIX_TEMPDIR/$TEMP_BIN > $EPIX_OUTFILE" + ./$EPIX_TEMPDIR/"$TEMP_BIN" >> "$EPIX_OUTFILE" + + if [ $? -ne 0 ]; then + ePiX_warn "Could not create $EPIX_OUTFILE" + let failure=failure+1 + else + let success=success+1 + fi + + else + ePiX_warn "Compilation of $EPIX_INFILE failed" + let failure=failure+1 + fi + + # Clean up; for multiple input files, clear output name + rm -f "$EPIX_TEMPDIR/$TEMP_BIN" "$EPIX_TEMPDIR/$TEMP_INPUT" + if [ "$EPIX_OUTROOT" = "$EPIX_INROOT" ]; then unset EPIX_OUTROOT; fi + + echo -e "\nTranscript written on $EPIX_LOGFILE" > "$EPIX_STDOUT" + + done # for EPIX_INFILE in $INFILE_LIST + + if [ $processed -gt 1 ]; then + echo "$processed files processed: $success successfully, $failure failed" > "$EPIX_STDERR" + fi + + if [ -d "$EPIX_TEMPDIR" ]; then rm -Rf "$EPIX_TEMPDIR"; fi +} # end of epix_compile_files + +## Script proper starts here ## + +if [ $# -eq 0 ]; then + ePiX_usage epix $EPIX_DOT_EXT + epix_help + exit 0 +fi + +# Read options from the config file, if any +if [ -f "$EPIX_CONFIG_FILE" ]; then + cat "$EPIX_CONFIG_FILE" | grep -v "#" | \ + while read line; do + epix_parse_options "$line" + done +fi + +# Command line options override config file options +epix_parse_options "$@" + +# Suppress all warnings if none are requested +if [ "$EPIX_MYWARNS" = "" ]; then EPIX_MYWARNS="-w"; fi + +# Remaining option(s) assumed to be input file(s) +epix_compile_files "${EPIX_FILE_LIST[@]}" + +exit 0 diff --git a/graphics/epix/errors.h b/graphics/epix/errors.h new file mode 100644 index 0000000000..7867e22686 --- /dev/null +++ b/graphics/epix/errors.h @@ -0,0 +1,55 @@ +/* + * errors.h -- ePiX warning/error functions + * + * This file is part of ePiX, a preprocessor for creating high-quality + * line figures in LaTeX + * + * Version 1.1.9 + * Last Change: July 30, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_ERRORS +#define EPIX_ERRORS + +#include <iostream> +#include <string> + +namespace ePiX { + + inline void epix_warning(std::string msg) + { + std::cerr << "ePiX WARNING: " << msg << std::endl; + } + + inline void epix_error(std::string msg) + { + std::cerr << "ePiX ERROR: " << msg << std::endl; + exit(1); + } +} // end of namespace + +#endif /* EPIX_ERRORS */ diff --git a/graphics/epix/facet.cc b/graphics/epix/facet.cc new file mode 100644 index 0000000000..3b808d1b59 --- /dev/null +++ b/graphics/epix/facet.cc @@ -0,0 +1,505 @@ +/* + * facet.cc -- Utility classes for shaded surface plotting + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> + +#include "constants.h" +#include "errors.h" +#include "functions.h" + +#include "frame.h" +#include "camera.h" + +#include "Color.h" +#include "paint_style.h" + +#include "facet.h" + +namespace ePiX { + + facet::facet(P f(double, double), + double u0, double v0, + double du, double dv, + const unsigned int N1, const unsigned int N2) + : m_tint(the_paint_style().fill_color()), + m_line(the_paint_style().line_pen()), + m_fill(the_paint_style().fill_flag()), + pt1(f(u0, v0)), + pt2(f(u0 + N1*du, v0)), + pt3(f(u0 + N1*du, v0 + N2*dv)), + pt4(f(u0, v0 + N2*dv)), + center(0.25*(pt1 + pt2 + pt3 + pt4)), + direction(center-cam().viewpt()), + distance(norm(direction)) + { + perp = ((pt2 - center)*(pt1 - center)); + + if (norm(perp) < EPIX_EPSILON) + perp = (pt4 - center)*(pt3 - center); + + perp *= recip(norm(perp)); + + // bottom edge + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + i*du, v0)); + + // right edge + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0 + N1*du, v0 + j*dv)); + + // top edge (backward) + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + (N1-i)*du, v0 + N2*dv)); + + // left edge (downward) + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0, v0 + (N2-j)*dv)); + + bd.close().fill(!m_tint.is_unset()); + } + + + // facet constructor for f(double, double, double) + facet::facet(P f(double, double, double), + double u0, double v0, double w0, + double du, double dv, double dw, + const unsigned int N1, const unsigned int N2) + : m_tint(the_paint_style().fill_color()), + m_line(the_paint_style().line_pen()), + m_fill(the_paint_style().fill_flag()), + pt1(f(u0, v0, w0)) + { + if (du == 0) // (y,z) + { + // bottom edge + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0, v0 + i*dv, w0)); + + // right edge + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0, v0 + N1*dv, w0 + j*dw)); + + // top edge (backward) + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0, v0 + (N1-i)*dv, w0 + N2*dw)); + + // left edge (downward) + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0, v0, w0 + (N2-j)*dw)); + + // use corners to approximate distance to camera + pt2 = f(u0, v0 + N1*dv, w0); + pt3 = f(u0, v0 + N1*dv, w0 + N2*dw); + pt4 = f(u0, v0, w0 + N2*dw); + } + + else if (dv == 0) // (x,z) + { + // bottom edge + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + i*du, v0, w0)); + + // right edge + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0 + N1*du, v0, w0 + j*dw)); + + // top edge (backward) + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + (N1-i)*du, v0, w0 + N2*dw)); + + // left edge (downward) + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0, v0, w0 + (N2-j)*dw)); + + // use corners to approximate distance to camera + pt2 = f(u0 + N1*du, v0, w0); + pt3 = f(u0 + N1*du, v0, w0 + N2*dw); + pt4 = f(u0, v0, w0 + N2*dw); + } + + else if (dw == 0) // (x,y) + { + // bottom edge + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + i*du, v0, w0)); + + // right edge + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0 + N1*du, v0 + j*dv, w0)); + + // top edge (backward) + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + (N1-i)*du, v0 + N2*dv, w0)); + + // left edge (downward) + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0, v0 + (N2-j)*dv, w0)); + + // use corners to approximate distance to camera + pt2 = f(u0 + N1*du, v0, w0); + pt3 = f(u0 + N1*du, v0 + N2*dv, w0); + pt4 = f(u0, v0 + N2*dv, w0); + } + + else + epix_error("Bad call to facet constructor"); // exits + + bd.close().fill(!m_tint.is_unset()); + + center = 0.25*(pt1 + pt2 + pt3 + pt4); + + direction = center-cam().viewpt(); + distance = norm(direction); + + perp = ((pt2 - center)*(pt1 - center)); + + if (norm(perp) < EPIX_EPSILON) + perp = (pt4 - center)*(pt3 - center); + + perp *= recip(norm(perp)); + + } // end of facet(f(double, double, double), ...) + + + // for surface of rotation + facet::facet(double f(double), double g(double), + double u0, double v0, + double du, double dv, + const unsigned int N1, const unsigned int N2, + const frame& coords) + : m_tint(the_paint_style().fill_color()), + m_line(the_paint_style().line_pen()), + m_fill(the_paint_style().fill_flag()), + pt1(f(u0)*coords.sea() + + g(u0)*Cos(v0)*coords.sky() + + g(u0)*Sin(v0)*coords.eye()), + pt2(f(u0 + N1*du)*coords.sea() + + g(u0 + N1*du)*Cos(v0)*coords.sky() + + g(u0 + N1*du)*Sin(v0)*coords.eye()), + pt3(f(u0 + N1*du)*coords.sea() + + g(u0 + N1*du)*Cos(v0 + N2*dv)*coords.sky() + + g(u0 + N1*du)*Sin(v0 + N2*dv)*coords.eye()), + pt4(f(u0)*coords.sea() + + g(u0)*Cos(v0 + N2*dv)*coords.sky() + + g(u0)*Sin(v0 + N2*dv)*coords.eye()), + center(0.25*(pt1 + pt2 + pt3 + pt4)), + direction(center-cam().viewpt()), distance(norm(direction)) + { + perp = ((pt2 - center)*(pt1 - center)); + + if (norm(perp) < EPIX_EPSILON) + perp = (pt4 - center)*(pt3 - center); + + perp *= recip(norm(perp)); + + // bottom edge + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + i*du)*coords.sea() + + g(u0 + i*du)*Cos(v0)*coords.sky() + + g(u0 + i*du)*Sin(v0)*coords.eye()); + + // right edge + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0 + N1*du)*coords.sea() + + g(u0 + N1*du)*Cos(v0 + j*dv)*coords.sky() + + g(u0 + N1*du)*Sin(v0 + j*dv)*coords.eye()); + + // top edge (backward) + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + (N1-i)*du)*coords.sea() + + g(u0 + (N1-i)*du)*Cos(v0 + N2*dv)*coords.sky() + + g(u0 + (N1-i)*du)*Sin(v0 + N2*dv)*coords.eye()); + + // left edge (downward) + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0)*coords.sea() + + g(u0)*Cos(v0 + (N2-j)*dv)*coords.sky() + + g(u0)*Sin(v0 + (N2-j)*dv)*coords.eye()); + + bd.close().fill(!m_tint.is_unset()); + } + + //// Color-dependent constructors + facet::facet(P f(double, double), + double u0, double v0, + double du, double dv, + const unsigned int N1, const unsigned int N2, + const Color& tint) + : m_tint(tint), m_line(the_paint_style().line_pen()), + m_fill(the_paint_style().fill_flag()), + pt1(f(u0, v0)), + pt2(f(u0 + N1*du, v0)), + pt3(f(u0 + N1*du, v0 + N2*dv)), + pt4(f(u0, v0 + N2*dv)), + center(0.25*(pt1 + pt2 + pt3 + pt4)), + direction(center-cam().viewpt()), + distance(norm(direction)) + { + perp = ((pt2 - center)*(pt1 - center)); + + if (norm(perp) < EPIX_EPSILON) + perp = (pt4 - center)*(pt3 - center); + + perp *= recip(norm(perp)); + + // bottom edge + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + i*du, v0)); + + // right edge + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0 + N1*du, v0 + j*dv)); + + // top edge (backward) + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + (N1-i)*du, v0 + N2*dv)); + + // left edge (downward) + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0, v0 + (N2-j)*dv)); + + bd.close().fill(!m_tint.is_unset()); + } + + + // facet constructor for f(double, double, double) + facet::facet(P f(double, double, double), + double u0, double v0, double w0, + double du, double dv, double dw, + const unsigned int N1, const unsigned int N2, + const Color& tint) + : m_tint(tint), m_line(the_paint_style().line_pen()), + m_fill(the_paint_style().fill_flag()), + pt1(f(u0, v0, w0)) + { + if (du == 0) // (y,z) + { + // bottom edge + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0, v0 + i*dv, w0)); + + // right edge + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0, v0 + N1*dv, w0 + j*dw)); + + // top edge (backward) + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0, v0 + (N1-i)*dv, w0 + N2*dw)); + + // left edge (downward) + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0, v0, w0 + (N2-j)*dw)); + + // use corners to approximate distance to camera + pt2 = f(u0, v0 + N1*dv, w0); + pt3 = f(u0, v0 + N1*dv, w0 + N2*dw); + pt4 = f(u0, v0, w0 + N2*dw); + } + + else if (dv == 0) // (x,z) + { + // bottom edge + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + i*du, v0, w0)); + + // right edge + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0 + N1*du, v0, w0 + j*dw)); + + // top edge (backward) + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + (N1-i)*du, v0, w0 + N2*dw)); + + // left edge (downward) + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0, v0, w0 + (N2-j)*dw)); + + // use corners to approximate distance to camera + pt2 = f(u0 + N1*du, v0, w0); + pt3 = f(u0 + N1*du, v0, w0 + N2*dw); + pt4 = f(u0, v0, w0 + N2*dw); + } + + else if (dw == 0) // (x,y) + { + // bottom edge + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + i*du, v0, w0)); + + // right edge + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0 + N1*du, v0 + j*dv, w0)); + + // top edge (backward) + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + (N1-i)*du, v0 + N2*dv, w0)); + + // left edge (downward) + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0, v0 + (N2-j)*dv, w0)); + + // use corners to approximate distance to camera + pt2 = f(u0 + N1*du, v0, w0); + pt3 = f(u0 + N1*du, v0 + N2*dv, w0); + pt4 = f(u0, v0 + N2*dv, w0); + } + + else + epix_error("Bad call to facet constructor"); // exits + + bd.close().fill(!m_tint.is_unset()); + + center = 0.25*(pt1 + pt2 + pt3 + pt4); + + direction = center-cam().viewpt(); + distance = norm(direction); + + perp = ((pt2 - center)*(pt1 - center)); + + if (norm(perp) < EPIX_EPSILON) + perp = (pt4 - center)*(pt3 - center); + + perp *= recip(norm(perp)); + + } // end of facet(f(double, double, double), ...) + + + // for surface of rotation + facet::facet(double f(double), double g(double), + double u0, double v0, + double du, double dv, + const unsigned int N1, const unsigned int N2, + const Color& tint, const frame& coords) + : m_tint(tint), m_line(the_paint_style().line_pen()), + m_fill(the_paint_style().fill_flag()), + pt1(f(u0)*coords.sea() + + g(u0)*Cos(v0)*coords.sky() + + g(u0)*Sin(v0)*coords.eye()), + pt2(f(u0 + N1*du)*coords.sea() + + g(u0 + N1*du)*Cos(v0)*coords.sky() + + g(u0 + N1*du)*Sin(v0)*coords.eye()), + pt3(f(u0 + N1*du)*coords.sea() + + g(u0 + N1*du)*Cos(v0 + N2*dv)*coords.sky() + + g(u0 + N1*du)*Sin(v0 + N2*dv)*coords.eye()), + pt4(f(u0)*coords.sea() + + g(u0)*Cos(v0 + N2*dv)*coords.sky() + + g(u0)*Sin(v0 + N2*dv)*coords.eye()), + center(0.25*(pt1 + pt2 + pt3 + pt4)), + direction(center-cam().viewpt()), distance(norm(direction)) + { + perp = ((pt2 - center)*(pt1 - center)); + + if (norm(perp) < EPIX_EPSILON) + perp = (pt4 - center)*(pt3 - center); + + perp *= recip(norm(perp)); + + // bottom edge + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + i*du)*coords.sea() + + g(u0 + i*du)*Cos(v0)*coords.sky() + + g(u0 + i*du)*Sin(v0)*coords.eye()); + + // right edge + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0 + N1*du)*coords.sea() + + g(u0 + N1*du)*Cos(v0 + j*dv)*coords.sky() + + g(u0 + N1*du)*Sin(v0 + j*dv)*coords.eye()); + + // top edge (backward) + for (unsigned int i=0; i<N1; ++i) + bd.pt(f(u0 + (N1-i)*du)*coords.sea() + + g(u0 + (N1-i)*du)*Cos(v0 + N2*dv)*coords.sky() + + g(u0 + (N1-i)*du)*Sin(v0 + N2*dv)*coords.eye()); + + // left edge (downward) + for (unsigned int j=0; j<N2; ++j) + bd.pt(f(u0)*coords.sea() + + g(u0)*Cos(v0 + (N2-j)*dv)*coords.sky() + + g(u0)*Sin(v0 + (N2-j)*dv)*coords.eye()); + + bd.close().fill(!m_tint.is_unset()); + } + + + facet* facet::clone() const + { + return new facet(*this); + } + + double facet::how_far() const { return distance; } + + bool facet::front_facing() const + { + return (-direction|perp) > -EPIX_EPSILON; + } + + // N.B. We assume the fill state is stored by our caller + void facet::draw(int cull) const + { + if (( cull == 1 && front_facing() ) || ( cull == -1 && !front_facing() )) + return; + + // else + Color paint(m_tint); + if (paint.is_unset()) + paint = White(); + + Color ink(m_line.color()); + if (ink.is_unset()) + ink = paint; + + if (m_fill) + { + // calculate cosine^2 of normal angle + // Magic formula (simulated ambient lighting) + const double dens(0.5*(1+pow(perp|(recip(distance)*direction), 2))); + + paint *= dens; + ink *= dens; + } + + bd.draw(paint, pen_data(ink, m_line.width())); + } // end of facet::draw(bool, int) + + + bool by_distance::operator() (const facet& arg1, const facet& arg2) + { + return arg1.how_far() > arg2.how_far(); + } + + bool by_distance::operator() (const facet* arg1, const facet* arg2) + { + return arg1->how_far() > arg2->how_far(); + } +} // end of namespace diff --git a/graphics/epix/facet.h b/graphics/epix/facet.h new file mode 100644 index 0000000000..0e118da181 --- /dev/null +++ b/graphics/epix/facet.h @@ -0,0 +1,105 @@ +/* + * facet.h -- Utility classes for shaded surface plotting + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.7 + * Last Change: July 08, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "triples.h" +#include "frame.h" + +#include "path.h" + +#include "Color.h" +#include "pen_data.h" + +namespace ePiX { + + class facet { + public: + // create quasi-planar region bounded by path segments in f(R) + facet(P f(double, double), + double u0, double v0, double du, double dv, + const unsigned int N1, const unsigned int N2); + + facet(P f(double, double, double), + double u0, double v0, double w0, + double du, double dv, double dw, + const unsigned int N1, const unsigned int N2); + + // for surfaces of rotation + facet(double f(double), double g(double), + double u0, double v0, double du, double dv, + const unsigned int N1, const unsigned int N2, + const frame& coords=frame()); + + + facet(P f(double, double), + double u0, double v0, double du, double dv, + const unsigned int N1, const unsigned int N2, const Color&); + + facet(P f(double, double, double), + double u0, double v0, double w0, + double du, double dv, double dw, + const unsigned int N1, const unsigned int N2, const Color&); + + // for surfaces of rotation + facet(double f(double), double g(double), + double u0, double v0, double du, double dv, + const unsigned int N1, const unsigned int N2, const Color&, + const frame& coords=frame()); + + + facet* clone() const; + + double how_far() const; + + bool front_facing() const; + + void draw(int cull) const; + + private: + Color m_tint; + pen_data m_line; + bool m_fill; + + P pt1, pt2, pt3, pt4, center, direction, perp; + double distance; + + path bd; + }; + + + class by_distance { + public: + bool operator() (const facet&, const facet&); + bool operator() (const facet*, const facet*); + }; +} // end of namespace diff --git a/graphics/epix/files b/graphics/epix/files new file mode 100644 index 0000000000..4997b1e7ba --- /dev/null +++ b/graphics/epix/files @@ -0,0 +1,224 @@ +# Version 1.2.1 +AUTHORS +BUGS +ChangeLog +COPYING +INSTALL +Makefile.am +Makefile.in +NEWS +POST-INSTALL +README +THANKS +TODO +VERSION +aclocal.m4 +active_screen.cc +active_screen.h +affine.cc +affine.h +angle_units.cc +angle_units.h +arrow_data.cc +arrow_data.h +arrow_style.cc +arrow_style.h +axis.cc +axis.h +bash_completions +camera.cc +camera.h +circle.cc +circle.h +clipping.cc +clipping.h +Color.cc +Color.h +Color_Base.cc +Color_Base.h +Color_CMY.cc +Color_CMY.h +Color_CMYK.cc +Color_CMYK.h +Color_Gray.cc +Color_Gray.h +#Color_Named.cc +#Color_Named.h +Color_Neutral.cc +Color_Neutral.h +Color_RGB.cc +Color_RGB.h +Color_Sep.cc +Color_Sep.h +Color_Utils.cc +Color_Utils.h +#color.cc +#color.h +config.guess +config.sub +configure +configure.ac +#configure.in +constants.h +crop_algorithms.h +cropping.h +cropping.cc +curves.cc +curves.h +data_bins.cc +data_bins.h +data_file.cc +data_file.h +data_mask.cc +data_mask.h +#dataplot.cc +#dataplot.h +debug.h +depcomp +deriv.h +domain.cc +domain.h +edge_data.h +eepic.cc +eepic.h +elaps.1 +elaps.in +enums.h +#epix.1 +epix.1.in +#epix.ebuild +epix.el.in +epix.in +#epix.spec +epix-lib.sh +errors.h +facet.cc +facet.h +files +flix.1 +flix.in +fmt_template.cc +fmt_template.h +format.cc +format.h +frac.cc +frac.h +frame.cc +frame.h +functions.cc +functions.h +geometry.cc +geometry.h +#globals.cc +#globals.h +glyph.cc +glyph.h +halfspace.cc +halfspace.h +hatching.cc +hatching.h +install-sh +intersections.cc +intersections.h +interval.cc +interval.h +label_data.cc +label_data.h +label_style.cc +label_style.h +#Label.cc +#Label.h +laps.1 +laps.in +legend.cc +legend.h +legend_item.cc +legend_item.h +legend_tile.cc +legend_tile.h +length.cc +length.h +lens.cc +lens.h +make_header +map.h +markers.cc +markers.h +marker_style.cc +marker_style.h +mask_diamond.cc +mask_diamond.h +mask_ellipse.cc +mask_ellipse.h +mask_rectangle.cc +mask_rectangle.h +missing +mkinstalldirs +#objects.cc +#objects.h +#output.cc +#output.h +paint_style.cc +paint_style.h +pairs.cc +pairs.h +path.h +path.cc +path_data.cc +path_data.h +path_style.cc +path_style.h +pen_arrow.cc +pen_arrow.h +pen_data.cc +pen_data.h +pen_fill.cc +pen_fill.h +pen_line.cc +pen_line.h +picture.cc +picture.h +picture_data.cc +picture_data.h +plane.cc +plane.h +plot_algorithms.h +plots.cc +plots.h +#polygon.cc +#polygon.h +#polyhedron.cc +#polyhedron.h +pst.cc +pst.h +screen.cc +screen.h +screen_crop.cc +screen_crop.h +screen_data.cc +screen_data.h +screen_mask.cc +screen_mask.h +segment.cc +segment.h +sphere.cc +sphere.h +spline_data.h +spline.cc +spline.h +state.cc +state.h +#state_data.cc +#state_data.h +surface.cc +surface.h +tikz.cc +tikz.h +tile.cc +tile.h +triples.cc +triples.h +utils.cc +utils.h +verbatim.cc +verbatim.h diff --git a/graphics/epix/flix.1 b/graphics/epix/flix.1 new file mode 100644 index 0000000000..4430a02037 --- /dev/null +++ b/graphics/epix/flix.1 @@ -0,0 +1 @@ +.so man1/epix.1 diff --git a/graphics/epix/flix.in b/graphics/epix/flix.in new file mode 100644 index 0000000000..5c011ab3af --- /dev/null +++ b/graphics/epix/flix.in @@ -0,0 +1,563 @@ +#! /bin/bash +# +# flix: Convert ePiX file(s) to png/mng/gif +# +# Options: --help for usage, --version for version and license +# +# Compiler flags may be specified on the command line or in the config +# file ~/.epixrc, just as for epix. +# +# LaTeX packages may be specified on the command line or in the config +# file ~/.dvipsrc, just as for elaps +# +# Copyright (C) 2004, 2005, 2006, 2007 +# Andrew D. Hwang <For address, do "flix -V"> +# + +. "@pkglibdir@/epix-lib.sh" + +EPIX_CONFIG_FILE="$HOME/.epixrc" +FLIX_CONFIG_FILE="$HOME/.flixrc" + +# Search these extensions in order of preference +FLIX_EXTENSIONS="flx xp cc c C cpp" # or NULL +FLIX_DOT_EXT=".${FLIX_EXTENSIONS// /|.}" # for usage message + +# Path to standard header and library and compiler +HDR_PATH="-I@includedir@" +LIB_PATH="-L@pkglibdir@" +COMPILER="@RUNTIME_COMPILER@" + +# default values +FLIX_TMAX=1 +FLIX_FRAME_COUNT=24 +FLIX_DELAY=8 + +# filename variables +declare FLIX_FRAME # $EPIX_INROOT-frameXX +declare FLIX_MOVIE # actual output filename + +FLIX_SUFFIX=mng + +# flags +FLIX_PROGRESS="yes" # Show progress bar? +FLIX_ONLY_EEPIC="no" # Create eepic files only? +FLIX_ONLY_PNG="no" # Create png and eepic files only? +FLIX_SAVE_EEPIC="no" # Save eepic files after run? +FLIX_SAVE_PNG="no" # Save png files after run? + +FLIX_FRAME_PAD="" # zero or more zeros, dep. on number of frames +FLIX_1ST_FRAME= # filename, to test success of compile + +trap '[ -n "$EPIX_TEMPDIR" ] && rm -rf "$EPIX_TEMPDIR"' 0 1 2 3 7 10 13 15 + +# options for external programs +declare -a ELAPS_OPTS + +# compiler variables +declare GXX_INCLUDES +declare GXX_LIBDIRS +GXX_LIBS="-lm" +GXX_POSTLIBS="-lepix" +declare -a GXX_DEFINES + +function flix_help +{ +cat <<HELP +Options: + -h, --help + Show this message and exit + + -V, --version, --gpl + Show version and license + + -v, --verbose + Show success/failure messages + + -d, --delay + Set frame delay in 1/100 sec (default 8) + + --frames + Set number of frames (default 24). + + --gif + Create gif output instead of mng + + --no-defaults + Do not use default include/library directories or libraries + + --pst + Write frames using PSTricks macros (useful only with --save-eepic) + + --tikz + Write frames using tikz macros (useful only with --save-eepic) + + --eepic + Write frames using eepic macros (useful only with --save-eepic) + + --only-eepic + Create only eepic files (default no); implies --save-eepic + + --only-png + Create only png files (default no); implies --save-png + + -o, --output + Specify output file explicitly (extension optional) + + --save-eepic + Save eepic files (default no) + + --save-png + Save png files (default no) + + -t, --tmax + Set maximum time on animation interval (default 1.0). + + -H, --huge + Use hugelatex (if available) to compile frames + + -D* + Pass preprocessor definition to the compiler + + -I*, -L*, -l*, -W*, -i*, -u, -x + Passed to g++ (q.v.) + + Other options are passed to elaps (q.v.) + +HELP +ePiX_bugreport + +} # End of flix_help + + +function flix_pad_init() +{ + let TMP_CT=$((FLIX_FRAME_COUNT/10)) + while [ $TMP_CT -ne 0 ] + do + let TMP_CT=$((TMP_CT/10)) + FLIX_FRAME_PAD="0$FLIX_FRAME_PAD" + done +} + + +# Parse command line/config file for compiler flags/options +function flix_parse_options +{ +while [ "$1" != "${1#-}" ]; do + case "$1" in + + -v|--verbose) + if [ -z "$2" ]; then + echo "Please use -V for version" + exit 0 + fi + EPIX_STDOUT="$SYSTEM_STDOUT" + FLIX_PROGRESS="no" + shift; continue + ;; + + -vv) + echo "Discontinued option -vv; please use -v for verbose output" + exit 0 + ;; + + -h|--help) + ePiX_usage flix $FLIX_DOT_EXT + flix_help + exit 0 + ;; + + -V|--version|--gpl) + ePiX_version flix + ePiX_license + exit 0 + ;; + + -d|--delay) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + FLIX_DELAY="$2" + shift 2; continue + ;; + + --frames) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + FLIX_FRAME_COUNT="$2" + shift 2; continue + ;; + + --gif) + FLIX_SUFFIX=gif + shift; continue + ;; + + --no-defaults) + GXX_POSTLIBS= + HDR_PATH= + LIB_PATH= + ELAPS_OPTS=("${ELAPS_OPTS[@]}" "$1") + shift; continue + ;; + + --pst) + GXX_DEFINES=("${GXX_DEFINES[@]}" "-DEPIX_FMT_PSTRICKS") + shift; continue + ;; + + --tikz) + GXX_DEFINES=("${GXX_DEFINES[@]}" "-DEPIX_FMT_TIKZ") + shift; continue + ;; + + --eepic) + GXX_DEFINES=("${GXX_DEFINES[@]}" "-DEPIX_FMT_EEPIC") + shift; continue + ;; + + --only-eepic) + FLIX_ONLY_EEPIC="yes" + FLIX_SAVE_EEPIC="yes" + shift; continue + ;; + + --only-png) + FLIX_ONLY_PNG="yes" + FLIX_SAVE_PNG="yes" + shift; continue + ;; + + -o|--output) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + FLIX_OUTFILE="$2" + if [ "$FLIX_OUTFILE" = "${FLIX_OUTFILE%.mng}.mng" ]; then + FLIX_SUFFIX=mng + EPIX_OUTROOT="${FLIX_OUTFILE%.mng}" + + elif [ "$FLIX_OUTFILE" = "${FLIX_OUTFILE%.gif}.gif" ]; then + FLIX_SUFFIX=gif + EPIX_OUTROOT="${FLIX_OUTFILE%.gif}" + + else + EPIX_OUTROOT="$FLIX_OUTFILE" + + fi + shift 2; continue + ;; + + # Deliberately undocumented + -q|--quiet) + EPIX_STDERR="$SYSTEM_DEVNULL" + shift; continue + ;; + + --save-eepic) + FLIX_SAVE_EEPIC="yes" + shift; continue + ;; + + --save-png) + FLIX_SAVE_PNG="yes" + shift; continue + ;; + + -t|--tmax) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + FLIX_TMAX="$2" + shift 2; continue + ;; + + -H|--huge) + ELAPS_OPTS=("${ELAPS_OPTS[@]}" "$1") + shift 1; continue + ;; + + -D) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + if [ "$2" != "${2#-}" ]; then + GXX_DEFINES=("${GXX_DEFINES[@]}" "-D$2") + shift 2; continue + else + ePiX_warn "Ignoring option \"$1\" followed by \"$2\"" + shift 1; continue + fi + ;; + + -D*) + GXX_DEFINES=("${GXX_DEFINES[@]}" "$1") + shift 1; continue + ;; + + -I) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + GXX_INCLUDES="$GXX_INCLUDES -I$2"; shift 2; continue + ;; + + -L) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + GXX_LIBDIRS="$GXX_LIBDIRS -L$2"; shift 2; continue + ;; + + -l) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + GXX_LIBS="$GXX_LIBS -l$2"; shift 2; continue + ;; + + -W) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + FLIX_WARNS="$FLIX_WARNS -W$2"; shift 2; continue + ;; + + -I*) + GXX_INCLUDES="$GXX_INCLUDES $1"; shift; continue + ;; + + -L*) + GXX_LIBDIRS="$GXX_LIBDIRS $1"; shift; continue + ;; + + -l*) + GXX_LIBS="$GXX_LIBS $1"; shift; continue + ;; + + -W*) + FLIX_WARNS="$FLIX_WARNS $1"; shift; continue + ;; + + # Relatively obscure compiler options + -i*|-u|-x) + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + FLIX_FLAGS="$FLIX_FLAGS $1 $2"; shift 2; continue + ;; + + *) # Pass other options to elaps + if [ $# -lt 2 ]; then ePiX_die "Missing argument to \"$1\" option"; fi + if [ "$2" != "${2#-}" ]; then + ELAPS_OPTS=("${ELAPS_OPTS[@]}" "$1") + shift 1; continue + else + ELAPS_OPTS=("${ELAPS_OPTS[@]}" "$1" "$2") + shift 2; continue + fi + ;; + esac +done + +# Assume remaining parameters are input files +FLIX_FILE_LIST=("$@") +} # End of flix_parse_options + + +# compile infile outfile.exe +function flix_compile_files() +{ + if [ -z "$1" ]; then + ePiX_die "No input file specified" + fi + + # See epix-lib.sh + mkdir "$EPIX_TEMPDIR" || ePiX_die "Can't create \"${EPIX_TEMPDIR}\"" + + # file counts + local processed=0 + local success=0 + local failure=0 + + # N.B. Global variables named EPIX_XX + for EPIX_INFILE in "${FLIX_FILE_LIST[@]}"; do + + epix_parse_filename "$EPIX_INFILE" "$FLIX_EXTENSIONS" + let processed=processed+1 + + if [ "$EPIX_NOTFOUND" = "yes" ]; then ePiX_fail && continue ; fi + + : ${EPIX_OUTROOT=$EPIX_INROOT} + FLIX_FRAME="$EPIX_OUTROOT"-frame + + # Temporary binary + { TEMP_BIN="$EPIX_INROOT" && touch "${EPIX_TEMPDIR}/$TEMP_BIN" ; } || + { ePiX_fail "No write permission in \"${EPIX_TEMPDIR}\"?!" && \ + continue ; } + + TEMPFILES=("{TEMPFILES[@]}" "${EPIX_TEMPDIR}/$TEMP_BIN") + + # Create symlink to input file with appropriate extension for compiler + TEMP_INPUT="${TEMP_BIN}-tmp.cc" + + TEMPFILES=("{TEMPFILES[@]}" "${EPIX_TEMPDIR}/$TEMP_INPUT") + + { cd ${EPIX_TEMPDIR} && \ + ln -s "../$EPIX_INFILE" "$TEMP_INPUT" && cd .. ; } || + { ePiX_fail "Couldn't create \"${EPIX_TEMPDIR}/$TEMP_INPUT\"" && \ + continue ; } + + # Compile executable + TMP_CMD=($COMPILER "${EPIX_TEMPDIR}/$TEMP_INPUT" $FLIX_WARNS \ + "${GXX_DEFINES[@]}" -o "${EPIX_TEMPDIR}/$TEMP_BIN" \ + $HDR_PATH $GXX_INCLUDES $LIB_PATH $GXX_LIBDIRS $GXX_LIBS \ + $GXX_POSTLIBS $FLIX_FLAGS) + + ePiX_command "${TMP_CMD[@]}" + + # Write animation frames + if [ ! -x "${EPIX_TEMPDIR}/$TEMP_BIN" ]; then + ePiX_fail "Couldn't compile executable \"${EPIX_TEMPDIR}/$TEMP_BIN\"" + continue + fi + + # purge old files + rm -f "$FLIX_FRAME"*.eepic # eepics always overwritten + + if [ "$FLIX_ONLY_EEPIC" = "no" ]; then + # some pngs clobbered => remove all + rm -f "$FLIX_FRAME"*.png + fi + + # and create new frames + for i in $(seq 1 $FLIX_FRAME_COUNT); do + flix_png "${EPIX_TEMPDIR}/$TEMP_BIN" $i + + # bomb out if we can't create first new frame + if [ ! -f "${FLIX_1ST_FRAME}" ]; then + ePiX_fail "Couldn't create frames" + continue 2 + fi + done + + if [ "$FLIX_ONLY_PNG" = "no" -a "$FLIX_ONLY_EEPIC" = "no" ]; then + FLIX_MOVIE="${EPIX_OUTROOT}.$FLIX_SUFFIX" + TMP_CMD=(convert -delay $FLIX_DELAY "$FLIX_FRAME"*.png "$FLIX_MOVIE") + + ePiX_command "${TMP_CMD[@]}" + + if [ -f "$FLIX_MOVIE" ]; then + let success=success+1 + else + ePiX_fail "Couldn't assemble frames" + continue + fi + fi + + echo -e "\nTranscript written on $EPIX_LOGFILE" > "$EPIX_STDOUT" + + # clean up + if [ "$EPIX_OUTROOT" = "$EPIX_INROOT" ]; then unset EPIX_OUTROOT; fi + + rm -f "$FLIX_FRAME"*.eps "$FLIX_FRAME"*.log + + if [ "$FLIX_SAVE_EEPIC" = "no" ]; then + rm -f "$FLIX_FRAME"*.eepic + fi + + if [ "$FLIX_SAVE_PNG" = "no" ]; then + rm -f "$FLIX_FRAME"*.png + fi + + # Newline after progress bar? + if [ "$FLIX_PROGRESS" = "yes" ]; then echo; fi + + done # for EPIX_INFILE in $FLIX_INFILE_LIST + + if [ $processed -gt 1 ]; then + echo "$processed files processed: $success movie(s) written, $failure failed" > "$EPIX_STDERR" + fi + + if [ -d "$EPIX_TEMPDIR" ]; then rm -Rf "$EPIX_TEMPDIR"; fi +} # end of flix_compile_files() + + +# Prints ....|....10....|....20 +function progress_bar() +{ + if [ $(($1 % 10)) -eq 0 ]; then + echo -n "$1" + elif [ $(($1 % 5)) -eq 0 ]; then + echo -n "|" + else + echo -n "." + fi +} + + +# Create a single eepic, eps, and/or png file: +# flix_png file.exe frame_number +function flix_png() +{ + local TEMP_BIN="$1" + local INDEX="$2" + + TIME=$(echo ${FLIX_TMAX}*${INDEX} | bc) + + # Calculate number of 0s in output filename + TMP_CT=$(( ${INDEX}/10 )) + TMP_PAD="$FLIX_FRAME_PAD" + + # progress bar + if [ "$FLIX_PROGRESS" = "yes" ]; then + progress_bar $INDEX + else + ePiX_msg "Frame $INDEX.eps" + fi + + # each time we're divisible by ten, remove a 0 from padding + while [ $TMP_CT -ne 0 ] + do + TMP_CT=$(($TMP_CT/10)) + TMP_PAD="${TMP_PAD%%0}" + done + + INDEX="$TMP_PAD$INDEX" # pad with 0s + if [ $2 -eq 1 ]; then FLIX_1ST_FRAME="$FLIX_FRAME"${TMP_PAD}1.eepic; fi + + TMP_NAME="${FLIX_FRAME}${INDEX}" + + "./$TEMP_BIN" $TIME $FLIX_FRAME_COUNT > "$TMP_NAME".eepic + + if [ $? -ne 0 ]; then + ePiX_warn "Could not create frames" + return + fi + + if [ "$FLIX_ONLY_EEPIC" = "no" ]; then # create eps + TEMPFILES=("{TEMPFILES[@]}" "$TMP_NAME".eps) + + TMP_CMD=(elaps "${ELAPS_OPTS[@]}" -o "$TMP_NAME".eps "$TMP_NAME".eepic) + ePiX_command "${TMP_CMD[@]}" + + TMP_CMD=(convert "$TMP_NAME".eps "$TMP_NAME".png) + ePiX_command "${TMP_CMD[@]}" + fi +} # end of flix_png() + +## Script proper starts here ## + +if [ $# -eq 0 ]; then + ePiX_usage flix $FLIX_DOT_EXT + flix_help + exit 0 +fi + +# Read options from config files, if any +if [ -f "$EPIX_CONFIG_FILE" ]; then + cat "$EPIX_CONFIG_FILE" | grep -v "#" | \ + while read line; do + flix_parse_options "$line" + done +fi + +if [ -f "$FLIX_CONFIG_FILE" ]; then + cat "$FLIX_CONFIG_FILE" | grep -v "#" | \ + while read line; do + flix_parse_options "$line" + done +fi + +flix_parse_options "$@" + +flix_pad_init + +# Suppress all warnings if none are requested +if [ "$FLIX_WARNS" = "" ]; then FLIX_WARNS="-w"; fi + +flix_compile_files "${FLIX_FILE_LIST[@]}" + +exit 0 diff --git a/graphics/epix/fmt_template.cc b/graphics/epix/fmt_template.cc new file mode 100644 index 0000000000..3b7e423070 --- /dev/null +++ b/graphics/epix/fmt_template.cc @@ -0,0 +1,177 @@ +/* + * fmt.cc -- ePiX::fmt output format + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.15 + * Last Change: September 08, 2007 + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <list> + +#include <string> +#include <sstream> + +#include <set> + +#include "pairs.h" +#include "edge_data.h" + +#include "Color.h" + +#include "path_style.h" +#include "pen_data.h" + +#include "format.h" +#include "fmt.h" + +namespace ePiX { + + fmt::fmt() { } // modify as necessary + + fmt* fmt::clone() const + { + return new fmt(*this); + } + + // Filled region with specified Cartesian edges, offset, and color + std::string fmt::print_fill(const std::list<edge2d>& edges, + const pair& offset, + const Color& fill, + const pen_data& line, + const std::string& len) const + { + // Use print_paths to represent a closed polygon bounded by + // "edges", drawn with "line" and solid "fill"-ed. + } + + // Unfilled region, specified Cartesian edges. Should generally be + // trivially implemented using one-pen function (supplied). + std::string fmt::print_line(const std::list<edge2d>& edges, + const pair& offset, + const pen_data& line_pen, + const pen_data& base_pen, + const path_state& style, + const std::string& len) const + { + // Use print_paths (solid) or format::print_edges (otherwise) to + // represent a (closed or open) polygon bounded by "edges", drawn + // with "line" and "base" pens in the line "style". + } + + /* + * Default implementations provided, see format.cc. If default works + * for the new format, remove these declarations. + // Picture start and finish: + // Size and offset in page units, + // pallet (set of colors contained in the screen), + // unitlength + std::string fmt::pic_header(const pair& sizes, + const pair& offsets, + const std::set<Color>& pallet, + const std::string& len) const + { + // Print commands to draw a picture of specified true size and offset + } + + std::string fmt::pic_footer() const + { + // Close/end the picture + } + */ + + // Print color declaration strings: model, name, densities; + // may simply return xdefinecolor(...) if appropriate + std::string fmt::print_color(const std::string&, + const std::string&, + double, + double, + double) const; + + std::string fmt::print_color(const std::string&, + const std::string&, + double, + double, + double, + double) const; + + // One-line comment + std::string fmt::print_comment(const std::string&) const; + + // Verbatim output + std::string fmt::print_verbatim(const std::string&) const; + + + // start/end a picture-like environment, set unit length + std::string fmt::start_picture(const pair&, const pair&) const; + std::string fmt::end_picture() const; + + std::string fmt::set_unitlength(const std::string& len) const; + + // reset internal state date to null + void fmt::reset_state() const; + + //// private member functions //// + + // returns "usepackages" + [SPACE] + "comma-separated LaTeX packages" + std::string fmt::usepackages() const + { + return "usepackages fmt"; + } + + // string argument for passing attributes local to this path/loop + std::string fmt::start_open_path(const std::string&) const; + std::string fmt::end_open_path(const std::string&) const; + + std::string fmt::start_closed_path(const std::string&) const; + std::string fmt::end_closed_path(const std::string&) const; + + // print declarations to set state of output format + std::string fmt::set_fill_state(const Color&) const; + std::string fmt::set_pen_state(const pen_data&) const; + + // place a LaTeX box of width zero (containing string) at location (pair) + std::string fmt::put_box(const pair&, const std::string&) const; + + // draw a filled or hollow circle of specified diam, color + std::string fmt::print_circle_marker(const pair& here, double diam, + bool fill, const Color& color, + const std::string& len) const; + + //// "Optional" (implemented, but reimplementable) functions //// + // Used to format line breaks in long paths (e.g. newline and two spaces) + // std::string fmt::path_break() const; + + // Used between points in paths (e.g. "" or "--") + // std::string fmt::path_connector() const; + + // std::string fmt::print_pallet(const std::set<Color>& pallet) const; + + // Represent a pair, length, or Color as a string + // std::string fmt::print(const pair&) const; // Default: "(a,b)" + // std::string fmt::print(const length&) const; // Default: "3.5cm", e.g. + // std::string fmt::print(const Color&) const; // Default: color name + +} // end of namespace diff --git a/graphics/epix/fmt_template.h b/graphics/epix/fmt_template.h new file mode 100644 index 0000000000..a50b3a3855 --- /dev/null +++ b/graphics/epix/fmt_template.h @@ -0,0 +1,170 @@ +/* + * fmt.h -- ePiX::fmt output format + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.15 + * Last Change: September 08, 2007 + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * To create files foo.h, foo.cc for output format "foo", do + * + * for suff in cc h; do + * sed 's/fmt/foo/g' format_template.$suff > foo.$suff + * done + * + * The include guards and initial comments should be updated manually. + */ + +#ifndef EPIX_FMT +#define EPIX_FMT + +#include <set> +#include <list> +#include <string> + +#include "edge_data.h" + +namespace ePiX { + + class Color; + class pair; + class path_state; + class pen_data; + + class fmt : public format { + public: + + fmt(); // some constructor mandatory, needn't have this signature + + // Return a copy of this + fmt* clone() const; + + // Filled region with specified Cartesian edges, offset, and color + std::string print_fill(const std::list<edge2d>& edges, + const pair& offset, + const Color& fill, + const pen_data& line, + const std::string& len) const; + + // Unfilled region, specified Cartesian edges. Should generally be + // trivially implemented using one-pen function (supplied). + std::string print_line(const std::list<edge2d>& edges, + const pair& offset, + const pen_data& line_pen, + const pen_data& base_pen, + const path_state& style, + const std::string& len) const; + + /* + * Picture start and finish: + * Size and offset in page units, + * pallet (set of colors contained in the screen), + * unitlength + * + * These functions have default implementations, see format.cc. + * If the new format can use the default implementation, these + * functions declarations should be removed. + * + std::string pic_header(const pair& sizes, + const pair& offsets, + const std::set<Color>& pallet, + const std::string& len) const; + + std::string pic_footer() const; + */ + + // Print color declaration strings: model, name, densities + std::string print_color(const std::string&, + const std::string&, + double, + double, + double) const; + + std::string print_color(const std::string&, + const std::string&, + double, + double, + double, + double) const; + + // One-line comment + std::string print_comment(const std::string&) const; + + // Verbatim output + std::string print_verbatim(const std::string&) const; + + + // begin and end a picture-like environment, set the unit length + std::string start_picture(const pair&, const pair&) const; + std::string end_picture() const; + + std::string set_unitlength(const std::string& len) const; + + // State data, if any, must be mutable + void reset_state() const; + + private: + + std::string usepackages() const; + + // string argument for passing attributes local to this path/loop + std::string start_open_path(const std::string&) const; + std::string end_open_path(const std::string&) const; + + std::string start_closed_path(const std::string&) const; + std::string end_closed_path(const std::string&) const; + + // print declarations to set state of output format + std::string set_fill_state(const Color&) const; + std::string set_pen_state(const pen_data&) const; + + // place a LaTeX box of width zero (containing string) at location (pair) + std::string put_box(const pair&, const std::string&) const; + + // draw a filled or hollow circle of specified diam, color + std::string print_circle_marker(const pair& here, double diam, + bool fill, const Color& color, + const std::string& len) const; + + //// "Optional" (implemented, but reimplementable) functions //// + // inserted in long paths, defaults to <newline> and two spaces + // std::string path_break() const; + + // inserted between path points, deaults to "" + // std::string path_break() const; + + // std::string print_pallet(const std::set<Color>&) const; + + // Represent a pair, length, or Color as a string + // std::string print(const pair&) const; // Default: "(a,b)" + // std::string print(const length&) const; // Default: "3.5cm", e.g. + // std::string print(const Color&) const; // Default: color name + + }; // end of class fmt +} // end of namespace + +#endif /* EPIX_FMT */ diff --git a/graphics/epix/format.cc b/graphics/epix/format.cc new file mode 100644 index 0000000000..f799baa7a4 --- /dev/null +++ b/graphics/epix/format.cc @@ -0,0 +1,720 @@ +/* + * format.cc -- ePiX output format interface and label-writing functions + * + * This file is part of ePiX, a c++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> +#include <string> +#include <sstream> +#include <vector> +#include <list> + +#include "enums.h" +#include "constants.h" + +#include "errors.h" +#include "utils.h" + +#include "functions.h" + +#include "marker_style.h" +#include "label_style.h" +#include "path_style.h" +#include "Color.h" + +#include "pen_data.h" + +#include "pairs.h" +#include "edge_data.h" + +#include "length.h" + +#include "picture.h" // circ may need to add White to pallet +#include "picture_data.h" + +#include "format.h" + +namespace ePiX { + // public, non-virtual + // LaTeX label-generating commands written in terms of protected interface + std::string format::print_mark(const pair& here, const pair& offset, + const epix_mark_type mk, + const marker_sizes& sz, + const label_state& style, + const std::string& len) const + { + // convert dotsize to len + length true_diam(sz.dot_size()); + double diam(true_diam.to(len).magnitude()); + + // set diameter + if (mk == DOT || mk == CIRC) + diam *= 0.75; + else if (mk == DDOT) + diam *= 0.5; + + // and print + if (mk == SPOT || mk == DOT || mk == DDOT) + return print_circle_marker(here + pt_to_len(offset, len), diam, true, + style.text_color(), len); + + else if (mk == CIRC) // Draw filled dot, then ring + { + Color bk(style.mask_color()); + // use White for unset mask + if (bk.is_unset()) + { + bk = White(); + the_picture().add_to_pallet(bk); + } + + return print_circle_marker(here + pt_to_len(offset, len), diam, true, + bk, len) + + print_circle_marker(here + pt_to_len(offset, len), diam, false, + style.text_color(), len); + } + + else if (mk == RING) + return print_circle_marker(here + pt_to_len(offset, len), diam, false, + style.text_color(), len); + + else + return put_box(here + pt_to_len(offset, len), + print_latex_label(style, print_latex_marker(mk, sz, len), + false)); // no mask or box + } + + // public, non-virtual + std::string format::print_text(const pair& here, const pair& offset, + const std::string& label, + const label_state& style, + const std::string& len) const + { + return put_box(here + pt_to_len(offset, len), + print_latex_label(style, label, true)); + } + + + // public, non-virtual + std::string format::print_line(const edge2d& e, + const pair& offset, + const pen_data& line, + const pen_data& base, + const path_state& style, + const std::string& len) const + { + if ((line.width() < length(EPIX_EPSILON)) + || (line.color().is_unset()) + || !e.is_seen() ) + return ""; + + // else + std::list<edge2d> edges; + edges.push_back(e); + return print_line(edges, offset, line, base, style, len); + } + + + // public, non-virtual (file header comment block) + std::string format::file_comments(const std::string& units, + const length& hoffset, + const length& voffset, + double Xmin, double Xmax, + double Ymin, double Ymax, + double Hsize, double Vsize) const + { + std::ostringstream obuf; + + const std::string hoff_dir(length(0) < hoffset ? "right" : "left"); + const std::string voff_dir(length(0) < voffset ? "up" : "down"); + + const double hoff(hoffset.magnitude()); + const double voff(voffset.magnitude()); + + std::stringstream bd_box, act_sz, fg_off; + bd_box << " Cartesian bounding box: [" + << Xmin << "," << Xmax << "] x [" << Ymin << "," << Ymax<< "]"; + + act_sz << " Actual size: " << Hsize << " x " << Vsize << units; + + fg_off << " Figure offset: " + << hoff_dir << " by " << hoff << units << ", " + << voff_dir << " by " << voff << units; + + obuf << print_comment("ePiX-" + epix_version()) + << print_comment("") + << print_comment(bd_box.str()) + << print_comment(act_sz.str()) + << print_comment(fg_off.str()) + << print_comment("") + << print_comment(usepackages()) + << print_comment(""); + + return obuf.str(); + } // end of file_comments() + + + // public, virtual + std::string format::pic_header(const pair& sizes, + const pair& offsets, + const std::set<Color>& pallet, + const std::string& len) const + { + std::stringstream obuf; + obuf << print_pallet(pallet) + << set_unitlength(len) + << start_picture(sizes, offsets); + + return obuf.str(); + } + + // public, virtual + std::string format::pic_footer() const + { + return end_picture(); + } + + // public, non-virtual + std::string format::print_color(const std::string& model, + const std::string& name, + const std::vector<double>& dens) const + { + if (dens.size() == 3) + return print_color(model, name, dens.at(0), dens.at(1), dens.at(2)); + + else if (dens.size() == 4) + return print_color(model, name, + dens.at(0), dens.at(1), dens.at(2), dens.at(3)); + + else if (dens.size() == 0) // Neutral() + return ""; + + else + { + epix_warning("format::print_color(): Internal error"); + return print_color("rgb", "rgb_000000", 0, 0, 0); + } + } + + // protected, non-virtual (one-pen version) + std::string format::print_line(const std::list<edge2d>& edges, + const pair& offset, const pen_data& line, + const path_state& style, + const std::string& attribs, + const std::string& len) const + { + if ( (line.width() < length(EPIX_EPSILON)) + || (line.color().is_unset()) + || edges.begin() == edges.end() ) + return ""; + + // else + std::stringstream value, obuf; + + obuf << set_pen_state(line); + + if (style.is_solid()) + obuf << print_paths(edges, offset, attribs, len); + + else // not solid + { + // compute diameter of dots + length lw(line.width()); + lw.to(len); + + // compute unit length in pt + length units("1"+len); + units.to("pt"); + double in_pt(units.magnitude()); + + double pattern_size(style.separation()); // in pt + + // split each edge into pattern_size chunks if necessary + for (std::list<edge2d>::const_iterator ep = edges.begin(); + ep != edges.end(); ++ep) + { + double curr_len(((*ep).length())*in_pt); + + // number of dash patterns *ep can hold + unsigned int N((unsigned int) ceil(curr_len/pattern_size)); + if (N == 1) + obuf << print_edge((*ep), offset, style.breakpts(), + lw.magnitude(), line.color(), attribs, len); + + if (N > 1) + { + pair T((*ep).tail()), dir((1.0/N)*((*ep).head() - T)); + for (unsigned int i=0; i<N; ++i) + obuf << print_edge(edge2d(T+i*dir, T+(i+1)*dir, + (*ep).is_seen()), + offset, style.breakpts(), + lw.magnitude(), line.color(), + attribs, len); + } + } + } // end of !solid + + return obuf.str(); + } // end of print_line(edges, offset, line, style, attribs, len) + + + std::string format::print_line(const edge2d& e, + const pair& offset, + const pen_data& line, + const path_state& style, + const std::string& attribs, + const std::string& len) const + { + if ( (line.width() < length(EPIX_EPSILON)) || + (line.color().is_unset()) || + !e.is_seen() ) + return ""; + + std::list<edge2d> edges; + edges.push_back(e); + return print_line(edges, offset, line, style, attribs, len); + } + + + // local to this file + std::string __epix_rule(double x, double y) + { + std::stringstream buf; + buf << "\\rule{" << x << "pt}{" << y << "pt}"; + + return buf.str(); + } + + + // protected, non-virtual + std::string format::xdefinecolor(const std::string& model, + const std::string& name, + double d1, double d2, double d3) const + { + std::stringstream obuf; + obuf << "\\xdefinecolor{" << name << "}"; + + if (model == "cmy") + { + double bk(min(min(d1,d2),d3)); + + obuf << "{cmyk}{" + << d1-bk << "," << d2-bk << "," << d3-bk << "," << bk << "}%" + << std::endl; + } + + else + obuf << "{" << model << "}{" << d1 << "," << d2 << "," << d3 << "}%" + << std::endl; + + return obuf.str(); + } + + // protected, non-virtual + std::string format::xdefinecolor(const std::string& model, + const std::string& name, + double d1, double d2, + double d3, double d4) const + { + std::stringstream obuf; + obuf << "\\xdefinecolor{" << name << "}{cmyk}{" + << d1 << "," << d2 << "," << d3 << "," << d4 << "}%" + << std::endl; + + return obuf.str(); + } + + // protected, virtual + std::string format::print_pallet(const std::set<Color>& pallet) const + { + std::stringstream obuf; + + for (std::set<Color>::const_iterator cp=pallet.begin(); + cp!=pallet.end(); ++cp) + obuf << print_color((*cp).model(), (*cp).name(), (*cp).densities()); + + return obuf.str(); + } + + // protected, virtual + std::string format::print(const pair& arg) const + { + std::stringstream o; + o << "(" << truncate(arg.x1()) << "," << truncate(arg.x2()) << ")"; + return o.str(); + } + + // protected, virtual + std::string format::print(const length& len) const + { + return len.name(); + } + + // protected, virtual + std::string format::print(const Color& col) const + { + return col.name(); + } + + // protected, non-virtual (print non-solid edge as segments and dots) + std::string format::print_edge(const edge2d& edge, const pair& offset, + const std::vector<double> bkpts, + double diam, const Color& col, + const std::string& attribs, + const std::string& len) const + { + if (!edge.is_seen()) + return ""; + + if (bkpts.size() % 2 != 0) + { + epix_warning("Internal error in path pattern"); + return ""; + } + + // else + std::stringstream obuf; + + const pair T(edge.tail() + pt_to_len(offset, len)); + const pair dir(edge.head() - edge.tail()); + + for (unsigned int i=0; i < bkpts.size(); i += 2) + { + double curr(bkpts.at(i)), next(bkpts.at(i+1)); + + if (EPIX_EPSILON < next - curr) // dash + obuf << start_open_path(attribs) + << print(T + curr*dir) + << path_connector() + << print(T + next*dir) + << end_open_path(attribs); + + else // dot + obuf << print_circle_marker(T + curr*dir, diam, true, col, len); + } + + return obuf.str(); + } + + + // protected, non-virtual (solid path, handle (offset) data only) + std::string format::print_paths(const std::list<edge2d>& edges, + const pair& offset, + const std::string& attribs, + const std::string& len) const + { + std::stringstream obuf; + + std::list<edge2d>::const_iterator ep(edges.begin()); + + const pair shift(pt_to_len(offset, len)); + + bool all_visible(true); // all edges visible? + + // Assume not for now + const std::string pname(start_open_path(attribs)); + + // print contiguous lists of visible edges + while (ep != edges.end()) + { + if ((*ep).is_seen()) // print contiguous visible path + { + obuf << pname + << print((*ep).tail() + shift) + << path_connector() + << print((*ep).head() + shift); + ++ep; + + while ((*ep).is_seen() && ep != edges.end()) + obuf << path_connector() << print((*ep++).head() + shift); + + obuf << end_open_path(attribs); + } + + else // invisible edge + { + ++ep; + all_visible = false; + } + } + + std::string value(obuf.str()); + + --ep; // last edge + + // if we're a closed loop of visible edges, adjust open/close path + if (all_visible && (*edges.begin()).tail() == (*ep).head()) + { + value.replace(0, + start_open_path(attribs).size(), + start_closed_path(attribs)); + + value.replace(value.size()-end_open_path(attribs).size(), + end_open_path(attribs).size(), + end_closed_path(attribs)); + } + + return break_lines(value, path_break()); + } + + + //// Label and marker functions //// + // protected, non-virtual (print LaTeX command for marker of specified size) + std::string format::print_latex_marker(const epix_mark_type mark, + const marker_sizes& sz, + const std::string& len) const + { + std::stringstream obuf; + + obuf << "$"; + + switch(mark) + { + case PLUS: + obuf << "+"; + break; + case OPLUS: + obuf << "\\oplus"; + break; + case TIMES: + obuf << "\\times"; + break; + case OTIMES: + obuf << "\\otimes"; + break; + case DIAMOND: + obuf << "\\diamond"; + break; + case UP: + obuf << "\\bigtriangleup"; + break; + case DOWN: + obuf << "\\bigtriangledown"; + break; + case BOX: + obuf << __epix_rule(0.75*sz.dot_size(), 0.75*sz.dot_size()); + break; + case BBOX: + obuf << __epix_rule(0.5*sz.dot_size(), 0.5*sz.dot_size()); + break; + case HTICK: + obuf << __epix_rule(0.5, 2*sz.tick_size()); + break; + case VTICK: + obuf << __epix_rule(2*sz.tick_size(), 0.5); + break; + // should never see these cases + case SPOT: + case DOT: + case DDOT: + case CIRC: + case RING: + epix_warning("Mark type internal error"); // fall through + case PATH: // fall through + case TEXT: + default: + return ""; // N.B. return + } + + obuf << "$"; + + return obuf.str(); + } + + + // public, non-virtual + // handles font face, size, and color + std::string format::print_latex_hbox(const label_state& style, + const std::string& label) const + { + std::stringstream text_buf; + + bool need_ff(style.fontface() != "rm"); // roman + bool need_fs(style.fontsize() != "nsz"); // normalsize + + text_buf << "\\hbox{\\color{" << print(style.text_color()) << "}"; + + if (need_ff) + text_buf << "\\text" << style.fontface() << "{"; + + if (need_fs) + text_buf << "\\" << style.fontsize() << " "; + + text_buf << label; + + if (need_ff) + text_buf << "}"; + + text_buf << "}"; + + return text_buf.str(); + } + + + // protected, virtual + std::string format::path_break() const + { + std::stringstream buf; + buf << std::endl << " "; + + return buf.str(); + } + + // inserted between points of a path + std::string format::path_connector() const + { + return ""; + } + + // protected, non-virtual + // handles rotation, masking, border, and alignment + std::string format::print_latex_label(const label_state& style, + const std::string& label, + bool boxed) const + { + std::stringstream obuf; + + // need rotatebox? + bool rotated(EPIX_EPSILON < fabs(style.label_angle())); + + // need colorbox? + bool masked(boxed && style.is_masked()); + + // need extra fcolorbox? + bool padded(style.label_padding() != length(0)); + + obuf << "\\makebox(0,0)" + << print(style.align_to()); // "none" -> "" + + obuf << "{"; + + if (rotated) + obuf << "\\rotatebox{" << style.label_angle() << "}{"; + + if (masked) + { + pen_data bpen(style.label_border()); + + // draw border? + if (!bpen.color().is_unset() && length(EPIX_EPSILON) < bpen.width()) + obuf << "\\fboxrule" << print(bpen.width()) << "%" << std::endl + << "\\fcolorbox{" << print(bpen.color()) << "}{" + << print(style.mask_color()) << "}"; + + else + obuf << "\\colorbox{" << print(style.mask_color()) << "}"; + + if (padded) + { + // cancel off the xcolor default + length extra_pad(style.label_padding() + length(-3)); + + obuf << "{\\fboxrule" << print(extra_pad) << "%" << std::endl + << "\\fcolorbox{" << print(style.mask_color()) << "}{" + << print(style.mask_color()) << "}"; + } + + obuf << "{"; + } + + // finally, the payload + obuf << print_latex_hbox(style, label); + + // close wrappers + if (masked) + { + obuf << "}"; + + if (padded) + obuf << "}"; + } + + if (rotated) + obuf << "}"; + + obuf << "}"; + + return obuf.str(); + } // end of print_latex_label + + // private (convert an epix_label_posn to a string) + std::string format::print(const epix_label_posn arg) const + { + std::string val; + switch(arg) + { + case none: + return ""; // other cases return at bottom + + case c: + val="c"; + break; + case r: + val="l"; // opposite of LaTeX + break; + case tr: + case rt: + val="bl"; + break; + case t: + val="b"; + break; + case tl: + case lt: + val="br"; + break; + case l: + val="r"; + break; + case bl: + case lb: + val="tr"; + break; + case b: + val="t"; + break; + case br: + case rb: + val="tl"; + break; + } + + return "[" + val + "]"; + } // end of format::print(align_type) + + + // private (true pt offset to len) + pair format::pt_to_len(pair offset, const std::string& len) const + { + return offset *= length("1pt").to(len).magnitude(); + } +} // end of namespace diff --git a/graphics/epix/format.h b/graphics/epix/format.h new file mode 100644 index 0000000000..7432526ac9 --- /dev/null +++ b/graphics/epix/format.h @@ -0,0 +1,300 @@ +/* + * format.h -- ePiX::output format interface + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * Last Change: September 13, 2007 + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file defines ePiX's output interface. The fmt_template + * files contain skeleton code for a new format. The command + * + * for suff in cc h; do + * sed 's/fmt/foo/g' fmt_template.$suff > foo.$suff + * done + * + * (or manual search-and-replace) creates "blank" files containing + * declarations and pseudocode. (The include guards should also be + * changed.) Please consult pst.cc and eepic.cc for complete examples. + * + * The pure virtual functions in this file *must* be implemented by + * derived classes. They are signified by the keyword "virtual" and + * the definition "= 0" after their declaration. They are also found + * in the skeleton class mentioned above. + * + * The seven ordinary virtual functions (the destructor, pic_header and + * pic_footer, and four low-level functions for printing a pallet, pair, + * Color, or length) _may_ be overridden by derived classes, but will + * not be (unless the format has unusual conventions). + * + * No other functions should be re-implemented by derived classes. + */ + +#ifndef EPIX_FORMAT +#define EPIX_FORMAT + +#include <set> +#include <list> +#include <vector> +#include <string> + +#include "enums.h" +#include "edge_data.h" + +namespace ePiX { + + class Color; + class label_state; + class length; + + class marker_sizes; + class pair; + class path_state; + class pen_data; + + class format { + public: + // Free resources allocated by the constructor (usually unnecessary) + virtual ~format() { } + + // Return a copy of this + virtual format* clone() const = 0; + + + // LaTeX symbol with specified location, offset and alignment + std::string print_mark(const pair& location, + const pair& offset, + const epix_mark_type mark, + const marker_sizes& sizes, + const label_state& style, + const std::string& len) const; + + // Label text with specified location, offset, and alignment + std::string print_text(const pair& location, + const pair& offset, + const std::string& text, + const label_state& style, + const std::string& len) const; + + + // Filled region with specified Cartesian edges, offset, and color + virtual std::string print_fill(const std::list<edge2d>& edges, + const pair& offset, + const Color& fill, + const pen_data& line, + const std::string& len) const = 0; + + + // Unfilled region, specified Cartesian edges. Should generally be + // trivially implemented using one-pen function (supplied). + virtual std::string print_line(const std::list<edge2d>& edges, + const pair& offset, + const pen_data& line_pen, + const pen_data& base_pen, + const path_state& style, + const std::string& len) const = 0; + + // implemented using previous function + std::string print_line(const edge2d&, + const pair&, + const pen_data&, + const pen_data&, + const path_state&, + const std::string&) const; + + + // File comment and information block + std::string file_comments(const std::string& units, + const length& hoff, + const length& voff, + double Xmin, double Xmax, + double Ymin, double Ymax, + double Hsize, double Vsize) const; + + + // Picture start and finish: + // Size and offset in page units, + // pallet (set of colors contained in the screen), + // unitlength + virtual std::string pic_header(const pair& sizes, + const pair& offsets, + const std::set<Color>& pallet, + const std::string& len) const; + + virtual std::string pic_footer() const; + + + // Print color declaration strings: model, name, densities + std::string print_color(const std::string&, + const std::string&, + const std::vector<double>&) const; + + // One-line comment + virtual std::string print_comment(const std::string&) const = 0; + + // Verbatim output + virtual std::string print_verbatim(const std::string&) const = 0; + + + // print text with color, font in an hbox + std::string print_latex_hbox(const label_state& style, + const std::string& label) const; + + // Derived classes use functions below to implement the public interface. + // The first two are needed to print screen_data for legend items. + virtual std::string start_picture(const pair&, const pair&) const = 0; + virtual std::string end_picture() const = 0; + + virtual std::string set_unitlength(const std::string& len) const = 0; + + // If child maintains drawing state, this function clears it. + virtual void reset_state() const = 0; + + protected: + // inserted between points when breaking lines + virtual std::string path_break() const; + // inserted between points of a path + virtual std::string path_connector() const; + + // names of LaTeX packages required to process our output + virtual std::string usepackages() const = 0; + + // string argument for passing attributes local to this path/loop + virtual std::string start_open_path(const std::string&) const = 0; + virtual std::string end_open_path(const std::string&) const = 0; + + virtual std::string start_closed_path(const std::string&) const = 0; + virtual std::string end_closed_path(const std::string&) const = 0; + + // print declarations to set state of output format + virtual std::string set_fill_state(const Color&) const = 0; + virtual std::string set_pen_state(const pen_data&) const = 0; + + // place a LaTeX box of width zero (containing string) at location (pair) + virtual std::string put_box(const pair&, const std::string&) const = 0; + + // too idiosyncratic to handle format-independently + virtual std::string print_circle_marker(const pair& here, double diam, + bool fill, const Color& color, + const std::string& len) const = 0; + + // xcolor definition strings + std::string xdefinecolor(const std::string&, + const std::string&, + double, + double, + double) const; + + std::string xdefinecolor(const std::string&, + const std::string&, + double, + double, + double, + double) const; + + virtual std::string print_color(const std::string&, + const std::string&, + double, + double, + double) const = 0; + + virtual std::string print_color(const std::string&, + const std::string&, + double, + double, + double, + double) const = 0; + + // Define all colors in the picture + virtual std::string print_pallet(const std::set<Color>& pallet) const; + + // Represent a pair, length, or Color as a string + virtual std::string print(const pair&) const; // Default: "(a,b)" + virtual std::string print(const length&) const; // Default: "3.5cm", e.g. + virtual std::string print(const Color&) const; // Default: color name + + + // one-pen version + std::string print_line(const std::list<edge2d>& edges, + const pair& offset, + const pen_data& line, + const path_state& style, + const std::string& attribs, + const std::string& len) const; + + // for single edge; wrap in list and pass to previous function + std::string print_line(const edge2d& e, + const pair& offset, + const pen_data& line, + const path_state& style, + const std::string& attribs, + const std::string& len) const; + + // Print a non-solid edge, using the virtual interface + std::string print_edge(const edge2d& edge, const pair& offset, + const std::vector<double> bkpts, + double diam, + const Color& col, + const std::string& attribs, + const std::string& len) const; + + // Print an edge list as offset path segments, or as a loop + // if all edges are visible and path is closed. + std::string print_paths(const std::list<edge2d>& edges, + const pair& offset, + const std::string& attribs, + const std::string& len) const; + + /* + * Text in an ePiX output file is assumed to be typeset with + * LaTeX. The functions below perform LaTeX-specific low-level + * formatting. For uniformity and simplicity, these functions are + * format-independent: Implementations are provided and these + * functions are non-virtual. Format-specific masking, padding, + * and bordering capabilities (e.g. in PSTricks) are not used. + */ + // label style, text, masking flag + std::string print_latex_label(const label_state&, + const std::string&, + bool) const; + + // Print LaTeX command for marker symbol; 3rd (len) argument for scaling + std::string print_latex_marker(const epix_mark_type, + const marker_sizes&, + const std::string&) const; + + private: + // convert an epix_label_posn to string + std::string print(const epix_label_posn arg) const; + + // convert true pt offset to len + pair pt_to_len(pair offset, const std::string& len) const; + + }; // end of base class format +} // end of namespace + +#endif /* EPIX_FORMAT */ diff --git a/graphics/epix/frac.cc b/graphics/epix/frac.cc new file mode 100644 index 0000000000..6fadd246af --- /dev/null +++ b/graphics/epix/frac.cc @@ -0,0 +1,262 @@ +/* + * frac.cc -- ePiX rational number class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> + +#include "frac.h" + +namespace ePiX { + + const int MAX_DENOM(10000); + const double EPS(1.0/MAX_DENOM); + + unsigned int __epix_gcd (int i, unsigned int j); + + frac::frac(const int n, const unsigned int d) + : m_num(n), m_denom(d) { } + + // express arg as a fraction with denominator no larger than MAX_DENOM + frac::frac(double arg) + { + unsigned int denom(1); + if (fabs(arg) < EPS) + { + m_num = 0; + m_denom = 1; + } + + else + { + int sgn(arg < 0 ? -1 : 1); + double abs_arg(sgn*arg); + + // store best approximation + int best_num(0); + double running_error(0.5); + + while (denom <= 1+MAX_DENOM) + { + const double tmp(abs_arg*denom); + + int tmp_lo((int) floor(tmp)); + + if (tmp - tmp_lo < EPS) // good approx + { + best_num = tmp_lo; + break; + } + + else if (tmp - tmp_lo < running_error) // improved approx + { + best_num = tmp_lo; + running_error = tmp - best_num; + } + + int tmp_hi((int) ceil(tmp)); + if (tmp_hi - tmp < EPS) + { + best_num = tmp_hi; + break; + } + + else if (tmp_hi - tmp < running_error) + { + best_num = tmp_hi; + running_error = best_num - tmp; + } + + ++denom; + } + + m_num = sgn*best_num; + m_denom = denom; + } + } // end of frac::frac(double arg) + + + // increment operators + frac& frac::operator += (const frac& arg) + { + m_num *= arg.m_denom; + m_num += m_denom*arg.m_num; + m_denom *= arg.m_denom; + + return *this; + } + + frac& frac::operator -= (const frac& arg) + { + m_num *= arg.m_denom; + m_num -= m_denom*arg.m_num; + m_denom *= arg.m_denom; + + return *this; + } + + frac& frac::operator *= (const frac& arg) + { + m_num *= arg.m_num; + m_denom *= arg.m_denom; + + return *this; + } + + frac& frac::operator /= (const frac& arg) + { + unsigned int arg_num(arg.m_num < 0 ? -arg.m_num : arg.m_num); + + m_num *= arg.m_denom; + m_denom *= arg_num; + + if (arg.m_num < 0) + m_num = -1; + + return *this; + } + + frac& frac::reduce() + { + unsigned int factor(__epix_gcd(m_num, m_denom)); + m_num /= factor; + m_denom /= factor; + + return *this; + } + + double frac::eval() const + { + double temp(m_num); + return temp /= m_denom; + } + + int frac::num() const + { + return m_num; + } + + unsigned int frac::denom() const + { + return m_denom; + } + + bool frac::is_int() const + { + return __epix_gcd(m_num, m_denom) == m_denom; + } + + + frac operator+ (frac arg1, const frac& arg2) + { + return arg1 += arg2; + } + + frac operator- (frac arg1) + { + return arg1 *= -1; + } + + frac operator- (frac arg1, const frac& arg2) + { + return arg1 -= arg2; + } + + frac operator* (frac arg1, const frac& arg2) + { + return arg1 *= arg2; + } + + frac operator/ (frac arg1, const frac& arg2) + { + return arg1 /= arg2; + } + + // (in)equality + bool operator == (const frac& u, const frac& v) + { + return u.num()*v.denom() == v.num()*u.denom(); + } + + bool operator != (const frac& u, const frac& v) + { + return !(u == v); + } + + // denoms are unsigned + bool operator < (const frac& u, const frac& v) + { + return u.num()*v.denom() < v.num()*u.denom(); + } + + bool operator > (const frac& u, const frac& v) + { + return u.num()*v.denom() > v.num()*u.denom(); + } + + bool operator <= (const frac& u, const frac& v) + { + return u.num()*v.denom() <= v.num()*u.denom(); + } + + bool operator >= (const frac& u, const frac& v) + { + return u.num()*v.denom() >= v.num()*u.denom(); + } + + // N.B.: gcd(0,i) = |i| + unsigned int __epix_gcd (int i, unsigned int j) + { + unsigned int new_i(i<0 ? -i : i); + unsigned int temp; + + if (new_i==0 || j==0) // (1,0) and (0,1) coprime, others not + return new_i + j; + + else { + if (j < new_i) // swap them + { + temp = j; + j = new_i; + new_i = temp; + } + // Euclidean algorithm + while ((temp = j%new_i)) // i does not evenly divide j + { + j = new_i; + new_i = temp; + } + + return new_i; + } + } +} // end of namespace + diff --git a/graphics/epix/frac.h b/graphics/epix/frac.h new file mode 100644 index 0000000000..c76d469852 --- /dev/null +++ b/graphics/epix/frac.h @@ -0,0 +1,81 @@ +/* + * frac.h -- ePiX::rational number class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.10 + * Last Change: August 07, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_FRACTION +#define EPIX_FRACTION + +namespace ePiX { + + class frac { + public: + frac(const int n, const unsigned int d=1); + explicit frac(double); + + // increment operators + frac& operator += (const frac& arg); + frac& operator -= (const frac& arg); + frac& operator *= (const frac& arg); + frac& operator /= (const frac& arg); + + frac& reduce(); + double eval() const; + + int num() const; + unsigned int denom() const; + + bool is_int() const; + + private: + int m_num; + unsigned int m_denom; + }; // end of class frac + + frac operator+ (frac arg1, const frac& arg2); + frac operator- (frac arg1); + frac operator- (frac arg1, const frac& arg2); + frac operator* (frac arg1, const frac& arg2); + frac operator/ (frac arg1, const frac& arg2); + + // (in)equality + bool operator == (const frac& u, const frac& v); + bool operator != (const frac& u, const frac& v); + + bool operator < (const frac& u, const frac& v); + bool operator > (const frac& u, const frac& v); + + bool operator <= (const frac& u, const frac& v); + bool operator >= (const frac& u, const frac& v); + +} // end of namespace + +#endif /* EPIX_FRACTION */ diff --git a/graphics/epix/frame.cc b/graphics/epix/frame.cc new file mode 100644 index 0000000000..176025ffe0 --- /dev/null +++ b/graphics/epix/frame.cc @@ -0,0 +1,114 @@ +/* + * frame.cc -- ePiX orthonormal basis + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.0.23 + * Last Change: January 10, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "constants.h" +#include "functions.h" + +#include "errors.h" +#include "triples.h" +#include "frame.h" + +namespace ePiX { + + // standard basis + frame::frame() + : m_e1(E_1), m_e2(E_2), m_e3(E_3) { } + + // frame constructor, suitable for (sea,sky,eye) frames: Usually we + // know the eye vector and want to preserve its direction. The frame + // is guaranteed to be right-handed, and the first arg is immaterial. + frame::frame(P arg1, P arg2, P arg3) + { + if (norm(arg2*arg3) < EPIX_EPSILON) // too nearly linearly dependent + epix_error("Linearly dependent arguments to frame"); + + // partial Gram-Schmidt + arg3 *= 1/norm(arg3); // normalize eye + + arg2 %= arg3; // orthogonalize sky_vector, preserving screen direction + arg2 *= 1/norm(arg2); // and normalize + + m_e1 = arg2*arg3; + m_e2 = arg2; + m_e3 = arg3; + } + + + frame& frame::rot1(double angle) + { + P temp2(m_e2); + P temp3(m_e3); + + m_e2 = (Cos(angle)*(temp2)) - (Sin(angle)*(temp3)); + m_e3 = (Sin(angle)*(temp2)) + (Cos(angle)*(temp3)); + + return *this; + } + + + frame& frame::rot2(double angle) + { + P temp3(m_e3); + P temp1(m_e1); + + m_e3 = (Cos(angle)*(temp3)) - (Sin(angle)*(temp1)); + m_e1 = (Sin(angle)*(temp3)) + (Cos(angle)*(temp1)); + + return *this; + } + + frame& frame::rot3(double angle) + { + P temp1(m_e1); + P temp2(m_e2); + + m_e1 = (Cos(angle)*(temp1)) - (Sin(angle)*(temp2)); + m_e2 = (Sin(angle)*(temp1)) + (Cos(angle)*(temp2)); + + return *this; + } + + // frame elements + P frame::sea() const + { + return m_e1; + } + P frame::sky() const + { + return m_e2; + } + P frame::eye() const + { + return m_e3; + } +} // end of namespace diff --git a/graphics/epix/frame.h b/graphics/epix/frame.h new file mode 100644 index 0000000000..fa70c3d16d --- /dev/null +++ b/graphics/epix/frame.h @@ -0,0 +1,82 @@ +/* + * frame.h -- Orthonormal basis + * + * This file is part of ePiX, a preprocessor for creating high-quality + * line figures in LaTeX + * + * Version 1.0.15 + * Last Change: October 10, 2006 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * In geometry, a "frame" is a right-handed orthonormal basis, that is, + * an ordered set of three mututally perpendicular unit vectors, oriented + * according to the right-hand rule. A frame has nothing to do with + * picture frames. + * + * + * This file provides: + * - the frame class, and routines for rotating a frame about the axes + * determined by its elements. (Note that there are no methods for + * rotating about fixed coordinate axes, and that rotations in R^3 do + * not generally commute. + */ + +#ifndef EPIX_FRAME +#define EPIX_FRAME + +#include "triples.h" + +namespace ePiX { + + class frame { + public: + // standard basis + frame(); + + // Gram-Schmidt + frame(P arg1, P arg2, P arg3); // need args by value + + // frame elements + P sea() const; + P sky() const; + P eye() const; + + // rotations about frame elements + frame& rot1(double angle); + frame& rot2(double angle); + frame& rot3(double angle); + + private: + P m_e1; // sea + P m_e2; // sky + P m_e3; // eye + }; // end of class frame + +} // end of namespace + +#endif /* EPIX_FRAME */ diff --git a/graphics/epix/functions.cc b/graphics/epix/functions.cc new file mode 100644 index 0000000000..ae1c9649ae --- /dev/null +++ b/graphics/epix/functions.cc @@ -0,0 +1,398 @@ +/* + * functions.cc -- non-standard mathematical functions + * + * This file is part of ePiX, a preprocessor for creating high-quality + * line figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <cmath> + +#include "constants.h" +#include "errors.h" +#include "deriv.h" + +#include "angle_units.h" +#include "triples.h" + +#include "functions.h" + +namespace ePiX { + + // trig functions with angle units + double Cos(double t) + { + return std::cos(the_angle_style().to_radians(t)); + } + + double Sin(double t) + { + return std::sin(the_angle_style().to_radians(t)); + } + + double Tan(double t) + { + return std::tan(the_angle_style().to_radians(t)); + } + + double Sec(double t) + { + return 1.0/std::cos(the_angle_style().to_radians(t)); + } + + double Csc(double t) + { + return 1.0/std::sin(the_angle_style().to_radians(t)); + } + + double Cot(double t) + { + return 1.0/std::tan(the_angle_style().to_radians(t)); + } + + // and inverses + double Acos(double arg) + { + return std::acos(arg)/the_angle_style().to_radians(1); + } + + double Asin(double arg) + { + return std::asin(arg)/the_angle_style().to_radians(1); + } + + double Atan(double arg) + { + return std::atan(arg)/the_angle_style().to_radians(1); + } + + double Atan2(double y, double x) + { + return std::atan2(y, x)/the_angle_style().to_radians(1); + } + + // Additional hyperbolic tric functions and inverses + double sech(double x) + { + return 1.0/cosh(x); + } + + double csch(double x) + { + return 1.0/sinh(x); + } + + double coth(double x) + { + return 1.0/tanh(x); + } + + double asech(double x) + { + return log((1+sqrt((1-x)*(1+x)))/x); + } + + double acsch(double x) + { + return log((1+sqrt(1+x*x))/x); + } + + double acoth(double x) + { + return 0.5*log((x+1)/(x-1)); + } + + double zero(double arg) + { + return 0; + } + + double zero(double x, double y) + { + return 0; + } + + double zero(double x, double y, double z) + { + return 0; + } + + double zero(const P& arg) + { + return 0; + } + + P xyz(double x, double y, double z) + { + return P(x, y, z); + } + + P cyl(double r, double t, double z) + { + return P(r*Cos(t), r*Sin(t), z); + } + + P sph(double r, double t, double phi) + { + return P(r*(Cos(t))*(Cos(phi)), r*(Sin(t))*(Cos(phi)), r*(Sin(phi))); + } + + P log_log(double x, double y, double z) + { + return P(log10(x), log10(y), z); + } + + P log_lin(double x, double y, double z) + { + return P(log10(x), y, z); + } + + P lin_log(double x, double y, double z) + { + return P(x, log10(y), z); + } + + + // for plot templates, arg mustn't be const P& + P cylindrical(P arg) + { + return cyl(arg.x1(), arg.x2(), arg.x3()); + } + + P spherical(P arg) + { + return sph(arg.x1(), arg.x2(), arg.x3()); + } + + P polar(double r, double t) + { + return cyl(r, t, 0); + } + + P cis(double t) + { + return cyl(1, t, 0); + } + + double recip (double x) + { + return 1.0/x; + } + + // sin(x)/x + double sinx (double x) + { + if (1. + x*x == 1.) // from Don Hatch + return 1.; + else + return Sin(x)/the_angle_style().to_radians(x); + } + + // signum, x/|x|, defined to be 0 at 0 + double sgn (double x) + { + if (x > 0) + return 1; + else if (x < 0) + return -1; + else + return 0; + } + + // Charlie Brown: Period-2 extension of |x| on [-1,1] /\/\/\/\/\/ + double cb (double x) + { + x = fabs(x); + x -= 2*floor(0.5*x); + return min(x, 2-x); + } + + // N.B.: gcd(0,i) = |i| + int gcd (int i, int j) + { + int temp; + + i=abs(i); + j=abs(j); + + if (i==0 || j==0) // (1,0) and (0,1) coprime, others not + return i+j; + + else { + if (j < i) // swap them + { + temp = j; + j=i; + i=temp; + } + // Euclidean algorithm + while ((temp = j%i)) // i does not evenly divide j + { + j=i; + i=temp; + } + + return i; + } + } + + double min(double a, double b) + { + return a < b ? a : b; + } + + double max(double a, double b) + { + return b < a ? a : b; + } + + double snip_to(double var, double arg1, double arg2) + { + if (var < min(arg1, arg2)) + var = min(arg1,arg2); + else if (var > max(arg1, arg2)) + var = max(arg1,arg2); + return var; + } + + // inf and sup of f on [a,b] + double inf (double f(double), double a, double b) + { + const int N((int) ceil(fabs(b-a))); // N >= 1 unless a=b + double y(f(a)); + const double dx((b-a)/(N*EPIX_ITERATIONS)); + + for (unsigned int i=1; i <= N*EPIX_ITERATIONS; ++i) + y = min(y, f(a + i*dx)); + + return y; + } + + double sup (double f(double), double a, double b) + { + const int N((int) ceil(fabs(b-a))); // N >= 1 unless a=b + double y(f(a)); + const double dx((b-a)/(N*EPIX_ITERATIONS)); + + for (unsigned int i=1; i <= N*EPIX_ITERATIONS; ++i) + y = max(y, f(a + i*dx)); + + return y; + } + + // Integral class helper + double integrand(double f(double), double t, double dt) + { + return (1.0/6)*(f(t) + 4*f(t+0.5*dt)+f(t + dt))*dt; + } // Simpson's rule + + Integral::Integral(double func(double), double a) + : f(func), x0(a) { } + + double Integral::eval(double t) const + { + double sum(0); + const int N(16*(int)ceil(fabs(t - x0))); // hardwired constant 16 + + if (N > 0) + { + const double dx((t - x0)/N); + + for (int i=0; i < N; ++i) + sum += integrand(f, x0+i*dx, dx); + } + + return sum; + } + + P Integral::operator() (const P& arg) const + { + double t(arg.x1()); + return P(t, eval(t), 0); + } + + double newton (double f(double), double g(double), double start) + { + double guess(start); + int count(0); // number of iterations + + // Magic number 5 + const int ITERS(5); + while ( (fabs(f(guess)-g(guess)) > EPIX_EPSILON) && (count < ITERS) ) + { + if (fabs(deriv(f, guess)-deriv(g, guess)) < EPIX_EPSILON) + { + epix_warning("Returning critical point in Newton's method"); + return guess; + } + + guess -= (f(guess)-g(guess))/(deriv(f, guess)-deriv(g, guess)); + ++count; + } + + if (count == ITERS) + epix_warning("Maximum number of iterations in Newton's method"); + + return guess; + } + + double newton (double f(double), double start) + { + return newton(f, zero, start); + } + + // Member functions + Deriv::Deriv(double func(double)) + : f(func), dt(EPIX_EPSILON) { } + + Deriv::Deriv(double func(double), double eps) + : f(func), dt(eps) { } + + P Deriv::operator() (const P& arg) const + { + double t(arg.x1()); + return P(t, deriv(f, t, dt), 0); + } + + double Deriv::eval(double t) const + { + return deriv(f, t, dt); + } + + // one-sided derivatives + double Deriv::right(double t) const + { + return (2.0/dt)*(f(t+0.5*dt) - f(t)); + } + + double Deriv::left(double t) const + { + return (2.0/dt)*(f(t) - f(t-0.5*dt)); + } +} // end of namespace diff --git a/graphics/epix/functions.h b/graphics/epix/functions.h new file mode 100644 index 0000000000..40726a8f12 --- /dev/null +++ b/graphics/epix/functions.h @@ -0,0 +1,147 @@ +/* + * functions.h -- ePiX auxiliary functions; Deriv, Integral classes + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.22 + * Last Change: September 24, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_FUNCTIONS +#define EPIX_FUNCTIONS + +namespace ePiX { + + class P; + + // sensitive to angle units + double Cos(double t); + double Sin(double t); + double Tan(double t); + + double Sec(double t); + double Csc(double t); + double Cot(double t); + + double Acos(double t); + double Asin(double t); + double Atan(double t); + + double Atan2(double y, double x); + + // additional hyperbolic functions and inverses + double sech(double); + double csch(double); + double coth(double); + + double asech(double); + double acsch(double); + double acoth(double); + + // zero functions + double zero(double); + double zero(double, double); + double zero(double, double, double); + double zero(const P&); + + // P constructors + P xyz(double x, double y, double z=0); + P cyl(double r, double t, double z); + P sph(double r, double t, double phi); + + // for log data plotting + P log_log(double x, double y, double z=0); + P log_lin(double x, double y, double z=0); + P lin_log(double x, double y, double z=0); + + P cylindrical(P); // not const P& + P spherical(P); + + P polar(double r, double t); + P cis(double t); + + // utility functions + double recip (double); + double sinx (double); // discontinuity removed + double sgn (double); + + // period-2 extension of absolute value on [-1,1]: \/\/\/ + double cb (double); + + int gcd (int, int); + + double min(double, double); + double max(double, double); + + double snip_to(double var, double arg1, double arg2); + + double inf (double f(double), double, double); + double sup (double f(double), double, double); + + + // derivative class + class Deriv { + private: + double (*f)(double); + double dt; + + public: + Deriv(double func(double)); + Deriv(double func(double), double eps); + + P operator() (const P&) const; // for plotting + + // numerical values + double eval(double t) const; + + // one-sided derivatives + double right(double t) const; + double left(double t) const; + }; // end of class Deriv + + + // definite integral class + class Integral { + private: + double (*f)(double); + double x0; // lower limit + + public: + Integral(double func(double), double a=0); + + P operator() (const P&) const; + + double eval(double) const; + }; // end of class Integral + + double newton (double f(double), double g(double), double start); + double newton (double f(double), double start); + +} // end of namespace + +#endif /* EPIX_FUNCTIONS */ diff --git a/graphics/epix/geometry.cc b/graphics/epix/geometry.cc new file mode 100644 index 0000000000..dec6342fc2 --- /dev/null +++ b/graphics/epix/geometry.cc @@ -0,0 +1,804 @@ +/* + * geometry.cc -- spherical and hyperbolic geometry + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.21 + * Last Change: September 22, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <cmath> +#include <vector> + +#include "constants.h" +#include "errors.h" +#include "functions.h" + +#include "triples.h" +#include "frame.h" + +#include "state.h" + +#include "camera.h" + +#include "path.h" + +#include "sphere.h" +#include "curves.h" + +#include "geometry.h" + +namespace ePiX { + + //// Static utility functions //// + + // Flag for type of projection to the sphere + enum sphere_proj_type {RADIAL, STEREO_N, STEREO_S}; + + // point constructor in geographic coords on specified sphere/frame + P sphere_posn(double lat, double lngtd, const Sphere& S, const frame& coords) + { + double rad(S.radius()); + + return S.center() + + rad*Cos(lat)*(Cos(lngtd)*coords.sea() + Sin(lngtd)*coords.sky()) + + rad*Sin(lat)*coords.eye(); + } + + // latitudes and longitudes + void draw_latitude(double lat, double lngtd_min, double lngtd_max, + bool front, const Sphere& S, const frame& coords) + { + P center(S.center() + (S.radius()*Sin(lat)*coords.eye())); + double radius(S.radius()*Cos(lat)); + + path temp(center, radius*coords.sea(), radius*coords.sky(), + lngtd_min, lngtd_max); + + temp.clip_to(S, cam().viewpt(), front); + temp.draw(); + } + + // draw portion of longitude line + void draw_longitude(double lngtd, double lat_min, double lat_max, + bool front, const Sphere& S, const frame& coords) + { + P center(S.center()); + double radius(S.radius()); + + path temp(center, + radius*(Cos(lngtd)*coords.sea()+Sin(lngtd)*coords.sky() ), + radius*coords.eye(), lat_min, lat_max); + + temp.clip_to(S, cam().viewpt(), front); + temp.draw(); + } + + + // Spherical geometry + P proj_to_sphere(const P& arg, const Sphere& S, sphere_proj_type TYPE) + { + P O(S.center()); + double rad(S.radius()); + P loc(arg - O); // location relative to O + + if (TYPE == RADIAL) + return O + (rad/norm(loc))*loc; + + else if (TYPE == STEREO_N) + { + P temp(loc%E_3); + double rho(temp|temp); + return O + (rad/(rho+1))*P(2*temp.x1(), 2*temp.x2(), rho-1); + } + + else if (TYPE == STEREO_S) + { + P temp(loc%E_3); + double rho(temp|temp); + return O + (rad/(rho+1))*P(2*temp.x1(), 2*temp.x2(), 1-rho); + } + + else // Return center on erroneous projection type + return O; + } + + void draw_sphereplot(double f1(double),double f2(double),double f3(double), + double t_min, double t_max, int num_pts, bool front, + sphere_proj_type TYPE, const Sphere& S) + { + std::vector<P> data(num_pts+1); + double t(t_min); + const double dt((t_max - t_min)/num_pts); + + for (int i=0; i <= num_pts; ++i, t += dt) + data.at(i) = proj_to_sphere(P(f1(t), f2(t), f3(t)), S, TYPE); + + path temp(data, false, false); + temp.clip_to(S, cam().viewpt(), front); + temp.draw(); + } // end of draw_sphereplot + + void draw_sphereplot(P Phi(double), double t_min, double t_max, + int num_pts, bool front, sphere_proj_type TYPE, + const Sphere& S) + { + std::vector<P> data(num_pts+1); + double t(t_min); + const double dt((t_max - t_min)/num_pts); + + for (int i=0; i <= num_pts; ++i, t += dt) + data.at(i) = proj_to_sphere(Phi(t), S, TYPE); + + path temp(data, false, false); + temp.clip_to(S, cam().viewpt(), front); + temp.draw(); + } // end of draw_sphereplot + + + // segment mapping class + class seg { + public: + seg(const P& tail, const P& head) + : m_tail(tail), m_head(head) { } + + // so we can be plotted + P operator() (double t) const + { + return m_tail + t*(m_head - m_tail); + } + + private: + P m_tail; + P m_head; + }; // end of class seg + + + // assumes seg contains the actual (scaled, translated) endpoints + void draw_sphere_arc(const seg& sgmt, double t_min, double t_max, + bool front, sphere_proj_type TYPE, const Sphere& S) + { + P tail(sgmt(t_min)), head(sgmt(t_max)); + double cos_theta(((head-S.center())|(tail-S.center()))/pow(S.radius(),2)); + if (1-cos_theta < EPIX_EPSILON) // endpoints equal + return; // draw nothing + + else if (1+cos_theta < EPIX_EPSILON) // endpoints antipodal + { + epix_warning("Spherical arc joins antipodes, no output"); + return; + } + // else + + int num_pts((int) ceil(EPIX_NUM_PTS*Acos(cos_theta)/full_turn())); + if (num_pts < 2) + num_pts=2; + + std::vector<P> data(num_pts+1); + double t(t_min); + const double dt((t_max - t_min)/num_pts); + + P O(S.center()); + double rad(S.radius()); + + for (int i=0; i <= num_pts; ++i, t += dt) + { + P loc(sgmt(t) - O); // location relative to O + data.at(i) = S.center() + rad*recip(norm(loc))*loc; + } + + path temp(data, false, false); + temp.clip_to(S, cam().viewpt(), front); + temp.draw(); + } // end of draw_sphere_arc + + + //// "Geography" and spherical plotting //// + void latitude(double lat, double lngtd_min, double lngtd_max, + const Sphere& S, const frame& coords) + { + draw_latitude(lat, lngtd_min, lngtd_max, true, S, coords); + } + + + void longitude(double lngtd, double lat_min, double lat_max, + const Sphere& S, const frame& coords) + { + draw_longitude(lngtd, lat_min, lat_max, true, S, coords); + } + + void back_latitude(double lat, double lngtd_min, double lngtd_max, + const Sphere& S, const frame& coords) + { + draw_latitude(lat, lngtd_min, lngtd_max, false, S, coords); + } + + void back_longitude(double lngtd, double lat_min, double lat_max, + const Sphere& S, const frame& coords) + { + draw_longitude(lngtd, lat_min, lat_max, false, S, coords); + } + + + // spherical plotting + void frontplot_N(double f1(double), double f2(double), + double t_min, double t_max, int num_pts, + const Sphere& S) + { + draw_sphereplot(f1, f2, zero, t_min, t_max, num_pts, true, STEREO_N, S); + } + + void backplot_N(double f1(double), double f2(double), + double t_min, double t_max, int num_pts, + const Sphere& S) + { + draw_sphereplot(f1, f2, zero, t_min, t_max, num_pts, false, STEREO_N, S); + } + + void frontplot_S(double f1(double), double f2(double), + double t_min, double t_max, int num_pts, + const Sphere& S) + { + draw_sphereplot(f1, f2, zero, t_min, t_max, num_pts, true, STEREO_S, S); + } + + void backplot_S(double f1(double), double f2(double), + double t_min, double t_max, int num_pts, + const Sphere& S) + { + draw_sphereplot(f1, f2, zero, t_min, t_max, num_pts, false, STEREO_S, S); + } + + + // Radial projection from center + void frontplot_R(P phi(double), double t_min, double t_max, + int num_pts, const Sphere& S) + { + draw_sphereplot(phi, t_min, t_max, num_pts, true, RADIAL, S); + } + + void backplot_R(P phi(double), double t_min, double t_max, + int num_pts, const Sphere& S) + { + draw_sphereplot(phi, t_min, t_max, num_pts, false, RADIAL, S); + } + + + //// Spherical geometry -- arcs and polyhedra //// + // arc of great circle between non-antipodal points + void arc(const P& tail, const P& head, const bool front, const Sphere& S) + { + draw_sphere_arc(seg(tail, head), 0, 1, front, RADIAL, S); + } + + + // user-space functions + void front_arc(const P& p1, const P& p2, const Sphere& S) + { + const P ctr(S.center()); + const double rad(S.radius()); + + arc(ctr+(rad/norm(p1))*p1, ctr+(rad/norm(p2))*p2, true, S); + } + + void back_arc(const P& p1, const P& p2, const Sphere& S) + { + const P ctr(S.center()); + const double rad(S.radius()); + + arc(ctr+(rad/norm(p1))*p1, ctr+(rad/norm(p2))*p2, false, S); + } + + // join p1 to -p1 through p2 + void front_arc2(const P& p1, const P& p2, const Sphere& S) + { + front_arc(p1, p2, S); + front_arc(p2, -p1, S); + } + + void back_arc2(const P& p1, const P& p2, const Sphere& S) + { + back_arc(p1, p2, S); + back_arc(p2, -p1, S); + } + + void front_line(const P& p1, const P& p2, const Sphere& S) + { + front_arc( p1, p2, S); + front_arc( p2, -p1, S); + front_arc(-p1, -p2, S); + front_arc(-p2, p1, S); + } + + + void back_line(const P& p1, const P& p2, const Sphere& S) + { + back_arc( p1, p2, S); + back_arc( p2, -p1, S); + back_arc(-p1, -p2, S); + back_arc(-p2, p1, S); + } + + + void front_triangle(const P& p1, const P& p2, const P& p3, const Sphere& S) + { + front_arc(p1, p2, S); + front_arc(p2, p3, S); + front_arc(p3, p1, S); + } + + void back_triangle(const P& p1, const P& p2, const P& p3, const Sphere& S) + { + back_arc(p1, p2, S); + back_arc(p2, p3, S); + back_arc(p3, p1, S); + } + + // local to this file + void front_dual(const P& p1, const P& p2, const P& p3, const Sphere& S) + { + const P ctr(0.3333*(p1+p2+p3)); + + front_arc(ctr, 0.5*(p1+p2), S); + front_arc(ctr, 0.5*(p2+p3), S); + front_arc(ctr, 0.5*(p3+p1), S); + } + + void back_dual(const P& p1, const P& p2, const P& p3, const Sphere& S) + { + const P ctr(0.3333*(p1+p2+p3)); + + back_arc(ctr, 0.5*(p1+p2), S); + back_arc(ctr, 0.5*(p2+p3), S); + back_arc(ctr, 0.5*(p3+p1), S); + } + + + // spherical polyhedra + void front_tetra(const Sphere& S, const frame& coords) + { + const P f1(coords.sea()); + const P f2(coords.sky()); + const P f3(coords.eye()); + + const P ppp( f1+f2+f3); + const P pnn( f1-f2-f3); + const P npn(-f1+f2-f3); + const P nnp(-f1-f2+f3); + + front_triangle(ppp,pnn,npn,S); + front_triangle(ppp,npn,nnp,S); + front_triangle(ppp,nnp,pnn,S); + front_triangle(nnp,pnn,npn,S); + } + void back_tetra(const Sphere& S, const frame& coords) + { + const P f1(coords.sea()); + const P f2(coords.sky()); + const P f3(coords.eye()); + + const P ppp( f1+f2+f3); + const P pnn( f1-f2-f3); + const P npn(-f1+f2-f3); + const P nnp(-f1-f2+f3); + + back_triangle(ppp,pnn,npn,S); + back_triangle(ppp,npn,nnp,S); + back_triangle(ppp,nnp,pnn,S); + back_triangle(nnp,pnn,npn,S); + } + + void front_cube(const Sphere& S, const frame& coords) + { + const P f1(coords.sea()); + const P f2(coords.sky()); + const P f3(coords.eye()); + + const P ppp( f1+f2+f3); + const P npp(-f1+f2+f3); + const P nnp(-f1-f2+f3); + const P pnp( f1-f2+f3); + + const P ppn( f1+f2-f3); + const P npn(-f1+f2-f3); + const P nnn(-f1-f2-f3); + const P pnn( f1-f2-f3); + + front_arc(ppp,npp,S); + front_arc(npp,nnp,S); + front_arc(nnp,pnp,S); + front_arc(pnp,ppp,S); + + front_arc(ppn,npn,S); + front_arc(npn,nnn,S); + front_arc(nnn,pnn,S); + front_arc(pnn,ppn,S); + + front_arc(ppp,ppn,S); + front_arc(npp,npn,S); + front_arc(nnp,nnn,S); + front_arc(pnp,pnn,S); + } + void back_cube(const Sphere& S, const frame& coords) + { + const P f1(coords.sea()); + const P f2(coords.sky()); + const P f3(coords.eye()); + + const P ppp( f1+f2+f3); + const P npp(-f1+f2+f3); + const P nnp(-f1-f2+f3); + const P pnp( f1-f2+f3); + + const P ppn( f1+f2-f3); + const P npn(-f1+f2-f3); + const P nnn(-f1-f2-f3); + const P pnn( f1-f2-f3); + + back_arc(ppp,npp,S); + back_arc(npp,nnp,S); + back_arc(nnp,pnp,S); + back_arc(pnp,ppp,S); + + back_arc(ppn,npn,S); + back_arc(npn,nnn,S); + back_arc(nnn,pnn,S); + back_arc(pnn,ppn,S); + + back_arc(ppp,ppn,S); + back_arc(npp,npn,S); + back_arc(nnp,nnn,S); + back_arc(pnp,pnn,S); + } + + void front_octa(const Sphere& S, const frame& coords) + { + const P p1(coords.sea()); + const P p2(coords.sky()); + const P p3(coords.eye()); + + const P m1(-coords.sea()); + const P m2(-coords.sky()); + const P m3(-coords.eye()); + + // draw "even parity" triangles only + front_triangle(p1,p2,p3,S); + front_triangle(m1,m2,p3,S); + + front_triangle(m1,p2,m3,S); + front_triangle(p1,m2,m3,S); + } + void back_octa(const Sphere& S, const frame& coords) + { + const P p1(coords.sea()); + const P p2(coords.sky()); + const P p3(coords.eye()); + + const P m1(-coords.sea()); + const P m2(-coords.sky()); + const P m3(-coords.eye()); + + // draw "even parity" triangles only + back_triangle(p1,p2,p3,S); + back_triangle(m1,m2,p3,S); + + back_triangle(m1,p2,m3,S); + back_triangle(p1,m2,m3,S); + } + + + void front_dodeca(const Sphere& S, const frame& coords) + { + const P f1(coords.sea()); + const P f2(coords.sky()); + const P f3(coords.eye()); + const double gam(0.5*(1+sqrt(5))); + + const P pop( gam*f1 + f3); + const P pom( gam*f1 - f3); + const P mom(-gam*f1 - f3); + const P mop(-gam*f1 + f3); + + const P ppo( f1 + gam*f2); + const P pmo( f1 - gam*f2); + const P mmo(-f1 - gam*f2); + const P mpo(-f1 + gam*f2); + + const P opp( f2 + gam*f3); + const P opm( f2 - gam*f3); + const P omm(-f2 - gam*f3); + const P omp(-f2 + gam*f3); + + // faces surrounding pop + front_dual(pop, ppo, opp, S); + front_dual(pop, opp, omp, S); + front_dual(pop, omp, pmo, S); + front_dual(pop, pmo, pom, S); + front_dual(pop, pom, ppo, S); + + // respective reflections about link of pop + front_dual(opp, ppo, mpo, S); + front_dual(omp, opp, mop, S); + front_dual(pmo, omp, mmo, S); + front_dual(pom, pmo, omm, S); + front_dual(ppo, pom, opm, S); + + // and their antipodes + front_dual(mom, omm, mmo, S); + front_dual(mom, opm, omm, S); + front_dual(mom, mpo, opm, S); + front_dual(mom, mop, mpo, S); + front_dual(mom, mmo, mop, S); + + front_dual(omm, pmo, mmo, S); + front_dual(opm, pom, omm, S); + front_dual(mpo, ppo, opm, S); + front_dual(mop, opp, mpo, S); + front_dual(mmo, omp, mop, S); + } + + void back_dodeca(const Sphere& S, const frame& coords) + { + const P f1(coords.sea()); + const P f2(coords.sky()); + const P f3(coords.eye()); + const double gam(0.5*(1+sqrt(5))); + + const P pop( gam*f1 + f3); + const P pom( gam*f1 - f3); + const P mom(-gam*f1 - f3); + const P mop(-gam*f1 + f3); + + const P ppo( f1 + gam*f2); + const P pmo( f1 - gam*f2); + const P mmo(-f1 - gam*f2); + const P mpo(-f1 + gam*f2); + + const P opp( f2 + gam*f3); + const P opm( f2 - gam*f3); + const P omm(-f2 - gam*f3); + const P omp(-f2 + gam*f3); + + // faces surrounding pop + back_dual(pop, ppo, opp, S); + back_dual(pop, opp, omp, S); + back_dual(pop, omp, pmo, S); + back_dual(pop, pmo, pom, S); + back_dual(pop, pom, ppo, S); + + // respective reflections about link of pop + back_dual(opp, ppo, mpo, S); + back_dual(omp, opp, mop, S); + back_dual(pmo, omp, mmo, S); + back_dual(pom, pmo, omm, S); + back_dual(ppo, pom, opm, S); + + // and their antipodes + back_dual(mom, omm, mmo, S); + back_dual(mom, opm, omm, S); + back_dual(mom, mpo, opm, S); + back_dual(mom, mop, mpo, S); + back_dual(mom, mmo, mop, S); + + back_dual(omm, pmo, mmo, S); + back_dual(opm, pom, omm, S); + back_dual(mpo, ppo, opm, S); + back_dual(mop, opp, mpo, S); + back_dual(mmo, omp, mop, S); + } + + + void front_icosa(const Sphere& S, const frame& coords) + { + const P f1(coords.sea()); + const P f2(coords.sky()); + const P f3(coords.eye()); + const double gam(0.5*(1+sqrt(5))); + + const P pop( gam*f1 + f3); + const P pom( gam*f1 - f3); + const P mom(-gam*f1 - f3); + const P mop(-gam*f1 + f3); + + const P ppo( f1 + gam*f2); + const P pmo( f1 - gam*f2); + const P mmo(-f1 - gam*f2); + const P mpo(-f1 + gam*f2); + + const P opp( f2 + gam*f3); + const P opm( f2 - gam*f3); + const P omm(-f2 - gam*f3); + const P omp(-f2 + gam*f3); + + // faces surrounding pop + front_triangle(pop, ppo, opp, S); + front_triangle(pop, opp, omp, S); + front_triangle(pop, omp, pmo, S); + front_triangle(pop, pmo, pom, S); + front_triangle(pop, pom, ppo, S); + + // respective reflections about link of pop + front_triangle(opp, ppo, mpo, S); + front_triangle(omp, opp, mop, S); + front_triangle(pmo, omp, mmo, S); + front_triangle(pom, pmo, omm, S); + front_triangle(ppo, pom, opm, S); + + // and their antipodes + front_triangle(mom, omm, mmo, S); + front_triangle(mom, opm, omm, S); + front_triangle(mom, mpo, opm, S); + front_triangle(mom, mop, mpo, S); + front_triangle(mom, mmo, mop, S); + + front_triangle(omm, pmo, mmo, S); + front_triangle(opm, pom, omm, S); + front_triangle(mpo, ppo, opm, S); + front_triangle(mop, opp, mpo, S); + front_triangle(mmo, omp, mop, S); + } + + void back_icosa(const Sphere& S, const frame& coords) + { + const P f1(coords.sea()); + const P f2(coords.sky()); + const P f3(coords.eye()); + const double gam(0.5*(1+sqrt(5))); + + const P pop( gam*f1 + f3); + const P pom( gam*f1 - f3); + const P mom(-gam*f1 - f3); + const P mop(-gam*f1 + f3); + + const P ppo( f1 + gam*f2); + const P pmo( f1 - gam*f2); + const P mmo(-f1 - gam*f2); + const P mpo(-f1 + gam*f2); + + const P opp( f2 + gam*f3); + const P opm( f2 - gam*f3); + const P omm(-f2 - gam*f3); + const P omp(-f2 + gam*f3); + + // faces surrounding pop + back_triangle(pop, ppo, opp, S); + back_triangle(pop, opp, omp, S); + back_triangle(pop, omp, pmo, S); + back_triangle(pop, pmo, pom, S); + back_triangle(pop, pom, ppo, S); + + // respective reflections about link of pop + back_triangle(opp, ppo, mpo, S); + back_triangle(omp, opp, mop, S); + back_triangle(pmo, omp, mmo, S); + back_triangle(pom, pmo, omm, S); + back_triangle(ppo, pom, opm, S); + + // and their antipodes + back_triangle(mom, omm, mmo, S); + back_triangle(mom, opm, omm, S); + back_triangle(mom, mpo, opm, S); + back_triangle(mom, mop, mpo, S); + back_triangle(mom, mmo, mop, S); + + back_triangle(omm, pmo, mmo, S); + back_triangle(opm, pom, omm, S); + back_triangle(mpo, ppo, opm, S); + back_triangle(mop, opp, mpo, S); + back_triangle(mmo, omp, mop, S); + } + + + + // Hyperbolic lines in upper half space + // For compatibility with 2-D geometry, the boundary is the (x1,x3)-plane + + void hyperbolic_line(const P& tail, const P& head) + { + if ( (tail.x2() < 0) || (head.x2() < 0) ) + epix_warning("Endpoint not in upper half-space"); + + P sh_tail(tail%E_2); // shadow of tail + P sh_head(head%E_2); + double ht_tail(tail|E_2), ht_head(head|E_2); + double dist(norm(sh_head - sh_tail)); // dist btw projections to boundary + + if (dist < EPIX_EPSILON) + line(tail, head); + + else + { + // use similar triangles to find center; get basis; draw arc + double diff((ht_head - ht_tail)*(ht_head + ht_tail)/dist); + double frac(0.5*(diff + dist)); + P center((1-frac/dist)*sh_tail + (frac/dist)*sh_head); + P e1(tail - center); + double rad(norm(e1)); + + P e2(E_2%e1); + e2 *= rad/norm(e2); + double theta(Acos(((head-center)|e1)/(rad*rad))); + + ellipse(center, e1, e2, 0, theta); + } + } // end of hyperbolic_line + + + // Lines in Poincare disk model. + // + // Consider the "positive" portion of the standard hyperboloid of two + // sheets: x^2 + y^2 + 1 = z^2, z>0, and consider copies of the unit + // disk in the planes z=0 (D0) and z=1 (D1). The Klein model of the disk + // is gotten by stereographic projection from the origin to D1, while the + // Poincare model is gotten by stereographic projection from (0,0,-1) to + // D0. Appropriate compositions of these projection maps are hyperbolic + // isometries. The algorithm for drawing lines in the disk model is to + // find the images of the endpoints in the Klein model, draw the line + // between them, and map this line back to the Poincare model. Because + // the isometry is "square-root-like" in the radial direction at the + // unit circle, the points on the Klein line are spaced quadratically + // close together at the endpoints of the segment (the variable "s") so + // their images will be roughly equally-spaced in the Poincare model. + // There is no visual harm if one or both endpoints are far from the + // circle, and the result is acceptable if both points are on or near the + // circle. The number of points to draw is determined both by the true + // distance between the endpoints and by how close they are to the circle. + + P poincare_klein(P pt) + { + return (2.0/(1+(pt|pt)))*pt; + } + + P klein_poincare(P pt) + { + return (1.0/(1+sqrt(1-(pt|pt))))*pt; + } + + P p_line(const P& tail, const P& head, double t) + { + double s(0.5*(1+std::cos(M_PI*t))); // s in [0,1] + + P current((s*poincare_klein(tail)) + ((1-s)*poincare_klein(head))); + return klein_poincare(current); + } + + void disk_line(const P& tail, const P& head) + { + const int N(EPIX_NUM_PTS); + std::vector<P> data(N+1); + + double t(0); + + for (int i=0; i <= N; ++i, t += 1.0/N) + data.at(i) = p_line(tail, head, t); + + path temp(data, false, false); + temp.draw(); + } + +} // end of namespace diff --git a/graphics/epix/geometry.h b/graphics/epix/geometry.h new file mode 100644 index 0000000000..60afb8af9c --- /dev/null +++ b/graphics/epix/geometry.h @@ -0,0 +1,125 @@ +/* + * geometry.h + * + * This file is part of ePiX, a preprocessor for creating high-quality + * line figures in LaTeX + * + * Version 1.1.6 + * Last Change: June 28, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_GEOMETRY +#define EPIX_GEOMETRY + +#include "frame.h" +#include "sphere.h" + +namespace ePiX { + class P; + + // latitude, longitude lines with hiding + void latitude(double lat, double long_min, double long_max, + const Sphere& S=Sphere(), const frame& coords=frame()); + + void longitude(double lngtd, double lat_min, double lat_max, + const Sphere& S=Sphere(), const frame& coords=frame()); + + void back_latitude(double lat, double long_min, double long_max, + const Sphere& S=Sphere(), const frame& coords=frame()); + + void back_longitude(double lngtd, double lat_min, double lat_max, + const Sphere& S=Sphere(), const frame& coords=frame()); + + + // stereographic projection; path first projected vertically + void frontplot_N(double f1(double), double f2(double), + double t_min, double t_max, int num_pts, + const Sphere& S = Sphere()); + + void backplot_N(double f1(double), double f2(double), + double t_min, double t_max, int num_pts, + const Sphere& S = Sphere()); + + void frontplot_S(double f1(double), double f2(double), + double t_min, double t_max, int num_pts, + const Sphere& S = Sphere()); + + void backplot_S(double f1(double), double f2(double), + double t_min, double t_max, int num_pts, + const Sphere& S = Sphere()); + + // Radial projection from center + void frontplot_R(P phi(double), double t_min, double t_max, + int num_pts, const Sphere& S = Sphere()); + + void backplot_R(P phi(double), double t_min, double t_max, + int num_pts, const Sphere& S = Sphere()); + + + // All sphere line functions treat point arguments as unscaled + // displacements from the center of the sphere, not as absolute + // spatial locations. If the center or radius of the sphere + // changes, the line automatically adjusts as expected. + + // front portion of spherical segment joining p1 to p2 + void front_arc(const P& p1, const P& p2, const Sphere& S = Sphere()); + void back_arc(const P& p1, const P& p2, const Sphere& S = Sphere()); + + // half-line joining p1 to -p1 through p2 + void front_arc2(const P&, const P&, const Sphere& S=Sphere()); + void back_arc2(const P&, const P&, const Sphere& S=Sphere()); + + // great circle through p1 and p2 + void front_line(const P&, const P&, const Sphere& S=Sphere()); + void back_line(const P&, const P&, const Sphere& S=Sphere()); + + void front_triangle(const P&, const P&, const P&, const Sphere& S=Sphere()); + void back_triangle(const P&, const P&, const P&, const Sphere& S=Sphere()); + + // spherical polyhedra + void front_tetra(const Sphere& S=Sphere(), const frame& coords=frame()); + void back_tetra(const Sphere& S=Sphere(), const frame& coords=frame()); + + void front_cube(const Sphere& S=Sphere(), const frame& coords=frame()); + void back_cube(const Sphere& S=Sphere(), const frame& coords=frame()); + + void front_octa(const Sphere& S=Sphere(), const frame& coords=frame()); + void back_octa(const Sphere& S=Sphere(), const frame& coords=frame()); + + void front_dodeca(const Sphere& S=Sphere(), const frame& coords=frame()); + void back_dodeca(const Sphere& S=Sphere(), const frame& coords=frame()); + + void front_icosa(const Sphere& S=Sphere(), const frame& coords=frame()); + void back_icosa(const Sphere& S=Sphere(), const frame& coords=frame()); + + // Hyperbolic lines + void hyperbolic_line (const P&, const P&); + void disk_line (const P&, const P&); + +} // end of namespace + +#endif /* EPIX_GEOMETRY */ diff --git a/graphics/epix/glyph.cc b/graphics/epix/glyph.cc new file mode 100644 index 0000000000..db4e0f2b37 --- /dev/null +++ b/graphics/epix/glyph.cc @@ -0,0 +1,145 @@ +/* + * glyph.cc -- ePiX screen implemenation for labels and markers + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.22 + * Last Change: September 24, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <cmath> +#include <sstream> + +#include "constants.h" +#include "angle_units.h" + +#include "functions.h" + +#include "pairs.h" +#include "affine.h" +#include "screen_mask.h" + +#include "length.h" + +#include "marker_style.h" +#include "label_style.h" + +#include "format.h" +#include "state.h" + +#include "picture_data.h" +#include "picture.h" + +#include "glyph.h" + +namespace ePiX { + + glyph::glyph(const pair& here, const pair& offset, + const std::string& label, const epix_mark_type mark, + const marker_sizes& sizes, + const label_state& style, const bool seen) + : m_here(here), m_offset(offset), + m_label(label), m_mark(mark), m_sizes(sizes), + m_style(style), m_seen(seen) { } + + glyph& glyph::map_by(const affine& f) + { + m_here = f(m_here); // new location + + // map offset, preserving length + const double old_norm(norm(m_offset)); + m_offset = f(m_offset) - f(pair(0,0)); // new displacement + + const double new_norm(norm(m_offset)); + if (EPIX_EPSILON < new_norm) + m_offset *= old_norm/new_norm; // scale to preserve page length + + // compute new label angle; work in radians for safety/efficiency + const double th(PI_180*m_style.label_angle()); // old angle in radians + + // new baseline direction + const pair tmp_dir(f(pair(std::cos(th), std::sin(th))) - f(pair(0,0))); + + // no change if old baseline maps to zero + if (EPIX_EPSILON < norm(tmp_dir)) + { + // new angle in current units + double theta(Atan2(tmp_dir.x2(), tmp_dir.x1())); + + // effectively, reflect label; works well stylistically + if (f.reverses_orientation()) + theta -= 0.5*full_turn(); + + m_style.label_angle(theta); + } + + return *this; + } + + glyph& glyph::crop_to(const screen_mask& M) + { + if (M.crops(m_here)) + m_seen = false; + + return *this; + } + + glyph* glyph::clone() const + { + return new glyph(*this); + } + + bool glyph::is_empty() const + { + return !m_seen; + } + + + std::string glyph::print_to(const format& fmt, const std::string& len) const + { + if (is_empty()) + return ""; + + std::stringstream obuf; + // print (masked) label, if any, before mark. + if (m_label != "") + obuf << fmt.print_text(m_here, m_offset, m_label, m_style, len); + + if (m_mark != TEXT && m_mark != PATH) + obuf << fmt.print_mark(m_here, m_offset, m_mark, m_sizes, m_style, len); + + return obuf.str(); + } + + void glyph::add_to_pallet() const + { + the_picture().add_to_pallet(m_style.text_color()) + .add_to_pallet(m_style.mask_color()) + .add_to_pallet(m_style.label_border().color()); + } +} // end of namespace diff --git a/graphics/epix/glyph.h b/graphics/epix/glyph.h new file mode 100644 index 0000000000..44f7fb8cec --- /dev/null +++ b/graphics/epix/glyph.h @@ -0,0 +1,85 @@ +/* + * glyph.h -- ePiX screen implemenation for labels and markers + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.18 + * Last Change: September 16, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_GLYPH +#define EPIX_GLYPH + +#include <string> + +#include "pairs.h" +#include "length.h" +#include "Color.h" + +#include "marker_style.h" +#include "label_style.h" +#include "tile.h" + +namespace ePiX { + + class format; + class affine; + class screen_mask; + + class glyph : public tile { + public: + // location, offsets, contents, mark type, visibility + glyph(const pair& here, const pair& offset, + const std::string& label, const epix_mark_type mark, + const marker_sizes& sizes, + const label_state& style, const bool seen); + + glyph& map_by(const affine&); + glyph& crop_to(const screen_mask&); + + glyph* clone() const; + + bool is_empty() const; + + std::string print_to(const format&, const std::string&) const; + void add_to_pallet() const; + + private: + pair m_here; + pair m_offset; + + std::string m_label; + epix_mark_type m_mark; + + marker_sizes m_sizes; + label_state m_style; + + bool m_seen; + }; // end of class glyph + +} // end of namespace + +#endif /* EPIX_GLYPH */ diff --git a/graphics/epix/halfspace.cc b/graphics/epix/halfspace.cc new file mode 100644 index 0000000000..4be13a979c --- /dev/null +++ b/graphics/epix/halfspace.cc @@ -0,0 +1,67 @@ +/* + * halfspace.cc -- ePiX::halfspace class for clipping + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.8 + * Last Change: July 17, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <list> + +#include "triples.h" +#include "edge_data.h" +#include "crop_algorithms.h" + +#include "halfspace.h" + +namespace ePiX { + + halfspace::halfspace(const P& base, const P& perp) + : m_base(base), m_perp((1.0/norm(perp))*perp) { } + + halfspace& halfspace::reverse() + { + m_perp *= -1; + return *this; + } + + bool halfspace::clips(const P& arg) const + { + return height(m_perp, m_base, arg) < -EPIX_EPSILON; + } + + std::list<edge3d>& halfspace::clip_path(std::list<edge3d>& L) const + { + return chop_path<P>(m_perp, m_base, L); + } + + std::list<edge3d>& halfspace::clip_loop(std::list<edge3d>& L) const + { + return chop_loop<P>(m_perp, m_base, L); + } +} // end of namespace diff --git a/graphics/epix/halfspace.h b/graphics/epix/halfspace.h new file mode 100644 index 0000000000..44f4a8a89c --- /dev/null +++ b/graphics/epix/halfspace.h @@ -0,0 +1,67 @@ +/* + * halfspace.h -- ePiX::halfspace class for clipping + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.8 + * Last Change: July 17, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file provides the halfspace class for path clipping. + * A halfspace contains a base point p and a unit vector n, and defines the + * affine half space (x-p)|n > 0; n points "inward". + */ +#ifndef EPIX_HALFSPACE +#define EPIX_HALFSPACE + +#include <list> + +#include "triples.h" +#include "edge_data.h" + +namespace ePiX { + + class halfspace { + public: + halfspace(const P& base, const P& perp); + + halfspace& reverse(); + + bool clips(const P&) const; + + std::list<edge3d>& clip_path(std::list<edge3d>&) const; + std::list<edge3d>& clip_loop(std::list<edge3d>&) const; + + private: + P m_base; + P m_perp; + }; // end of class halfspace +} // end of namespace + +#endif /* EPIX_HALFSPACE */ diff --git a/graphics/epix/hatching.cc b/graphics/epix/hatching.cc new file mode 100644 index 0000000000..00fe64b7a3 --- /dev/null +++ b/graphics/epix/hatching.cc @@ -0,0 +1,258 @@ +/* + * hatching.cc -- ePiX's internal data for filled polygons + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <list> +#include <vector> +#include <cmath> + +#include "errors.h" + +#include "constants.h" +#include "functions.h" +#include "pairs.h" + +#include "edge_data.h" + +#include "state.h" +#include "hatching.h" + +namespace ePiX { + + bd_edge::bd_edge(const edge2d& edge, double ht1, double ht2, int orient) + : m_edge(edge), m_lo(min(ht1, ht2)), m_hi(max(ht1, ht2)), + m_orient(orient) { } + + pair bd_edge::tail() const + { + return m_edge.tail(); + } + + pair bd_edge::head() const + { + return m_edge.head(); + } + + pair bd_edge::dir() const + { + return m_edge.head() - m_edge.tail(); + } + + double bd_edge::lo() const + { + return m_lo; + } + + double bd_edge::hi() const + { + return m_hi; + } + + int bd_edge::orient() const + { + return m_orient; + } + + + cut::cut(pair loc, int sign) + : m_loc(loc), m_sign(sign) { } + + pair cut::loc() const + { + return m_loc; + } + + int cut::sign() const + { + return m_sign; + } + + + // (h-t) assumed unit + scan_line::scan_line(const pair& t, const pair& h) + : m_perp(J(t - h)), m_ht(h.x1()*t.x2() - h.x2()*t.x1()) { } + + + // keep m_cuts sorted by x + void scan_line::add_cut(const cut& crossing) + { + if (EPIX_EPSILON < fabs((m_perp|crossing.loc()) + m_ht)) + return; + + const double x(J(m_perp)|crossing.loc()); + + std::list<cut>::iterator p(m_cuts.begin()); + + while (p != m_cuts.end() && (J(m_perp)|(*p).loc()) < x) + ++p; + + m_cuts.insert(p, crossing); + } + + + // add scans to value + void scan_line::draw(std::vector<edge2d>& value) const + { + std::list<cut>::const_iterator p(m_cuts.begin()); + + if (p == m_cuts.end()) // redundant guard + return; + + int winding((*p).sign()); + + pair start((*p).loc()); + pair end(start); + + while (p != m_cuts.end()) + { + // non-zero winding rule + while (winding != 0 && ++p != m_cuts.end()) + { + end = (*p).loc(); + winding += (*p).sign(); + } + + if (start != end) + value.push_back(edge2d(start, end, true)); + + // seek to next start + while (winding == 0 && ++p != m_cuts.end()) + { + start = (*p).loc(); + winding += (*p).sign(); + } + } + } // end of scan_line::draw + + + // private function; assumes horiz is unit + void hatch_data::hatch_init(const pair& horiz, + double sep, + std::list<edge2d> polygon) + { + const pair vert(J(horiz)); + + // initialize loop with first edge + std::list<edge2d>::iterator p(polygon.begin()); + + // first pass: Get min, max vertex heights; remove horizontal edges + double min_ht((*p).tail()|vert); + double max_ht(min_ht); + + for (p = polygon.begin(); p != polygon.end(); ) // increment at bottom + { + double tmp_tl((*p).tail()|vert); + double tmp_hd((*p).head()|vert); + + if (fabs(tmp_hd - tmp_tl) < EPIX_EPSILON) // horizontal edge + p = polygon.erase(p); + + else + { + // running extrema from head height + min_ht = min(min_ht, tmp_hd); + max_ht = max(max_ht, tmp_hd); + + int up(tmp_tl < tmp_hd ? 1 : -1); // get edge orientation + m_edges.push_back(bd_edge(*p, tmp_tl, tmp_hd, up)); + ++p; + } + } + + // compute subdivision heights, initialize vector of scan_lines + unsigned int num_cuts((unsigned int) ceil((max_ht - min_ht)/sep)); + const double true_sep((max_ht - min_ht)/num_cuts); + + // initialize hatch lines + for (unsigned int i=0; i <= num_cuts; ++i) + { + double ht(min_ht + i*true_sep); + m_scans.push_back(scan_line(ht*vert, horiz + ht*vert)); + } + + // Second pass: add scan line cuts + for (std::list<bd_edge>::iterator ep=m_edges.begin(); + ep != m_edges.end(); ++ep) + { + // indices of scan lines we cross + unsigned int i_min((unsigned int) ceil(((*ep).lo()-min_ht)/true_sep)); + unsigned int i_max((unsigned int) floor(((*ep).hi()-min_ht)/true_sep)); + + // compute parameters once per edge + const pair tl((*ep).tail()); + const pair dir((*ep).dir()); + + // relative heights of endpoints + const double ht_hd((*ep).head()|vert); + const double ht_tl(tl|vert); + + const int up((*ep).orient()); + + for (unsigned int i = i_min; i <= i_max; ++i) + { + const double t((min_ht + i*true_sep - ht_tl)/(ht_hd - ht_tl)); + m_scans.at(i).add_cut(cut(tl + t*dir, up)); + } + } + } // end of hatch_init + + + // user-visible constructors + hatch_data::hatch_data(double dir_x, double dir_y, + double sep, const std::list<edge2d>& polygon) + { + pair dir(dir_x, dir_y); + dir *= 1.0/norm(dir); + + hatch_init(dir, sep, polygon); + } + + hatch_data::hatch_data(double th, double sep, + const std::list<edge2d>& polygon) + { + const double theta(th*PI_180); // th in radians + + // orthonormal basis; horiz along cuts, vert perp to cuts + hatch_init(pair(std::cos(theta), std::sin(theta)), sep, polygon); + } + + + std::vector<edge2d> hatch_data::data() const + { + std::vector<edge2d> value; + + for (unsigned int i=0; i < m_scans.size(); ++i) + m_scans.at(i).draw(value); + + return value; + } +} // end of namespace diff --git a/graphics/epix/hatching.h b/graphics/epix/hatching.h new file mode 100644 index 0000000000..877efde8c8 --- /dev/null +++ b/graphics/epix/hatching.h @@ -0,0 +1,123 @@ +/* + * hatching.h -- ePiX hatched region data structures + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.13 + * Last Change: August 29, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_HATCHING +#define EPIX_HATCHING + +#include <list> +#include <vector> + +#include "pairs.h" +#include "edge_data.h" + +namespace ePiX { + + // edge, endpoint heights, orientation (+/-1 = up/down) + class bd_edge { + public: + bd_edge(const edge2d&, double, double, int); + + pair tail() const; + pair head() const; + pair dir() const; + + double lo() const; + double hi() const; + + int orient() const; + + private: + edge2d m_edge; + + double m_lo; + double m_hi; + + int m_orient; + }; + + // location where scan line crosses bd_edge + class cut { + public: + cut(pair loc, int sign); + + pair loc() const; + int sign() const; + + private: + pair m_loc; // location + int m_sign; // orientation + }; + + // ax + by + c = 0 + class scan_line { + public: + scan_line(const pair& t, const pair& h); + + void add_cut(const cut&); + + // store what we find in value + void draw(std::vector<edge2d>& value) const; + + private: + pair m_perp; // (a, b) + double m_ht; // c + + std::list<cut> m_cuts; + }; // end of class scan_line + + + // ctor converts a list of edge2d into a (large) vector of scan lines + class hatch_data { + public: + // components of hatch direction, scanline separation, polygon to fill + hatch_data(double, double, + double sep, const std::list<edge2d>&); + + // angle, scanline separation, polygon to fill + hatch_data(double th, double sep, const std::list<edge2d>&); + + std::vector<edge2d> data() const; + + private: + std::list<bd_edge> m_edges; + std::vector<scan_line> m_scans; + + // convert polygon to scan lines parallel to dir, common to both ctors + void hatch_init(const pair& dir, + double sep, + std::list<edge2d> polygon); + }; // end of class hatch_data + +} // end of namespace + +#endif /* EPIX_HATCHING */ diff --git a/graphics/epix/install-sh b/graphics/epix/install-sh new file mode 100644 index 0000000000..4d4a9519ea --- /dev/null +++ b/graphics/epix/install-sh @@ -0,0 +1,323 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2005-05-14.22 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + mkdircmd=: + chmodcmd= + else + mkdircmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + shift + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test -d "$pathcomp" || exit + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $mkdircmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit 1; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit 0 +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/graphics/epix/intersections.cc b/graphics/epix/intersections.cc new file mode 100644 index 0000000000..6789e64dbe --- /dev/null +++ b/graphics/epix/intersections.cc @@ -0,0 +1,318 @@ +/* + * intersections.cc -- ePiX's intersection operators + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * Last Change: September 13, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> + +#include "constants.h" +#include "errors.h" + +#include "circle.h" +#include "plane.h" +#include "segment.h" +#include "sphere.h" + +#include "intersections.h" + +namespace ePiX { + + static const double EPS(EPIX_EPSILON); + + Segment operator* (const Circle& arg1, const Circle& arg2) + { + if (arg1.malformed() || arg2.malformed()) + return Segment(true); + + const P p2(arg2.center()); + const P n2(arg2.perp()); + + P dir(p2 - arg1.center()); // displacement between centers + + const double r1(arg1.radius()); + const double r2(arg2.radius()); + const double rad_diff(fabs(r2 - r1)); + const double rad_sum(r2 + r1); + const double sep(norm(dir)); + + if ( EPS < norm(arg1.perp()*arg2.perp()) || // non-coplanar + rad_sum <= sep || // separated + sep <= rad_diff ) // concentric, catches equality + return Segment(true); + + // else + dir *= 1.0/sep; + + const double COS(((r1-r2)*(r1+r2) - sep*sep)/(2*r2*sep)); + const double SIN(sqrt((1-COS)*(1+COS))); + + return Segment(p2 + r2*(COS*dir + SIN*(n2*dir)), + p2 + r2*(COS*dir - SIN*(n2*dir))); + } + + + Segment operator* (const Circle& circ, const Plane& pl) + { + if (circ.malformed() || pl.malformed()) + return Segment(true); + + // else + P bi_perp(circ.perp()*pl.perp()); + const double denom(norm(bi_perp)); + + if (denom < EPS) // parallel + return Segment(true); + + // else + bi_perp *= 1.0/denom; + + const P dir(bi_perp*circ.perp()); // unit vector toward pl in circ plane + + // shortest distance from circ.center() to pl in circ plane + const double x(-((circ.center() - pl.pt())|pl.perp())/(dir|pl.perp())); + + const double rad(circ.radius()); + + if (rad <= fabs(x)) // disjoint + return Segment(true); + + // else + const P vec_y(sqrt((rad-x)*(rad+x))*bi_perp); + const P midpt(circ.center() + x*dir); + + return Segment(midpt - vec_y, midpt + vec_y); + } + + // Extend seg into a line, look for two crossings + Segment operator* (const Circle& circ, const Segment& seg) + { + if (seg.malformed() || circ.malformed()) + return Segment(true); + + // else + const P dir(seg.end2() - seg.end1()); + + if (EPS < fabs(dir|circ.perp())) + return Segment(true); + + // else + P to_ctr(circ.center() - seg.end1()); + P perp(circ.perp()*dir); + + const double dist((to_ctr|perp)/norm(perp)); + const double rad(circ.radius()); + + if (rad <= fabs(dist)) + return Segment(true); + + // else + const P vec_x(circ.center() - (dist/norm(perp))*perp); + const P vec_y((sqrt((rad-dist)*(rad+dist))/norm(dir))*dir); + + return Segment(vec_x + vec_y, vec_x - vec_y); + } + + + // cut plane of circ by S, intersect + Segment operator* (const Circle& circ, const Sphere& S) + { + Plane pl(circ.center(), circ.perp()); + return circ*(pl*S); + } + + Segment operator* (const Plane& pl1, const Plane& pl2) + { + if (pl1.malformed() || pl2.malformed()) + return Segment(true); + + // else + P N3((pl1.perp())*(pl2.perp())); + const double temp(norm(N3)); + + if (temp < EPS) // parallel + return Segment(true); + + // else N3 non-zero, parallel to intersection + N3 *= 1/temp; // normalize + + P perp((pl1.perp())*N3); // unit vector in pl, perp to intersection + P pt(pl1.pt() + (((pl2.pt()-pl1.pt())|pl2.perp())/(perp|pl2.perp()))*perp); + P ctr(pt %= N3); // closest pt to origin on line + // P ctr(pt - (pt|N3)*N3); + + return Segment(ctr - EPIX_INFTY*N3, ctr + EPIX_INFTY*N3); + } + + + P operator* (const Plane& pl, const Segment& seg) + { + if (pl.malformed() || seg.malformed()) + epix_warning("Malformed argument(s) to Plane*Segment"); + + const P tail(seg.end1()); + const P head(seg.end2()); + + const double ptail((tail - pl.pt())|pl.perp()); + const double phead((head - pl.pt())|pl.perp()); + + if (fabs(phead - ptail) < EPS) + epix_warning("Plane parallel to Segment in intersection"); + + return tail + (ptail/(ptail-phead))*(head-tail); + } + + + Circle operator* (const Plane& pl, const Sphere& S) + { + if (pl.malformed() || S.malformed()) + return Circle(true); + + // else + const double rad(S.radius()); + const double ht((pl.pt() - S.center())|pl.perp()); + + if (rad <= fabs(ht)) // disjoint + return Circle(true); + + else + return Circle(S.center() + ht*pl.perp(), + sqrt((rad - ht)*(rad + ht)), + pl.perp()); + } + + + P operator* (const Segment& seg1, const Segment& seg2) + { + if (seg1.malformed() || seg2.malformed()) + epix_warning("Malformed argument(s) in Segment intersection"); + + const P p1(seg1.end1()); + const P dir1(seg1.end2() - p1); + + const P p3(seg2.end1()); + const P p4(seg2.end2()); + const P dir2(p4 - p3); + + P perp(dir1*dir2); + double normal_length(); + + // non-coplanar or parallel + if (EPS < fabs((dir1*(p3 - p1)) | (p4 - p1)) || norm(perp) < EPS) + epix_warning("Non-generic arguments in Segment intersection"); + + // perp lies in plane of segments, is orthog to dir2 + perp *= dir2; + + // get t so that normal|(X - p3) = (normal|(p1 - p3 + t*dir1)) = 0. + // note: X may not lie on either segment + return p1 + ((perp|(p3-p1))/(perp|dir1))*dir1; + } + + // extend seg into a line + Segment operator* (const Segment& seg, const Sphere& S) + { + if (seg.malformed() || S.malformed()) + return Segment(true); + + // else + P dir(seg.end2() - seg.end1()); + dir *= 1.0/norm(dir); + + const P posn(S.center() - seg.end1()); + const P perp(posn%dir); + + if (S.radius() <= norm(perp)) // disjoint + return Segment(true); + + // else + const double B(dir|posn); + const double C((posn|posn)-pow(S.radius(), 2)); + const double discrim(sqrt(B*B - C)); // [sic] + + return Segment(seg.end1() + (B-discrim)*dir, + seg.end1() + (B+discrim)*dir); + } + + Circle operator* (const Sphere& sph1, const Sphere& sph2) + { + if (sph1.malformed() || sph2.malformed()) + return Circle(true); + + // else + const double r1(sph1.radius()); + const double r2(sph2.radius()); + P dir(sph2.center() - sph1.center()); + + const double dist(norm(dir)); + + // separated, tangent, or concentric + if (r1+r2 <= dist || dist <= fabs(r2-r1)) + return Circle(true); + + // else + const double x(0.5*(dist + (r1-r2)*(r1+r2)/dist)); + const P perp((1/dist)*dir); + + return Circle(sph1.center() + x*perp, sqrt((r1-x)*(r1+x)), perp); + } + + + // derived operators + Segment operator* (const Plane& pl, const Circle& circ) + { + return circ*pl; + } + + Segment operator* (const Segment& seg, const Circle& circ) + { + return circ*seg; + } + + Segment operator* (const Sphere& S, const Circle& circ) + { + return circ*S; + } + + P operator* (const Segment& seg, const Plane& pl) + { + return pl*seg; + } + + Circle operator* (const Sphere& S, const Plane& pl) + { + return pl*S; + } + + Segment operator* (const Sphere& S, const Segment& seg) + { + return seg*S; + } +} // end of namespace diff --git a/graphics/epix/intersections.h b/graphics/epix/intersections.h new file mode 100644 index 0000000000..edf7b05569 --- /dev/null +++ b/graphics/epix/intersections.h @@ -0,0 +1,70 @@ +/* + * intersections.h -- Circle, Plane, Segment, Sphere intersection operators + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.9 + * Last Change: July 30, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_INTERSECTIONS +#define EPIX_INTERSECTIONS + +namespace ePiX { + + class Circle; + class Plane; + class Segment; + class Sphere; + + Segment operator* (const Circle&, const Circle&); + Segment operator* (const Circle&, const Plane&); + Segment operator* (const Circle&, const Segment&); + Segment operator* (const Circle&, const Sphere&); + + Segment operator* (const Plane&, const Plane&); + P operator* (const Plane&, const Segment&); + Circle operator* (const Plane&, const Sphere&); + + P operator* (const Segment&, const Segment&); + Segment operator* (const Segment&, const Sphere&); + + Circle operator* (const Sphere&, const Sphere&); + + // derived operators with reversed argument order + Segment operator* (const Plane&, const Circle&); + Segment operator* (const Segment&, const Circle&); + Segment operator* (const Sphere&, const Circle&); + + P operator* (const Segment&, const Plane&); + Circle operator* (const Sphere&, const Plane&); + + Segment operator* (const Sphere&, const Segment&); + +} // end of namespace + +#endif /* EPIX_INTERSECTIONS */ diff --git a/graphics/epix/interval.cc b/graphics/epix/interval.cc new file mode 100644 index 0000000000..11f7a2aace --- /dev/null +++ b/graphics/epix/interval.cc @@ -0,0 +1,228 @@ +/* + * interval.cc -- ePiX::interval class functions + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include <cstdlib> +#include <string> + +#include "functions.h" +#include "interval.h" + +namespace ePiX { + + // expect arg of the form (a,b), [a,b), (a,b], or [a,b] + interval::interval(std::string arg) + : m_closed_l(true), m_closed_r(true) + { + std::string::size_type i(arg.find_first_of("[(")); + + if (i == std::string::npos) // return "empty interval" + { + m_rmin=1; + m_rmax=0; + return; + } + + // else + arg.erase(0, i); + + if (arg.at(0) == '(') + m_closed_l = false; + + // expect numerical argument + i = arg.find_first_of("-0123456789."); + if (i == std::string::npos) + { + m_rmin=1; + m_rmax=0; + return; + } + + arg.erase(0, i); + + // get left endpoint + const char* tmp1(arg.c_str()); + char* new_arg; + m_rmin = strtod(tmp1, &new_arg); + arg=new_arg; + + i = arg.find_first_of(","); + if (i == std::string::npos) + { + m_rmax=0; + m_rmin=1; + return; + } + + arg.erase(0, i); + + // expect another numerical argument + i = arg.find_first_of("-0123456789."); + if (i == std::string::npos) + { + m_rmax=0; + m_rmin=1; + return; + } + + arg.erase(0, i); + + const char* tmp2(arg.c_str()); + m_rmax = strtod(tmp2, &new_arg); + arg=new_arg; + + i = arg.find_first_of(")]"); + + if (i == std::string::npos) + { + m_rmax=0; + m_rmin=1; + return; + } + + if (arg.at(0) == ')') + m_closed_r = false; + } // end of interval(std::string) + + + interval::interval(double a, double b) + : m_rmin(ePiX::min(a, b)), m_rmax(ePiX::max(a, b)), + m_closed_l(true), m_closed_r(true) { } + + interval interval::literal(double a, double b) + { + interval value(a, a); + value.m_rmax = b; + return value; + } + + interval interval::emptyset(literal(1,0)); + + double interval::min() const + { + return m_rmin; + } + + double interval::max() const + { + return m_rmax; + } + + double interval::avg() const + { + return 0.5*(m_rmin + m_rmax); + } + + + // Magic number + const double EPS(1.0e-10); + + bool interval::contains(double x) const + { + // check bounds at each endpoint + return ( (m_closed_l ? (m_rmin - EPS <= x) : (m_rmin + EPS < x)) + && (m_closed_r ? (x <= m_rmax + EPS) : (x < m_rmax - EPS)) ); + } + + // Minkowski sum + interval& interval::operator +=(const interval& I) + { + if (is_empty()) + ; + + else if (I.is_empty()) + *this = interval::emptyset; + + else + { + m_rmin += I.m_rmin; + m_rmax += I.m_rmax; + + // sum contains endpoint iff both arguments do + m_closed_l &= I.m_closed_l; + m_closed_r &= I.m_closed_r; + } + + return *this; + } + + // intersection + interval& interval::operator *=(const interval& I) + { + if (!is_empty()) + { + m_rmin = ePiX::max(m_rmin, I.m_rmin); + m_rmax = ePiX::min(m_rmax, I.m_rmax); + + m_closed_l &= I.m_closed_l; + m_closed_r &= I.m_closed_r; + } + + return *this; + } + + bool interval::operator== (const interval& I) const + { + if (is_empty()) + return (I.is_empty()); // both empty? + + else + return ((m_rmin == I.m_rmin) && (m_rmax == I.m_rmax) + && (m_closed_l == I.m_closed_l) && (m_closed_r == I.m_closed_r)); + } + + bool interval::operator!= (const interval& I) const + { + return !(*this == I); + } + + bool interval::is_empty() const + { + if ( (m_rmin < m_rmax) + || ( (m_rmin == m_rmax) && m_closed_l && m_closed_r ) ) + return false; + + else + return true; + } + + // non-members + interval operator+ (interval I1, const interval& I2) + { + return I1 += I2; + } + + interval operator* (interval I1, const interval& I2) + { + return I1 *= I2; + } + +} // end of namespace diff --git a/graphics/epix/interval.h b/graphics/epix/interval.h new file mode 100644 index 0000000000..465262c4da --- /dev/null +++ b/graphics/epix/interval.h @@ -0,0 +1,81 @@ +/* + * interval.h -- ePiX::interval class and operations + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.0.25 + * Last Change: May 20, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * This file provides the interval class: + * + * - Minkowski sum, intersection + */ + +#ifndef EPIX_INTERVAL +#define EPIX_INTERVAL + +#include <string> + +namespace ePiX { + + class interval { + public: + interval(std::string); // allow implicit conversion, must mangle argument + interval(double, double); // closed interval + + static interval emptyset; + + double min() const; + double max() const; + double avg() const; + + bool contains(double) const; + + // Minkowski sum + interval& operator +=(const interval&); + + // intersection + interval& operator *=(const interval&); + + bool operator== (const interval&) const; + bool operator!= (const interval&) const; + bool is_empty() const; + + private: + double m_rmin, m_rmax; + + bool m_closed_l, m_closed_r; + + static interval literal(double a, double b); // can force b<a + }; // end of interval class + + interval operator+ (interval I1, const interval& I2); + interval operator* (interval I1, const interval& I2); + +} // end of namespace + +#endif /* EPIX_INTERVAL */ diff --git a/graphics/epix/label_data.cc b/graphics/epix/label_data.cc new file mode 100644 index 0000000000..7f0e8b20f2 --- /dev/null +++ b/graphics/epix/label_data.cc @@ -0,0 +1,140 @@ +/* + * label_data.cc -- ePiX::label_data class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.21 + * Last Change: September 22, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <sstream> + +#include "enums.h" + +#include "triples.h" +#include "pairs.h" + +#include "label_data.h" +#include "camera.h" +#include "screen_data.h" +#include "screen.h" + +#include "clipping.h" + +#include "paint_style.h" + +#include "active_screen.h" +#include "glyph.h" + +namespace ePiX { + + label_data::label_data(const P& here, const P& offset, + const std::string& text, epix_mark_type mark) + : m_here(here), m_offset(offset.x1(), offset.x2()), + m_text(text), m_mark(mark), m_sizes(the_mark_size()), + m_style(the_label_style()), m_seen(!the_clip_box().clips(m_here)) + { + // set axis tick color to line color; rotation ok if requested + if (m_mark == HTICK || m_mark == VTICK) + m_style.text_color(the_paint_style().line_color()); + } + + // generate label text from user-specified function of 2 or 3 variables + label_data::label_data(const P& here, const P& offset, + std::string f(double,double), epix_mark_type mark) + : m_here(here), m_offset(offset.x1(), offset.x2()), + m_text(f(here.x1(), here.x2())), + m_mark(mark), m_sizes(the_mark_size()), m_style(the_label_style()), + m_seen(!the_clip_box().clips(m_here)) + { + if (m_mark == HTICK || m_mark == VTICK) + m_style.text_color(the_paint_style().line_color()); + } + + label_data::label_data(const P& here, const P& offset, + std::string f(double,double,double), + epix_mark_type mark) + : m_here(here), m_offset(offset.x1(), offset.x2()), + m_text(f(here.x1(), here.x2(), here.x3())), + m_mark(mark), m_sizes(the_mark_size()), m_style(the_label_style()), + m_seen(!the_clip_box().clips(m_here)) + { + if (m_mark == HTICK || m_mark == VTICK) + m_style.text_color(the_paint_style().line_color()); + } + + // markers subject to masking, border + // Only this constructor aligns TICK marks, prevents their rotation + label_data::label_data(const P& here, epix_mark_type mark, epix_label_posn A) + : m_here(here), m_offset(0, 0), + m_text(""), m_mark(mark), m_sizes(the_mark_size()), + m_style(the_label_style()), m_seen(!the_clip_box().clips(m_here)) + { + if (m_mark == HTICK || m_mark == VTICK) + { + m_style.text_color(the_paint_style().line_color()); + m_style.label_angle(0); // no initial rotation + + // prevent unseemly alignment; default is c, so needn't check + if (m_mark == HTICK && A == t || A == b) + m_style.align_to(A); + + else if (A == l || A == r) + m_style.align_to(A); + } + } + + + label_data& label_data::text_color(const Color& col) + { + m_style.text_color(col); + return *this; + } + + label_data& label_data::mask_color(const Color& col) + { + m_style.mask_color(col); + return *this; + } + + label_data& label_data::align_to(epix_label_posn align) + { + m_style.align_to(align); + return *this; + } + + // send colors through cam + void label_data::draw() const + { + if (m_seen) + (*active_screen()).m_screen->add_tile(glyph(cam()(m_here), m_offset, + m_text, m_mark, m_sizes, + m_style.seen_through(cam()), + true)); + } +} // end of namespace diff --git a/graphics/epix/label_data.h b/graphics/epix/label_data.h new file mode 100644 index 0000000000..53ccd0abe5 --- /dev/null +++ b/graphics/epix/label_data.h @@ -0,0 +1,97 @@ +/* + * label_data.h -- ePiX::label_data class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.18 + * Last Change: September 16, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * label_data comprises spatial location, screen offsets, text (contents), + * mark type, and a label_style (q.v.). label_data can be constructed from + * string-valued functions of position; examples are given below. + */ + +#ifndef EPIX_LABEL +#define EPIX_LABEL + +#include <string> + +#include "enums.h" +#include "triples.h" + +#include "pairs.h" + +#include "marker_style.h" +#include "label_style.h" + +namespace ePiX { + + class Camera; + class Color; + class screen; + + class label_data { + public: + label_data(const P& here, const P& offset, + const std::string& text, epix_mark_type mark=TEXT); + + // generate label text from user-specified function of 2 or 3 variables + label_data(const P& here, const P& offset, + std::string f(double,double), epix_mark_type mark=TEXT); + + label_data(const P& here, const P& offset, + std::string f(double,double,double), epix_mark_type mark=TEXT); + + // marker; alignment affects only TICK marks + label_data(const P& here, epix_mark_type mark, epix_label_posn align=c); + + // pass through to m_style + label_data& text_color(const Color&); + label_data& mask_color(const Color&); + label_data& align_to(epix_label_posn); + + void draw() const; + + private: + P m_here; + pair m_offset; + + std::string m_text; + epix_mark_type m_mark; + + marker_sizes m_sizes; + label_state m_style; + + bool m_seen; + }; // end of label_data class + +} // end of namespace + +#endif /* EPIX_LABEL */ diff --git a/graphics/epix/label_style.cc b/graphics/epix/label_style.cc new file mode 100644 index 0000000000..ddd08f55ec --- /dev/null +++ b/graphics/epix/label_style.cc @@ -0,0 +1,177 @@ +/* + * label_style.cc -- ePiX's current state for text and markers + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.22 + * Last Change: September 24, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <string> + +#include "enums.h" +#include "constants.h" +#include "functions.h" // for snip_to + +#include "angle_units.h" + +#include "Color.h" +#include "camera.h" +#include "length.h" + +#include "label_style.h" + +namespace ePiX { + + // Users can only construct the default style, since label angles + // are specified in current units but stored/returned in degrees. + label_state::label_state() + : the_text_color(Black()), the_mask_color(Neutral()), + the_padding(length(0)), the_label_border(Xfine()), + the_alignment(none), the_fontsize("nsz"), + the_fontface("rm"), + the_angle(0) { } + + // set + void label_state::text_color(const Color& col) + { + the_text_color = col; + } + + void label_state::mask_color(const Color& col) + { + the_mask_color = col; + } + + void label_state::label_padding(const length& len) + { + the_padding=len; + } + + void label_state::label_border(const pen_data& p) + { + the_label_border = p; + } + + void label_state::align_to(const epix_label_posn a) + { + the_alignment = a; + } + + void label_state::fontsize(const std::string& fs) + { + the_fontsize = fs; + } + + void label_state::fontface(const std::string& ff) + { + the_fontface = ff; + } + + // store label rotation angle internally in degrees + void label_state::label_angle(double th) + { + the_angle = the_angle_style().to_degrees(th); + } + + // get + Color label_state::text_color() const + { + return the_text_color; + } + + Color label_state::mask_color() const + { + return the_mask_color; + } + + bool label_state::is_masked() const + { + return !the_mask_color.is_unset(); + } + + length label_state::label_padding() const + { + return the_padding; + } + + pen_data label_state::label_border() const + { + return the_label_border; + } + + epix_label_posn label_state::align_to() const + { + return the_alignment; + } + + // e.g. "scriptsize" + std::string label_state::fontsize() const + { + return the_fontsize; + } + + std::string label_state::fontface() const + { + return the_fontface; + } + + double label_state::label_angle() const + { + return the_angle; + } + + // map us through a camera filter + label_state label_state::seen_through(const Camera& mycam) const + { + return label_state(mycam(the_text_color), mycam(the_mask_color), + the_padding, the_label_border.seen_through(mycam), + the_alignment, the_fontsize, the_fontface, + the_angle); + } + + // private constructor, for seen_through + label_state::label_state(const Color& text, const Color& mask, + const length& pad, const pen_data& border, + const epix_label_posn align, + const std::string& fontsize, + const std::string& fontface, + double th) + : the_text_color(text), the_mask_color(mask), + the_padding(pad), the_label_border(border), + the_alignment(align), the_fontsize(fontsize), + the_fontface(fontface), + the_angle(th) { } + + + label_state& the_label_style() + { + static label_state* the_label_state(new label_state()); + return *the_label_state; + } +} // end of namespace diff --git a/graphics/epix/label_style.h b/graphics/epix/label_style.h new file mode 100644 index 0000000000..3d3461281f --- /dev/null +++ b/graphics/epix/label_style.h @@ -0,0 +1,136 @@ +/* + * label_style.h -- ePiX's current state for text and markers + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.22 + * Last Change: September 24, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file implements label_state: + * + * [] Text and mask color (Color x2) + * [] Alignment (epix_label_posn) + * [] Font face and size (strings) + * [] Label angle (double, in degrees) + * + * The class in this file implements backend for user-level global + * functions defined in state.h, which modify the_label_style(). + * + * This header is not part of epix.h. + */ +#ifndef EPIX_LABEL_STATE +#define EPIX_LABEL_STATE + +#include <string> + +#include "enums.h" + +#include "Color.h" +#include "length.h" + +#include "pen_data.h" + +namespace ePiX { + + class Camera; + + class label_state { + public: + // Clients can only construct the default state: black, unmasked, + // unbordered, basepoint-aligned, unrotated normalsize Roman text. + label_state(); + + // set + void text_color(const Color& col); + void mask_color(const Color& col); + + void label_padding(const length& len); + void label_border(const pen_data& p); + + void align_to(const epix_label_posn a); + + void fontsize(const std::string& fs); + void fontface(const std::string& f); + + // store label rotation angle internally in degrees + void label_angle(double th); + + // get + Color text_color() const; + Color mask_color() const; + + bool is_masked() const; + + length label_padding() const; + pen_data label_border() const; + + epix_label_posn align_to() const; + + // e.g. "scriptsize" + std::string fontsize() const; + std::string fontface() const; + + // return angle in degrees + double label_angle() const; + + // map us through a camera filter + label_state seen_through(const Camera& cam) const; + + private: + Color the_text_color; + Color the_mask_color; + + length the_padding; + pen_data the_label_border; + + epix_label_posn the_alignment; + + std::string the_fontsize; + std::string the_fontface; + + double the_angle; // stored in degrees + + // text and background color, padding, border style, + // alignment, font size and face, angle (degrees) + label_state(const Color& text, + const Color& mask, + const length& pad, + const pen_data& border, + const epix_label_posn align, + const std::string& fontsize, + const std::string& fontface, + double th); + }; // end of label_state + + label_state& the_label_style(); + +} // end of namespace + +#endif /* EPIX_LABEL_STATE */ diff --git a/graphics/epix/laps.1 b/graphics/epix/laps.1 new file mode 100644 index 0000000000..4430a02037 --- /dev/null +++ b/graphics/epix/laps.1 @@ -0,0 +1 @@ +.so man1/epix.1 diff --git a/graphics/epix/laps.in b/graphics/epix/laps.in new file mode 100644 index 0000000000..8c8d8efe0f --- /dev/null +++ b/graphics/epix/laps.in @@ -0,0 +1,259 @@ +#! /bin/bash +# +# laps: latex to Postscript/PDF +# +# Options: --help for usage, --version for version and license +# +# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 +# Andrew D. Hwang <For address, do "laps -V"> +# + +. "@pkglibdir@/epix-lib.sh" + +declare -a DVIPS_OPTS +declare -a LAPS_FILE_LIST +declare -i LAPS_FILE_COUNT + +PS2PDF="ps2pdf" +LATEX="latex" +LAPS_PDF= + +LATEX_INTERACT="batchmode" + +LAPS_EXTENSIONS="tex dtx ltx" # or NULL +LAPS_DOT_EXT=".${LAPS_EXTENSIONS// /|.}" # for usage message +LAPS_DEFAULT_EXT="tex" + +declare -a TMP_CMD + + +function laps_help () +{ +cat <<"HELP" +Options: + -h, --help + Show this message and exit + + -V, --version, --gpl + Show version and license + + -v, --verbose + Scroll output/error messages + + -H, --huge + Use hugelatex (if available) + + -i, -int, --interactive + Run (La)TeX interactively (implies --verbose) + + -n, --no-config + Ignore $(HOME)/.dvipsrc + + --pdf + Post-process ps file with ps2pdf + + --pdf(la)tex + Use pdf(la)tex instead of latex. + + -ps, --ps, --pslatex + Use pslatex instead of latex. + + -P<printer> + dvips printer options, e.g. "-Pamz", may be given on the command + line. They are also read from ~/.dvipsrc if this file exists. + + -t, --tex + Use tex instead of latex + +HELP +ePiX_bugreport + +} # End of laps_help + + +function laps_parse_options { +# Command-line options start with "-" +while [ "$1" != "${1#-}" ]; do + case "$1" in + + -h|--help) + ePiX_usage laps $LAPS_DOT_EXT + laps_help + exit 0 + ;; + + -H|--huge) + if [ $(which hugelatex 2> /dev/null) ]; then + LATEX="hugelatex" + else + ePiX_warn " hugelatex not available, ignoring \"$1\" option" + fi + shift + ;; + + -i|-int|--interactive) + EPIX_STDOUT="$SYSTEM_STDOUT" + LATEX_INTERACT="scrollmode" + shift + ;; + + -n|--no-config) # do not use ~/.dvipsrc + export DVIPSRC="$SYSTEM_DEVNULL" + shift + ;; + + -pdf|--pdf) + LATEX="${LATEX##pdf}" + LAPS_PDF="yes" + shift + ;; + + --pdflatex) + LATEX="pdflatex" + LAPS_PDF="" + shift + ;; + + --pdftex) + LATEX="pdftex" + LAPS_PDF="" + shift + ;; + + -ps|--ps|--pslatex) + LATEX="pslatex" + shift + ;; + + -P) + DVIPS_OPTS=("${DVIPS_OPTS[@]}" "-P$2") + shift 2 + ;; + + -P*) + DVIPS_OPTS=("${DVIPS_OPTS[@]}" "$1") + shift + ;; + + -t|--tex) + LATEX="tex" + shift + ;; + + -V|--version|--gpl) + ePiX_version laps + ePiX_license + exit 0 + ;; + + -v|--verbose) + if [ -z "$2" ]; then + echo "Please use -V for version" + exit 0 + fi + EPIX_STDOUT="$SYSTEM_STDOUT" + shift + ;; + + -vv) + echo "Discontinued option -vv; please use -v for verbose output" + exit 0 + ;; + + *) + ePiX_warn "Ignoring unknown option \"$1\"" + shift + ;; + esac +done + +LAPS_FILE_LIST=("$@") +} # End of laps_parse_options + + +function laps_compile_files() +{ + if [ -z "$1" ]; then ePiX_die "No input file specified"; fi + + # file counts + local processed=0 + local success=0 + local failure=0 + + for EPIX_INFILE in "${LAPS_FILE_LIST[@]}"; do + + # sets EPIX_INROOT, EPIX_SUFFIX, EPIX_NOTFOUND, touches EPIX_LOGFILE + epix_parse_filename "$EPIX_INFILE" "$LAPS_EXTENSIONS" + + let processed=processed+1 + + if [ "$EPIX_NOTFOUND" = "yes" ]; then + let failure=failure+1 + continue + fi + + TMP_CMD=($LATEX -interaction=$LATEX_INTERACT "$EPIX_INROOT.$EPIX_SUFFIX") + TEMPFILES=("{TEMPFILES[@]}" "${EPIX_INROOT}.dvi" "${EPIX_INROOT}.log") + + # aux file out of date + if [ "$EPIX_INROOT.$EPIX_SUFFIX" -nt "$EPIX_INROOT.aux" ]; then + ePiX_msg "aux file out of date" + + ePiX_command "${TMP_CMD[@]}" + fi + + ePiX_command "${TMP_CMD[@]}" + + if [ "${EPIX_INROOT}.$EPIX_SUFFIX" -nt "$EPIX_INROOT.dvi" ]; then + ePiX_warn "\"${TMP_CMD[*]}\" failed" + let failure=failure+1 + continue + fi + + if [ "$LATEX" = "latex" -o "$LATEX" = "tex" ]; then + TMP_CMD=(dvips "${DVIPS_OPTS[@]}" -f -o "$EPIX_INROOT.ps" "$EPIX_INROOT.dvi") + + ePiX_command "${TMP_CMD[@]}" + + if [ "$EPIX_INROOT.dvi" -nt "$EPIX_INROOT.ps" ]; then + ePiX_warn "${TMP_CMD[*]} failed" + let failure=failure+1 + continue + fi + fi + + if [ "$LAPS_PDF" = "yes" ]; then + TMP_CMD=($PS2PDF "$EPIX_INROOT.ps") + + ePiX_command "${TMP_CMD[@]}" + + if [ "$EPIX_INROOT.ps" -nt "$EPIX_INROOT.pdf" ]; then + ePiX_warn "${TMP_CMD[*]} failed" + let failure=failure+1 + continue + fi + fi + + let success=success+1 + echo -e "\nTranscript written on $EPIX_LOGFILE" > "$EPIX_STDOUT" + + done # for EPIX_INFILE in $LAPS_INFILE_LIST + + if [ $processed -gt 1 ]; then + echo "$processed files processed: $success successfully, $failure failed" > "$EPIX_STDERR" + fi +} + +### main ### + +if [ $# -eq 0 ]; then + ePiX_usage laps $LAPS_DOT_EXT + laps_help + exit 0 +fi + +laps_parse_options "$@" + +laps_compile_files "${LAPS_FILE_LIST[@]}" + +exit 0 diff --git a/graphics/epix/legend.cc b/graphics/epix/legend.cc new file mode 100644 index 0000000000..8f9b7c2054 --- /dev/null +++ b/graphics/epix/legend.cc @@ -0,0 +1,204 @@ +/* + * legend.cc -- ePiX legend class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.1 + * Last Change: September 28, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +// #include <cmath> +#include <string> +#include <sstream> +#include <list> + +#include "constants.h" + +#include "triples.h" + +#include "Color.h" + +#include "length.h" + +#include "camera.h" + +#include "curves.h" + +#include "screen.h" +#include "active_screen.h" +#include "screen_data.h" + +#include "label_data.h" +#include "markers.h" + +#include "legend_item.h" +#include "legend_tile.h" +#include "legend.h" + +namespace ePiX { + + legend::legend() + : m_backing(White()), + m_bord(Black()), m_bord_width(PLAIN_WIDTH.magnitude()), + m_item_bord(Black()), m_item_bord_width(0.5*PLAIN_WIDTH.magnitude()), + m_key_size(12), m_label_skip(6) { } + + legend::legend(const legend& L) + : m_backing(L.m_backing), m_bord(L.m_bord), m_bord_width(L.m_bord_width), + m_item_bord(L.m_item_bord), m_item_bord_width(L.m_item_bord_width), + m_key_size(L.m_key_size), m_label_skip(L.m_label_skip) + { + for (std::list<legend_item*>::const_iterator ip = L.m_items.begin(); + ip != L.m_items.end(); ++ip) + m_items.push_back((*ip)->clone()); + } + + legend& legend::operator=(const legend& L) + { + if (&L != this) + { + std::list<legend_item*> tmp; + for (std::list<legend_item*>::const_iterator ip = L.m_items.begin(); + ip != L.m_items.end(); ++ip) + tmp.push_back((*ip)->clone()); + + m_backing = L.m_backing; + m_bord = L.m_bord; + m_bord_width = L.m_bord_width; + + m_item_bord = L.m_item_bord; + m_item_bord_width = L.m_item_bord_width; + + m_key_size = L.m_key_size; + m_label_skip = L.m_label_skip; + + swap(m_items, tmp); + } + + return *this; + } + + legend::~legend() + { + for (std::list<legend_item*>::iterator ip = m_items.begin(); + ip != m_items.end(); ++ip) + delete *ip; + } + + // add items + legend& legend::fill_item(const std::string& text) + { + m_items.push_back(new ePiX::fill_item(text)); + return *this; + } + + legend& legend::path_item(const std::string& text) + { + m_items.push_back(new ePiX::path_item(text)); + return *this; + } + + legend& legend::mark_item(epix_mark_type mark, const std::string& text) + { + m_items.push_back(new ePiX::mark_item(mark, text)); + return *this; + } + + // decorations + legend& legend::backing(const Color& col) + { + m_backing = col; + return *this; + } + + legend& legend::border(const Color& col, double len) + { + m_bord = col; + m_bord_width = len; + + return *this; + } + + legend& legend::border(double len) + { + m_bord = Black(); + m_bord_width = len; + + return *this; + } + + // item attributes + legend& legend::item_border(const Color& col, double len) + { + m_item_bord = col; + m_item_bord_width = len; + + return *this; + } + + legend& legend::item_border(double len) + { + m_item_bord = Black(); + m_item_bord_width = len; + + return *this; + } + + legend& legend::key_size(double len) + { + m_key_size = len; + return *this; + } + + legend& legend::label_skip(double len) + { + m_label_skip = len; + return *this; + } + + void legend::draw(const P& loc, const P& off, epix_label_posn align) const + { + std::list<legend_item*>::const_iterator ip(m_items.begin()); + if (ip == m_items.end()) + return; + + // else + label_state ls(the_label_style()); + ls.mask_color(m_backing); + ls.label_border(pen_data(m_bord, length(m_bord_width))); + ls.align_to(align); + + active_screen()->m_screen + ->add_tile(legend_tile(pair(loc.x1(), loc.x2()), + pair(off.x1(), off.x2()), + align, + ls.seen_through(cam()), + pen_data(cam()(m_item_bord), + length(m_item_bord_width)), + m_key_size, m_label_skip, m_items)); + } +} // end of namespace diff --git a/graphics/epix/legend.h b/graphics/epix/legend.h new file mode 100644 index 0000000000..ca7e096015 --- /dev/null +++ b/graphics/epix/legend.h @@ -0,0 +1,94 @@ +/* + * legend.h -- Plot/figure legend class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.11 + * Last Change: August 16, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_LEGEND +#define EPIX_LEGEND + +#include <string> + +#include "enums.h" + +#include "Color.h" + +namespace ePiX { + + class legend_item; + class P; + + class legend { + public: + legend(); + + legend(const legend&); + + legend& operator=(const legend&); + + ~legend(); + + // add items; get key style from drawing state + legend& fill_item(const std::string&); // solid color + legend& path_item(const std::string&); // line + legend& mark_item(epix_mark_type, const std::string&); // marker + + // decorations + legend& backing(const Color&); + legend& border(const Color&, double); + legend& border(double); // line width in pt + + // item attributes + legend& item_border(const Color&, double); + legend& item_border(double); + + legend& label_skip(double); // + legend& key_size(double); // size of legend keys in pt + + void draw(const P& loc, const P& offset=P(0,0), + epix_label_posn align=tr) const; + + private: + Color m_backing; + Color m_bord; + double m_bord_width; + + Color m_item_bord; + double m_item_bord_width; + + double m_key_size; + double m_label_skip; + + std::list<legend_item*> m_items; + }; // end of legend class + +} // end of namespace + +#endif /* EPIX_LEGEND */ diff --git a/graphics/epix/legend_item.cc b/graphics/epix/legend_item.cc new file mode 100644 index 0000000000..afbc5a8b65 --- /dev/null +++ b/graphics/epix/legend_item.cc @@ -0,0 +1,166 @@ +/* + * legend_item.cc -- ePiX legend_item implementations + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.18 + * Last Change: September 16, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <string> +#include <sstream> + +#include "enums.h" +#include "Color.h" +#include "pen_data.h" + +#include "pairs.h" +#include "edge_data.h" + +#include "camera.h" + +#include "format.h" + +#include "label_data.h" +#include "markers.h" + +#include "paint_style.h" + +#include "screen_data.h" +#include "glyph.h" +#include "pen_line.h" + +#include "legend_item.h" + +namespace ePiX { + + // Magic numbers + screen_data __epix_legend_key(double L) + { + return screen_data(pair(0, -0.075*L), pair(L, 0.925*L)); + } + + double legend_item::key_coord(double sz, const std::string& len) const + { + return sz*(length("1pt").to(len).magnitude()); + } + + + // N.B. store raw fill color; "key" passes through camera + fill_item::fill_item(const std::string& text) + : m_fill(the_paint_style().fill_color()), m_text(text) { } + + fill_item* fill_item::clone() const + { + return new fill_item(*this); + } + + std::string fill_item::value() const + { + return m_text; + } + + std::string fill_item::key(const format& fmt, double sz, + const pen_data& bpen, + const std::string& len) const + { + const double L(legend_item::key_coord(sz, len)); + + screen_data tmp(__epix_legend_key(L)); + + tmp.backing(m_fill).border(bpen.color(), bpen.width().name()); + + return tmp.print_to(fmt, len, true); + } + + + // N.B. Store pens passed through camera + path_item::path_item(const std::string& text) + : m_line(the_paint_style().line_pen().seen_through(cam())), + m_base(the_paint_style().base_pen().seen_through(cam())), + m_text(text) { } + + path_item* path_item::clone() const + { + return new path_item(*this); + } + + std::string path_item::value() const + { + return m_text; + } + + std::string path_item::key(const format& fmt, double sz, + const pen_data& bpen, + const std::string& len) const + { + const double L(legend_item::key_coord(sz, len)); + + screen_data tmp(__epix_legend_key(L)); + tmp.border(bpen.color(), bpen.width().name()); + + // draw a centered horizontal segment in the current line style + // Magic numbers + std::list<edge2d> edges; + edges.push_back(edge2d(tmp.l(), tmp.r(), true)); + + tmp.add_tile(pen_line(m_line, m_base, edges)); + return tmp.print_to(fmt, len, true); + } + + + // key is a marker in the current style + mark_item::mark_item(epix_mark_type mark, const std::string& text) + : m_mark(mark), m_style(the_label_style().seen_through(cam())), + m_sizes(the_mark_size()), m_text(text) { } + + mark_item* mark_item::clone() const + { + return new mark_item(*this); + } + + std::string mark_item::value() const + { + return m_text; + } + + std::string mark_item::key(const format& fmt, double sz, + const pen_data& bpen, + const std::string& len) const + { + const double L(legend_item::key_coord(sz, len)); + + screen_data tmp(__epix_legend_key(L)); + tmp.border(bpen.color(), bpen.width().name()); + + tmp.add_tile(glyph(tmp.c(), pair(0,0), "", + m_mark, m_sizes, m_style, true)); + + return tmp.print_to(fmt, len, true); // encapsulate in a picture env. + } +} // end of namespace diff --git a/graphics/epix/legend_item.h b/graphics/epix/legend_item.h new file mode 100644 index 0000000000..6250245ba3 --- /dev/null +++ b/graphics/epix/legend_item.h @@ -0,0 +1,120 @@ +/* + * legend_item.h -- ePiX legend_item base class and implementations + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.11 + * Last Change: August 17, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_LEGEND_ITEM +#define EPIX_LEGEND_ITEM + +#include <string> + +#include "enums.h" +#include "Color.h" +#include "pen_data.h" + +#include "label_data.h" +#include "markers.h" + +namespace ePiX { + + class format; + + // used to represent legend items both in "space" and in the screen + class legend_item { + public: + virtual ~legend_item() { } + virtual legend_item* clone() const = 0; + + virtual std::string value() const = 0; + virtual std::string key(const format& fmt, double sz, + const pen_data& bpen, + const std::string& len) const = 0; + + double key_coord(double sz, const std::string& len) const; + }; // end of base class + + + // key is a solid filled square in current color + class fill_item : public legend_item { + public: + fill_item(const std::string& text); + fill_item* clone() const; + + std::string value() const; + std::string key(const format&, double, + const pen_data&, + const std::string& len) const; + + private: + Color m_fill; + std::string m_text; + }; // end of class fill_item + + + // key is a line segment in current line style + class path_item : public legend_item { + public: + path_item(const std::string& text); + path_item* clone() const; + + std::string value() const; + std::string key(const format&, double sz, const pen_data&, + const std::string& len) const; + + private: + pen_data m_line; + pen_data m_base; + + std::string m_text; + }; // end of class path_item + + + // key is a marker in the current style + class mark_item : public legend_item { + public: + mark_item(epix_mark_type mark, const std::string& text); + mark_item* clone() const; + + std::string value() const; + std::string key(const format&, double sz, const pen_data&, + const std::string& len) const; + + private: + epix_mark_type m_mark; + label_state m_style; + marker_sizes m_sizes; + + std::string m_text; + }; // end of class mark_item + +} // end of namespace + +#endif /* EPIX_LEGEND_ITEM */ diff --git a/graphics/epix/legend_tile.cc b/graphics/epix/legend_tile.cc new file mode 100644 index 0000000000..546cf802b0 --- /dev/null +++ b/graphics/epix/legend_tile.cc @@ -0,0 +1,173 @@ +/* + * legend_tile.cc -- ePiX screen implemenation for legends + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.1 + * Last Change: September 28, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <string> +#include <sstream> +#include <list> + +#include "enums.h" + +#include "length.h" + +#include "label_style.h" +#include "pen_data.h" + +#include "functions.h" +#include "pairs.h" +#include "affine.h" +#include "screen_mask.h" + +#include "picture.h" +#include "picture_data.h" + +#include "format.h" + +#include "legend_item.h" +#include "legend_tile.h" + +namespace ePiX { + + // location, offsets, contents, mark type, visibility + legend_tile::legend_tile(const pair& here, const pair& offset, + epix_label_posn align, const label_state& style, + const pen_data& pen, + double key_size, double skip, + std::list<legend_item*> items) + : m_here(here), m_offset(offset), m_align(align), m_style(style), + m_item_border(pen), m_key_size(key_size), m_label_skip(skip) + { + for (std::list<legend_item*>::const_iterator li=items.begin(); + li != items.end(); ++li) + m_items.push_back((*li)->clone()); + } + + legend_tile::legend_tile(const legend_tile& L) + : m_here(L.m_here), m_offset(L.m_offset), m_align(L.m_align), + m_style(L.m_style), m_item_border(L.m_item_border), + m_key_size(L.m_key_size), m_label_skip(L.m_label_skip) + { + for (std::list<legend_item*>::const_iterator ip = L.m_items.begin(); + ip != L.m_items.end(); ++ip) + m_items.push_back((*ip)->clone()); + } + + legend_tile& legend_tile::operator=(const legend_tile& L) + { + if (&L != this) + { + std::list<legend_item*> tmp; + for (std::list<legend_item*>::const_iterator ip = L.m_items.begin(); + ip != L.m_items.end(); ++ip) + tmp.push_back((*ip)->clone()); + + m_here = L.m_here; + m_offset = L.m_offset; + + m_align = L.m_align; + m_style = L.m_style; + + m_item_border = L.m_item_border; + + m_key_size = L.m_key_size; + m_label_skip = L.m_label_skip; + + swap(m_items, tmp); + } + + return *this; + } + + legend_tile::~legend_tile() + { + for (std::list<legend_item*>::iterator ip = m_items.begin(); + ip != m_items.end(); ++ip) + delete *ip; + } + + + legend_tile& legend_tile::map_by(const affine& f) + { + m_here = f(m_here); + return *this; + } + + // legends unaffected by cropping + legend_tile& legend_tile::crop_to(const screen_mask& M) + { + /* + if (M.crops(m_here)) + m_seen = false; + */ + return *this; + } + + legend_tile* legend_tile::clone() const + { + return new legend_tile(*this); + } + + bool legend_tile::is_empty() const + { + return false; + } + + std::string legend_tile::print_to(const format& fmt, + const std::string& len) const + { + std::stringstream obuf, item_buf; + + item_buf << "%" << std::endl << "\\begin{tabular}{l}%" << std::endl; + + for (std::list<legend_item*>::const_iterator ip=m_items.begin(); + ip != m_items.end(); ++ip) + item_buf << (*ip)->key(fmt, m_key_size, m_item_border, len) + << "\\hskip " << m_label_skip << "pt " + << fmt.print_latex_hbox(m_style, (*ip)->value()) + << " \\\\" << std::endl; + + item_buf << "\\end{tabular}%" << std::endl; + + obuf << fmt.print_text(m_here, m_offset, item_buf.str(), m_style, len); + + return obuf.str(); + } + + void legend_tile::add_to_pallet() const + { + the_picture().add_to_pallet(m_item_border.color()) + .add_to_pallet(m_style.text_color()) + .add_to_pallet(m_style.mask_color()) + .add_to_pallet(m_style.label_border().color()); + } +} // end of namespace diff --git a/graphics/epix/legend_tile.h b/graphics/epix/legend_tile.h new file mode 100644 index 0000000000..37c5f97440 --- /dev/null +++ b/graphics/epix/legend_tile.h @@ -0,0 +1,94 @@ +/* + * legend_tile.h -- ePiX screen implemenation for legends + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.1 + * Last Change: September 28, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_LEGEND_TILE +#define EPIX_LEGEND_TILE +#include <string> + +#include "enums.h" + +#include "pairs.h" +#include "length.h" +#include "Color.h" + +#include "label_style.h" +#include "pen_data.h" + +#include "tile.h" + +namespace ePiX { + + class format; + class legend_item; + class affine; + class screen_mask; + + class legend_tile : public tile { + public: + legend_tile(const pair& here, const pair& offset, + epix_label_posn align, const label_state& style, + const pen_data& item_border, double key_size, double skip, + std::list<legend_item*> items); + + legend_tile(const legend_tile&); + legend_tile& operator= (const legend_tile&); + ~legend_tile(); + + legend_tile& map_by(const affine&); + legend_tile& crop_to(const screen_mask&); + + legend_tile* clone() const; + + bool is_empty() const; + + std::string print_to(const format&, const std::string&) const; + void add_to_pallet() const; + + private: + pair m_here; + pair m_offset; + + epix_label_posn m_align; + + label_state m_style; + + pen_data m_item_border; + + double m_key_size; // dims of key boxes in pt + double m_label_skip; // \hskip between box and item value + + std::list<legend_item*> m_items; + }; // end of class legend_tile + +} // end of namespace + +#endif /* EPIX_LEGEND_TILE */ diff --git a/graphics/epix/length.cc b/graphics/epix/length.cc new file mode 100644 index 0000000000..431874ee92 --- /dev/null +++ b/graphics/epix/length.cc @@ -0,0 +1,277 @@ +/* + * length.cc -- the ePiX::length class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <cmath> +#include <string> +#include <sstream> + +#include "errors.h" +#include "constants.h" +#include "length.h" + +namespace ePiX { + + // Inviolable "private" constants: number of pts per unit + const double IN(72.27); // the gold standard + const double CM(28.452755905512); // 2.54 cm = 72.27 pt + const double MM(2.8452755905512); // 25.4 mm = 72.27 pt + const double PC(6.0225); // 12 picas = 1 inch + const double BP(1.00375); // 72 big pt = 72.27 pt + // const double SP(0.0000152587890625); // 65536 scaled pt = 1 pt + + // extract length from "double [spaces] length unit" + length::length(std::string arg) + { + char* tmp_units; + m_mag = strtod(arg.c_str(), &tmp_units); + std::string putative_units(tmp_units); + + // skip spaces, get first two non-space characters + std::string::size_type i=putative_units.find_first_not_of(" "); + + if (i == std::string::npos) + { + epix_warning("Missing units, using pt"); + m_units = "pt"; + } + else + m_units = putative_units.substr(i, 2); + + // See what we found; ugly, but not going to change... + if (m_units == "pt") + pts_per_unit = 1.0; + + else if (m_units == "in") + pts_per_unit = IN; + + else if (m_units == "cm") + pts_per_unit = CM; + + else if (m_units == "mm") + pts_per_unit = MM; + + else if (m_units == "pc") + pts_per_unit = PC; + + else if (m_units == "bp") + pts_per_unit = BP; + /* + else if (m_units == "sp") + pts_per_unit = SP; + */ + else + { + std::string warn="Unrecognized units \""+m_units+"\", assuming pt"; + epix_warning(warn); + pts_per_unit = 1.0; + m_units = "pt"; + } + } // end of string constructor + + length::length(double lgth) + : m_mag(lgth), pts_per_unit(1.0), m_units("pt") { } + + length& length::operator+= (const length& increment) + { + m_mag += increment.m_mag*increment.pts_per_unit/pts_per_unit; + return *this; + } + + length& length::operator*= (double scale) + { + m_mag *= scale; + return *this; + } + + // convert to specified units + length& length::to(std::string units) + { + units = units.substr(0,2); + + if (m_units == units) + return *this; // null conversion + + if (units == "pt") + { + m_mag *= pts_per_unit; + pts_per_unit = 1.0; + m_units = units; + } + + else if (units == "in") + { + m_mag *= pts_per_unit/IN; + pts_per_unit = IN; + m_units = units; + } + + else if (units == "cm") + { + m_mag *= pts_per_unit/CM; + pts_per_unit = CM; + m_units = units; + } + + else if (units == "mm") + { + m_mag *= pts_per_unit/MM; + pts_per_unit = MM; + m_units = units; + } + + else if (units == "pc") + { + m_mag *= pts_per_unit/PC; + pts_per_unit = PC; + m_units = units; + } + + else if (units == "bp") + { + m_mag *= pts_per_unit/BP; + pts_per_unit = BP; + m_units = units; + } + + /* + else if (units == "sp") + { + m_mag *= pts_per_unit/SP; + pts_per_unit = SP; + m_units = units; + } + */ + else + epix_warning("Ignoring conversion to unrecognized units \""+units+"\""); + + return *this; + } + + bool length::operator== (const length& L) const + { + return (fabs(m_mag*pts_per_unit - L.m_mag*L.pts_per_unit) < EPIX_EPSILON); + } + + double length::magnitude() const + { + return m_mag; + } + + std::string length::units() const + { + return m_units; + } + + std::string length::name() const + { + std::stringstream buf; + buf << m_mag << m_units; + return buf.str(); + } + + + // value-returning operators + length operator+ (length len1, const length& len2) + { + return len1 += len2; + } + + length operator* (double sc, length len) + { + return len *= sc; + } + + + bool operator< (length arg1, length arg2) + { + return (arg1.to("pt").magnitude()) < (arg2.to("pt").magnitude()); + } + + // Parse a string into two lengths. + void get_lengths(std::string sz, length& length1, length& length2) + { + std::string units1; + std::string units2; + + double len1(0), len2(0); + + // find first digit + std::string::size_type i=sz.find_first_of("-0123456789."); + + if (i == std::string::npos) + epix_warning("Invalid width in size string"); + + else + { + sz.erase(0, i); // remove initial garbage + const char* tmp = sz.c_str(); + char* arg; + len1 = strtod(tmp, &arg); + sz=arg; + } + + // expect either unitlength or multiplication character + i=sz.find_first_not_of(" "); + std::string::size_type j=sz.find_first_of("Xx*"); + if (i != j) + units1 = sz.substr(i, 2); + + // next digit + i=sz.find_first_of("-0123456789."); + + if (i == std::string::npos) + epix_warning("Invalid height in size string"); + + else + { + sz.erase(0, i); + const char* tmp = sz.c_str(); + char* arg; + len2 = strtod(tmp, &arg); + sz=arg; + i=sz.find_first_not_of(" "); + units2 = sz.substr(i, 2); + } + + if (units1 == "") // e.g. sz = "4x6in" + units1 = units2; + + // assign values + std::stringstream buf1; + buf1 << len1 << units1; + length1=length(buf1.str()); + + std::stringstream buf2; + buf2 << len2 << units2; + length2=length(buf2.str()); + } +} // end of namespace diff --git a/graphics/epix/length.h b/graphics/epix/length.h new file mode 100644 index 0000000000..d44b86cffa --- /dev/null +++ b/graphics/epix/length.h @@ -0,0 +1,110 @@ +/* + * length.h -- ePiX true and LaTeX length manipulation + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0 + * Last Change: September 22, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file provides the length class from ePiX2: + * + * - length(std::string) assumes argument is "double [space(s)] unit" + * Recognized units are pt (points), in, cm, mm, pc (picas = 1/12 in), + * bp (big points = 1/72 in) + * + * Malformed strings are handled as follows: + * Missing doubles are assumed to be 0, units are assumed to be pt + * + * - length(double) sets length to specified number of pt + * + * - operator += Increments a length, returning answer in LHS units, e.g. + * 1cm+=2in is 6.08cm + * 2in+=1cm is 2.3937in + * + * - operator *= scales a length by a double + * - to(string) converts a length to specified units + * - operator< compares true lengths + * - get_lengths(string, length, length) parses a string into ht and width + * + * A length can be negative. + */ + +#ifndef EPIX_LENGTH +#define EPIX_LENGTH + +#include <string> + +namespace ePiX { + + class length { + public: + length(std::string); // not const std::string& + explicit length(double = 0); + + length& operator+= (const length&); // increment by another length + length& operator*= (double); // scale + length& to(std::string); // convert to specified units + + // compare, with units conversion + bool operator== (const length&) const; + bool operator!= (const length& len) const { return !((*this) == len); } + + // for output + double magnitude() const; + std::string units() const; + std::string name() const; + + private: + double m_mag; + double pts_per_unit; // constants defined in length.cc + std::string m_units; + }; // end of class length + + // value-returning operators + length operator+ (length, const length&); + length operator* (double, length len); + + // Compare true size; must pass by value... + bool operator< (length arg1, length arg2); + + /* + * Parse a string into two lengths (width and height). + * + * The "sz" argument is expected to look like "4in x 10cm" or "4 x 6 in", + * specifically a double, an optional two-letter unitlength, an "x", a + * double, and a two-letter unitlength (defaults to pt). Spaces are + * unimportant, as is initial or trailing garbage. Badly malformed input + * (e.g., "4,6 in") may confuse the parsing code on some platforms. + */ + void get_lengths(std::string sz, length& length1, length& length2); + +} // end of namespace + +#endif /* EPIX_LENGTH */ diff --git a/graphics/epix/lens.cc b/graphics/epix/lens.cc new file mode 100644 index 0000000000..cfca6df66b --- /dev/null +++ b/graphics/epix/lens.cc @@ -0,0 +1,162 @@ +/* + * lens.cc -- ePiX::lens functions + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.22 + * Last Change: September 24, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +// #include <cmath> + +#include "pairs.h" +#include "triples.h" +#include "frame.h" + +#include "lens.h" + +namespace ePiX { + + Lens::~Lens() { } + + pair Perspective::operator() + (const P& arg, const frame& orient, const P& viewpt, + double dist) const + { + P arg_vector(arg - viewpt); + + // get arg's location in our coordinates + double u1(orient.sea()|arg_vector); + double u2(orient.sky()|arg_vector); + double u3(orient.eye()|arg_vector); + + return (-dist/u3)*pair(u1, u2); + } // end of Camera::Perspective::operator() + + bool Perspective::is_linear() const + { + return true; + } + + bool Perspective::needs_clip() const + { + return true; + } + + Perspective* Perspective::clone() const + { + return new Perspective(*this); + } + + + pair Orthog::operator() + (const P& arg, const frame& orient, const P& viewpt, + double dist) const + { + P arg_vector(arg - viewpt); + double u1(orient.sea()|arg_vector); + double u2(orient.sky()|arg_vector); + + return pair(u1, u2); + } // end of Camera::Orthog::operator() + + bool Orthog::is_linear() const + { + return true; + } + + bool Orthog::needs_clip() const + { + return true; + } + + Orthog* Orthog::clone() const + { + return new Orthog(*this); + } + + + pair Fisheye::operator() + (const P& arg, const frame& orient, const P& viewpt, + double dist) const + { + P arg_vector(arg - viewpt); + arg_vector *= 1.0/(norm(arg_vector)); + + double u1(orient.sea()|arg_vector); + double u2(orient.sky()|arg_vector); + + // radial projection to camera sphere, then orthogonal projection + return dist*pair(u1, u2); + } // end of Camera::Fisheye::operator() + + bool Fisheye::is_linear() const + { + return false; + } + + bool Fisheye::needs_clip() const + { + return false; + } + + Fisheye* Fisheye::clone() const + { + return new Fisheye(*this); + } + + + pair Bubble::operator() + (const P& arg, const frame& orient, const P& viewpt, + double dist) const + { + P arg_vector(arg - viewpt); + arg_vector *= 1.0/(norm(arg_vector)); + + double u1(orient.sea()|arg_vector); + double u2(orient.sky()|arg_vector); + double u3(orient.eye()|arg_vector); + + // radial projection to camera sphere, then stereographic projection + return (2.0*dist/(1-u3))*pair(u1, u2); + } // end of Camera::Bubble::operator() + + bool Bubble::is_linear() const + { + return false; + } + + bool Bubble::needs_clip() const + { + return false; + } + + Bubble* Bubble::clone() const + { + return new Bubble(*this); + } +} // end of namespace diff --git a/graphics/epix/lens.h b/graphics/epix/lens.h new file mode 100644 index 0000000000..99281a51cc --- /dev/null +++ b/graphics/epix/lens.h @@ -0,0 +1,99 @@ +/* + * lens.h -- ePiX::Lens interface ans implementations + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.21 + * Last Change: September 22, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_LENS +#define EPIX_LENS + +namespace ePiX { + + class frame; + class P; + class pair; + + class Lens { + public: + // lens map(arg, orient, viewpt, distance) + virtual pair operator() (const P&, + const frame&, const P&, double) const = 0; + virtual bool is_linear() const = 0; // lens preserves lines? + virtual bool needs_clip() const = 0; // lens needs scene pre-clipping? + virtual ~Lens(); + virtual Lens* clone() const = 0; + }; // end of class Lens + + + // actual lenses + class Perspective : public Lens { + public: + pair operator() + (const P&, const frame&, const P&, double) const; + + bool is_linear() const; + bool needs_clip() const; + Perspective* clone() const; + }; // end of class Perspective + + + class Orthog : public Lens { + public: + pair operator() + (const P&, const frame&, const P&, double) const; + + bool is_linear() const; + bool needs_clip() const; + Orthog* clone() const; + }; // end of class Orthog + + + class Fisheye : public Lens { + public: + pair operator() + (const P&, const frame&, const P&, double) const; + + bool is_linear() const; + bool needs_clip() const; + Fisheye* clone() const; + }; // end of class Fisheye + + + class Bubble : public Lens { + public: + pair operator() + (const P&, const frame&, const P&, double) const; + + bool is_linear() const; + bool needs_clip() const; + Bubble* clone() const; + }; // end of class Bubble + +} // end of namespace + +#endif /* EPIX_LENS */ diff --git a/graphics/epix/make_header b/graphics/epix/make_header new file mode 100644 index 0000000000..0041b4a92e --- /dev/null +++ b/graphics/epix/make_header @@ -0,0 +1,35 @@ +#!/bin/bash +# +HEADER_FILE="epix.h" + +HEADERS="enums.h length.h interval.h triples.h functions.h pairs.h \ + affine.h Color.h state.h frame.h domain.h camera.h screen.h picture.h \ + markers.h axis.h legend.h path.h curves.h \ + circle.h plane.h segment.h sphere.h intersections.h \ + plots.h surface.h data_mask.h data_file.h data_bins.h geometry.h" + +# N.B. Spaces in 2nd line are properly adjusted +cat <<HEADER_HEADER > $HEADER_FILE +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\\ + * $HEADER_FILE -- Automatically created on $(date) * +\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include <iostream> +#include <vector> +#include <list> +#include <set> +#include <string> +#include <sstream> +#include <cmath> + +#ifndef EPIX_H +#define EPIX_H + +HEADER_HEADER + +cat $HEADERS | grep -v "\#include" >> $HEADER_FILE + +echo >> $HEADER_FILE +echo "#endif /* EPIX_H */" >> $HEADER_FILE + +exit 0; diff --git a/graphics/epix/map.h b/graphics/epix/map.h new file mode 100644 index 0000000000..c0c57a38be --- /dev/null +++ b/graphics/epix/map.h @@ -0,0 +1,167 @@ +/* + * map.h -- classes of map for function plotting + * + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * + * Version 1.1.5 + * Last Change: June 20, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file provides classes that represent mappings R -> R^3 or R x R -> R^3, + * both P-valued and assembled from double-valued components. Each class + * provides an evaluation operator that takes 1, 2, or 3 doubles and returns + * a P. Stubs for general coordinate systems are included. + * + * - path_map: R -> R^3 + * - surface_map: R x R -> R^3 + * - space_map: R x R x R -> R^3 + * + * - column_1var: assemble R -> R^3 from components + * - column_2var: assemble R x R -> R^3 from components + * + * These classes are intended primarily for internal use, allowing the + * plot algorithms to be templated. In new code, maps should be defined + * as P-valued, rather than assembled from components; the "column" classes + * are provided solely for backward compatibility. + */ + +#ifndef EPIX_MAP +#define EPIX_MAP + +#include "triples.h" +#include "functions.h" + +namespace ePiX { + + // identity and coordinate projection functions + template<class T>T id(T arg) { return arg; } + + template<class T1, class T2>T1 proj1(T1 arg1, T2 arg2) { return arg1; } + template<class T1, class T2>T2 proj2(T1 arg1, T2 arg2) { return arg2; } + + // R -> R^3 + class path_map { + private: + P (*y)(double); + P (*Y)(P); + + public: + path_map(P f(double), P F(P) = id) : y(f), Y(F) { } + + P operator() (const P& arg) const + { + return Y(y(arg.x1())); + } + + }; // end of class path_map + + // R x R -> R^3 + class surface_map { + private: + P (*y)(double, double); + P (*Y)(P); + + public: + surface_map(P f(double, double), P F(P) = id) : y(f), Y(F) { } + P operator() (const P& arg) const + { + return Y(y(arg.x1(), arg.x2())); + } + + }; // end of class surface_map + + // R x R x R -> R^3 + class space_map { + private: + P (*y)(double, double, double); + P (*Y)(P); + + public: + space_map(P f(double, double, double), P F(P) = id) : y(f), Y(F) { } + P operator() (const P& arg) const + { + return Y(y(arg.x1(), arg.x2(), arg.x3())); + } + + }; // end of class space_map + + + // assemble R -> R^3 from components + class column_1var { + private: + double (*y1)(double); + double (*y2)(double); + double (*y3)(double); + P (*Y)(P); + + public: + column_1var(double f1(double), double f2(double), double f3(double) = zero, + P F(P) = id) : y1(f1), y2(f2), y3(f3), Y(F) { } + + // parameterized path from f:R -> R + column_1var(double f(double), P F(P) = id) + : y1(id), y2(f), y3(zero), Y(F) { } + P operator() (const P& arg) const + { + double t = arg.x1(); + return Y(P(y1(t), y2(t), y3(t))); + } + }; // end of class column_1var + + // assemble R x R -> R^3 from components + class column_2var { + private: + double (*y1)(double, double); + double (*y2)(double, double); + double (*y3)(double, double); + P (*Y)(P); + + public: + column_2var(double f1(double, double), + double f2(double, double), + double f3(double, double), + P F(P) = id) : y1(f1), y2(f2), y3(f3), Y(F) { } + + // omitted third component defaults to zero + column_2var(double f1(double, double), + double f2(double, double), + P F(P) = id) : y1(f1), y2(f2), y3(zero), Y(F) { } + + // parameterized surface from f:R x R -> R + column_2var(double f(double, double), P F(P) = id) + : y1(proj1), y2(proj2), y3(f), Y(F) { } + P operator() (const P& arg) const + { + double u(arg.x1()); + double v(arg.x2()); + return Y(P(y1(u, v), y2(u, v), y3(u, v))); + } + }; // end of class column_2var +} // end of namespace + +#endif /* EPIX_MAP */ diff --git a/graphics/epix/marker_style.cc b/graphics/epix/marker_style.cc new file mode 100644 index 0000000000..7134a78ac9 --- /dev/null +++ b/graphics/epix/marker_style.cc @@ -0,0 +1,79 @@ +/* + * marker_style.cc -- ePiX's dot size and tick length + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.9 + * Last Change: July 29, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "constants.h" + +#include "functions.h" +#include "marker_style.h" + +namespace ePiX { + + marker_sizes::marker_sizes() + : the_dotsize(AVG_DOT), the_ticksize(AVG_TICK) { } + + marker_sizes& marker_sizes::dot_size(double diam) + { + if (0 < diam) + the_dotsize = snip_to(diam, MIN_DOT, MAX_DOT); + else + the_dotsize = AVG_DOT; + + return *this; + } + + marker_sizes& marker_sizes::tick_size(double len) + { + if (0 < len) + the_ticksize = snip_to(len, MIN_TICK, MAX_TICK); + else + the_ticksize = AVG_TICK; + + return *this; + } + + double marker_sizes::dot_size() const + { + return the_dotsize; + } + + double marker_sizes::tick_size() const + { + return the_ticksize; + } + + marker_sizes& the_mark_size() + { + static marker_sizes* the_mark_size(new marker_sizes()); + return *the_mark_size; + } +} // end of namespace diff --git a/graphics/epix/marker_style.h b/graphics/epix/marker_style.h new file mode 100644 index 0000000000..48b03193de --- /dev/null +++ b/graphics/epix/marker_style.h @@ -0,0 +1,59 @@ +/* + * marker_style.h -- ePiX's dot size and tick mark length + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.19 + * Last Change: September 17, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_MARKER_STYLE +#define EPIX_MARKER_STYLE + +namespace ePiX { + + class marker_sizes { + public: + marker_sizes(); + + marker_sizes& dot_size(double diam); + marker_sizes& tick_size(double len); + + double dot_size() const; + double tick_size() const; + + private: + double the_dotsize; // size of dots, 1 -- 36 pt + double the_ticksize; // (half-)size of tick marks, 1 -- 8 pt + }; + + marker_sizes& the_mark_size(); + +} // end of namespace + +#endif /* EPIX_MARKER_STYLE */ diff --git a/graphics/epix/markers.cc b/graphics/epix/markers.cc new file mode 100644 index 0000000000..ac418f8e1f --- /dev/null +++ b/graphics/epix/markers.cc @@ -0,0 +1,308 @@ +/* + * markers.cc -- ePiX axes, grids, markers, and labels + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.19 + * Last Change: September 17, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "constants.h" + +#include "triples.h" +#include "length.h" + +#include "functions.h" + +#include "path.h" +#include "curves.h" +#include "screen.h" +#include "picture.h" + +#include "label_data.h" +#include "markers.h" + +namespace ePiX { + + static void __epix_label(const P& base, const P& offset, + const std::string& lbl, + epix_label_posn POSN, bool masked) + { + label_data val(base, offset, lbl); + + if (masked) + { + // get mask color + Color my_mask(the_label_style().mask_color()); + + if (my_mask.is_unset()) + my_mask = White(); + + val.mask_color(my_mask); + } + + else // !masked + val.mask_color(Neutral()); + + val.align_to(POSN).draw(); + } + + // label -- put POSN-aligned string <label_text> + // at Cartesian position <base> translated by <offset> true points. + void label(const P& base, const P& offset, const std::string& lbl, + epix_label_posn POSN) + { + __epix_label(base, offset, lbl, POSN, the_label_style().is_masked()); + } + + // mask color comes from global style, falls back to White() + void masklabel(const P& base, const P& offset, const std::string& lbl, + epix_label_posn POSN) + { + __epix_label(base, offset, lbl, POSN, true); + } + + void label(const P& base, const P& offset, const std::string& lbl) + { + __epix_label(base, offset, lbl, none, the_label_style().is_masked()); + } + + void masklabel(const P& base, const P& offset, const std::string& lbl) + { + __epix_label(base, offset, lbl, none, true); + } + + // centered labels + void label(const P& base, const std::string& lbl) + { + __epix_label(base, P(0,0), lbl, c, the_label_style().is_masked()); + } + + void masklabel(const P& base, const std::string& lbl) + { + __epix_label(base, P(0,0), lbl, c, true); + } + + // Marker aliases + void marker(const P& arg, epix_mark_type TYPE) + { + label_data(arg, TYPE).draw(); + } + + // Markers with labels + void circ(const P& posn, const P& offset, const std::string& label_text, + epix_label_posn POSN) + { + if (label_text != "") + label(posn, offset, label_text, POSN); + label_data mk(posn, CIRC); + mk.draw(); + } + + void ring(const P& posn, const P& offset, const std::string& label_text, + epix_label_posn POSN) + { + if (label_text != "") + label(posn, offset, label_text, POSN); + label_data mk(posn, RING); + mk.draw(); + } + + void spot(const P& posn, const P& offset, const std::string& label_text, + epix_label_posn POSN) + { + if (label_text != "") + label(posn, offset, label_text, POSN); + label_data mk(posn, SPOT); + mk.draw(); + } + + void dot(const P& posn, const P& offset, const std::string& label_text, + epix_label_posn POSN) + { + if (label_text != "") + label(posn, offset, label_text, POSN); + label_data mk(posn, DOT); + mk.draw(); + } + + void ddot(const P& posn, const P& offset, const std::string& label_text, + epix_label_posn POSN) + { + if (label_text != "") + label(posn, offset, label_text, POSN); + label_data mk(posn, DDOT); + mk.draw(); + } + + void box(const P& posn, const P& offset, const std::string& label_text, + epix_label_posn POSN) + { + if (label_text != "") + label(posn, offset, label_text, POSN); + label_data mk(posn, BOX); + mk.draw(); + } + + void bbox(const P& posn, const P& offset, const std::string& label_text, + epix_label_posn POSN) + { + if (label_text != "") + label(posn, offset, label_text, POSN); + label_data mk(posn, BBOX); + mk.draw(); + } + + // Axis ticks (h_tick = tall, thin rectangle, for a *horizontal* axis) + void h_axis_tick(const P& arg, epix_label_posn POSN) + { + label_data mk(arg, HTICK, POSN); + mk.draw(); + } + + void v_axis_tick(const P& arg, epix_label_posn POSN) + { + label_data mk(arg, VTICK, POSN); + mk.draw(); + } + + + //// Curve-like elements + // arrow with label + void arrow(const P& tail, const P& head, const P& offset, + const std::string& label_text, + epix_label_posn POSN, double scale) + { + arrow(tail, head, scale); + label(tail, offset, label_text, POSN); + } + + // fixed-size elements + void right_angle(const P& loc, P leg1, P leg2, double scale) + { + const double norm1(norm(leg1)); + const double norm2(norm(leg2)); + + if (norm1 < EPIX_EPSILON || norm2 < EPIX_EPSILON) + return; + + //else + const double mult(pt_to_screen(scale)); + leg1 *= mult/norm1; + leg2 *= mult/norm2; + + path bd; + bd.pt(loc + leg1).pt(loc + leg1 + leg2).pt(loc + leg2); + bd.draw(); + } + + // the *acute* angle + void arc_measure(const P& loc, P leg1, P leg2, const P& offset, + const std::string& text, epix_label_posn align, + double scale) + { + const double norm1(norm(leg1)); + const double norm2(norm(leg2)); + + if (norm1 < EPIX_EPSILON || norm2 < EPIX_EPSILON) + return; + + //else normalize + leg1 *= 1.0/norm1; + leg2 *= 1.0/norm2; + + // check for parllelity + P perp(leg1*leg2); + const double norm3(norm(perp)); + + if (norm3 < EPIX_EPSILON) + return; + + // else get small angle + const double th(Acos(leg1|leg2)); + + perp *= 1.0/norm3; + leg1 *= pt_to_screen(scale); + + perp *= leg1; // perp to leg1 in plane of legs + + ellipse(loc, leg1, perp, 0, th); + + if (text != "") + label(loc + Cos(0.5*th)*leg1 + Sin(0.5*th)*perp, offset, + text, align); + } + + void arc_measure(const P& loc, P leg1, P leg2, double scale) + { + arc_measure(loc, leg1, leg2, P(0,0), "", none, scale); + } + + void axis_break(const P& tail, const P& head, double scale) + { + const P midpt(0.5*(head+tail)); + + P dir((head-tail)%E_3); // project to (x1,x2)-plane + + if (norm(dir) < EPIX_EPSILON) + return; + + // else + dir *= pt_to_screen(0.25*scale)/norm(dir); // zag is scale pt long + + path bd; + bd.pt(tail).pt(midpt-2*dir).pt(midpt-dir+1.5*J(dir)) + .pt(midpt+dir-1.5*J(dir)).pt(midpt+2*dir).pt(head); + + bd.draw(); + } + + void h_error_bar(const P& loc, double err, epix_mark_type mk, double ht) + { + const P dy(0, pt_to_screen(0.5*ht)); + const P bot(loc - P(err,0)); + const P top(loc + P(err,0)); + + line(bot, top); + line(bot - dy, bot + dy); + line(top - dy, top + dy); + marker(loc, mk); + } + + void v_error_bar(const P& loc, double err, epix_mark_type mk, double wd) + { + const P dx(pt_to_screen(0.5*wd), 0); + const P bot(loc - P(0,err)); + const P top(loc + P(0,err)); + + line(bot, top); + line(bot - dx, bot + dx); + line(top - dx, top + dx); + marker(loc, mk); + } +} // end of namespace diff --git a/graphics/epix/markers.h b/graphics/epix/markers.h new file mode 100644 index 0000000000..92b80f3660 --- /dev/null +++ b/graphics/epix/markers.h @@ -0,0 +1,119 @@ +/* + * markers.h -- ePiX markers and labels + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.16 + * Last Change: September 09, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * label -- put string constant <label_text> at Cartesian position <base> + * translated by (offset.x1, offset.x2) true points (i.e., 3rd component + * of <offset> is discarded). + * + * Accepts an optional LaTeX-style positioning argument. + * If no offset is specified, the label is centered at the given Cartesian + * location. + * masklabel requires the "color" package, and places the text in + * a white box that masks whatever is underneath and earlier in the file. + */ +#ifndef EPIX_MARKERS +#define EPIX_MARKERS + +#include <string> + +#include "enums.h" + +namespace ePiX { + + class P; + + // position, [offset], label text, [alignment] + void label(const P&, const P&, const std::string&); + void label(const P&, const std::string&); + void label(const P&, const P&, const std::string&, epix_label_posn); + + void masklabel(const P&, const P&, const std::string&); + void masklabel(const P&, const std::string&); + void masklabel(const P&, const P&, const std::string&, epix_label_posn); + + + // Empty and filled LaTeX circles of diameter get_dotsize() true pt + void marker (const P&, epix_mark_type); + + void circ(const P& posn, const P& offset=P(0,0), + const std::string& label_text="", + epix_label_posn align=none); // filled white circ + + void ring(const P& posn, const P& offset=P(0,0), + const std::string& label_text="", + epix_label_posn align=none); // unfilled circ + + void spot(const P& posn, const P& offset=P(0,0), + const std::string& label_text="", + epix_label_posn align=none); + + void dot(const P& posn, const P& offset=P(0,0), + const std::string& label_text="", + epix_label_posn align=none); + + void ddot(const P& posn, const P& offset=P(0,0), + const std::string& label_text="", + epix_label_posn align=none); + + void box(const P& posn, const P& offset=P(0,0), + const std::string& label_text="", + epix_label_posn align=none); + + void bbox(const P& posn, const P& offset=P(0,0), + const std::string& label_text="", + epix_label_posn align=none); + + void h_axis_tick(const P& location, epix_label_posn align=c); + void v_axis_tick(const P& location, epix_label_posn align=c); + + // Arrow with aligned label at tail + void arrow(const P& tail, const P& head, const P& offset, + const std::string& label_text, + epix_label_posn align, double scale=1); + + //// Path-like glyphs //// + // angle indicators; default args are true sizes in pt + void right_angle(const P& loc, P leg1, P leg2, double scale=8); + void arc_measure(const P& loc, P leg1, P leg2, + const P& offset, const std::string&, epix_label_posn, + double scale=8); + void arc_measure(const P& loc, P leg1, P leg2, double scale=8); + + void axis_break(const P& tail, const P& head, double scale=12); + void h_error_bar(const P& loc, double err, epix_mark_type mk, double ht=6); + void v_error_bar(const P& loc, double err, epix_mark_type mk, double wd=6); +} // end of namespace + +#endif /* EPIX_MARKERS */ diff --git a/graphics/epix/mask_diamond.cc b/graphics/epix/mask_diamond.cc new file mode 100644 index 0000000000..da11f29b50 --- /dev/null +++ b/graphics/epix/mask_diamond.cc @@ -0,0 +1,129 @@ +/* + * mask_diamond.cc -- ePiX diamond crop mask + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.10 + * Last Change: August 09, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> + +#include "functions.h" +//#include "errors.h" + +#include "constants.h" + +#include "pairs.h" + +#include "Color.h" + +#include "paint_style.h" +#include "length.h" + +#include "pen_line.h" +#include "pen_fill.h" + +#include "edge_data.h" +#include "screen_crop.h" + +#include "screen_mask.h" +#include "mask_diamond.h" + +namespace ePiX { + + mask_diamond::mask_diamond(const pair& arg1, const pair& arg2) + : m_hmin(min(arg1.x1(), arg2.x1())), + m_hmax(max(arg1.x1(), arg2.x1())), + m_vmin(min(arg1.x2(), arg2.x2())), + m_vmax(max(arg1.x2(), arg2.x2())) + { + m_border.push_back(edge2d(l(), b(), true)); + m_border.push_back(edge2d(b(), r(), true)); + m_border.push_back(edge2d(r(), t(), true)); + m_border.push_back(edge2d(t(), l(), true)); + } + + mask_diamond* mask_diamond::clone() const + { + return new mask_diamond(*this); + } + + // corners and midpoints + double mask_diamond::h_min() const { return m_hmin; } + double mask_diamond::v_min() const { return m_vmin; } + + double mask_diamond::h_max() const { return m_hmax; } + double mask_diamond::v_max() const { return m_vmax; } + + double mask_diamond::h_avg() const { return 0.5*(m_hmin+m_hmax); } + double mask_diamond::v_avg() const { return 0.5*(m_vmin+m_vmax); } + + double mask_diamond::h_size() const { return m_hmax - m_hmin; } + double mask_diamond::v_size() const { return m_vmax - m_vmin; } + + // diamond-specific functions + bool mask_diamond::crops(const pair& arg) const + { + const double x(fabs(arg.x1() - h_avg())/h_size()); + const double y(fabs(arg.x2() - v_avg())/v_size()); + + return !((x + y) <= 0.5); + } + + std::list<edge2d>& mask_diamond::crop_path(std::list<edge2d>& L) const + { + return crop_path_2nd(m_border, L); + } + + std::list<edge2d>& mask_diamond::crop_loop(std::list<edge2d>& L) const + { + return crop_loop_2nd(m_border, L); + } + + pen_line mask_diamond::border(const Color& col, const length& len) const + { + return pen_line(pen_data(col, len), Xfine(), m_border); + } + + pen_fill mask_diamond::backing(const Color& col) const + { + return pen_fill(col, pen_data(col, PLAIN_WIDTH), 0, m_border); + } + + pen_line mask_diamond::border() const + { + return pen_line(the_paint_style().line_pen(), + the_paint_style().base_pen(), m_border); + } + + pen_fill mask_diamond::backing() const + { + const Color& col(the_paint_style().fill_color()); + return pen_fill(col, pen_data(col, PLAIN_WIDTH), 0, m_border); + } +} // end of ePiX namespace diff --git a/graphics/epix/mask_diamond.h b/graphics/epix/mask_diamond.h new file mode 100644 index 0000000000..8d4435f567 --- /dev/null +++ b/graphics/epix/mask_diamond.h @@ -0,0 +1,89 @@ +/* + * mask_diamond.h -- ePiX:: rectangular screen_mask for cropping + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.15 + * Last Change: September 05, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_MASK_DIAMOND +#define EPIX_MASK_DIAMOND + +#include <list> +#include <string> + +#include "edge_data.h" +#include "screen_mask.h" + +namespace ePiX { + + class pair; + + class Color; + + class length; + class pen_fill; + class pen_line; + + class mask_diamond : public screen_mask { + public: + // mask_diamond() { } + mask_diamond(const pair& arg1, const pair& arg2); + + mask_diamond* clone() const; + double h_min() const; + double h_max() const; + double h_size() const; + double h_avg() const; + + double v_min() const; + double v_max() const; + double v_size() const; + double v_avg() const; + + bool crops(const pair& arg) const; // false if arg visible + std::list<edge2d>& crop_path(std::list<edge2d>&) const; + std::list<edge2d>& crop_loop(std::list<edge2d>&) const; + + pen_line border(const Color&, const length&) const; + pen_fill backing(const Color&) const; + + pen_line border() const; + pen_fill backing() const; + + private: + double m_hmin, m_hmax; + double m_vmin, m_vmax; + + std::list<edge2d> m_border; + }; // end of class mask_diamond + +} // end of namespace + +#endif /* EPIX_MASK_DIAMOND */ diff --git a/graphics/epix/mask_ellipse.cc b/graphics/epix/mask_ellipse.cc new file mode 100644 index 0000000000..0eed28f94e --- /dev/null +++ b/graphics/epix/mask_ellipse.cc @@ -0,0 +1,136 @@ +/* + * mask_ellipse.cc -- ePiX ellipse crop mask + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.10 + * Last Change: August 09, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> + +#include "functions.h" +//#include "errors.h" + +#include "constants.h" + +#include "pairs.h" + +#include "Color.h" + +#include "paint_style.h" +#include "length.h" + +#include "pen_line.h" +#include "pen_fill.h" + +#include "edge_data.h" +#include "screen_crop.h" + +#include "screen_mask.h" +#include "mask_ellipse.h" + +namespace ePiX { + + mask_ellipse::mask_ellipse(const pair& arg1, const pair& arg2) + : m_hmin(min(arg1.x1(), arg2.x1())), + m_hmax(max(arg1.x1(), arg2.x1())), + m_vmin(min(arg1.x2(), arg2.x2())), + m_vmax(max(arg1.x2(), arg2.x2())) + { + const double dt(2*M_PI/EPIX_NUM_PTS); + + const pair ctr(0.5*(m_hmin + m_hmax), 0.5*(m_vmin + m_vmax)); + + const double hsz(0.5*(m_hmax - m_hmin)); + const double vsz(0.5*(m_vmax - m_vmin)); + + for (unsigned int i=0; i<EPIX_NUM_PTS; ++i) + m_border.push_back(edge2d(ctr + pair(hsz*std::cos(i*dt), + vsz*std::sin(i*dt)), + ctr + pair(hsz*std::cos((i+1)*dt), + vsz*std::sin((i+1)*dt)), true)); + } + + mask_ellipse* mask_ellipse::clone() const + { + return new mask_ellipse(*this); + } + + // corners and midpoints + double mask_ellipse::h_min() const { return m_hmin; } + double mask_ellipse::v_min() const { return m_vmin; } + + double mask_ellipse::h_max() const { return m_hmax; } + double mask_ellipse::v_max() const { return m_vmax; } + + double mask_ellipse::h_avg() const { return 0.5*(m_hmin+m_hmax); } + double mask_ellipse::v_avg() const { return 0.5*(m_vmin+m_vmax); } + + double mask_ellipse::h_size() const { return m_hmax - m_hmin; } + double mask_ellipse::v_size() const { return m_vmax - m_vmin; } + + // ellipse-specific functions + bool mask_ellipse::crops(const pair& arg) const + { + const double dx((arg.x1() - h_avg())/h_size()); + const double dy((arg.x2() - v_avg())/v_size()); + return !(dx*dx + dy*dy <= 0.25); + } + + std::list<edge2d>& mask_ellipse::crop_path(std::list<edge2d>& L) const + { + return crop_path_2nd(m_border, L); + } + + std::list<edge2d>& mask_ellipse::crop_loop(std::list<edge2d>& L) const + { + return crop_loop_2nd(m_border, L); + } + + pen_line mask_ellipse::border(const Color& col, const length& len) const + { + return pen_line(pen_data(col, len), Xfine(), m_border); + } + + pen_fill mask_ellipse::backing(const Color& col) const + { + return pen_fill(col, pen_data(col, PLAIN_WIDTH), 0, m_border); + } + + pen_line mask_ellipse::border() const + { + return pen_line(the_paint_style().line_pen(), + the_paint_style().base_pen(), m_border); + } + + pen_fill mask_ellipse::backing() const + { + const Color col(the_paint_style().fill_color()); + return pen_fill(col, pen_data(col, PLAIN_WIDTH), 0, m_border); + } +} // end of ePiX namespace diff --git a/graphics/epix/mask_ellipse.h b/graphics/epix/mask_ellipse.h new file mode 100644 index 0000000000..09279ba0f6 --- /dev/null +++ b/graphics/epix/mask_ellipse.h @@ -0,0 +1,89 @@ +/* + * mask_ellipse.h -- ePiX:: elliptical screen_mask for cropping + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.15 + * Last Change: September 05, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_MASK_ELLIPSE +#define EPIX_MASK_ELLIPSE + +#include <list> +#include <string> + +#include "edge_data.h" +#include "screen_mask.h" + +namespace ePiX { + + class pair; + + class Color; + + class length; + class pen_fill; + class pen_line; + + class mask_ellipse : public screen_mask { + public: + // mask_ellipse() { } + mask_ellipse(const pair& arg1, const pair& arg2); + + mask_ellipse* clone() const; + double h_min() const; + double h_max() const; + double h_size() const; + double h_avg() const; + + double v_min() const; + double v_max() const; + double v_size() const; + double v_avg() const; + + bool crops(const pair& arg) const; // false if arg visible + std::list<edge2d>& crop_path(std::list<edge2d>&) const; + std::list<edge2d>& crop_loop(std::list<edge2d>&) const; + + pen_line border(const Color&, const length&) const; + pen_fill backing(const Color&) const; + + pen_line border() const; + pen_fill backing() const; + + private: + double m_hmin, m_hmax; + double m_vmin, m_vmax; + + std::list<edge2d> m_border; + }; // end of class mask_ellipse + +} // end of namespace + +#endif /* EPIX_MASK_ELLIPSE */ diff --git a/graphics/epix/mask_rectangle.cc b/graphics/epix/mask_rectangle.cc new file mode 100644 index 0000000000..d54e934cee --- /dev/null +++ b/graphics/epix/mask_rectangle.cc @@ -0,0 +1,129 @@ +/* + * mask_rectangle.cc -- ePiX rectangle crop mask + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.10 + * Last Change: August 09, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> + +#include "functions.h" +//#include "errors.h" + +#include "constants.h" + +#include "pairs.h" + +#include "Color.h" + +#include "paint_style.h" +#include "length.h" + +#include "pen_line.h" +#include "pen_fill.h" + +#include "edge_data.h" +#include "screen_crop.h" + +#include "screen_mask.h" +#include "mask_rectangle.h" + +namespace ePiX { + + mask_rectangle::mask_rectangle(const pair& arg1, const pair& arg2) + : m_hmin(min(arg1.x1(), arg2.x1())), + m_hmax(max(arg1.x1(), arg2.x1())), + m_vmin(min(arg1.x2(), arg2.x2())), + m_vmax(max(arg1.x2(), arg2.x2())) + { + m_border.push_back(edge2d(br(), tr(), true)); + m_border.push_back(edge2d(tr(), tl(), true)); + m_border.push_back(edge2d(tl(), bl(), true)); + m_border.push_back(edge2d(bl(), br(), true)); + } + + mask_rectangle* mask_rectangle::clone() const + { + return new mask_rectangle(*this); + } + + // corners and midpoints + double mask_rectangle::h_min() const { return m_hmin; } + double mask_rectangle::v_min() const { return m_vmin; } + + double mask_rectangle::h_max() const { return m_hmax; } + double mask_rectangle::v_max() const { return m_vmax; } + + double mask_rectangle::h_avg() const { return 0.5*(m_hmin+m_hmax); } + double mask_rectangle::v_avg() const { return 0.5*(m_vmin+m_vmax); } + + double mask_rectangle::h_size() const { return m_hmax - m_hmin; } + double mask_rectangle::v_size() const { return m_vmax - m_vmin; } + + // rectangle-specific functions + bool mask_rectangle::crops(const pair& arg) const + { + const double x(arg.x1()); + const double y(arg.x2()); + return !( (m_hmin <= x) && (x <= m_hmax) + && (m_vmin <= y) && (y <= m_vmax)); + } + + std::list<edge2d>& mask_rectangle::crop_path(std::list<edge2d>& L) const + { + return crop_path_2nd(m_border, L); + } + + std::list<edge2d>& mask_rectangle::crop_loop(std::list<edge2d>& L) const + { + return crop_loop_2nd(m_border, L); + } + + pen_line mask_rectangle::border(const Color& col, const length& len) const + { + return pen_line(pen_data(col, len), Xfine(), m_border); + } + + pen_fill mask_rectangle::backing(const Color& col) const + { + return pen_fill(col, pen_data(col, PLAIN_WIDTH), 0, m_border); + } + + pen_line mask_rectangle::border() const + { + return pen_line(the_paint_style().line_pen(), + the_paint_style().base_pen(), m_border); + } + + pen_fill mask_rectangle::backing() const + { + const Color& col(the_paint_style().fill_color()); + return pen_fill(col, pen_data(col, PLAIN_WIDTH), 0, m_border); + } +} // end of ePiX namespace diff --git a/graphics/epix/mask_rectangle.h b/graphics/epix/mask_rectangle.h new file mode 100644 index 0000000000..13d23e4f28 --- /dev/null +++ b/graphics/epix/mask_rectangle.h @@ -0,0 +1,89 @@ +/* + * mask_rectangle.h -- ePiX:: rectangular screen_mask for cropping + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.15 + * Last Change: September 05, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_MASK_RECTANGLE +#define EPIX_MASK_RECTANGLE + +#include <list> +#include <string> + +#include "edge_data.h" +#include "screen_mask.h" + +namespace ePiX { + + class pair; + + class Color; + + class length; + class pen_fill; + class pen_line; + + class mask_rectangle : public screen_mask { + public: + // mask_rectangle() { } + mask_rectangle(const pair& arg1, const pair& arg2); + + mask_rectangle* clone() const; + double h_min() const; + double h_max() const; + double h_size() const; + double h_avg() const; + + double v_min() const; + double v_max() const; + double v_size() const; + double v_avg() const; + + bool crops(const pair& arg) const; // false if arg visible + std::list<edge2d>& crop_path(std::list<edge2d>&) const; + std::list<edge2d>& crop_loop(std::list<edge2d>&) const; + + pen_line border(const Color&, const length&) const; + pen_fill backing(const Color&) const; + + pen_line border() const; + pen_fill backing() const; + + private: + double m_hmin, m_hmax; + double m_vmin, m_vmax; + + std::list<edge2d> m_border; + }; // end of class mask_rectangle + +} // end of namespace + +#endif /* EPIX_MASK_RECTANGLE */ diff --git a/graphics/epix/missing b/graphics/epix/missing new file mode 100644 index 0000000000..894e786e16 --- /dev/null +++ b/graphics/epix/missing @@ -0,0 +1,360 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2005-06-08.21 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. + +# 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to <bug-automake@gnu.org>." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). +case "$1" in + lex|yacc) + # Not GNU programs, they don't have --version. + ;; + + tar) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/graphics/epix/mkinstalldirs b/graphics/epix/mkinstalldirs new file mode 100644 index 0000000000..259dbfcd35 --- /dev/null +++ b/graphics/epix/mkinstalldirs @@ -0,0 +1,158 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy + +scriptversion=2005-06-29.22 + +# Original author: Noah Friedman <friedman@prep.ai.mit.edu> +# Created: 1993-05-16 +# Public domain. +# +# This file is maintained in Automake, please report +# bugs to <bug-automake@gnu.org> or send patches to +# <automake-patches@gnu.org>. + +errstatus=0 +dirmode= + +usage="\ +Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... + +Create each directory DIR (with mode MODE, if specified), including all +leading file name components. + +Report bugs to <bug-automake@gnu.org>." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" + exit $? + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --version) + echo "$0 $scriptversion" + exit $? + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and +# mkdir -p a/c at the same time, both will detect that a is missing, +# one will create a, then the other will try to create a and die with +# a "File exists" error. This is a problem when calling mkinstalldirs +# from a parallel make. We use --version in the probe to restrict +# ourselves to GNU mkdir, which is thread-safe. +case $dirmode in + '') + if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + test -d ./-p && rmdir ./-p + test -d ./--version && rmdir ./--version + fi + ;; + *) + if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && + test ! -d ./--version; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + else + # Clean up after NextStep and OpenStep mkdir. + for d in ./-m ./-p ./--version "./$dirmode"; + do + test -d $d && rmdir $d + done + fi + ;; +esac + +for file +do + case $file in + /*) pathcomp=/ ;; + *) pathcomp= ;; + esac + oIFS=$IFS + IFS=/ + set fnord $file + shift + IFS=$oIFS + + for d + do + test "x$d" = x && continue + + pathcomp=$pathcomp$d + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr= + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp=$pathcomp/ + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/graphics/epix/paint_style.cc b/graphics/epix/paint_style.cc new file mode 100644 index 0000000000..56ac9e7129 --- /dev/null +++ b/graphics/epix/paint_style.cc @@ -0,0 +1,145 @@ +/* + * paint_style.cc -- ePiX's current line and fill style. + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.21 + * Last Change: September 22, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "camera.h" +#include "length.h" +#include "pen_data.h" +#include "paint_style.h" + +namespace ePiX { + + // Magic numbers: initialization constants + paint_state::paint_state() + : m_line(pen_data()), m_base(Xfine()), + m_tint(Neutral()), m_filling(false) { } + + paint_state* paint_state::clone() const + { + return new paint_state(*this); + } + + // set + void paint_state::line_pen(const pen_data& pen) + { + m_line = pen; + } + + void paint_state::line_color(const Color& col) + { + m_line.color(col); + } + + void paint_state::line_width(const length& len) + { + m_line.width(len); + } + + void paint_state::base_pen(const pen_data& pen) + { + m_base = pen; + } + + void paint_state::base_color(const Color& col) + { + m_base.color(col); + } + + void paint_state::base_width(const length& len) + { + m_base.width(len); + } + + void paint_state::fill_color(const Color& col) + { + m_tint = col; + } + + void paint_state::fill_flag(bool fill) + { + m_filling = fill; + } + + + // get + pen_data paint_state::line_pen() const + { + return m_line; + } + Color paint_state::line_color() const + { + return m_line.color(); + } + length paint_state::line_width() const + { + return m_line.width(); + } + + pen_data paint_state::base_pen() const + { + return m_base; + } + Color paint_state::base_color() const + { + return m_base.color(); + } + length paint_state::base_width() const + { + return m_base.width(); + } + + Color paint_state::fill_color() const + { + return m_tint; + } + bool paint_state::fill_flag() const + { + return m_filling; + } + + paint_state paint_state::seen_through(const Camera& mycam) const + { + return paint_state(m_line.seen_through(mycam), m_base.seen_through(mycam), + mycam(m_tint), m_filling); + } + + paint_state::paint_state(const pen_data& lp, const pen_data& bp, + const Color& fc, bool ff) + : m_line(lp), m_base(bp), m_tint(fc), m_filling(ff) { } + + + paint_state& the_paint_style() + { + static paint_state* the_paint_state(new paint_state()); + return *the_paint_state; + } +} // end of namespace diff --git a/graphics/epix/paint_style.h b/graphics/epix/paint_style.h new file mode 100644 index 0000000000..95678f1706 --- /dev/null +++ b/graphics/epix/paint_style.h @@ -0,0 +1,103 @@ +/* + * paint_style.h -- ePiX's current line and fill style. + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.3 + * Last Change: March 04, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file implements ePiX's "paint" style: + * + * [] Front pen, base pen (Color and width x2) + * [] Filling and fill color (bool, Color) + * + * The class in this file implements backend for user-level global + * functions defined in state.h, which modify the_paint_style(). + * + * This header is not part of epix.h. + */ +#ifndef EPIX_PAINT_STYLE +#define EPIX_PAINT_STYLE + +#include "Color.h" +#include "pen_data.h" + +namespace ePiX { + + class Camera; + class length; + + class paint_state { + public: + paint_state(); + + paint_state* clone() const; + + // set + void line_pen(const pen_data& pen); + void line_color(const Color& col); + void line_width(const length& len); + + void base_pen(const pen_data& pen); + void base_color(const Color& col); + void base_width(const length& len); + + void fill_color(const Color& col); + void fill_flag(bool fill); + + // get + pen_data line_pen() const; + Color line_color() const; + length line_width() const; + + pen_data base_pen() const; + Color base_color() const; + length base_width() const; + + Color fill_color() const; + bool fill_flag() const; + + paint_state seen_through(const Camera& cam) const; + + private: + pen_data m_line; + pen_data m_base; + + Color m_tint; + bool m_filling; + + paint_state(const pen_data&, const pen_data&, const Color&, bool fill); + }; // end of class paint_state + + paint_state& the_paint_style(); + +} // end of namespace + +#endif /* EPIX_PAINT_STYLE */ diff --git a/graphics/epix/pairs.cc b/graphics/epix/pairs.cc new file mode 100644 index 0000000000..a2cf174825 --- /dev/null +++ b/graphics/epix/pairs.cc @@ -0,0 +1,158 @@ +/* + * pairs.cc -- ePiX pair:: class and mathematical operators + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.10 + * Last Change: August 04, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> + +#include "constants.h" +#include "triples.h" +#include "pairs.h" + +namespace ePiX { + pair::pair(const P& arg) + { + m_x1 = arg.x1(); + m_x2 = arg.x2(); + } + + // unary increment operators + pair& pair::operator += (const pair& arg) + { + m_x1 += arg.m_x1; + m_x2 += arg.m_x2; + + return *this; + } + + pair& pair::operator -= (const pair& arg) + { + m_x1 -= arg.m_x1; + m_x2 -= arg.m_x2; + + return *this; + } + + pair& pair::operator *= (double c) + { + m_x1 *= c; + m_x2 *= c; + + return *this; + } + + // complex multiplication and division + pair& pair::operator *= (const pair& arg) + { + double temp(m_x1); + m_x1 = temp * arg.m_x1 - m_x2 * arg.m_x2; + m_x2 = temp * arg.m_x2 + m_x2 * arg.m_x1; + + return *this; + } + + pair& pair::operator /= (const pair& arg) + { + double denom = (arg.m_x1)*(arg.m_x1)+(arg.m_x2)*(arg.m_x2); + + double temp(m_x1); + m_x1 = (temp * arg.m_x1 + m_x2 * arg.m_x2)/denom; + m_x2 = (m_x2 * arg.m_x1 - temp * arg.m_x2)/denom; + + return *this; + } + + bool pair::operator== (const pair& u) const + { + return ( fabs(m_x1-u.m_x1) < EPIX_EPSILON + && fabs(m_x2-u.m_x2) < EPIX_EPSILON ); + } + + bool pair::operator!= (const pair& u) const + { + return !((*this) == u); + } + + // non-member functions + pair operator- (pair u) + { + return u *= -1; + } + + pair operator+ (pair u, const pair& v) + { + return u += v; + } + + pair operator- (pair u, const pair& v) + { + return u -= v; + } + + pair operator* (double c, pair u) + { + return u *= c; + } + + // complex arithmetic + pair J(pair p) + { + return p *= pair(0,1); + } + + pair operator* (pair u, const pair& v) + { + return u *= v; + } + + pair operator/ (pair u, const pair& v) + { + return u /= v; + } + + // dot product + double operator| (const pair& u, const pair& v) + { + return u.x1()*v.x1() + u.x2()*v.x2(); + } + + double norm (const pair& u) + { + return sqrt(u|u); + } + + // componentwise product (a,b)&(x,y)=(ax,by) + pair operator& (const pair& u, const pair& v) + { + return pair(u.x1()*v.x1(), u.x2()*v.x2()); + } + +} // end of namespace diff --git a/graphics/epix/pairs.h b/graphics/epix/pairs.h new file mode 100644 index 0000000000..cfbfd27c1a --- /dev/null +++ b/graphics/epix/pairs.h @@ -0,0 +1,88 @@ +/* + * pairs.h -- ePiX pair:: class and mathematical operators + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.10 + * Last Change: August 04, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_PAIRS +#define EPIX_PAIRS + +namespace ePiX { + + class P; + + class pair { + public: + pair(double arg1=0, double arg2=0) + : m_x1(arg1), m_x2(arg2) { } + + pair(const P& arg); // take first two coordinates + + double x1() const { return m_x1; } + double x2() const { return m_x2; } + + // unary increment operators + pair& operator += (const pair& arg); + pair& operator -= (const pair& arg); + pair& operator *= (double c); + + // complex multiplication and division + pair& operator *= (const pair& arg); + pair& operator /= (const pair& arg); + bool operator== (const pair& u) const; + bool operator!= (const pair& u) const; + + private: + double m_x1; + double m_x2; + + }; // end of class pair + + pair operator- (pair u); + pair operator+ (pair u, const pair& v); + pair operator- (pair u, const pair& v); + pair operator* (double c, pair u); + + // complex arithmetic + pair J(pair p); + pair operator* (pair u, const pair& v); + pair operator/ (pair u, const pair& v); + + // dot product + double operator| (const pair& u, const pair& v); + double norm (const pair& u); + + // componentwise product (a,b)&(x,y)=(ax,by) + pair operator& (const pair& u, const pair& v); + +} // end of namespace + +#endif /* EPIX_PAIRS */ diff --git a/graphics/epix/path.cc b/graphics/epix/path.cc new file mode 100644 index 0000000000..c786485670 --- /dev/null +++ b/graphics/epix/path.cc @@ -0,0 +1,329 @@ +/* + * path.cc -- ePiX user class for polygons and paths + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 25, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <vector> +#include <cmath> + +#include "errors.h" +#include "triples.h" +#include "constants.h" + +#include "functions.h" + +#include "Color.h" +#include "pen_data.h" +#include "state.h" + +#include "camera.h" +#include "active_screen.h" + +#include "spline_data.h" +#include "path_data.h" + +#include "path.h" + +namespace ePiX { + + class screen; + class Sphere; + + path::path(const path& C) + : m_segments(C.m_segments->clone()) { } + + path& path::operator= (const path& C) + { + if (this != &C) + { + path_data* tmp_segs(C.m_segments->clone()); + + delete m_segments; + + m_segments=tmp_segs; + } + + return *this; + } + + path::~path() + { + delete m_segments; + } + + + path::path() + : m_segments(new path_data()) { } + + path::path(const std::vector<P>& data, bool closed, bool filled) + : m_segments(new path_data(data, closed, filled)) { } + + + // path constructors *do not* close/fill; this must be done by client code + + // lines, without and with specified number of points + path::path(const P& tail, const P& head, double expand) + : m_segments(new path_data()) + { + double c(expm1(M_LN2*expand/100.0)); // 2^{expand/100} - 1 + P dir(head - tail); + + m_segments->pt(tail - (0.5*c)*dir); + m_segments->pt(head + (0.5*c)*dir); + } // end of line constructor + + + path::path(const P& tail, const P& head, + double expand, unsigned int num_pts) + : m_segments(new path_data()) + { + if (num_pts < 1) + num_pts=1; + + double c(expm1(M_LN2*expand/100.0)); // 2^{expand/100} - 1 + + // direction and starting location + P dir(head - tail); + P start(tail - (0.5*c)*dir); + + dir *= ((1+c)/num_pts); + + for (unsigned int i=0; i <= num_pts; ++i) + m_segments->pt(start+i*dir); + + } // end of line constructor + + + // ellipse drawn with N edges + path::path(const P& center, const P& axis1, const P& axis2, + double t_min, double t_max, + unsigned int N) + : m_segments(new path_data()) + { + double T_MAX(t_max); + if (full_turn() < fabs(t_max-t_min)) + { + epix_warning("Angle bounds in ellipse span more than one turn"); + T_MAX = t_min + full_turn(); + } + + const unsigned int num_pts(1 < N ? N : 1); + const double dt((T_MAX - t_min)/num_pts); + + for (unsigned int i=0; i <= num_pts; ++i) + { + double t(t_min + i*dt); + m_segments->pt(center + ((Cos(t)*axis1)+(Sin(t)*axis2))); + } + } // end of ellipse constructor + + // ellipse with default number of points + path::path(const P& center, const P& axis1, const P& axis2, + double t_min, double t_max) + : m_segments(new path_data()) + { + double frac(min(fabs(t_max-t_min)/full_turn(), 1)); + unsigned int num_pts((unsigned int) max(2, ceil(frac*EPIX_NUM_PTS))); + + const double dt((t_max - t_min)/num_pts); + + for (unsigned int i=0; i <= num_pts; ++i) + { + double t(t_min + i*dt); + m_segments->pt(center + ((Cos(t)*axis1)+(Sin(t)*axis2))); + } + } // end of ellipse EPIX_NUM_PTS constructor + + + // Splines + path::path(const P& p1, const P& p2, const P& p3, unsigned int num_pts) + : m_segments(new path_data()) + { + if (num_pts < 2) + num_pts=2; // draw at least V + + const double dt(1.0/num_pts); + + for (unsigned int i=0; i <= num_pts; ++i) + m_segments->pt(spl_pt(p1, p2, p3, i*dt)); + } + + + path::path(const P& p1, const P& p2, const P& p3) + : m_segments(new path_data()) + { + const double dt(1.0/EPIX_NUM_PTS); + + for (unsigned int i=0; i <= EPIX_NUM_PTS; ++i) + m_segments->pt(spl_pt(p1, p2, p3, i*dt)); + } + + + path::path(const P& p1, const P& p2, const P& p3, const P& p4, + unsigned int num_pts) + : m_segments(new path_data()) + { + if (num_pts < 3) + num_pts=3; // draw at least N + + const double dt(1.0/num_pts); + + for (unsigned int i=0; i <= num_pts; ++i) + m_segments->pt(spl_pt(p1, p2, p3, p4, i*dt)); + } + + + path::path(const P& p1, const P& p2, const P& p3, const P& p4) + : m_segments(new path_data()) + { + const double dt(1.0/EPIX_NUM_PTS); + + for (unsigned int i=0; i <= EPIX_NUM_PTS; ++i) + m_segments->pt(spl_pt(p1, p2, p3, p4, i*dt)); + } + + + // parametrized path + path::path(P f(double), double t_min, double t_max, unsigned int num_pts) + : m_segments(new path_data()) + { + if (num_pts < 2) + num_pts = 2; + + const double dt((t_max - t_min)/num_pts); + + for (unsigned int i=0; i <= num_pts; ++i) + m_segments->pt(f(t_min + i*dt)); + } + + // with default number of points + path::path(P f(double), double t_min, double t_max) + : m_segments(new path_data()) + { + const double dt((t_max - t_min)/EPIX_NUM_PTS); + + for (unsigned int i=0; i <= EPIX_NUM_PTS; ++i) + m_segments->pt(f(t_min + i*dt)); + } + + + // graphs + path::path(double f(double), double t_min, double t_max, + unsigned int num_pts) + : m_segments(new path_data()) + { + if (num_pts < 2) + num_pts = 2; + + const double dt((t_max - t_min)/num_pts); + + for (unsigned int i=0; i <= num_pts; ++i) + { + double t(t_min + i*dt); + m_segments->pt(P(t, f(t))); + } + } + + path::path(double f(double), double t_min, double t_max) + : m_segments(new path_data()) + { + const double dt((t_max - t_min)/EPIX_NUM_PTS); + + for (unsigned int i=0; i <= EPIX_NUM_PTS; ++i) + { + double t(t_min + i*dt); + m_segments->pt(P(t, f(t))); + } + } + + + // append a point + path& path::pt(double x, double y, double z) + { + m_segments->pt(P(x, y, z)); + return *this; + } + + path& path::pt(const P& loc) + { + m_segments->pt(loc); + return *this; + } + + + // concatenate + path& path::operator+= (const path& data) + { + *m_segments += *(data.m_segments); + + return *this; + } + + path& path::operator-= (const path& data) + { + *m_segments -= *(data.m_segments); + + return *this; + } + + path& path::close() + { + m_segments->close(); + return *this; + } + path& path::fill(const bool arg) + { + m_segments->fill(arg); + return *this; + } + + + void path::clip() + { + m_segments->clip(); + } + + void path::clip_to(const Sphere& S, const P& viewpt, bool back) + { + m_segments->clip_to(S, viewpt, back); + } + + void path::draw() const + { + m_segments->draw(); + } + + void path::draw(const Color& col, const pen_data& pen) const + { + m_segments->photo(*active_screen(), cam(), col, pen, Xfine()); + } +} // end of namespace diff --git a/graphics/epix/path.h b/graphics/epix/path.h new file mode 100644 index 0000000000..9816eed383 --- /dev/null +++ b/graphics/epix/path.h @@ -0,0 +1,135 @@ +/* + * path.h -- ePiX user class for polygons and paths + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.3 + * Last Change: March 04, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_PATHS +#define EPIX_PATHS + +#include <vector> + +namespace ePiX { + + class Camera; + class Color; + class P; + class path_data; + class pen_data; + class screen; + class Sphere; + + class path { + friend class facet; + public: + + // path was visible to users, but is now implemented as a p_impl. + path(const path&); + path& operator= (const path&); + ~path(); + + // Interface dictated by backward compatibility + path(const std::vector<P>& data, bool closed, bool filled); + path(); + + // line constructors + path(const P& tail, const P& head, double expand=0); + path(const P&, const P&, double expand, unsigned int num_pts); + + + // Constructors that specify the number of points have two prototypes + // rather than accepting a default argument. This hides the global + // (but user-inaccessible) default number of points (see constants.h). + + // ellipse + path(const P& center, const P& axis1, const P& axis2, + double t_min, double t_max, + unsigned int num_pts); + + path(const P& center, const P& axis1, const P& axis2, + double t_min, double t_max); + + + // spline + path(const P& p1, const P& p2, const P& p3, unsigned int n); + path(const P& p1, const P& p2, const P& p3); + + path(const P& p1, const P& p2, const P& p3, const P& p4, unsigned int n); + path(const P& p1, const P& p2, const P& p3, const P& p4); + + + // parametric path + path(P f(double), double t_min, double t_max, unsigned int num_pts); + path(P f(double), double t_min, double t_max); + + // function graph + path(double f(double), double t_min, double t_max, unsigned int num_pts); + path(double f(double), double t_min, double t_max); + + // append a point + path& pt(double, double, double=0); + path& pt(const P&); + + // concatenate path segments + path& operator+= (const path&); + // concatenate, reversing second sequence + path& operator-= (const path&); + + bool is_closed() const; + bool is_filled() const; + + // set attributes + path& close(); + path& fill(const bool arg=true); + + + void clip(); + + // assumes path lies on sphere + void clip_to(const Sphere&, const P& viewpt, bool back=false); + + void draw() const; + void draw(const Color&, const pen_data&) const; + + private: + path_data* m_segments; + + }; // end of class path + + /* + Slated for removal + // polygon/polyline with variable number of vertices + path polygon(unsigned int num_pts ...); + path polyline(unsigned int num_pts ...); + */ + +} // end of namespace + +#endif /* EPIX_PATHS */ diff --git a/graphics/epix/path_data.cc b/graphics/epix/path_data.cc new file mode 100644 index 0000000000..e4359ee030 --- /dev/null +++ b/graphics/epix/path_data.cc @@ -0,0 +1,280 @@ +/* + * path_data.cc -- ePiX implementation classes for polygons and paths + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.21 + * Last Change: September 22, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <list> +#include <algorithm> + +#include "errors.h" +#include "constants.h" + +#include "triples.h" +#include "camera.h" +#include "sphere.h" + +#include "edge_data.h" +#include "active_screen.h" +#include "clipping.h" + +#include "paint_style.h" + +#include "halfspace.h" +#include "pen_line.h" +#include "pen_fill.h" + +#include "screen_data.h" +#include "screen.h" + +#include "path_data.h" + +namespace ePiX { + + path_data::path_data() : m_closed(false), m_filled(false) { } + + path_data::path_data(const std::vector<P>& pv, bool closed, bool filled) + : m_closed(closed), m_filled(closed && filled) + { + if (pv.size() == 1) + m_data.push_back(edge3d(pv.at(0), pv.at(0), true)); // will delete later + + else + for (unsigned int i=0; i<pv.size()-1; ++i) + m_data.push_back(edge3d(pv.at(i), pv.at(i+1), true)); + } + + path_data::path_data(const std::list<edge3d>& data, bool closed, bool filled) + : m_closed(closed), m_filled(closed && filled), m_data(data) { } + + + path_data* path_data::clone() const + { + return new path_data(*this); + } + + + // join to arg; no effect if we're closed + path_data& path_data::pt(const P& arg) + { + if (0 < m_data.size()) + { + const P hd((--m_data.end())->head()); // terminal point + m_data.push_back(edge3d(hd, arg, true)); + } + + else + m_data.push_back(edge3d(arg, arg, true)); + + return *this; + } + + + // concatenate path_data segments + path_data& path_data::operator+= (path_data pd) + { + if (!m_closed) + m_data.splice(m_data.end(), pd.m_data); + + return *this; + } + + // concatenate, reversing second sequence + path_data& path_data::operator-= (path_data pd) + { + if (!m_closed) + { + for (std::list<edge3d>::iterator ep=pd.m_data.begin(); + ep != pd.m_data.end(); ++ep) + (*ep).reverse(); // swap tails and heads + + pd.m_data.reverse(); // reverse list order + m_data.splice(m_data.end(), pd.m_data); + } + + return *this; + } + + bool path_data::is_closed() const + { + return m_closed; + } + + bool path_data::is_filled() const + { + return m_filled; + } + + + // set flag and close up if necessary + path_data& path_data::close() + { + if (0 < m_data.size()) + { + m_closed=true; + + const P tail_pt((m_data.begin())->tail()); + const P head_pt((--m_data.end())->head()); + + if (tail_pt != head_pt) + m_data.push_back(edge3d(head_pt, tail_pt, true)); + } + + return *this; + } + + // no action unless we're closed + path_data& path_data::fill(const bool arg) + { + if (m_closed) + m_filled=arg; + return *this; + } + + + path_data& path_data::clip() + { + if (m_closed) + the_clip_box().clip_loop(m_data); + + else + the_clip_box().clip_path(m_data); + + return *this; + } + + path_data& path_data::clip_to(const halfspace& knife) + { + if (m_closed) + knife.clip_loop(m_data); + else + knife.clip_path(m_data); + return *this; + } + + + path_data& path_data::clip_to(const Sphere& S, const P& viewpt, + bool back) + { + const double rad(S.radius()); + + P dir(S.center() - viewpt); + const double dist(norm(dir)); + + if (rad < dist) // viewpt is outside + { + dir *= 1/dist; // unit vector from center to viewpt + double x(rad*rad/dist); + + halfspace knife(S.center() - x*dir, dir); + + if (back) + knife.reverse(); + + clip_to(knife); + } + + else + epix_warning("Can't clip path to sphere from interior viewpoint"); + + return *this; + } + + + void path_data::photo(screen& scr, const Camera& mycam, const Color& fill, + const pen_data& line, const pen_data& base) const + { + path_data tmp_data(*this); + + tmp_data.clip(); // clip_box + if (mycam.needs_clip()) + tmp_data.clip_to(mycam.clip_plane()); + + std::list<edge2d> edges; + unsigned int edge_ct(0); // don't print filled unless >= 3 non-null edges + + for (std::list<edge3d>::const_iterator p=tmp_data.m_data.begin(); + p != tmp_data.m_data.end(); ++p) + { + edge2d tmp(mycam((*p).tail()), mycam((*p).head()), (*p).is_seen()); + + if (!tmp.is_null()) // endpoints not equal + { + ++edge_ct; + edges.push_back(tmp); + } + } + + // draw fill bordered by base, then re-draw border with line/base pens + if (m_filled && 3 <= edge_ct) + { + scr.m_screen->add_tile(pen_fill(mycam(fill), + line.seen_through(mycam), edges)); + if (line.width() < base.width()) + scr.m_screen->add_tile(pen_line(line.seen_through(mycam), + base.seen_through(mycam), edges)); + } + + else if (1 <= edge_ct) + { + // print edges in groups + std::list<edge2d>::iterator p(edges.begin()); + std::list<edge2d> path_buf; + + int count(0); + while (p != edges.end()) + { + path_buf.push_back(*p); + p = edges.erase(p); + + if (++count == 250 || p == edges.end()) // Magic number + { + scr.m_screen->add_tile(pen_line(line.seen_through(mycam), + base.seen_through(mycam), + path_buf)); + path_buf.clear(); + count = 0; + } + } + } + } + + void path_data::draw() const + { + photo(*active_screen(), cam(), the_paint_style().fill_color(), + the_paint_style().line_pen(), the_paint_style().base_pen()); + } + + void path_data::draw(const Color& col, const pen_data& pen) const + { + photo(*active_screen(), cam(), col, pen, Xfine()); + } +} // end of namespace diff --git a/graphics/epix/path_data.h b/graphics/epix/path_data.h new file mode 100644 index 0000000000..fa7803f976 --- /dev/null +++ b/graphics/epix/path_data.h @@ -0,0 +1,101 @@ +/* + * path_data.h -- ePiX implementation classes for polygons and paths + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.18 + * Last Change: September 14, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_PATH_DATA +#define EPIX_PATH_DATA + +#include <list> +#include <vector> + +#include "triples.h" +#include "edge_data.h" + +namespace ePiX { + + class Camera; + class Color; + class halfspace; + class pen_data; + class screen; + class Sphere; + + // sequence of vertices + class path_data { + public: + path_data(); + path_data(const std::vector<P>&, bool closed=false, bool filled=false); + path_data(const std::list<edge3d>&, bool closed=false, bool filled=false); + + path_data* clone() const; + + // add points + path_data& pt(const P&); + + // concatenate path_data segments + path_data& operator+= (path_data); + + // concatenate, reversing second sequence + path_data& operator-= (path_data); + + bool is_closed() const; + bool is_filled() const; + + // make loop and prevent subsequent additions of points + path_data& close(); + + // (un)set fill flag if closed + path_data& fill(const bool arg=true); + + path_data& clip(); + path_data& clip_to(const halfspace&); + + // assumes path already lies on sphere + path_data& clip_to(const Sphere&, const P& viewpt, bool back=false); + + void photo(screen&, const Camera&, const Color& fill, + const pen_data& line, const pen_data& base) const; + + void draw() const; + void draw(const Color&, const pen_data&) const; + + private: + bool m_closed; + bool m_filled; + + std::list<edge3d> m_data; + + }; // end of class path_data + +} // end of namespace + +#endif /* EPIX_PATH_DATA */ diff --git a/graphics/epix/path_style.cc b/graphics/epix/path_style.cc new file mode 100644 index 0000000000..43b93681a4 --- /dev/null +++ b/graphics/epix/path_style.cc @@ -0,0 +1,160 @@ +/* + * path_style.cc -- ePiX's class for path styles. + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.18 + * Last Change: September 15, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> +#include <string> +#include <vector> + +#include "constants.h" + +#include "functions.h" // for snip_to +#include "utils.h" // for get_chars +#include "path_style.h" + +namespace ePiX { + + // true if arg is a string of ch + static bool __epix_all_one_char(const std::string& arg, const char ch) + { + return arg.find_first_not_of(ch) == std::string::npos; + } + + // convert string of dashes, spaces, and periods to a vector of breakpoints + static std::vector<double> __epix_get_breakpts(const std::string& pattern) + { + std::vector<double> value; + + // Assume solid on anomalous input + if (pattern.size() == 0 + || __epix_all_one_char(pattern, '-') + || __epix_all_one_char(pattern, ' ')) + { + value.push_back(0); + value.push_back(1); + + return value; + } + + // else + const unsigned int sz(pattern.size()); // not zero + const double dt(1.0/sz); + + for (unsigned int i=0; i<sz; ++i) + { + if (pattern.at(i) == '-') + { + // previous element was a dash; extend instead of adding breaks + if (0 < value.size() + && fabs(value.at(value.size()-1) - i*dt) < 0.25*dt) + value.at(value.size()-1) = (i+1)*dt; + + else + { + value.push_back(i*dt); + value.push_back((i+1)*dt); + } + } + + else if (pattern.at(i) == '.') + { + value.push_back((i+0.5)*dt); + value.push_back((i+0.5)*dt); // same value twice + } + // spaces have no breakpoints, just increment i + } + + return value; + } // end of __epix_get_breakpts + + + path_state::path_state() + : m_separation(AVG_SEP), m_natural_length(1), m_solid(true) + { + m_breakpoints.push_back(0); + m_breakpoints.push_back(1); + } + + path_state::path_state(std::string arg) + : m_separation(AVG_SEP), m_solid(false) + { + // strip out everything but dash, space, period. + const std::string pattern(get_chars(arg, "- .")); + m_breakpoints = __epix_get_breakpts(pattern); // ok even if pattern="" + + m_natural_length = pattern.size(); + + if (m_breakpoints.at(0) == 0 && m_breakpoints.at(1) == 1) + { + m_solid = true; + m_natural_length = 1; + } + } + + path_state& path_state::separation(double len) + { + if (0 < len) + m_separation = snip_to(len, MIN_SEP, MAX_SEP); + + else + m_separation = AVG_SEP; + + return *this; + } + + double path_state::separation() const + { + return m_separation; + } + + unsigned int path_state::natural_length() const + { + return m_natural_length; + } + + std::vector<double> path_state::breakpts() const + { + return m_breakpoints; + } + + bool path_state::is_solid() const + { + return m_solid; + } + + + path_state& the_path_style() + { + static path_state* the_path_state(new path_state()); + return *the_path_state; + } +} // end of namespace diff --git a/graphics/epix/path_style.h b/graphics/epix/path_style.h new file mode 100644 index 0000000000..988847660e --- /dev/null +++ b/graphics/epix/path_style.h @@ -0,0 +1,83 @@ +/* + * path_style.h -- ePiX's class for solid/dashed/dotted paths + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.7 + * Last Change: July 13, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file implements ePiX's styles for dashed and dotted paths. The + * data are a string containing dashes (-), spaces ( ), and dots (.), + * each of which represents a fixed portion of a path segment, e.g. + * + * Solid: "-" + * Dashed: "- -" + * Dotted: " . " + * Custom: "- . -- . -", etc. + * + * The class in this file implements backend for user-level global + * functions defined in state.h. + * + * This header is not part of epix.h. + */ +#ifndef EPIX_PATH_STYLE +#define EPIX_PATH_STYLE + +#include <string> +#include <vector> + +namespace ePiX { + + class path_state { + public: + path_state(); + path_state(std::string); + + path_state& separation(double len); // dist in pt between adjacent elements + + double separation() const; + unsigned int natural_length() const; + std::vector<double> breakpts() const; + + bool is_solid() const; + + private: + double m_separation; // true length of pattern + std::vector<double> m_breakpoints; // subdivision of [0,1] + + unsigned int m_natural_length; // number of chars in defining string + bool m_solid; + }; // end of class path_state + + path_state& the_path_style(); + +} // end of namespace + +#endif /* EPIX_PATH_STYLE */ diff --git a/graphics/epix/pen_arrow.cc b/graphics/epix/pen_arrow.cc new file mode 100644 index 0000000000..e39dbd906c --- /dev/null +++ b/graphics/epix/pen_arrow.cc @@ -0,0 +1,190 @@ +/* + * pen_arrow.cc -- ePiX::pen_arrow class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <sstream> +#include <list> // for arrow shaft cropping + +#include "pairs.h" +#include "affine.h" +#include "screen_mask.h" + +#include "length.h" + +#include "edge_data.h" + +#include "Color.h" +#include "arrow_style.h" +#include "label_style.h" +#include "marker_style.h" // for bbox marker + +#include "format.h" +#include "picture_data.h" +#include "picture.h" + +#include "tile.h" +#include "pen_arrow.h" + +namespace ePiX { + pen_arrow::pen_arrow(const pair& tail, const pair& head, + const pen_data& line, const pen_data& base, + double scale, double sin_th, bool head_seen) + : m_shaft(tail, head, true), m_line(line), m_base(base), + m_scale(scale), m_shorten(sin_th), m_head_seen(head_seen), + m_style(the_arrowhead_style()) { } + + pen_arrow* pen_arrow::clone() const + { + return new pen_arrow(*this); + } + + pen_arrow& pen_arrow::map_by(const affine& f) + { + m_shaft = edge2d(f(m_shaft.tail()), f(m_shaft.head()), m_shaft.is_seen()); + + return *this; + } + + + pen_arrow& pen_arrow::crop_to(const screen_mask& M) + { + // update head visibility; never re-mark as visible + if (M.crops(m_shaft.head())) + m_head_seen = false; + + // screen masks are convex, so we're cropped iff an end is cropped + if (M.crops(m_shaft.head()) || M.crops(m_shaft.tail())) + { + std::list<edge2d> shaft; + shaft.push_back(m_shaft); + M.crop_path(shaft); + + // search for visible segment; will find no more than one + bool still_seen(false); + + for (std::list<edge2d>::const_iterator ep = shaft.begin(); + ep != shaft.end(); ++ep) + if ((*ep).is_seen()) + { + still_seen = true; + m_shaft = *ep; + } + + if (!still_seen) + { + m_head_seen = false; + m_shaft.seen(false); + } + } + + return *this; + } + + bool pen_arrow::is_empty() const + { + return !(m_head_seen && m_shaft.is_seen()) || m_line.color().is_unset(); + } + + + /* + * + * 1: base, 2: foot, 3: tip, 4: ear_right, 5: ear_left + * + 5 + ... + ......... ..... + .........1 2.....3 + ......... ..... + ... + 4 + * <-height-> + * + * <--> inset (fraction of height) + * + */ + std::string pen_arrow::print_to(const format& fmt, + const std::string& len) const + { + if (is_empty()) + return ""; + + // else + std::stringstream obuf; + + if (m_shaft.tail() == m_shaft.head()) // draw a ddot + { + label_state my_state(the_label_style()); + my_state.text_color(m_line.color()); + + obuf << fmt.print_mark(m_shaft.tail(), pair(0,0), + DDOT, the_mark_size(), my_state, len); + } + + else + { + const pair head(m_shaft.head()); + const double stretch(length("1pt").to(len).magnitude()); + + pair dir(head - m_shaft.tail()); + double dist(norm(dir)); + + const pair unit_dir((stretch/dist)*dir); + const pair unit_perp(J(unit_dir)); + + const double wd(m_scale*m_style.width()); + const double ht(m_style.ratio()*wd*m_shorten); + + const pair base(head - ht*unit_dir); + const pair foot(head - (1-m_style.inset())*ht*unit_dir); + + const pair ear_left(base + wd*unit_perp); + const pair ear_right(base - wd*unit_perp); + + std::list<edge2d> bd; + bd.push_back(edge2d(foot, ear_right, true)); + bd.push_back(edge2d(ear_right, head, true)); + bd.push_back(edge2d(head, ear_left, true)); + bd.push_back(edge2d(ear_left, foot, true)); + + obuf << fmt.print_fill(bd, pair(0,0), m_line.color(), m_line, len); + } + + return obuf.str(); + } + + void pen_arrow::add_to_pallet() const + { + if (!is_empty()) + the_picture().add_to_pallet(m_line.color()) + .add_to_pallet(m_base.color()); + } +} // end of namespace diff --git a/graphics/epix/pen_arrow.h b/graphics/epix/pen_arrow.h new file mode 100644 index 0000000000..09f65e8a42 --- /dev/null +++ b/graphics/epix/pen_arrow.h @@ -0,0 +1,83 @@ +/* + * pen_arrow.cc -- ePiX::pen_arrow class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.8 + * Last Change: July 19, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_PEN_ARROW +#define EPIX_PEN_ARROW + +#include <list> +#include <string> + +#include "edge_data.h" +#include "pen_data.h" +#include "tile.h" + +namespace ePiX { + + class affine; + class screen_mask; + + // arrowhead tile class + class pen_arrow : public tile { + public: + pen_arrow(const pair& tail, const pair& head, + const pen_data& line, const pen_data& base, + double scale, double sin_th, bool head_seen); + + pen_arrow* clone() const; + + pen_arrow& map_by(const affine&); + pen_arrow& crop_to(const screen_mask&); + + bool is_empty() const; + + std::string print_to(const format&, const std::string&) const; + void add_to_pallet() const; + + private: + edge2d m_shaft; + + pen_data m_line; + pen_data m_base; + + double m_scale; // overall scale of head + double m_shorten; // foreshortening factor + + bool m_head_seen; + + arrowhead_state m_style; + }; // end of class pen_arrow + +} // end of namespace + +#endif /* EPIX_PEN_ARROW */ diff --git a/graphics/epix/pen_data.cc b/graphics/epix/pen_data.cc new file mode 100644 index 0000000000..95bcef0ec2 --- /dev/null +++ b/graphics/epix/pen_data.cc @@ -0,0 +1,88 @@ +/* + * pen_data.cc -- ePiX's pen class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.20 + * Last Change: September 19, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "constants.h" + +#include "camera.h" +#include "pen_data.h" + +namespace ePiX { + + pen_data::pen_data(const Color& col, const length& wid) + : m_color(col), m_width(wid) { } + + pen_data::pen_data(const Color& col) + : m_color(col), m_width(PLAIN_WIDTH) { } + + // set + void pen_data::color(const Color& col) { m_color = col; } + void pen_data::width(const length& len) { m_width = len; } + + // get + Color pen_data::color() const { return m_color; } + length pen_data::width() const { return m_width; } + + bool pen_data::operator== (const pen_data& pen) const + { + return ((m_color == pen.m_color) && (m_width == pen.m_width)); + } + + bool pen_data::operator!= (const pen_data& pen) const + { + return !(*this == pen); + } + + pen_data pen_data::seen_through(const Camera& mycam) const + { + Color col(m_color); + if (!col.is_unset()) + col = mycam(col); + + return pen_data(col, m_width); + } + + bool pen_data::is_unset() const + { + return m_color.is_unset() || (m_width < length(EPIX_EPSILON)); + } + + // undrawn + const pen_data& Xfine() + { + static const pen_data* + const xfine_pen(new pen_data(Neutral(), length(0))); + + return *xfine_pen; + } +} // end of namespace diff --git a/graphics/epix/pen_data.h b/graphics/epix/pen_data.h new file mode 100644 index 0000000000..643e7161fe --- /dev/null +++ b/graphics/epix/pen_data.h @@ -0,0 +1,82 @@ +/* + * pen_data.h -- Color and width + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.20 + * Last Change: September 19, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file defines ePiX's concept of a pen (Color and length) + * + * This header is not part of epix.h. + */ +#ifndef EPIX_PEN_DATA +#define EPIX_PEN_DATA + +#include "Color.h" +#include "length.h" + +namespace ePiX { + + class Camera; + + class pen_data { + public: + // plain black + pen_data(const Color& col, const length& wid); + pen_data(const Color& col=Black()); + + // set + void color(const Color& col); + void width(const length& len); + + // get + Color color() const; + length width() const; + + bool operator== (const pen_data& pen) const; + bool operator!= (const pen_data& pen) const; + + pen_data seen_through(const Camera& cam) const; + + bool is_unset() const; + + private: + Color m_color; + length m_width; + }; // end of class pen_data + + + // undrawn + const pen_data& Xfine(); + +} // end of namespace + +#endif /* EPIX_PEN_DATA */ diff --git a/graphics/epix/pen_fill.cc b/graphics/epix/pen_fill.cc new file mode 100644 index 0000000000..5da5de647b --- /dev/null +++ b/graphics/epix/pen_fill.cc @@ -0,0 +1,149 @@ +/* + * pen_fill.cc -- ePiX::pen_fill class, for filled screen elements + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.20 + * Last Change: September 19, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <string> + +#include "functions.h" + +#include "pairs.h" +#include "affine.h" +#include "screen_mask.h" + +#include "length.h" + +#include "pen_data.h" +#include "path_style.h" + +#include "format.h" +#include "picture_data.h" +#include "picture.h" + +#include "edge_data.h" + +#include "tile.h" +#include "pen_fill.h" + +namespace ePiX { + + typedef std::list<edge2d>::const_iterator ep2; + + pen_fill::pen_fill() + : m_tint(Neutral()), m_line(Xfine()), m_style(the_path_style()) { } + + pen_fill::pen_fill(const Color& fill, const pen_data& line, + const std::list<edge2d>& data) + : m_tint(fill), m_line(line), + m_style(the_path_style()), m_border(data), m_edges(data) { } + + pen_fill::pen_fill(const Color& fill, const pen_data& line, double th, + const std::list<edge2d>& data) + : m_tint(fill), m_line(line), + m_style(the_path_style()), m_border(data), m_edges(data) { } + + + pen_fill* pen_fill::clone() const + { + return new pen_fill(*this); + } + + + pen_fill& pen_fill::map_by(const affine& f) + { + if (m_border.size() == 0) + return *this; + + // else map border + std::list<edge2d> bord; + + for (ep2 p=m_border.begin(); p!=m_border.end(); ++p) + bord.push_back(edge2d(f(p->tail()), f(p->head()), (*p).is_seen())); + + swap(m_border, bord); + + // and edges + std::list<edge2d> edges; + + for (ep2 p=m_edges.begin(); p!=m_edges.end(); ++p) + edges.push_back(edge2d(f(p->tail()), f(p->head()), (*p).is_seen())); + + swap(m_edges, edges); + return *this; + } + + + pen_fill& pen_fill::crop_to(const screen_mask& M) + { + m_border = M.crop_loop(m_border); + m_edges = M.crop_path(m_edges); + return *this; + } + + bool pen_fill::is_empty() const + { + return (m_border.size() == 0 + || (m_tint.is_unset() && m_line.is_unset())); + } + + + std::string pen_fill::print_to(const format& fmt, + const std::string& len) const + { + if (is_empty()) + return ""; + + // else at least one is true + bool filled(!m_tint.is_unset()); + bool edged(!m_line.is_unset()); + + // if solid bd, try to draw/fill in one step + if (m_style.is_solid() && filled && edged) + return fmt.print_fill(m_border, pair(0,0), m_tint, m_line, len); + + // else draw fill, border separately + std::string val; + + if (filled) + val += fmt.print_fill(m_border, pair(0,0), m_tint, + pen_data(m_tint, m_line.width()), len); + + if (edged) + val += fmt.print_line(m_edges, pair(0,0), m_line, Xfine(), + m_style, len); + + return val; + } + + void pen_fill::add_to_pallet() const + { + the_picture().add_to_pallet(m_tint).add_to_pallet(m_line.color()); + } +} // end of namespace diff --git a/graphics/epix/pen_fill.h b/graphics/epix/pen_fill.h new file mode 100644 index 0000000000..12abe4707e --- /dev/null +++ b/graphics/epix/pen_fill.h @@ -0,0 +1,83 @@ +/* + * pen_fill.cc -- ePiX::pen_fill class, for filled screen elements + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.11 + * Last Change: August 12, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_PEN_FILL +#define EPIX_PEN_FILL + +#include <list> +#include <string> + +#include "edge_data.h" + +#include "Color.h" +#include "path_style.h" +#include "tile.h" + +namespace ePiX { + + class length; + class screen_mask; + + class pen_fill : public tile { + public: + pen_fill(); + + pen_fill(const Color&, const pen_data&, const std::list<edge2d>&); + + pen_fill(const Color&, const pen_data&, double theta, + const std::list<edge2d>&); + + pen_fill* clone() const; + + pen_fill& map_by(const affine&); + pen_fill& crop_to(const screen_mask&); + + bool is_empty() const; + + std::string print_to(const format&, const std::string&) const; + void add_to_pallet() const; + + private: + Color m_tint; + pen_data m_line; + + path_state m_style; + + std::list<edge2d> m_border; // filled boundary (loop) + std::list<edge2d> m_edges; // visible boundary (path) + }; // end of class pen_fill + +} // end of namespace + +#endif /* EPIX_PEN_FILL */ diff --git a/graphics/epix/pen_line.cc b/graphics/epix/pen_line.cc new file mode 100644 index 0000000000..9ce7621a4d --- /dev/null +++ b/graphics/epix/pen_line.cc @@ -0,0 +1,125 @@ +/* + * pen_line.cc -- ePiX::pen_line class, for line-like objects + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.20 + * Last Change: September 19, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "functions.h" + +#include "pairs.h" +#include "affine.h" +#include "screen_mask.h" + +#include "length.h" + +#include "pen_data.h" +#include "paint_style.h" + +#include "format.h" +#include "picture_data.h" // for add_to_pallet() +#include "picture.h" // for the_picture() + +#include "edge_data.h" + +#include "tile.h" +#include "pen_line.h" + +namespace ePiX { + + typedef std::list<edge2d>::const_iterator ep2; + + pen_line::pen_line() + : m_line(the_paint_style().line_pen()), + m_base(the_paint_style().base_pen()), m_style(the_path_style()) { } + + pen_line::pen_line(const pen_data& line, const pen_data& base, + const std::list<edge2d>& data) + : m_line(line), m_base(base), m_style(the_path_style()), m_border(data) { } + + + pen_line* pen_line::clone() const + { + return new pen_line(*this); + } + + + pen_line& pen_line::map_by(const affine& f) + { + if (m_border.size() == 0) + return *this; + + std::list<edge2d> bord; + + for (ep2 p=m_border.begin(); p!=m_border.end(); ++p) + bord.push_back(edge2d(f(p->tail()), f(p->head()), (*p).is_seen())); + + swap(m_border, bord); + return *this; + } + + + pen_line& pen_line::crop_to(const screen_mask& M) + { + m_border = M.crop_path(m_border); + return *this; + } + + + bool pen_line::is_empty() const + { + // N.B. line trumps base, even if base is otherwise visible + return (m_border.size() == 0 || + m_line.color().is_unset() || + m_line.width() == length(0)); + } + + + std::string pen_line::print_to(const format& fmt, + const std::string& len) const + { + if (is_empty()) + return ""; + + // else + return fmt.print_line(m_border, pair(0,0), m_line, m_base, m_style, len); + } + + void pen_line::add_to_pallet() const + { + // add_to_pallet checks for unset + the_picture().add_to_pallet(m_line.color()) + .add_to_pallet(m_base.color()); + } + + void pen_line::add(const edge2d& E) + { + m_border.push_back(E); + } +} // end of namespace + diff --git a/graphics/epix/pen_line.h b/graphics/epix/pen_line.h new file mode 100644 index 0000000000..6713b5de74 --- /dev/null +++ b/graphics/epix/pen_line.h @@ -0,0 +1,79 @@ +/* + * pen_line.h -- ePiX::pen_line class, for line-like objects + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.3 + * Last Change: March 04, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_PEN_LINE +#define EPIX_PEN_LINE + +#include <list> +#include <string> + +#include "edge_data.h" +#include "pen_data.h" +#include "path_style.h" +#include "tile.h" + +namespace ePiX { + + class length; + class affine; + class screen_mask; + + class pen_line : public tile { + public: + pen_line(); + pen_line(const pen_data&, const pen_data&, const std::list<edge2d>&); + + pen_line* clone() const; + + pen_line& map_by(const affine&); + pen_line& crop_to(const screen_mask&); + + bool is_empty() const; + + std::string print_to(const format&, const std::string&) const; + void add_to_pallet() const; + + void add(const edge2d&); + + private: + pen_data m_line; + pen_data m_base; + + path_state m_style; + + std::list<edge2d> m_border; + + }; // end of class pen_line + +} // end of namespace + +#endif /* EPIX_PEN_LINE */ diff --git a/graphics/epix/picture.cc b/graphics/epix/picture.cc new file mode 100644 index 0000000000..d194edf5f4 --- /dev/null +++ b/graphics/epix/picture.cc @@ -0,0 +1,429 @@ +/* + * picture.cc -- ePiX::epix_picture class, and global functions + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <sstream> + +#include "triples.h" +#include "errors.h" + +#include "functions.h" +#include "length.h" + +#include "verbatim.h" +#include "screen_data.h" + +#include "screen_mask.h" + +#include "screen.h" +#include "active_screen.h" + +#include "eepic.h" +#include "pst.h" +#include "tikz.h" + +#include "picture_data.h" +#include "picture.h" + +namespace ePiX { + + // static objects + picture_data& the_picture() + { + static picture_data* the_root_picture(new picture_data()); + return *the_root_picture; + } + + double& xmin() + { + static double* the_x_min(new double); + return *the_x_min; + } + + double& xmax() + { + static double* the_x_max(new double); + return *the_x_max; + } + + double& xsize() + { + static double* the_x_size(new double); + return *the_x_size; + } + + double& ymin() + { + static double* the_y_min(new double); + return *the_y_min; + } + + double& ymax() + { + static double* the_y_max(new double); + return *the_y_max; + } + + double& ysize() + { + static double* the_y_size(new double); + return *the_y_size; + } + + + double & tix() + { + static double* the_tix(new double); + return *the_tix; + } + + + void bounding_box(const P& arg1, const P& arg2) + { + xmin()=min(arg1.x1(), arg2.x1()); + xmax()=max(arg1.x1(), arg2.x1()); + + ymin()=min(arg1.x2(), arg2.x2()); + ymax()=max(arg1.x2(), arg2.x2()); + + xsize() = xmax() - xmin(); + if (xsize() == 0) + epix_error("Bounding box has width zero!"); + + ysize() = ymax() - ymin(); + if (ysize() == 0) + epix_error("Bounding box has height zero!"); + + // else + the_picture().the_canvas + = screen(P(xmin(), ymin()), P(xmax(), ymax())); + } + + + // one-line initializer + void picture(const P& arg1, const P& arg2, std::string sz) + { + // bounding_box() + the_picture().the_canvas + = screen(P(arg1.x1(), arg1.x2()), P(arg2.x1(), arg2.x2())); + + xmin() = the_picture().the_canvas.h_min(); + xmax() = the_picture().the_canvas.h_max(); + xsize() = the_picture().the_canvas.h_size(); + + ymin() = the_picture().the_canvas.v_min(); + ymax() = the_picture().the_canvas.v_max(); + ysize() = the_picture().the_canvas.v_size(); + + + // parse size string + length pic_hsize, pic_vsize; + get_lengths(sz, pic_hsize, pic_vsize); + + // width units take precedence + std::string u(pic_hsize.units()); + pic_vsize.to(u); + the_picture().the_hoffset.to(u); + the_picture().the_voffset.to(u); + + // unitlength() + the_picture().the_unitlength = length("1"+u); + + // offset() + the_picture().the_hoffset = length("0"+u); + the_picture().the_voffset = length("0"+u); + + // picture() + the_picture().the_page + = screen(P(0,0), P(pic_hsize.magnitude(), pic_vsize.magnitude())); + + if (xsize() == 0 || pic_hsize.magnitude() == 0) + epix_error("Picture has width zero!"); + + if (ysize() == 0 || pic_vsize.magnitude() == 0) + epix_error("Picture has height zero!"); + } + + // old initializers + void picture(double horiz, double vert) + { + if (horiz == 0) + epix_error("Picture has width zero!"); + + if (vert == 0) + epix_error("Picture has height zero!"); + + the_picture().the_page = screen(P(0,0), P(horiz, vert)); + } + + void picture(const P& arg) + { + picture(arg.x1(), arg.x2()); + } + + // same syntax as for picture dimensions + void offset(std::string sz) + { + length hoff, voff; + std::string units(the_picture().the_unitlength.units()); + + get_lengths(sz, hoff, voff); + + the_picture().the_hoffset=hoff.to(units); + the_picture().the_voffset=voff.to(units); + } + + void offset(double hoff, double voff) + { + std::string u(the_picture().the_unitlength.units()); + + std::stringstream hbuf, vbuf; + hbuf << hoff << u; + vbuf << voff << u; + + the_picture().the_hoffset = length(hbuf.str()); + the_picture().the_voffset = length(vbuf.str()); + } + + void offset(const P& arg) + { + offset(arg.x1(), arg.x2()); + } + + void unitlength(const std::string& units) + { + the_picture().the_unitlength = length(units); + } + + + void begin() + { + const double mult(the_picture().the_unitlength.magnitude()); + if (mult != 1) // someone called unitlength(); must adjust size, offsets + { + const P TR(the_picture().the_page.tr()); + the_picture().the_page = screen(P(0,0), mult*TR); + + the_picture().the_hoffset *= mult; + the_picture().the_voffset *= mult; + } + + // If we've seen bounding_box or equivalent, this properly initializes. + // Otherwise we'll segfault momentarily... :( + active_screen(); + } + + void end_picture() + { + the_picture().print(); + } + + screen& canvas() + { + return the_picture().the_canvas; + } + + void activate(screen& scr) + { + the_screen_stack().push(scr); + } + + void deactivate(screen& scr) + { + const screen* active(the_screen_stack().pop()); + + if (active != &scr) + epix_warning("Deactivation requested for non-active screen"); + } + + // page layout + void import() + { + if (&(the_picture().the_canvas) != active_screen()) + the_picture().the_canvas.paste(*active_screen()); + } + + void inset(const P& sw, const P& ne) + { + if (&(the_picture().the_canvas) != active_screen()) + the_picture().the_canvas.paste(*active_screen(), sw, ne); + } + + + void import(const screen& child) + { + the_picture().the_canvas.paste(child); + } + + void inset(const screen& child, const P& sw, const P& ne) + { + the_picture().the_canvas.paste(child, sw, ne); + } + + void inset(const screen& child) + { + the_picture().the_canvas.paste(child, child.bl(), child.tr()); + } + + void inlay(const screen& child, const P& loc) + { + const std::string units(the_picture().the_unitlength.units()); + const double scale(length("1pt").to(units).magnitude()); + double H(active_screen()->h_size()/the_picture().the_page.h_size()); + double V(active_screen()->v_size()/the_picture().the_page.v_size()); + + active_screen()->paste(child, + loc + H*scale*child.bl(), + loc + V*scale*child.tr()); + } + + // interpret stated coord as true pt, the other as Cartesian + void inlay_vertical(const screen& child, const P& loc) + { + const std::string units(the_picture().the_unitlength.units()); + const double scale(length("1pt").to(units).magnitude()); + double V(active_screen()->v_size()/the_picture().the_page.v_size()); + + active_screen()->paste(child, + loc + child.l() + V*scale*child.b(), + loc + child.r() + V*scale*child.t()); + } + + void inlay_horizontal(const screen& child, const P& loc) + { + const std::string units(the_picture().the_unitlength.units()); + const double scale(length("1pt").to(units).magnitude()); + double H(active_screen()->h_size()/the_picture().the_page.h_size()); + + active_screen()->paste(child, + loc + child.b() + H*scale*child.l(), + loc + child.t() + H*scale*child.r()); + } + + void backing(const Color& col) + { + active_screen()->backing(col); + } + + void border(const Color& col, double len) + { + active_screen()->border(col, len); + } + + void border(const Color& col, const std::string& len) + { + active_screen()->border(col, len); + } + + void backing() + { + active_screen()->backing(); + } + + void border() + { + active_screen()->border(); + } + + void write(const std::string& text) + { + active_screen()->m_screen->add_tile(verbatim(text)); + } + + void pre_write(const std::string& text) + { + the_picture().pre_write(text); + } + + void post_write(const std::string& text) + { + the_picture().post_write(text); + } + + void eepic_format() + { + the_picture().set_format(eepic()); + } + + void tikz_format() + { + the_picture().set_format(tikz()); + } + + void pst_format() + { + the_picture().set_format(pst()); + } + + + // write in specified format to named output file + void print_eepic(const std::string& filename) + { + the_picture().print_to(filename, eepic()); + } + + void print_tikz(const std::string& filename) + { + the_picture().print_to(filename, tikz()); + } + + void print_pst(const std::string& filename) + { + the_picture().print_to(filename, pst()); + } + + + double pic_units_per_pt() + { + return length("1pt").to(the_picture().the_unitlength.units()).magnitude(); + } + + // approximate, but correct at true aspect ratio + double units_per_pic_unit() + { + const double H(active_screen()->h_size()/the_picture().the_page.h_size()); + const double V(active_screen()->v_size()/the_picture().the_page.v_size()); + + return 0.5*(H+V); + } + + double pt_to_screen(double arg) + { + return arg*units_per_pic_unit()*pic_units_per_pt(); + } + + // initialize deprecated globals + double x_min(xmin()), x_max(xmax()), x_size(xsize()); + double y_min(ymin()), y_max(ymax()), y_size(ysize()); + +} // end of namespace diff --git a/graphics/epix/picture.h b/graphics/epix/picture.h new file mode 100644 index 0000000000..38258fc02c --- /dev/null +++ b/graphics/epix/picture.h @@ -0,0 +1,170 @@ +/* + * picture.h -- ePiX globals functions for picture interface + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.16 + * Last Change: September 11, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_PICTURE +#define EPIX_PICTURE + +#include <string> + +namespace ePiX { + + class Color; + class P; + class picture_data; + class screen; + + // "global" references + picture_data& the_picture(); + + double& xmin(); + double& xmax(); + double& xsize(); + + double& ymin(); + double& ymax(); + double& ysize(); + + double& tix(); + + // preferred initialization functions + // corners and dimensions, e.g. "4in x 15cm" or "4 x 6in" + // (width units take precedence, dimension string must be passed by value) + void picture(const P& arg1, const P& arg2, std::string); + + // same syntax as for picture dimensions + void offset(std::string); + + //// Old global functions for manipulating the page markup region //// + void bounding_box(const P&, const P&); + + void picture(double, double); + void picture(const P&); + + void offset(double hoff, double voff); + void offset(const P& arg); + + void unitlength(const std::string& units); + + // activate default screen + void begin(); + // write the output file + void end_picture(); + + //// New global functions //// + // the_picture().the_canvas + screen& canvas(); + + // specify active screen; pass non-const ref only to assign/compare pointer + void activate(screen&); + void deactivate(screen&); + + // add active or specified screen to the_picture + void import(); + void inset(const P& sw, const P& ne); + + void import(const screen& child); + void inset(const screen& child, const P& sw, const P& ne); + + void inset(const screen& child); // use child's corners + + // interpret child's coordinates as true pt on the page, + // place origin at P + void inlay(const screen& child, const P& loc); + + // interpret stated coord as true pt, the other as Cartesian + void inlay_vertical(const screen& child, const P& loc); + void inlay_horizontal(const screen& child, const P& loc); + + // set decorations on active screen + void backing(const Color&); + void border(const Color&, double); // width in pt + void border(const Color&, const std::string&); + + void backing(); // use current fill style + void border(); // use current line pen + + // write verbatim string to output file + void write(const std::string&); + + void pre_write(const std::string&); // before picture header + void post_write(const std::string&); // after picture footer + + // set output format + void eepic_format(); + // void mp_format(); + void tikz_format(); + void pst_format(); + + // write in specified format to named output file + void print_eepic(const std::string& filename); + // void print_mp(const std::string& filename); + void print_tikz(const std::string& filename); + void print_pst(const std::string& filename); + + // allow user to override in-file format request on the command line + inline void end() + { +#ifdef EPIX_FMT_PSTRICKS + pst_format(); +#else +#ifdef EPIX_FMT_TIKZ + tikz_format(); +#else +#ifdef EPIX_FMT_EEPIC + eepic_format(); +#endif /* EPIX_FMT_EEPIC */ +#endif /* EPIX_FMT_TIKZ */ +#endif /* EPIX_FMT_PSTRICKS */ + end_picture(); + } + + // for implementors of true-size elements + double pic_units_per_pt(); // exact + double units_per_pic_unit(); // approximate, exact at true aspect ratio + double pt_to_screen(double); // true length to screen length + + //////////////////////////////////////////////////////////////// + //// //// + //// DEPRECATED global variables required for backward //// + //// compatibility. Will be removed in a future release. //// + //// Use reference functions xmin() et. al. //// + //// //// + //////////////////////////////////////////////////////////////// + + // bounding_box corners and dimensions + extern double x_min, x_max, x_size, y_min, y_max, y_size; + +} // end of namespace + +#endif /* EPIX_PICTURE */ diff --git a/graphics/epix/picture_data.cc b/graphics/epix/picture_data.cc new file mode 100644 index 0000000000..a16c0552b8 --- /dev/null +++ b/graphics/epix/picture_data.cc @@ -0,0 +1,193 @@ +/* + * picture_data.cc -- ePiX::picture implementation class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.18 + * Last Change: September 14, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <iostream> +#include <fstream> +#include <sstream> + +#include "errors.h" +#include "utils.h" +#include "Color.h" + +#include "verbatim.h" + +#include "format.h" +#include "eepic.h" // default format +#include "picture.h" + +#include "screen_data.h" +#include "picture_data.h" + +namespace ePiX { + + picture_data::picture_data() + : m_format(new eepic()), m_pallet() { } + + + picture_data::picture_data(const picture_data& pd) + : the_unitlength(pd.the_unitlength), + the_hoffset(pd.the_hoffset), the_voffset(pd.the_voffset), + the_canvas(pd.the_canvas), the_page(pd.the_page), + m_format(pd.m_format->clone()), m_pallet(pd.m_pallet), + m_pre_writes(pd.m_pre_writes), m_post_writes(pd.m_post_writes) { } + + + picture_data& picture_data::operator= (const picture_data& pd) + { + if (this != &pd) + { + format* tmp_fmt(pd.m_format->clone()); + + // okay, safe to muck with our data + the_unitlength = pd.the_unitlength; + the_hoffset = pd.the_hoffset; + the_voffset = pd.the_voffset; + + the_canvas = pd.the_canvas; + the_page = pd.the_page; + + delete m_format; + m_format = tmp_fmt; + + m_pallet = pd.m_pallet; + + m_pre_writes = pd.m_pre_writes; + m_post_writes = pd.m_post_writes; + } + + return *this; + } // end of copy assignment + + picture_data::~picture_data() + { + delete m_format; + } + + + picture_data& picture_data::add_to_pallet(const Color& col) + { + if (!col.is_unset()) + m_pallet.insert(col); + return *this; + } + + void picture_data::set_format(const format& fmt) + { + m_format = fmt.clone(); + } + + void picture_data::print() + { + print_to(*m_format); + } + + void picture_data::print_to(const format& fmt) + { + the_page.clear(); + the_page.paste(the_canvas); + + const pair offset(the_hoffset.magnitude(), the_voffset.magnitude()); + + std::cout << fmt.file_comments(the_unitlength.units(), + the_hoffset, the_voffset, + xmin(), xmax(), ymin(), ymax(), + the_page.h_size(), the_page.v_size()); + + for (std::list<verbatim>::const_iterator p = m_pre_writes.begin(); + p != m_pre_writes.end(); ++p) + std::cout << (*p).print_to(fmt, the_unitlength.units()); + + // the_page.br() = (0,0), so tr() is size + std::cout << fmt.pic_header(the_page.tr(), offset, + m_pallet, the_unitlength.units()) + + << the_page.m_screen->print_to(fmt, the_unitlength) + + << fmt.pic_footer(); + + for (std::list<verbatim>::const_iterator p = m_post_writes.begin(); + p != m_post_writes.end(); ++p) + std::cout << (*p).print_to(fmt, the_unitlength.units()); + } + + void picture_data::print_to(const std::string& filename, const format& fmt) + { + const char* fn(filename.c_str()); + + std::ofstream output(fn); + if (!output) + { + epix_warning("Cannot open file " + filename); + return; + } + + // else + the_page.clear(); + the_page.paste(the_canvas); + + const pair offset(the_hoffset.magnitude(), the_voffset.magnitude()); + + output << fmt.file_comments(the_unitlength.units(), + the_hoffset, the_voffset, + xmin(), xmax(), ymin(), ymax(), + the_page.h_size(), the_page.v_size()); + + for (std::list<verbatim>::const_iterator p = m_pre_writes.begin(); + p != m_pre_writes.end(); ++p) + output << (*p).print_to(fmt, the_unitlength.units()); + + // the_page.br() = (0,0), so tr() is size + output << fmt.pic_header(the_page.tr(), offset, + m_pallet, the_unitlength.units()) + + << the_page.m_screen->print_to(fmt, the_unitlength) + + << fmt.pic_footer(); + + for (std::list<verbatim>::const_iterator p = m_post_writes.begin(); + p != m_post_writes.end(); ++p) + output << (*p).print_to(fmt, the_unitlength.units()); + + output.close(); + } + + void picture_data::pre_write(const std::string& text) + { + m_pre_writes.push_back(verbatim(text)); + } + + void picture_data::post_write(const std::string& text) + { + m_post_writes.push_back(verbatim(text)); + } +} // end of namespace diff --git a/graphics/epix/picture_data.h b/graphics/epix/picture_data.h new file mode 100644 index 0000000000..518dbb966b --- /dev/null +++ b/graphics/epix/picture_data.h @@ -0,0 +1,113 @@ +/* + * picture_data.h -- ePiX::picture implementation class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.7 + * Last Change: July 14, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * The picture_data class was designed with three primary goals: + * + * (i) Encapsulate state data formerly scattered (and inconsistently + * structured) through multiple files, + * + * (ii) Provide some of the flexibility of building a scene in memory + * instead of writing data immediately to the output, + * + * (iii) Ensure compatibility with existing syntax. + * + * A picture_data comprises two screens (canvas -- the bounding_box, and + * page -- the picture box), unitlength and offsets, state data + * (clip_box; angle units; styles for labels, painting, and arrowheads), + * and a set of colors so that color dclarations in the output file can + * be made using named colors. + * + * Dozens of global and member functions need to access and modify + * the_picture(). Instead of making these functions friends, our data + * (except for the color pallet) are public. Under the circumstances, + * this seemed the Path of Least Evil. + */ +#ifndef EPIX_PICTURE_DATA +#define EPIX_PICTURE_DATA + +#include <string> +#include <list> +#include <set> + +#include "verbatim.h" + +#include "length.h" +#include "Color.h" +#include "screen.h" + +namespace ePiX { + + class format; + + class picture_data { + public: + // rely on members' default constructors + picture_data(); + + picture_data(const picture_data&); + picture_data& operator= (const picture_data&); + ~picture_data(); + + picture_data& add_to_pallet(const Color&); + + void set_format(const format&); + + // output requires knowledge of unitlength; all other ops handled by data + void print(); + void print_to(const format&); + void print_to(const std::string& filename, const format&); + + void pre_write(const std::string&); + void post_write(const std::string&); + + //// public data (true size, offsets, and screens) //// + length the_unitlength; + length the_hoffset, the_voffset; + + screen the_canvas; + screen the_page; + + + private: + format* m_format; + std::set<Color> m_pallet; + // user-specified strings to be written before/after start of picture + std::list<verbatim> m_pre_writes; + std::list<verbatim> m_post_writes; + }; // end of class picture_data + +} // end of namespace + +#endif /* EPIX_PICTURE_DATA */ diff --git a/graphics/epix/plane.cc b/graphics/epix/plane.cc new file mode 100644 index 0000000000..148e81a7e0 --- /dev/null +++ b/graphics/epix/plane.cc @@ -0,0 +1,143 @@ +/* + * plane.cc -- ePiX::Plane class and mathematical operators + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * Last Change: September 13, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "constants.h" +#include "errors.h" + +#include "curves.h" // for draw() + +#include "plane.h" + +namespace ePiX { + + const double INF(2*EPIX_INFTY); + + Plane::Plane(const P& pt, const P& perp) + : m_pt(pt), m_perp(perp), m_malformed(false) + { + double temp(norm(perp)); + + if (temp < EPIX_EPSILON) + { + epix_warning("Degenerate plane normal, using (0,0,1)"); + m_perp=E_3; + } + + else + m_perp *= 1.0/temp; + } + + Plane::Plane(const P& p1, const P& p2, const P& p3) + : m_pt(p1), m_malformed(false) + { + P perp((p3-p1)*(p2-p1)); + double norm_perp(norm(perp)); + + if (norm_perp < EPIX_EPSILON) + { + epix_warning("Collinear points in Plane constructor"); + m_malformed = true; + } + + else + m_perp = (1/norm_perp)*perp; + } + + + P Plane::pt() const + { + return m_pt; + } + + P Plane::perp() const + { + return m_perp; + } + + bool Plane::malformed() const + { + return m_malformed; + } + + // translate + Plane& Plane::shift(const P& arg) + { + if (!m_malformed) + m_pt += arg; + return *this; + } + + Plane& Plane::move_to(const P& arg) + { + if (!m_malformed) + m_pt = arg; + return *this; + } + + void Plane::draw() const + { + if (m_malformed) + return; + + // else + const P ctr((m_pt|m_perp)*m_perp); // closest point to origin + + // construct an orthonormal basis + P e1(m_perp*E_1); + + if (norm(e1) < 0.7) // ~sqrt(0.5) + e1 = m_perp*E_2; + + e1 *= 1.0/norm(e1); + P e2(m_perp*e1); + + // very large rectangle + quad(ctr + INF*( e1 + e2), ctr + INF*(-e1 + e2), + ctr + INF*(-e1 - e2), ctr + INF*( e1 - e2)); + } + + + //// global functions //// + void plane(const P& point, const P& normal) + { + Plane pl(point, normal); + pl.draw(); + } + + void plane(const P& p1, const P& p2, const P& p3) + { + Plane pl(p1, p2, p3); + pl.draw(); + } +} // end of namespace diff --git a/graphics/epix/plane.h b/graphics/epix/plane.h new file mode 100644 index 0000000000..637e3e8240 --- /dev/null +++ b/graphics/epix/plane.h @@ -0,0 +1,74 @@ +/* + * plane.h -- ePiX::Plane class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.17 + * Last Change: September 13, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_PLANE +#define EPIX_PLANE + +#include "triples.h" + +namespace ePiX { + + class Circle; + class Plane; + class Segment; + class Sphere; + + class Plane { + public: + Plane(const P& pt=P(0,0,0), const P& perp=E_3); + Plane(const P&, const P&, const P&); + + P pt() const; + P perp() const; + bool malformed() const; + + // affine operations + Plane& shift(const P&); + Plane& move_to(const P&); + + void draw() const; + + private: + P m_pt; + P m_perp; // unit normal + + bool m_malformed; + }; // end of Plane class + + void plane(const P& pt=P(0,0,0), const P& perp=E_3); + void plane(const P&, const P&, const P&); + +} // end of namespace + +#endif /* EPIX_PLANE */ diff --git a/graphics/epix/plot_algorithms.h b/graphics/epix/plot_algorithms.h new file mode 100644 index 0000000000..3566915f09 --- /dev/null +++ b/graphics/epix/plot_algorithms.h @@ -0,0 +1,245 @@ +/* + * plot_algorithms.h -- plot function templates, for build use only + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * + * Version 1.1.9 + * Last Change: August 01, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file provides plotting templates, with T a class + * + * void plot_map_dom(const T&, const domain&) + * void plot_map_domlist(const T&, const domain_list&) + * void plot_function(const T&, double, double, int) + * void euler_plot(const T&, const P&, double, double, int) + * P euler_flow(const T&, P start, double, int) + */ + +#ifndef EPIX_PLOT_ALGO +#define EPIX_PLOT_ALGO + +#include <cmath> +#include <list> + +#include "constants.h" + +#include "triples.h" +#include "functions.h" + +#include "edge_data.h" + +#include "paint_style.h" + +#include "domain.h" +#include "path_data.h" + +namespace ePiX { + + typedef std::list<domain>::const_iterator dolci; + + const double INF(EPIX_INFTY); + + // Are args endpoints of a plottable edge? + static bool is_valid(const P& tail, const P& head) + { + return tail.is_valid() && head.is_valid(); + } + + template<class T> void plot_map_dom(const T& map, const domain& R) + { + // only attempt to fill if plotting a curve + const bool is_curve(R.dim() == 1); + const bool filling(is_curve && the_paint_style().fill_flag()); + + // max summation indices + unsigned int i_max((R.dx1() > 0) ? R.coarse_n1() : 0); + unsigned int j_max((R.dx2() > 0) ? R.coarse_n2() : 0); + unsigned int k_max((R.dx3() > 0) ? R.coarse_n3() : 0); + + if (R.dx1() > 0) // there's something to draw + { + // number of intervals in subdivision + unsigned int count1(R.fine_n1()); + + const double st1(R.dx1()); + const double st2(R.step2()); + const double st3(R.step3()); + + for (unsigned int j=0; j <= j_max; ++j) + for (unsigned int k=0; k <= k_max; ++k) + { + std::list<edge3d> data1; + const P init(R.corner1() + (j*st2)*E_2 + (k*st3)*E_3); + + for (unsigned int i=0; i < count1; ++i) + { + P curr(map(init + P(i*st1,0,0))); + P next(map(init + P((i+1)*st1,0,0))); + data1.push_back(edge3d(curr, next, is_valid(curr, next))); + } + + // close path if initial and terminal points coincide + bool closed(is_curve && + map(init) == map(init + P(count1*st1,0,0))); + + path_data path1(data1, closed && filling, filling); + path1.draw(); + } + } + + if (R.dx2() > 0) + { + unsigned int count2(R.fine_n2()); + + const double st1(R.step1()); + const double st2(R.dx2()); + const double st3(R.step3()); + + for (unsigned int i=0; i <= i_max; ++i) + for (unsigned int k=0; k <= k_max; ++k) + { + std::list<edge3d> data2; + const P init(R.corner1() + (i*st1)*E_1 + (k*st3)*E_3); + + for (unsigned int j=0; j < count2; ++j) + { + P curr(map(init + P(0,j*st2,0))); + P next(map(init + P(0,(j+1)*st2,0))); + data2.push_back(edge3d(curr, next, is_valid(curr, next))); + } + + // close path if initial and terminal points coincide + bool closed(is_curve && + map(init) == map(init + P(0,count2*st2,0))); + + path_data path2(data2, closed && filling, filling); + path2.draw(); + } + } + + if (R.dx3() > 0) + { + unsigned int count3(R.fine_n3()); + + const double st1(R.step1()); + const double st2(R.step2()); + const double st3(R.dx3()); + + for (unsigned int i=0; i <= i_max; ++i) + for (unsigned int j=0; j <= j_max; ++j) + { + std::list<edge3d> data3; + const P init(R.corner1() + (i*st1)*E_1 + (j*st2)*E_2); + + for (unsigned int k=0; k < count3; ++k) + { + P curr(map(init + P(0,0,k*st3))); + P next(map(init + P(0,0,(k+1)*st3))); + data3.push_back(edge3d(curr, next, is_valid(curr, next))); + } + + // close path if initial and terminal points coincide + bool closed(is_curve && + map(init) == map(init + P(0,0,count3*st3))); + + path_data path3(data3, closed && filling, filling); + path3.draw(); + } + } + }; // end of plot_map_dom + + // plot over a list of domains + template<class T> void plot_map_domlist(const T& map, const domain_list& R) + { + for (dolci p=R.m_list.begin(); p != R.m_list.end(); ++p) + plot_map_dom(map, *p); + } + + // paths + template<class T>void plot_function(const T& f, double t1, double t2, + unsigned int n) + { + plot_map_dom(f, domain(t1, t2, n)); + } + + + // Solutions of ODE systems + template<class VF> void euler_plot(const VF& field, P curr, + double t_min, double t_max, + unsigned int num_pts) + { + std::list<edge3d> data; + + const double dt(t_max/(num_pts*EPIX_ITERATIONS)); + const double dseek(t_min/(num_pts*EPIX_ITERATIONS)); + + if (fabs(t_min/num_pts) > EPIX_EPSILON) // seek beginning of path + for (unsigned int i=0; i <= num_pts*EPIX_ITERATIONS; ++i) + curr += dseek*field(curr); + + // curr = "start, flowed by t_min" + P next(curr); + + for (unsigned int i=0; i <= num_pts*EPIX_ITERATIONS; ++i) + { + next += dt*field(next); // Euler's method + + if (i%EPIX_ITERATIONS == 0) + { + data.push_back(edge3d(curr, next, is_valid(curr, next))); + curr = next; + } + } + + path_data temp(data, false, false); + + temp.draw(); + } // end of euler_plot + + + // flow x0 under field for specified time; pass x0 by value + template<class VF> P euler_flow(const VF& field, P x0, + double t_max, unsigned int num_pts=0) + { + if (num_pts == 0) // use "sensible" default; hardwired constant 4 + num_pts = 4*(1 + (unsigned int)ceil(fabs(t_max))); + + const double dt(t_max/(num_pts*EPIX_ITERATIONS)); + + for (unsigned int i=0; i <= num_pts*EPIX_ITERATIONS; ++i) + x0 += dt*field(x0); + + return x0; + } +} // end of namespace + +#endif /* EPIX_PLOT_ALGO */ diff --git a/graphics/epix/plots.cc b/graphics/epix/plots.cc new file mode 100644 index 0000000000..5f619dbe40 --- /dev/null +++ b/graphics/epix/plots.cc @@ -0,0 +1,613 @@ +/* + * plots.cc: Plotting functions + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "constants.h" +#include "errors.h" + +#include "triples.h" +#include "functions.h" + +#include "camera.h" +#include "map.h" +#include "domain.h" + +#include "path.h" + +#include "markers.h" +#include "curves.h" + +#include "deriv.h" +#include "plot_algorithms.h" +#include "plots.h" + +namespace ePiX { + + typedef std::list<domain>::const_iterator dolci; + + // f:R -> R^3 + void plot(P f(double), double t_min, double t_max, unsigned int num_pts) + { + plot_map_dom(path_map(f), domain(t_min, t_max, num_pts)); + } + + // f:R -> R x R x R + void plot(double f1(double), double f2(double), double f3(double), + double t_min, double t_max, unsigned int num_pts) + { + plot_map_dom(column_1var(f1,f2,f3), domain(t_min, t_max, num_pts)); + } + + // f:R -> R + void plot(double f(double), double t_min, double t_max, unsigned int num_pts) + { + plot(id, f, zero, t_min, t_max, num_pts); + } + + void plot(const Deriv& f, double t_min, double t_max, unsigned int num_pts) + { + plot_map_dom(f, domain(t_min, t_max, num_pts)); + } + + void plot(const Integral& f, double t_min, double t_max, + unsigned int num_pts) + { + plot_map_dom(f, domain(t_min, t_max, num_pts)); + } + + // f: R -> R x R + void plot(double f1(double), double f2(double), + double t_min, double t_max, unsigned int num_pts) + { + plot(f1, f2, zero, t_min, t_max, num_pts); + } + + void polarplot (double f(double), double t_min, double t_max, + unsigned int num_pts) + { + plot_map_dom(column_1var(f, id, zero, cylindrical), + domain(t_min, t_max, num_pts)); + } + + // surfaces + // f:R^2 -> R x R x R + void plot(double f1(double u1, double u2), + double f2(double u1, double u2), + double f3(double u1, double u2), + const P& min, const P& max, const mesh& coarse, const mesh& fine) + { + plot_map_dom(column_2var(f1,f2,f3), domain(min, max, coarse, fine)); + } + + void plot(double f1(double u1, double u2), + double f2(double u1, double u2), + double f3(double u1, double u2), + const domain& R) + { + plot_map_dom(column_2var(f1,f2,f3), R); + } + + // f:R^2 -> R + void plot(double f(double u1, double u2), + const P& p1, const P& p2, const mesh& coarse, const mesh& fine) + { + plot(proj1, proj2, f, p1, p2, coarse, fine); + } + + // f:R^2 -> R^3 + void plot(P f(double u1, double u2), const domain& R) + { + plot_map_dom(surface_map(f), R); + } + + void plot(P f(double u1, double u2), const domain_list& R) + { + surface_map phi(f); + + for (dolci p=R.m_list.begin(); p != R.m_list.end(); ++p) + plot_map_dom(phi, *p); + } + + + // f:R^3 -> R^3 + void plot(P f(double, double, double), const domain& R) + { + plot_map_dom(space_map(f), R); + } + + void plot(P f(double, double, double), const domain_list& R) + { + space_map phi(f); + + for (dolci p=R.m_list.begin(); p != R.m_list.end(); ++p) + plot_map_dom(phi, *p); + } + + + // Derivatives and integrals + void plot_deriv(double f(double t), double a, double b, + unsigned int num_pts) + { + plot_function(Deriv(f), a, b, num_pts); + } + + void plot_int(double f(double), double a, double b, + unsigned int num_pts) + { + plot_function(Integral(f, a), a, b, num_pts); + } + + void plot_int(double f(double), double x0, double a, double b, + unsigned int num_pts) + { + plot_function(Integral(f, x0), a, b, num_pts); + } + + // tuples of real-valued plot arguments + void tan_line(double f1(double t), double f2(double t), double t0) + { + Line(P(f1(t0), f2(t0)), + P(f1(t0), f2(t0)) + P(deriv(f1, t0), deriv(f2, t0))); + } + + void tan_line(double f(double t), double t0) + { + Line(P(t0, f(t0)), P(t0, f(t0)) + P(1, deriv(f, t0))); + } + + void envelope(double f1(double t), double f2(double t), + double t_min, double t_max, unsigned int num_pts) + { + const double step((t_max - t_min)/num_pts); + double t(t_min); + + for (unsigned int i=0; i <= num_pts; ++i, t += step) + Line(P(f1(t), f2(t)), + P(f1(t), f2(t)) + P(deriv(f1, t), deriv(f2, t))); + } + + void envelope(double f(double t), double t_min, double t_max, + unsigned int num_pts) + { + const double step((t_max - t_min)/num_pts); + double t(t_min); + + for (unsigned int i=0; i <= num_pts; ++i, t += step) + Line(P(t, f(t)), P(t, f(t)) + P(1, deriv(f, t))); + } + + // P-valued plot argument + void tan_line(P f(double t), double t0) + { + Line(f(t0), f(t0) + deriv(f, t0)); + } + + void envelope(P f(double t), double t_min, double t_max, + unsigned int num_pts) + { + const double step((t_max - t_min)/num_pts); + double t(t_min); + + for (unsigned int i=0; i <= num_pts; ++i, t += step) + Line(f(t), f(t) + deriv(f, t)); + } + + // Tangent field along parametrized path + void tan_field(double f1(double), double f2(double), double t_min, + double t_max, unsigned int num_pts) + { + const double step((t_max - t_min)/num_pts); + double t(t_min); + + for (unsigned int i=0; i <= num_pts; ++i, t += step) + arrow(P(f1(t), f2(t)), P(f1(t), f2(t)) + + step*P(deriv(f1, t), deriv(f2, t))); + } + + // P-valued plot argument + void tan_field(P f(double), double t_min, double t_max, + unsigned int num_pts) + { + const double step((t_max - t_min)/num_pts); + double t(t_min); + + for (unsigned int i=0; i <= num_pts; ++i, t += step) + arrow(f(t), f(t) + step*deriv(f, t)); + } + + // Slope, dart, and vector fields + + // utility functions + // vector, dart, and slope fields + void field_element(const P& tail, const P& head, epix_field_type TYPE, + double head_scale=1.0) + { + switch(TYPE) { + + case VECTOR: + arrow(tail, head, head_scale); + break; + + case DART: + dart(tail, head); + break; + + case SLOPE: + line(tail, head, 0, 1); + break; + + default: + ; // do nothing + } // end of switch(TYPE) + } // end of field_element + + + void draw_field(P F(double, double, double), P p, P q, + unsigned int n1, unsigned int n2, + epix_field_type TYPE, double scale) + { + P diagonal(q-p); + int perp_count(0); + P jump1, jump2; + + if (fabs(diagonal|E_1) < EPIX_EPSILON) + { + ++perp_count; + jump1 = E_2&diagonal; + jump2 = E_3&diagonal; + + } + if (fabs(diagonal|E_2) < EPIX_EPSILON) + { + ++perp_count; + jump1 = E_3&diagonal; + jump2 = E_1&diagonal; + } + if (fabs(diagonal|E_3) < EPIX_EPSILON) + { + ++perp_count; + jump1 = E_1&diagonal; + jump2 = E_2&diagonal; + } + + if (perp_count == 0) + { + epix_warning("Projecting corners of vector field plot"); + jump1 = E_1&diagonal; + jump2 = E_2&diagonal; + p %= E_3; // project corners to (x1, x2)-plane + q %= E_3; + } + + // grid line spacing + jump1 *= 1.0/n1; + jump2 *= 1.0/n2; + + const double d1(norm(jump1)); + const double d2(norm(jump2)); + + for (unsigned int i=0; i <= n1; ++i) + for (unsigned int j=0; j <= n2; ++j) + { + P base(p + (i*jump1 + j*jump2)); + P vect(F(base.x1(), base.x2(), base.x3())); + + if (norm(camera(base+vect) - camera(base)) < EPIX_EPSILON) + marker(base, BBOX); + + else if (TYPE == VECTOR) + field_element(base, base + vect, VECTOR, scale); + + else + { + // N.B. May not work if page export bolloxes aspect ratio + double object_len(norm(camera(base+vect)-camera(base))); + pair dX(pair(d1, d2)); + + // Hardwired constant 0.4: Segment 80% of shorter grid length + double minimum((dX.x1() > dX.x2()) ? 0.4*dX.x2() : 0.4*dX.x1()); + + if ( object_len > EPIX_EPSILON) // not projected to zero + vect *= minimum/object_len; + + // scale affects length of element, not head size + field_element(base - scale*vect, base + scale*vect, TYPE); + } + } + } // end of draw_field F(x, y, z) + + + void draw_field(P F(double, double), P p, P q, + unsigned int n1, unsigned int n2, + epix_field_type TYPE, double scale) + { + P diagonal(q-p); + P jump1(E_1&diagonal); + P jump2(E_2&diagonal); + p %= E_3; // project corners to (x1, x2)-plane + q %= E_3; + + // grid line spacing + jump1 *= 1.0/n1; + jump2 *= 1.0/n2; + + const double d1(norm(jump1)); + const double d2(norm(jump2)); + + for (unsigned int i=0; i <= n1; ++i) + for (unsigned int j=0; j <= n2; ++j) + { + P base(p + (i*jump1 + j*jump2)); + P vect(F(base.x1(), base.x2())); + + if (norm(camera(base+vect) - camera(base)) < EPIX_EPSILON) + marker(base, BBOX); + + // scale affects head size + else if (TYPE == VECTOR) + field_element(base, base + vect, VECTOR, scale); + + else + { + // see caution above + double object_len(norm(camera(base+vect)-camera(base))); + pair dX(pair(d1, d2)); + // Hardwired constant 0.4: Segment 80% of shorter grid length + double minimum((dX.x1() > dX.x2()) ? 0.4*dX.x2() : 0.4*dX.x1()); + if ( object_len > EPIX_EPSILON) // not projected to zero + vect *= minimum/object_len; + + // scale affects length of element, not head size + field_element(base - scale*vect, base + scale*vect, TYPE); + } + } + } // end of draw_field F(x, y) + + + // planar fields + void slope_field(P F(double, double), const P& p, const P& q, + unsigned int n1, unsigned int n2, double scale) + { + draw_field(F, p, q, n1, n2, SLOPE, scale); + } + + void dart_field(P F(double, double), const P& p, const P& q, + unsigned int n1, unsigned int n2, double scale) + { + draw_field(F, p, q, n1, n2, DART, scale); + } + + void vector_field(P F(double, double), const P& p, const P& q, + unsigned int n1, unsigned int n2, double scale) + { + draw_field(F, p, q, n1, n2, VECTOR, scale); + } + + void slope_field(P F(double, double), const domain& R, double scale) + { + draw_field(F, R.corner1(), R.corner2(), + R.coarse_n1(), R.coarse_n2(), + SLOPE, scale); + } + + void dart_field(P F(double, double), const domain& R, double scale) + { + draw_field(F, R.corner1(), R.corner2(), + R.coarse_n1(), R.coarse_n2(), + DART, scale); + } + + void vector_field(P F(double, double), const domain& R, double scale) + { + draw_field(F, R.corner1(), R.corner2(), + R.coarse_n1(), R.coarse_n2(), + VECTOR, scale); + } + + // spatial fields + void slope_field(P F(double, double, double), const P& p, const P& q, + unsigned int n1, unsigned int n2, double scale) + { + draw_field(F, p, q, n1, n2, SLOPE, scale); + } + + void dart_field(P F(double, double, double), const P& p, const P& q, + unsigned int n1, unsigned int n2, double scale) + { + draw_field(F, p, q, n1, n2, DART, scale); + } + + void vector_field(P F(double, double, double), const P& p, const P& q, + unsigned int n1, unsigned int n2, double scale) + { + draw_field(F, p, q, n1, n2, VECTOR, scale); + } + + // spatial fields over a domain + void slope_field(P F(double, double, double), const domain& R, + double scale) + { + P p(R.corner1()), q(R.corner2()); + double height(q.x3() - p.x3()); + q -= height*E_3; // p.x3() == q.x3() + + // horizontal/vertical subdivisions + unsigned int i_max(R.coarse_n1()), j_max(R.coarse_n2()); + unsigned int k_max((R.dx3() > 0) ? R.coarse_n3() : 0); + for (unsigned int k = 0; k <= k_max; ++k) + draw_field(F, p + (k*R.step3())*E_3, q + (k*R.step3())*E_3, + i_max, j_max, SLOPE, scale); + } + + void dart_field(P F(double, double, double), const domain& R, + double scale) + { + P p(R.corner1()), q(R.corner2()); + double height(q.x3() - p.x3()); + q -= height*E_3; // p.x3() == q.x3() + + unsigned int i_max(R.coarse_n1()), j_max(R.coarse_n2()); + unsigned int k_max((R.dx3() > 0) ? R.coarse_n3() : 0); + + for (unsigned int k = 0; k <= k_max; ++k) + draw_field(F, p + (k*R.step3())*E_3, q + (k*R.step3())*E_3, + i_max, j_max, DART, scale); + } + + void vector_field(P F(double, double, double), const domain& R, + double scale) + { + P p(R.corner1()), q(R.corner2()); + double height(q.x3() - p.x3()); + q -= height*E_3; // p.x3() == q.x3() + + unsigned int i_max(R.coarse_n1()), j_max(R.coarse_n2()); + unsigned int k_max((R.dx3() > 0) ? R.coarse_n3() : 0); + + for (unsigned int k = 0; k <= k_max; ++k) + draw_field(F, p + (k*R.step3())*E_3, q + (k*R.step3())*E_3, + i_max, j_max, VECTOR, scale); + } + + // Solutions of ODE systems + // start at time 0 + void ode_plot (P F(double, double), const P& start, + double t_max, unsigned int n) + { + euler_plot(surface_map(F), start, 0, t_max, n); + } + + void ode_plot (P F(double, double, double), const P& start, + double t_max, unsigned int num_pts) + { + euler_plot(space_map(F), start, 0, t_max, num_pts); + } + + // arbitrary start time + void ode_plot (P F(double, double), const P& start, + double t_min, double t_max, unsigned int num_pts) + { + euler_plot(surface_map(F), start, t_min, t_max, num_pts); + } + + void ode_plot (P F(double, double, double), const P& start, + double t_min, double t_max, unsigned int num_pts) + { + euler_plot(space_map(F), start, t_min, t_max, num_pts); + } + + + // flow x0 under field for specified time + P flow (P F(double, double), const P& start, double t_max, + unsigned int n) + { + return euler_flow(surface_map(F), start, t_max, n); + } + + P flow (P F(double, double, double), const P& start, double t_max, + unsigned int n) + { + return euler_flow(space_map(F), start, t_max, n); + } + + + void riemann_sum(double f(double), double a, double b, + unsigned int n, epix_integral_type TYPE) + { + const double dx((b-a)/n); + + for (unsigned int i=0; i < n; ++i) + { + double x(a + i*dx); + + switch (TYPE) { + + case LEFT: + rect(P(x, f(x)), P(x+dx,0)); + break; + + case RIGHT: + rect(P(x, 0), P(x+dx, f(x+dx))); + break; + + case UPPER: + rect(P(x, 0), P(x+dx, sup(f, x, x+dx))); + break; + + case LOWER: + rect(P(x, 0), P(x+dx, inf(f, x, x+dx))); + break; + + case TRAP: + quad(P(x, 0), P(x+dx, 0), P(x+dx, f(x+dx)), P(x, f(x))); + break; + + case MIDPT: + rect(P(x, 0), P(x+dx, f(x+0.5*dx))); + break; + + default: + ; + + } // end of switch(TYPE) + } + } // end of riemann_sum() + + + // Jay Belanger's shaded plotting functions -- December 1, 2002 + // Re-implemented using paths, July 16, 2004 + // " for Version 1.2, June 2007 + void shadeplot(double f1(double), double f2(double), + double t_min, double t_max, unsigned int num_pts) + { + // build contour + path boundary(f1, t_min, t_max, num_pts); + path graph2(f2, t_min, t_max, num_pts); + + path right_edge(P(t_max, f1(t_max)), P(t_max, f2(t_max))); + path left_edge(P(t_min, f2(t_min)), P(t_min, f1(t_min))); + + boundary += right_edge; + boundary -= graph2; + boundary += left_edge; + + boundary.close().fill(); + boundary.draw(); + } // end of shadeplot + + void shadeplot(double f(double), double t_min, double t_max, + unsigned int num_pts) + { + shadeplot(f, zero, t_min, t_max, num_pts); + } +} // end of namespace diff --git a/graphics/epix/plots.h b/graphics/epix/plots.h new file mode 100644 index 0000000000..05069c838b --- /dev/null +++ b/graphics/epix/plots.h @@ -0,0 +1,206 @@ +/* + * plots.h -- parametrized plotting algorithms + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * + * Version 1.0.23 + * Last Change: January 13, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_PLOTS +#define EPIX_PLOTS + +#include "enums.h" + +namespace ePiX { + + class domain; + class domain_list; + class Deriv; + class Integral; + class P; + + //// paths //// + // f:R -> R^3 + void plot (P f(double), double t_min, double t_max, unsigned int n); + + // f:R -> R x R x R + void plot (double f1(double), double f2(double), double f3(double), + double t_min, double t_max, unsigned int n); + + // f:R -> R + void plot (double f(double), double t_min, double t_max, unsigned int n); + void plot (const Deriv&, double t_min, double t_max, unsigned int n); + void plot (const Integral&, double t_min, double t_max, unsigned int n); + + // f: R -> R x R + void plot (double f1(double), double f2(double), + double t_min, double t_max, unsigned int n); + + void polarplot (double f(double), double t_min, double t_max, unsigned int); + + //// surfaces //// + // f:R^2 -> R x R x R + void plot(double f1(double u1, double u2), + double f2(double u1, double u2), + double f3(double u1, double u2), + const P& min, const P& max, const mesh& coarse, const mesh& fine); + + void plot(double f1(double u1, double u2), + double f2(double u1, double u2), + double f3(double u1, double u2), + const domain& R); + + // f:R^2 -> R + void plot(double f(double u1, double u2), + const P& p1, const P& p2, const mesh& coarse, const mesh& fine); + + // f:R^2 -> R^3 + void plot(P f(double, double), const domain&); + void plot(P f(double, double), const domain_list&); + + // f:R^3 -> R^3 + void plot(P f(double, double, double), const domain&); + void plot(P f(double, double, double), const domain_list&); + + + // Derivatives and integrals + void plot_deriv(double f(double), double a, double b, unsigned int n); + + void plot_int(double f(double), double a, double b, unsigned int n); + + void plot_int(double f(double), double x0, double a, double b, unsigned int); + + void tan_line(double f1(double), double f2(double), double t0); + void tan_line(double f(double), double t0); + void tan_line(P f(double), double t0); + + void envelope(double f1(double), double f2(double), + double, double, unsigned int); + void envelope(double f(double), double, double, unsigned int); + void envelope(P f(double), double, double, unsigned int); + + void tan_field(double f1(double), double f2(double), double, double, + unsigned int); + void tan_field(P f(double), double, double, unsigned int); + + + // Slope, dart, and vector fields + // For slope and dart fields, the optional scale argument affects the + // (constant) drawn length of field elements. For vector fields, elements + // are drawn at true length, and "scale" affects the arrowhead size. + + // planar fields + void slope_field(P F(double, double), const P& p, const P& q, + unsigned int, unsigned int, double scale=1.0); + void dart_field(P F(double, double), const P& p, const P& q, + unsigned int, unsigned int, double scale=1.0); + void vector_field(P F(double, double), const P& p, const P& q, + unsigned int, unsigned int, double scale=1.0); + + void slope_field(P F(double, double), const domain& R, + double scale=1.0); + void dart_field(P F(double, double), const domain& R, + double scale=1.0); + void vector_field(P F(double, double), const domain& R, + double scale=1.0); + + // spatial fields + void slope_field(P F(double, double, double), const P&, const P&, + unsigned int, unsigned int, double scale=1.0); + void dart_field(P F(double, double, double), const P&, const P&, + unsigned int, unsigned int, double scale=1.0); + void vector_field(P F(double, double, double), const P&, const P&, + unsigned int, unsigned int, double scale=1.0); + + // spatial fields over a (3-D) domain + void slope_field(P F(double, double, double), const domain&, + double scale=1.0); + void dart_field(P F(double, double, double), const domain&, + double scale=1.0); + void vector_field(P F(double, double, double), const domain&, + double scale=1.0); + + + // Solutions of ODE systems + + // start at time 0 + void ode_plot (P F(double, double), + const P& start, double t_max, unsigned int); + + void ode_plot (P F(double, double, double), + const P& start, double t_max, unsigned int); + + // arbitrary start time + void ode_plot (P F(double, double), + const P& start, double t_min, double t_max, unsigned int); + + void ode_plot (P F(double, double, double), + const P& start, double t_min, double t_max, unsigned int); + + // flow x0 under field for specified time + P flow (P F(double, double), const P& start, double t_max, unsigned int n=0); + P flow (P F(double, double, double), + const P& start, double t_max, unsigned int n = 0); + + void riemann_sum(double f(double), double a, double b, + unsigned int n, epix_integral_type TYPE); + + + // Jay Belanger's shaded plot functions -- December 1, 2002 + void shadeplot(double f1(double), double f2(double), double, double, + unsigned int); + void shadeplot(double f(double), double t_min, double t_max, unsigned int); + + void blackplot(double f1(double), double f2(double), + double t_min, double t_max, unsigned int); + + void blackplot(double f(double), double t_min, double t_max, unsigned int); + + void whiteplot(double f1(double), double f2(double), + double t_min, double t_max, unsigned int); + + void whiteplot(double f(double), double t_min, double t_max, unsigned int); + + + // wiremesh surface plotting + void plot(P Phi(double, double), + const P&, const P&, const mesh& N, const mesh& num_pts); + + /* + void clipplot(P Phi(double, double), + const P&, const P&, const mesh& N, const mesh& num_pts); + + void cropplot(P Phi(double, double), + const P&, const P&, const mesh& N, const mesh& num_pts); + */ + +} // end of namespace + +#endif /* EPIX_PLOTS */ diff --git a/graphics/epix/pst.cc b/graphics/epix/pst.cc new file mode 100644 index 0000000000..c10c6ec08b --- /dev/null +++ b/graphics/epix/pst.cc @@ -0,0 +1,359 @@ +/* + * pst.cc -- ePiX's pstricks output format + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.20 + * Last Change: September 19, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <list> + +#include <string> +#include <sstream> + +#include <set> + +#include "constants.h" + +#include "functions.h" + +#include "pairs.h" +#include "edge_data.h" + +#include "Color.h" + +#include "path_style.h" +#include "pen_data.h" + +#include "format.h" +#include "pst.h" + +namespace ePiX { + + pst::pst() + : m_fill(Neutral()), m_line(Black()), m_base(Neutral()), + m_lwidth(PLAIN_WIDTH), m_bwidth("0pt") { } + + pst* pst::clone() const + { + return new pst(*this); + } + + std::string pst::print_fill(const std::list<edge2d>& edges, + const pair& offset, + const Color& fc, + const pen_data& line, + const std::string& len) const + { + std::stringstream obuf; + + // compute attribute string + std::string attribs("[fillstyle="); + + if (fc.is_unset()) + attribs += "none"; + else + attribs += "solid"; + + attribs += "]"; + + obuf << set_fill_state(fc) << set_pen_state(line); // side effects + obuf << print_paths(edges, offset, attribs, len); + + return obuf.str(); + } + + + std::string pst::print_line(const std::list<edge2d>& edges, + const pair& offset, + const pen_data& line, + const pen_data& base, + const path_state& style, + const std::string& len) const + { + std::stringstream value, obuf; + + obuf << set_pen_state(line); + + // update base + m_base = base.color(); + m_bwidth = base.width(); + + std::string attribs; + + // Generate string to pass as third argument to print_paths if need border + if (m_lwidth < m_bwidth && !m_base.is_unset()) + { + length tmp_b(m_bwidth), tmp_l(m_lwidth); + tmp_b += (tmp_l *= -1); + tmp_b *= 0.5; + + std::stringstream bordbuf; + bordbuf << "[border=" << print(tmp_b) + << ",bordercolor=" << m_base.name() << "]"; + + attribs = bordbuf.str(); + } + + if (style.is_solid()) + obuf << print_paths(edges, offset, attribs, len); + + else // not solid + { + // Use base to draw solid underlayer, line to draw top layer. + // Attempt to adjust PST pen alignment; m_bwidth too large. + if (m_lwidth < m_bwidth && !base.color().is_unset()) + obuf << set_pen_state(pen_data(base.color(), + 0.5*(m_bwidth + m_lwidth))) + << print_paths(edges, offset, attribs, len); + + obuf << format::print_line(edges, offset, line, style, "", len); + } + + return obuf.str(); + } + + + std::string pst::print_color(const std::string& model, + const std::string& name, + double d1, double d2, + double d3) const + { + // PSTricks declaration + std::stringstream obuf; + obuf << "\\new" << model; + if (model == "cmy") + obuf << "k"; + + obuf << "color{" << name << "}"; + + if (model == "cmy") + { + double bk(min(min(d1,d2),d3)); + + obuf << "{" + << d1-bk << " " << d2-bk << " " << d3-bk << " " << bk + << "}%" << std::endl; + } + + else + obuf << "{" + << d1 << " " << d2 << " " << d3 + << "}%" << std::endl; + + return obuf.str(); + } + + std::string pst::print_color(const std::string& model, + const std::string& name, + double d1, double d2, + double d3, double d4) const + { + // model presumably "cmyk" + std::stringstream obuf; + obuf << "\\newcmykcolor{" << name << "}{" + << d1 << " " << d2 << " " << d3 << " " << d4 << "}%" + << std::endl; + + return obuf.str(); + } + + + std::string pst::print_comment(const std::string& msg) const + { + std::stringstream obuf; + obuf << "%% " << msg << std::endl; + + return obuf.str(); + } + + // verbatim text, %-protected newline + std::string pst::print_verbatim(const std::string& msg) const + { + std::stringstream obuf; + obuf << msg << "%" << std::endl; + + return obuf.str(); + } + + void pst::reset_state() const + { + m_fill = Neutral(); + m_line = Neutral(); + m_base = Neutral(); + + m_lwidth = length(0); + m_bwidth = length(0); + } + + + //// private member functions //// + std::string pst::start_picture(const pair& sz, const pair& offset) const + { + std::stringstream obuf; + obuf << "\\begin{pspicture}" + << format::print(sz) << format::print(-offset) << "%" << std::endl; + + return obuf.str(); + } + + std::string pst::end_picture() const + { + std::stringstream obuf; + obuf << "\\end{pspicture}%" << std::endl; + return obuf.str(); + } + + std::string pst::set_unitlength(const std::string& len) const + { + std::stringstream obuf; + + obuf << "\\psset{unit=1" << len + << ",linewidth=" << print(length(PLAIN_WIDTH)) << "}%" + << std::endl; + + return obuf.str(); + } + + + std::string pst::usepackages() const + { + return "usepackages pstricks"; + } + + std::string pst::start_open_path(const std::string& attribs) const + { + return "\\psline" + attribs; + } + + std::string pst::end_open_path(const std::string& attribs) const + { + std::stringstream obuf; + obuf << std::endl; + return obuf.str(); + } + + std::string pst::start_closed_path(const std::string& attribs) const + { + return "\\pspolygon" + attribs; + } + + std::string pst::end_closed_path(const std::string& attribs) const + { + std::stringstream obuf; + obuf << std::endl; + return obuf.str(); + } + + std::string pst::set_fill_state(const Color& col) const + { + if (m_fill == col) + return ""; + + // else + m_fill = col; + + std::stringstream obuf; + obuf << "\\psset{"; + + // filled paths set fillstyle + if (m_fill.is_unset()) + obuf << "fillstyle=none"; + + else + obuf << "fillcolor=" << m_fill.name(); + + obuf << "}%" << std::endl; + + return obuf.str(); + } + + std::string pst::set_pen_state(const pen_data& pen) const + { + std::stringstream obuf; + + if (pen.color().is_unset()) + { + m_lwidth=length(0); + return "\\psset{linewidth=0pt}"; + } + + // else + bool change_width(m_lwidth != pen.width()); + bool change_color(m_line != pen.color()); + + if (change_width || change_color) + { + obuf << "\\psset{"; + + if (change_width) + { + m_lwidth = pen.width(); + obuf << "linewidth=" << m_lwidth.name(); + + if (change_color) // both true, need separator + obuf << ","; + } + + if (change_color) + { + m_line = pen.color(); + obuf << "linecolor=" << m_line.name(); + } + + obuf << "}%" << std::endl; + } + + return obuf.str(); + } + + // place a LaTeX box of width zero (containing string) at location (pair) + std::string pst::put_box(const pair& loc, const std::string& msg) const + { + std::stringstream obuf; + obuf << "\\rput" << print(loc) << "{" << msg << "}" << std::endl; + + return obuf.str(); + } + + std::string pst::print_circle_marker(const pair& here, double diam, + bool fill, const Color& color, + const std::string& len) const + { + std::stringstream obuf; + obuf << "\\pscircle"; + + if (fill) + obuf << "*"; + + obuf << "[linecolor=" << print(color) << "]" << print(here) + << "{" << 0.5*diam << "}%" << std::endl; + + return obuf.str(); + } +} // end of namespace diff --git a/graphics/epix/pst.h b/graphics/epix/pst.h new file mode 100644 index 0000000000..342bce9573 --- /dev/null +++ b/graphics/epix/pst.h @@ -0,0 +1,124 @@ +/* + * pst.h -- ePiX's pstricks output format + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.15 + * Last Change: September 07, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_PST +#define EPIX_PST + +#include <string> +#include <list> +#include <set> + +#include "Color.h" +#include "length.h" + +#include "edge_data.h" +#include "format.h" + +namespace ePiX { + + class path_state; + class pen_data; + + class pst : public format { + public: + pst(); + + pst* clone() const; + + std::string print_fill(const std::list<edge2d>& edges, + const pair& offset, + const Color& fill, + const pen_data& line, + const std::string& len) const; + + std::string print_line(const std::list<edge2d>& edges, + const pair& offset, + const pen_data& line, + const pen_data& base, + const path_state& style, + const std::string& len) const; + + + // model, name, densities + std::string print_color(const std::string&, const std::string&, + double, double, + double) const; + + std::string print_color(const std::string&, const std::string&, + double, double, + double, double) const; + + + // output file comment + std::string print_comment(const std::string&) const; + + std::string print_verbatim(const std::string&) const; + + void reset_state() const; + + private: + mutable Color m_fill; + mutable Color m_line; + mutable Color m_base; + + mutable length m_lwidth; + mutable length m_bwidth; + + // start, end pspicture, set unit and default linewidth + std::string start_picture(const pair&, const pair&) const; + std::string end_picture() const; + + std::string set_unitlength(const std::string& len) const; + + std::string usepackages() const; + + // string argument for passing attributes local to this path/loop + std::string start_open_path(const std::string&) const; + std::string end_open_path(const std::string&) const; + + std::string start_closed_path(const std::string&) const; + std::string end_closed_path(const std::string&) const; + + // print declarations to set state of output format + std::string set_fill_state(const Color&) const; + std::string set_pen_state(const pen_data&) const; + + // place a LaTeX box of width zero (containing string) at location (pair) + std::string put_box(const pair&, const std::string&) const; + + std::string print_circle_marker(const pair& here, double diam, + bool fill, const Color& color, + const std::string& len) const; + }; // end of class pst +} // end of namespace + +#endif /* EPIX_PST */ diff --git a/graphics/epix/samples/Makefile.am b/graphics/epix/samples/Makefile.am new file mode 100644 index 0000000000..46aea1a065 --- /dev/null +++ b/graphics/epix/samples/Makefile.am @@ -0,0 +1,20 @@ +# Makefile.am for ePiX v1.x "samples" directory +# + +XPS := $(wildcard *.xp) +FLX := $(wildcard *.flx) + +CLEANFILES = *~ *.eepic *.eps sample_src.tar sample_src.tar.gz sample-stamp + +## Targets ## +doc_DATA = sample_src.tar.gz + + +# tar up tex, xp, and eepic files +sample-stamp: $(XPS) $(FLX) + touch sample-stamp + +sample_src.tar.gz: sample-stamp + tar -cf sample_src.tar $(XPS) $(FLX) \ + README binom.cc lighting.h std_F.cc std_F.h + gzip -9 sample_src.tar diff --git a/graphics/epix/samples/Makefile.in b/graphics/epix/samples/Makefile.in new file mode 100644 index 0000000000..759cd4259f --- /dev/null +++ b/graphics/epix/samples/Makefile.in @@ -0,0 +1,340 @@ +# Makefile.in generated by automake 1.9.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Makefile.am for ePiX v1.x "samples" directory +# + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +subdir = samples +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(docdir)" +docDATA_INSTALL = $(INSTALL_DATA) +DATA = $(doc_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASH_PATH = @BASH_PATH@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_EPIX_EL_FALSE = @ENABLE_EPIX_EL_FALSE@ +ENABLE_EPIX_EL_TRUE = @ENABLE_EPIX_EL_TRUE@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ +MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +RUNTIME_COMPILER = @RUNTIME_COMPILER@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ +am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +XPS := $(wildcard *.xp) +FLX := $(wildcard *.flx) +CLEANFILES = *~ *.eepic *.eps sample_src.tar sample_src.tar.gz sample-stamp +doc_DATA = sample_src.tar.gz +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu samples/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu samples/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +uninstall-info-am: +install-docDATA: $(doc_DATA) + @$(NORMAL_INSTALL) + test -z "$(docdir)" || $(mkdir_p) "$(DESTDIR)$(docdir)" + @list='$(doc_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(docDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(docdir)/$$f'"; \ + $(docDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(docdir)/$$f"; \ + done + +uninstall-docDATA: + @$(NORMAL_UNINSTALL) + @list='$(doc_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(docdir)/$$f'"; \ + rm -f "$(DESTDIR)$(docdir)/$$f"; \ + done +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(DATA) +installdirs: + for dir in "$(DESTDIR)$(docdir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-docDATA + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-docDATA uninstall-info-am + +.PHONY: all all-am check check-am clean clean-generic distclean \ + distclean-generic distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-docDATA install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am uninstall uninstall-am uninstall-docDATA \ + uninstall-info-am + + +# tar up tex, xp, and eepic files +sample-stamp: $(XPS) $(FLX) + touch sample-stamp + +sample_src.tar.gz: sample-stamp + tar -cf sample_src.tar $(XPS) $(FLX) \ + README binom.cc lighting.h std_F.cc std_F.h + gzip -9 sample_src.tar +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/graphics/epix/samples/README b/graphics/epix/samples/README new file mode 100644 index 0000000000..b51bd10d3c --- /dev/null +++ b/graphics/epix/samples/README @@ -0,0 +1,258 @@ +ePiX -- samples/README + +Last Change: September 22, 2007 + +This directory contains sample files. Files with extension ".flx" may +be compiled like xp files with epix or elaps, or converted to gif or +mng animations with flix. + + +artifacts.xp + Interaction between coarse and fine meshes in shade surface plotting. + +binom.cc: + Generates pseudo-random data for histogram.xp + +bowl.xp: + Quasi-realistic colored surface shading. + +butterfly.xp: + A Thom catastrophe graph. + +calculus.xp: + Plotting derivatives and definite integrals. + +clipping.xp: + Clipping, shaded surfaces, and fake transparency. + +color_sep.xp: + Color separation. + +conic.xp: + Envelopes and tangent lines; projective equivalence of a parabola + with a circle. + +contour.xp: + Building a path from sub-paths. + +coord_tricks.xp: + Using page layout to achieve broken axes. + +cropplot.xp + Graphing functions with singularities. + +cube.flx: + Stereoscopic (3-D glasses) movie of a rotating cube. + +dataplot.xp: + Scatter plots, histograms, and page layout. + +decorate.xp: + Decorated shaded surface (see file for compiling). + +demoivre.xp: + Loops; a geometric proof of deMoivre's formula. + +densityplot.xp: + A gray-shaded interference pattern. + +dipole.xp: + Plotting flow lines and isobars. + +denom.xp: + Loops and gcd; Thomae's function with discontinuity set Q. + +extract.xp: + A magnified inset using screen::extract; an unexpected tangent line. + +geomsum.xp: + Loops and color filling. + +golden_rect.xp: + Simple use of variables; constructing a golden rectangle. + +helicoid.flx: + Isometric deformation of a catenoid to a helicoid. + +hello.xp: + My First Figure, from the manual. + +histogram.xp: + Histograms of simulated coin tosses (data from binom.cc). + +house.flx: + Color semantics; sun setting on a simple house. + +hyperboloid.xp: + Clipping, shaded surfaces; two families of rulings on a hyperboloid. + +inverse.xp: + Screen affine operations; inverse functions. + +koch.xp: + The von Koch snowflake fractal. + +label_debug.xp: + Format debugging tests for labels, draws 32 attribute combinations. + +layout2.xp: + Page layout; flow lines of a planar vector field. + +layout.xp: + Page layout; six views of the square root Riemann surface. + +legend.xp: + Axes and legends; Taylor polynomials of sin x. + +levelset.xp: + Clipping and plotting; manual level curves on a saddle. + +levelset2.xp: + "Advanced" clipping; level bands on a monkey saddle. + +levelset3.xp: + Clipping and legends; flat-shaded level bands wth matching legend. + +lissajous.xp: + A Lissajous figure with arrows. + +lighting.h: Classes for lighting effects and color-shaded surfaces. + (lighting.flx illustrates use.) + +line_debug.xp: + Format debugging tests for paths, draws 32 attribute combinations. + +log.xp: + Object hiding with paths and surfaces; the Riemann surface of log. + +lorenz.xp: + Page layout, ode_plot; the Lorenz attractor and its 3-D vector field. + +medians.xp: + Euclidean geometry; medians and altitudes of a triangle. + +minkowski.xp: + A longitudinal slice of Minkowski space R^{2,1}. + +mirrorball.flx: + The circle class and intersections; 3-D stereographic movie. + +newton.xp: + Loops; root location by Newton's method. + +objects.xp: + Simple geometric objects; 2-D landscape. + +oscillator.xp: + Graphing, user-defined elements, and page layout. + +parabola.xp: + A basic plot. + +pascal.xp: + Intersection operators; Pascal's theorem in projective geometry. + +pendulum.flx: + Phase diagram of an undamped pendulum. + +planes.xp: + Manipulating objects, clipping; a stack of plane sections of a cube. + +plotting2.xp: + Surface plotting in PSTricks; from the manual. + +plotting3.xp: + Loops and color control; from the manual. + +plotting.xp: + A basic plot; from the manual. + +polar.xp: + Polar plotting. + +pole.xp: + Clipping a plot; the real part of a first-order pole. + +polyhedra.xp: + Spherical regular polyhedra. Compilation controlled with + pre-processor flags, e.g., "epix -DCOLOR -DDODECA polyhedra.xp". + +R_demo.xp: + Gaussians from the R demo. + +riemann.flx: + Rotating the Riemann surface of sqrt(z) in R^4. + +S2_harmonics.xp: + Domain-dependent surface shading (color function depends on two + variables), page layout; the spherical harmonic Y_3^0. (Compile with + "epix -DY20 S2_harmonics.xp" for Y_2^0.) + +saddle.xp: + A quadratic saddle using "surface" capabilities. + +semicirc.xp: + A simple figure using variables and a function for organization. + +shadeplot.xp: + Shading regions enclosed by graphs; the fundamental theorem of calculus. + +slopefield.xp: + A slope field and flow lines. + +sphere.xp: + Plotting curves and latitudes/longitudes; loxodromes. + +spherical.xp: + Scenery (multiple shaded surfaces); spherical coordinates. + +sqrt.xp: + Domains and selective plotting; the Riemann surface of sqrt(z). + +sqrt2.xp: + Domains, selective plotting, and change of style in a single plot. + +std_F.cc, std_F.h: + Extensively-commented library code for depicting 2-D affine maps. + +std_F.xp: + Sample file illustrating the use of external libraries. Contains + instructions on building a library from std_F.cc. + +steiner.flx: + Steiner's Roman surface, rotating. + +steiner2.flx: + Steiner's Roman surface sliced, with slice direction rotating. + +surface_shade.xp: + Position-dependent surface shading. (Color function depends on three + variables.) + +symmetries.xp: + Affine maps and layout; the symmetry group S_3 acting on a regular + hexagon. + +tori.xp: + Clipping and cropping, page layout. + +torus.xp: + Domains and selective plotting. + +trig.flx: + Trigonometric functions. + +twisted_cubic.xp: + Page layout; a crossed-eyes stereogram of the twisted cubic. + +uppersum.xp: + Riemann sums. + +vfield.xp: + 3-D vector field plotting. + +weierstrass.xp: + Loops; a Weierstrass nowhere-differentiable function. + +wheel.xp: + Page layout; a cycloid at successive times. diff --git a/graphics/epix/samples/R_demo.xp b/graphics/epix/samples/R_demo.xp new file mode 100644 index 0000000000..183f74b988 --- /dev/null +++ b/graphics/epix/samples/R_demo.xp @@ -0,0 +1,69 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const double mult(1.0/sqrt(M_PI)); + +double f(double x) +{ + return 0.4*exp(-mult*x*x); +} + +double g(double x) +{ + return f(x-3); +} + +double PAD_X(0.4), PAD_Y(0.01); + +int main() { + picture(P(-3-PAD_X, -PAD_Y), P(8+PAD_X, 0.4+PAD_Y), "5 x 3.5in"); + + begin(); + border(); + + legend L; + L.border(0); + + fill(Black(0.2)); + shadeplot(g, 1.96, xmax(), 120); + L.fill_item("$P(|Z|>1.96, H_1) = 0.85$"); + + fill(Black(0.8)); + shadeplot(f, xmin(), -1.96, 20); + shadeplot(f, 1.96, 4, 40); + L.fill_item("$P(|Z|>1.96, H_0) = 0.05$"); + + plot(f, xmin(), xmax(), 240); + plot(g, xmin(), xmax(), 240); + + font_size("scriptsize"); + L.draw(P(4,0.35), P(0,0), tr); + + label(P(0, 0.15), P(0,2), "$H_0$: $\\mu_1=\\mu_2$", t); + label(P(2, 0.15), P(2,2), "$H_1$: $\\mu_1=\\mu_2+\\delta$", tr); + + font_size("footnotesize"); + axis Ax(P(-2, ymin()), P(8, ymin()), 5, P(0,-8), b); + Ax.align(b).draw(); + + label(P(2, ymin()), P(0,-18), + "$Z=\\displaystyle\\frac{\\mu_1-\\mu_2}{\\sigma/\\sqrt{\\pi}}$", b); + + degrees(); + label_angle(90); + +#ifdef OLD_GCC + axis Ay(P(-3.4, 0), P(xmin(), 0.4), 4, P(-8,0), l); +#else + // may not compile under gcc <= 3.3 + axis Ay(P(xmin(), 0), P(xmin(), 0.4), 4, P(-8,0), l); +#endif + + Ay.align(l).draw(); + + label(P(xmin(), 0.2), P(-18,0), "Density", l); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/S2_harmonics.xp b/graphics/epix/samples/S2_harmonics.xp new file mode 100644 index 0000000000..d1ed709165 --- /dev/null +++ b/graphics/epix/samples/S2_harmonics.xp @@ -0,0 +1,104 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +double P_n(double z) +{ +#ifdef Y20 + return 0.5*(3*z*z - 1); +#else + // Y_3^0 + return 0.5*z*(5*z*z - 3); +#endif +} + +double rho(double th, double phi) +{ + return P_n(Sin(phi)); +} + +P color(double x, double y) +{ + return P(rho(x,y), 0, -rho(x,y)); +} + +P orbital(double u, double v) +{ + return sph(fabs(rho(u,v)), u, v); +} + +int main() +{ + picture(P(-1,-1), P(1,1.5), "4x5in"); + + begin(); + + backing(Black()); + + set_crop(); + revolutions(); + fill(); + + // back 3/4 + domain Bk(P(0.25, -0.25), P(1, 0.25), mesh(24,96), mesh(48,96)); + + plain(RGB(1, 0.8, 0.2) *= 0.8); + + camera.at(sph(10, 0.06, 0.05)); + + // color-shaded surface + surface(orbital, Bk, color); + + // draw boundary with "tube-like" green pen + nofill(); + plain(Green(1.6)); + base(Green(0.6), "2pt"); + plot(orbital, Bk.slice1(0.25)); + plot(orbital, Bk.slice1(1)); + + // set color for axes and labels + rgb(0.9,0.7,1); + base(RGB(0.8, 0, 1), "1pt"); + + arrow(P(0,0,0), P(1,0,0)); + arrow(P(0,0,0), P(0,0.75,0)); + arrow(P(0,0,0), P(0,0,1.25)); + + label(P(1,0,0), P(-2,-2), "$x$", bl); + label(P(0,0.75,0), P(4,-2), "$y$", r); + label(P(0,0,1.25), P(0,4), "$z$", t); + + // "unset" base pen + base(Neutral()); + + // inset graph of Legendre polynomial + screen graph(P(-1,-1), P(1,1)); + activate(graph); + + camera.at(P(0,0,10000)); + plain(Green(0.6)); + grid(P(-1,-1), P(1,1), 8, 8); + bold(Yellow()); + h_axis(8); + v_axis(8); + + bold(Green()); + plot(P_n, -1, 1, 60); + + font_size("footnotesize"); + label_color(Green(0.6)); + label_mask(RGB(1, 0.8,0.2)); + +#ifdef Y20 + label(P(0,-1), P(0,-4), "$P(z)=\\frac{1}{2}(3z^2-1)$", b); +#else + // Y30 + label(P(0,-1), P(0,-4), "$P(z)=\\frac{1}{2}(5z^2-3)$", b); +#endif + + inset(P(-1,0.875), P(-0.375,1.5)); + deactivate(graph); // a good habit, but not strictly necessary + + tikz_format(); + end(); +} diff --git a/graphics/epix/samples/artifacts.xp b/graphics/epix/samples/artifacts.xp new file mode 100644 index 0000000000..bd20166717 --- /dev/null +++ b/graphics/epix/samples/artifacts.xp @@ -0,0 +1,51 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const double MAX(1); + +P F(double u, double v) +{ + return sph(1, u, v); +} + +int main() +{ + picture(P(0,0),P(5,1), "5 x 1in"); + + begin(); + + pst_format(); + domain coarse(P(0,0), P(0.5, 1), mesh(6,12), mesh(60,60)); + domain fine(P(0,0), P(0.5, 1), mesh(15,30), mesh(60,60)); + + revolutions(); + camera.at(P(5, 4, 3)); + + fill(White()); + + nofill(); // fill color set -> flat shading + screen scr1(P(-1,-1), P(1,1)); + activate(scr1); + surface(F, coarse); + + screen scr2(P(-1,-1), P(1,1)); + activate(scr2); + surface(F, fine); + + fill(); + screen scr3(P(-1,-1), P(1,1)); + activate(scr3); + surface(F, coarse); + + screen scr4(P(-1,-1), P(1,1)); + activate(scr4); + surface(F, fine); + + inset(scr1, P(0,0), P(1,1)); + inset(scr2, P(1.25,0), P(2.25,1)); + inset(scr3, P(2.5,0), P(3.5,1)); + inset(scr4, P(3.75,0), P(4.75,1)); + + end(); +} diff --git a/graphics/epix/samples/binom.cc b/graphics/epix/samples/binom.cc new file mode 100644 index 0000000000..1dc068fcd6 --- /dev/null +++ b/graphics/epix/samples/binom.cc @@ -0,0 +1,37 @@ +#include <iostream> +#include <cmath> +// Generate pseudo-random outcomes of tossing a biased coin 100 times. +// Compile with, e.g. +// +// g++ -o binom binom.cc && ./binom > binom.dat + +const int trials=100000; // amount of data to collect + +int flip(double wt=0.5) // 0 < wt < 1 +{ + if (rand() < (1-wt)*RAND_MAX) + return 0; + else + return 1; +} + +void toss(unsigned int tosses, double wt=0.5) +{ + int count=0; + for (int i=0; i < tosses; ++i) + count += flip(wt); + + std::cout << count << "\t"; +} + +int main() +{ + for (int j=0; j < trials; ++j) + { + toss(100, 0.05); + toss(100, 0.1); + toss(100, 0.3); + toss(100); + std::cout << "\n"; + } +} diff --git a/graphics/epix/samples/bowl.xp b/graphics/epix/samples/bowl.xp new file mode 100644 index 0000000000..fe3921b6db --- /dev/null +++ b/graphics/epix/samples/bowl.xp @@ -0,0 +1,55 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +P f(double u, double v) +{ + return u*P(Cos(v), Sin(v), u); +} + +int main() +{ + picture(P(-2,-1),P(2,2), "6x4.5in"); + + begin(); + + backing(Black()); + + white(); + label(P(0, ymax()), P(0,-2), "\\LARGE$z=x^2+y^2$", b); + + revolutions(); + camera.at(P(3,2,2.5)); + + red(); + polar_grid(1, 8, 36); + + arrow(P(0,0,0), P(1.25,0,0)); + arrow(P(0,0,0), P(0,1.25,0)); + label(P(1.25,0,0), P(-2,-2), "$x$", bl); + label(P(0,1.25,0), P(2,-1), "$y$", br); + + fill(); + rgb(1,0.8,0.2); + domain R(P(0,0), P(1,1), mesh(12,180), mesh(12,180)); + + scenery my(f, R); + + my.draw(1); // cull front-pointing facets + + red(); + arrow(P(0,0,0), P(0,0,1)); + + pen(Blue(1.6), "0.5pt"); + fill(Blue(1.4)); + scenery my2(f, R); + my2.draw(-1); // cull back-pointing facets + + nofill(); + bold(Green()); + base(Green(0.6), "1.5pt"); + plot(f, R.slice1(1)); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/butterfly.xp b/graphics/epix/samples/butterfly.xp new file mode 100644 index 0000000000..2ec303d780 --- /dev/null +++ b/graphics/epix/samples/butterfly.xp @@ -0,0 +1,136 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const P VIEWPT(20, 0, 8); + +const double tmin(2/sqrt(3)); + +const Color light(Blue(1.6)); +const Color dark(Red(0.8)); +const Color lt_gray(Black(0.2)); +const Color net_color(Yellow(0.1)); + +void label_tag(P loc, P head, std::string txt, epix_label_posn align) +{ + dart(loc, head); + masklabel(loc, P(0,0), txt, align); +} + +domain R(P(-2,-2), P(2,2), mesh(20, 20), mesh(40,40)); +domain edge(P(-2,-2), P(2,2), mesh(1,1), mesh(40,40)); + +// surface +P Phi(double u, double v) +{ + return P(4*v, 0.75*(u*u-2*v)*u, 2*u); +} + +P cubic(double t) { return Phi(t, 1.5*t*t); } + +// cubic projections to background planes +P Phi12(double t) +{ + P temp(cubic(t)); + return P(temp.x1(), temp.x2(), -8); +} + +P Phi13(double t) +{ + P temp(cubic(t)); + return P(temp.x1(), -8, temp.x3()); +} + +P Phi23(double t) +{ + P temp(cubic(t)); + return P(-8, temp.x2(), temp.x3()); +} + + +int main() { + picture(P(-14,-15), P(10,9), "6x6in"); + + begin(); + set_crop(); + camera.at(VIEWPT); + + // background grids + pen(lt_gray); + grid(P(-8, -8, -8), P(8, 8, -8), 8,8); + grid(P(-8, -8, -8), P(8, -8, 6), 7,8); // n.b. (z,x) divisions + grid(P(-8, -8, -8), P(-8, 8, 6), 8,7); + + // background coordinate axes + pen(Black()); + line(P(0, -8, -8), P(0, 8, -8)); + line(P(-8, 0, -8), P(8, 0, -8)); + + line(P(0, -8, -8), P(0, -8, 6)); + line(P(-8, -8, 0), P(8, -8, 0)); + + line(P(-8, 0, -8), P(-8, 0, 6)); + line(P(-8, -8, 0), P(-8, 8, 0)); + + // projections of cubic + bold(dark); + plot(Phi12, -tmin, tmin, 80); + plot(Phi13, -tmin, tmin, 80); + plot(Phi23, -tmin, tmin, 80); + + // surface + plain(net_color); + fill(lt_gray); + surface(Phi, R.resize1(-2,0)); // bottom half + + // and cubic curve + bold(dark); + plot(cubic, -tmin, 0, 80); + + plain(net_color); + surface(Phi, R.resize1(0,2)); // top half + + bold(dark); + plot(cubic, 0, tmin, 80); + + // surface boundary + bold(Yellow()); + plot(Phi, edge); + + // guide lines to cusp projection + plain(light); + dashed(); + line(cubic( tmin), Phi12( tmin)); + line(cubic(-tmin), Phi12(-tmin)); + + /* + // guide lines to other projections + line(cubic( tmin), Phi13( tmin)); + line(cubic(-tmin), Phi13(-tmin)); + + line(cubic( tmin), Phi23( tmin)); + line(cubic(-tmin), Phi23(-tmin)); + */ + + // fake transparency + plain(dark); + plot(Phi12, -tmin, tmin, 20); // cusp + // plot(Phi13, -tmin, tmin, 20); + // plot(Phi23, -tmin, tmin, 20); + + label_color(Black()); + label(P(8,0,-8), P(0,-4), "$x$", b); + label(P(0,8,-8), P(4,0), "$y$", r); + + pen(light); + label_border(light, "0.4pt"); + solid(); + label_tag(Phi(-2,-2)+P(0,2,6), Phi(-1.75,-1.75), + "$y=\\frac{3}{32}(z^3-2xz)$", t); + + label_tag(cubic(-1)+P(0,2,3), cubic(-1), + "$(x,y,z)=(6t^2, -\\frac{3}{2}t^3, 2t)$", t); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/calculus.xp b/graphics/epix/samples/calculus.xp new file mode 100644 index 0000000000..c5aa0efe0b --- /dev/null +++ b/graphics/epix/samples/calculus.xp @@ -0,0 +1,43 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +double MAX(2*M_PI); +double f(double t) +{ + return t*Sin(t); +} + +int main() +{ + picture(P(-MAX,-MAX), P(MAX,MAX), "240x240pt"); + + begin(); + + // Coordinate axes and labels + pen(Black(0.3)); + grid(8,8); + + font_size("scriptsize"); + // trigonometric axis labels + bottom_axis(4, P(0,-4)).trig().draw_labels(); + left_axis(4, P(-4,0)).trig().draw_labels(); + + legend L; + L.item_border(0).border(Red(), 0.4); + + bold(Black()); + plot(f, xmin(), xmax(), 90); + L.path_item("$y=x\\sin x$"); + + pen(Green()); + plot(Deriv(f), xmin(), xmax(), 90); + L.path_item("$y=\\frac{d}{dx}(x\\sin x)$"); + + pen(Blue()); + plot(Integral(f, 0), xmin(), xmax(), 90); // definite integral from 0 + L.path_item("$y=\\int_0^x t\\sin t\\,dt$"); + + L.draw(P(0,2*M_PI), P(2,-2), br); + end(); +} diff --git a/graphics/epix/samples/clipping.xp b/graphics/epix/samples/clipping.xp new file mode 100644 index 0000000000..0df86eb85b --- /dev/null +++ b/graphics/epix/samples/clipping.xp @@ -0,0 +1,233 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; +/* + * This file, a monkey saddle sliced by two vertical planes showing + * the definition and geometric meaning of partial derivatives, + * contains a high degree of manual object ordering. Coordinate grids + * in the back come first. The surface itself is broken into pieces + * interspersed with axes and cutting planes. Figure parameters + * (color, the size and fineness of the domain, locations of cutting + * planes, and camera location) are defined in the preamble. The + * figure's appearance can then be adjusted visually at leisure to + * obtain the desired effect. + * + * Compile with + * + * epix -DDISSECT clipping.xp + * + * to create frames showing stages of the construction. + */ + +// Style parameters +// camera location (in spherical coordinates); must be in first orthant +const P VIEWPT(sph(4, M_PI/6, M_PI/6)); + +// colors +void color_coord() +{ + // fill(RGB(1, 0.9, 0.5)); + // plain(RGB(1, 0.5, 0.2)); + plain(RGB(1, 0.9, 0.7)); +} + +void color_axis() +{ + rgb(0.8, 0.2, 0.9); +} + +// graph and mesh +void color_surf() +{ + plain(RGB(1, 0.5, 0)); + fill(RGB(1, 0.8, 0.2)); +} + +// slicing plane and border +void color_xslice() +{ + red(); +} + +void fill_xslice() +{ + // black(0.1); + rgb(0.8, 0.5, 0.1); +} + +void color_yslice() +{ + blue(); +} + +void fill_yslice() +{ + // black(0.3); + rgb(0.6, 0.3,0); +} + +const int MESH(12); // number of coordinate grid squares + +// location of tangency point +const double x_0(7.0/MESH); +const double y_0(6.0/MESH); +const double z_0(0.25); // height of top of slicing planes + +const int MAX(1); // maximum coordinate + +const double sqrt3(sqrt(3)); + +// function to be graphed +P f(double x, double y) +{ + return P(x, y, 0.75*y*(y-sqrt3*x)*(y+sqrt3*x)); +} + +int main() +{ + picture(P(-2,-2), P(2,1.5), "6 x 5.25in"); + + begin(); + + // "legend" + masklabel(P(xmax(), ymax()), P(-2,-2), + "$z=\\displaystyle\\frac{1}{2}(y^3-3x^2y)$", bl); + + font_size("scriptsize"); + camera.at(VIEWPT); + border(Green(0.6), "1pt"); + + domain R(P(-MAX,-MAX), P(MAX,MAX), + mesh(4*MESH, 4*MESH), mesh(8*MESH, 8*MESH)); + + // coordinate grids + color_coord(); + grid(P(-MAX,-MAX,-MAX), P(-MAX, MAX, MAX), MESH, MESH); + grid(P(-MAX,-MAX,-MAX), P( MAX,-MAX, MAX), MESH, MESH); + grid(P(-MAX,-MAX,-MAX), P( MAX, MAX,-MAX), MESH, MESH); + +#ifdef DISSECT + print_pst("clipping01.eepic"); +#endif + + clip_box(P(-2, -2, -1), P(2, 2, 1)); + + // back half and front left quarter + color_surf(); + surface(f, R.resize1(-MAX,0)); +#ifdef DISSECT + print_pst("clipping02.eepic"); +#endif + + surface(f, R.resize1(0,MAX).resize2(-MAX,0)); +#ifdef DISSECT + print_pst("clipping03.eepic"); +#endif + + // coordinate axes + color_axis(); + bold(); + + clip_box(P(-2, -2, -1), P(2, 2, 2)); + + dart(P(-MAX,0,0), P(0.25+MAX,0,0)); + dart(P(0,-MAX,0), P(0,0.25+MAX,0)); + dart(P(0,0,0), P(0,0,0.25+MAX)); + + label(P(0.25+MAX,0,0), P(-2,-2), "$x$", bl); + label(P(0,0.25+MAX,0), P( 4,-2), "$y$", r); + label(P(0,0,0.25+MAX), P( 0, 4), "$z$", t); + +#ifdef DISSECT + print_pst("clipping04.eepic"); +#endif + + // front quarter of surface; chop into four pieces + color_surf(); + surface(f, R.resize1(0, x_0).resize2(0,y_0)); // behind both planes + +#ifdef DISSECT + print_pst("clipping05.eepic"); +#endif + + fill_xslice(); + rect(P(x_0, 0, -MAX), P(x_0, y_0, z_0)); // left part of plane x = x_0 + +#ifdef DISSECT + print_pst("clipping06.eepic"); +#endif + + pen(3); + color_xslice(); + plot(f, R.slice1(x_0).resize2(0, y_0)); + +#ifdef DISSECT + print_pst("clipping07.eepic"); +#endif + + color_surf(); + surface(f, R.resize1(x_0, MAX).resize2(0,y_0)); // back right piece + +#ifdef DISSECT + print_pst("clipping08.eepic"); +#endif + + fill_yslice(); + rect(P(0, y_0, -MAX), P(MAX, y_0, z_0)); // plane y = y_0 + +#ifdef DISSECT + print_pst("clipping09.eepic"); +#endif + + pen(3); + color_yslice(); + plot(f, R.slice2(y_0).resize1(0, MAX)); + +#ifdef DISSECT + print_pst("clipping11.eepic"); +#endif + + color_surf(); + surface(f, R.resize1(0, x_0).resize2(y_0, MAX)); // front left piece + +#ifdef DISSECT + print_pst("clipping12.eepic"); +#endif + + fill_xslice(); + rect(P(x_0, y_0, -MAX), P(x_0, MAX, z_0)); // right part of plane x = x_0 + +#ifdef DISSECT + print_pst("clipping13.eepic"); +#endif + + pen(3); + color_xslice(); + plot(f, R.slice1(x_0).resize2(y_0, MAX)); + +#ifdef DISSECT + print_pst("clipping14.eepic"); +#endif + + color_surf(); + surface(f, R.resize1(x_0, MAX).resize2(y_0, MAX)); // front right piece + + clip_box(P(-MAX,-MAX,-2), P(MAX,MAX,2)); + + // labels and graph slices + color_yslice(); + label(f(MAX, y_0), P(-4,0), + "$\\displaystyle\\frac{\\partial f}{\\partial x}$: $y$ constant", l); + + color_xslice(); + label(f(x_0, MAX), P(4,0), + "$\\displaystyle\\frac{\\partial f}{\\partial y}$: $x$ constant", br); + +#ifdef DISSECT + print_pst("clipping15.eepic"); +#endif + + pst_format(); + end(); +} + diff --git a/graphics/epix/samples/color_sep.xp b/graphics/epix/samples/color_sep.xp new file mode 100644 index 0000000000..5ba4df4fc9 --- /dev/null +++ b/graphics/epix/samples/color_sep.xp @@ -0,0 +1,76 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// re cos(u+iv) +P f(double u, double v) +{ + return P(u, v, 2*cosh(u)*Cos(v)); +} + +domain R(P(-1,-1), P(1,1), mesh(16,16)); + +// RGB densities +P color(double x, double y, double z) +{ + return P(Sin(x), -Sin(y), -Sin(x)); +} + +int main() +{ + picture(P(0,0), P(5,1), "5x1in"); + + begin(); + + camera.filter(CMYK_Neutral()); // convert colors to CMYK in output + grid(5,1); + camera.at(4,3,1); + + plain(Red(1.6)); + + // Original + screen all(P(-1.5,0.5), P(1.5,3.5)); + activate(all); + set_crop(); + + surface(f, R, color); + inset(all, P(0,0), P(1,1)); + + // Cyan + screen cyn(P(-1.5,0.5), P(1.5,3.5)); + activate(cyn); + set_crop(); + camera.filter(C_Process()); // get cyan layer + + surface(f, R, color); + inset(cyn, P(1,0), P(2,1)); + + // Magenta + screen mgn(P(-1.5,0.5), P(1.5,3.5)); + activate(mgn); + set_crop(); + camera.filter(M_Process()); + + surface(f, R, color); + inset(mgn, P(2,0), P(3,1)); + + // Yellow + screen ylw(P(-1.5,0.5), P(1.5,3.5)); + activate(ylw); + set_crop(); + camera.filter(Y_Process()); + + surface(f, R, color); + inset(ylw, P(3,0), P(4,1)); + + // Black + screen blk(P(-1.5,0.5), P(1.5,3.5)); + activate(blk); + set_crop(); + camera.filter(K_Process()); + + surface(f, R, color); + inset(blk, P(4,0), P(5,1)); + + end(); +} diff --git a/graphics/epix/samples/conic.xp b/graphics/epix/samples/conic.xp new file mode 100644 index 0000000000..394a326394 --- /dev/null +++ b/graphics/epix/samples/conic.xp @@ -0,0 +1,55 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const int MAX(24); +const double x0(4); +const double ht(3); // camera height +const double INFTY(100000); + +P f(double t) +{ + return P(t, t*t, 0); +} + +int main() +{ + picture(P(-3,-3),P(3,3), "4x4in"); + + begin(); + + border(); + set_crop(); + + viewpoint(0,-ht*ht, ht); + camera.look_at(P(0,0,1)); + + pen(Black(0.3), "0.1pt"); + grid(P(-MAX,0), P(MAX, MAX*MAX), MAX, MAX*MAX/8); + grid(P(-MAX, 0, 2*ht), P(MAX, MAX*MAX, 2*ht), MAX, MAX*MAX/8); + + pen(Blue(1.4)); + envelope(f, -MAX/2, MAX/2, 20); // envelope of tangent lines + + + bbold(Blue()); + Line(P(-100, INFTY, 0), P(100, INFTY, 0)); + + masklabel(P(0,0), P(0,2), "$(0,0)$", t); + label(P(0,INFTY), P(0,-2), "$(0,\\infty)$", b); + label(P(-0.25*INFTY,INFTY), P(0, 2), "Horizon", t); + + masklabel(P(x0, x0*x0), P(-4,0), "$y=x^2$", l); + + box(P(0,0)); + box(P(0,INFTY)); + + pen(1); + plot(f, -MAX, MAX, 240); + + camera.at(0,0,1000); + masklabel(P(0, ymin()), P(0,0), + "Projective equivalence of a parabola and a circle", t); + + end(); +} diff --git a/graphics/epix/samples/contour.xp b/graphics/epix/samples/contour.xp new file mode 100644 index 0000000000..2a0b093b5b --- /dev/null +++ b/graphics/epix/samples/contour.xp @@ -0,0 +1,56 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// arc arrow extent +const double theta(60); + +// arc radii +const double rad(0.25); +const double Rad(4.5); + +// half-width of slit +const double ht(0.0625); + +int main() +{ + // old-style size declarations + bounding_box(P(-5, -5), P(5,5)); + picture(160, 160); + unitlength("0.35mm"); + + begin(); + degrees(); + tikz_format(); + + // "start" angles of arcs; must come after degrees() + const double theta1(Asin(ht/rad)); + const double theta2(Asin(ht/Rad)); + + fill(Black(0.1)); // light gray + + // build keyhole in pieces; += concatenates + path contour(P(0,0), Rad*E_1, Rad*E_2, theta2, 360-theta2); // outer arc + contour += path(polar(Rad,-theta2), polar(rad,-theta1)); // lower slit + contour += path(P(0,0), rad*E_1, rad*E_2, 360-theta1, theta1); // inner arc + contour += path(polar(rad, theta1), polar(Rad, theta2)); // upper slit + + contour.close().fill().draw(); + + dot(P(0,0)); // the origin + + // plain(Black()); + arrow_width(2); + arrow_inset(0.25); + + arrow(P(Rad/4, 0.1*Rad), P(3*Rad/4, 0.1*Rad)); // arrow ends in terms of Rad + arrow(P(3*Rad/4, -0.1*Rad), P(Rad/4, -0.1*Rad)); + + arc_arrow(P(0,0), 0.9*Rad, 180-theta, 180+theta); + + label(P(Rad,ht), P(2,4), "$R\\to\\infty$", tr); + label(P(0,rad), P(0,4), "$\\delta\\to0$", tl); + label(polar(Rad, 45), P(0,0), "$\\gamma$", tr); + + end(); +} diff --git a/graphics/epix/samples/coord_tricks.xp b/graphics/epix/samples/coord_tricks.xp new file mode 100644 index 0000000000..06cf009037 --- /dev/null +++ b/graphics/epix/samples/coord_tricks.xp @@ -0,0 +1,66 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const double gap(0.15); // distance between graph portions + +Color GRAY(Black(0.5)); + +int main() +{ + picture(P(0,0),P(2+gap,2+gap), "4x4in"); + + begin(); + + plain(GRAY); + // draw in global coordinates + axis_break(P(1,0), P(1+gap,0)); + axis_break(P(0,1), P(0,1+gap)); + + // portion adjacent to origin + screen scr1(P(0,0), P(4,4)); + activate(scr1); + + set_crop(); + grid(8,8); + + h_axis_labels(4, P(0,-4), b); + v_axis_labels(4, P(-4,0), l); + + bold(Red()); + plot(recip, 0, 4, 120); + + inset(P(0,0), P(1,1)); + + // right portion + screen scr2(P(10,0), P(14,4)); + activate(scr2); + + set_crop(); + plain(GRAY); + grid(8,8); + + h_axis_labels(4, P(0,-4), b); + + bold(Red()); + plot(recip, 10, 14, 20); + + inset(P(1+gap,0), P(2+gap,1)); + + // top portion + screen scr3(P(0,10), P(4,14)); + activate(scr3); + + set_crop(); + plain(GRAY); + grid(8,8); + + v_axis_labels(4, P(-4,0), l); + + bold(Red()); + plot(recip, 0.05, 0.1, 10); + + inset(P(0,1+gap), P(1,2+gap)); + + end(); +} diff --git a/graphics/epix/samples/cropplot.xp b/graphics/epix/samples/cropplot.xp new file mode 100644 index 0000000000..b470d90497 --- /dev/null +++ b/graphics/epix/samples/cropplot.xp @@ -0,0 +1,35 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +double f(double t) { return 2*t*(1-t)*(1-t); } +double g(double t) { return 1/(1-t*t); } + +int main() +{ + picture(P(-2,-4), P(2,4), "200x200pt"); + + begin(); + + set_crop(); + // Vertical asymptotes + dashed(); + line(P(-1, ymin()), P(-1, ymax())); + line(P( 1, ymin()), P( 1, ymax())); + solid(); + + // Axes + h_axis(8); + v_axis(8); + + h_axis_labels(4, P(-1, 2), tl); // align top-left + v_axis_labels(4, P(-1, 2), tl); + + // Graphs + plot(f, xmin(), xmax(), 80); + + bold(); + plot(g, xmin(), xmax(), 80); // N.B. poles are sample points + + end(); +} diff --git a/graphics/epix/samples/cube.flx b/graphics/epix/samples/cube.flx new file mode 100644 index 0000000000..c2d1df2505 --- /dev/null +++ b/graphics/epix/samples/cube.flx @@ -0,0 +1,44 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +int main(int argc, char* argv[]) +{ + if (argc == 3) + { + char* arg; + double temp1, temp2; + temp1=strtod(argv[1], &arg); + temp2=strtod(argv[2], &arg); + + tix()=temp1/temp2; + } + + picture(P(-4,-4), P(4,4), "5 x 5in"); + + begin(); + revolutions(); + + grid(1,1); + + P ctr(3.25,-3.25); // "clock" center + bold(); + ellipse(ctr, P(0.5,0.5)); // clock face + + line(ctr, ctr+polar(0.4,tix())); // hands + label_angle(tix()-0.25); + label(ctr+polar(0.6,tix()), "$\\theta$"); + + // a cube :) + domain R(P(-2,-2,-2), P(2,2,2), mesh(1,1,1)); + + camera.at(sph(10,tix(),-0.05)); + plain(Cyan()); + plot(xyz, R); // draw cube; xyz = Cartesian pt constructor + + camera.at(sph(10,0.01 + tix(),-0.05)); // 3.6 degrees away + red(1.4); // slightly lightened red + plot(xyz, R); + + end(); +} diff --git a/graphics/epix/samples/dataplot.xp b/graphics/epix/samples/dataplot.xp new file mode 100644 index 0000000000..221c33a73c --- /dev/null +++ b/graphics/epix/samples/dataplot.xp @@ -0,0 +1,55 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +P F(double x, double y) +{ + return P((x-y)*(x+y), 2*x*y); +} + +int main() +{ + picture(P(-1,0),P(1,20), "6x6in"); + + begin(); + + // create a 2-column data file with 121 rows + data_file DF(Cos, Sin, 0, M_PI, 120); + + legend L; + plain(Black()); + fill(Blue(1.8)); + + // act on first two columns; result doubles angles + DF.transform(F); + + data_bins db(-1.05, 1.05, 21); // bins centered on -1, -0.9, ..., 0.9, 1 + db.read(DF.column(1)); // read col1 + db.bar_chart(db.pop()); // and plot, scaling to population + + L.fill_item("Population count"); // add a filled legend item + + label_color(Blue(1.2)); + v_axis_labels(P(xmin(), ymin()), P(xmin(), ymax()), 0.5*ysize(), P(-4,0), l); + // superimpose plot of raw data + screen raw(P(-1,-1), P(1,1)); + activate(raw); + label_color(Red()); + DF.plot(DDOT); // scatter plot + L.mark_item(DDOT, "Data points"); + + nofill(); + plain(Black(0.3)); + grid(1,10); + + v_axis_labels(P(1,-1), P(1,1), 4, P(4,0), r); + + // DF.write("circle.dat"); // write to a disk file + inset(P(-1,0), P(1,20)); + deactivate(raw); // polite but unnecessary + + L.draw(canvas().c(), P(0,0), c); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/decorate.xp b/graphics/epix/samples/decorate.xp new file mode 100644 index 0000000000..5b6d9cf32c --- /dev/null +++ b/graphics/epix/samples/decorate.xp @@ -0,0 +1,120 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; +/* + * Compile with, e.g. elaps -DNORMAL --huge decorate.xp + */ + +#define LINEFIELD +// #define NORMAL + +const int N1(24); // latitudes +const int N2(48); // longitudes + +const double du(1.0/N1); +const double dv(1.0/N2); + +const P VIEWPT(6, 3, 4); + +const double r_0(0.95); // minor radius +const double R_0(2); // major radius +double g(double u) +{ + return R_0 + r_0*Cos(u); +} + +P F(double u, double v) +{ + return polar(g(u), v) + P(0,0,r_0*Sin(u)); +} + +namespace ePiX { + // a facet-like class that can be drawn with extra decorations, e.g., + // normal vectors, diagonals, orientation-dependent colors... + class mesh_quad { + private: + P pt1, pt2, pt3, pt4, center; + double distance; + + public: + mesh_quad(P f(double u, double v), double u0, double v0) + : pt1(f(u0,v0)), pt2(f(u0+du,v0)), pt3(f(u0+du,v0+dv)), pt4(f(u0,v0+dv)), + center(0.25*(pt1 + pt2 + pt3 + pt4)), + distance(norm(center-camera.viewpt())) { } + + double how_far() const { return distance; } + + void draw() const + { + P direction(center-camera.viewpt()); + P normal((pt2 - pt1)*(pt4 - pt1)); + normal *= 1/norm(normal); + + blue(0.75*(normal|(recip(distance)*direction))); + +#ifdef NORMAL + if ((normal|direction) < 0) + { + plain(Green(0.6)); + arrow(center, center-0.5*normal, 0.5); + } +#endif + fill(); + ePiX::quad(pt1, pt2, pt3, pt4); + fill(false); + +#ifdef LINEFIELD + if ((normal|direction) > 0) + bbold(Blue(1.8)); + else + bold(Red()); + + line(pt1, 0.5*(pt3+pt4)); + line(0.5*(pt1+pt2), pt3); +#endif + +#ifdef NORMAL + if ((normal|direction) > 0) + { + plain(Green(0.6)); + arrow(center, center-0.5*normal, 0.5); + } +#endif + } + }; + + class by_distance { + public: + bool operator() (const mesh_quad& arg1, const mesh_quad& arg2) + { return arg1.how_far() > arg2.how_far(); } + }; +} // end of namespace + +int main() { + picture(P(-3,-3),P(3,3), "4x4in"); + + begin(); + revolutions(); + + viewpoint(VIEWPT); + camera.range(10); + + // chop off the front + clip_face(P(R_0, 0, r_0), P(-0.25,-0.25,-1)); + + // build and draw a torus + std::vector<mesh_quad> mesh; + + for (int i=0; i<N1; ++i) + for (int j=0; j<N2; ++j) + mesh.push_back(mesh_quad(F, i*du, j*dv)); + + sort(mesh.begin(), mesh.end(), by_distance()); + + // arrow_fill(1); + for (unsigned int i=0; i<mesh.size(); ++i) + mesh.at(i).draw(); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/demoivre.xp b/graphics/epix/samples/demoivre.xp new file mode 100644 index 0000000000..1225906a12 --- /dev/null +++ b/graphics/epix/samples/demoivre.xp @@ -0,0 +1,42 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const int N(24); +const double theta(0.875*M_PI); +const pair alpha(1, theta/N); + +// pairs implement complex arithmetic, but need P to draw +P pair2P(pair arg) +{ + return P(arg.x1(), arg.x2()); +} + +int main() +{ + picture(P(-1.5,0), P(1,1.25), "200 x 100pt"); + + begin(); + + pair power(1,0); + + for(int i=0; i<N; ++i) + { + line(P(0,0), pair2P(alpha*power)); // draw two sides + line(pair2P(power), pair2P(alpha*power)); // of triangle + power *= alpha; // and increment power + } + + label(pair2P(alpha), P(2,0), "$\\alpha=1+\\frac{i\\theta}{n}$", r); + label_angle(theta-M_PI); + ddot(pair2P(power), P(2,4), "$\\alpha^n\\approx e^{i\\theta}$", b); + + plain(Black(0.3)); + arc(P(0,0), 1, 0, theta); + ddot(cis(theta), P(0,-4), "$$", b); + + bold(Red()); + triangle(P(0, 0), P(1, 0), pair2P(alpha)); + + end(); +} diff --git a/graphics/epix/samples/denom.xp b/graphics/epix/samples/denom.xp new file mode 100644 index 0000000000..015f29bb4a --- /dev/null +++ b/graphics/epix/samples/denom.xp @@ -0,0 +1,39 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +int N(30); // maximum denominator plotted + +int main() +{ + picture(P(-2,0), P(2,1), "4x1in"); + + begin(); + tikz_format(); + + axis Ax(P(-2,0), P(2,0), 8, P(0,-6), b); + Ax.subdivide(6).frac().draw(); + + v_axis(2); + + dot_size(2); + for (int i=1; i< N; ++i) + for (int j=i*xmin(); j <= i*xmax(); ++j) + if (gcd(i, j) == 1) + ddot(P(j*1.0/i, 1.0/i)); + + font_size("scriptsize"); + + // The long label text can be written in one string, but using a + // stringstream allows the input to be formatted more readably. + std::stringstream buf; + buf << "$f(x)=\\begin{cases}%" << std::endl + << " \\frac{1}{q} & " + << "\\text{ $x=\\frac{p}{q}$ in lowest terms} \\\\" << std::endl + << " 0 & \\text{ $x$ irrational}%" << std::endl + << "\\end{cases}$"; + + label(P(0,0.75), P(2,0), buf.str(), r); + end(); +} + diff --git a/graphics/epix/samples/densityplot.xp b/graphics/epix/samples/densityplot.xp new file mode 100644 index 0000000000..51ef671cc6 --- /dev/null +++ b/graphics/epix/samples/densityplot.xp @@ -0,0 +1,44 @@ +/* -*-ePiX-*- */ +#include <epix.h> +using namespace ePiX; + +const int MAX(18); + +// basic circular wave +double ripple(double u, double v) +{ + return pow(Cos(0.5*sqrt(u*u+v*v)),2); +} + +// superposition +double f(double u, double v) +{ + return 0.25*(1+ripple(u, v-10) + ripple(u, v+10)); +} + +// f as a parametric surface +P F(double u, double v) +{ + return P(u, v, f(u,v)); +} + +// height-dependent coloring +P color(double u, double v, double w) +{ + return P(0.2+0.8*w, 0.3, 0.8 - 0.6*w); +} + +domain R(P(-MAX,-MAX), P(MAX,MAX), mesh(2*MAX, 2*MAX)); + +int main() +{ + picture(P(-MAX,-MAX), P(MAX,MAX), "3x3in"); + + begin(); + + pen(Magenta(1.4), 0.2); + surface(F, R, color); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/dipole.xp b/graphics/epix/samples/dipole.xp new file mode 100644 index 0000000000..da17229481 --- /dev/null +++ b/graphics/epix/samples/dipole.xp @@ -0,0 +1,86 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// number of field lines per charge +const int N(13); + +// charge magnitudes and locations +const int charge1(1); +const int charge2(1); + +const P Q1( 1,0); +const P Q2(-1,0); + +// inverse-square electric field from a point charge at the origin +P unit_charge(const P& arg) +{ + return recip(arg|arg)*arg; +} + +// electric field simulated by superimposing individual fields, then +// re-scaling so that field -> 0 near the charge location (improves +// plot quality:) +P E(double x, double y) +{ + P temp(x,y); + // superposition of charge fields + P E_temp(charge1*unit_charge(temp-Q1) + charge2*unit_charge(temp-Q2)); + + // re-scale + return (1.0/(E_temp|E_temp))*E_temp; +} + +P potential(double x, double y) +{ + // J rotates a vector by 1/4 turn; parallel to equipotentials + return J(E(x,y)); +} + +const double MAX(3); + +int main() +{ + picture(P(-MAX,-MAX), P(MAX,MAX), "4x4in"); + + begin(); + set_crop(); + degrees(); // change angle mode + + // plot field lines + blue(); + for (int i=0; i < N; ++i) + { + // initial points trace a small circle about Q1 or Q2, + ode_plot(E, Q1+polar(0.05, i*360.0/N), 10, 120); + ode_plot(E, Q2-polar(0.05, i*360.0/N), 10, 120); + + // location of arrowhead + P pt(flow(E, Q2-polar(0.05, i*360.0/N), 3, 12)); + } + + green(); + for (int i=-10; i < 10; ++i) + { + ode_plot(potential, Q1+polar(0.25*pow(0.8, i), 0), 2*M_PI, 120); + ode_plot(potential, Q2-polar(0.25*pow(0.8, i), 0), 2*M_PI, 120); + } + + dot_size(6); + circ(Q1); + circ(Q2); + + magenta(); + label(Q1, "$+$"); + label(Q2, "$+$"); + + blue(); + for (int i=0; i < N; ++i) + { + P pt(flow(E, Q2-polar(0.05, i*360.0/N), 3.5, 12)); + arrow(pt, pt+0.01*E(pt.x1(), pt.x2())); + arrow(-pt, -pt+0.01*E(-pt.x1(), -pt.x2())); + } + + end(); +} diff --git a/graphics/epix/samples/extract.xp b/graphics/epix/samples/extract.xp new file mode 100644 index 0000000000..b061df18db --- /dev/null +++ b/graphics/epix/samples/extract.xp @@ -0,0 +1,109 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// a benign function +double phi(double x) +{ + return x*x; +} + +// and its derivative +Deriv dphi(phi); + +// parameters defining an arbitrary line ell +const double slope(-2); +const double beta(0.5); + +const double ht(phi(beta)); +const double alpha(slope-dphi.eval(beta)); + +const double eps(0.02); // size of extraction + +// a small perturbation to adjust the derivative +double f(double x) +{ + return x/(1+16384*x*x); +} + +double gn(double x) +{ + return f(alpha*(x-beta)); +} + +// phi's Evil Twin +double psi(double x) +{ + return phi(x) + gn(x); +} + +// inset parameters +const P mag_ctr(P(0.75, 0.2)); +const double mag_sz(0.125); + +int main() +{ + picture(P(0,0), P(1,0.75), "4x3in"); + + begin(); + set_crop(); + + // two nearly-equal graphs, and the tangent to one of them + plain(Blue()); + plot(psi, xmin(), beta-eps, 60); + plot(psi, beta+eps, xmax(), 60); + plot(psi, beta-eps, beta+eps, 60); + + pen(Green(0.6)); + Line(P(beta,phi(beta)), slope); + + bold(Red()); + plot(phi, xmin(), xmax(), 60); + plain(); + + // cut out a small neighborhood and magnify it + screen mag(canvas().extract_ellipse(P(beta-eps, psi(beta)-eps), + P(beta+eps, psi(beta)+eps))); + mag.backing(Yellow(0.05)); + mag.border(Black(), "0.4pt"); + + inset(mag, mag_ctr - mag_sz*P(1,1), mag_ctr + mag_sz*P(1,1)); + + pen(Black()); + // axes + line(P(xmin(),0), P(xmax(),0)); + line(P(0,ymin()), P(0,ymax())); + + // indicators + line(P(beta,0), P(beta,phi(beta)), -20); // shorten slightly + line(P(0,phi(beta)), P(beta,phi(beta)), -10); + + // zoom lines + line(P(beta, phi(beta)), mag_ctr + polar(mag_sz, 2*M_PI/3), -20); + line(P(beta, phi(beta)), mag_ctr + polar(mag_sz, 5*M_PI_4), -20); + + font_size("footnotesize"); + label(P(beta,0), P(0,-4), "$\\beta$", b); + label(P(0,phi(beta)), P(-4,0), "$b$", l); + + // use mag_ctr to place inset labels + red(); + label(P(beta+0.1,phi(beta+0.1)), P(-2,2), "$\\varphi$",tl); + label(mag_ctr, P(0,6), "$\\varphi$",tr); + + blue(); + label(P(beta+0.1,psi(beta+0.1)), P(2,-2), "$\\psi$",br); + label(mag_ctr, P(8,-2), "$\\psi$",br); + + green(0.6); + label(P(beta-0.1,ht-0.1*slope), P(2,2), "$\\ell$",tr); + label(mag_ctr, P(-12,20), "$\\ell$", bl); + + black(); + // a large label + label_border(Blue(), "0.2pt"); + masklabel(P(0.5*(xmin()+xmax()), ymax()), P(0,0), + "\\begin{minipage}{2.25in}A graph with unexpected tangent line\\end{minipage}", b); + + end(); +} diff --git a/graphics/epix/samples/geomsum.xp b/graphics/epix/samples/geomsum.xp new file mode 100644 index 0000000000..665b1568e8 --- /dev/null +++ b/graphics/epix/samples/geomsum.xp @@ -0,0 +1,37 @@ +/* -*-ePiX-*- */ +/* geomsum.c -- July 16, 2001 */ +#include "epix.h" +using namespace ePiX; + +const int N(8); + +int main() +{ + picture(P(0,0), P(1,1), "2.5x2.5in"); + begin(); + + pen(White(), "0.8pt"); + fill(White(0.9)); + rect(P(0,0), P(1,1)); + + black(); + label(P(1.0/4, 1.0/2), "$\\frac{1}{2}$"); + label(P(5.0/8, 3.0/4), "$\\frac{1}{8}$"); + label(P(13.0/16, 7.0/8), "$\\frac{1}{32}$"); + + white(); + fill(Blue()); + double t(0.5); + + for(int i=0; i<N; ++i, t *= 0.5) + { + rect(P(1-t, 1-2*t), P(1, 1-t)); + line(P(1-t, 1-2*t), P(1-t, 1)); + } + + label(P(3.0/4, 1.0/4), "$\\mathbf{\\frac{1}{4}}$"); + label(P(7.0/8, 5.0/8), "$\\mathbf{\\frac{1}{16}}$"); + label(P(15.0/16, 13.0/16), "$\\mathbf{\\frac{1}{64}}$"); + + end(); +} diff --git a/graphics/epix/samples/golden_rect.xp b/graphics/epix/samples/golden_rect.xp new file mode 100644 index 0000000000..f6fc6d54a1 --- /dev/null +++ b/graphics/epix/samples/golden_rect.xp @@ -0,0 +1,29 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const double tau((1+sqrt(5))/2); + +int main() +{ + bounding_box(P(0,0), P(tau,1)); + picture(100*(1+tau), 100*tau); + unitlength("0.0125in"); + + begin(); + + dashed(); + line(P(0.5,0), P(0.5,1)); + + solid(); + line(P(1,0), P(1,1)); + line(P(0.5,0), P(1,1)); + + arc(P(0.5,0), tau-0.5, 0, Atan(2.0)); + + bold(); + rect(P(0,0), P(tau, 1)); + + end(); +} + diff --git a/graphics/epix/samples/helicoid.flx b/graphics/epix/samples/helicoid.flx new file mode 100644 index 0000000000..fdf68fc7ad --- /dev/null +++ b/graphics/epix/samples/helicoid.flx @@ -0,0 +1,133 @@ +/* -*-flix-*- */ +/* + * Animation depicting the local isometric deformation of a + * catenoid to a helicoid through minimal immersions + */ +#include "epix.h" +using namespace ePiX; + +// number of meridians and latitudes +int N1(72); +int N2(24); + +P VIEWPT(4, 3, 4); + +// locations of "lights"; see mesh::draw() below for implementation +P LIGHT_R(10,0,10); +P LIGHT_G(0,10,10); +P LIGHT_B(0,-10,10); + +// internal constants +double r_0(1.0); +double EPS(0.0); // fact shrink factor +double du(2.0/N1), dv(4.0/N2); + +// parametrized surfaces +P helicoid(double u, double v) +{ + return P(sinh(v)*Cos(M_PI*u), sinh(v)*Sin(M_PI*u), 2*M_PI*u); +} + +P catenoid(double u, double v) +{ + return P(cosh(v)*Sin(M_PI*u), -cosh(v)*Cos(M_PI*u), -v); +} + +P morph(double u, double v) +{ + return Cos(2*M_PI*tix())*helicoid(u,v) + Sin(2*M_PI*tix())*catenoid(u,v); +} + +// facet-like class with spot reflection +class element +{ +private: + P pt1; + P pt2; + P pt3; + P pt4; + + double distance; + +public: + element(P f(double u, double v), double u0, double v0) + : pt1(f(u0+EPS,v0+EPS)), pt2(f(u0+du-EPS,v0+EPS)), + pt3(f(u0+du-EPS,v0+dv-EPS)), pt4(f(u0+EPS,v0+dv-EPS)) + { + P center(0.25*(pt1 + (pt2 + (pt3 + pt4)))); + P temp(camera.viewpt()); + + distance = norm(center-temp); + } + + double how_far() const { return distance; } + + void draw() + { + P normal((pt2 - pt1)*(pt4 - pt1)); + normal *= 1/norm(normal); + + double dens_r(0.75*(pow(normal|LIGHT_R, 2)/(LIGHT_R|LIGHT_R))); + double dens_g(0.75*(pow(normal|LIGHT_G, 2)/(LIGHT_G|LIGHT_G))); + double dens_b(0.75*(pow(normal|LIGHT_B, 2)/(LIGHT_B|LIGHT_B))); + + fill(RGB(dens_r, dens_g, dens_b)); + ePiX::quad(pt1, pt2, pt3, pt4); + } + +}; + +class By_distance { +public: + bool operator() (const element& arg1, const element& arg2) + { + return arg1.how_far() > arg2.how_far(); + } +}; + + +int main(int argc, char* argv[]) +{ + if (argc == 3) + { + char* arg; + double temp1, temp2; + temp1=strtod(argv[1], &arg); + temp2=strtod(argv[2], &arg); + + tix()=temp1/temp2; + } + + double MAX(8); + picture(P(-MAX,-MAX),P(MAX,MAX), "5x5in"); + + begin(); + pen(Neutral(), 0); // no grid lines + + // draw bounding square for uniform frame size + backing(Black()); + viewpoint(VIEWPT); + + /* rotating lights + LIGHT_R=cis(2*M_PI*tix()); + LIGHT_G=cis(2*M_PI*(tix()+0.25)); + LIGHT_B=P(-2,-2,6); + */ + + camera.range(20); + + // build surface + std::vector<element> mesh; + + for (int i=0; i<N1; ++i) + for (int j=0; j<N2; ++j) + mesh.push_back(element(morph, -1+du*i, -2+dv*j)); + + sort(mesh.begin(), mesh.end(), By_distance()); + + for (unsigned int i=0; i<mesh.size(); ++i) + mesh.at(i).draw(); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/hello.xp b/graphics/epix/samples/hello.xp new file mode 100644 index 0000000000..812529f654 --- /dev/null +++ b/graphics/epix/samples/hello.xp @@ -0,0 +1,20 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +int main() +{ + picture(P(-1,-1), P(1,1), "2x1in"); + + begin(); + + // uncomment and permute these lines + // crop_ellipse(); + // backing(Cyan()); + border(Black(), "1pt"); + + font_size("Huge"); + label(P(0,0), "Hello, world!"); + + end(); +} diff --git a/graphics/epix/samples/histogram.xp b/graphics/epix/samples/histogram.xp new file mode 100644 index 0000000000..47e704fba2 --- /dev/null +++ b/graphics/epix/samples/histogram.xp @@ -0,0 +1,83 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// See binom.cc for instructions on creating data file binom.dat + +double erf(double x) +{ + return 100*exp(-0.02*(x-50)*(x-50))/sqrt(50*M_PI); +} + +int main() +{ + picture(P(0,0),P(100,20), "6 x 6in"); + + begin(); + + grid(1,10); + + // read disk file + data_file binom("binom.dat"); + + // create "bins" for bar chart + data_bins db05(-0.5, 100.5, 101); // 5% biased coin + data_bins db10(-0.5, 100.5, 101); // 10% + data_bins db30(-0.5, 100.5, 101); // 30% + data_bins db50(-0.5, 100.5, 101); // 50% + + db05.read(binom.column(1)); + db10.read(binom.column(2)); + db30.read(binom.column(3)); + db50.read(binom.column(4)); + + legend L; + + fill(); + gray(0.6); + db05.bar_chart(100); + L.fill_item("5\\%"); + + gray(0.4); + db10.bar_chart(100); + L.fill_item("10\\%"); + + gray(0.2); + db30.bar_chart(100); + L.fill_item("30\\%"); + + gray(0); + db50.bar_chart(100); + L.fill_item("50\\%"); + + nofill(); + + font_size("footnotesize"); + tick_size(1); + bottom_axis(10, P(0,-4), b).draw(); + + left_axis(10, P(-4,0), l).subdivide(2).draw(); + + bold(Red()); + plot(erf, xmin(), xmax(), 240); + L.path_item("Normal"); + + font_size("LARGE"); + L.key_size(18); + L.draw(P(50, 12.5), P(2,2), tr); + + font_face("sc"); + label(P(0.5*(xmin()+xmax()), ymax()), P(0,12), + "Tossing a Biased Coin, 100,000 Trials", t); + + font_size(); // reset to default + label(P(0.5*(xmin()+xmax()), ymin()), P(0,-18), + "Number of Heads (100 Tosses per Trial)", b); + + degrees(); + label_angle(90); + label(P(xmin(), 0.5*(ymin()+ymax())), P(-18,0), "Percentage of Trials", l); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/house.flx b/graphics/epix/samples/house.flx new file mode 100644 index 0000000000..7f4d683849 --- /dev/null +++ b/graphics/epix/samples/house.flx @@ -0,0 +1,88 @@ +/* -*-flix-*- */ +#include "epix.h" +using namespace ePiX; + +const double DY(0.1); +const int N(200); +const double dN(1.0/N); + +int main(int argc, char* argv[]) +{ + if (argc == 3) + { + char* arg; + double temp1, temp2; + temp1=strtod(argv[1], &arg); + temp2=strtod(argv[2], &arg); + + tix()=temp1/temp2; + } + + picture(P(0,0), P(5,3), "5 x 3in"); + + begin(); + set_crop(); + // sky + bbold(); + for (int i=0; i<2*N; ++i) + { + // fade blue gradient to black + rgb((1-0.6*tix())*(0.5-0.25*dN*i), + (1-0.6*tix())*(0.5-0.25*dN*i), + (1-0.6*tix())*(1-0.2*dN*i)); + + line(P(0,1+i*dN), P(5,1+i*dN)); + } + + // sun + pen(4); + revolutions(); + for (int i=1; i<=10; ++i) + { + // redden as tix() -> 1 + rgb((1-0.25*tix())*(1-0.01*i), (1-tix())*(1-0.015*i), 0); + circle(P(3+0.5*tix(), 2.5 - 2*tix()), 0.025*i); + } + + // roof + red(0.6*(1-0.6*tix())); + line(P(0.9,1.5), P(1.5,1.8)); + line(P(2.1,1.5), P(1.5,1.8)); + + // lawn + bbold(); + for (int i=0; i<N; ++i) + { + // fade green gradient to black + green((1-0.6*tix())*0.4*(1+i*dN)); + + line(P(0,i*dN), P(5,i*dN)); + } + + plain(); + fill(); + gray(0.2+0.8*tix()); + + path house; + house.pt(P(1,1-DY)).pt(P(2,1-DY)).pt(P(2, 1.5)).pt(P(1.5,1.75)).pt(P(1,1.5)); + house.close().fill(); + house.draw(); + + gray(0.1+0.4*tix()); + + rect(P(1.2,1.1), P(1.4, 1.3)); // window + + pen(2); + dot_size(1); + rgb(0.8*(1-tix()), 0.8*(1-tix()), 0); + ring(P(1.65, 1.15)); // doorknob + + fill(false); + plain(Black()); + rect(P(1.6, 1-DY), P(1.85, 1.4)); // door frame + + bold(RGB((1-tix())*(0.6),(1-tix())*(0.4),(1-tix())*(0.2))); + grid(P(1.2,1.1), P(1.4, 1.3), 2, 2); // panes + + end(); +} diff --git a/graphics/epix/samples/hyperboloid.xp b/graphics/epix/samples/hyperboloid.xp new file mode 100644 index 0000000000..6ea45c9192 --- /dev/null +++ b/graphics/epix/samples/hyperboloid.xp @@ -0,0 +1,63 @@ +/* -*-ePiX-*- */ +// A circular hyperboloid of one sheet and its two families of rulings +#include "epix.h" +using namespace ePiX; + +const int NUM_LINES(64); +const double dt(1.0/NUM_LINES); + +int main() +{ + picture(P(-3, -3), P(3, 3), "6x6in"); + + begin(); + revolutions(); + + cam().at(20, 0, 5); + + clip_box(P(4, 4, 2)); + + fill(Black(0.8)); + + // hyperboloid + surface_rev(sinh, cosh, domain(P(-2,0), P(2,1), mesh(24,36)), + frame(E_3, E_2, E_1)); + + // clip to {x>0} + clip_box(P(0, -4, -2), P(4, 4, 2)); + + // rulings + for (int i=-0.5*NUM_LINES; i <= 0.5*NUM_LINES; ++i) + { + const double t(i*dt); + rgb(0,0.5,1); + Line(P(Cos(t), Sin(t), 0), P(Cos(t) + Sin(t), Sin(t) - Cos(t), 1)); + + red(); + Line(P(Cos(t), Sin(t), 0), P(Cos(t) - Sin(t), Sin(t) + Cos(t), 1)); + } + + // emphatic rulings + bbold(RGB(0.1,0.6,0.9)); + Line(P(1,0,0), P(1,-1,1)); + + pen(Red(1.2)); + Line(P(1,0,0), P(1,1,1)); + Line(P(0,1,0), P(-1,1,1)); + + clip_box(); + // font_size("footnotesize"); + black(); + label(P(1,0,0)-P(0,-2,2), P(2,-2), "$\\ell_0^-$", br); + label(P(1,0,0)+P(0, 2,2), P(18,2), "$\\ell_0^+$", t); + label(P(0,1,0)-P(-2,0,2), P(0,-4), "$\\ell_{\\pi/2}^+$",b); + + label(P(0,0,-3), P(0,-24), + "$\\ell_\\theta^-(t)=(\\cos\\theta, \\sin\\theta, 0) + t(\\sin\\theta, -\\cos\\theta, 1)$", b); + + label(P(0,0,-3), P(0,-12), + "$\\ell_\\theta^+(t)=(\\cos\\theta, \\sin\\theta, 0) + t(-\\sin\\theta, \\cos\\theta, 1)$", b); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/inverse.xp b/graphics/epix/samples/inverse.xp new file mode 100644 index 0000000000..d336b67b31 --- /dev/null +++ b/graphics/epix/samples/inverse.xp @@ -0,0 +1,74 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// parameters and an odd cubic +const double x0(0.4); // critical point +const double sqrt3(sqrt(3)); + +double f(double x) +{ + return 2*x*(x-sqrt3*x0)*(x+sqrt3*x0); +} + +int main() +{ + picture(P(-2,-1), P(2,1), "6 x 3in"); + + begin(); + + degrees(); + + // draw "ordinary" graph + screen tmp(P(-1,-1), P(1,1)); + activate(tmp); + + // diagonal + pen(Black(0.1)); + line(P(-1,-1), P(1,1)); + + // two-headed arrow + pen(Black(0.3)); + aarrow(P(0.4,0.6), P(0.6,0.4), 0.5); + + // axes and labels + pen(Black()); + font_size("footnotesize"); + + h_axis(8); + v_axis(8); + + masklabel(P(1,0), "$x$"); + masklabel(P(0,1), "$y$"); + + label(P(0.5,-0.5), "$y=f(x)$"); + + label_angle(-90); + label(P(-0.5,0.5), "$x=f^{-1}(y)$"); + + // crop remaining elements + tmp.set_crop(); + + // a horizontal tangent line + plain(Blue(1.4)); + tan_line(f, x0); + + // graphs that will be inverse branches + plain(Red(1.4)); + plot(f, -1, -x0, 20); + + bold(Red()); + plot(f, -x0, x0, 20); + + plain(Red(1.4)); + plot(f, x0, 1, 20); + + inset(tmp, P(-2,-1), P(0,1)); + + // flip plane over diagonal + affine af; + af.reflect(45).shift(P(0.25,0)); // compose affine maps + inset(tmp.apply(af), P(0,-1), P(2,1)); + + end(); +} diff --git a/graphics/epix/samples/koch.xp b/graphics/epix/samples/koch.xp new file mode 100644 index 0000000000..8a9683715c --- /dev/null +++ b/graphics/epix/samples/koch.xp @@ -0,0 +1,38 @@ +/* -*-ePiX-*- */ +/* koch.c -- May 29, 2002 */ +#include "epix.h" +using namespace ePiX; + +const int koch_seed[] = {6, 4, 0, 1, -1, 0}; + +int main() +{ + picture(P(0,0), P(4, 1), "6 x 1.5in"); + + begin(); + degrees(); + + for (int i=1; i <= 4; ++i) + { + // draw von Koch curve at "depth" i + screen tmp(P(-1,-1), P(1,1)); + activate(tmp); + + if (i==1) + { + bold(Red()); + fractal(cis(150), cis(30), i, koch_seed); + plain(Black()); + } + else + fractal(cis(150), cis( 30), i, koch_seed); + + fractal(cis( 30), cis(-90), i, koch_seed); + fractal(cis(-90), cis(150), i, koch_seed); + + inset(tmp, P(i-1,0), P(i,1)); + deactivate(tmp); + } + end(); +} + diff --git a/graphics/epix/samples/label_debug.xp b/graphics/epix/samples/label_debug.xp new file mode 100644 index 0000000000..0ca0462d74 --- /dev/null +++ b/graphics/epix/samples/label_debug.xp @@ -0,0 +1,132 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +/* + * Font tests; draws all 32 combinations of five attributes: + * + * label_color: (Neutral: cols 1, 3; Red, cols 2, 4) + * label_mask: (Neutral: cols 1, 2; Yellow: cols 3, 4) + * + * label_border color: (Neutral: odd rows, Blue otherwise) + * label_border width: (0pt: rows 1-2, 5-6, 1pt otherwise) + * + * pad: (0pt: rows 1-4, 1pt otherwise) + */ + +// test objects +void objs() +{ + label(P(-0.5,0), "The"); + masklabel(P(0.5,0), "The"); +} + +// attribute-setting commands on bool flags +void label_color(bool arg) +{ + if (arg) + label_color(Red()); + + else + label_color(Neutral()); +} + +void label_mask(bool arg) +{ + if (arg) + label_mask(Yellow(0.3)); + else + label_mask(Neutral()); +} + +void set_border(bool col, std::string len) +{ + if (col) + label_border(Blue(1.2), len); + + else + label_border(Neutral(), len); +} + +void label_border(bool col, bool wid) +{ + if (wid) + set_border(col, "1pt"); + + else + set_border(col, "0pt"); +} + +void pad(bool arg) +{ + if (arg) + label_pad("6pt"); + + else + label_pad("0pt"); +} + +// we'll use 0, 1 as loop indices; convert to bool +bool tf(int i) +{ + return i == 0 ? false : true; +} + +// where to position the result of a test +P loc(int i0, int i1, int i2, int i3, int i4) +{ + double horiz(0), vert(7); + if (tf(i0)) + horiz += 1; + + if (tf(i1)) + horiz += 2; + + if (tf(i2)) + vert -= 1; + + if(tf(i3)) + vert -= 2; + + if (tf(i4)) + vert -= 4; + + return P(horiz, vert); +} + +int main() +{ + picture(P(0,0), P(4,8), "6 x 9in"); + + begin(); + + // the tests proper + for (int i0=0; i0<2; ++i0) + for (int i1=0; i1<2; ++i1) + for (int i2=0; i2<2; ++i2) + for (int i3=0; i3<2; ++i3) + for (int i4=0; i4<2; ++i4) + { + screen scr(P(-1,-1), P(1,1)); + activate(scr); + + solid(); // may need to reset line style + border(Green(0.6), "0.1pt"); + + backing(Black(0.1)); + pen(Black(0.3)); + grid(8,8); + + label_color(tf(i0)); + label_mask(tf(i1)); + label_border(tf(i2),tf(i3)); + pad(tf(i4)); + + objs(); + + scr.scale(0.9); + inset(loc(i0,i1,i2,i3,i4), loc(i0,i1,i2,i3,i4) + P(1,1)); + deactivate(scr); + } + end(); +} diff --git a/graphics/epix/samples/layout.xp b/graphics/epix/samples/layout.xp new file mode 100644 index 0000000000..0967af53e2 --- /dev/null +++ b/graphics/epix/samples/layout.xp @@ -0,0 +1,36 @@ +/* -*-ePiX-*- */ +/* layout.xp -- June 27, 2007 */ +#include "epix.h" +using namespace ePiX; + +P f(double u, double v) +{ + return P((u-v)*(u+v), 2*u*v, u); +} + +int main() +{ + picture(P(0,0), P(2,3), "5x7.5in"); + + begin(); + + domain R(P(-1,-1), P(1,1), mesh(12,12), mesh(24,24)); + + for (int i=0; i<2; ++i) + for (int j=0; j<3; ++j) + { + screen my(P(-3,-3), P(3,3)); + activate(my); + border(Red(0.6), "1pt"); + camera.at(sph(10, (2*j+i+1)*M_PI/8, M_PI/6)); + + plot(f, R); + arrow(P(0,0,0), 2*E_1); + arrow(P(0,0,0), 2*E_2); + inset(P(i+0.05,2.05-j), P(i+0.95,2.95-j)); + deactivate(my); + } + + end(); +} + diff --git a/graphics/epix/samples/layout2.xp b/graphics/epix/samples/layout2.xp new file mode 100644 index 0000000000..f2203a2a84 --- /dev/null +++ b/graphics/epix/samples/layout2.xp @@ -0,0 +1,42 @@ +/* -*-ePiX-*- */ +/* layout.xp -- June 27, 2007 */ +#include "epix.h" +using namespace ePiX; + +P F(double s, double t) +{ + return P(0.1*s, 0.025*t) + (1/(0.01+s*s+t*t))*P(-t, s); +} + +int main() +{ + picture(P(0,0), P(2,3), "5x7in"); + + begin(); + + for (int k=0; k<3; ++k) + for (int j=0; j<2; ++j) + { + screen my(P(-4, -3), P(2,2)); + activate(my); + + border(Red(0.6), "1pt"); + set_crop(); + plain(Blue(1.8)); + dart_field(F, P(-4, -3), P(2, 2), 12, 10); + + bold(); + for (int i=0; i<7; ++i) + { + pen(RGB(0.05*(7-i), 1 - 0.1*i, 0.15*i)); + ode_plot(F, P(-0.9-0.025*i,0), 4*(3*j+k+0.5), 30*(3*j+k+0.5)); + } + + inset(P(j+0.05,1.05-k), P(j+0.95,1.95-k)); + + deactivate(my); + } + + end(); +} + diff --git a/graphics/epix/samples/legend.xp b/graphics/epix/samples/legend.xp new file mode 100644 index 0000000000..a6be848bc9 --- /dev/null +++ b/graphics/epix/samples/legend.xp @@ -0,0 +1,72 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +P sin_n(double x, double n) // Taylor polynomial of sin x +{ + const int N((int) floor(n)); // convert y to an index bound + const double sqx(-pow(x, 2)); // store -x^2 for efficiency + double val(x), summand(x); // places to store results of evaluation + + // step through odd numbers from 1 to 2N+1 + for (int i=1; i <= 2*N+1; i += 2) + { + summand *= (sqx/((i+1)*(i+2))); // (-1)^i x^{2i+1}/(2i+1)! + val += summand; + } + + return P(x, val); +} + +int main() +{ + picture(P(0,-2.5),P(6*M_PI, 1), "5x3.5in"); + + begin(); + + camera.filter(CMY_Neutral()); + set_crop(); + plain(Black(0.5)); + grid(12, 7); + + // coordinate axis + axis Ax(P(0,0), P(6*M_PI,0), 12, P(0,-4), b); + Ax.trig().subdivide(4); + + axis Ay(P(0,ymin()), P(0,ymax()), 7, P(-4,0), l); + Ay.frac().draw_labels(); + + // define a legend and set global attributes + legend L; + L.backing(Yellow(0.1)).border(Blue(), 1).item_border(0); + + bbold(Green()); + plot(Sin, 0, xmax(), 120); + + // add a legend item + L.path_item("$y=\\sin x$"); + + domain R(P(0,1), P(6*M_PI, 41), mesh(60, 40), mesh(240, 40)); + + // print in descending degree so paths overlap better + for (int i=3; 0 <= i; --i) + { + pen(RGB(0.25*i, 0, 1-0.25*i)); + plot(sin_n, R.slice2(5*i+1)); + + // add a legend item; key set automatically + std::stringstream buf; + buf << "$y=p_{" << 10*i+5 << "}(x)$"; + L.path_item(buf.str()); + } + + plain(Black()); + label_mask(White()); + Ax.draw(); + + // place at bottom left + L.draw(canvas().bl(), P(2,2), tr); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/levelset.xp b/graphics/epix/samples/levelset.xp new file mode 100644 index 0000000000..c802f5dc52 --- /dev/null +++ b/graphics/epix/samples/levelset.xp @@ -0,0 +1,60 @@ +/* -*-ePiX-*- */ +/* levelset.xp -- level sets */ +#include "epix.h" +using namespace ePiX; + +const int MAX(3); +const double k(0.25); + +P Fp(double u, double v) +{ + double r(sqrt(fabs(v))); + if (v>=0) + return P(r*cosh(u), r*sinh(u), k*v); + + else + return P(-r*sinh(u), -r*cosh(u), k*v); + +} + +P Fm(double u, double v) +{ + double r(sqrt(fabs(v))); + if (v>=0) + return P(-r*cosh(u), r*sinh(u), k*v); + + else + return P(-r*sinh(u), r*cosh(u), k*v); + +} + +double f(double x, double y) +{ + return k*(x-y)*(x+y); +} + +int main() +{ + picture(P(-MAX,-MAX), P(MAX, MAX), "2x2in"); + + begin(); + + camera.at(P(1,-3,5)); + camera.range(40); + + clip_box(P(MAX,MAX,2*MAX)); + clip(); + + red(); + plot(f, P(-MAX,-MAX), P(MAX, MAX), mesh(4,4), mesh(40,40)); + + domain R(P(-4,-9), P(4,9), mesh(1,12), mesh(90,1)); + + bold(); rgb(0.5,0.5,1); + line(P(MAX,-MAX,0), P(-MAX, MAX,0)); + line(P(MAX, MAX,0), P(-MAX,-MAX,0)); + plot(Fp, R.slices2()); + plot(Fm, R.slices2()); + + end(); +} diff --git a/graphics/epix/samples/levelset2.xp b/graphics/epix/samples/levelset2.xp new file mode 100644 index 0000000000..ab1a605069 --- /dev/null +++ b/graphics/epix/samples/levelset2.xp @@ -0,0 +1,72 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// Style parameters +const int MAX(1); // maximum coordinate + +domain R(P(-MAX,-MAX), P(MAX, MAX), (24, 24), mesh(72,72)); + +const double sqrt3(sqrt(3)); + +// function to be graphed +P f(double x, double y) +{ + return P(x, y, 0.75*y*(y-sqrt3*x)*(y+sqrt3*x)); +} + +P color(double u, double v, double w) +{ + return P(-0.5*w, 0.25*w, 0.95*w); +} + +int main() +{ + picture(P(-2*MAX,-2*MAX), P(2*MAX,2*MAX), "6 x 6in"); + + begin(); + + border(Green(0.6), "1pt"); + backing(Black()); + + camera.at(sph(4*MAX, M_PI/6, M_PI/6)); + + // positioned for viewpt in first orthant + yellow(); + grid(P(-MAX,-MAX,-MAX), P(MAX,MAX,-MAX), 4, 4); + grid(P(-MAX,-MAX,-MAX), P(MAX,-MAX,MAX), 4, 4); + grid(P(-MAX,-MAX,-MAX), P(-MAX,MAX,MAX), 4, 4); + + axis Ax(P(-MAX,-MAX,MAX), P(MAX,-MAX,MAX), 4, P(0,6), t); + axis Ay(P(MAX,-MAX,-MAX), P(MAX,MAX,-MAX), 4, P(-2,-2), bl); + axis Az(P(MAX,-MAX,-MAX), P(MAX,-MAX,MAX), 4, P(-2,-2), bl); + + Ax.frac().draw(); + Ay.frac().draw(); + Az.frac().draw(); + + clip_box(P(MAX,MAX,MAX)); + + // wire mesh surface + plain(Green()); + plot(f, R); + + // level bands + plain(Red()); + + for (int i=-5; i <=5; ++i) + { + clip_slice(P(0,0,0.2*i), P(0,0,1), 0.1); +#ifdef FLATFILL + fill(RGB(0.25+0.1*i, 0, -0.1*i)); // index-dependent coloring + surface(f, R); +#else + surface(f, R, color); // domain- or position-dependent coloring +#endif + clip_restore(); // remove temporary slicing planes, keep clip box + } + + pst_format(); + end(); +} + diff --git a/graphics/epix/samples/levelset3.xp b/graphics/epix/samples/levelset3.xp new file mode 100644 index 0000000000..aab13bec4f --- /dev/null +++ b/graphics/epix/samples/levelset3.xp @@ -0,0 +1,89 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// Style parameters +const int MESH(12); // number of coordinate grid squares +const int MAX(3); // maximum coordinate + +// camera location (in spherical coordinates); must be in first orthant +const P VIEWPT(sph(4*MAX, M_PI/6, M_PI/6)); + +const double sqrt3(sqrt(3)); + +// function to be graphed +P f(double x, double y) +{ + // return P(x, y, 0.75*y*(y-sqrt3*x)*(y+sqrt3*x)); + return P(x,y, 0.9*MAX*exp(-0.5*(x*x+y*y))*x*y); + // return P(x, y, 0.25*(x-y*y)*(x-3*y*y)); +} + +P color(double u, double v, double w) +{ + return P(-0.5*w, 0.25*w, 0.5*w); +} + +Color Bk(Green(0.7)); + +int main() +{ + // picture(P(-2*MAX,-2*MAX), P(2*MAX,2*MAX), "6 x 6in"); + picture(P(-MAX,-MAX), P(MAX,MAX), "6 x 6in"); + + begin(); + backing(Bk); + + camera.at(0,-10,4); + + border(Green(0.6), "1pt"); + + clip_box(P(MAX,MAX,MAX)); + + domain R(P(-MAX,-MAX), P(MAX, MAX), (6*MESH, 6*MESH), mesh(6*MESH, 6*MESH)); + + legend L1, L2, L3; + L1.backing(Bk); + L2.backing(Bk); + L3.backing(Bk); + + // pen(RGB(1, 0.8, 0.2), 0.1); + for (int i=-10; i <=10; ++i) + { + clip_slice(P(0,0,0.1*i), P(0,0,1), 0.1); + // fill(RGB(0.25+0.1*i, 0, -0.1*i)); + rgb(0.25+0.1*i, 0, -0.1*i); + + std::stringstream buf; + buf << "$" << 0.1*i - 0.05 + << "\\leq z \\leq " << 0.1*i + 0.05 << "$"; + + if (i <-3) + L1.fill_item(buf.str()); + + else if(i<4) + L2.fill_item(buf.str()); + + else + L3.fill_item(buf.str()); + + nofill(); + surface(f, R); + clip_restore(); + } + + camera.at(0,0,1000); + font_size("scriptsize"); + label_color(Black()); + L1.border(0); + L2.border(0); + L3.border(0); + + L1.draw(canvas().bl(), P(2,2), tr); + L2.draw(canvas().bl()+P(2,0), P(2,2), tr); + L3.draw(canvas().bl()+P(4,0), P(2,2), tr); + + pst_format(); + end(); +} + diff --git a/graphics/epix/samples/lighting.flx b/graphics/epix/samples/lighting.flx new file mode 100644 index 0000000000..80997bebeb --- /dev/null +++ b/graphics/epix/samples/lighting.flx @@ -0,0 +1,132 @@ +/* -*-flix-*- */ +// compile with flix -I. [-DAXES] lighting.flx +// in a directory containing lighting.h +#include "epix.h" +#include "lighting.h" +using namespace ePiX; + +// mesh intervals for torus +int N1(36), N2(12); + +// torus +P F(double x, double y) +{ + double R(5-2*Sin(M_PI*y/N2)); + return P(R*Cos(2*M_PI*x/N1), R*Sin(2*M_PI*x/N1), 2*Cos(M_PI*y/N2)); +} + +int main(int argc, char* argv[]) +{ + if (argc == 3) + { + char* arg; + double temp1, temp2; + temp1=strtod(argv[1], &arg); + temp2=strtod(argv[2], &arg); + + tix()=temp1/temp2; + } + picture(P(-10,-10),P(10,10), "4x4in"); + + begin(); + set_crop(); + + backing(Black()); + + domain R(P(0,N2), P(N1,2*N2), mesh(N1,N2), mesh(2*N1,2*N2)); + + // manual layering below may require adjustment if the camera is moved + camera.at(P(4,6,4)); + camera.range(16); + +#ifdef AXES + yellow(); + label(P(8,0,0), P(-2,-2), "$\\mathbf{x}$", bl); + label(P(0,8,0), P( 2,-2), "$\\mathbf{y}$", br); + label(P(0,0,8), P( 0, 4), "$\\mathbf{z}$", t); +#endif + + // draw grid only + pen(Green(), 0.15); + plot(F, R); + + // axes (with solid arrowheads) and shaded surface +#ifdef AXES + arrow(P(0,0,0), P(8,0,0)); + arrow(P(0,0,0), P(0,8,0)); + arrow(P(0,0,0), P(0,0,8)); +#endif + + rgb(0.8, 0.4, 0); + fill(); + Color chip_color(White()); // true color of torus + Color ambient(RGB(1,0.75,0)); // ambient light + + Fog fog(White(), 0.0125); + + // spot light location + P spot_at(sph(10, M_PI_4, 2*M_PI*tix())); // traverses a longitude + + // P spot_b=P(5,0,0)+cyl(10, 2*M_PI*tix(), 5); // or latitude + // P spot_b(5,-5,10); // or stays put + Spot spot(Blue(), spot_at); + + std::vector<Chip> surf_mesh; + // torus, surface reflectivity .75 + for (int i=0; i<N1; ++i) + for (int j=0; j<N2; ++j) + surf_mesh.push_back(Chip(F(i,j), F(i+1,j), F(i+1,j+1), F(i,j+1), + 0.75, chip_color)); + + sort(surf_mesh.begin(), surf_mesh.end(), chip_distance()); + +#ifdef SHOW_SPOT + // mark spot light's location + if (spot_at.x2() <= 0) + { + blue(); + box(spot.m_loc); + } +#endif + + // draw shaded surface mesh + for (unsigned int i=0; i<surf_mesh.size(); ++i) + surf_mesh.at(i).draw(fog, spot, ambient); + +#ifdef SHOW_SPOT + if (spot_at.x2() > 0) + { + blue(); + box(spot.m_loc); + } +#endif + +#ifdef AXES + // re-draw hidden portions + green(); + line(P(3,0,0), P(8,0,0)); + line(P(0,3,0), P(0,8,0)); + line(P(0,0,0), P(0,0,8)); +#endif + + fill(false); + // redraw front portion of mesh partially covered by solid surface + pen(Green(), 0.15); + plot(F, R.resize1(0, 0.25*N1)); + + // labels + base(White(), 1); + line(P(3,0,6), F(0,0.25*N2)); + line(P(6,0,4), F(0,-0.25*N2)); + + label_border(Green(0.6), "0.5pt"); + label_color(Black()); + label_mask(RGB(1,0.8,0.2)); + + font_size("footnotesize"); + masklabel(P(3,0,6), P(0,0), "Total curvature $-\\pi$", t); + masklabel(P(6,0,4), P(0,0), "Total curvature $\\pi$", t); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/lighting.h b/graphics/epix/samples/lighting.h new file mode 100644 index 0000000000..6493332a95 --- /dev/null +++ b/graphics/epix/samples/lighting.h @@ -0,0 +1,114 @@ +double clip_0_1(double t) +{ + return (t<0) ? 0 : (t>1 ? 1 : t); +} + +double trunc(double t) +{ + if (fabs(t) < 0.0001) + t=0; + + return t; +} + +namespace ePiX { + + class Spot { + public: + Spot(const Color& col, const P& loc) : m_tint(col), m_loc(loc) { } + + Color m_tint; + P m_loc; + }; + + class Fog { + public: + Fog(const Color& c, const double k) : m_tint(c), m_dens(k) { } + + Color apply_to(const Color& col, const double dist) const + { + Color me(m_tint); + return me.blend(col, exp(-dist*m_dens)); + } + + private: + Color m_tint; + double m_dens; + }; + + // cf. facet class in facet.h + class Chip { + public: + Chip(const P& p1, const P& p2, const P& p3, const P& p4, const double s, + const Color& c) + : pt1(p1), pt2(p2), pt3(p3), pt4(p4), m_shine(s), m_tint(c) + { + m_ctr = 0.25*(p1+p2+p3+p4); + P n = (p2-p1)*(p4-p1); + n *= recip(norm(n)); + m_perp=n; + } + + double how_far() const { return norm(camera.viewpt()-m_ctr); } + + void draw(const ePiX::Fog& fog, + const ePiX::Spot& spot, + const ePiX::Color& ambient) const + { + fill(appearance(camera.viewpt(), fog, spot, ambient)); + ePiX::quad(pt1, pt2, pt3, pt4); + } + + private: + P pt1, pt2, pt3, pt4; // vertices + double m_shine; // shininess + Color m_tint; // out color + + P m_ctr; // our location + P m_perp; // unit normal + + Color appearance(const P& viewer, const Fog& fog, + const Spot& spot, Color ambient) const + { + P spot_dir(spot.m_loc - m_ctr); + double spot_dist(norm(spot_dir)); + spot_dir *= recip(spot_dist); + + P view_dir(viewer - m_ctr); + double view_dist(norm(view_dir)); + view_dir *= recip(view_dist); + + // calculate relative intensities + //double I_ambt = pow((m_perp|view_dir), 2); // cos^2 of normal angle + double I_ambt(fabs(m_perp|view_dir)); // |cos| of normal angle + + // crude but fairly effective + //double I_spot = 0.5*(1+((spot_dir*m_perp)|(m_perp*view_dir))); + + // reflect spot_dir across m_perp in the plane they span, + // then take (cos(angle to viewer)^4) + P refl_dir(-spot_dir + 2*(spot_dir|m_perp)*m_perp); + double I_spot(pow((refl_dir|view_dir), 2)); + + + // light from spot that reaches our location and is reflected to viewer + Color spot_refl(I_spot*(fog.apply_to(spot.m_tint, spot_dist))); + + // not shiny -> reflect mostly ambient + Color refl(I_ambt*ambient.blend(spot_refl, m_shine)); + + // Color we reflect toward viewer + Color source(m_tint.filter(refl)); + return fog.apply_to(source, view_dist); + } + }; + + class chip_distance { + public: + bool operator() (const Chip& arg1, const Chip& arg2) + { + return arg1.how_far() > arg2.how_far(); + } + }; +} // end of namespace + diff --git a/graphics/epix/samples/line_debug.xp b/graphics/epix/samples/line_debug.xp new file mode 100644 index 0000000000..13af932c78 --- /dev/null +++ b/graphics/epix/samples/line_debug.xp @@ -0,0 +1,126 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +/* + * Line and fill style test; draws all 32 combinations of five attributes: + * + * line color: (Neutral: cols 1, 3; Red, cols 2, 4) + * line style: (Solid: cols 1, 2; dashed: cols 3, 4) + * + * base color: (Neutral: odd rows, Blue otherwise) + * base width: (1pt: rows 1-2, 5-6, 4pt otherwise) + * + * fill color: (Neutral: rows 1-4, Yellow otherwise) + */ + +// test objects +void objs() +{ + rect(P(0,0), P(1,1)); + line(P(-1,-1), P(1,-1)); +} + +// attribute-setting commands on bool flags +void line_color(bool arg) +{ + if (arg) + pen(Red(), 2); + + else + pen(Neutral(), 2); +} + +void line_style(bool arg) +{ + if (arg) + dashed(); +} + +void base_color(bool col, double wid) +{ + if (col) + base(Blue(1.2), wid); + + else + base(Neutral(), wid); +} + +void base_pen(bool col, bool wid) +{ + if (wid) + base_color(col, 4); + + else + base_color(col, 1); +} + +void fill_color(bool arg) +{ + if (arg) + fill(Yellow()); + + else + fill(Neutral()); +} + +// we'll use 0, 1 as loop indices; convert to bool +bool tf(int i) +{ + return i == 0 ? false : true; +} + +// where to position the result of a test +P loc(int i0, int i1, int i2, int i3, int i4) +{ + double horiz(0), vert(7); + if (tf(i0)) + horiz += 1; + + if (tf(i1)) + horiz += 2; + + if (tf(i2)) + vert -= 1; + + if(tf(i3)) + vert -= 2; + + if (tf(i4)) + vert -= 4; + + return P(horiz, vert); +} + +int main() +{ + picture(P(0,0), P(4,8), "6 x 9in"); + + begin(); + + // the tests proper + for (int i0=0; i0<2; ++i0) + for (int i1=0; i1<2; ++i1) + for (int i2=0; i2<2; ++i2) + for (int i3=0; i3<2; ++i3) + for (int i4=0; i4<2; ++i4) + { + screen scr(P(-1,-1), P(1,1)); + activate(scr); + + solid(); // may need to reset line style + border(Green(0.6), "0.1pt"); + + line_color(tf(i0)); + line_style(tf(i1)); + base_pen(tf(i2),tf(i3)); + fill_color(tf(i4)); + + objs(); + + scr.scale(0.9); + inset(loc(i0,i1,i2,i3,i4), loc(i0,i1,i2,i3,i4) + P(1,1)); + deactivate(scr); + } + end(); +} diff --git a/graphics/epix/samples/lissajous.xp b/graphics/epix/samples/lissajous.xp new file mode 100644 index 0000000000..c713d760bb --- /dev/null +++ b/graphics/epix/samples/lissajous.xp @@ -0,0 +1,28 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +P f(double t) +{ + return P(Sin(3*t), Sin(4*t)); +} + +int main() +{ + picture(P(-1,-1), P(1,1), "2 x 2in"); + + begin(); + revolutions(); + + bold(Red()); + plot(f, 0, 1, 200); + + arrow_inset(0.2); + arrow_width(1.5); + + plain(Blue()); + tan_field(f, 0, 1, 81); + + end(); +} + diff --git a/graphics/epix/samples/log.xp b/graphics/epix/samples/log.xp new file mode 100644 index 0000000000..4f16921cdf --- /dev/null +++ b/graphics/epix/samples/log.xp @@ -0,0 +1,217 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// October 28, 2006 +// +// This file depicts two sheets of the Riemann surface of log, together +// with the log function over the unit circle. Surface and path elements +// must be drawn together. However, path-like mesh elements must be drawn +// after surface elements that lie at the same location in the scene, +// since otherwise surface elements' edges occlude the path. +// +// A mesh_elt class stores the necessary P data as well as a flag marking +// the element as a segment or a surface patch. Elements are stored in a +// std::vector (global to the scene) and sorted by distance. To ensure that +// surface patches are printed first, their true distance is increased by a +// "fudge" amount (0.25), making the By_distance class see them as farther +// than they really are. +// +// Path elements are drawn in green; surface patches are shaded gray +// according to the angle between the incoming light (from a point source) +// and the surface normal. +// +// Surface patches are drawn as octagons to make the mesh appear smoother +// than a quadrilateral mesh. The vertices of a patch are the images of the +// corners and midpoints of a coordinate quadrilateral, "retracted" inward +// by a small "gap" EPS (possibly zero). A positive gap simulates surface +// transparency. +// +// (u,v+dv) (u+0.5*du,v+dv) (u+du,v+dv) +// +----------------------+-----------------------+ +// | *--------------------*---------------------* | +// | | | | +// | | | | +// | | | | +// + * (u+EPS,v+0.5*dv) * + (u+du,v+0.5*dv) +// | | | | +// | | | | +// | | (u+EPS,v+EPS) | | +// | *--------------------*---------------------* | +// +----------------------+-----------------------+ +// (u,v) (u+0.5*du,v) (u+du,v) + + +const P LIGHT(2, 2, 0); // location of light, for shading +const P VIEWPT(15,-10,6); + +// surface and path mesh fineness +const int N1(18); +const int N2(80); + +const int N3(120); + +const double du(4.5/N1); +const double dv(6.0/N2); + +const double dt(4.0/N3); + +// "gap size" between surface mesh elements +const double EPS(0); // (0.002); + +// visual styles +void path_color() { green(0.8); } +void label_color() { yellow(0.5); } +void dot_color() { red(); } +void path_width() { pen(1.5); } + +// class can represent either a surface element or a path element +class mesh_elt { +private: + P pt1, pt2, pt3, pt4, pt5, pt6, pt7, pt8, center; + + double fudge; // artificial increment to distance + static bool last_was_seg; + bool is_segment; + +public: + double how_far() const + { + return fudge + norm(center - camera.viewpt()); + } + + mesh_elt(P f(double u, double v), double u0, double v0) + : pt1(f(u0+EPS,v0+EPS)), pt2(f(u0+0.5*du,v0+EPS)), + pt3(f(u0+du-EPS,v0+EPS)), pt4(f(u0+du-EPS,v0+0.5*dv)), + pt5(f(u0+du-EPS,v0+dv-EPS)), pt6(f(u0+0.5*du,v0+dv-EPS)), + pt7(f(u0+EPS,v0+dv-EPS)), pt8(f(u0+EPS,v0+0.5*dv)), + center(0.25*(pt1 + (pt3 + (pt5 + pt7)))), + fudge(0.25), is_segment(false) { } + + mesh_elt(P f(double), double t0) + : pt1(f(t0)), pt2(f(t0+0.25*dt)), pt3(f(t0+0.5*dt)), + pt4(f(t0+0.75*dt)), pt5(f(t0+dt)), pt6(), pt7(), pt8(), + center(0.333*(pt1 + (pt3 + pt5))), + fudge(0), is_segment(true) { } + + void draw() const + { + if (!is_segment) { + P normal((pt2 - pt1)*(pt4 - pt1)); + normal *= 1/norm(normal); + + double dens(0.5*(1-((normal|LIGHT)/norm(LIGHT)))); + + if (mesh_elt::last_was_seg) + { + mesh_elt::last_was_seg=false; + plain(); // reset pen width + } + + black(); + gray(dens); + + std::vector<P> bd; + bd.push_back(pt1); + bd.push_back(pt2); + bd.push_back(pt3); + bd.push_back(pt4); + bd.push_back(pt5); + bd.push_back(pt6); + bd.push_back(pt7); + bd.push_back(pt8); + + path temp(bd, true, true); // closed and filled + temp.draw(); + } + else { // segment + if (!mesh_elt::last_was_seg) + { + mesh_elt::last_was_seg=true; + path_width(); + path_color(); + } + + std::vector<P> bd; + bd.push_back(pt1); + bd.push_back(pt2); + bd.push_back(pt3); + bd.push_back(pt4); + bd.push_back(pt5); + + path temp(bd, false, false); + temp.draw(); + } + + } // end of mesh_elt::draw() + +}; // end of class mesh_elt + +// initialize static data +bool mesh_elt::last_was_seg = false; + +class By_distance { +public: + bool operator() (const mesh_elt arg1, const mesh_elt arg2) + { + return (arg1.how_far()) > (arg2.how_far()); + } +}; + +// the maps to be plotted +P C_log(double u, double v) +{ + return polar(exp(u), M_PI*v) + P(0, 0, u+M_PI*v); +} + +P C_log1(double t) +{ + return C_log(0,t); +} + +int main() { + bounding_box(P(-6, -12),P(6,12)); + unitlength("1in"); + picture(P(4,8)); + + begin(); + fill(); + + degrees(); + // label_angle(90); + label(P(0, ymin()), P(0,4), + "$z=\\mathrm{Re}\\,\\log(x+iy) + \\mathrm{Im}\\,\\log(x+iy)$", t); + radians(); + // label_angle(0); + + viewpoint(VIEWPT); + camera.range(20); + + std::vector<mesh_elt> mesh_data; + + // surface elements + for (int i=0; i<N1; ++i) + for (int j=0; j<N2; ++j) + mesh_data.push_back(mesh_elt(C_log, -3+du*i, -3+dv*j)); + + // path elements + for (int i=0; i<N3; ++i) + mesh_data.push_back(mesh_elt(C_log1, -2+i*dt)); + + stable_sort(mesh_data.begin(), mesh_data.end(), By_distance()); + + for (int i=0; i<mesh_data.size(); ++i) + mesh_data.at(i).draw(); + + dot_color(); + marker(C_log(0,-2), BOX); + marker(C_log(0, 0), BOX); + marker(C_log(0, 2), BOX); + + label_color(); + label(C_log(0,-2), P(6, 0), "$-2\\pi i$", r); + label(C_log(0, 0), P(6, 0), "$0$", r); + label(C_log(0, 2), P(-6, 0), "$2\\pi i$", l); + + end(); +} diff --git a/graphics/epix/samples/lorenz.xp b/graphics/epix/samples/lorenz.xp new file mode 100644 index 0000000000..6b2afae3cf --- /dev/null +++ b/graphics/epix/samples/lorenz.xp @@ -0,0 +1,70 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// ODE parameters +const double A1(10); +const double A2(28); +const double A3(2.6666); + +// parameter box +const double MAX(30); + +// bounding box (set in screens) +const double XMAX(50); + +// flow time +const double TMAX(2000); + +P F(double x, double y, double z) +{ + return 0.01*P(A1*(y-x), x*(A2-z)-y, x*y-A3*z); +} + +domain R(P(-MAX,-MAX,0), P(MAX,MAX,2*MAX), mesh(6, 6, 6)); + +void draw_frame() +{ + dart_field(F, R.resize1(0,MAX), 0.5); + + bold(Red()); + ode_plot(F, P(10,0,0), 0, TMAX, TMAX); + + pen(Blue()); + // nearby start points, but trajectories not close + ode_plot(F, P(10.5,0,0), 0, TMAX, TMAX); + + plain(Black()); + dart_field(F, R.resize1(-MAX,0), 0.5); +} + +// initialize the camera +void init_cam(const P& arg) +{ + camera.at(arg); + camera.look_at(P(0,0,MAX)); + camera.range(500); +} + +int main() +{ + picture(P(-1,0), P(1,1), "6x3in"); + + begin(); + + screen left_eye(P(-XMAX,-XMAX), P(XMAX,XMAX)); + activate(left_eye); + init_cam(P(-100, 90, 63)); + draw_frame(); + + screen right_eye(P(-XMAX,-XMAX), P(XMAX,XMAX)); + activate(right_eye); + init_cam(P(-100, 80, 63)); + draw_frame(); + + // page layout + inset(left_eye, P(0,0), P(1,1)); + inset(right_eye, P(-1,0), P(0,1)); + + end(); +} diff --git a/graphics/epix/samples/medians.xp b/graphics/epix/samples/medians.xp new file mode 100644 index 0000000000..e1e8bf910a --- /dev/null +++ b/graphics/epix/samples/medians.xp @@ -0,0 +1,134 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const P pt1(2,-1); +const P pt2(1,2); +const P pt3(-2,0); + +void altitude_color() +{ + blue(1.4); +} + +#ifdef BISECTORS +void bisector_color() +{ + green(1.4); +} +#endif + +// project arg to line through tail, head +P drop_perp(const P& arg, const P& tail, const P& head) +{ + return arg - ((arg - tail)%(head - tail)); // % = orthogonalization +} + +#ifdef BISECTORS +P bisector(const P& arg, const P& tail, const P& head) +{ + P dir_tl(tail - arg); + dir_tl *= 1.0/norm(dir_tl); + + P dir_hd(head - arg); + dir_hd *= 1.0/norm(dir_hd); + + Segment bisect(arg, arg + 0.5*(dir_tl + dir_hd)); + + return Segment(tail, head)*bisect; +} +#endif + +void rangle(const P& arg, const P& tail, const P& head) +{ + const P dir(head - tail); + const P loc(arg - ((arg - tail)%dir)); + + right_angle(loc, dir, J(dir)); +} + +const P q1(drop_perp(pt1, pt2, pt3)); +const P q2(drop_perp(pt2, pt3, pt1)); +const P q3(drop_perp(pt3, pt1, pt2)); + +#ifdef BISECTORS +const P r1(bisector(pt1, pt2, pt3)); +const P r2(bisector(pt2, pt3, pt1)); +const P r3(bisector(pt3, pt1, pt2)); +#endif + +int main() +{ + picture(P(-3,-3), P(3,3), "4x4in"); + + begin(); + set_crop(); + + // sides + Segment side1(pt2, pt3); + Segment side2(pt3, pt1); + Segment side3(pt1, pt2); + + // medians + Segment med1(pt1, side1.midpoint()); + Segment med2(pt2, side2.midpoint()); + Segment med3(pt3, side3.midpoint()); + + // altitudes + Segment alt1(pt1, q1); + Segment alt2(pt2, q2); + Segment alt3(pt3, q3); + +#ifdef BISECTORS + // bisectors + Segment bis1(pt1, r1); + Segment bis2(pt2, r2); + Segment bis3(pt3, r3); +#endif + + med1.draw(); + med2.draw(); + med3.draw(); + + bold(); + side1.draw(); + side2.draw(); + side3.draw(); + plain(); + + altitude_color(); + alt1.draw(); + alt2.draw(); + alt3.draw(); + + rangle(q1, pt2, pt3); + rangle(q2, pt3, pt1); + rangle(q3, pt1, pt2); + + circle(q1, q2, q3); + + label(q1, P(-2,4), "$a_1$", t); + label(q2, P(-2,-4), "$a_2$", b); + label(q3, P(4,0), "$a_3$", r); + +#ifdef BISECTORS + bisector_color(); + bis1.draw(); + bis2.draw(); + bis3.draw(); + + // circle(r1, r2, r3); +#endif + + black(); + font_size("footnotesize"); + label(pt1, P(2,-2), "$p_1$", br); + label(pt2, P(2,2), "$p_2$", tr); + label(pt3, P(-4,-2), "$p_3$", l); + + label(side1*med1, P(-4,2), "$m_1$", tl); + label(side2*med2, P(-2,-4), "$m_2$", b); + label(side3*med3, P(4,0), "$m_3$", r); + + end(); +} diff --git a/graphics/epix/samples/minkowski.xp b/graphics/epix/samples/minkowski.xp new file mode 100644 index 0000000000..c9e841730b --- /dev/null +++ b/graphics/epix/samples/minkowski.xp @@ -0,0 +1,103 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const double MAX(3); + +// hyperboloid of one sheet/spacelike cone +P Fp(double x, double y, double z) +{ + return P(z*cosh(x)*Cos(y), z*cosh(x)*Sin(y), z*sinh(x)); +} + +// hyperboloid of two sheets/timelike cone +P Fm(double x, double y, double z) +{ + return P(z*sinh(x)*Cos(y), z*sinh(x)*Sin(y), z*cosh(x)); +} + +// light cone +P Fz(double x, double y) +{ + return fabs(sinh(x))*P(Cos(y), Sin(y), sgn(x)); +} + +// hyperbolic lines +P hl1(double t) +{ + return cosh(t)*P(-sqrt(1.25),0,1.5) + sinh(t)*E_2; +} + +P hl2(double t) +{ + return cosh(t)*P(-1,0.5,1.5) + (sqrt(0.4)*sinh(t))*P(0.5, 1, 0); +} + +int main() +{ + bounding_box(P(-MAX,-MAX),P(MAX,MAX)); + unitlength("1in"); + picture(6,6); + + begin(); + camera.at(10,-3,4); + // camera.range(40); + + revolutions(); + + domain R(P(-1.5,0.25,-1), P(1.5,0.75,1), mesh(18, 12, 4), mesh(36, 48, 12)); + + fill(White()); + + // assemble surfaces as a single object + scenery hyp(Fp, R.slice3(1)); + hyp.add(Fm, R.resize1(0,1.5).slice3(1)); + hyp.add(Fm, R.resize1(-1.5,0).slice3(-1)); + hyp.add(Fz, R.slice3(1)); + + hyp.draw(); + nofill(); + + // Draw cuts of intersection with (y,z)-plane. + // Simulated 3-D/tube pen: light color drawn over darker shade + base(Red(0.6), "3pt"); + bold(Red()); + + plot(Fp, R.slice2(0.25).slice3(1)); + plot(Fp, R.slice2(0.25).slice3(-1)); + + plot(Fm, R.slice2(0.25).slice3(1)); + plot(Fm, R.slice2(0.25).slice3(-1)); + + plot(Fz, R.slice2(0.25).slice3(1)); + plot(Fz, R.slice2(0.75).slice3(-1)); + + // to clip lines + clip_box(P(-10,-10,-cosh(1.5)), P(10,10,cosh(1.5))); + + base(Green(0.6), "3pt"); + bold(Green()); + + plot(hl1, -1.5, 1.5, 120); + plot(hl2, -1.5, 1.5, 120); + + // Labels with "overlay" arrows + font_size("scriptsize"); + + black(); + camera.at(P(0,0,10000)); + label(P(1.5,0), P(4,16), "Future timelike unit vectors", r); + label(P(1.5,0), P(4,0), "Unit spacelike vectors", r); + label(P(1.5,0), P(4,-16), "Lightlike vectors", r); + label(P(1.5,0), P(4,-32), "Past timelike unit vectors", r); + + base(White(), "2pt"); + bold(Black()); + arrow(P(1.5,0), P(1,0), 0.5); + arrow(P(1.5, 0.25), P(1,1.35), 0.5); + arrow(P(1.5,-0.25), P(1,-0.75), 0.5); + arrow(P(1.5,-0.5), P(1,-1.05), 0.5); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/mirrorball.flx b/graphics/epix/samples/mirrorball.flx new file mode 100644 index 0000000000..858ee4e904 --- /dev/null +++ b/graphics/epix/samples/mirrorball.flx @@ -0,0 +1,93 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const double r_0(1); //0.75; +const double golden(0.5*(1+sqrt(5))); + +Sphere S0(P(0,0,0), sqrt(3)); + +Sphere S1(P( 1, golden, 0), r_0); +Sphere S2(P(-1, golden, 0), r_0); +Sphere S3(P( 1,-golden, 0), r_0); +Sphere S4(P(-1,-golden, 0), r_0); + +Sphere S5(P( 0, 1, golden), r_0); +Sphere S6(P( 0,-1, golden), r_0); +Sphere S7(P( 0, 1,-golden), r_0); +Sphere S8(P( 0,-1,-golden), r_0); + +Sphere S9(P( golden, 0, 1), r_0); +Sphere Sa(P( golden, 0,-1), r_0); +Sphere Sb(P(-golden, 0, 1), r_0); +Sphere Sc(P(-golden, 0,-1), r_0); + +Circle C1(S0*S1); +Circle C2(S0*S2); +Circle C3(S0*S3); +Circle C4(S0*S4); +Circle C5(S0*S5); +Circle C6(S0*S6); +Circle C7(S0*S7); +Circle C8(S0*S8); +Circle C9(S0*S9); +Circle Ca(S0*Sa); +Circle Cb(S0*Sb); +Circle Cc(S0*Sc); + +// bold circle if facing camera, otherwise plain +void sphere_draw(const Circle& C) +{ + if ((C.center()|camera.viewpt()) >= 0) + bold(); + else plain(); + + C.draw(); +} + +void icosa() +{ + // S0.draw(); + sphere_draw(C1); + sphere_draw(C2); + sphere_draw(C3); + sphere_draw(C4); + sphere_draw(C5); + sphere_draw(C6); + sphere_draw(C7); + sphere_draw(C8); + sphere_draw(C9); + sphere_draw(Ca); + sphere_draw(Cb); + sphere_draw(Cc); +} + +int main(int argc, char* argv[]) +{ + if (argc == 3) + { + char* arg; + double temp1, temp2; + temp1=strtod(argv[1], &arg); + temp2=strtod(argv[2], &arg); + + tix()=temp1/temp2; + } + + picture(P(-2,-2),P(2,2), "6x6in"); + + begin(); + set_crop(); + revolutions(); + + // draw frames + camera.at(sph(12, 0.5*tix(), 0.05)); + red(-1.4); // nearly cyan + icosa(); + + camera.at(sph(12, 0.01+0.5*tix(), 0.05)); + red(1.4); + icosa(); + + end(); +} diff --git a/graphics/epix/samples/newton.xp b/graphics/epix/samples/newton.xp new file mode 100644 index 0000000000..d9af0b087f --- /dev/null +++ b/graphics/epix/samples/newton.xp @@ -0,0 +1,43 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +double f(double t) +{ + return 1 + t*(-3 + t*t); +} + +double df(double t) +{ + return Deriv(f)(t).x2(); +} + +int main() +{ + picture(P(1.5,0), P(2,3), "2.5 x 2.5in"); + + begin(); + h_axis(2); + + double x0(2), x1(x0-f(x0)/df(x0)); + label(P(x0,0), P(0,-4), "$x_i$", b); + + for (int i=0; i < 3; ++i) + { + dashed(); + line(P(x0,0), P(x0,f(x0))); + solid(); + line(P(x0,f(x0)), P(x0-f(x0)/df(x0),0)); + + x0 -= f(x0)/df(x0); // Newton's method + } + + bold(); + plot(f, xmin(), xmax()+0.05, 60); + + label(P(1.75, f(1.75)), P(-2,2), "$y=f(x)$", tl); + label(P(x1,0), P(0,-4), "$x_{i+1}$", b); + label(P(1.75, df(2)*(1.75-x1)), P(0,-4), "Slope $= f'(x_i)$", br); + + end(); +} diff --git a/graphics/epix/samples/objects.xp b/graphics/epix/samples/objects.xp new file mode 100644 index 0000000000..ddf38cbee1 --- /dev/null +++ b/graphics/epix/samples/objects.xp @@ -0,0 +1,32 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +int main() +{ + picture(P(0,0), P(5,2), "3.75 x 1.5in"); + + begin(); + + // roof + triangle(P(0.9, 1), P(3.1, 1), P(2, 1.5)); // vertices + + // sun + circle(P(4,1.5), 0.25); // center and radius + + // house + rect(P(1,0), P(3,1)); // opposite corners + // grid(P(1,0), P(3,1), 1, 10); // corners, numbers of subdivisions + + // door + fill(Black(0.1)); + rect(P(2.3,0), P(2.7,0.8)); // corners + + fill(White()); + // window + bold(); + grid(P(1.4,0.2), P(2, 0.6), 2, 2); + + line(P(xmin(),0), P(xmax(),0)); + end(); +} diff --git a/graphics/epix/samples/oscillator.xp b/graphics/epix/samples/oscillator.xp new file mode 100644 index 0000000000..c174613cb0 --- /dev/null +++ b/graphics/epix/samples/oscillator.xp @@ -0,0 +1,89 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +double f(double t, double a) { return 2*exp(-0.5*t)*Sin(a*t); } + +// Completely fabricated data +// "Predicted" +double f1(double t) +{ + return f(t,2); +} + +// "Observed" +double f2(double t) +{ + return f1(t)+0.1*Cos(3*t); +} + +//"error" +double err(double t) +{ + return 0.125*(1+fabs(f1(t))); +} + +// Number of error bars +const int samples(8); + +// Half-size of bounding box +const int N(2); + +int main() +{ + picture(P(0,-N),P(2*N,N), "2.5 x 2.5in"); + + begin(); + + // displacement for miscellaneous labels/objects + const double delta(0.0625*xsize()); + + // graph paper + pen(Black(0.25)); + grid(5*N*(int)xsize(),5*N*ysize()); + + pen(Black()); + grid(N*(int)xsize(), N*(int)ysize()); + + // axes, names, and labels + bold(); + dart(P(xmin(),0), P(xmax()+delta,0)); + dart(P(0,ymin()), P(0,ymax()+delta)); + + font_size("scriptsize"); + h_axis_masklabels(P(xmin()+1,0), P(xmax(),0), xsize()-1, P(0,2), c); + v_axis_labels(P(0,ymin()), P(0,ymax()), ysize(), P(-2, 0), l); + + font_size("footnotesize"); + label(P(xmax()+delta,0), P(2,0), "Time (sec)", r); + label_angle(M_PI_2); + label(P(0,0), P(-8,0), "Displacement (cm)",l); + label_angle(0); + + legend L; + L.item_border(0); + + // "Predicted" curve + pen(RGB(0.2, 0.7, 0.8)); + plot(f1, xmin(), xmax(), 120); + L.path_item("Predicted"); + + // "error bars" + red(); + L.mark_item(CIRC, "Measured"); + + for (int i=1; i < samples; ++i) + { + double t(xmin() + i*xsize()/samples); + v_error_bar(P(t, f2(t)), err(t), CIRC, 4); // 4 pt wide + } + + black(); + L.draw(canvas().br(), P(-2,2), tl); + + font_face("sc"); + label(P(0.5*(xmin()+xmax()), ymax()), P(0,2), + "A damped harmonic oscillator", t); + + end(); +} diff --git a/graphics/epix/samples/parabola.xp b/graphics/epix/samples/parabola.xp new file mode 100644 index 0000000000..474a89c132 --- /dev/null +++ b/graphics/epix/samples/parabola.xp @@ -0,0 +1,32 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// the function to be plotted +double f(double x) +{ + return x*x; +} + +int main() +{ + picture(P(-2,0), P(2,4), "2.5x2.5in"); + + begin(); + + pen(Black(0.3)); + grid(8,8); // and coarse + + pen(Black()); + axis Ax(P(xmin(),0), P(xmax(),0), 4, P(0,-4), b); + axis Ay(P(0,ymin()), P(0,ymax()), 4, P(4, 0), r); + + font_size("scriptsize"); + Ax.draw(); + Ay.unmark(0).draw(); + + bold(Red()); + plot(f, xmin(), xmax(), 40); + + end(); +} diff --git a/graphics/epix/samples/pascal.xp b/graphics/epix/samples/pascal.xp new file mode 100644 index 0000000000..7c597077a0 --- /dev/null +++ b/graphics/epix/samples/pascal.xp @@ -0,0 +1,53 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +int main() +{ + picture(P(-2,-2),P(2,2), "3 x 3in"); + + begin(); + set_crop(); + + P V(2,-0.25), W(3,1); + P P1(-1.5,-1), P2(P1 + V), P3(P1 + 1.5*V); // points + P Q1(-1,1), Q2(Q1 + 0.5*W), Q3(Q1 + W); + + Segment L12(P1, Q2), L13(P1, Q3); + Segment L21(P2, Q1), L23(P2, Q3); + Segment L31(P3, Q1), L32(P3, Q2); + + // points of intersection + P R1(L12*L21), R2(L13*L31), R3(L32*L23); + + dot(P1, P(0,-2), "$P_1$", b); + dot(P2, P(0,-2), "$P_2$", b); + dot(P3, P(0,-2), "$P_3$", b); + + dot(Q1, P(0,2), "$Q_1$", t); + dot(Q2, P(0,2), "$Q_2$", t); + dot(Q3, P(0,2), "$Q_3$", t); + + red(); + L12.draw(); + L21.draw(); + L13.draw(); + + L31.draw(); + L32.draw(); + L23.draw(); + + green(); + Line(P1,P3); + Line(Q1,Q3); + + blue(); + dot(R1, P(4,2), "$p_1$", r); + dot(R2, P(4,2), "$p_2$", r); + dot(R3, P(4,2), "$p_3$", r); + + dashed(); + Line(R1,R3); + + end(); +} diff --git a/graphics/epix/samples/pendulum.flx b/graphics/epix/samples/pendulum.flx new file mode 100644 index 0000000000..ac0751d435 --- /dev/null +++ b/graphics/epix/samples/pendulum.flx @@ -0,0 +1,62 @@ +/* -*-flix-*- */ +#include "epix.h" +using namespace ePiX; + +P F(double u, double v) +{ + return P(v, -Sin(u)); +} + +double theta0(-5*M_PI/6); +double EPS(0.01); // to avoid singularity of f at theta0 + +P posn0(theta0, 0); + +P pivot(0,5.5); +double ell(3); + +double K(-Cos(theta0)); + +double f(double t) +{ + return 1.0/sqrt(2*(K+Cos(t))); +} + +int main(int argc, char* argv[]) +{ + if (argc == 3) + { + char* arg; + double temp1, temp2; + temp1=strtod(argv[1], &arg); + temp2=strtod(argv[2], &arg); + + tix()=temp1/temp2; + } + picture(P(-6.5,-2.5), P(6.5, 8.5), "6.5 x 5.5in"); + + begin(); + + // calculate period, avoiding singularity at theta0 + double period(4*(sqrt(2*EPS/(-Sin(theta0)))+Integral(f).eval(-theta0-EPS))); + + border(Black(0.1), "1pt"); + + P posn(flow(F, posn0, period*tix(), 120*tix())); // phase position + double x_t(-Sin(posn.x1())); + double y_t( Cos(posn.x1())); + + slope_field(F, P(-2*M_PI,-2), P(2*M_PI,2), 48, 12); + + bold(); + line(pivot, pivot-ell*P(x_t, y_t)); + + red(); + ode_plot(F, posn0, period, 120); + + blue(); + box(posn); + box(pivot-ell*P(x_t, y_t)); + + end(); +} diff --git a/graphics/epix/samples/planes.xp b/graphics/epix/samples/planes.xp new file mode 100644 index 0000000000..385a32194e --- /dev/null +++ b/graphics/epix/samples/planes.xp @@ -0,0 +1,29 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const int N(20); + +int main() +{ + picture(P(-2,-2), P(2,2), "6x6in"); + + begin(); + + border(); + fill(); + + camera.at(P(10,-6,4)); + clip_box(P(-1,-1,-1), P(1,1,1)); + + Plane C(P(-1,-1,-1), P(1,1,1)); + for (int i=1; i<N; ++i) + { + rgb(i*1.0/N, 0.2, 1-i*1.0/N); + C.shift((2.0/N)*P(1,1,1)); + C.draw(); + } + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/plotting.xp b/graphics/epix/samples/plotting.xp new file mode 100644 index 0000000000..ad310f7b02 --- /dev/null +++ b/graphics/epix/samples/plotting.xp @@ -0,0 +1,26 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +double f(double x) +{ + return 0.75*Sin(x) - 0.25*Sin(2*x); +} + +int main() +{ + picture(P(-2,-1),P(2,1), "5x1in"); + + begin(); + + h_axis(16); + v_axis(4); + + h_axis_labels(4, P(0,-4), b); // shift labels down 4pt, align below + + revolutions(); // set angle units + red(); + plot(f, xmin(), xmax(), 120); // use 120 intervals + + end(); +} diff --git a/graphics/epix/samples/plotting2.xp b/graphics/epix/samples/plotting2.xp new file mode 100644 index 0000000000..41891142f5 --- /dev/null +++ b/graphics/epix/samples/plotting2.xp @@ -0,0 +1,29 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +P f(double r, double th) +{ + return P(r*Cos(th), r*Sin(th), pow(r, 3)*Cos(3*th)); +} + +int main() +{ + picture(P(-1,-1),P(1,1), "2x1in"); + + begin(); + + domain R(P(0,0), P(1, 2*M_PI), mesh(8,40), mesh(16,120)); + + camera.at(3,1,2); // set the viewpoint + + arrow(P(0,0,0), P(1.25,0,0)); + arrow(P(0,0,0), P(0,1.25,0)); + + plain(Blue(1.2)); + fill(Yellow()); // shade + surface(f, R); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/plotting3.xp b/graphics/epix/samples/plotting3.xp new file mode 100644 index 0000000000..bd095e722c --- /dev/null +++ b/graphics/epix/samples/plotting3.xp @@ -0,0 +1,43 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +P sin_n(double x, double n) // Taylor polynomial of sin x +{ + const int N((int) floor(n)); // convert y to an index bound + const double sqx(-pow(x, 2)); // store -x^2 for efficiency + double val(x), summand(x); // places to store results of evaluation + + // step through odd numbers from 1 to 2N+1 + for (int i=1; i <= 2*N+1; i += 2) + { + summand *= (sqx/((i+1)*(i+2))); // (-1)^i x^{2i+1}/(2i+1)! + val += summand; + } + + return P(x, val); +} + +int main() +{ + picture(P(0,-1), P(6*M_PI, 1), "5x1in"); + + begin(); + + set_crop(); + h_axis(4); + v_axis(1); + + bold(); + green(); + plot(Sin, 0, xmax(), 120); + + domain R(P(0,1), P(6*M_PI, 41), mesh(60, 40), mesh(120, 40)); + for (int i=0; i<4; ++i) + { + pen(RGB(0.25*i, 0, 1-0.25*i)); + plot(sin_n, R.slice2(5*i+1)); // plot with 2nd var = 5i+1 + } + + end(); +} diff --git a/graphics/epix/samples/polar.xp b/graphics/epix/samples/polar.xp new file mode 100644 index 0000000000..d2c1934552 --- /dev/null +++ b/graphics/epix/samples/polar.xp @@ -0,0 +1,29 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +double f(double t) +{ + return 2*Cos(3*t); +} + +int main() +{ + picture(P(-2,-2), P(2,2), "2x2in"); + + begin(); + degrees(); + + black(0.3); + polar_grid(2, 4, 24); // radius, rings, sectors + + black(); + bottom_axis(4, P(0,-4)).subdivide(2).draw(); + left_axis(4, P(-4,0)).subdivide(2).draw(); + + bold(); + polarplot(f, 0, 180, 120); // plot over [0, 180] using 120 intervals + + end(); +} + diff --git a/graphics/epix/samples/pole.xp b/graphics/epix/samples/pole.xp new file mode 100644 index 0000000000..435c258a68 --- /dev/null +++ b/graphics/epix/samples/pole.xp @@ -0,0 +1,60 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const int M(8); +double MAX(1.5), Bd(2); + +P F(double x, double y) // fake pole +{ + return P(x, y, x/(0.01+x*x+y*y)); +} + +P pt1(-MAX,-MAX), pt2(MAX, MAX); +domain R(pt1, pt2, mesh(2*M,2*M), mesh(6*M,6*M)); + +int main() +{ + picture(P(-Bd,-Bd), P(Bd,Bd), "2.5x2.5in"); + + begin(); + + label(P(xmax(), 2.5), P(-2,-2), + "$z=\\mathrm{Re}\\,\\displaystyle\\frac{1}{x+iy}$", bl); + + camera.at(P(6,8,5)); + + clip_box(P(-Bd,-Bd,-Bd), P(Bd,Bd,0)); + + plain(Magenta()); + fill(White()); + surface(F, R); // bottom half + + grid(pt1, pt2, M, M); // axes + + pen(White(0.75), "0.15pt"); + plot(F,R); // simulate transparency + + clip_box(P(-Bd,-Bd,-Bd), P(Bd,Bd,2*Bd)); + plain(Magenta()); + + // axes and labels + arrow(P(-Bd,0,0), P(Bd,0,0)); + label(P(Bd,0), P(-4,-2), "$x$", l); + + arrow(P(0,-Bd,0), P(0,Bd,0)); + label(P(0,Bd), P( 2,-2), "$y$", br); + + arrow(P(0, 0, 0), P(0,0,2.5)); + label(P(0,0,2.5), P(0,4), "$z$", t); + + clip_box(P(-Bd,-Bd,0),P(Bd,Bd,Bd)); + + surface(F,R); // top half + + bbold(Red()); + plot(F, R.resize1(0.25,MAX).slice2(0)); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/polyhedra.xp b/graphics/epix/samples/polyhedra.xp new file mode 100644 index 0000000000..c2a788986e --- /dev/null +++ b/graphics/epix/samples/polyhedra.xp @@ -0,0 +1,129 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// compile with, e.g., elaps -DALL polyhedra.xp + +const double MAX(1.25); + +#define A5 + +// draw everyone +#ifdef ALL +#define A4 +#define A5 +#endif /* ALL */ + +// draw three polyhedra with A4 symmetry +#ifdef A4 +#define COLOR +#define TETRA +#define CUBE +#define OCTA +#endif /* A4 */ + +// draw two polyhedra with A5 symmetry +#ifdef A5 +#ifndef COLOR +#define COLOR +#endif /* ndef COLOR */ +#define DODECA +#define ICOSA +#endif /* A5 */ + +int main() +{ + picture(P(-MAX,-MAX),P(MAX,MAX), "6 x 6in"); + + begin(); + const double gam(0.5*(1+sqrt(5))); + + grid(); + camera.at(P(8,3,2)); + camera.range(20); + + Sphere S; + frame f; + frame f2(E_2, E_1, E_3); + +#ifdef TETRA +#ifdef COLOR + rgb(1,0.7,0.7); +#endif /* COLOR */ + back_tetra(S, f); + back_tetra(S, f2); +#endif + +#ifdef CUBE +#ifdef COLOR + rgb(0.7,0.7,1); +#endif /* COLOR */ + back_cube(S, f); +#endif + +#ifdef OCTA +#ifdef COLOR + rgb(0.7,1,0.7); +#endif /* COLOR */ + back_octa(S, f); +#endif + +#ifdef DODECA +#ifdef COLOR + rgb(0.7,1,1); +#endif /* COLOR */ + back_dodeca(S, f); +#endif + +#ifdef ICOSA +#ifdef COLOR + rgb(1,1,0.7); +#endif /* COLOR */ + back_icosa(S, f); +#endif + + bold(); + +#ifdef TETRA +#ifdef COLOR + red(); +#endif /* COLOR */ + front_tetra(S, f); + front_tetra(S, f2); +#endif + +#ifdef CUBE +#ifdef COLOR + blue(); +#endif /* COLOR */ + front_cube(S, f); +#endif + +#ifdef OCTA +#ifdef COLOR + green(0.6); +#endif /* COLOR */ + front_octa(S, f); +#endif + +#ifdef DODECA +#ifdef COLOR + rgb(0, 0.7, 0.7); +#endif /* COLOR */ + front_dodeca(S, f); +#endif + +#ifdef ICOSA +#ifdef COLOR + rgb(1, 0.9, 0); +#endif /* COLOR */ + front_icosa(S, f); +#endif + +#ifdef COLOR + green(0.8); +#endif + S.draw(); + + end(); +} diff --git a/graphics/epix/samples/riemann.flx b/graphics/epix/samples/riemann.flx new file mode 100644 index 0000000000..f7e4b47161 --- /dev/null +++ b/graphics/epix/samples/riemann.flx @@ -0,0 +1,68 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +P F(double t, double r, double theta) +{ + return P(r*r*Cos(2*theta), + r*r*Cos(t)*Sin(2*theta) + r*Sin(t)*Sin(theta), + r*Cos(theta)); +} + +domain R(P(0,0,0), P(1, 1.5, 1), mesh(24, 8, 32), mesh(24, 40, 80)); + +int main(int argc, char* argv[]) +{ + if (argc == 3) + { + char* arg; + double temp1, temp2; + temp1=strtod(argv[1], &arg); + temp2=strtod(argv[2], &arg); + + tix()=temp1/temp2; + } + + domain R1(R.slice1(tix())); + + picture(P(-4,-4),P(4,4), "5x5in"); + + begin(); + revolutions(); + + grid(1,1); + + const P ctr(3.25,-3.25); // "clock" center + bold(); + circle(ctr, 0.5); // clock face + + line(ctr, ctr+polar(0.4, tix())); // hands + label(ctr+polar(0.6, tix()), "$y$"); + + line(ctr, ctr+polar(0.4, tix()+0.25)); + label(ctr+polar(0.6, tix()+0.25), "$w$"); + + viewpoint(4,5,3); + camera.range(20); + + line(P(0,0,0), P(3,0,0)); + line(P(0,0,0), P(0,3,0)); + line(P(0,0,0), P(0,0,2)); + + plain(Red()); + plot(F, R1.resize3(0, 0.5)); + + blue(); + plot(F, R1.resize3(0.5, 1)); + + bold(Magenta()); + plot(F, R.slice3(0)); + plot(F, R.slice3(0.5)); + + black(); + masklabel(P(3,0,0), "$x$"); + masklabel(P(0,3,0), "$y$"); + masklabel(P(0,0,2), P(-4,0), "$z=\\textrm{Re}\\,\\sqrt{x+iy}$", tr); + + end(); +} diff --git a/graphics/epix/samples/saddle.xp b/graphics/epix/samples/saddle.xp new file mode 100644 index 0000000000..b486cc4c9e --- /dev/null +++ b/graphics/epix/samples/saddle.xp @@ -0,0 +1,70 @@ +/* -*-ePiX-*- */ +// fake 3D by layering +#include "epix.h" +using namespace ePiX; + +// function to plot +P F(double u, double v) +{ + return P(u, v, 0.25*(u+v)*(u-v)); +} + +P TF(double u, double v) +{ + return P(u, v); +} + +int main() +{ + picture(P(-3,-2),P(3,2), "6x4in"); + + begin(); + backing(Black()); + + label_color(White()); + label(P(0, ymax()), P(0,-4), + "\\textbf{A quadratic saddle cut by a tangent plane}", b); + + camera.at(P(6,12,8)); + camera.look_at(P(0,0,-0.25)); + + domain R(P(-2,-2), P(2,2), mesh(24,24), mesh(48,48)); + + // clip to lower half space + clip_face(P(0,0,0), -E_3); // 2nd arg is inward normal vector + + // draw shaded saddle + fill(); + surface(F, R); + + // and re-draw the wiremesh in color + bold(); + green(); // change label color as well + plot(F, R); + label(F(0,2), P(0,-4), "$\\mathbf{z<0}$", b); + + // (x,y)-plane + red(); + plot(TF, R); + label(P(2,0,0), P(-4,-2), "$\\mathbf{z=0}$", bl); + + clip_restore(); // remove old restriction + clip_face(P(0,0,0), E_3); // and set new one + + fill(Blue()); // set pen and fill colors + surface(F, R); + + // fake transparency: re-draw (x,y)-plane lightly + pen(Red(), 0.2); + plot(TF, R); + + // and plot top half of wiremesh in color + bold(Blue()); + plot(F, R); + + rgb(0.5,0.5,1); + label(F(-2,0), P(4,4), "$\\mathbf{z>0}$", tr); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/semicirc.xp b/graphics/epix/samples/semicirc.xp new file mode 100644 index 0000000000..8cac63ae9d --- /dev/null +++ b/graphics/epix/samples/semicirc.xp @@ -0,0 +1,28 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; +double f(double x) +{ + return sqrt(1-x*x); +} + +double width(0.6), height(f(width)), posn(0.5), y_posn(f(posn)); + +int main() +{ + picture(P(-1, 0), P(1, 1), "2.5 x 1.25in"); + + begin(); + + h_axis(4); + v_axis(2); + h_axis_labels(xsize(), P(0, -4), b); + + arc(P(0,0), 1, 0, M_PI); + bold(); + rect(P(-width,0), P(width, height)); + + label(P(posn, y_posn), P(2,4), "$y=\\sqrt{1-x^2}$", tr); + + end(); +} diff --git a/graphics/epix/samples/shadeplot.xp b/graphics/epix/samples/shadeplot.xp new file mode 100644 index 0000000000..7beb97e87f --- /dev/null +++ b/graphics/epix/samples/shadeplot.xp @@ -0,0 +1,61 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; +double k(4); // change width of hump +double dx(0.05); // width of thin shaded region +double x(1/sqrt(k)); // position of thin shaded region + +const double dy(0.5); + +double f(double t) +{ + return sqrt(fabs(k)/(2*M_PI))*exp(-k*t*t); +} + +P pt1(x, f(x)+2*dy); +P pt2(x+dx,f(x)+dy); +P pt3(x+3*dx,f(x)); + +Color shade1(Black(0.1)); +Color shade2(Black(0.4)); +Color shade3(Black(0.6)); + +int main() +{ + picture(P(0,0), P(1,1), "150x150pt"); + + begin(); + legend L; + L.backing(Neutral()); + + fill(shade1); + shadeplot(f, xmin(), x, 90); + L.fill_item("$=\\displaystyle\\int_a^x f(t)\\,dt$"); + + fill(shade2); + rect(P(x,0), P(x+dx, f(x))); + L.fill_item("= $f(x)\\,dx\\vphantom{\\Bigg|}$"); + + fill(shade3); + shadeplot(f, x, x+dx, 10); + L.fill_item("= $F(x+dx)-F(x)$"); + + bold(); + plot(f, xmin(), xmax(), 120); + + plain(); + h_axis(4); + v_axis(4); + + font_size("scriptsize"); + L.draw(canvas().tr(), P(-2,-2), bl); + + font_size("footnotesize"); + label(P(xmin(),0), P(0,-5), "$a$", b); + label(P(x,0), P(0,-5), "$x$", b); + label(P(x+dx,0), P(0,-2), "$x+dx$", br); + + pst_format(); + + end(); +} diff --git a/graphics/epix/samples/slopefield.xp b/graphics/epix/samples/slopefield.xp new file mode 100644 index 0000000000..5ecfd597c1 --- /dev/null +++ b/graphics/epix/samples/slopefield.xp @@ -0,0 +1,29 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +P F(double s, double t) +{ + return P(0.1*s, 0.025*t) + (1/(0.01+s*s+t*t))*P(-t, s); +} + +int main() +{ + picture(P(-4, -3), P(2,2), "3x2.5in"); + + begin(); + + blue(1.8); + dart_field(F, P(xmin(), ymin()), P(xmax(), ymax()), 4*xsize(), 4*ysize()); + set_crop(); + + bold(); + for (int i=0; i<7; ++i) + { + rgb(0.05*(7-i), 1 - 0.1*i, 0.15*i); + ode_plot(F, P(-0.9-0.025*i,0), 20, 200); + } + + end(); +} + diff --git a/graphics/epix/samples/sphere.xp b/graphics/epix/samples/sphere.xp new file mode 100644 index 0000000000..dfff26e1e4 --- /dev/null +++ b/graphics/epix/samples/sphere.xp @@ -0,0 +1,46 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const double k(2*M_PI/(360*sqrt(3))); // assume "degrees" mode + +double exp_cos(double t) { return exp(k*t)*Cos(t); } +double exp_sin(double t) { return exp(k*t)*Sin(t); } +double minus_exp_cos(double t) { return -exp_cos(t); } +double minus_exp_sin(double t) { return -exp_sin(t); } + +int main() +{ + picture(P(-1,-1), P(1,1), "2.5 x 2.5in"); + + begin(); + degrees(); // set angle units + camera.at(P(1, 2.5, 3)); + + sphere(); // draw unit sphere's horizon + + pen(Blue(1.6)); // hidden portions of loxodromes + backplot_N(exp_cos, exp_sin, -540, 540, 180); + backplot_N(minus_exp_cos, minus_exp_sin, -540, 540, 180); + + pen(Red(1.6)); + backplot_N(exp_sin, minus_exp_cos, -540, 540, 180); + backplot_N(minus_exp_sin, exp_cos, -540, 540, 180); + + pen(Black(0.3)); // coordinate grid + + for (int i=0; i<=12; ++i) { + latitude(90-15*i, 0, 360); + longitude(30*i, 0, 360); + } + + bold(Blue()); // visible portions of loxodromes + frontplot_N(exp_cos, exp_sin, -540, 540, 360); + frontplot_N(minus_exp_cos, minus_exp_sin, -540, 540, 360); + + pen(Red()); + frontplot_N(exp_sin, minus_exp_cos, -540, 540, 360); + frontplot_N(minus_exp_sin, exp_cos, -540, 540, 360); + + end(); +} diff --git a/graphics/epix/samples/spherical.xp b/graphics/epix/samples/spherical.xp new file mode 100644 index 0000000000..c40b897e8f --- /dev/null +++ b/graphics/epix/samples/spherical.xp @@ -0,0 +1,76 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const double MAX(3); + +int main() +{ + picture(P(-MAX,-MAX),P(MAX,MAX), "6x6in"); + + begin(); + camera.at(30,5,20); + +#ifdef GRAY + camera.filter(Gray_Neutral()); +#endif + revolutions(); + + domain R(P(0,0,-0.25), P(3,1,0.25), mesh(12, 48, 24), mesh(12, 96, 120)); + + std::list<domain> cuts; + + double Phi(7.0/48), Theta(7.0/48); + + cuts.push_back(R.slice1(2)); + cuts.push_back(R.slice2(0)); + cuts.push_back(R.slice2(Theta)); + cuts.push_back(R.slice3(0)); + cuts.push_back(R.slice3(Phi)); + + plain(Black(0.5)); + fill(Red(1.9)); + scenery coords(sph, R.slice1(2)); // rho = 2 + + fill(Yellow(0.35)); + coords.add(sph, R.slice2(0)).add(sph, R.slice2(Theta)); // theta = 0, Theta + + fill(Blue(1.9)); + coords.add(sph, R.slice3(0)).add(sph, R.slice3(Phi)); // phi = 0, Phi + + coords.draw(); + // surface(sph, cuts); + fill(false); + + pen(Black()); + base(White(), "1.2pt"); + arrow_fill(1); + arrow(P(3,0,0), P(3.5,0,0)); + label(P(3.5,0,0), P(-2,-2), "$x$", bl); + + arrow(P(0,3,0), P(0,3.5,0)); + label(P(0,3.5,0), P(2,-2), "$y$", br); + + arrow(P(0,0,3), P(0,0,3.5)); + label(P(0,0,3.5), P(0,4), "$z$", t); + + bold(); + arc_arrow(P(0,0,0), 2, 0.5*Theta, Theta); + arc_arrow(P(0,0,0), 2, 0.5*Theta, 0); + + aarrow(P(0,0,0), sph(2, Theta, Phi)); + + label(sph(2, 0.5*Theta, 0), P(2,2), "$\\theta$", t); + label(sph(2, Theta, 0.5*Phi), P(-2,0), "$\\phi$", l); + label(sph(1, Theta, Phi), P(2,-2), "$\\rho$", br); + + base(Neutral(), 0); + dashed(); + plain(); + line(P(0,0,0), P(2,0,0)); + line(P(0,0,0), sph(2, Theta, 0)); + line(P(0,0,0), sph(2, Theta, Phi)); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/sqrt.xp b/graphics/epix/samples/sqrt.xp new file mode 100644 index 0000000000..ffc5335c99 --- /dev/null +++ b/graphics/epix/samples/sqrt.xp @@ -0,0 +1,51 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +P f(double x, double y) +{ + pair z(x,y); + pair temp(z*z); + return P(temp.x1(), temp.x2(), x); +} + +P F(double r, double t) +{ + return f(r*Cos(t), r*Sin(t)); +} + +P g(double t) +{ + return t*P(t,0,1); +} + +domain R(P(0,0), P(1.25,0.5), mesh(6,24), mesh(12,60)); + +int main() +{ + picture(P(-1.5, -1.5), P(1.5, 1.5), "2.5x2.5in"); + + begin(); + revolutions(); + camera.at(P(4,-2,3)); + + pen(Blue(1.7)); + plot(F, R); + + pen(Blue()); + plot(F, R.resize2(0.5,1)); + + pen(Black()); + arrow(P(0,0,0), 2*E_1); + arrow(P(0,0,0), 2*E_2); + arrow(P(0,0,0), 1.5*E_3); + + masklabel(2*E_1, P(0,0), "$\\mathrm{Re}\\,z$", r); + label(2*E_2, P(0,0), "$\\mathrm{Im}\\,z$", r); + label(1.5*E_3, P(2,0), "$\\mathrm{Re}\\,\\sqrt{z}$", r); + + bold(Red()); + plot(g, -1.25, 1.25, 40); + + end(); +} diff --git a/graphics/epix/samples/sqrt2.xp b/graphics/epix/samples/sqrt2.xp new file mode 100644 index 0000000000..8bfcfcfab4 --- /dev/null +++ b/graphics/epix/samples/sqrt2.xp @@ -0,0 +1,64 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// MAX^2 = radius of plot +const double MAX(1.5); + +// complex square root in polar coordinates +P f(double u, double v) +{ + return P(u*u*Cos(v), u*u*Sin(v), u*Cos(0.5*v)); +} + +// restrictions of sqrt to real axis, unit circle +P sqrt_re(double t) { return f(t,0); } +P sqrt_im(double t) { return f(1,t); } + +int main() { + picture(P(-4, -4), P(4, 2), "4x3in"); + + begin(); + + camera.filter(RGB_Neutral()); + + backing(Magenta(0.1)); + set_crop(); + + revolutions(); + label(P(xmin(), ymax()), P(2,-2), "Branches of $\\sqrt{z}$", br); + + camera.at(6, -2, 2); + camera.range(4); + domain R(P(0,0), P(MAX,2), mesh(16, 80), mesh(16, 160)); + + // transparent branch + pen(Green(0.7), "0.15pt"); + scenery surf(f, R.resize2(1,2)); + + fill(White(0.7)); + pen(Black()); + // opaque branch + surf.add(f, R.resize2(0,1)); + + surf.draw(); + nofill(); + // boundary curve, unit circle, axes, grid, labels + bbold(Red()); + + plot(sqrt_re, -MAX, 0, 30); + + bold(Blue()); + arrow(P(0,0,0), P(2,0,0)); + arrow(P(0,0,0), P(0,2,0)); + + label_color(Blue()); + label(P(2,0,0), P(0,-4), "$\\mathrm{Re}\\,z$", b); + label(P(0,2,0), P(4, 0), "$\\mathrm{Im}\\,z$", r); + + bbold(Yellow()); + plot(sqrt_re, 0, MAX, 30); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/std_F.cc b/graphics/epix/samples/std_F.cc new file mode 100644 index 0000000000..9ccd7b90c6 --- /dev/null +++ b/graphics/epix/samples/std_F.cc @@ -0,0 +1,124 @@ +/* + * std_F.cc -- The std_F class definitions + * + * Last Change: September 23, 2007 + */ +// Include only the headers we need; burdensome, but generally more +// efficient for larger projects with many dependencies. +#ifdef MINIMAL +#include "epix/affine.h" +#include "epix/Color.h" +#include "epix/curves.h" +#include "epix/pairs.h" +#include "epix/path.h" +#include "epix/state.h" +#include "epix/triples.h" + +#else +#include "epix.h" +#endif + +#include "epix/paint_style.h" +#include "std_F.h" + +namespace ePiX { + + // The constructor initializes the class data, ensuring objects are + // well-formed. For efficiency, we use "initialization" instead of + // assignment (the "=" operator); this way, data members get their + // actual values immediately. The constructor body is empty, since + // this class requires no further initialization. + + // All class member function definitions must be qualified with the + // class name, here "std_F::" + std_F::std_F() + : m_loc(0,0), m_e1(1,0), m_e2(0,1), + m_fore(Black()), m_back(White()), + m_edge(Black()), m_edge_width(0.4) { } + + // Apply the affine map af; return a reference to this object so + // calls can be daisy-chained. Note the efficiency of storing only + // the bare minimum data to specify an affine map rather than + // holding and manipulating the shape of an F. + std_F& std_F::map_by(const affine& af) + { + m_loc = af(m_loc); // affines map locations, so this works + m_e1 = af(m_e1); + m_e2 = af(m_e2); + + return *this; + } + + // Set the background and foreground colors. Arguments' names chosen + // to indicate their purpose. + std_F& std_F::backing(const Color& back) + { + m_back = back; + return *this; + } + + std_F& std_F::fill(const Color& fore) + { + m_fore = fore; + return *this; + } + + // Set outline parameters. + std_F& std_F::border(const Color& edge, double wid) + { + m_edge = edge; + m_edge_width = wid; + return *this; + } + + // Draw in the active screen. Most of the "real work" is done here. + void std_F::draw() const + { + // Get global drawing state, so we can restore before returning. + // Not particularly elegant, but it's what we have to work with. + Color old_fill(the_paint_style().fill_color()); + bool old_flag(the_paint_style().fill_flag()); + + Color old_line(the_paint_style().line_color()); + length old_line_width(the_paint_style().line_width()); + + // now we can draw + const double r(1.0/6.0); + + path F; + + // pr converts coords in [0,1] x [0,1] to our coords + F .pt(pr(r, 0.75*r)).pt(pr(2*r, 0.75*r)).pt(pr(2*r, 2.25*r)) + .pt(pr(4*r, 2.25*r)).pt(pr(4*r, 3.25*r)).pt(pr(2*r, 3.25*r)) + .pt(pr(2*r, 4.25*r)).pt(pr(5*r, 4.25*r)).pt(pr(5*r, 5.25*r)) + .pt(pr( r, 5.25*r)); + + F.close().fill(); + + // Set global drawing state. We have a member function named fill, + // so the call must be explicitly qualified with "ePiX::". + ePiX::fill(m_back); + ePiX::pen(m_edge, m_edge_width); + + // Bounding parallelogram + ePiX::quad(pr(0,0), pr(1,0), pr(1,1), pr(0,1)); + + ePiX::fill(m_fore); + F.draw(); + // Restore global fill state. + the_paint_style().fill_color(old_fill); + the_paint_style().fill_flag(old_flag); + + the_paint_style().line_color(old_line); + the_paint_style().line_width(old_line_width); + } + + // private; convert (x,y) to a location usable in path construction + // "Privacy" is enforced by the compiler from reading the header; + // the definition requires no special syntax. + P std_F::pr(double x, double y) const + { + pair loc((1 - x -y)*m_loc + x*m_e1 + y*m_e2); + return P(loc.x1(), loc.x2()); + } +} // end of namespace diff --git a/graphics/epix/samples/std_F.h b/graphics/epix/samples/std_F.h new file mode 100644 index 0000000000..961fc984e4 --- /dev/null +++ b/graphics/epix/samples/std_F.h @@ -0,0 +1,83 @@ +/* + * std_F.h -- A class to draw the action of an affine transformation. + * + * This file is a C++ class tutorial (illustrating basic features), as + * well as sample code for a small library, and style guide to writing + * external modules for ePiX. + * + * Last Change: September 23, 2007 + */ + +/* + * This file provides the "std_F" class, which draws the image of an "F" + * (the first roman letter having no symmetries) under an affine map. + * + * std_F(); // An F in the unit square [0,1] x [0,1]. + * map_by(af); // Apply the affine map af + * + * // Set the background, foreground, border style + * backing(color); + * fill(folor); + * border(color, width); + * + * draw(); // Draw in the active screen + * + * The file affine.xp illustrates use. + */ +// "MINIMAL" compilation works, and entails fewer dependencies, +// but places a larger burdern on the programer +#ifdef MINIMAL +#include "epix/pairs.h" +#include "epix/Color.h" +#else + +#include "epix.h" +#endif + +namespace ePiX { + + // forward declarations if we don't include epix.h +#ifdef MINIMAL + class affine; + class P; +#endif + + // declare a new class "std_F" + class std_F { + // The "public" part of a class declaration specifies the interface: + public: + // A "constructor"; creates the standard F in the unit square + std_F(); + + // apply the affine map af; return a reference to this object so + // calls can be daisy-chained + std_F& map_by(const affine& af); + + // set the background and foreground colors + std_F& backing(const Color&); + std_F& fill(const Color&); + + // set outline pen + std_F& border(const Color&, double); + + void draw() const; // draw in the active screen + + // The private section contains implementation data, etc. The + // shape of the F is not stored in the class data, but generated + // at runtime by draw(). + private: + pair m_loc; // lower left corner + pair m_e1; // lower right corner + pair m_e2; // upper left corner + + Color m_fore; + Color m_back; + Color m_edge; + + double m_edge_width; + + // for internal use; convert (x,y) in [0,1] x [0,1] to a location + P pr(double x, double y) const; + }; // end of std_F; class declarations must end with a semicolon + +} // end of namespace diff --git a/graphics/epix/samples/std_F.xp b/graphics/epix/samples/std_F.xp new file mode 100644 index 0000000000..e2ae794d5d --- /dev/null +++ b/graphics/epix/samples/std_F.xp @@ -0,0 +1,88 @@ +/* -*-ePiX-*- */ +#include "epix.h" +#include "std_F.h" // include the custom header +using namespace ePiX; + +// September 23, 2007 +// +// The instructions below assume you've copied this file and the +// sample files std_F.cc and std_F.h into a directory where you +// have write permission. +// +// To build std_F.cc, you'll need to run commands similar to +// +// g++ -I. -c std_F.cc +// ar -ru libaff.a std_F.o +// ranlib libaff.a +// +// Respectively, these compile std_F.cc into an object file, std_F.o; +// create a static library named libaff.a containing the object code; +// and create an index in libaff.a for the linker, so the library can +// be used in external programs, such as the one built from this +// source file. (On Mac OSX, you may need to run ranlib *after* moving +// the library file to its permanent home.) +// +// You may give the library a different name, but it MUST begin "lib" +// and have the extension ".a": "libblug.a" and "libaff-1.0.a" are all +// right, but "mylib.a" or "libaff.test" are not. You refer to the +// library by its name with "lib" and ".a" removed, as in "blug" or +// "aff-1.0". +// +// To compile this source file (the one you're reading now), build +// libaff.a as described above, then run the command +// +// epix -I. -L. -laff std_F.xp +// +// Files (such as this one) that use an external library cannot be +// compiled from emacs, since there is no way to pass the required +// options; they must be compiled at a shell prompt. +// +// Please consult the gcc documentation ("g++ --help") for information on +// what each option does. + + +// About this file: +// +// "F" is the first letter of the Roman alphabet that has no non-trivial +// symmetries. +// +// std_F is a class for representing plane affine maps; please consult +// the manual for general information of ePiX's plane affine map class. +// + +int main() +{ + picture(P(0,0), P(6,6), "4x4in"); + + begin(); + degrees(); + + grid(6,6); + + std_F F1; // the standard F + affine af1; // the identity map + + F1.draw(); + + // stretch along the main diagonal + af1.rotate(45).v_scale(3).h_scale(0.75).rotate(-45); + + // flip over the main diagonal and translate + af1.reflect(45).shift(pair(3,2)); + + // apply af, set style, and draw + F1.map_by(af1).fill(Black(0.6)).backing(Blue(1.8)).draw(); + + std_F F2; + affine af2; + af2.rotate(60).scale(1.5).shift(pair(5,0)); + F2.map_by(af2).backing(RGB(1,0.8,0.2)).fill(Green(0.6)).draw(); + + std_F F3; + // define af3 by images of e1, e2, origin + affine af3(pair(2-sqrt(3), 6), pair(2,3), pair(2,5)); + F3.map_by(af3).backing(Black(0.4)).fill(White()).draw(); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/steiner.flx b/graphics/epix/samples/steiner.flx new file mode 100644 index 0000000000..a7d4953097 --- /dev/null +++ b/graphics/epix/samples/steiner.flx @@ -0,0 +1,50 @@ +/* -*-flix-*- */ +// Steiner's Roman surface, using "surface" plots +// May 19, 2006 +#include "epix.h" + +using namespace ePiX; + +double MAX(2.5), rad(0.8*MAX); + +P F(double u, double v) +{ + double x(rad*Cos(u)*Cos(v)), y(rad*Cos(u)*Sin(v)), z(rad*Sin(u)); + return P(y*z, x*z, x*y); +} + +P color(double x, double y) +{ +#ifdef COLORSHADE + return P(0.5*Sin(x), -0.5*Sin(x), Cos(y)); +#else + return P(1,1,1); // white +#endif +} + +int main(int argc, char* argv[]) +{ + if (argc == 3) + { + char* arg; + double temp1, temp2; + temp1=strtod(argv[1], &arg); + temp2=strtod(argv[2], &arg); + + tix()=temp1/temp2; + } + picture(P(-MAX,-MAX),P(MAX,MAX), "4x4in"); + + begin(); + + backing(RGB(0.7, 0.9, 1)); + + fill(); + revolutions(); + camera.at(cyl(10, 0.5*tix(), 2)); // exploit 2-fold symmetry + + surface(F, domain(P(-0.25, 0), P(0.25, 0.5), mesh(32,32), mesh(64,64)), color); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/steiner2.flx b/graphics/epix/samples/steiner2.flx new file mode 100644 index 0000000000..37a8199825 --- /dev/null +++ b/graphics/epix/samples/steiner2.flx @@ -0,0 +1,70 @@ +/* -*-flix-*- */ +#include "epix.h" +using namespace ePiX; + +double MAX(2.5), rad(0.8*MAX); + +int N(6); // slices + +P F(double u, double v) +{ + double x(rad*Cos(u)*Cos(v)), y(rad*Cos(u)*Sin(v)), z(rad*Sin(u)); + return P(y*z, x*z, x*y); +} + +/* +P color(double x, double y) +{ +#ifdef COLORSHADE + return P(0.5*Sin(x), -0.5*Sin(x), Cos(y)); +#else + return P(1,1,1); // white +#endif +} +*/ + +int main(int argc, char* argv[]) +{ + if (argc == 3) + { + char* arg; + double temp1(strtod(argv[1], &arg)), temp2(strtod(argv[2], &arg)); + + tix()=temp1/temp2; + } + + picture(P(-MAX,-MAX),P(MAX,MAX), "4x4in"); + + begin(); + + backing(RGB(0.7, 0.9, 1)); + + fill(); + revolutions(); + camera.at(cyl(10, 0.25, 4)); + + P perp(sph(1, 0.125, tix())); + + domain R(P(-0.25, 0), P(0.25, 0.5), mesh(32,32), mesh(64,64)); +#ifdef SHOWGRID + plain(Red()); + plot(F, R); +#endif + + int mult(1); + // reverse slice order if necessary + if ((perp | camera.eye()) < 0) + mult=-1; + + for (int i=-mult*N; i != mult*N; i += mult) + { + clip_slice((MAX*i*1.0/N)*perp, perp, 0.1); + rgb(0.25+0.1*i, 0, -0.1*i); + + surface(F, R); + clip_restore(); + } + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/surface_shade.xp b/graphics/epix/samples/surface_shade.xp new file mode 100644 index 0000000000..d2676190c8 --- /dev/null +++ b/graphics/epix/samples/surface_shade.xp @@ -0,0 +1,46 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// surface to plot (a dog saddle) +P f(double u, double v) +{ + return P(u, v, 0.5*u*v*(u-v)*(u+v)); +} + +// position-dependent color function +P color(double x, double y, double z) +{ +#ifdef LAUREL_BURCH + return P(-Sin(0.25*x), 0.2, -Cos(0.25*x)); // Laurel Burch colors +#else + return P(-tanh(z), 0, tanh(z)); // Quasi-geographic 70s colors +#endif +} + +int main() +{ + picture(P(-3,-3), P(3,3), "6x6in"); + + begin(); + + // Set creation attributes, + revolutions(); + set_crop(); + fill(); + + // style attributes, + backing(Black()); + plain(Yellow()); + + // and viewpoint. + camera.at(P(8, -8, 4)); + + // Add scenery + domain R(P(-2,-2), P(2, 2), mesh(36, 36), mesh(72, 72)); + surface(f, R, color); + + // and print + pst_format(); + end(); +} diff --git a/graphics/epix/samples/symmetries.xp b/graphics/epix/samples/symmetries.xp new file mode 100644 index 0000000000..bda649bdbf --- /dev/null +++ b/graphics/epix/samples/symmetries.xp @@ -0,0 +1,87 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// draw a regular n-gon with labeled vertices +void polygon(int n, double th_0 = 0) +{ + const double d_th(full_turn()/n); + path poly; + for (int i=0; i<n; ++i) + { + // i-th vertex + double th(th_0 + i*d_th); + const P vtx(cis(th)); + poly.pt(vtx); + + // set label angle + label_angle(th + 0.25*full_turn()); + + // draw label + std::stringstream buf; + buf << "$" << i << "$"; + dot(vtx, -8*vtx, buf.str()); + } + + poly.close().draw(); +} + +int main() +{ + picture(P(0,0), P(2,3), "4 x 6in"); + + begin(); + + border(); + + // draw one hexagon in a screen + screen scr(P(-1,-1), P(1,1)); + activate(scr); + + polygon(6); + + // marks to distinguish a vertex and orientation + spot(P(1,0)); + black(0.3); + line(P(-0.75,0), P(0.75,0)); + + black(); + arc_arrow(P(0,0), 0.75, 0, M_PI/3); + arc_arrow(P(0,0), 0.75, 2*M_PI/3, M_PI); + arc_arrow(P(0,0), 0.75, 4*M_PI/3, 5*M_PI/3); + scr.scale(0.9); + + // use layout and affine maps to draw symmetries + inset(P(0,2), P(1,3)); + + scr.rotate(2*M_PI/3); + inset(P(0,1), P(1,2)); + + scr.rotate(2*M_PI/3); + inset(P(0,0), P(1,1)); + + scr.rotate(2*M_PI/3).reflect(0); + inset(P(1,2), P(2,3)); + + scr.rotate(2*M_PI/3); + inset(P(1,1), P(2,2)); + + scr.rotate(2*M_PI/3); + inset(P(1,0), P(2,1)); + + deactivate(scr); + + // label insets + font_size("LARGE"); + label_angle(0); + masklabel(P(0.5, 2.5), "$e$"); + masklabel(P(0.5, 1.5), "$\\alpha$"); + masklabel(P(0.5, 0.5), "$\\alpha^2$"); + + masklabel(P(1.5, 2.5), "$\\beta$"); + masklabel(P(1.5, 1.5), "$\\beta\\alpha^2$"); + masklabel(P(1.5, 0.5), "$\\beta\\alpha$"); + + pst_format(); + end(); +} diff --git a/graphics/epix/samples/tori.xp b/graphics/epix/samples/tori.xp new file mode 100644 index 0000000000..aa925845d6 --- /dev/null +++ b/graphics/epix/samples/tori.xp @@ -0,0 +1,63 @@ +/* -*-ePiX-*- */ +/* tori.xp -- May 09, 2005 */ +// compile tutorial torus meshes at once +#include "epix.h" +using namespace ePiX; + +// torus +P F(double u, double v) +{ + return polar(2.25+Cos(u), v) + P(0,0,Sin(u)); +} + +int main() +{ + picture(P(0,0), P(4,1), "6 x 1.5in"); + + begin(); + + domain R(P(0,0), P(1,1), mesh(12,30), mesh(24, 60)); + + revolutions(); + camera.at(10,7,5); + + // unclipped/cropped + screen scr1(P(-3,-3), P(3,3)); + activate(scr1); + fill(White()); + surface(F, R); + inset(P(0,0), P(1,1)); + deactivate(scr1); + + // cropped + screen scr2(P(-3,-3), P(3,3)); + activate(scr2); + set_crop(); + border(); + surface(F, R); + inset(P(1.5,0), P(2.5,1)); + deactivate(scr2); + + // clipped + screen scr3(P(-3,-3), P(3,3)); + activate(scr3); + clip_box(P(3.5, 2, 1.5)); + + // box, sides layered manually + nofill(); + rect(P(-3.5, -2, -1.5), P(-3.5, 2, 1.5)); + rect(P(-3.5, -2, -1.5), P( 3.5, -2, 1.5)); + + fill(); + surface(F, R); + nofill(); + rect(P( 3.5, -2, -1.5), P( 3.5, 2, 1.5)); + rect(P(-3.5, 2, -1.5), P( 3.5, 2, 1.5)); + + inset(P(3,0), P(4,1)); + deactivate(scr3); + + pst_format(); + end(); +} + diff --git a/graphics/epix/samples/torus.xp b/graphics/epix/samples/torus.xp new file mode 100644 index 0000000000..dbcfe31906 --- /dev/null +++ b/graphics/epix/samples/torus.xp @@ -0,0 +1,39 @@ +/* -*-ePiX-*- */ +/* torus.xp -- July 6, 2004 */ +#include "epix.h" +using namespace ePiX; + +const int N(8); + +P F(double t1, double t2) +{ + return polar(2+Sin(t2), t1) + Cos(t2)*E_3; +} + +domain R(P(0,0), P(1,1), mesh(4*N, 2*N), mesh(12*N, 6*N)); + +int main() +{ + picture(P(-3,-3), P(3,3), "2x2in"); + + begin(); + revolutions(); + camera.at(1.7,-1, 0.75); + camera.range(8); + + rgb(0.2, 0.5, 0.7); + + plot(F, R.resize1(0,0.875)); + + bold(); + rgb(0.5, 0.3, 0.9); + plot(F, R.resize2(-0.375,0).resize1(0,0.125)); + + red(); + dashed(); + plot(F, R.slice1(0)); + plot(F, R.slice2(0)); + + end(); +} + diff --git a/graphics/epix/samples/trig.flx b/graphics/epix/samples/trig.flx new file mode 100644 index 0000000000..f07763f4d4 --- /dev/null +++ b/graphics/epix/samples/trig.flx @@ -0,0 +1,74 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +P f(double x, double t) +{ + return P(x, Sin(x+t)); +} + +domain R(P(0,0), P(1,1), mesh(60,24), mesh(120, 72)); + +int main(int argc, char* argv[]) +{ + if (argc == 3) + { + char* arg; + double temp1, temp2; + temp1=strtod(argv[1], &arg); + temp2=strtod(argv[2], &arg); + + tix()=temp1/temp2; + } + + picture(P(0,0), P(5,2), "5x2in"); + + begin(); + revolutions(); + + border(); + set_crop(); + + screen rolling(P(-1,-1), P(1,1)); + screen waving(P(0,-1), P(1,1)); + + activate(rolling); + + P ctr(polar(0.5, tix())); + P rim(polar(0.5, tix()) + polar(0.5, -tix())); + P rim2(polar(0.5, tix()) + polar(0.5, 0.5-tix())); + + circle(ctr, 0.5); // small wheel + + bold(); + circle(P(0,0), 1); // big wheel + + green(); + line(P(1,0), P(-1,0)); + + blue(); + line(P(0,1), P(0,-1)); + + red(); + line(ctr, rim); + line(ctr, rim2); + + ddot(rim); + ddot(rim2); + deactivate(rolling); + + activate(waving); + set_crop(); + blue(); + plot(f, R.slice2(tix())); + deactivate(waving); + + inset(rolling, P(0,0), P(2,2)); + inset(waving, P(3,0), P(5,2)); + + dashed(); + pen(Blue(1.6), 0.15); + line(P(1,1+Sin(tix())), P(3,1) + f(0, tix())); + + end(); +} diff --git a/graphics/epix/samples/twisted_cubic.xp b/graphics/epix/samples/twisted_cubic.xp new file mode 100644 index 0000000000..8e9ec5d4b7 --- /dev/null +++ b/graphics/epix/samples/twisted_cubic.xp @@ -0,0 +1,106 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const double MAX(2.5); + +const double XMIN(-2); + +// twisted cubic +P cubic(double t) +{ + return t*P(1, t, t*t); +} + +// projections to coordinate planes +P cubic12(double t) +{ + const P arg(cubic(t)); + return P(arg.x1(), arg.x2(), XMIN); +} + +P cubic13(double t) +{ + const P arg(cubic(t)); + return P(arg.x1(), XMIN, arg.x3()); +} + +P cubic23(double t) +{ + const P arg(cubic(t)); + return P(XMIN, arg.x2(), arg.x3()); +} + +// draw lines from one path to another +void bars(P f1(double), P f2(double)) +{ + for (int i=0; i<=20; ++i) + line(f1(-1+0.1*i), f2(-1+0.1*i)); +} + +// code to draw entire figure +void draw_frame() +{ + // (x,z)-plane + blue(); + bbold(); + plot(cubic13, -1, 1, 60); + plain(); + bars(cubic13, cubic); + label(cubic13(1), P(0,2), "$x$-$z$", t); + + // (y,z)-plane + green(0.6); + bbold(); + plot(cubic23, -1, 1, 60); + plain(); + bars(cubic23, cubic); + label(cubic23(1), P(0,2), "$y$-$z$", t); + + // (x,y)-plane + magenta(); + bbold(); + plot(cubic12, -1, 1, 60); + plain(); + bars(cubic12, cubic); + label(cubic12(1), P(2,0), "$x$-$y$",r); + + // the cubic + bold(Red(1.6)); + base(Red(0.6), "2pt"); + plot(cubic, -1, 1, 60); +} + +int main() +{ + picture(P(-1,0), P(1.25,1), "4.5 x 2in"); + + begin(); + + screen scr_left(P(-MAX,-MAX), P(MAX,MAX)); + activate(scr_left); + + border(Black(), "1pt"); + + camera.at(sph(10, 0.8, 0.5)); + camera.look_at(P(0,0,-0.25)); + + draw_frame(); + base(Neutral()); + + screen scr_right(P(-MAX,-MAX), P(MAX,MAX)); + activate(scr_right); + + border(Black(), "1pt"); + + camera.at(sph(10, 0.9, 0.5)); + camera.look_at(P(0,0,-0.25)); + + draw_frame(); + + inset(scr_left, P(0.25,0), P(1.25,1)); + inset(scr_right, P(-1,0), P(0,1)); + + end(); +} + diff --git a/graphics/epix/samples/uppersum.xp b/graphics/epix/samples/uppersum.xp new file mode 100644 index 0000000000..d1ff6ac2b0 --- /dev/null +++ b/graphics/epix/samples/uppersum.xp @@ -0,0 +1,37 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const int N(12); // Number of rectangles + +// gather references to integrand +double f(double t) +{ + return Sin(t); +} + +int main() +{ + picture(P(0,0), P(3,1), "3x1in"); + + begin(); + + const double dx(xsize()/N); + + riemann_sum(f, xmin(), xmax(), N, UPPER); + + fill(Black(0.1)); + riemann_sum(f, xmin(), xmax(), N, LOWER); + nofill(); + + h_axis(xsize()); + v_axis(2*ysize()); + + h_axis_labels(xsize(), P(0,-4), b); + label(P(2, f(2)), P(4,2), "$y=\\sin x$", tr); + + bold(Blue()); + plot(f, xmin(), xmax(), 40); + + end(); +} diff --git a/graphics/epix/samples/vfield.xp b/graphics/epix/samples/vfield.xp new file mode 100644 index 0000000000..ba6e1fd8ba --- /dev/null +++ b/graphics/epix/samples/vfield.xp @@ -0,0 +1,71 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +// A spatial vector field depending on three variables +P F(double x, double y, double z) +{ + return -0.25*P(0.5*x+y, 0.5*y-x, 1+z); +} + +domain R(P(-1,-1,-1), P(1,1,1), mesh(6,6,4), mesh()); + +int main() +{ + picture(P(-2,-2),P(2,2), "4x4in"); + + begin(); + border(); + + label(P(0, ymax()), P(0,-4), "$F(x,y,z)=-(x+2y, y-2x, 1+z)$",b); + + camera.at(P(11,8,5)); + + // coordinate grids + const int GRIDS(6); + plain(Black(0.3)); + grid(P(-1, -1,-1), P(-1, 1, 1), GRIDS, GRIDS); + grid(P(-1, -1,-1), P( 1,-1, 1), GRIDS, GRIDS); + grid(P(-1, -1,-1), P(1, 1, -1), GRIDS, GRIDS); + + // flow lines + bold(); + for (int i=0; i<12; ++i) + { + double t(M_PI_2+i*M_PI/6); + pen(RGB(0.25*(3+Sin(t)), 0.25, 0.25*(3+Cos(t)))); + ode_plot(F, cyl(1.4, t, 1), 0, 10, 60); + } + + // draw arrows in plain black borderd by a white edge; + // vectors will appear to hide vectors behind them + plain(Black()); + base(White(), "2pt"); + + // the field is drawn in successive slices x_3 = const +#ifdef VECT + vector_field(F, R, 0.75); // draw arrowheads at 75% of default size +#else + dart_field(F, R, 0.5); // draw darts at 50% of default length +#endif + + const double DX(0.125); // label padding + font_size("scriptsize"); + degrees(); + + label_angle(30); // adjusted visually; could calculate from camera position + label(P(1+DX, -1, -1), P(-4,-2), "$y=-1$", bl); + label(P(1+DX, 0, -1), P(-4,-2), "$y=0$", bl); + label(P(1+DX, 1, -1), P(-4,-2), "$y=1$", bl); + + label_angle(-15); + label(P(-1, 1+DX, -1), P(4,0), "$x=-1$", br); + label(P( 0, 1+DX, -1), P(4,0), "$x=0$", br); + label(P( 1, 1+DX, -1), P(4,0), "$x=1$", br); + + label(P( 1, -1-DX, -1), P(-4,0), "$z=-1$", tl); + label(P( 1, -1-DX, 0), P(-4,0), "$z=0$", tl); + label(P( 1, -1-DX, 1), P(-4,0), "$z=1$", tl); + + end(); +} diff --git a/graphics/epix/samples/weierstrass.xp b/graphics/epix/samples/weierstrass.xp new file mode 100644 index 0000000000..2822b0737a --- /dev/null +++ b/graphics/epix/samples/weierstrass.xp @@ -0,0 +1,36 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +const int N(8); // Number of summands + +double weierstrass(double t) +{ + double y(0); + for(int i=0; i < N; ++i) + y += pow(2,-i)*cb(pow(2,i)*t); + + return y; +} + +int main() +{ + picture(P(-2, 0), P(2, 1.5), "3.2 x 1.2in"); + + begin(); + + h_axis(2*xsize()); + v_axis(2*ysize()); + h_axis_labels(xsize(), P(-4,-8)); + + blue(); + plot(cb, xmin() - 0.25, xmax()+0.25, 4*xsize() + 2); + + bold(Black()); + plot(weierstrass, xmin(), xmax(), pow(2,N)); + + pen(Red()); + plot(weierstrass, 0.5, 1.5, pow(2,N-2)); + + end(); +} diff --git a/graphics/epix/samples/wheel.xp b/graphics/epix/samples/wheel.xp new file mode 100644 index 0000000000..e8056f8658 --- /dev/null +++ b/graphics/epix/samples/wheel.xp @@ -0,0 +1,50 @@ +/* -*-ePiX-*- */ +#include "epix.h" +using namespace ePiX; + +P F(double t, double r) +{ + return P(t-r*Sin(t), 1-r*Cos(t)); // a cycloid +} + +int main() +{ + picture(P(0,0), P(15,27), "4 x 7.2in"); + + begin(); + + const double dt(5*M_PI/11); + double t(dt); + + for(int i=0; i < 9; ++i, t += dt) + { + screen scr(P(-1,0), P(15,2)); // drawing area + activate(scr); + + plain(Black()); + line(P(-1, 0), P(15, 0)); // the ground + + circle(P(t,1), 1); // the wheel + + // [0,t] x [0,1] + domain R(P(0,0), P(t, 1), mesh(10*i,5), mesh((int) ceil(1+4*t), 5)); + + // the paths + bold(); + for (int j=0; j < 6; ++j) + { + pen(RGB(1-0.125*j, 0.125*j, 0.5+0.125*j)); + plot(F, R.slice2(0.2*j)); + } + + // the spoke + bold(Green()); + line(P(t,1), F(t,1)); + + inset(P(0, 25-3*i), P(15, 27-3*i)); // page layout + deactivate(scr); + } + + end(); +} + diff --git a/graphics/epix/screen.cc b/graphics/epix/screen.cc new file mode 100644 index 0000000000..2c23a26d68 --- /dev/null +++ b/graphics/epix/screen.cc @@ -0,0 +1,390 @@ +/* + * screen.cc -- ePiX::screen_data class wrapper (for user interface) + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.18 + * Last Change: September 16, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <string> +#include <sstream> + +#include "triples.h" +#include "pairs.h" +#include "affine.h" + +#include "Color.h" + +#include "mask_ellipse.h" +#include "mask_rectangle.h" +#include "mask_diamond.h" + +#include "screen_data.h" +#include "screen.h" + +namespace ePiX { + + // N.B. Our interface handles only P, not pair. + // Our implementation works only with pair, not P. + + P __epix_pair2P(const pair& arg) + { + return P(arg.x1(), arg.x2(), 0); + } + + screen::screen() { } + + screen::screen(const P& arg1, const P& arg2) + : m_screen(new screen_data(pair(arg1.x1(), arg1.x2()), + pair(arg2.x1(), arg2.x2()))) { } + + + screen::screen(const screen& sc) + : m_screen(sc.m_screen->clone()) { } + + screen& screen::operator= (const screen& sc) + { + if (this != &sc) + { + screen_data* tmp(sc.m_screen->clone()); + + delete m_screen; + m_screen = tmp; + } + + return *this; + } + + screen::~screen() + { + delete m_screen; + } + + + // Set mask; one named function for each type of screen_mask + screen& screen::crop_mask_rectangle(const P& sw, const P& ne) + { + const pair BL(sw.x1(), sw.x2()); + const pair TR(ne.x1(), ne.x2()); + + m_screen->set_mask(mask_rectangle(BL, TR)); + return *this; + } + + screen& screen::crop_mask_ellipse(const P& sw, const P& ne) + { + const pair BL(sw.x1(), sw.x2()); + const pair TR(ne.x1(), ne.x2()); + + m_screen->set_mask(mask_ellipse(BL, TR)); + return *this; + } + + screen& screen::crop_mask_diamond(const P& sw, const P& ne) + { + const pair BL(sw.x1(), sw.x2()); + const pair TR(ne.x1(), ne.x2()); + + m_screen->set_mask(mask_diamond(BL, TR)); + return *this; + } + + // masks' cardinal points lie on circumrectangle, corners may not + screen& screen::crop_mask_rectangle() + { + const pair BL((m_screen->l()).x1(), (m_screen->b()).x2()); + const pair TR((m_screen->r()).x1(), (m_screen->t()).x2()); + + m_screen->set_mask(mask_rectangle(BL, TR)); + return *this; + } + + screen& screen::crop_mask_ellipse() + { + const pair BL((m_screen->l()).x1(), (m_screen->b()).x2()); + const pair TR((m_screen->r()).x1(), (m_screen->t()).x2()); + + m_screen->set_mask(mask_ellipse(BL, TR)); + return *this; + } + + screen& screen::crop_mask_diamond() + { + const pair BL((m_screen->l()).x1(), (m_screen->b()).x2()); + const pair TR((m_screen->r()).x1(), (m_screen->t()).x2()); + + m_screen->set_mask(mask_diamond(BL, TR)); + return *this; + } + + + screen screen::extract(const P& arg1, const P& arg2) const + { + screen value(arg1, arg2); + + value.m_screen + = new screen_data(m_screen->extract(pair(arg1.x1(), arg1.x2()), + pair(arg2.x1(), arg2.x2()))); + return value; + } + + screen screen::extract_diamond(const P& arg1, const P& arg2) const + { + screen value(arg1, arg2); + + value.m_screen + = new screen_data(m_screen->extract_diamond(pair(arg1.x1(), arg1.x2()), + pair(arg2.x1(), arg2.x2()))); + return value; + } + + screen screen::extract_ellipse(const P& arg1, const P& arg2) const + { + screen value(arg1, arg2); + + value.m_screen + = new screen_data(m_screen->extract_ellipse(pair(arg1.x1(), arg1.x2()), + pair(arg2.x1(), arg2.x2()))); + return value; + } + + + screen& screen::set_crop(bool arg) + { + m_screen->set_crop(arg); + return *this; + } + + // crop contents to current mask + screen& screen::crop() + { + m_screen->crop(); + return *this; + } + + + // inset and import + screen& screen::paste(const screen& child, const P& sw, const P& ne) + { + m_screen->paste(*(child.m_screen), mask_rectangle(pair(sw.x1(), sw.x2()), + pair(ne.x1(), ne.x2()))); + return *this; + } + + screen& screen::paste(const screen& child) + { + m_screen->paste(*(child.m_screen)); + return *this; + } + + screen& screen::clear() + { + m_screen->clear(); + return *this; + } + + screen& screen::border(const Color& col, double len) + { + std::stringstream buf; + buf << len << "pt"; + m_screen->border(col, buf.str()); + return *this; + } + + screen& screen::border(const Color& col, const std::string& len) + { + m_screen->border(col, len); + return *this; + } + + screen& screen::backing(const Color& col) + { + m_screen->backing(col); + return *this; + } + + + screen& screen::border() + { + m_screen->border(); + return *this; + } + + screen& screen::backing() + { + m_screen->backing(); + return *this; + } + + // affine operations on contents (not border, backing) + screen& screen::apply(const affine& af) + { + m_screen->apply(af); + return *this; + } + + screen& screen::shift(const P& arg) + { + m_screen->shift(pair(arg.x1(), arg.x2())); + return *this; + } + + // rotate by theta about ctr + screen& screen::rotate(double theta, const P& ctr) + { + m_screen->rotate(theta, pair(ctr.x1(), ctr.x2())); + return *this; + } + + // reflect in angle-theta line through ctr + screen& screen::reflect(double theta, const P& ctr) + { + m_screen->reflect(theta, pair(ctr.x1(), ctr.x2())); + return *this; + } + + // scale coord direction(s) fixing ctr + screen& screen::h_scale(double sc, const P& ctr) + { + m_screen->h_scale(sc, pair(ctr.x1(), ctr.x2())); + return *this; + } + + screen& screen::v_scale(double sc, const P& ctr) + { + m_screen->v_scale(sc, pair(ctr.x1(), ctr.x2())); + return *this; + } + + screen& screen::scale(double sc, const P& ctr) + { + m_screen->scale(sc, pair(ctr.x1(), ctr.x2())); + return *this; + } + + // shear, fixing ctr, e.g. h_shear(sc) : (x,y) -> (x+sc*y, y) + screen& screen::h_shear(double sc, const P& ctr) + { + m_screen->h_shear(sc, pair(ctr.x1(), ctr.x2())); + return *this; + } + + screen& screen::v_shear(double sc, const P& ctr) + { + m_screen->v_shear(sc, pair(ctr.x1(), ctr.x2())); + return *this; + } + + P screen::tr() const + { + return __epix_pair2P(m_screen->tr()); + } + + P screen::tl() const + { + return __epix_pair2P(m_screen->tl()); + } + + P screen::bl() const + { + return __epix_pair2P(m_screen->bl()); + } + + P screen::br() const + { + return __epix_pair2P(m_screen->br()); + } + + + P screen::t() const + { + return __epix_pair2P(m_screen->t()); + } + + P screen::b() const + { + return __epix_pair2P(m_screen->b()); + } + + P screen::l() const + { + return __epix_pair2P(m_screen->l()); + } + + P screen::r() const + { + return __epix_pair2P(m_screen->r()); + } + + P screen::c() const + { + return __epix_pair2P(m_screen->c()); + } + + + double screen::h_min() const + { + return m_screen->h_min(); + } + + double screen::h_max() const + { + return m_screen->h_max(); + } + + double screen::h_size() const + { + return m_screen->h_size(); + } + + double screen::h_avg() const + { + return m_screen->h_avg(); + } + + + double screen::v_min() const + { + return m_screen->v_min(); + } + + double screen::v_max() const + { + return m_screen->v_max(); + } + + double screen::v_size() const + { + return m_screen->v_size(); + } + + double screen::v_avg() const + { + return m_screen->v_avg(); + } +} // end of namespace diff --git a/graphics/epix/screen.h b/graphics/epix/screen.h new file mode 100644 index 0000000000..023d34b4be --- /dev/null +++ b/graphics/epix/screen.h @@ -0,0 +1,175 @@ +/* + * screen.h -- ePiX::screen class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.18 + * Last Change: September 15, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file defines the screen class interface, a Cartesian rectangle + * into which objects are drawn. Object-creating commands add to the + * the "global" screen the_picture(). Users may create and activate + * additional screens, then import their content to the_picture(). + * + * Constructor: + * screen(P(a,c), P(b,d)); // corners of bounding box + * + * Markup functions: + * crop(); // remove elements outside bounding box + * crop_to(mask); // or specified mask + * paste(screen); // overlay contents of screen + * paste(screen, P(a,c), P(b,d)); // or inset into specified rectangle + * + * Decorations: + * border(Color, "1pt"); // set border color/width + * backing(Color); // and backing color + * + * This file wraps the implementation, which is hidden from the user. + */ +#ifndef EPIX_SCREEN +#define EPIX_SCREEN + +#include <string> + +#include "triples.h" + +namespace ePiX { + + class Color; + class affine; + class screen_data; + class P; + + // global function + void write(const std::string&); + + class screen { + // There's no user-visible form for screen contents, so + // we give these classes access to our implementation. + friend class arrow_data; + friend class label_data; + friend class legend; + friend class path_data; + friend class picture_data; + friend void write(const std::string&); + + public: + screen(); + screen(const P&, const P&); + + screen(const screen&); + screen& operator= (const screen&); + ~screen(); + + // Set mask; one named function for each type of screen_mask + screen& crop_mask_rectangle(const P&, const P&); + screen& crop_mask_ellipse(const P&, const P&); + screen& crop_mask_diamond(const P&, const P&); + + screen& crop_mask_rectangle(); + screen& crop_mask_ellipse(); + screen& crop_mask_diamond(); + + // return selected region + screen extract(const P&, const P&) const; + screen extract_diamond(const P&, const P&) const; + screen extract_ellipse(const P&, const P&) const; + + // set flag only + screen& set_crop(bool arg=true); + + // crop contents to current mask + screen& crop(); + + // inset and import + screen& paste(const screen& child, const P& inset_sw, const P& inset_ne); + screen& paste(const screen& child); + + screen& clear(); + + // border(Color, length)? + screen& border(const Color&, double); + screen& border(const Color&, const std::string&); + screen& backing(const Color&); + + screen& border(); + screen& backing(); + + //// pass-through functions //// + // affine operations on contents (not border, backing) + screen& apply(const affine& f); + + // convenience operators for single affine ops + screen& shift(const P& arg); + + // rotate by theta about ctr + screen& rotate(double theta, const P& ctr = P(0,0)); + + // reflect in angle-theta line through ctr + screen& reflect(double theta, const P& ctr = P(0,0)); + + // scale coord direction(s) fixing ctr + screen& h_scale(double, const P& ctr=P(0,0)); + screen& v_scale(double, const P& ctr=P(0,0)); + screen& scale(double, const P& ctr=P(0,0)); + + // shear, fixing ctr, e.g. h_shear(sc) : (x,y) -> (x+sc*y, y) + screen& h_shear(double sc, const P& ctr=P(0,0)); + screen& v_shear(double sc, const P& ctr=P(0,0)); + + P tr() const; + P tl() const; + P bl() const; + P br() const; + + P t() const; + P b() const; + P l() const; + P r() const; + P c() const; + + double h_min() const; + double h_max() const; + double h_size() const; + double h_avg() const; + + double v_min() const; + double v_max() const; + double v_size() const; + double v_avg() const; + + private: + screen_data* m_screen; + + }; // end of class screen + +} // end of namespace + +#endif /* EPIX_SCREEN */ diff --git a/graphics/epix/screen_crop.cc b/graphics/epix/screen_crop.cc new file mode 100644 index 0000000000..1eb6860266 --- /dev/null +++ b/graphics/epix/screen_crop.cc @@ -0,0 +1,70 @@ +/* + * screen_crop.cc -- ePiX functions for cropping 2D paths and loops + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.8 + * Last Change: July 17, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "functions.h" +#include "pairs.h" + +#include "edge_data.h" +#include "screen_crop.h" +#include "crop_algorithms.h" + +namespace ePiX { + + typedef std::list<edge2d>::const_iterator CLI; + + static pair unit_perp(const edge2d& E) + { + pair N(J(E.head() - E.tail())); + return N *= recip(norm(N)); + } + + // O(n^2) algorithm seems necessary since edge_list needn't be convex + std::list<edge2d>& crop_path_2nd(const std::list<edge2d>& bord, + std::list<edge2d>& edge_list) + { + for (CLI ep=bord.begin(); ep != bord.end(); ++ep) + chop_path<pair>(unit_perp(*ep), (*ep).tail(), edge_list); + + return cull<pair>(edge_list); + } + + std::list<edge2d>& crop_loop_2nd(const std::list<edge2d>& bord, + std::list<edge2d>& edge_list) + { + for (CLI ep=bord.begin(); ep != bord.end(); ++ep) + { + chop_path<pair>(unit_perp(*ep), (*ep).tail(), edge_list); + loopify<pair>(edge_list); + } + + return cull<pair>(edge_list); + } +} // end of namespace diff --git a/graphics/epix/screen_crop.h b/graphics/epix/screen_crop.h new file mode 100644 index 0000000000..910114528a --- /dev/null +++ b/graphics/epix/screen_crop.h @@ -0,0 +1,49 @@ +/* + * screen_crop.h -- ePiX functions for cropping 2D paths and loops + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.8 + * Last Change: July 17, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_SCREEN_CROP +#define EPIX_SCREEN_CROP + +#include <list> + +#include "edge_data.h" + +namespace ePiX { + + // return reference to second argument + std::list<edge2d>& crop_path_2nd(const std::list<edge2d>&, + std::list<edge2d>&); + + std::list<edge2d>& crop_loop_2nd(const std::list<edge2d>&, + std::list<edge2d>&); +} // end of namespace + +#endif /* EPIX_SCREEN_CROP */ diff --git a/graphics/epix/screen_data.cc b/graphics/epix/screen_data.cc new file mode 100644 index 0000000000..02eac318b5 --- /dev/null +++ b/graphics/epix/screen_data.cc @@ -0,0 +1,572 @@ +/* + * screen_data.cc -- ePiX::screen class implementation + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.1 + * Last Change: September 28, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <list> +#include <algorithm> +#include <sstream> + +#include "camera.h" + +#include "pairs.h" + +#include "functions.h" + +#include "Color.h" + +#include "utils.h" + +#include "tile.h" + +#include "pen_line.h" +#include "pen_fill.h" + +#include "affine.h" +#include "mask_ellipse.h" +#include "mask_rectangle.h" +#include "mask_diamond.h" + +#include "format.h" + +// #include "screen_mask.h" +#include "screen_data.h" + +namespace ePiX { + + typedef std::list<tile*>::const_iterator Tp; + + // constructor + screen_data::screen_data(const pair& arg1, const pair& arg2) + : m_bl(pair(min(arg1.x1(), arg2.x1()), min(arg1.x2(), arg2.x2()))), + m_tr(pair(max(arg1.x1(), arg2.x1()), max(arg1.x2(), arg2.x2()))), + m_mask(new mask_rectangle(m_bl, m_tr)), + m_border(new pen_line()), + m_backing(new pen_fill()), + m_crop(false) { } + + // copy constructor + screen_data::screen_data(const screen_data& scr) + : m_bl(scr.m_bl), + m_tr(scr.m_tr), + m_mask(scr.m_mask->clone()), + m_border(scr.m_border->clone()), + m_backing(scr.m_backing->clone()), + m_crop(scr.m_crop) + { + for(Tp p=scr.m_tiles.begin(); p!= scr.m_tiles.end(); ++p) + add_tile(*p); + } + + // copy assignment + screen_data& screen_data::operator= (const screen_data& scr) + { + if (this != &scr) + { + // copy scr's tiles before freeing ours + std::list<tile*> tmp; + for(Tp p=scr.m_tiles.begin(); p!= scr.m_tiles.end(); ++p) + add_tile(*p); + + screen_mask* tmp_mask(scr.m_mask->clone()); + + pen_line* tmp_border(scr.m_border->clone()); + pen_fill* tmp_backing(scr.m_backing->clone()); + + // okay, safe to muck with our data + m_bl = scr.m_bl; + m_tr = scr.m_tr; + + delete m_mask; + m_mask = tmp_mask; + + delete m_border; + m_border = tmp_border; + + delete m_backing; + m_backing = tmp_backing; + + for (Tp p=m_tiles.begin(); p!=m_tiles.end(); ++p) + delete *p; + + swap(m_tiles, tmp); + + m_crop = scr.m_crop; + } + return *this; + } // end of copy assignment + + + screen_data::~screen_data() + { + delete m_mask; + delete m_border; + delete m_backing; + + for(Tp p=m_tiles.begin(); p!= m_tiles.end(); ++p) + delete *p; + } + + screen_data* screen_data::clone() const + { + return new screen_data(*this); + } + + + // superimpose a layer by affine scaling + // map child to inset (inset defaults to m_mask) + screen_data& screen_data::paste(const screen_data& child, + const screen_mask& inset) + { + if (this != &child) + { + const double h_sc(inset.h_size()/child.h_size()); + const double v_sc(inset.v_size()/child.v_size()); + + const pair tmp00(inset.bl() - (child.bl() & pair(h_sc, v_sc))); + + affine af(tmp00 + pair(h_sc, 0), tmp00 + pair(0, v_sc), tmp00); + + // backing + if (!child.m_backing->is_empty()) + { + // child is const, so must copy tile + pen_fill* temp(child.m_backing->clone()); + add_tile(temp->map_by(af)); + } + + // tiles + for(Tp p=child.m_tiles.begin(); p!= child.m_tiles.end(); ++p) + { + tile* temp((*p)->clone()); + add_tile(temp->map_by(af)); + } + + // border + if (!child.m_border->is_empty()) + { + pen_line* temp(child.m_border->clone()); + add_tile(temp->map_by(af)); + } + } + + return *this; + } // end of paste(child, inset) + + + screen_data& screen_data::paste(const screen_data& child) + { + if (this != &child) + { + const double h_sc(h_size()/child.h_size()); + const double v_sc(v_size()/child.v_size()); + + const pair tmp00(bl() - (child.bl() & pair(h_sc, v_sc))); + + affine af(tmp00 + pair(h_sc, 0), tmp00 + pair(0, v_sc), tmp00); + + // backing + if (!child.m_backing->is_empty()) + { + // child is const, so must copy tile + pen_fill* temp(child.m_backing->clone()); + + add_tile(temp->map_by(af)); + } + + // tiles + for(Tp p=child.m_tiles.begin(); p!= child.m_tiles.end(); ++p) + { + tile* temp((*p)->clone()); + add_tile(temp->map_by(af)); + } + + // border + if (!child.m_border->is_empty()) + { + pen_line* temp(child.m_border->clone()); + add_tile(temp->map_by(af)); + } + } + + return *this; + } + + screen_data& screen_data::clear() + { + delete m_border; + m_border = new pen_line(); + + m_tiles.clear(); + + delete m_backing; + m_backing = new pen_fill(); + + m_crop = false; + return *this; + } + + screen_data& screen_data::crop_to(const screen_mask& mask) + { + std::list<tile*> visibles; + + if (!m_border->is_empty()) + m_border->crop_to(mask); + + if (!m_backing->is_empty()) + m_backing->crop_to(mask); + + for (Tp curr=m_tiles.begin(); curr!=m_tiles.end(); ++curr) + { + (*curr)->crop_to(mask); + + if (!(*curr)->is_empty()) + visibles.push_back(*curr); + } + + swap(m_tiles, visibles); + return *this; + } + + screen_data& screen_data::crop() + { + return crop_to(*m_mask); + } + + + screen_data& screen_data::set_mask(const screen_mask& mask) + { + delete m_mask; + m_mask = mask.clone(); + + return *this; + } + + screen_data& screen_data::set_crop(bool arg) + { + m_crop = arg; + return *this; + } + + screen_data screen_data::extract(const pair& arg1, const pair& arg2) const + { + screen_data value(arg1, arg2); + value.set_crop(true); + + for (Tp curr=m_tiles.begin(); curr!=m_tiles.end(); ++curr) + value.add_tile(*curr); + + return value; + } + + screen_data screen_data::extract_diamond(const pair& arg1, + const pair& arg2) const + { + screen_data value(arg1, arg2); + + value.set_mask(mask_diamond(arg1, arg2)).set_crop(true); + + for (Tp curr=m_tiles.begin(); curr!=m_tiles.end(); ++curr) + value.add_tile(*curr); + + return value; + } + + screen_data screen_data::extract_ellipse(const pair& arg1, + const pair& arg2) const + { + screen_data value(arg1, arg2); + + value.set_mask(mask_ellipse(arg1, arg2)).set_crop(true); + + for (Tp curr=m_tiles.begin(); curr!=m_tiles.end(); ++curr) + value.add_tile(*curr); + + return value; + } + + + screen_data& screen_data::border(const Color& col, const std::string& len) + { + delete m_border; + m_border = new pen_line(m_mask->border(cam()(col), len)); + m_crop = true; + + return *this; + } + + + screen_data& screen_data::backing(const Color& col) + { + delete m_backing; + m_backing = new pen_fill(m_mask->backing(cam()(col))); + m_crop = true; + + return *this; + } + + + screen_data& screen_data::border() + { + delete m_border; + m_border = new pen_line(m_mask->border()); + m_crop = true; + + return *this; + } + + + screen_data& screen_data::backing() + { + delete m_backing; + m_backing = new pen_fill(m_mask->backing()); + m_crop = true; + + return *this; + } + + // screen cropping done in these two functions + void screen_data::add_tile(const tile& T) + { + tile* tmp(T.clone()); + if (m_crop) + tmp->crop_to(*m_mask); + + if (!tmp->is_empty()) + m_tiles.push_back(tmp); + } + + void screen_data::add_tile(tile* Tp) + { + tile* tmp(Tp->clone()); + if (m_crop) + tmp->crop_to(*m_mask); + + if (!tmp->is_empty()) + m_tiles.push_back(tmp); + } + + + // affine operations on contents (not border, backing) + void screen_data::apply(const affine& af) + { + for (Tp curr=m_tiles.begin(); curr!=m_tiles.end(); ++curr) + (*curr)->map_by(af); + } + + void screen_data::shift(const pair& arg) + { + affine af; + af.shift(arg); + apply(af); + } + + // rotate by theta about ctr + void screen_data::rotate(double theta, const pair& ctr) + { + affine af; + af.rotate(theta, ctr); + apply(af); + } + + // reflect in angle-theta line through ctr + void screen_data::reflect(double theta, const pair& ctr) + { + affine af; + af.reflect(theta, ctr); + apply(af); + } + + // scale coord direction(s) fixing ctr + void screen_data::h_scale(double sc, const pair& ctr) + { + affine af; + af.h_scale(sc, ctr); + apply(af); + } + + void screen_data::v_scale(double sc, const pair& ctr) + { + affine af; + af.v_scale(sc, ctr); + apply(af); + } + + void screen_data::scale(double sc, const pair& ctr) + { + affine af; + af.scale(sc, ctr); + apply(af); + } + + // shear, fixing ctr, e.g. h_shear(sc) : (x,y) -> (x+sc*y, y) + void screen_data::h_shear(double sc, const pair& ctr) + { + affine af; + af.h_shear(sc, ctr); + apply(af); + } + + void screen_data::v_shear(double sc, const pair& ctr) + { + affine af; + af.v_shear(sc, ctr); + apply(af); + } + + + pair screen_data::tr() const + { + return m_tr; + } + + pair screen_data::tl() const + { + return pair(m_bl.x1(), m_tr.x2()); + } + + pair screen_data::bl() const + { + return m_bl; + } + + pair screen_data::br() const + { + return pair(m_tr.x1(), m_bl.x2()); + } + + + pair screen_data::t() const + { + return pair(0.5*(m_bl.x1() + m_tr.x1()), m_tr.x2()); + } + + pair screen_data::b() const + { + return pair(0.5*(m_bl.x1() + m_tr.x1()), m_bl.x2()); + } + + pair screen_data::l() const + { + return pair(m_bl.x1(), 0.5*(m_bl.x2() + m_tr.x2())); + } + + pair screen_data::r() const + { + return pair(m_tr.x1(), 0.5*(m_bl.x2() + m_tr.x2())); + } + + pair screen_data::c() const + { + return pair(0.5*(m_bl.x1() + m_tr.x1()), 0.5*(m_bl.x2() + m_tr.x2())); + } + + + double screen_data::h_min() const + { + return m_bl.x1(); + } + + double screen_data::h_max() const + { + return m_tr.x1(); + } + + double screen_data::h_size() const + { + return m_tr.x1() - m_bl.x1(); + } + + double screen_data::h_avg() const + { + return 0.5*(m_bl.x1() + m_tr.x1()); + } + + + double screen_data::v_min() const + { + return m_bl.x2(); + } + + double screen_data::v_max() const + { + return m_tr.x2(); + } + + double screen_data::v_size() const + { + return m_tr.x2() - m_bl.x2(); + } + + double screen_data::v_avg() const + { + return 0.5*(m_bl.x2() + m_tr.x2()); + } + + std::string screen_data::print_to(const format& fmt, const length& len, + bool wrap) const + { + std::ostringstream obuf; + + if (wrap) + { + obuf << fmt.start_picture(tr()-bl(), bl()); + fmt.reset_state(); // ensures drawing attribs set properly below + } + + if (!m_backing->is_empty()) + { + m_backing->add_to_pallet(); + + obuf << m_backing->print_to(fmt, len.units()); + } + + for (Tp curr = m_tiles.begin(); curr != m_tiles.end(); ++curr) + { + (*curr)->add_to_pallet(); + + obuf << (*curr)->print_to(fmt, len.units()); + } + + if (!m_border->is_empty()) + { + m_border->add_to_pallet(); + + obuf << m_border->print_to(fmt, len.units()); + } + + if (wrap) + obuf << fmt.end_picture(); + + return obuf.str(); + } // end of print_to() + +} // end of namespace diff --git a/graphics/epix/screen_data.h b/graphics/epix/screen_data.h new file mode 100644 index 0000000000..582ec1d555 --- /dev/null +++ b/graphics/epix/screen_data.h @@ -0,0 +1,153 @@ +/* + * screen_data.h -- ePiX::screen class implementation + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.18 + * Last Change: September 16, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file implements the screen class, a Cartesian rectangle into + * which objects are drawn. This file is not part of epix.h. + */ +#ifndef EPIX_SCREEN_DATA +#define EPIX_SCREEN_DATA + +#include <string> +#include <list> + +#include "pairs.h" + +namespace ePiX { + + class affine; + class Color; + class format; + class length; + class pen_fill; + class pen_line; + class screen_mask; + class tile; + + class screen_data { + public: + screen_data(const pair&, const pair&); + + screen_data(const screen_data&); + screen_data& operator= (const screen_data&); + ~screen_data(); + + screen_data* clone() const; + + screen_data& crop_to(const screen_mask&); + screen_data& crop(); + + + screen_data& set_mask(const screen_mask&); + screen_data& set_crop(bool); + + // cut out and return a region + screen_data extract(const pair&, const pair&) const; + screen_data extract_diamond(const pair&, const pair&) const; + screen_data extract_ellipse(const pair&, const pair&) const; + + // inset and import + screen_data& paste(const screen_data& child, const screen_mask& inset); + screen_data& paste(const screen_data& child); + + screen_data& clear(); + + screen_data& border(const Color&, const std::string&); + screen_data& backing(const Color&); + + screen_data& border(); + screen_data& backing(); + + void add_tile(const tile&); + void add_tile(tile*); + + // wrap=true -> encapsulate in a picture, for legends + std::string print_to(const format&, const length&, bool wrap=false) const; + + // affine operations on contents (not border, backing) + void apply(const affine& af); + void shift(const pair& arg); + + // rotate by theta about ctr + void rotate(double theta, const pair& ctr = pair(0,0)); + + // reflect in angle-theta line through ctr + void reflect(double theta, const pair& ctr = pair(0,0)); + + // scale coord direction(s) fixing ctr + void h_scale(double, const pair& ctr=pair(0,0)); + void v_scale(double, const pair& ctr=pair(0,0)); + void scale(double, const pair& ctr=pair(0,0)); + + // shear, fixing ctr, e.g. h_shear(sc) : (x,y) -> (x+sc*y, y) + void h_shear(double sc, const pair& ctr=pair(0,0)); + void v_shear(double sc, const pair& ctr=pair(0,0)); + + pair tr() const; + pair tl() const; + pair bl() const; + pair br() const; + + pair t() const; + pair b() const; + pair l() const; + pair r() const; + pair c() const; + + double h_min() const; + double h_max() const; + double h_size() const; + double h_avg() const; + + double v_min() const; + double v_max() const; + double v_size() const; + double v_avg() const; + + private: + pair m_bl; + pair m_tr; + + screen_mask* m_mask; + pen_line* m_border; + pen_fill* m_backing; + + bool m_crop; + + std::list<tile*> m_tiles; + }; // end of class screen_data + +} // end of namespace + +#endif /* EPIX_SCREEN_DATA */ diff --git a/graphics/epix/screen_mask.cc b/graphics/epix/screen_mask.cc new file mode 100644 index 0000000000..e652685e4e --- /dev/null +++ b/graphics/epix/screen_mask.cc @@ -0,0 +1,55 @@ +/* + * screen_mask.cc -- ePiX::screen_mask interface + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.4 + * Last Change: June 17, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "constants.h" + +#include "pairs.h" + +#include "screen_mask.h" + +namespace ePiX { + + //// screen_mask::alignment points //// + pair screen_mask::tr() const { return pair(h_max(), v_max()); } + pair screen_mask::tl() const { return pair(h_min(), v_max()); } + pair screen_mask::bl() const { return pair(h_min(), v_min()); } + pair screen_mask::br() const { return pair(h_max(), v_min()); } + + pair screen_mask::t() const { return pair(h_avg(), v_max()); } + pair screen_mask::b() const { return pair(h_avg(), v_min()); } + pair screen_mask::l() const { return pair(h_min(), v_avg()); } + pair screen_mask::r() const { return pair(h_max(), v_avg()); } + pair screen_mask::c() const { return pair(h_avg(), v_avg()); } + +} // end of ePiX namespace diff --git a/graphics/epix/screen_mask.h b/graphics/epix/screen_mask.h new file mode 100644 index 0000000000..0ec475f3db --- /dev/null +++ b/graphics/epix/screen_mask.h @@ -0,0 +1,97 @@ +/* + * screen_mask.h -- ePiX::screen_mask interface, for screen cropping + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.8 + * Last Change: July 17, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_SCREEN_MASK +#define EPIX_SCREEN_MASK + +#include <list> +#include <string> + +#include "edge_data.h" + +namespace ePiX { + + class pair; + + class Color; + + class length; + class pen_fill; + class pen_line; + + class screen_mask { + public: + virtual ~screen_mask() { } + + virtual screen_mask* clone() const = 0; + + // alignment points + pair tr() const; + pair tl() const; + pair bl() const; + pair br() const; + + pair t() const; + pair b() const; + pair l() const; + pair r() const; + pair c() const; + + // cropping facilities (for tiles: glyph, pen_line, pen_fill resp.) + virtual bool crops(const pair& arg) const = 0; // false if arg visible + virtual std::list<edge2d>& crop_path(std::list<edge2d>&) const = 0; + virtual std::list<edge2d>& crop_loop(std::list<edge2d>&) const = 0; + + // extreme and average coordinates, dimensions + virtual double h_min() const = 0; + virtual double h_max() const = 0; + virtual double h_size() const = 0; + virtual double h_avg() const = 0; + + virtual double v_min() const = 0; + virtual double v_max() const = 0; + virtual double v_size() const = 0; + virtual double v_avg() const = 0; + + // convert us to screen border or backing + virtual pen_line border(const Color&, const length&) const = 0; + virtual pen_fill backing(const Color&) const = 0; + + virtual pen_line border() const = 0; + virtual pen_fill backing() const = 0; + }; // end of class screen_mask + +} // end of namespace + +#endif /* EPIX_SCREEN_MASK */ diff --git a/graphics/epix/segment.cc b/graphics/epix/segment.cc new file mode 100644 index 0000000000..3ea5eb3760 --- /dev/null +++ b/graphics/epix/segment.cc @@ -0,0 +1,111 @@ +/* + * segment.cc -- ePiX::Segment class and mathematical operators + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.9 + * Last Change: July 30, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "triples.h" + +#include "path.h" +#include "segment.h" + +namespace ePiX { + + Segment::Segment(const P& p1, const P& p2) + : m_endpt1(p1), m_endpt2(p2), m_malformed(false) { } + + Segment::Segment(bool tag) : m_malformed(true) { } + + P Segment::end1() const + { + return m_endpt1; + } + + P Segment::end2() const + { + return m_endpt2; + } + + bool Segment::malformed() const + { + return m_malformed; + } + + // translate + Segment& Segment::shift(const P& arg) + { + if (!m_malformed) + { + m_endpt1 += arg; + m_endpt2 += arg; + } + return *this; + } + + Segment& Segment::move_to(const P& arg) + { + if (!m_malformed) + { + const P dX(arg - 0.5*(m_endpt1 + m_endpt2)); + m_endpt1 += dX; + m_endpt2 += dX; + } + return *this; + } + + Segment& Segment::scale(double c) + { + if (!m_malformed) + { + const P ctr(0.5*(m_endpt1 + m_endpt2)); + + m_endpt1 = ctr + c*(m_endpt1 - ctr); + m_endpt2 = ctr + c*(m_endpt2 - ctr); + } + return *this; + } + + P Segment::midpoint() const + { + return 0.5*(m_endpt1 + m_endpt2); + } + + void Segment::draw() const + { + if (m_malformed) + return; + + // else + path temp(m_endpt1, m_endpt2); + + temp.draw(); + } +} // end of namespace diff --git a/graphics/epix/segment.h b/graphics/epix/segment.h new file mode 100644 index 0000000000..5a19b1dd6a --- /dev/null +++ b/graphics/epix/segment.h @@ -0,0 +1,84 @@ +/* + * segment.h -- ePiX::Segment class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.9 + * Last Change: July 30, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file provides: + * + * The Segment class (unordered pair of points), and operators: + * - end1(), end2() (no guaranteed order) + * - Translation operators shift(P), move_to(P) + * - Stretch about midpoint: scale(double) + * - draw() (ePiX line) + * - midpoint(); + */ + +#ifndef EPIX_SEGMENT +#define EPIX_SEGMENT + +#include "triples.h" + +namespace ePiX { + + class Segment { + public: + Segment(const P&, const P&); // endpoints + + Segment(bool); // malformed Segment for intersection operators + + // Segment ends are not distinguished geometrically, + // so these functions should normally be used in tandem. + P end1() const; + P end2() const; + + bool malformed() const; + + // translate + Segment& shift(const P&); + Segment& move_to(const P&); + + Segment& scale(double); + + P midpoint() const; + + void draw() const; + + private: + P m_endpt1; + P m_endpt2; + + bool m_malformed; + }; // end of Segment class + +} // end of namespace +#endif /* EPIX_SEGMENT */ diff --git a/graphics/epix/sphere.cc b/graphics/epix/sphere.cc new file mode 100644 index 0000000000..5f172e0fb0 --- /dev/null +++ b/graphics/epix/sphere.cc @@ -0,0 +1,131 @@ +/* + * sphere.cc -- ePiX::Sphere class and mathematical operators + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.9 + * Last Change: July 30, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <cmath> + +#include "errors.h" + +#include "triples.h" + +#include "functions.h" + +#include "camera.h" +#include "circle.h" + +#include "sphere.h" + +namespace ePiX { + + Sphere::Sphere(const P& ctr, double rad) + : m_ctr(ctr), m_rad(rad), m_malformed(false) { } + + Sphere::Sphere(const P& ctr, const P& pt) + : m_ctr(ctr), m_rad(norm(pt-ctr)), m_malformed(false) { } + + P Sphere::center() const + { + return m_ctr; + } + + double Sphere::radius() const + { + return m_rad; + } + + bool Sphere::malformed() const + { + return m_malformed; + } + + // translation + Sphere& Sphere::shift(const P& arg) + { + if (!m_malformed) + m_ctr += arg; + return *this; + } + + Sphere& Sphere::move_to(const P& arg) + { + if (!m_malformed) + m_ctr = arg; + return *this; + } + + Sphere& Sphere::scale(double& arg) + { + if (!m_malformed) + m_rad *= arg; + return *this; + } + + + void Sphere::draw() const + { + if (m_malformed) + return; + + // else + P location(cam().viewpt()); + + P dir(m_ctr - location); + double dist(norm(dir)); + + if (dist <= m_rad) + epix_warning("Cannot draw sphere enclosing camera"); + + else + { + dir *= 1/dist; + double x(m_rad*m_rad/dist); + + Circle temp(m_ctr - x*dir, sqrt((m_rad-x)*(m_rad+x)), dir); + temp.draw(); + } + } // end of Sphere::photo() + + + //// global functions //// + void sphere(const P& ctr, double rad) + { + Sphere S(ctr, rad); + S.draw(); + } + + void sphere(const P& ctr, const P& pt) + { + Sphere S(ctr, pt); + S.draw(); + } +} // end of namespace diff --git a/graphics/epix/sphere.h b/graphics/epix/sphere.h new file mode 100644 index 0000000000..fa043ca382 --- /dev/null +++ b/graphics/epix/sphere.h @@ -0,0 +1,87 @@ +/* + * sphere.h -- ePiX::Sphere class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.9 + * Last Change: July 30, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file provides: + * + * The Sphere class (center, radius), and operators: + * - Sphere += P (translate by <P>) + * - Sphere *= double (scale about center) + * - draw() (ePiX line) + * - center(); + * - radius(); + * + * Hiding test, latitude and longitudes on a sphere. + */ +#ifndef EPIX_SPHERE +#define EPIX_SPHERE + +#include "triples.h" + +namespace ePiX { + + class Sphere { + public: + Sphere(const P& ctr=P(0,0,0), double rad=1); + Sphere(const P& ctr, const P& pt); + + P center() const; + double radius() const; + + bool malformed() const; // always returns false, currently + + // translation + Sphere& shift(const P&); + Sphere& move_to(const P&); + + // scale radius + Sphere& scale(double&); + + void draw() const; + + private: + P m_ctr; + double m_rad; + + bool m_malformed; + }; // end of Sphere class + + + // global horizon-drawing functions + void sphere(const P& ctr=P(0,0,0), double rad=1); + void sphere(const P& ctr, const P& pt); + +} // end of namespace + +#endif /* EPIX_SPHERE */ diff --git a/graphics/epix/spline.cc b/graphics/epix/spline.cc new file mode 100644 index 0000000000..286d63d57a --- /dev/null +++ b/graphics/epix/spline.cc @@ -0,0 +1,145 @@ +/* + * spline.cc -- ePiX n_spline class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.9 + * Last Change: August 02, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "path.h" +#include "spline.h" + +namespace ePiX { + // natural spline constructor + n_spline::n_spline(const std::vector<P>& data, bool loop) + : m_vertices(data) + { + if (loop) + m_vertices.push_back(m_vertices.at(0)); + + const unsigned int N(m_vertices.size()-1); + + // notation and algorithm from John H. Matthews and Kurtis K. Fink + std::vector<double> tmp_h(N+1); // h_k = x_{k+1} - x_k + std::vector<double> tmp_d(N+1); // d_k = (y_{k+1} - y_k)/h_k + std::vector<double> tmp_u(N+1); // u_k = 6*(d_{k+1} - d_k) + std::vector<double> tmp_y(N+1); // y_k + + // entries of tridiagonal coefficient matrix + std::vector<double> tmp_A(N+1); // subdiagonal of coefficient matrix + std::vector<double> tmp_C(N+1); // superdiagonal + std::vector<double> tmp_D(N+1); // diagonal + + std::vector<double> tmp_m(N+1); // m_k = S"(x_k), 1 <= k <= N-1 + + // initialize... + for (unsigned int i = 0; i <= N; ++i) + { + P curr(m_vertices.at(i)); + + tmp_y.at(i) = curr.x2(); + + if (i <= N-1) + { + P next(m_vertices.at(i+1)); + + tmp_h.at(i) = (next.x1() - curr.x1()); + tmp_d.at(i) = (next.x2() - curr.x2())/tmp_h.at(i); + + if (0 < i) + { + tmp_u.at(i) = 6*(tmp_d.at(i) - tmp_d.at(i-1)); + tmp_D.at(i) = 2*(tmp_h.at(i) + tmp_h.at(i-1)); + + if (i <= N-2) + { + tmp_A.at(i) = tmp_h.at(i); + tmp_C.at(i) = tmp_h.at(i); + } + } + } + } + + for (unsigned int i=2; i <= N; ++i) + { + const double ratio(tmp_A.at(i-1)/tmp_D.at(i-1)); + + tmp_D.at(i) -= ratio*tmp_C.at(i-1); + tmp_u.at(i) -= ratio*tmp_u.at(i-1); + } + + tmp_m.at(N) = tmp_u.at(N-1)/tmp_D.at(N-1); + + for (unsigned int i=N-1; 0 < i; --i) + tmp_m.at(i) = (tmp_u.at(i) - tmp_C.at(i)*tmp_m.at(i+1))/tmp_D.at(i); + + std::vector<double> tmp_k0(N); + std::vector<double> tmp_k1(N); + std::vector<double> tmp_k2(N); + std::vector<double> tmp_k3(N); + + for (unsigned int i=0; i < N; ++i) + { + tmp_k0.at(i) = tmp_y.at(i); + tmp_k1.at(i) + = tmp_d.at(i) - (tmp_h.at(i)/6)*(2*tmp_m.at(i) + tmp_m.at(i+1)); + + tmp_k2.at(i) = 0.5*tmp_m.at(i); + tmp_k3.at(i) = (tmp_m.at(i+1) - tmp_m.at(i))/(6*tmp_h.at(i)); + } + + swap(tmp_k0, m_k0); + swap(tmp_k1, m_k1); + swap(tmp_k2, m_k2); + swap(tmp_k3, m_k3); + } + + path n_spline::data(const unsigned int num_pts) const + { + path value; + for (unsigned int i=0; i < m_vertices.size()-1; ++i) + { + const double Xmin(m_vertices.at(i).x1()); + const double dx((m_vertices.at(i+1).x1() - Xmin)/num_pts); + + for (unsigned int j=0; j<=num_pts; ++j) + { + const double w(j*dx); + const double x(Xmin + w); + + // Horner's form + double y((((m_k3.at(i)*w) + m_k2.at(i))*w + m_k1.at(i))*w + m_k0.at(i)); + + value.pt(P(x, y)); + } + } + return value; + } + +} // end of namespace diff --git a/graphics/epix/spline.h b/graphics/epix/spline.h new file mode 100644 index 0000000000..bf8630a39f --- /dev/null +++ b/graphics/epix/spline.h @@ -0,0 +1,63 @@ +/* + * spline.h -- ePiX spline class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.3 + * Last Change: March 04, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_SPLINE +#define EPIX_SPLINE + +#include <vector> +#include "triples.h" + +namespace ePiX { + + class path; + + class n_spline { + public: + + n_spline(const std::vector<P>& data, bool loop=false); + + path data(const unsigned int) const; + + private: + std::vector<P> m_vertices; + + // coefficient sequences + std::vector<double> m_k0; + std::vector<double> m_k1; + std::vector<double> m_k2; + std::vector<double> m_k3; + }; // end of class n_spline + +} // end of namespace + +#endif /* EPIX_SPLINE */ diff --git a/graphics/epix/spline_data.h b/graphics/epix/spline_data.h new file mode 100644 index 0000000000..ea47eeb982 --- /dev/null +++ b/graphics/epix/spline_data.h @@ -0,0 +1,51 @@ +/* + * splinee_data.h -- ePiX parametric spline functions + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.4 + * Last Change: June 18, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_SPLINE_DATA +#define EPIX_SPLINE_DATA + +namespace ePiX { + + template <typename T> + T spl_pt(const T& p1, const T& p2, const T& p3, double t) + { + return (1-t)*(1-t)*p1 + 2*t*(1-t)*p2 + t*t*p3; + } + + template <typename T> + T spl_pt(const T& p1, const T& p2, const T& p3, const T& p4, double t) + { + const double s(1-t); + return s*s*(s*p1 + 3*t*p2) + t*t*(3*s*p3 + t*p4); + } +} // end of namespace + +#endif /* EPIX_SPLINE_DATA */ diff --git a/graphics/epix/state.cc b/graphics/epix/state.cc new file mode 100644 index 0000000000..44802bf991 --- /dev/null +++ b/graphics/epix/state.cc @@ -0,0 +1,509 @@ +/* + * state.cc -- ePiX's current drawing state + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.22 + * Last Change: September 24, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "constants.h" +#include "errors.h" +#include "triples.h" +#include "Color.h" + +#include "length.h" + +#include "camera.h" + +#include "angle_units.h" +#include "arrow_style.h" +#include "label_style.h" +#include "marker_style.h" +#include "paint_style.h" +#include "path_style.h" + +#include "active_screen.h" +#include "screen.h" + +#include "clipping.h" + +#include "state.h" + +namespace ePiX { + + // set camera position + void viewpoint(const P& arg) + { + cam().at(arg); + } + + void viewpoint(double x1, double x2, double x3) + { + cam().at(P(x1, x2, x3)); + } + + // Set angular mode + void radians() + { + the_angle_style().set_radians_mode(); + } + + void degrees() + { + the_angle_style().set_degrees_mode(); + } + + void revolutions() + { + the_angle_style().set_revolutions_mode(); + } + + + // number of current units in a full turn + double full_turn() + { + return the_angle_style().from_degrees(360.0); + } + + + // clipping is always on + void clip(bool arg) { } + + void clip_box() + { + the_clip_box() = clip_state(); + } + + void clip_box(const P& arg1, const P& arg2) + { + the_clip_box() = clip_state(arg1, arg2); + } + + void clip_to(const P& arg) + { + the_clip_box() = clip_state(P(0,0,0), arg); + } + + void clip_box(const P& arg) + { + the_clip_box() = clip_state(-arg, arg); + } + + // add a clip face; perp points inward + void clip_face(const P& loc, const P& perp) + { + the_clip_box().add_face(loc, perp); + } + + // add parallel clip planes + void clip_slice(const P& loc, const P& perp) + { + the_clip_box().add_face(loc-0.5*EPIX_EPSILON*perp, perp) + .add_face(loc+0.5*EPIX_EPSILON*perp, -perp); + } + + void clip_slice(const P& perp, double thickness) + { + clip_slice(P(0,0,0), perp, thickness); + } + + void clip_slice(const P& perp) + { + clip_slice(P(0,0,0), perp); + } + + void clip_slice(const P& loc, const P& perp, double thickness) + { + the_clip_box().add_face(loc-0.5*thickness*perp, perp) + .add_face(loc+0.5*thickness*perp, -perp); + } + + // remove user-specified clip planes, preserve clip box settings + void clip_restore() + { + the_clip_box().clear_extras(); + } + + + // Set crop state and select region + void set_crop(bool arg) + { + active_screen()->set_crop(arg); + } + + void crop() + { + active_screen()->crop(); + } + + void crop_rectangle(const P& sw, const P& ne) + { + active_screen()->crop_mask_rectangle(sw, ne).set_crop(true); + } + + void crop_ellipse(const P& sw, const P& ne) + { + active_screen()->crop_mask_ellipse(sw, ne).set_crop(true); + } + + void crop_diamond(const P& sw, const P& ne) + { + active_screen()->crop_mask_diamond(sw, ne).set_crop(true); + } + + void crop_rectangle() + { + active_screen()->crop_mask_rectangle().set_crop(true); + } + + void crop_ellipse() + { + active_screen()->crop_mask_ellipse().set_crop(true); + } + + void crop_diamond() + { + active_screen()->crop_mask_diamond().set_crop(true); + } + + + void crop_box(const P& arg1, const P& arg2) + { + active_screen()->crop_mask_rectangle(arg1, arg2).set_crop(true); + } + + void crop_box() // (re)set active crop box to active bounding box + { + active_screen()->crop_mask_rectangle().set_crop(true); + } + + + // Set font size and face, label angle, mask color + void font_size(const std::string& arg) + { + the_label_style().fontsize(arg); + } + + void font_face(const std::string& arg) + { + the_label_style().fontface(arg); + } + + void label_color(const Color& col) + { + the_label_style().text_color(col); + } + + void label_angle(double th) + { + the_label_style().label_angle(th); + } + + void label_mask(const Color& arg) + { + the_label_style().mask_color(arg); + } + + void label_mask() + { + the_label_style().mask_color(White()); + } + + void label_pad(std::string len) + { + the_label_style().label_padding(length(len)); + } + + void label_border(const Color& col, double len) + { + the_label_style().label_border(pen_data(col, length(len))); + } + + void label_border(const Color& col, std::string len) + { + the_label_style().label_border(pen_data(col, len)); + } + + // set color only + void label_border(const Color& col) + { + length len(the_label_style().label_border().width()); + the_label_style().label_border(pen_data(col, len)); + } + + // set width only + void label_border(double len) + { + Color col(the_label_style().label_border().color()); + the_label_style().label_border(pen_data(col, length(len))); + } + + void label_border(std::string len) + { + Color col(the_label_style().label_border().color()); + the_label_style().label_border(pen_data(col, len)); + } + + void no_label_border() + { + label_border("0pt"); + } + + + // Gray depth, path filling, [fill color] + void gray(double depth) + { + the_paint_style().fill_color(Black(depth)); + } + + // new function + void fill(const Color& col) + { + the_paint_style().fill_color(col); + the_paint_style().fill_flag(!col.is_unset()); + } + + void fill(bool arg) + { + the_paint_style().fill_flag(arg); + if (arg && the_paint_style().fill_color().is_unset()) + the_paint_style().fill_color(White()); + } + + void nofill() + { + the_paint_style().fill_flag(false); + } + + + // Arrowhead parameters + void arrow_width(double w) + { + the_arrowhead_style().width(w); + } + + void arrow_ratio(double r) + { + the_arrowhead_style().ratio(r); + } + + void arrow_inset(double arg) + { + the_arrowhead_style().inset(arg); + } + + void arrow_fill(bool fill) + { + the_arrowhead_style().fill(fill); + } + + + // Set (approximate) length of dashes, dot separation + void dash_size(double len) + { + the_path_style().separation(len); + } + + void dot_sep(double len) + { + dash_size(len); + } + + // Dot/box marker size + void dot_size(double diam) + { + the_mark_size().dot_size(diam); + } + + void tick_size(double len) + { + the_mark_size().tick_size(len); + } + + // Line style + void line_style(std::string style) + { + the_path_style() = path_state(style); + } + + void solid() + { + line_style("-"); + } + + void dashed() + { + line_style("- -"); + } + + void dotted() + { + line_style(" . "); + } + + + // Line width + void pen(const std::string& len) + { + the_paint_style().line_width(length(len)); + } + + void pen(double wd) + { + the_paint_style().line_width(length(wd)); + } + + + void bbold() + { + the_paint_style().line_width(BBOLD_WIDTH); + } + + void bold() + { + the_paint_style().line_width(BOLD_WIDTH); + } + + void plain() + { + the_paint_style().line_width(PLAIN_WIDTH); + } + + // line width and color + void bbold(const Color& col) + { + the_paint_style().line_color(col); + the_paint_style().line_width(BBOLD_WIDTH); + } + + void bold(const Color& col) + { + the_paint_style().line_color(col); + the_paint_style().line_width(BOLD_WIDTH); + } + + void plain(const Color& col) + { + the_paint_style().line_color(col); + the_paint_style().line_width(PLAIN_WIDTH); + } + + void pen(const Color& col) + { + the_paint_style().line_color(col); + } + void pen(const Color& col, double len) + { + the_paint_style().line_color(col); + the_paint_style().line_width(length(len)); + } + void pen(const Color& col, std::string len) + { + the_paint_style().line_color(col); + the_paint_style().line_width(length(len)); + } + + // base width and color + void base(const Color& col) + { + the_paint_style().base_color(col); + } + void base(const Color& col, double len) + { + the_paint_style().base_color(col); + the_paint_style().base_width(length(len)); + } + void base(const Color& col, std::string len) + { + the_paint_style().base_color(col); + the_paint_style().base_width(length(len)); + } + + + // Red-Blue-Green + void rgb(double r, double g, double b) + { + the_paint_style().line_color(RGB(r, g, b)); + the_paint_style().fill_color(RGB(r, g, b)); + the_label_style().text_color(RGB(r, g, b)); + } + + // Cyan-Magenta-Yellow-Black + void cmyk(double c, double m, double y, double k) + { + the_paint_style().line_color(CMYK(c, m, y, k)); + the_paint_style().fill_color(CMYK(c, m, y, k)); + the_label_style().text_color(CMYK(c, m, y, k)); + } + + void rgb(const P& arg) + { + rgb(arg.x1(), arg.x2(), arg.x3()); + } + + void cmyk(const P& arg) + { + cmyk(arg.x1(), arg.x2(), arg.x3(), 0); + } + + // primary colors + void red(double d) + { + rgb(d,0,0); + } + void green(double d) + { + rgb(0,d,0); + } + void blue(double d) + { + rgb(0,0,d); + } + void white(double d) + { + rgb(d,d,d); + } + void black(double d) + { + rgb(1-d,1-d,1-d); + } + + void cyan(double d) + { + cmyk(d,0,0,0); + } + void magenta(double d) + { + cmyk(0,d,0,0); + } + void yellow(double d) + { + cmyk(0,0,d,0); + } +} // end of namespace diff --git a/graphics/epix/state.h b/graphics/epix/state.h new file mode 100644 index 0000000000..207a39b33e --- /dev/null +++ b/graphics/epix/state.h @@ -0,0 +1,213 @@ +/* + * state.h -- ePiX global functions to control current drawing state + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.22 + * Last Change: September 24, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file contains the (old) user interface governing: + * + * [] Angular mode + * [] Clipping and cropping + * [] Font size and face, label angle, mask color + * [] Gray depth, path filling, fill color + * [] Whether to use PSTricks macros + * [] Arrowhead parameters + * [] Line style, dash length, dot size + * [] Line width + * [] Line/text color + */ + +#ifndef EPIX_STATE +#define EPIX_STATE + +#include <string> + +namespace ePiX { + + class Color; + class P; + + // set camera position + void viewpoint(const P&); + void viewpoint(double, double, double); + + // Set angular mode + void radians(); + void degrees(); + void revolutions(); + + // number of current angle units in one full turn + double full_turn(); + + // set clip box + void clip(bool arg=true); // no effect + void clip_box(); // default (very large) + void clip_box(const P& arg1, const P& arg2); + void clip_to(const P& arg); + void clip_box(const P& arg); + + // add a clip face; perp points inward + void clip_face(const P& loc, const P& perp); + + // add parallel clip planes + void clip_slice(const P& loc, const P& perp); + void clip_slice(const P& loc, const P& perp, double thickness); + + // loc = origin + void clip_slice(const P& perp); + void clip_slice(const P& perp, double thickness); + + // remove user-specified clip planes, preserve clip box settings + void clip_restore(); + + // set flag on active screen; contents unchanged + void set_crop(bool arg=true); + + // crop contents of active screen + void crop(); + + //// New cropping functions //// + // set crop mask of active screen + void crop_rectangle(const P&, const P&); + void crop_ellipse(const P&, const P&); + void crop_diamond(const P&, const P&); + + void crop_rectangle(); + void crop_ellipse(); + void crop_diamond(); + + void crop_box(const P&, const P&); + void crop_box(); // (re)set crop box to bounding box + + // Set label attributes + void font_size(const std::string& arg="nsz"); + void font_face(const std::string& arg="rm"); + + void label_color(const Color&); + + void label_angle(double t=0); + void label_mask(const Color& col); + void label_mask(); + + void label_pad(std::string); + void label_border(const Color&, double); + void label_border(const Color&, std::string); + void label_border(const Color&); + + void label_border(double); + void label_border(std::string); + void no_label_border(); + + // Gray depth, path filling, [fill color] + void gray(double depth=0.3); + void fill(const Color&); // set fill color + void fill(bool arg=true); // set fill flag + void nofill(); + // void fill_color(const std::string& arg); + + // Arrowhead parameters + void arrow_width(double w=3); + void arrow_ratio(double r=5.5); + void arrow_inset(double arg=0); + void arrow_fill(bool arg=true); + + // Dash pattern length + void dash_size(double len=0); + void dot_sep(double len=0); + + // Dot and box marker size + void dot_size(double diam=0); + + // Tick length + void tick_size(double len=0); + + // Line style + void line_style(std::string style="-"); // solid by default + + void solid(); + void dashed(); + void dotted(); + + // Line width + void pen(const std::string&); + void pen(double); + + void bbold(); + void bold(); + void plain(); + + // Line width and color + void bbold(const Color&); + void bold(const Color&); + void plain(const Color&); + + void pen(const Color&); + void pen(const Color&, double); + void pen(const Color&, std::string); + + void base(const Color&); + void base(const Color&, double); + void base(const Color&, std::string); + + // Line and text color + // ePiX provides rgb/cmyk colors via xcolor. The following are equivalent: + // red(); + // rgb(1,0,0); + // + // cmyk(0,1,1,0); is visually equivalent but not the same. + // + // Densities outside the unit interval [0,1] are truncated, e.g., + // rgb(2, -1, 0.3) = rgb(1, 0, 0.3). + + // red-green-blue + void rgb(double r, double g, double b); // must pass args by value + // cyan-magenta-yellow-black + void cmyk(double c, double m, double y, double k); + + // P arguments, for easy function control + void rgb(const P&); + void cmyk(const P&); + + // primary colors + void red(double d=1); + void green(double d=1); + void blue(double d=1); + void white(double d=1); + void black(double d=1); + + void cyan(double d=1); + void magenta(double d=1); + void yellow(double d=1); + +} // end of namespace + +#endif /* EPIX_STATE */ diff --git a/graphics/epix/surface.cc b/graphics/epix/surface.cc new file mode 100644 index 0000000000..0da2210fb6 --- /dev/null +++ b/graphics/epix/surface.cc @@ -0,0 +1,1072 @@ +/* + * surface.cc -- Shaded surface plotting + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.18 + * Last Change: September 14, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <cmath> + +#include "constants.h" +#include "errors.h" + +#include "triples.h" +#include "frame.h" + +#include "camera.h" +#include "Color.h" + +#include "pen_data.h" +#include "state.h" + +#include "domain.h" + +#include "facet.h" +#include "surface.h" + +namespace ePiX { + + typedef std::list<domain>::const_iterator dolci; + + static double id(double x) { return x; } + + scenery::scenery() : m_cull(0) { } + + scenery::scenery(P F(double, double), const domain& R) : m_cull(0) + { + // construct sorted list of facet*s + if (R.dim() != 2) + { + epix_warning("scenery() requires a 2-dimensional domain"); + return; + } + // else may assume dim(R)=2 + + // exactly one test of first three should succeed + if (fabs(R.corner2_x1() - R.corner1_x1()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n2()/R.coarse_n2()); + const unsigned int N2(R.fine_n3()/R.coarse_n3()); + + const double du(R.dx2()); + const double dv(R.dx3()); + + for (int i=0; i<R.coarse_n2(); ++i) + for (int j=0; j<R.coarse_n3(); ++j) + m_data.push_back(new facet(F, + R.corner1_x2() + i*R.step2(), + R.corner1_x3() + j*R.step3(), + du, dv, N1, N2)); + } + + // if dx2() == 0, use (u,v) = (x,z) + else if (fabs(R.corner2_x2() - R.corner1_x2()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n1()/R.coarse_n1()); + const unsigned int N2(R.fine_n3()/R.coarse_n3()); + + const double du(R.dx1()); + const double dv(R.dx3()); + + for (int i=0; i<R.coarse_n1(); ++i) + for (int j=0; j<R.coarse_n3(); ++j) + m_data.push_back(new facet(F, + R.corner1_x1() + i*R.step1(), + R.corner1_x3() + j*R.step3(), + du, dv, N1, N2)); + } + + else if (fabs(R.corner2_x3() - R.corner1_x3()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n1()/R.coarse_n1()); + const unsigned int N2(R.fine_n2()/R.coarse_n2()); + + const double du(R.dx1()); + const double dv(R.dx2()); + + for (int i=0; i<R.coarse_n1(); ++i) + for (int j=0; j<R.coarse_n2(); ++j) + m_data.push_back(new facet(F, + R.corner1_x1() + i*R.step1(), + R.corner1_x2() + j*R.step2(), + du, dv, N1, N2)); + } + + else + { + epix_warning("scenery() internal error!"); + // clean up + for (std::list<facet*>::iterator p=m_data.begin(); + p!=m_data.end(); ++p) + delete *p; + + return; + } + + m_data.sort(by_distance()); + // sort(m_data.begin(), m_data.end(), by_distance()); + } // end of scenery(P F(double, double), const domain& R) + + + scenery::scenery(P F(double, double, double), const domain& R) : m_cull(0) + { + if (R.dim() != 2) + { + epix_warning("scenery() requires a 2-dimensional domain"); + return; + } + // else may assume dim(R)=2 + + // exactly one test of first three should succeed + if (fabs(R.corner2_x1() - R.corner1_x1()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n2()/R.coarse_n2()); + const unsigned int N2(R.fine_n3()/R.coarse_n3()); + + const double du(R.dx2()); + const double dv(R.dx3()); + + for (int i=0; i<R.coarse_n2(); ++i) + for (int j=0; j<R.coarse_n3(); ++j) + m_data.push_back(new facet(F, + R.corner1_x1(), + R.corner1_x2() + i*R.step2(), + R.corner1_x3() + j*R.step3(), + 0, du, dv, N1, N2)); + } + + // if dx2() == 0, use (u,v) = (x,z) + else if (fabs(R.corner2_x2() - R.corner1_x2()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n1()/R.coarse_n1()); + const unsigned int N2(R.fine_n3()/R.coarse_n3()); + + const double du(R.dx1()); + const double dv(R.dx3()); + + for (int i=0; i<R.coarse_n1(); ++i) + for (int j=0; j<R.coarse_n3(); ++j) + m_data.push_back(new facet(F, + R.corner1_x1() + i*R.step1(), + R.corner1_x2(), + R.corner1_x3() + j*R.step3(), + du, 0, dv, N1, N2)); + } + + else if (fabs(R.corner2_x3() - R.corner1_x3()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n1()/R.coarse_n1()); + const unsigned int N2(R.fine_n2()/R.coarse_n2()); + + const double du(R.dx1()); + const double dv(R.dx2()); + + for (int i=0; i<R.coarse_n1(); ++i) + for (int j=0; j<R.coarse_n2(); ++j) + m_data.push_back(new facet(F, + R.corner1_x1() + i*R.step1(), + R.corner1_x2() + j*R.step2(), + R.corner1_x3(), + du, dv, 0, N1, N2)); + } + + else + { + epix_warning("scenery() internal error!"); + // clean up + for (std::list<facet*>::iterator p=m_data.begin(); + p!=m_data.end(); ++p) + delete *p; + + return; + } + + m_data.sort(by_distance()); + // sort(m_data.begin(), m_data.end(), by_distance()); + } // end of scenery(P F(double, double, double), const domain& R) + + + //// Color-dependent constructors //// + // position-valued color + scenery::scenery(P F(double, double), const domain& R, + P color(double, double, double)) : m_cull(0) + { + // construct sorted list of facet*s + if (R.dim() != 2) + { + epix_warning("scenery() requires a 2-dimensional domain"); + return; + } + // else may assume dim(R)=2 + + // exactly one test of first three should succeed + if (fabs(R.corner2_x1() - R.corner1_x1()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n2()/R.coarse_n2()); + const unsigned int N2(R.fine_n3()/R.coarse_n3()); + + const double du(R.dx2()); + const double dv(R.dx3()); + + for (int i=0; i<R.coarse_n2(); ++i) + for (int j=0; j<R.coarse_n3(); ++j) + { + // use mesh center to approximate facet's location + P posn(F(R.corner1_x2() + (i+0.5)*R.step2(), + R.corner1_x3() + (j+0.5)*R.step3())); + + P col(color(posn.x1(), posn.x2(), posn.x3())); + + m_data.push_back(new facet(F, + R.corner1_x2() + i*R.step2(), + R.corner1_x3() + j*R.step3(), + du, dv, N1, N2, + RGB(col.x1(),col.x2(),col.x3()))); + } + } + + // if dx2() == 0, use (u,v) = (x,z) + else if (fabs(R.corner2_x2() - R.corner1_x2()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n1()/R.coarse_n1()); + const unsigned int N2(R.fine_n3()/R.coarse_n3()); + + const double du(R.dx1()); + const double dv(R.dx3()); + + for (int i=0; i<R.coarse_n1(); ++i) + for (int j=0; j<R.coarse_n3(); ++j) + { + // use mesh center to approximate facet's location + P posn(F(R.corner1_x1() + (i+0.5)*R.step1(), + R.corner1_x3() + (j+0.5)*R.step3())); + + P col(color(posn.x1(), posn.x2(), posn.x3())); + + m_data.push_back(new facet(F, + R.corner1_x1() + i*R.step1(), + R.corner1_x3() + j*R.step3(), + du, dv, N1, N2, + RGB(col.x1(), col.x2(), col.x3()))); + } + } + + else if (fabs(R.corner2_x3() - R.corner1_x3()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n1()/R.coarse_n1()); + const unsigned int N2(R.fine_n2()/R.coarse_n2()); + + const double du(R.dx1()); + const double dv(R.dx2()); + + for (int i=0; i<R.coarse_n1(); ++i) + for (int j=0; j<R.coarse_n2(); ++j) + { + // use mesh center to approximate facet's location + P posn(F(R.corner1_x1() + (i+0.5)*R.step1(), + R.corner1_x2() + (j+0.5)*R.step2())); + + P col(color(posn.x1(), posn.x2(), posn.x3())); + + m_data.push_back(new facet(F, + R.corner1_x1() + i*R.step1(), + R.corner1_x2() + j*R.step2(), + du, dv, N1, N2, + RGB(col.x1(), col.x2(), col.x3()))); + } + } + + else + { + epix_warning("scenery() internal error!"); + // clean up + for (std::list<facet*>::iterator p=m_data.begin(); + p!=m_data.end(); ++p) + delete *p; + + return; + } + + m_data.sort(by_distance()); + // sort(m_data.begin(), m_data.end(), by_distance()); + } // end of scenery(P F(double, double), const domain& R) + + + scenery::scenery(P F(double, double, double), const domain& R, + P color(double, double, double)) : m_cull(0) + { + if (R.dim() != 2) + { + epix_warning("scenery() requires a 2-dimensional domain"); + return; + } + // else may assume dim(R)=2 + + // exactly one test of first three should succeed + if (fabs(R.corner2_x1() - R.corner1_x1()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n2()/R.coarse_n2()); + const unsigned int N2(R.fine_n3()/R.coarse_n3()); + + const double du(R.dx2()); + const double dv(R.dx3()); + + for (int i=0; i<R.coarse_n2(); ++i) + for (int j=0; j<R.coarse_n3(); ++j) + { + // use mesh center to approximate facet's location + P posn(F(R.corner1_x1(), + R.corner1_x2() + (i+0.5)*R.step2(), + R.corner1_x3() + (j+0.5)*R.step3())); + + P col(color(posn.x1(), posn.x2(), posn.x3())); + + m_data.push_back(new facet(F, + R.corner1_x1(), + R.corner1_x2() + i*R.step2(), + R.corner1_x3() + j*R.step3(), + 0, du, dv, N1, N2, + RGB(col.x1(), col.x2(), col.x3()))); + } + } + + // if dx2() == 0, use (u,v) = (x,z) + else if (fabs(R.corner2_x2() - R.corner1_x2()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n1()/R.coarse_n1()); + const unsigned int N2(R.fine_n3()/R.coarse_n3()); + + const double du(R.dx1()); + const double dv(R.dx3()); + + for (int i=0; i<R.coarse_n1(); ++i) + for (int j=0; j<R.coarse_n3(); ++j) + { + P posn(F(R.corner1_x1() + (i+0.5)*R.step1(), + R.corner1_x2(), + R.corner1_x3() + (j+0.5)*R.step3())); + + P col(color(posn.x1(), posn.x2(), posn.x3())); + + m_data.push_back(new facet(F, + R.corner1_x1() + i*R.step1(), + R.corner1_x2(), + R.corner1_x3() + j*R.step3(), + du, 0, dv, N1, N2, + RGB(col.x1(), col.x2(), col.x3()))); + } + } + + else if (fabs(R.corner2_x3() - R.corner1_x3()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n1()/R.coarse_n1()); + const unsigned int N2(R.fine_n2()/R.coarse_n2()); + + const double du(R.dx1()); + const double dv(R.dx2()); + + for (int i=0; i<R.coarse_n1(); ++i) + for (int j=0; j<R.coarse_n2(); ++j) + { + P posn(F(R.corner1_x1() + (i+0.5)*R.step1(), + R.corner1_x2() + (j+0.5)*R.step2(), + R.corner1_x3())); + + P col(color(posn.x1(), posn.x2(), posn.x3())); + + m_data.push_back(new facet(F, + R.corner1_x1() + i*R.step1(), + R.corner1_x2() + j*R.step2(), + R.corner1_x3(), + du, dv, 0, N1, N2, + RGB(col.x1(), col.x2(), col.x3()))); + } + } + + else + { + epix_warning("scenery() internal error!"); + // clean up + for (std::list<facet*>::iterator p=m_data.begin(); + p!=m_data.end(); ++p) + delete *p; + + return; + } + + m_data.sort(by_distance()); + // sort(m_data.begin(), m_data.end(), by_distance()); + } // end of scenery(P F(double, double, double), const domain& R) + + + //// domain-valued color //// + scenery::scenery(P F(double, double), const domain& R, + P color(double, double)) : m_cull(0) + { + // construct sorted list of facet*s + if (R.dim() != 2) + { + epix_warning("scenery() requires a 2-dimensional domain"); + return; + } + // else may assume dim(R)=2 + + // exactly one test of first three should succeed + if (fabs(R.corner2_x1() - R.corner1_x1()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n2()/R.coarse_n2()); + const unsigned int N2(R.fine_n3()/R.coarse_n3()); + + const double du(R.dx2()); + const double dv(R.dx3()); + + for (int i=0; i<R.coarse_n2(); ++i) + for (int j=0; j<R.coarse_n3(); ++j) + { + P col(color(R.corner1_x2() + (i+0.5)*R.step2(), + R.corner1_x3() + (j+0.5)*R.step3())); + + m_data.push_back(new facet(F, + R.corner1_x2() + i*R.step2(), + R.corner1_x3() + j*R.step3(), + du, dv, N1, N2, + RGB(col.x1(),col.x2(),col.x3()))); + } + } + + // if dx2() == 0, use (u,v) = (x,z) + else if (fabs(R.corner2_x2() - R.corner1_x2()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n1()/R.coarse_n1()); + const unsigned int N2(R.fine_n3()/R.coarse_n3()); + + const double du(R.dx1()); + const double dv(R.dx3()); + + for (int i=0; i<R.coarse_n1(); ++i) + for (int j=0; j<R.coarse_n3(); ++j) + { + // use mesh center to approximate facet's location + P col(color(R.corner1_x1() + (i+0.5)*R.step1(), + R.corner1_x3() + (j+0.5)*R.step3())); + + m_data.push_back(new facet(F, + R.corner1_x1() + i*R.step1(), + R.corner1_x3() + j*R.step3(), + du, dv, N1, N2, + RGB(col.x1(), col.x2(), col.x3()))); + } + } + + else if (fabs(R.corner2_x3() - R.corner1_x3()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n1()/R.coarse_n1()); + const unsigned int N2(R.fine_n2()/R.coarse_n2()); + + const double du(R.dx1()); + const double dv(R.dx2()); + + for (int i=0; i<R.coarse_n1(); ++i) + for (int j=0; j<R.coarse_n2(); ++j) + { + // use mesh center to approximate facet's location + P col(color(R.corner1_x1() + (i+0.5)*R.step1(), + R.corner1_x2() + (j+0.5)*R.step2())); + + m_data.push_back(new facet(F, + R.corner1_x1() + i*R.step1(), + R.corner1_x2() + j*R.step2(), + du, dv, N1, N2, + RGB(col.x1(), col.x2(), col.x3()))); + } + } + + else + { + epix_warning("scenery() internal error!"); + // clean up + for (std::list<facet*>::iterator p=m_data.begin(); + p!=m_data.end(); ++p) + delete *p; + + return; + } + + m_data.sort(by_distance()); + // sort(m_data.begin(), m_data.end(), by_distance()); + } // end of scenery(P F(double, double), const domain& R) + + + scenery::scenery(P F(double, double, double), const domain& R, + P color(double, double)) : m_cull(0) + { + if (R.dim() != 2) + { + epix_warning("scenery() requires a 2-dimensional domain"); + return; + } + // else may assume dim(R)=2 + + // exactly one test of first three should succeed + if (fabs(R.corner2_x1() - R.corner1_x1()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n2()/R.coarse_n2()); + const unsigned int N2(R.fine_n3()/R.coarse_n3()); + + const double du(R.dx2()); + const double dv(R.dx3()); + + for (int i=0; i<R.coarse_n2(); ++i) + for (int j=0; j<R.coarse_n3(); ++j) + { + // Color indep of x1 + P col(color(R.corner1_x2() + (i+0.5)*R.step2(), + R.corner1_x3() + (j+0.5)*R.step3())); + + m_data.push_back(new facet(F, + R.corner1_x1(), + R.corner1_x2() + i*R.step2(), + R.corner1_x3() + j*R.step3(), + 0, du, dv, N1, N2, + RGB(col.x1(), col.x2(), col.x3()))); + } + } + + // if dx2() == 0, use (u,v) = (x,z) + else if (fabs(R.corner2_x2() - R.corner1_x2()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n1()/R.coarse_n1()); + const unsigned int N2(R.fine_n3()/R.coarse_n3()); + + const double du(R.dx1()); + const double dv(R.dx3()); + + for (int i=0; i<R.coarse_n1(); ++i) + for (int j=0; j<R.coarse_n3(); ++j) + { + P col(color(R.corner1_x1() + (i+0.5)*R.step1(), + R.corner1_x3() + (j+0.5)*R.step3())); + + m_data.push_back(new facet(F, + R.corner1_x1() + i*R.step1(), + R.corner1_x2(), + R.corner1_x3() + j*R.step3(), + du, 0, dv, N1, N2, + RGB(col.x1(), col.x2(), col.x3()))); + } + } + + else if (fabs(R.corner2_x3() - R.corner1_x3()) <= EPIX_EPSILON) + { + const unsigned int N1(R.fine_n1()/R.coarse_n1()); + const unsigned int N2(R.fine_n2()/R.coarse_n2()); + + const double du(R.dx1()); + const double dv(R.dx2()); + + for (int i=0; i<R.coarse_n1(); ++i) + for (int j=0; j<R.coarse_n2(); ++j) + { + P col(color(R.corner1_x1() + (i+0.5)*R.step1(), + R.corner1_x2() + (j+0.5)*R.step2())); + + m_data.push_back(new facet(F, + R.corner1_x1() + i*R.step1(), + R.corner1_x2() + j*R.step2(), + R.corner1_x3(), + du, dv, 0, N1, N2, + RGB(col.x1(), col.x2(), col.x3()))); + } + } + + else + { + epix_warning("scenery() internal error!"); + // clean up + for (std::list<facet*>::iterator p=m_data.begin(); + p!=m_data.end(); ++p) + delete *p; + + return; + } + + m_data.sort(by_distance()); + // sort(m_data.begin(), m_data.end(), by_distance()); + } // end of scenery(P F(double, double, double), const domain& R) + + + scenery::scenery(const scenery& sc) + : m_cull(sc.m_cull) + { + for (std::list<facet*>::const_iterator p=sc.m_data.begin(); + p!=sc.m_data.end(); ++p) + m_data.push_back((*p)->clone()); + } + + scenery& scenery::operator= (const scenery& sc) + { + if (this != &sc) + { + std::list<facet*> tmp; + // get facets from sc + for (std::list<facet*>::const_iterator p=sc.m_data.begin(); + p!=sc.m_data.end(); ++p) + tmp.push_back((*p)->clone()); + + // free memory + for (std::list<facet*>::iterator p=m_data.begin(); + p!=m_data.end(); ++p) + delete *p; + + swap(m_data, tmp); + + m_cull=sc.m_cull; + } + + return *this; + } + + scenery::~scenery() + { + for (std::list<facet*>::iterator p=m_data.begin(); p!=m_data.end(); ++p) + delete *p; + } + + + scenery& scenery::add(P F(double, double), const domain& R) + { + scenery tmp(F, R); + (*this).m_data.merge(tmp.m_data, by_distance()); + + return *this; + } + + scenery& scenery::add(P F(double, double, double), const domain& R) + { + scenery tmp(F, R); + (*this).m_data.merge(tmp.m_data, by_distance()); + + return *this; + } + + scenery& scenery::add(P F(double, double), const domain_list& DL) + { + for (dolci p=DL.m_list.begin(); p!=DL.m_list.end(); ++p) + { + scenery tmp(F, *p); + (*this).m_data.merge(tmp.m_data, by_distance()); + } + + return *this; + } + + scenery& scenery::add(P F(double, double, double), const domain_list& DL) + { + for (dolci p=DL.m_list.begin(); p!=DL.m_list.end(); ++p) + { + scenery tmp(F, *p); + (*this).m_data.merge(tmp.m_data, by_distance()); + } + + return *this; + } + + + //// Color-dependent versions //// + // position-dependent color + scenery& scenery::add(P F(double, double), const domain& R, + P color(double, double, double)) + { + scenery tmp(F, R, color); + (*this).m_data.merge(tmp.m_data, by_distance()); + + return *this; + } + + scenery& scenery::add(P F(double, double, double), const domain& R, + P color(double, double, double)) + { + scenery tmp(F, R, color); + (*this).m_data.merge(tmp.m_data, by_distance()); + + return *this; + } + + scenery& scenery::add(P F(double, double), const domain_list& DL, + P color(double, double, double)) + { + for (dolci p=DL.m_list.begin(); p!=DL.m_list.end(); ++p) + { + scenery tmp(F, *p, color); + (*this).m_data.merge(tmp.m_data, by_distance()); + } + + return *this; + } + + scenery& scenery::add(P F(double, double, double), const domain_list& DL, + P color(double, double, double)) + { + for (dolci p=DL.m_list.begin(); p!=DL.m_list.end(); ++p) + { + scenery tmp(F, *p, color); + (*this).m_data.merge(tmp.m_data, by_distance()); + } + + return *this; + } + + + //domain-dependent color + scenery& scenery::add(P F(double, double), const domain& R, + P color(double, double)) + { + scenery tmp(F, R, color); + (*this).m_data.merge(tmp.m_data, by_distance()); + + return *this; + } + + scenery& scenery::add(P F(double, double, double), const domain& R, + P color(double, double)) + { + scenery tmp(F, R, color); + (*this).m_data.merge(tmp.m_data, by_distance()); + + return *this; + } + + scenery& scenery::add(P F(double, double), const domain_list& DL, + P color(double, double)) + { + for (dolci p=DL.m_list.begin(); p!=DL.m_list.end(); ++p) + { + scenery tmp(F, *p, color); + (*this).m_data.merge(tmp.m_data, by_distance()); + } + + return *this; + } + + scenery& scenery::add(P F(double, double, double), const domain_list& DL, + P color(double, double)) + { + for (dolci p=DL.m_list.begin(); p!=DL.m_list.end(); ++p) + { + scenery tmp(F, *p, color); + (*this).m_data.merge(tmp.m_data, by_distance()); + } + + return *this; + } + + + scenery& scenery::cull(int c) + { + if (c == 0) + m_cull=0; + else if (c > 0) + m_cull=1; + else + m_cull=-1; + return *this; + } + + void scenery::draw(int cull) const + { + for (std::list<facet*>::const_iterator p=m_data.begin(); + p!=m_data.end(); ++p) + (*p)->draw(cull); + } + + + //// User-accessible functions //// + void surface(P F(double, double), const domain& R, int cull) + { + scenery surf(F, R); + surf.draw(cull); + } + + + // for slices of maps R^3 -> R^3 + void surface(P F(double, double, double), const domain& R, int cull) + { + scenery surf(F, R); + surf.draw(cull); + } + + void surface(P F(double, double, double), const domain_list& R, int cull) + { + scenery tmp; + + for (dolci p= R.m_list.begin(); p!=R.m_list.end(); ++p) + tmp.add(F, *p); + + tmp.draw(cull); + } + + + void surface_rev(double f(double), double g(double), + double min_x, double max_x, int i_max, int j_max, int cull) + { + surface_rev(f, g, + domain(P(min_x, 0), P(max_x, full_turn()), + mesh(i_max, j_max), mesh(i_max, j_max)), frame(), cull); + } + + void surface_rev(double f(double), + double min_x, double max_x, int i_max, int j_max, int cull) + { + surface_rev(id, f, + domain(P(min_x, 0), P(max_x, full_turn()), + mesh(i_max, j_max), mesh(i_max, j_max)), frame(), cull); + } + + void surface_rev(double f(double), double g(double), + const domain& R, const frame& coords, int cull) + { + if (R.dx3() > 0) + epix_warning("surface_rev() ignores domain's third coordinate"); + + std::list<facet*> mesh; + + const unsigned int N1(R.fine_n1()/R.coarse_n1()); + const unsigned int N2(R.fine_n2()/R.coarse_n2()); + const double du(R.dx1()); + const double dv(R.dx2()); + + for (int i=0; i<R.coarse_n1(); ++i) + for (int j=0; j<R.coarse_n2(); ++j) + mesh.push_back(new facet(f, g, + R.corner1_x1() + i*R.step1(), + R.corner1_x2() + j*R.step2(), + du, dv, N1, N2, coords)); + + mesh.sort(by_distance()); + // sort(mesh.begin(), mesh.end(), by_distance()); + + for (std::list<facet*>::iterator p=mesh.begin(); p!=mesh.end(); ++p) + { + (*p)->draw(cull); + delete *p; + } + } + + //// Color-dependent versions //// + // location-dependent color + void surface(P F(double, double), const domain& R, + P color(double, double, double), int cull) + { + scenery surf(F, R, color); + surf.draw(cull); + } + + + // for slices of maps R^3 -> R^3 + void surface(P F(double, double, double), const domain& R, + P color(double, double, double), int cull) + { + scenery surf(F, R, color); + surf.draw(cull); + } + + void surface(P F(double, double, double), const domain_list& R, + P color(double, double, double), int cull) + { + scenery tmp; + + for (dolci p= R.m_list.begin(); p!=R.m_list.end(); ++p) + tmp.add(F, *p, color); + + tmp.draw(cull); + } + + + void surface_rev(double f(double), double g(double), + double min_x, double max_x, int i_max, int j_max, + P color(double, double, double), int cull) + { + surface_rev(f, g, + domain(P(min_x, 0), P(max_x, full_turn()), + mesh(i_max, j_max), mesh(i_max, j_max)), color, + frame(), cull); + } + + void surface_rev(double f(double), + double min_x, double max_x, int i_max, int j_max, + P color(double, double, double), int cull) + { + surface_rev(id, f, + domain(P(min_x, 0), P(max_x, full_turn()), + mesh(i_max, j_max), mesh(i_max, j_max)), color, + frame(), cull); + } + + void surface_rev(double f(double), double g(double), + const domain& R, P color(double, double, double), + const frame& coords, int cull) + { + if (R.dx3() > 0) + epix_warning("surface_rev() ignores domain's third coordinate"); + + std::list<facet*> mesh; + + const unsigned int N1(R.fine_n1()/R.coarse_n1()); + const unsigned int N2(R.fine_n2()/R.coarse_n2()); + const double du(R.dx1()); + const double dv(R.dx2()); + + const double u0(R.corner1_x1()); + const double v0(R.corner1_x2()); + const double DU(R.step1()); + const double DV(R.step2()); + + for (int i=0; i<R.coarse_n1(); ++i) + for (int j=0; j<R.coarse_n2(); ++j) + { + // mesh center approximates facet's location + P posn(f(u0 + (i+0.5)*DU)*coords.sea() + + g(u0 + (i+0.5)*DU)*Cos(v0 + (j+0.5)*DV)*coords.sky() + + g(u0 + (i+0.5)*DU)*Sin(v0 + (j+0.5)*DV)*coords.eye()); + + P col(color(posn.x1(), posn.x2(), posn.x3())); + + mesh.push_back(new facet(f, g, + R.corner1_x1() + i*R.step1(), + R.corner1_x2() + j*R.step2(), + du, dv, N1, N2, + RGB(col.x1(), col.x2(), col.x3()), coords)); + } + + mesh.sort(by_distance()); + // sort(mesh.begin(), mesh.end(), by_distance()); + + for (std::list<facet*>::iterator p=mesh.begin(); p!=mesh.end(); ++p) + { + (*p)->draw(cull); + delete *p; + } + } + + // domain-dependent color + void surface(P F(double, double), const domain& R, + P color(double, double), int cull) + { + scenery surf(F, R, color); + surf.draw(cull); + } + + + // for slices of maps R^3 -> R^3 + void surface(P F(double, double, double), const domain& R, + P color(double, double), int cull) + { + scenery surf(F, R, color); + surf.draw(cull); + } + + void surface(P F(double, double, double), const domain_list& R, + P color(double, double), int cull) + { + scenery tmp; + + for (dolci p= R.m_list.begin(); p!=R.m_list.end(); ++p) + tmp.add(F, *p, color); + + tmp.draw(cull); + } + + + void surface_rev(double f(double), double g(double), + double min_x, double max_x, int i_max, int j_max, + P color(double, double), int cull) + { + surface_rev(f, g, + domain(P(min_x, 0), P(max_x, full_turn()), + mesh(i_max, j_max), mesh(i_max, j_max)), color, + frame(), cull); + } + + void surface_rev(double f(double), + double min_x, double max_x, int i_max, int j_max, + P color(double, double), int cull) + { + surface_rev(id, f, + domain(P(min_x, 0), P(max_x, full_turn()), + mesh(i_max, j_max), mesh(i_max, j_max)), color, + frame(), cull); + } + + void surface_rev(double f(double), double g(double), + const domain& R, P color(double, double), + const frame& coords, int cull) + { + if (R.dx3() > 0) + epix_warning("surface_rev() ignores domain's third coordinate"); + + std::list<facet*> mesh; + + const unsigned int N1(R.fine_n1()/R.coarse_n1()); + const unsigned int N2(R.fine_n2()/R.coarse_n2()); + const double du(R.dx1()); + const double dv(R.dx2()); + + const double u0(R.corner1_x1()); + const double v0(R.corner1_x2()); + const double DU(R.step1()); + const double DV(R.step2()); + + for (int i=0; i<R.coarse_n1(); ++i) + for (int j=0; j<R.coarse_n2(); ++j) + { + // mesh center approximates facet's location + P posn(f(u0 + (i+0.5)*DU)*coords.sea() + + g(u0 + (i+0.5)*DU)*Cos(v0 + (j+0.5)*DV)*coords.sky() + + g(u0 + (i+0.5)*DU)*Sin(v0 + (j+0.5)*DV)*coords.eye()); + + P col(color(u0 + (i+0.5)*DU, v0 + (j+0.5)*DV)); + + mesh.push_back(new facet(f, g, + R.corner1_x1() + i*R.step1(), + R.corner1_x2() + j*R.step2(), + du, dv, N1, N2, + RGB(col.x1(), col.x2(), col.x3()), coords)); + } + + mesh.sort(by_distance()); + // sort(mesh.begin(), mesh.end(), by_distance()); + + for (std::list<facet*>::iterator p=mesh.begin(); p!=mesh.end(); ++p) + { + (*p)->draw(cull); + delete *p; + } + } +} // end of namespace diff --git a/graphics/epix/surface.h b/graphics/epix/surface.h new file mode 100644 index 0000000000..9c5be67a0c --- /dev/null +++ b/graphics/epix/surface.h @@ -0,0 +1,194 @@ +/* + * surface.h -- Shaded surface plotting + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.7 + * Last Change: July 08, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <list> + +#include "triples.h" +#include "frame.h" + +#include "path.h" + +namespace ePiX +{ + class domain; + class domain_list; + class facet; + + // manipulable collection of surface-like objects + class scenery { + public: + scenery(); + scenery(P F(double, double), const domain& R); + scenery(P F(double, double, double), const domain& R); + + // third arg is RGB-valued function of position + scenery(P F(double, double), const domain& R, + P color(double, double, double)); + + scenery(P F(double, double, double), const domain& R, + P color(double, double, double)); + + // third arg is RGB-valued function of domain location + scenery(P F(double, double), const domain& R, + P color(double, double)); + + scenery(P F(double, double, double), const domain& R, + P color(double, double)); + + scenery(const scenery&); + scenery& operator= (const scenery&); + ~scenery(); + + scenery& add(P F(double, double), const domain& R); + scenery& add(P F(double, double, double), const domain& R); + + scenery& add(P F(double, double), const domain_list&); + scenery& add(P F(double, double, double), const domain_list&); + + // color-dependent + // location-colored + scenery& add(P F(double, double), const domain& R, + P color(double, double, double)); + scenery& add(P F(double, double, double), const domain& R, + P color(double, double, double)); + + scenery& add(P F(double, double), const domain_list&, + P color(double, double, double)); + scenery& add(P F(double, double, double), const domain_list&, + P color(double, double, double)); + + // domain-colored + scenery& add(P F(double, double), const domain& R, + P color(double, double)); + scenery& add(P F(double, double, double), const domain& R, + P color(double, double)); + + scenery& add(P F(double, double), const domain_list&, + P color(double, double)); + scenery& add(P F(double, double, double), const domain_list&, + P color(double, double)); + + // remove backward-pointing faces? 0=no, -1=front, 1=back + scenery& cull(int); + void draw(int cull=0) const; + + private: + int m_cull; + + std::list<facet*> m_data; + }; // end of class scenery + + + //// global functions //// + // except as noted, dim(R) must be 2 + // cosine-shaded surface with fake z-buffered hidden object removal + void surface(P F(double, double), const domain& R, int cull=0); + + // for slices of maps R^3 -> R^3 + void surface(P F(double, double, double), const domain& R, int cull=0); + + // plot multiple slices + void surface(P F(double, double, double), const domain_list& R, int cull=0); + + // Surface from revolving the curve (f(t),g(t)) about the x-axis... + void surface_rev(double f(double), double g(double), + double t_min, double t_max, + int latitudes, int longitudes=24, int cull=0); + + void surface_rev(double f(double), + double t_min, double t_max, + int latitudes, int longitudes=24, int cull=0); + + // or about the specified axis, with specified angle range + void surface_rev(double f(double), double g(double), + const domain& R, const frame& coords=frame(), int cull=0); + + + + //// location-colored versions //// + void surface(P F(double, double), const domain& R, + P color(double, double, double), int cull=0); + + // for slices of maps R^3 -> R^3 + void surface(P F(double, double, double), const domain& R, + P color(double, double, double), int cull=0); + + // plot multiple slices + void surface(P F(double, double, double), const domain_list& R, + P color(double, double, double), int cull=0); + + // Surface from revolving the curve (f(t),g(t)) about the x-axis... + void surface_rev(double f(double), double g(double), + double t_min, double t_max, + int latitudes, int longitudes, + P color(double, double, double), int cull=0); + + void surface_rev(double f(double), + double t_min, double t_max, + int latitudes, int longitudes, + P color(double, double, double), int cull=0); + + // or about the specified axis, with specified angle range + void surface_rev(double f(double), double g(double), + const domain& R, P color(double, double, double), + const frame& coords=frame(), int cull=0); + + + //// domain-colored versions //// + void surface(P F(double, double), const domain& R, + P color(double, double), int cull=0); + + // for slices of maps R^3 -> R^3 + void surface(P F(double, double, double), const domain& R, + P color(double, double), int cull=0); + + // plot multiple slices + void surface(P F(double, double), const domain_list& R, + P color(double, double, double), int cull=0); + + // Surface from revolving the curve (f(t),g(t)) about the x-axis... + void surface_rev(double f(double), double g(double), + double t_min, double t_max, + int latitudes, int longitudes, + P color(double, double), int cull=0); + + void surface_rev(double f(double), + double t_min, double t_max, + int latitudes, int longitudes, + P color(double, double), int cull=0); + + // or about the specified axis, with specified angle range + void surface_rev(double f(double), double g(double), + const domain& R, P color(double, double), + const frame& coords=frame(), int cull=0); +} // end of namespace ePiX diff --git a/graphics/epix/tikz.cc b/graphics/epix/tikz.cc new file mode 100644 index 0000000000..b28a4832e4 --- /dev/null +++ b/graphics/epix/tikz.cc @@ -0,0 +1,312 @@ +/* + * tikz.cc -- ePiX::tikz output format + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.15 + * Last Change: September 07, 2007 + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <list> + +#include <string> +#include <sstream> + +#include <set> + +#include "constants.h" + +#include "utils.h" + +#include "pairs.h" +#include "edge_data.h" + +#include "Color.h" + +#include "path_style.h" +#include "pen_data.h" + +// need to get units from the_picture +#include "picture_data.h" +#include "picture.h" + +#include "format.h" +#include "tikz.h" + +namespace ePiX { + + tikz::tikz() + : m_fill(Neutral()), m_stroke(Black()), m_lwidth(PLAIN_WIDTH), + m_units(the_picture().the_unitlength.units()) { } + + + tikz* tikz::clone() const + { + return new tikz(*this); + } + + // Filled region with specified Cartesian edges, offset, and color + std::string tikz::print_fill(const std::list<edge2d>& edges, + const pair& offset, + const Color& fc, + const pen_data& line, + const std::string& len) const + { + std::stringstream obuf; + obuf << set_fill_state(fc) << set_pen_state(line); + + // compute attribute string + std::stringstream attribs; + + if ( !(fc.is_unset()) ) + { + attribs << "[fill"; + + if (fc.alpha() < 1) + attribs << ",opacity=" << fc.alpha(); + + attribs << "]"; + } + + obuf << print_paths(edges, offset, attribs.str(), len); + + return obuf.str(); + } + + // Unfilled region, specified Cartesian edges + std::string tikz::print_line(const std::list<edge2d>& edges, + const pair& offset, + const pen_data& line, + const pen_data& base, + const path_state& style, + const std::string& len) const + { + std::string value; + + // draw *solid* base first + if (line.width() < base.width() && !base.color().is_unset()) + { + std::stringstream battr; + battr << "[color=" << format::print(base.color()) << "," + << "line width=" << format::print(base.width()) << "]"; + + value += format::print_line(edges, offset, base, path_state(), + battr.str(), len); + } + + value += set_pen_state(line); + + return value += format::print_line(edges, offset, line, style, "", len); + } + + // Print color declaration strings: model, name, densities + std::string tikz::print_color(const std::string& model, + const std::string& name, + double d1, double d2, + double d3) const + { + return format::xdefinecolor(model, name, d1, d2, d3); + } + + std::string tikz::print_color(const std::string& model, + const std::string& name, + double d1, double d2, + double d3, double d4) const + { + return format::xdefinecolor(model, name, d1, d2, d3, d4); + } + + + // One-line comment + std::string tikz::print_comment(const std::string& msg) const + { + std::stringstream obuf; + obuf << "%% " << msg << std::endl; + + return obuf.str(); + } + + // verbatim string, newline protected + std::string tikz::print_verbatim(const std::string& msg) const + { + std::stringstream obuf; + obuf << msg << "%" << std::endl; + + return obuf.str(); + } + + + // start/end a picture-like environment, set unit length + std::string tikz::start_picture(const pair& sz, const pair& offset) const + { + std::stringstream obuf; + obuf << "\\begin{tikzpicture}" << std::endl + << "\\pgfsetlinewidth{" << format::print(PLAIN_WIDTH) << "}" + << std::endl + << "\\useasboundingbox " << print(offset) + << " rectangle " << print(sz + offset) << ";" + << std::endl; + + return obuf.str(); + } + + std::string tikz::end_picture() const + { + std::stringstream obuf; + obuf << "\\end{tikzpicture}" << std::endl; + + return obuf.str(); + } + + // Actual work done in start_picture + std::string tikz::set_unitlength(const std::string& len) const + { + return ""; + /* + std::stringstream obuf; + + obuf << "\\setlength{\\unitlength}{1" << len << "}%" << std::endl; + + return obuf.str(); + */ + } + + + void tikz::reset_state() const + { + m_fill = Neutral(); + m_stroke = Black(); + m_lwidth = PLAIN_WIDTH; + } + + //// private member functions //// + std::string tikz::path_connector() const + { + return "--"; + } + + + std::string tikz::usepackages() const + { + return "usepackages tikz"; + } + + // string argument for passing attributes local to this path/loop + std::string tikz::start_open_path(const std::string& attribs) const + { + return "\\draw " + attribs; + } + + std::string tikz::end_open_path(const std::string&) const + { + std::stringstream obuf; + obuf << ";" << std::endl; + + return obuf.str(); + } + + std::string tikz::start_closed_path(const std::string& attribs) const + { + return "\\draw " + attribs; + } + + std::string tikz::end_closed_path(const std::string&) const + { + std::stringstream obuf; + obuf << "--cycle;" << std::endl; + + return obuf.str(); + } + + // print declarations to set state of output format + std::string tikz::set_fill_state(const Color& col) const + { + std::stringstream buf; + if (col != m_fill && !col.is_unset()) + buf << "\\pgfsetfillcolor{" << format::print(col) << "}" << std::endl; + + m_fill = col; + return buf.str(); + } + + std::string tikz::set_pen_state(const pen_data& pen) const + { + std::stringstream buf; + if (pen.color() != m_stroke) + { + buf << "\\pgfsetstrokecolor{" << format::print(pen.color()) << "}" + << std::endl; + + m_stroke = pen.color(); + } + + if (pen.width() != m_lwidth) + { + buf << "\\pgfsetlinewidth{" << format::print(pen.width()) << "}" + << std::endl; + + m_lwidth = pen.width(); + } + + return buf.str(); + } + + // place a LaTeX box of width zero (containing string) at location (pair) + std::string tikz::put_box(const pair& loc, const std::string& msg) const + { + std::stringstream obuf; + + obuf << "\\pgftext[at={\\pgfpoint{" + << truncate(loc.x1()) << m_units << "}{" + << truncate(loc.x2()) << m_units + << "}}] {" << msg << "}" << std::endl; + + return obuf.str(); + } + + std::string tikz::print_circle_marker(const pair& here, double diam, + bool fill, const Color& color, + const std::string& len) const + { + std::stringstream obuf; + obuf << "\\"; + + if (fill) + obuf << "fill"; + + obuf << "draw[color=" << format::print(color) << "] " + << print(here) << " circle(" << 0.5*diam << len << ");" << std::endl; + + return obuf.str(); + } + + std::string tikz::print(const pair& arg) const + { + std::stringstream o; + o << "(" << truncate(arg.x1()) << m_units + << "," << truncate(arg.x2()) << m_units << ")"; + return o.str(); + } +} // end of namespace diff --git a/graphics/epix/tikz.h b/graphics/epix/tikz.h new file mode 100644 index 0000000000..e437edb122 --- /dev/null +++ b/graphics/epix/tikz.h @@ -0,0 +1,152 @@ +/* + * tikz.h -- ePiX::tikz output format + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.15 + * Last Change: September 07, 2007 + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_TIKZ +#define EPIX_TIKZ + +#include <set> +#include <list> +#include <string> + +#include "edge_data.h" + +namespace ePiX { + + class Color; + class pair; + class path_state; + class pen_data; + + class tikz : public format { + public: + tikz(); + + // Return a copy of this + tikz* clone() const; + + // Filled region with specified Cartesian edges, offset, and color + std::string print_fill(const std::list<edge2d>& edges, + const pair& offset, + const Color& fill, + const pen_data& line, + const std::string& len) const; + + // Unfilled region, specified Cartesian edges. Should generally be + // trivially implemented using one-pen function (supplied). + std::string print_line(const std::list<edge2d>& edges, + const pair& offset, + const pen_data& line_pen, + const pen_data& base_pen, + const path_state& style, + const std::string& len) const; + + /* + * Picture start and finish: + * Size and offset in page units, + * pallet (set of colors contained in the screen), + * unitlength + * + * These functions have default implementations, see format.cc. + * If the new format can use the default implementation, these + * functions declarations should be removed. + * + std::string pic_header(const pair& sizes, + const pair& offsets, + const std::set<Color>& pallet, + const std::string& len) const; + + std::string pic_footer() const; + */ + + // Print color declaration strings: model, name, densities + std::string print_color(const std::string&, + const std::string&, + double, + double, + double) const; + + std::string print_color(const std::string&, + const std::string&, + double, + double, + double, + double) const; + + // One-line comment + std::string print_comment(const std::string&) const; + + // Verbatim output + std::string print_verbatim(const std::string&) const; + + + // begin and end a picture-like environment, set the unit length + std::string start_picture(const pair&, const pair&) const; + std::string end_picture() const; + + std::string set_unitlength(const std::string& len) const; + + // State data, if any, must be mutable + void reset_state() const; + + private: + mutable Color m_fill; + mutable Color m_stroke; + mutable length m_lwidth; + + std::string m_units; + + // override: inserted between path points + std::string path_connector() const; + + std::string usepackages() const; + + // string argument for passing attributes local to this path/loop + std::string start_open_path(const std::string&) const; + std::string end_open_path(const std::string&) const; + + std::string start_closed_path(const std::string&) const; + std::string end_closed_path(const std::string&) const; + + // print declarations to set state of output format + std::string set_fill_state(const Color&) const; + std::string set_pen_state(const pen_data&) const; + + // place a LaTeX box of width zero (containing string) at location (pair) + std::string put_box(const pair&, const std::string&) const; + + std::string print_circle_marker(const pair& here, double diam, + bool fill, const Color& color, + const std::string& len) const; + + std::string print(const pair&) const; // override base class, print units + }; // end of class tikz +} // end of namespace + +#endif /* EPIX_TIKZ */ diff --git a/graphics/epix/tile.cc b/graphics/epix/tile.cc new file mode 100644 index 0000000000..a7717a818c --- /dev/null +++ b/graphics/epix/tile.cc @@ -0,0 +1,38 @@ +/* + * tile.cc -- ePiX::tile destructor + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.0.23 + * Last Change: January 14, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "tile.h" + +namespace ePiX { + tile::~tile() { } + +} // end of namespace diff --git a/graphics/epix/tile.h b/graphics/epix/tile.h new file mode 100644 index 0000000000..da4639e694 --- /dev/null +++ b/graphics/epix/tile.h @@ -0,0 +1,62 @@ +/* + * tile.h -- ePiX::screen object base class (tile) + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.0.23 + * Last Change: January 14, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef EPIX_TILE +#define EPIX_TILE + +#include <string> + +namespace ePiX { + + class format; + class length; + class affine; + class screen; + class screen_mask; + + class tile { + public: + virtual ~tile(); + + virtual tile* clone() const = 0; + virtual tile& map_by(const affine&) = 0; + virtual tile& crop_to(const screen_mask&) = 0; + + virtual bool is_empty() const = 0; + + // pass length for (e.g.) dash length, marker size + virtual std::string print_to(const format&, const std::string&) const = 0; + virtual void add_to_pallet() const = 0; + }; // end of class tile + +} // end of namespace + +#endif /* EPIX_TILE */ diff --git a/graphics/epix/triples.cc b/graphics/epix/triples.cc new file mode 100644 index 0000000000..f62076d4f7 --- /dev/null +++ b/graphics/epix/triples.cc @@ -0,0 +1,211 @@ +/* + * triples.cc -- ePiX::P class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.9 + * Last Change: August 01, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <cmath> + +#include "constants.h" +#include "errors.h" +#include "triples.h" + +namespace ePiX { + + P::P(double arg1, double arg2, double arg3) + : m_x1(arg1), m_x2(arg2), m_x3(arg3) { } + + double P::x1() const + { + return m_x1; + } + + double P::x2() const + { + return m_x2; + } + + double P::x3() const + { + return m_x3; + } + + bool P::is_valid() const + { + using std::isnan; + using std::isinf; + + return + !isinf(m_x3) && !isnan(m_x3) + && !isinf(m_x2) && !isnan(m_x2) + && !isinf(m_x1) && !isnan(m_x1) + && m_x1*m_x1 + m_x2*m_x2 + m_x3*m_x3 < EPIX_INFTY; + } + + // increment operators + P& P::operator += (const P& arg) + { + m_x1 += arg.m_x1; + m_x2 += arg.m_x2; + m_x3 += arg.m_x3; + + return *this; + } + + P& P::operator -= (const P& arg) + { + m_x1 -= arg.m_x1; + m_x2 -= arg.m_x2; + m_x3 -= arg.m_x3; + + return *this; + } + + // scalar multipication + P& P::operator *= (double c) + { + m_x1 *= c; + m_x2 *= c; + m_x3 *= c; + + return *this; + } + + // cross product + P& P::operator *= (const P& v) + { + P temp(*this); + + m_x1 = (temp.m_x2 * v.m_x3 - temp.m_x3 * v.m_x2); + m_x2 = (temp.m_x3 * v.m_x1 - temp.m_x1 * v.m_x3); + m_x3 = (temp.m_x1 * v.m_x2 - temp.m_x2 * v.m_x1); + + return *this; + } + + // componentwise product + P& P::operator &= (const P& v) + { + m_x1 *= v.m_x1; + m_x2 *= v.m_x2; + m_x3 *= v.m_x3; + + return *this; + } + + // orthogonalization: u %= v is the vector of the form u-k*v perp to v + P& P::operator%= (const P& v) + { + double denom(v.m_x1*v.m_x1 + v.m_x2*v.m_x2 + v.m_x3*v.m_x3); + if (denom < EPIX_EPSILON) + { + epix_warning("Orthogonalizing by zero vector, no action"); + return *this; + } + + // else c=(u|v)/(v|v) + double c((m_x1*v.m_x1 + m_x2*v.m_x2 + m_x3*v.m_x3)/denom); + + m_x1 -= c*v.m_x1; + m_x2 -= c*v.m_x2; + m_x3 -= c*v.m_x3; + + return *this; + } + // end of class functions + + // vector space operations + P operator- (P u) + { + return u *= -1; + } + + P operator+ (P u, const P& v) + { + return u += v; + } + + P operator- (P u, const P& v) + { + return u -= v; + } + + // scalar multiplication + P operator* (double c, P v) + { + return v *= c; + } + + // cross product + P operator* (P u, const P& v) + { + return u *= v; + } + + P J(P arg) + { + // E_3 * arg, but E_3 is const + return arg *= -E_3; + } + + // dot product + double operator | (const P& u, const P& v) + { + return u.x1()*v.x1() + u.x2()*v.x2() + u.x3()*v.x3(); + } + + double norm(const P& u) + { + return sqrt(u|u); + } + + // componentwise product (a,b,c)&(x,y,z)=(ax,by,cz) + P operator& (P u, const P& v) + { + return u &= v; + } + + P operator% (P u, const P& v) + { + return u %= v; + } + + // (in)equality + bool operator == (const P& u, const P& v) + { + return (norm(u-v) < EPIX_EPSILON); + } + + bool operator != (const P& u, const P& v) + { + return !(u==v); + } +} // end of namespace diff --git a/graphics/epix/triples.h b/graphics/epix/triples.h new file mode 100644 index 0000000000..54f5c5581b --- /dev/null +++ b/graphics/epix/triples.h @@ -0,0 +1,115 @@ +/* + * triples.h -- ePiX::P class + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.10 + * Last Change: August 04, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * This file provides: + * + * The P class (ordered triple of <double>s) and operators + * + * - P(), P() (default to origin), E_1, E_2, E_3 (standard basis) + * - Vector space operators + * - Other vector operators, operands (a,b,c), (x,y,z) + * | dot product ax + by + cz + * norm(p) = sqrt(p|p) + * & componentwise product (ax, by, cz) + * * cross product (bz-cy, cx-az, ay-bx) + * J rotate (x1,x2,0)-plane 1/4 turn (-b,a,0) + * % orthogonalization u%v = u - ((u|v)/(v|v))*v + */ +#ifndef EPIX_TRIPLES +#define EPIX_TRIPLES + +namespace ePiX { + + class P { + public: + P(double arg1=0, double arg2=0, double arg3=0); + + double x1() const; + double x2() const; + double x3() const; + + bool is_valid() const; // coords not inf or nan + + // increment operators + P& operator += (const P&); + P& operator -= (const P&); + P& operator *= (double); // scalar multipication + + // cross product + P& operator *= (const P&); + + // componentwise product + P& operator &= (const P&); + + // orthogonalization: u %= v is the vector of the form u-k*v perp to v + P& operator %= (const P&); + + private: + double m_x1, m_x2, m_x3; + }; // end of class P + + + // standard basis in global namespace + const P E_1(1,0,0); + const P E_2(0,1,0); + const P E_3(0,0,1); + + // vector space operations + P operator- (P u); // unary negation + P operator+ (P u, const P& v); + P operator- (P u, const P& v); + // scalar multiplication + P operator* (double c, P v); + + // cross product + P operator* (P, const P&); + P J(P); // quarter turn about E_3-axis + + // dot product + double operator | (const P&, const P&); + double norm(const P&); + + // componentwise product (a,b,c)&(x,y,z)=(ax,by,cz) + P operator& (P, const P&); + // orthogonalization + P operator% (P, const P&); + + // (in)equality + bool operator == (const P&, const P&); + bool operator != (const P&, const P&); + +} // end of namespace + +#endif /* EPIX_TRIPLES */ diff --git a/graphics/epix/utils.cc b/graphics/epix/utils.cc new file mode 100644 index 0000000000..2b57ddf1ea --- /dev/null +++ b/graphics/epix/utils.cc @@ -0,0 +1,124 @@ +/* + * utils.cc -- global utility functions for ePiX + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.18 + * Last Change: September 15, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <string> +#include <cmath> +#include <ctime> + +#include "constants.h" +#include "utils.h" + +namespace ePiX { + + const std::string epix_version() + { + return "1.2.1"; + } + + double truncate(double arg) + { + return fabs(arg) < EPIX_EPSILON ? 0 : arg; + } + + std::string date_and_time() + { + ////// N.B.: Revise this if time format string changes! + const int max_len = 31; + char buf[max_len]; + time_t t=time(0); + + // strftime(buf, max_len, "%c", localtime(&t)); + + // Sat Jul 1 23:25:39 2006 (GMT) + strftime(buf, max_len, "%a %b %d %X %Y (%Z)", gmtime(&t)); + return std::string(buf); + } + + + // remove everything from arg except chars in srch + std::string get_chars(std::string arg, const std::string& srch) + { + std::string::size_type curr(0); + std::string::size_type next(arg.find_first_of(srch)); + + while (next != std::string::npos) + { + arg.erase(curr, next-curr); + + curr = arg.find_first_not_of(srch); + next = arg.find_first_of(srch, curr); + } + + if (next != curr) + arg.erase(curr, next); + + return arg; + } + + // add linebreaks before opening parentheses to make lines at most + // FILE_WIDTH characters long; return reference to arg + std::string break_lines(std::string arg, const std::string& path_break) + { + std::string value; // append here; swap with arg at end + + // initialize markers prev, curr, next + std::string::size_type prev(0); // position of last line break + std::string::size_type next(arg.find_first_of("(")); + std::string::size_type curr(next); + + unsigned int pbk_sz(path_break.size()); + + while (next != std::string::npos) + { + // seek next break points + while (next-prev <= EPIX_FILE_WIDTH - pbk_sz) + { + curr = next; + next = arg.find_first_of("(", ++next); + } + + value.append(arg, prev, curr-prev); // append current line + // Magic number 20 (greater than width of a printed pair) + if (next - prev <= 20+EPIX_FILE_WIDTH) // not at end of data + value += path_break; // and formatting string + prev = curr; // update front of line + } + + // get remaining characters + value.append(arg, prev, next-prev); + + swap(arg, value); + return arg; + } +} // end of namespace diff --git a/graphics/epix/utils.h b/graphics/epix/utils.h new file mode 100644 index 0000000000..018efcdfca --- /dev/null +++ b/graphics/epix/utils.h @@ -0,0 +1,56 @@ +/* + * utils.h -- global utility functions for ePiX + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.18 + * Last Change: September 15, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_UTILS +#define EPIX_UTILS + +#include <string> + +namespace ePiX { + + const std::string epix_version(); + + double truncate(double); // return 0 if fabs(arg) < epsilon + + // print GMT string for file header + std::string date_and_time(); + + // remove everything from arg except chars in srch + std::string get_chars(std::string arg, const std::string& srch); + + // Use break to split arg into lines of at most FILE_WIDTH characters, + // return mangled copy of arg + std::string break_lines(std::string arg, const std::string& break_str); +} +#endif /* EPIX_UTILS */ diff --git a/graphics/epix/verbatim.cc b/graphics/epix/verbatim.cc new file mode 100644 index 0000000000..8f7df3b3fb --- /dev/null +++ b/graphics/epix/verbatim.cc @@ -0,0 +1,80 @@ +/* + * verbatim.cc -- ePiX screen implemenation for verbatim text + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.7 + * Last Change: July 14, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <sstream> + +#include "format.h" +#include "verbatim.h" + +namespace ePiX { + + class affine; + class screen_mask; + + verbatim::verbatim(const std::string& text) : m_text(text) + { + } + + verbatim& verbatim::map_by(const affine& f) + { + return *this; + } + + verbatim& verbatim::crop_to(const screen_mask& M) + { + return *this; + } + + verbatim* verbatim::clone() const + { + return new verbatim(*this); + } + + bool verbatim::is_empty() const + { + return (m_text == ""); + } + + std::string verbatim::print_to(const format& fmt, const std::string& L) const + { + if (is_empty()) + return ""; + + // else + return fmt.print_verbatim(m_text); + } + + void verbatim::add_to_pallet() const { } +} // end of namespace + diff --git a/graphics/epix/verbatim.h b/graphics/epix/verbatim.h new file mode 100644 index 0000000000..39b2d3b9d5 --- /dev/null +++ b/graphics/epix/verbatim.h @@ -0,0 +1,66 @@ +/* + * verbatim.h -- ePiX screen implemenation of verbatim text + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.1.7 + * Last Change: July 14, 2007 + * + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + * + * + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EPIX_VERBATIM +#define EPIX_VERBATIM + +#include <string> + +#include "tile.h" + +namespace ePiX { + + class format; + class affine; + class screen_mask; + + class verbatim : public tile { + public: + verbatim(const std::string& text=""); + + verbatim& map_by(const affine&); + verbatim& crop_to(const screen_mask&); + + verbatim* clone() const; + + bool is_empty() const; + + std::string print_to(const format&, const std::string&) const; + void add_to_pallet() const; + + private: + std::string m_text; + }; // end of class verbatim + +} // end of namespace + +#endif /* EPIX_VERBATIM */ |