pax_global_header00006660000000000000000000000064133055360410014512gustar00rootroot0000000000000052 comment=b258ecc32bba3c8c8387a64c019f05051574c877 jsurf-alggeo-0.4.1+ds/000077500000000000000000000000001330553604100145035ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/.editorconfig000066400000000000000000000005011330553604100171540ustar00rootroot00000000000000# This file is for unifying the coding style for different editors and IDEs. # More information at http://EditorConfig.org # No .editorconfig files above the root directory root = true [*] indent_style = space indent_size = 4 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true jsurf-alggeo-0.4.1+ds/CHANGELOG.md000066400000000000000000000050731330553604100163210ustar00rootroot00000000000000# Change log All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased][unreleased] ## [0.4.1] - 2017-12-04 ### Fixed - allow to disable RotateSphericalDragger when mouse button is released ## [0.4.0] - 2017-11-25 ### Changed - some backward compatibility for option machinery - more detailed help text ### Added - add support for EditorConfig to unify coding style - AST nodes keep track of parentheses in the input ## [0.3.0] - 2015-11-17 ### Changed - default to headless instead of graphical operation - use Sun's javax.vecmath 1.5.2 implementation again (GPLv2 w/ classpath exception) ### Added - new command line option --gui ### Fixed - background threads do not prevent application from exiting anymore ## [0.2.0] - 2015-11-09 ### Added - long options --help and --version ## [0.1.4] - 2015-09-07 ### Changed - removed unintended executable privilege of some .jsurf example files ### Fixed - fixed division of univariate polynomials by constants ### Added - change log ## [0.1.3] - 2015-03-03 ### Added - unit tests via JUnit ### Changed - ignore Eclipse build files via .gitignore ### Fixed - avoid side effects of multivariate polynomial addition (which sometimes changed the internal representation of variables like X, Y and Z) ## [0.1.2] - 2014-07-03 ### Changed - switched to non-GPL licensed implementation of the javax.vecmath API - switched gradle plugin 'maven' to 'maven-publish' - updated to Gradle 1.12 - ignore Eclipse project files via .gitignore ## [0.1.1] - 2014-02-07 ### Added - .gitignore - .jsurf examples files and demo for gradle 'run' task ### Fixed - properly exit after saving PNG image ## [0.1.0] - 2013-06-13 ### Added - basic setup for Maven deployment to GitHub - import code from internal code repository of IMAGINARY ### Changed - improved scheduling of parallel rendering tasks [unreleased]: https://github.com/IMAGINARY/jsurf/compare/v0.4.1...HEAD [0.4.1]: https://github.com/IMAGINARY/jsurf/compare/v0.4.0...v0.4.1 [0.4.0]: https://github.com/IMAGINARY/jsurf/compare/v0.3.0...v0.4.0 [0.3.0]: https://github.com/IMAGINARY/jsurf/compare/v0.2.0...v0.3.0 [0.2.0]: https://github.com/IMAGINARY/jsurf/compare/v0.1.4...v0.2.0 [0.1.4]: https://github.com/IMAGINARY/jsurf/compare/v0.1.3...v0.1.4 [0.1.3]: https://github.com/IMAGINARY/jsurf/compare/v0.1.2...v0.1.3 [0.1.2]: https://github.com/IMAGINARY/jsurf/compare/v0.1.1...v0.1.2 [0.1.1]: https://github.com/IMAGINARY/jsurf/compare/v0.1.0...v0.1.1 [0.1.0]: https://github.com/IMAGINARY/jsurf/compare/v0.0.0...v0.1.0 jsurf-alggeo-0.4.1+ds/LICENSE000066400000000000000000000261361330553604100155200ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. jsurf-alggeo-0.4.1+ds/NOTICE000066400000000000000000000014041330553604100154060ustar00rootroot00000000000000 Copyright 2008 Christian Stussak Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. This program is part of IMAGINARY (www.imaginary.org) by the Mathematisches Forschungsinstitut Oberwolfach (www.mfo.de). It is the raytracing core for the exhibit SURFER (www.imaginary.org/program/surfer). jsurf-alggeo-0.4.1+ds/examples/000077500000000000000000000000001330553604100163215ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/examples/fantasy_calypso.jsurf000066400000000000000000000031041330553604100225710ustar00rootroot00000000000000#jSurfer surface description #Thu Feb 17 14:46:28 CET 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.4 0.4745098 0.7019608 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=-0.019998182 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=-0.7355779 -0.033347078 -0.6766381 0.0 -0.67297435 -0.0787503 0.7354782 0.0 -0.07781051 0.9963461 0.035486355 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x^2+y^2*z-z^2 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.5686275 0.44313726 0.6392157 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/fantasy_dingdong.jsurf000066400000000000000000000031031330553604100227070ustar00rootroot00000000000000#jSurfer surface description #Thu Feb 17 17:31:34 CET 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.13725491 0.56078434 0.0627451 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.3000002 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=-0.19729406 -0.24643514 0.94886947 0.0 0.98011094 -0.07081119 0.18540007 0.0 0.021502197 0.9665734 0.25550473 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x^2 +y^2 +z^3 - z^2 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=1.0 0.21176471 0.2 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/fantasy_distel.jsurf000066400000000000000000000031301330553604100224020ustar00rootroot00000000000000#jSurfer surface description #Thu Feb 17 14:52:16 CET 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.3764706 0.17254902 0.52156866 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.020000448 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.79032904 0.06338288 0.60939556 0.0 0.43526262 0.6419169 -0.63126034 0.0 -0.4311923 0.76415026 0.4797375 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=-1+x^2+y^2+z^2+(x^2+y^2)*(x^2+z^2)*(y^2+z^2)*2000 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=1.0 0.8 0.4 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/fantasy_dullo.jsurf000066400000000000000000000033041330553604100222400ustar00rootroot00000000000000#jSurfer surface description #Fri Jul 08 16:58:33 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_b=0.5 #0.41559362411499023 surface_parameter_a=0.5 #0.41736117005348206 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.9411765 0.25882354 0.05882353 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.11388256 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=-0.9975637 0.06831278 -0.014604302 0.0 -0.050649248 -0.56332713 0.82468677 0.0 0.048110377 0.82340914 0.5654113 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=(x^2+y^2+z^2+a^2-b^2)^2-4*b^2*(x^2+y^2) camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.87058824 0.41960785 0.101960786 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/fantasy_helix.jsurf000066400000000000000000000031231330553604100222310ustar00rootroot00000000000000#jSurfer surface description #Fri Jul 08 16:59:32 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.7411765 0.09019608 0.043137256 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.60000014 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=-0.8083986 0.07481562 -0.5838717 0.0 -0.5856568 -0.20203695 0.78498316 0.0 -0.05923382 0.9765199 0.20714238 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=6*x^2-2*x^4-y^2*z^2 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.050980393 0.5803922 0.105882354 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/fantasy_himmel.jsurf000066400000000000000000000031131330553604100223720ustar00rootroot00000000000000#jSurfer surface description #Fri Jul 08 17:00:53 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.19607843 0.14901961 0.7411765 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.75999975 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=-0.38830876 -0.085946456 -0.91751784 0.0 -0.3679515 -0.8983743 0.23987652 0.0 -0.8448887 0.43074587 0.31722137 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x^2-y^2*z^2 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.6784314 0.039215688 0.0627451 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/fantasy_kolibri.jsurf000066400000000000000000000031021330553604100225500ustar00rootroot00000000000000#jSurfer surface description #Thu Feb 17 17:08:07 CET 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.78039217 0.59607846 0.2 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.26000023 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=-0.046498846 0.98681486 -0.15504088 0.0 0.8711488 0.11601071 0.47712216 0.0 0.48881748 -0.11287785 -0.86505544 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x^3+x^2*z^2-y^2 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=1.0 0.19215687 0.30588236 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/fantasy_kreisel.jsurf000066400000000000000000000031461330553604100225630ustar00rootroot00000000000000#jSurfer surface description #Thu Feb 17 14:59:10 CET 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.11372549 0.5882353 0.24313726 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.92000103 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.013943902 0.14249302 -0.98969924 0.0 -0.9993122 -0.03207966 -0.018698018 0.0 -0.034412865 0.98927724 0.14194682 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=60*(x^2+y^2)*z^4-(60-x^2-y^2-z^2)^3 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.30588236 0.81960785 0.03529412 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/fantasy_miau.jsurf000066400000000000000000000031251330553604100220550ustar00rootroot00000000000000#jSurfer surface description #Thu Feb 17 14:41:15 CET 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.20392157 0.13333334 0.6117647 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.6600013 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=-0.74236906 0.4141376 -0.5266902 0.0 -0.652213 -0.26671094 0.70958126 0.0 0.15338786 0.8702723 0.4680983 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x^2*y*z+x^2*z^2+2*y^3*z+3*y^3 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.34901962 0.65882355 0.8509804 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/fantasy_nepali.jsurf000066400000000000000000000031301330553604100223660ustar00rootroot00000000000000#jSurfer surface description #Fri Jul 08 17:01:58 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.34509805 0.29411766 0.7411765 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.20000076 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=-0.9626499 -0.17683345 0.20503022 0.0 0.21769734 -0.05527428 0.9744517 0.0 -0.16098322 0.9826884 0.09170532 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=(x*y-z^3-1)^2-(1-x^2-y^2)^3 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.6784314 0.06666667 0.15294118 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/fantasy_quaste.jsurf000066400000000000000000000034631330553604100224310ustar00rootroot00000000000000#jSurfer surface description #Fri Jul 08 17:03:12 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.68235296 0.70980394 0.7411765 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.3000002 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=-0.24703549 0.22806507 -0.94179034 0.0 -0.7210419 -0.6925646 0.021419764 0.0 -0.64736474 0.68435943 0.33553103 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=8*z^9-24*x^2*z^6-24*y^2*z^6+36*z^8+24*x^4*z^3-168*x^2*y^2*z^3+24*y^4*z^3-72*x^2*z^5-72*y^2*z^5+54*z^7-8*x^6-24*x^4*y^2-24*x^2*y^4-8*y^6+36*x^4*z^2-252*x^2*y^2*z^2+36*y^4*z^2-54*x^2*z^4-108*y^2*z^4+27*z^6-108*x^2*y^2*z+54*y^4*z-54*y^2*z^3+27*y^4 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.3372549 0.34509805 0.38039216 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/fantasy_suess.jsurf000066400000000000000000000031461330553604100222670ustar00rootroot00000000000000#jSurfer surface description #Thu Feb 17 14:21:49 CET 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.6117647 0.019607844 0.06666667 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.22000168 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=-0.99927646 -0.0049358155 0.03789161 0.0 0.03810715 -0.055194702 0.9977543 0.0 -0.0028316977 0.9984675 0.05534416 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=(x^2+9/4*y^2+z^2-1)^3-x^2*z^3-9/80*y^2*z^3 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.8509804 0.6 0.10980392 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/fantasy_tuelle.jsurf000066400000000000000000000031061330553604100224130ustar00rootroot00000000000000#jSurfer surface description #Thu Feb 17 14:54:05 CET 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.52156866 0.078431375 0.22352941 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.020000448 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.4866662 -0.25870213 -0.83440423 0.0 -0.85162795 0.07232085 -0.51913446 0.0 0.1946466 0.96324646 -0.1851219 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=y*z*(x^2+y-z) camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=1.0 0.45490196 0.6039216 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/fantasy_visavis.jsurf000066400000000000000000000031051330553604100226040ustar00rootroot00000000000000#jSurfer surface description #Tue Jul 12 16:30:44 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.3647059 0.47058824 0.7058824 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.5 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.06494648 -0.9829913 -0.17180364 0.0 0.39192083 -0.13320524 0.9103081 0.0 -0.9177063 -0.12645374 0.3766019 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x^2-x^3+y^2+y^4+z^3-z^4 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.9843137 1.0 0.24705882 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/fantasy_zeck.jsurf000066400000000000000000000031071330553604100220560ustar00rootroot00000000000000#jSurfer surface description #Thu Feb 17 17:06:18 CET 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.3137255 0.28235295 0.78039217 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.26000023 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=-0.47687274 -0.1281684 0.8695794 0.0 0.8789695 -0.07275737 0.47129878 0.0 0.0028628586 0.98908186 0.14735195 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x^2+y^2-z^3*(1-z) camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.7137255 0.77254903 1.0 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/fantasy_zitrus.jsurf000066400000000000000000000032401330553604100224600ustar00rootroot00000000000000#jSurfer surface description #Wed Jul 25 19:42:05 CEST 2012 back_material_specular_intensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.78039217 0.92941177 0.31764707 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=-0.11999965459108354 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 front_material_specular_intensity=0.5 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.7786124895562688 -0.4752428874922392 0.409765970757826 0.0 0.5952991551804274 0.35289958751183637 -0.7218610611494469 0.0 0.19845291999045425 0.8059827466811341 0.557682978950456 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=1.2*x^2+1.2*z^2-5*(y+0.5)^3*(0.5-y)^3 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=1.0 0.8 0.4 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/record_7eck.jsurf000066400000000000000000000036631330553604100215730ustar00rootroot00000000000000#jSurfer surface description #Mon Jun 20 12:13:21 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_a=1.0 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.8 0.76862746 0.22745098 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.71463776 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.08274177 -0.5759694 0.8132837 0.0 -0.99645865 -0.03515144 0.07648576 0.0 -0.015462978 -0.81672406 -0.57683164 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=a*0.99*(64*(0.5*z)^7-1*112*(0.5*z)^5+56*(0.5*z)^3-1*7*(0.5*z)-1*1)+(.7818314825-1*.3765101982*y-1*.7818314825*x)*(.7818314824-1*.8460107361*y-1*.1930964297*x)*(.7818314825-1*.6784479340*y+.5410441731*x)*(.7818314825+.8677674789*x)*(.7818314824+.6784479339*y+.541044172*x)*(.7818314824+.8460107358*y-1*.193096429*x)*(.7818314821+.3765101990*y-1*.781831483*x) camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.10980392 0.6 0.08235294 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/record_barthsextic.jsurf000066400000000000000000000033201330553604100232500ustar00rootroot00000000000000#jSurfer surface description #Mon Jun 20 11:42:02 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_a=1.0 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=1.0 0.09803922 0.43137255 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.34000018 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.50119334 0.2850557 0.8170455 0.0 -0.79794276 -0.21308568 0.5638187 0.0 0.3348199 -0.93452984 0.12065979 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=4*((a*(1+sqrt(5))/2)^2*x^2-1*y^2)*((a*(1+sqrt(5))/2)^2*y^2-1*z^2)*((a*(1+sqrt(5))/2)^2*z^2-1*x^2)-1*(1+2*(a*(1+sqrt(5))/2))*(x^2+y^2+z^2-1*1)^2 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=1.0 0.24705882 1.0 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/record_barthsextic30cuspen.jsurf000066400000000000000000000033431330553604100246360ustar00rootroot00000000000000#jSurfer surface description #Mon Jun 20 12:21:29 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_a=1.0 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.18431373 0.2784314 0.8 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.31463814 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=-0.40214008 0.084009714 -0.9117274 0.0 -0.9123627 -0.12028783 0.39133537 0.0 -0.07679104 0.9891857 0.12501787 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=4*((a*(1+sqrt(5))/2)^2*x^2-1*1*y^2)*((a*(1+sqrt(5))/2)^2*y^2-1*1*z^2)*((a*(1+sqrt(5))/2)^2*z^2-1*1*x^2)-1*1*(1+2*(a*(1+sqrt(5))/2))*(x^2+y^2+z^2-1*1*1)^3 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.8 0.22745098 0.6784314 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/record_cayleycubic.jsurf000066400000000000000000000032621330553604100232310ustar00rootroot00000000000000#jSurfer surface description #Fri Jul 08 16:40:21 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_b=0.5 surface_parameter_a=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.7058824 0.47843137 0.45882353 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.65999985 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.26447517 -0.47794443 -0.8376317 0.0 0.5578079 -0.6327149 0.5371454 0.0 -0.78670573 -0.60929716 0.0992635 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=(b-0.5)*(x+y+z-1)^2+(a-0.5)*(x+y+z+3)^2+x^3+y^3+z^3+1-0.25*(x+y+z+1)^3 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.8392157 0.06666667 0.24705882 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/record_chmutovoktic.jsurf000066400000000000000000000033121330553604100234500ustar00rootroot00000000000000#jSurfer surface description #Fri Jul 08 16:52:29 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_a=0.0 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.11764706 0.09803922 0.6901961 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.27405787 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=-0.4978695 0.6287298 -0.59736294 0.0 -0.8123411 -0.096857205 0.57509595 0.0 0.30371907 0.7715779 0.5589577 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=(a*(-1*2))/125+x^8+y^8+z^8-1*2*x^6-1*2*y^6-1*2*z^6+1.25*x^4+1.25*y^4+1.25*z^4-1*0.25*x^2-1*0.25*y^2-1*0.25*z^2+0.03125 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.7254902 0.33333334 0.87058824 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/record_doppelkegel.jsurf000066400000000000000000000031301330553604100232220ustar00rootroot00000000000000#jSurfer surface description #Fri Jul 08 16:37:50 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_a=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.7058824 0.02745098 0.02745098 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.5 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.28104958 -0.14850272 0.9481345 0.0 0.9594597 0.021667702 -0.28101322 0.0 0.02118737 0.98867476 0.14857173 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x^2+y^2-z^2+a-0.5 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=1.0 0.8117647 0.05882353 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/record_endrass.jsurf000066400000000000000000000044361330553604100224000ustar00rootroot00000000000000#jSurfer surface description #Fri Jul 08 16:50:17 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_a=1.0 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.7882353 0.1254902 0.13725491 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.5956521 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.8536812 -0.2056901 0.47847307 0.0 -0.5208004 -0.33169973 0.78660953 0.0 -0.0030862177 -0.92069346 -0.3902868 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=a*(-1*(1.0)/(4.0)*(1.0-1*sqrt(2.0))*(x^2+y^2)^2 +(x^2+y^2)*((1.0-1*(1.0)/sqrt(2.0))*z^2+0*z+(1.0)/(8.0)*(2.0-1*7.0*sqrt(2.0))) -1*1.0*z^4 +0*z^3 +(0.5+sqrt(2.0))*z^2 +0*z -1*(1.0)/(16.0)*(1.0-1*12.0*sqrt(2.0)))^2 -1*(cos(0*3.14159265358979/4)*x+sin(0*3.14159265358979/4)*y-1*1)*(cos(1*3.14159265358979/4)*x+sin(1*3.14159265358979/4)*y-1*1)*(cos(2*3.14159265358979/4)*x+sin(2*3.14159265358979/4)*y-1*1)*(cos(3*3.14159265358979/4)*x+sin(3*3.14159265358979/4)*y-1*1)*(cos(4*3.14159265358979/4)*x+sin(4*3.14159265358979/4)*y-1*1)*(cos(5*3.14159265358979/4)*x+sin(5*3.14159265358979/4)*y-1*1)*(cos(6*3.14159265358979/4)*x+sin(6*3.14159265358979/4)*y-1*1)*(cos(7*3.14159265358979/4)*x+sin(7*3.14159265358979/4)*y-1*1) camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.87058824 0.7372549 0.105882354 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/record_kummerquartic.jsurf000066400000000000000000000033531330553604100236270ustar00rootroot00000000000000#jSurfer surface description #Fri Jul 08 16:45:41 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_a=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.7058824 0.44313726 0.0627451 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.3000002 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.5272737 -0.8403951 -0.1254016 0.0 -0.19924057 -0.26575094 0.94323117 0.0 -0.8260085 -0.47235364 -0.30756372 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=(x^2+y^2+z^2-1*(0.5+2*a)^2)^2-1*(3.0*((0.5+2*a)^2)-1*1.0)/(3.0-1*((0.5+2*a)^2))*(1-1*z-1*sqrt(2)*x)*(1-1*z+sqrt(2)*x)*(1+z+sqrt(2)*y)*(1+z-1*sqrt(2)*y) camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.8392157 0.8117647 0.47058824 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/record_labsseptic.jsurf000066400000000000000000000117431330553604100230710ustar00rootroot00000000000000#jSurfer surface description #Tue Jul 12 18:41:12 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_a=1.0 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.21176471 0.85882354 0.06666667 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.97999954 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.8109337 -0.3495264 0.46929234 0.0 -0.58499795 -0.46599162 0.6638076 0.0 -0.01332979 -0.81283 -0.5823557 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x^7-1*21*x^5*y^2+35*x^3*y^4-1*7*x*y^6+7*x^6*1+21*x^4*y^2*1+21*x^2*y^4*1+7*y^6*1-1*57*x^4*1^3-1*114*x^2*y^2*1^3-1*57*y^4*1^3+(24/7*(a*(-0.140106854987124776454220549858))^2+768/49*(a*(-0.140106854987124776454220549858))+800/7)*x^2*1^5+(24/7*(a*(-0.140106854987124776454220549858))^2+768/49*(a*(-0.140106854987124776454220549858))+800/7)*y^2*1^5+(-1*149808/2401*(a*(-0.140106854987124776454220549858))^2+3216/343*(a*(-0.140106854987124776454220549858))-1*147584/2401)*1^7+(-1*49*(a*(-0.140106854987124776454220549858))^2+7*(a*(-0.140106854987124776454220549858))-1*52)*x^4*1^2*z+(-1*98*(a*(-0.140106854987124776454220549858))^2+14*(a*(-0.140106854987124776454220549858))-1*104)*x^2*y^2*1^2*z+(-1*49*(a*(-0.140106854987124776454220549858))^2+7*(a*(-0.140106854987124776454220549858))-1*52)*y^4*1^2*z+(128/7*(a*(-0.140106854987124776454220549858))^2+704/49*(a*(-0.140106854987124776454220549858))+128/7)*x^2*1^4*z+(128/7*(a*(-0.140106854987124776454220549858))^2+704/49*(a*(-0.140106854987124776454220549858))+128/7)*y^2*1^4*z+(-1*1632/343*(a*(-0.140106854987124776454220549858))^2+16/7*(a*(-0.140106854987124776454220549858))-1*192/343)*1^6*z+(-1*98*(a*(-0.140106854987124776454220549858))^2+14*(a*(-0.140106854987124776454220549858))-1*101)*x^4*1*z^2+(-1*196*(a*(-0.140106854987124776454220549858))^2+28*(a*(-0.140106854987124776454220549858))-1*202)*x^2*y^2*1*z^2+(-1*98*(a*(-0.140106854987124776454220549858))^2+14*(a*(-0.140106854987124776454220549858))-1*101)*y^4*1*z^2+(3016/7*(a*(-0.140106854987124776454220549858))^2-1*2904/49*(a*(-0.140106854987124776454220549858))+440)*x^2*1^3*z^2+(3016/7*(a*(-0.140106854987124776454220549858))^2-1*2904/49*(a*(-0.140106854987124776454220549858))+440)*y^2*1^3*z^2+(-1*17440/343*(a*(-0.140106854987124776454220549858))^2+416/49*(a*(-0.140106854987124776454220549858))-1*17040/343)*1^5*z^2+(-1*49*(a*(-0.140106854987124776454220549858))^2+7*(a*(-0.140106854987124776454220549858))-1*50)*x^4*z^3+(-1*98*(a*(-0.140106854987124776454220549858))^2+14*(a*(-0.140106854987124776454220549858))-1*100)*x^2*y^2*z^3+(-1*49*(a*(-0.140106854987124776454220549858))^2+7*(a*(-0.140106854987124776454220549858))-1*50)*y^4*z^3+(5776/7*(a*(-0.140106854987124776454220549858))^2-1*5648/49*(a*(-0.140106854987124776454220549858))+5888/7)*x^2*1^2*z^3+(5776/7*(a*(-0.140106854987124776454220549858))^2-1*5648/49*(a*(-0.140106854987124776454220549858))+5888/7)*y^2*1^2*z^3+(-1*313136/343*(a*(-0.140106854987124776454220549858))^2+6288/49*(a*(-0.140106854987124776454220549858))-1*319264/343)*1^4*z^3+(3680/7*(a*(-0.140106854987124776454220549858))^2-1*3608/49*(a*(-0.140106854987124776454220549858))+536)*x^2*1*z^4+(3680/7*(a*(-0.140106854987124776454220549858))^2-1*3608/49*(a*(-0.140106854987124776454220549858))+536)*y^2*1*z^4+(-1*592240/343*(a*(-0.140106854987124776454220549858))^2+11856/49*(a*(-0.140106854987124776454220549858))-1*603856/343)*1^3*z^4+(816/7*(a*(-0.140106854987124776454220549858))^2-1*800/49*(a*(-0.140106854987124776454220549858))+832/7)*x^2*z^5+(816/7*(a*(-0.140106854987124776454220549858))^2-1*800/49*(a*(-0.140106854987124776454220549858))+832/7)*y^2*z^5+(-1*458832/343*(a*(-0.140106854987124776454220549858))^2+1312/7*(a*(-0.140106854987124776454220549858))-1*467840/343)*1^2*z^5+(-1*166272/343*(a*(-0.140106854987124776454220549858))^2+3328/49*(a*(-0.140106854987124776454220549858))-1*169536/343)*1*z^6+(-1*166272/2401*(a*(-0.140106854987124776454220549858))^2+3328/343*(a*(-0.140106854987124776454220549858))-1*169536/2401)*z^7 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.60784316 1.0 0.4627451 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/record_quintic15cuspen.jsurf000066400000000000000000000032451330553604100237760ustar00rootroot00000000000000#jSurfer surface description #Mon Jun 20 12:18:36 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.18431373 0.2784314 0.8 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.71463776 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=-0.35519874 0.27010906 -0.89492756 0.0 -0.93405837 -0.14070025 0.3282619 0.0 -0.037247792 0.95250154 0.3022701 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x^5-1*1*10*x^3*y^2+5*x*y^4-1*1*3*z^5-1*1*5*x^4-1*1*10*x^2*y^2-1*1*5*y^4+10*z^3+20*x^2+20*y^2-1*1*15*z-1*1*24 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.44705883 0.5647059 0.7019608 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/record_togliatti.jsurf000066400000000000000000000036661330553604100227450ustar00rootroot00000000000000#jSurfer surface description #Mon Jun 20 11:39:02 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_a=1.0 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.24313726 0.8666667 1.0 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.5799999 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=-0.005128823 -0.3225388 0.94654906 0.0 -0.9996793 0.025271885 0.0031949729 0.0 -0.024949454 -0.9462233 -0.3225622 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=(1-1*sqrt(5-1*sqrt(5))/2*z)*(x^2+y^2-1*1+(1+3*sqrt(5))/4*z^2)^2-a*3.8496061120482923113983843766*(x-1*z)*(cos(2*3.14159265358979/5)*x-1*sin(2*3.14159265358979/5)*y-1*z)*(cos(4*3.14159265358979/5)*x-1*sin(4*3.14159265358979/5)*y-1*z)*(cos(6*3.14159265358979/5)*x-1*sin(6*3.14159265358979/5)*y-1*z)*(cos(8*3.14159265358979/5)*x-1*sin(8*3.14159265358979/5)*y-1*z) camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.23529412 0.2901961 1.0 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/record_vielesing.jsurf000066400000000000000000000036251330553604100227250ustar00rootroot00000000000000#jSurfer surface description #Mon Jun 20 12:05:26 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.8 0.47058824 0.078431375 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.47565222 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.7739177 0.5366273 -0.33630326 0.0 -0.6214043 0.74589574 -0.23981252 0.0 0.122158006 0.39457047 0.91071516 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x^9-1*1*36*x^7*y^2+126*x^5*y^4-1*1*84*x^3*y^6+9*x*y^8+64*z^9-1*1*9*x^8+126*x^6*y^2-1*1*126*x^2*y^6+9*y^8+27*x^7-1*1* 27*x^5*y^2-1*1*135*x^3*y^4-1*1*81*x*y^6-1*1*144*z^7-1*1*21*x^6-1*1*225*x^4*y^2+45*x^2*y^4-1*1*39*y^6-1*1*36*x^5+72*x^3*y ^2+108*x*y^4+108*z^5+54*x^4+108*x^2*y^2+54*y^4+9*x^3-1*1*27*x*y^2-1*1*30*z^3-1*1*27*x^2-1*1*27*y^2+2.25*z+4.25 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.5019608 0.21568628 0.07450981 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/tutorial_2kugeln.jsurf000066400000000000000000000032011330553604100226620ustar00rootroot00000000000000#jSurfer surface description #Fri Jul 08 17:05:18 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_a=0.67641282081604 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.7411765 0.06666667 0.08627451 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.5256126 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.92125595 -0.36965042 0.12105258 0.0 0.313383 0.521029 -0.79393107 0.0 0.23040503 0.769348 0.5958424 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=(x^2+y^2+z^2-1)*((x-3*a)^2+y^2+z^2-1) camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.5803922 0.050980393 0.09019608 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/tutorial_ebene.jsurf000066400000000000000000000032051330553604100223750ustar00rootroot00000000000000#jSurfer surface description #Wed Jul 25 19:44:34 CEST 2012 back_material_specular_intensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.19607843 0.76862746 0.07450981 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.5 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 front_material_specular_intensity=0.5 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.8776129008664156 -0.3004127220911171 0.37356183219659705 0.0 -0.021452319297130592 0.7538831644837973 0.6566594351225551 0.0 -0.4788908179988047 -0.5843060679174239 0.6551726515842347 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.16470589 0.5803922 0.050980393 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/tutorial_gerade.jsurf000066400000000000000000000033051330553604100225470ustar00rootroot00000000000000#jSurfer surface description #Fri May 20 08:39:09 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_b=0.0 surface_parameter_a=1.0 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.06666667 0.3372549 0.8784314 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.5 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.9982771061621802 0.0037608024691454097 -0.05859070196552772 0.0 -0.001255924891183464 0.9990879718227635 0.04273143638543331 0.0 0.05869812742773203 -0.04258456770194343 0.9973709665955084 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x*y*(a*x+b-y) camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.15686275 0.43529412 0.7490196 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/tutorial_koord1.jsurf000066400000000000000000000032731330553604100225230ustar00rootroot00000000000000#jSurfer surface description #Wed Jul 25 19:43:29 CEST 2012 back_material_specular_intensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.65882355 0.96862745 0.26666668 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.8536233901977539 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 front_material_specular_intensity=0.5 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.9443245279294562 -0.12491816289780178 0.30438095263992904 0.0 0.0016058832699314127 0.9268605025092757 0.37540260382658003 0.0 -0.329013146408239 -0.3540130631208094 0.8754571746738623 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=(x^2+y^2-0.1)*(x^2+z^2-0.1)*(y^2+z^2-0.1) camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.23921569 0.6117647 0.1882353 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/tutorial_koord2.jsurf000066400000000000000000000032071330553604100225210ustar00rootroot00000000000000#jSurfer surface description #Wed Jul 25 19:52:08 CEST 2012 back_material_specular_intensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.1254902 0.8784314 0.827451 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.5 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 front_material_specular_intensity=0.5 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.9982771061621802 0.0037608024691454097 -0.05859070196552772 0.0 -0.001255924891183464 0.9990879718227635 0.04273143638543331 0.0 0.05869812742773203 -0.04258456770194343 0.9973709665955084 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x*y camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.06666667 0.4509804 0.43137255 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/tutorial_kreis.jsurf000066400000000000000000000031371330553604100224400ustar00rootroot00000000000000#jSurfer surface description #Fri May 20 08:46:35 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_a=1.0 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=1.0 0.25882354 0.9490196 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.15144944 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.9995013 -0.026408318 -0.017527938 0.0 0.026248684 0.99961543 -0.009268604 0.0 0.017766709 0.008803782 0.9998084 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x^2+y^2-a^2 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.68235296 0.11372549 0.7019608 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/tutorial_kugel.jsurf000066400000000000000000000031441330553604100224300ustar00rootroot00000000000000#jSurfer surface description #Fri May 20 08:46:10 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_a=1.0 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=1.0 0.20392157 0.42745098 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.15144944 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.9995013 -0.026408318 -0.017527938 0.0 0.026248684 0.99961543 -0.009268604 0.0 0.017766709 0.008803782 0.9998084 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x^2+y^2+z^2-a^2 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.7019608 0.101960786 0.4627451 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/tutorial_parabel.jsurf000066400000000000000000000032251330553604100227270ustar00rootroot00000000000000#jSurfer surface description #Fri May 20 08:43:39 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.37254903 0.13333334 0.8784314 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.5 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.9982771061621802 0.0037608024691454097 -0.05859070196552772 0.0 -0.001255924891183464 0.9990879718227635 0.04273143638543331 0.0 0.05869812742773203 -0.04258456770194343 0.9973709665955084 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x*y*(x^2-y) camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.21960784 0.078431375 0.7490196 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/tutorial_tricks1.jsurf000066400000000000000000000031611330553604100227000ustar00rootroot00000000000000#jSurfer surface description #Fri Jul 08 17:07:34 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_a=0.0 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.92156863 0.3647059 0.019607844 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.52420235 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.34621078 -0.47033587 -0.811745 0.0 -0.86678785 -0.49139225 -0.08496771 0.0 -0.35892105 0.7330262 -0.5778062 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=(x^2+y^2-1)*(x^2+z^2-1)-a camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.78039217 0.62352943 0.0627451 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/tutorial_tricks2.jsurf000066400000000000000000000031761330553604100227070ustar00rootroot00000000000000#jSurfer surface description #Fri May 20 12:58:59 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 surface_parameter_a=0.10555550456047058 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.9019608 0.7137255 0.105882354 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.4202895 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.6629907 -0.35071582 -0.6613998 0.0 -0.4165067 0.56132054 -0.715156 0.0 0.6220731 0.74961746 0.22607408 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=(x^2+y^2-1)^2+(y^2+z^2-1)^2-a camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.7019608 0.39607844 0.16470589 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/tutorial_wuerfel.jsurf000066400000000000000000000031071330553604100227710ustar00rootroot00000000000000#jSurfer surface description #Fri Jul 08 17:07:01 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.92156863 0.27058825 0.06666667 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.2202897 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.6629907 -0.35071582 -0.6613998 0.0 -0.4165067 0.56132054 -0.715156 0.0 0.6220731 0.74961746 0.22607408 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x^6+y^6+z^6-1 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.7019608 0.39607844 0.16470589 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/examples/tutorial_zitrus.jsurf000066400000000000000000000032401330553604100226560ustar00rootroot00000000000000#jSurfer surface description #Wed Jul 25 19:42:05 CEST 2012 back_material_specular_intensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.78039217 0.92941177 0.31764707 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=-0.11999965459108354 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 front_material_specular_intensity=0.5 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.7786124895562688 -0.4752428874922392 0.409765970757826 0.0 0.5952991551804274 0.35289958751183637 -0.7218610611494469 0.0 0.19845291999045425 0.8059827466811341 0.557682978950456 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=1.2*x^2+1.2*z^2-5*(y+0.5)^3*(0.5-y)^3 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=1.0 0.8 0.4 back_material_shininess=30.0 back_material_diffuse_intensity=0.8 jsurf-alggeo-0.4.1+ds/src/000077500000000000000000000000001330553604100152725ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/000077500000000000000000000000001330553604100162165ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/antlr/000077500000000000000000000000001330553604100173365ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/antlr/de/000077500000000000000000000000001330553604100177265ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/antlr/de/mfo/000077500000000000000000000000001330553604100205075ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/antlr/de/mfo/jsurf/000077500000000000000000000000001330553604100216405ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/antlr/de/mfo/jsurf/parser/000077500000000000000000000000001330553604100231345ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/antlr/de/mfo/jsurf/parser/AlgebraicExpression.g000066400000000000000000000077521330553604100272500ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ grammar AlgebraicExpression; options { language = Java; output = AST; } tokens { PLUS = '+' ; MINUS = '-' ; MULT = '*' ; DIV = '/' ; POW = '^' ; LPAR = '(' ; RPAR = ')' ; PARENTHESES; } @header { package de.mfo.jsurf.parser; import de.mfo.jsurf.algebra.*; } @lexer::header { package de.mfo.jsurf.parser; } @members { public static PolynomialOperation parse( String s ) throws Exception { // Create a string ANTLRStringStream input = new ANTLRStringStream( s ); // Create an ExprLexer that feeds from that stream AlgebraicExpressionLexer lexer = new AlgebraicExpressionLexer( input ); // Create a stream of tokens fed by the lexer CommonTokenStream tokens = new CommonTokenStream( lexer ); // Create a parser that feeds off the token stream AlgebraicExpressionParser parser = new AlgebraicExpressionParser( tokens ); // Begin parsing at start rule AlgebraicExpressionParser.start_return r = parser.start(); // Create a stream of nodes fed by the parser CommonTreeNodeStream nodes = new CommonTreeNodeStream( ( CommonTree ) r.getTree() ); // Create a tree parser that feeds off the node stream AlgebraicExpressionWalker walker = new AlgebraicExpressionWalker( nodes ); // Begin tree parsing at start rule return walker.start(); } protected void mismatch( IntStream input, int ttype, BitSet follow ) throws RecognitionException { throw new MismatchedTokenException(ttype, input); } @Override public java.lang.Object recoverFromMismatchedSet( IntStream input, RecognitionException e, BitSet follow ) throws RecognitionException { throw e; } @Override protected Object recoverFromMismatchedToken( IntStream input, int ttype, BitSet follow ) throws RecognitionException { throw new MismatchedTokenException( ttype, input ); } } @rulecatch { catch( RecognitionException e ) { throw e; } } /*------------------------------------------------------------------ * PARSER RULES *------------------------------------------------------------------*/ start : add_expr EOF! ; add_expr : mult_expr ( PLUS^ mult_expr | MINUS^ mult_expr )* ; mult_expr : neg_expr ( MULT^ neg_expr | DIV^ neg_expr )* ; neg_expr : MINUS^ pow_expr | pow_expr ; pow_expr : unary_expr ( POW^ pow_expr )? ; unary_expr : primary_expr | IDENTIFIER LPAR add_expr RPAR -> ^(IDENTIFIER PARENTHESES add_expr) ; primary_expr : DECIMAL_LITERAL | FLOATING_POINT_LITERAL | IDENTIFIER | LPAR add_expr RPAR -> PARENTHESES add_expr ; /*------------------------------------------------------------------ * LEXER RULES *------------------------------------------------------------------*/ DECIMAL_LITERAL : ( '0' | '1'..'9' '0'..'9'* ) ; FLOATING_POINT_LITERAL : DIGIT+ '.' DIGIT* EXPONENT? | '.' DIGIT+ EXPONENT? | DIGIT+ EXPONENT ; fragment EXPONENT : ( 'e' | 'E' ) ( PLUS | MINUS )? DIGIT+ ; IDENTIFIER : LETTER ( LETTER | DIGIT )*; WHITESPACE : ( '\t' | ' ' | '\r' | '\n' | '\u000C' )+ { $channel = HIDDEN; } ; fragment DIGIT : '0'..'9' ; fragment LETTER : 'A'..'Z' | 'a'..'z' | '_' ; ERRCHAR : .; jsurf-alggeo-0.4.1+ds/src/main/antlr/de/mfo/jsurf/parser/AlgebraicExpressionWalker.g000066400000000000000000000152451330553604100304120ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ tree grammar AlgebraicExpressionWalker; options { tokenVocab = AlgebraicExpression; ASTLabelType = CommonTree; } @header { package de.mfo.jsurf.parser; import de.mfo.jsurf.algebra.*; } @members { public static PolynomialOperation createVariable( String name, boolean hasParentheses ) { try { return new PolynomialVariable( PolynomialVariable.Var.valueOf( name ), hasParentheses ); } catch( Exception e ) { return new DoubleVariable( name, hasParentheses ); } } public static int createInteger( String text ) { try { return Integer.parseInt( text ); } catch( NumberFormatException nfe ) { return 0; } } } start returns [ PolynomialOperation op ] : e = expr { $op = $e.op; } ; expr returns [ PolynomialOperation op, Integer decimal ] : ( p = PARENTHESES )? ^( PLUS e1 = expr e2 = expr ) { try { $op = new DoubleBinaryOperation( DoubleBinaryOperation.Op.add, ( DoubleOperation ) $e1.op, ( DoubleOperation ) $e2.op, p != null ); } catch( ClassCastException cce ) { $op = new PolynomialAddition( $e1.op, $e2.op, p != null ); } } | ( p = PARENTHESES )? ^( MINUS e1 = expr ( e2 = expr )? ) { if( e2 != null ) { // subtraction try { $op = new DoubleBinaryOperation( DoubleBinaryOperation.Op.sub, ( DoubleOperation ) $e1.op, ( DoubleOperation ) $e2.op, p != null ); } catch( ClassCastException cce ) { $op = new PolynomialSubtraction( $e1.op, $e2.op, p != null ); } } else { try { $op = new DoubleUnaryOperation( DoubleUnaryOperation.Op.neg, ( DoubleOperation ) $e1.op, p != null ); } catch( ClassCastException cce ) { $op = new PolynomialNegation( $e1.op, p != null ); } } } | ( p = PARENTHESES )? ^( MULT e1 = expr e2 = expr ) { try { $op = new DoubleBinaryOperation( DoubleBinaryOperation.Op.mult, ( DoubleOperation ) $e1.op, ( DoubleOperation ) $e2.op ); } catch( ClassCastException cce ) { $op = new PolynomialMultiplication( $e1.op, $e2.op, p != null ); } } | ( p = PARENTHESES )? ^( DIV e1 = expr e2 = expr ) { try { $op = new DoubleBinaryOperation( DoubleBinaryOperation.Op.div, ( DoubleOperation ) $e1.op, ( DoubleOperation ) $e2.op, p != null ); } catch( ClassCastException cce1 ) { try { $op = new PolynomialDoubleDivision( $e1.op, ( DoubleOperation ) $e2.op, p != null ); } catch( ClassCastException cce2 ) { throw new RecognitionException(); } } } | ( p = PARENTHESES )? ^( POW e1 = expr e2 = expr ) { try { $op = new DoubleBinaryOperation( DoubleBinaryOperation.Op.pow, ( DoubleOperation ) $e1.op, ( DoubleOperation ) $e2.op, p != null ); } catch( ClassCastException cce ) { if( $e2.decimal == null ) { throw new RecognitionException(); } else { $op = new PolynomialPower( $e1.op, $e2.decimal, p != null ); } } } | ( p = PARENTHESES )? ^( id = IDENTIFIER e1 = expr ( e2 = expr )? ) { if( e2 != null ) { try { $op = new DoubleBinaryOperation( DoubleBinaryOperation.Op.valueOf( $id.text ), ( DoubleOperation ) $e1.op, ( DoubleOperation ) $e2.op, p != null ); } catch( ClassCastException cce ) { throw new RecognitionException(); } catch( IllegalArgumentException iae ) { throw new RecognitionException(); } } else { try { $op = new DoubleUnaryOperation( DoubleUnaryOperation.Op.valueOf( $id.text ), ( DoubleOperation ) $e1.op, p != null ); } catch( ClassCastException cce ) { throw new RecognitionException(); } catch( IllegalArgumentException iae ) { throw new RecognitionException(); } } } | pe = primary_expr { $op = $pe.op; $decimal = pe.decimal; } ; primary_expr returns [ PolynomialOperation op, Integer decimal ] : ( p = PARENTHESES )? i = DECIMAL_LITERAL { $op = new DoubleValue( $i.text, p != null ); $decimal = Integer.valueOf( createInteger( $i.text ) ); } | ( p = PARENTHESES )? f = FLOATING_POINT_LITERAL { $op = new DoubleValue( $f.text, p != null ); } | ( p = PARENTHESES )? id = IDENTIFIER { $op = createVariable( $id.text, p != null ); } ; jsurf-alggeo-0.4.1+ds/src/main/java/000077500000000000000000000000001330553604100171375ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/000077500000000000000000000000001330553604100175275ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/000077500000000000000000000000001330553604100203105ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/000077500000000000000000000000001330553604100214415ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/Main.java000066400000000000000000000272401330553604100231750ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf; import java.awt.Point; import java.awt.geom.AffineTransform; import java.awt.image.*; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; import java.io.OutputStream; import java.util.Properties; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.SwingUtilities; import org.apache.commons.io.FilenameUtils; import org.apache.commons.cli.*; import javax.imageio.*; import javax.imageio.metadata.*; import javax.imageio.stream.*; import java.util.Date; import java.util.TimeZone; import java.text.SimpleDateFormat; import java.util.Locale; import de.mfo.jsurf.rendering.cpu.AntiAliasingPattern; import de.mfo.jsurf.rendering.cpu.CPUAlgebraicSurfaceRenderer; import de.mfo.jsurf.rendering.cpu.CPUAlgebraicSurfaceRenderer.AntiAliasingMode; import de.mfo.jsurf.util.FileFormat; public class Main { public static final String jsurf_progname = "jsurf"; static int size = 512; static int quality = 1; static AntiAliasingMode aam; static AntiAliasingPattern aap; static CPUAlgebraicSurfaceRenderer asr = new CPUAlgebraicSurfaceRenderer(); static BufferedImage createBufferedImageFromRGB( ImgBuffer ib ) { int w = ib.width; int h = ib.height; DirectColorModel colormodel = new DirectColorModel( 24, 0xff0000, 0xff00, 0xff ); SampleModel sampleModel = colormodel.createCompatibleSampleModel( w, h ); DataBufferInt data = new DataBufferInt( ib.rgbBuffer, w * h ); WritableRaster raster = WritableRaster.createWritableRaster( sampleModel, data, new Point( 0, 0 ) ); return new BufferedImage( colormodel, raster, false, null ); } public static BufferedImage flipV( BufferedImage bi ) { AffineTransform tx = AffineTransform.getScaleInstance(1, -1); tx.translate( 0, -bi.getHeight(null) ); AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); return op.filter(bi, null); } public static OutputStream writeImage( OutputStream os, BufferedImage bi ) throws Exception { ImageWriter writer = ImageIO.getImageWritersByFormatName( "png" ).next(); ImageWriteParam writeParam = writer.getDefaultWriteParam(); ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType( BufferedImage.TYPE_INT_RGB ); // add metadata // see https://docs.oracle.com/javase/7/docs/api/javax/imageio/metadata/doc-files/png_metadata.html // and https://www.w3.org/TR/PNG/#11textinfo IIOMetadata metadata = writer.getDefaultImageMetadata( typeSpecifier, writeParam ); IIOMetadataNode textEntrySoftware = new IIOMetadataNode( "tEXtEntry" ); textEntrySoftware.setAttribute( "keyword", "Software" ); textEntrySoftware.setAttribute( "value", jsurf_progname + " version " + Main.class.getPackage().getImplementationVersion() + " (http://imaginary.org/program/jsurf)" ); TimeZone tz = TimeZone.getTimeZone("UTC"); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ"); df.setTimeZone(tz); Date theDate; // use either current time or the timestamp stored in the environment variable // SOURCE_DATE_EPOCH for reproducible builds if( System.getenv( "SOURCE_DATE_EPOCH" ) == null ) theDate = new Date(); else theDate = new Date( Long.parseLong( System.getenv( "SOURCE_DATE_EPOCH" ) ) * 1000 ); IIOMetadataNode textEntryCreationTime = new IIOMetadataNode( "tEXtEntry" ); textEntryCreationTime.setAttribute( "keyword", "CreationTime" ); textEntryCreationTime.setAttribute( "value", df.format( theDate ) ); IIOMetadataNode textEntrySource = new IIOMetadataNode( "tEXtEntry" ); textEntrySource.setAttribute( "keyword", "Source" ); textEntrySource.setAttribute( "value", jsurf_progname + " settings: --quality " + quality ); IIOMetadataNode text = new IIOMetadataNode( "tEXt" ); text.appendChild( textEntrySoftware ); text.appendChild( textEntryCreationTime ); text.appendChild( textEntrySource ); IIOMetadataNode root = new IIOMetadataNode( "javax_imageio_png_1.0" ); root.appendChild( text ); metadata.mergeTree( "javax_imageio_png_1.0", root ); // write the image and meta data ImageOutputStream image_os = ImageIO.createImageOutputStream( os ); writer.setOutput( image_os ); writer.write( metadata, new IIOImage( bi, null, metadata ), writeParam ); image_os.close(); return os; } /** * @param args */ public static void main(String[] args) { int helper_width = 103; String jsurf_filename = null; String output_filename = null; boolean show_gui = false; Options options = new Options(); options.addOption( OptionBuilder.withLongOpt( "help" ).withDescription( "display this help text and exit" ).create() ); options.addOption( OptionBuilder.withLongOpt( "version" ).withDescription( "print program version and exit" ).create() ); options.addOption("s","size", true, "image width and height (default: " + size + ")"); options.addOption("q","quality",true,"quality of the rendering: 0 (low), 1 (medium, default), 2 (high), 3 (extreme)"); options.addOption("o","output",true,"output PNG into this file (overrode by the 2nd argument if present)"); options.addOption( OptionBuilder.withLongOpt( "gui" ).withDescription( "display rendering (overrides output options)" ).create() ); CommandLineParser parser = new PosixParser(); HelpFormatter formatter = new HelpFormatter(); String cmd_line_syntax = jsurf_progname + " [options...] {jsurf_input|-} [png_output|-]\n\n"; String help_header = jsurf_progname + " is a renderer for real algebraic surfaces.\n" + jsurf_progname + " translates its own language script files (generally with extension '.jsurf') into Portable Network Graphics (PNG) files; " + "PNG is a raster graphics file format that supports lossless data compression.\n" + "If the output filename is not specified, the output is placed in a file of the same basename with a '.png' extension in the current working directory.\n" + "Either the input filename or the output filename can be '-' to request reading from stdin or writing to stdout, respectively. " + "Whenever the Graphic Unit Interface (GUI) is available, the gui option takes precedence over the output options, otherwise it is ignored. " + "That is, whenever the gui option is present (and available), the output is displayed in a window rather than written to a PNG file.\n" + "\n" ; String help_footer = ""; try { CommandLine cmd = parser.parse( options, args ); if( cmd.hasOption( "help" ) ) { formatter.printHelp( helper_width, cmd_line_syntax, help_header, options, help_footer ); return; } if( cmd.hasOption( "version" ) ) { System.out.println( Main.class.getPackage().getImplementationVersion() ); return; } if( cmd.hasOption( "output" ) ) output_filename = cmd.getOptionValue("output"); if( cmd.hasOption("size") ) size = Integer.parseInt( cmd.getOptionValue("size") ); if( cmd.hasOption("quality") ) quality = Integer.parseInt( cmd.getOptionValue( "quality" ) ); switch( quality ) { case 0: aam = AntiAliasingMode.ADAPTIVE_SUPERSAMPLING; aap = AntiAliasingPattern.OG_1x1; break; case 2: aam = AntiAliasingMode.ADAPTIVE_SUPERSAMPLING; aap = AntiAliasingPattern.OG_4x4; break; case 3: aam = AntiAliasingMode.SUPERSAMPLING; aap = AntiAliasingPattern.OG_4x4; break; case 1: aam = AntiAliasingMode.ADAPTIVE_SUPERSAMPLING; aap = AntiAliasingPattern.QUINCUNX; } if( cmd.hasOption( "gui" ) ) show_gui = !java.awt.GraphicsEnvironment.isHeadless() ; if( cmd.getArgs().length == 0 || cmd.getArgs().length > 2 ) { formatter.printHelp( helper_width, cmd_line_syntax, help_header, options, help_footer ); System.exit( -1 ); } else { jsurf_filename = cmd.getArgs()[ 0 ]; if (!show_gui) { if( cmd.getArgs().length > 1 ) output_filename = cmd.getArgs()[ 1 ]; if( output_filename == null ) { output_filename = FilenameUtils.getBaseName( jsurf_filename ) + ".png" ; } } else { output_filename = null ; } } } catch( ParseException exp ) { System.out.println( "Unexpected exception:" + exp.getMessage() ); System.exit( -1 ); } catch( NumberFormatException nfe ) { formatter.printHelp( cmd_line_syntax, help_header, options, help_footer ); System.exit( -1 ); } try { Properties jsurf = new Properties(); if( jsurf_filename.equals( "-" ) ) jsurf.load( System.in ); else jsurf.load( new FileReader( jsurf_filename ) ); FileFormat.load( jsurf, asr ); } catch( Exception e ) { System.err.println( "Unable to read jsurf file " + jsurf_filename ); e.printStackTrace(); System.exit( -2 ); } asr.setAntiAliasingMode( aam ); asr.setAntiAliasingPattern( aap ); BufferedImage bi = null; try { ImgBuffer ib = new ImgBuffer( size, size ); asr.draw( ib.rgbBuffer, size, size ); bi = flipV( createBufferedImageFromRGB( ib ) ); } catch( Exception e ) { System.err.println( "An error occurred during rendering." ); e.printStackTrace(); System.exit( -3 ); } if( output_filename != null ) { // save to file try { OutputStream os; if( output_filename.equals( "-" ) ) os = System.out; else os = new FileOutputStream( new File( output_filename ) ); writeImage( os, bi ); os.flush(); os.close(); } catch( Exception e ) { System.err.println( "Unable to save to file " + output_filename ); e.printStackTrace(); System.exit( -4 ); } } if( show_gui ) { // display the image in a window final String window_title = jsurf_progname + ": " + FilenameUtils.getBaseName( jsurf_filename ) + " (" + FilenameUtils.getFullPathNoEndSeparator( jsurf_filename ) + ")" ; final BufferedImage window_image = bi; SwingUtilities.invokeLater( new Runnable() { public void run() { JFrame f = new JFrame( window_title ); f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); f.getContentPane().add( new JLabel( new ImageIcon( window_image ) ) ); f.pack(); f.setResizable( false ); f.setVisible( true ); } }); } } } class ImgBuffer { public int[] rgbBuffer; public int width; public int height; public ImgBuffer( int w, int h ) { rgbBuffer = new int[ 3 * w * h ]; width = w; height = h; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/000077500000000000000000000000001330553604100230365ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/AbstractVisitor.java000066400000000000000000000017311330553604100270260ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public abstract class AbstractVisitor< RETURN_TYPE, PARAM_TYPE > implements Visitor< RETURN_TYPE, PARAM_TYPE > { public RETURN_TYPE visit( PolynomialOperation pop, PARAM_TYPE param ) { throw new UnsupportedOperationException(); } public RETURN_TYPE visit( DoubleOperation dop, PARAM_TYPE param ) { throw new UnsupportedOperationException(); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/AffineDecomposition.java000077500000000000000000000613121330553604100276340ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import javax.vecmath.*; public class AffineDecomposition { static public class AffineParts { public Vector3d t; /* Translation components */ public Quat4d q; /* Essential rotation */ public Quat4d u; /* Stretch rotation */ public Vector3d k; /* Stretch factors */ public double f; /* Sign of determinant */ public String toString() { String result = ""; result += "t=" + t + "\n"; result += "q=" + q + "\n"; result += "u=" + u + "\n"; result += "k=" + k + "\n"; result += "f=" + f; return result; } } public static AffineParts decompAffine( Matrix4d A ) { AffineDecompositionFromCCode.AffineParts ap = new AffineDecompositionFromCCode.AffineParts(); AffineDecompositionFromCCode.decomp_affine( toHMatrix( A ), ap ); AffineParts result = new AffineParts(); result.t = toVector3d( ap.t ); result.q = toQuat4d( ap.q ); result.u = toQuat4d( ap.u ); result.k = toVector3d( ap.k ); result.f = ap.f; return result; } static AffineDecompositionFromCCode.HMatrix toHMatrix( Matrix4d A ) { double[][] m = new double[ 4 ][ 4 ]; A.getRow( 0, m[ 0 ] ); A.getRow( 1, m[ 1 ] ); A.getRow( 2, m[ 2 ] ); A.getRow( 3, m[ 3 ] ); return new AffineDecompositionFromCCode.HMatrix( m ); } static Quat4d toQuat4d( AffineDecompositionFromCCode.Quat q ) { return new Quat4d( q.x, q.y, q.z, q.w ); } static Vector3d toVector3d( AffineDecompositionFromCCode.HVect v ) { return new Vector3d( v.x, v.y, v.z ); } } class AffineDecompositionFromCCode { static class Quat { public double x, y, z, w; public Quat() {}; public Quat( double x, double y, double z, double w ) { this.x = x; this.y = y; this.z = z; this.w = w; } } static class HVect extends Quat { public HVect() { super(); } public HVect( double x, double y, double z, double w ) { super( x,y,z,w ); } } static final int X = 0; static final int Y = 1; static final int Z = 2; static final int W = 3; static class HMatrix { public double[][] m; public HMatrix() { m = new double[ 4 ][ 4 ]; } public HMatrix( double[][] m ) { this.m = m; } } static class AffineParts { HVect t; /* Translation components */ Quat q; /* Essential rotation */ Quat u; /* Stretch rotation */ HVect k; /* Stretch factors */ double f; /* Sign of determinant */ public AffineParts() { t = new HVect(); q = new Quat(); u = new Quat(); k = new HVect(); } } /******* Matrix Preliminaries *******/ /** Fill out 3x3 matrix to 4x4 **/ static void mat_pad( HMatrix A ) { A.m[W][X]=A.m[X][W]=A.m[W][Y]=A.m[Y][W]=A.m[W][Z]=A.m[Z][W]=0; A.m[W][W]=1; } /** Copy nxn matrix A to C using "=" for assignment **/ static void mat_copy_assign( HMatrix C, HMatrix A, int n ) { int i,j; for(i=0;i 0 ) // Polynomial not squarefree! p = p.div( gcd ); } double[] negRoots = findAllNegRootsIn( p, lowerBound, upperBound ); double[] posRoots = findAllPosRootsIn( p, lowerBound, upperBound ); double[] roots = new double[ negRoots.length + posRoots.length ]; System.arraycopy( negRoots, 0, roots, 0, negRoots.length ); System.arraycopy( posRoots, 0, roots, negRoots.length, posRoots.length ); return roots; } double[] findAllPosRootsIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { if( upperBound < 0.0 ) return new double[ 0 ]; double bound2 = nextPowerOfTwo( upperBound ); p = p.shrink(); double tlb = lowerBound / bound2; double tub = upperBound / bound2; // move all roots in (0,upperBound) into (0,1) p = p.stretch( bound2 ); double[] results = new double[ p.degree() ]; int results_length = 0; if( p.getCoeff( 0 ) == 0.0 ) { if( lowerBound <= 0.0 ) results[ results_length++ ] = 0.0; p = new UnivariatePolynomial( deflate0( p.getCoeffs() ) ); } if( lowerBound < 0.0 ) lowerBound = 0.0; if( results_length != results.length ) { // isolate and refine all roots in (0,1) PolyInterval[] cand = new PolyInterval[ 10 ]; int cand_length = 0; cand[ cand_length++ ] = new PolyInterval( p.getCoeff( 0 ) == 0.0 ? deflate0( p.getCoeffs() ) : p.getCoeffs(), 0.0, 1.0 ); while( cand_length != 0 ) { PolyInterval pi = cand[ --cand_length ]; if( results_length == results.length ) break; int v = countSignChanges( pi.a ); if( v == 1 ) { double tmp_root = adjustIntervalAndBisect( p, pi.l, pi.u, tlb, tub ) * bound2; if( !java.lang.Double.isNaN( tmp_root ) ) results[ results_length++ ] = tmp_root; } if( results_length == results.length ) break; else if( v > 1 ) { // evtl. mehr als eine NST in (0,1) -> teile Interval (0,1) in zwei teile double c = 0.5 * ( pi.l + pi.u ); if( Math.abs( pi.u - pi.l ) < 0.5 * EPSILON ) // we have reached maximum precision { if( pi.l <= tlb ) results[ results_length++ ] = lowerBound; else results[ results_length++ ] = pi.l * bound2; continue; } if( cand_length + 2 >= cand.length ) { // resize candidate stack PolyInterval[] newCand = new PolyInterval[ 2 * cand.length ]; System.arraycopy( cand, 0, newCand, 0, cand.length ); cand = newCand; } double[] first = pi.a; double[] second = new double[ pi.a.length ]; deCasteljau( first, second ); if( c <= tub ) cand[ cand_length++ ] = new PolyInterval( second, c, pi.u ); if( c >= tlb ) cand[ cand_length++ ] = new PolyInterval( first, pi.l, c ); } } } double[] roots = new double[ results_length ]; System.arraycopy( results, 0, roots, 0, results_length ); return roots; } double[] findAllNegRootsIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { if( lowerBound >= 0.0 ) return new double[ 0 ]; // map the negative roots on positive ones, find them and transform back p = p.stretch( -1.0 ); double[] roots = findAllPosRootsIn( p, -upperBound, -lowerBound ); for( int i = 0, j = roots.length - 1; i < ( roots.length + 1 ) / 2; ++i, --j ) { // reverse order and negate elements double tmp = -roots[ i ]; roots[ i ] = -roots[ j ]; roots[ j ] = tmp; } return roots; } enum WhichRoot { SMALLEST, LARGEST }; /** * Find the smallest real root of p within lowerBound and upperBound (bounds may or may not be included). * If no real root exists in this interval, Double.NaN ist returned. * @param p * @param lowerBound * @param upperBound * @return */ public double findFirstRootIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { if( makeSquarefree ) { // make p squarefree UnivariatePolynomial gcd = UnivariatePolynomial.gcd( p, p.derive() ); if( gcd.degree() > 0 ) // Polynomial not squarefree! p = p.div( gcd ); } double root = -findPosRootIn( p.stretch( -1.0 ), -upperBound, -lowerBound, WhichRoot.LARGEST ); return java.lang.Double.isNaN( root ) ? findPosRootIn( p, lowerBound, upperBound, WhichRoot.SMALLEST ) : root; } double findPosRootIn( UnivariatePolynomial p, double lowerBound, double upperBound, WhichRoot w ) { if( upperBound <= 0.0 || p.degree() == 0 ) return java.lang.Double.NaN; p = p.shrink(); double bound2 = nextPowerOfTwo( upperBound ); double tlb = lowerBound / bound2; double tub = upperBound / bound2; // move all roots in (0,bound2) into (0,1) p = p.stretch( bound2 ); double tmp_result = java.lang.Double.NaN; if( p.getCoeff( 0 ) == 0.0 ) { if( lowerBound <= 0.0 ) { if( w == WhichRoot.SMALLEST ) return 0.0; else tmp_result = 0.0; } p = new UnivariatePolynomial( deflate0( p.getCoeffs() ) ); } if( lowerBound <= 0.0 ) lowerBound = 0.0; // isolate and refine first root in (0,1) PolyInterval[] cand = new PolyInterval[ 10 ]; int cand_length = 0; cand[ cand_length++ ] = new PolyInterval( bernsteinCoefficients( p.getCoeffs() ), 0.0, 1.0 ); while( cand_length != 0 ) { PolyInterval pi = cand[ --cand_length ]; if( pi.a[ 0 ] == 0.0 ) { double tmp_root = pi.l * bound2; if( lowerBound <= tmp_root && tmp_root <= upperBound ) { if( w == WhichRoot.SMALLEST ) return pi.l * bound2; else tmp_result = tmp_root; pi.a = deflate0( pi.a ); } } int v = countSignChanges( pi.a ); if( v == 1 ) { double tmp_root = adjustIntervalAndBisect( p, pi.l, pi.u, tlb, tub ) * bound2; if( !java.lang.Double.isNaN( tmp_root ) ) return tmp_root; } else if( v > 1 ) { // evtl. mehr als eine NST in (0,1) -> teile Interval (0,1) in zwei teile double c = 0.5 * ( pi.l + pi.u ); if( Math.abs( pi.u - pi.l ) < 0.5 * EPSILON ) // we have reached maximum precision { if( pi.l <= tlb ) return lowerBound; else return pi.l * bound2; } if( cand_length + 2 >= cand.length ) { // resize candidate stack PolyInterval[] newCand = new PolyInterval[ 2 * cand.length ]; System.arraycopy( cand, 0, newCand, 0, cand.length ); cand = newCand; } double[] first = pi.a; double[] second = new double[ pi.a.length ]; deCasteljau( first, second ); if( w == WhichRoot.SMALLEST ) { // search interval with smallest lower bound first if( c <= tub ) cand[ cand_length++ ] = new PolyInterval( second, c, pi.u ); if( c >= tlb ) cand[ cand_length++ ] = new PolyInterval( first, pi.l, c ); } else { // search interval with largest lower bound first if( c >= tlb ) cand[ cand_length++ ] = new PolyInterval( first, pi.l, c ); if( c <= tub ) cand[ cand_length++ ] = new PolyInterval( second, c, pi.u ); } } } return tmp_result; } private static double adjustIntervalAndBisect( UnivariatePolynomial p, double lowerBound, double upperBound, double strictLowerBound, double strictUpperBound ) { double fl = p.evaluateAt( lowerBound ); if( lowerBound < strictLowerBound ) { // intervals overlap if( upperBound < strictLowerBound ) return java.lang.Double.NaN; // search interval and strict interval do not overlap else { double fsl = p.evaluateAt( strictLowerBound ); if( fl * fsl < 0.0 || fl == 0.0 ) return java.lang.Double.NaN; // root is below strictLowerBound else { lowerBound = strictLowerBound; // root is between strictLowerBound and upperBound fl = fsl; } } } double fu = p.evaluateAt( upperBound ); if( strictUpperBound < upperBound ) { // intervals overlap if( strictUpperBound < lowerBound ) return java.lang.Double.NaN; // search interval and strict interval do not overlap else { double fsu = p.evaluateAt( strictUpperBound ); if( fu * fsu < 0.0 || fu == 0.0 ) return java.lang.Double.NaN; // root is above strictLowerBound else { upperBound = strictUpperBound; fu = fsu; } } } return bisect( p, lowerBound, upperBound, fl, fu ); } private double[] deflate0( double[] a ) { if( a.length == 0 ) return a; double[] deflated_a = new double[ a.length - 1 ]; System.arraycopy( a, 1, deflated_a, 0, deflated_a.length ); return deflated_a; } private static double bisect( UnivariatePolynomial p, double lowerBound, double upperBound ) { return bisect( p, lowerBound, upperBound, p.evaluateAt( lowerBound ), p.evaluateAt( upperBound ) ); } private static double bisect( UnivariatePolynomial p, double lowerBound, double upperBound, double fl, double fu ) { double[] a = p.getCoeffs(); assert fl * fu < 0.0 : "tried bisection on interval without sign change"; while( Math.abs( upperBound - lowerBound ) > EPSILON ) { double center = 0.5 * ( lowerBound + upperBound ); double fc = a[ a.length - 1 ]; for( int i = a.length - 2; i >= 0; i-- ) fc = fc * center + a[ i ]; if( fc * fl < 0.0 ) { upperBound = center; fu = fc; } else if( fc == 0.0 ) { return center; } else { lowerBound = center; fl = fc; } } return lowerBound; } static double nextPowerOfTwo( double d ) // computes the next power of two with respect to outward rounding { long bits = java.lang.Double.doubleToLongBits( d ); if( ( bits & 0x000fffffffffffffL ) != 0L ) { bits = java.lang.Double.doubleToLongBits( 2.0 * d ); // "round up" -> increase exponent by one bits &= 0xfff0000000000000L; // remove mantissa bits } return java.lang.Double.longBitsToDouble( bits ); } private int countSignChanges( double[] a ) { int signChanges = 0; double lastNonZeroCoeff = java.lang.Double.NaN; for( int i = 1; i <= a.length; i++ ) { if( a[ i - 1 ] != 0.0 ) { if( a[ i - 1 ] * lastNonZeroCoeff < 0.0 ) signChanges++; if( signChanges > 1 ) return signChanges; lastNonZeroCoeff = a[ i - 1 ]; } } return signChanges; } /** * Computes new Bernstein coefficients for a basis in the interval (0,0.5) and (0.5,1). * @param a Input coefficients and output for (0,0.5) * @param b output for (0.5,1) */ private void deCasteljau( double a[], double[] b ) { b[ a.length - 1 ] = a[ a.length - 1 ]; for( int i = 1; i < a.length; i++ ) { for( int j = a.length - 1; j >= i; j-- ) a[ j ] = ( a[ j - 1 ] + a[ j ] ) * 0.5; b[ a.length - 1 - i ] = a[ a.length - 1 ]; } } private double[] bernsteinCoefficients( double a[] ) { double[] result = new double[ a.length ]; for( int i = 0; i < a.length; i++ ) result[ i ] = a[ i ] / MultinomialCoefficients.binomialCoefficient( a.length - 1, i ); for( int i = 1; i < a.length; i++ ) for( int j = a.length - 1; j >= i; j-- ) result[ j ] = result[ j - 1 ] + result[ j ]; return result; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/CloneVisitor.java000066400000000000000000000056751330553604100263360ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class CloneVisitor extends AbstractVisitor< PolynomialOperation, Void > { public PolynomialOperation visit( PolynomialAddition pa, Void param ) { return new PolynomialAddition( pa.getFirstOperand().accept( this, ( Void ) null ), pa.getSecondOperand().accept( this, ( Void ) null ) ); } public PolynomialOperation visit( PolynomialSubtraction ps, Void param ) { return new PolynomialSubtraction( ps.getFirstOperand().accept( this, ( Void ) null ), ps.getSecondOperand().accept( this, ( Void ) null ) ); } public PolynomialOperation visit( PolynomialMultiplication pm, Void param ) { return new PolynomialMultiplication( pm.getFirstOperand().accept( this, ( Void ) null ), pm.getSecondOperand().accept( this, ( Void ) null ) ); } public PolynomialOperation visit( PolynomialPower pp, Void param ) { return new PolynomialPower( pp.getBase().accept( this, ( Void ) null ), pp.getExponent() ); } public PolynomialOperation visit( PolynomialNegation pn, Void param ) { return new PolynomialNegation( pn.getOperand().accept( this, ( Void ) null ) ); } public PolynomialOperation visit( PolynomialDoubleDivision pdd, Void param ) { return new PolynomialDoubleDivision( pdd.getDividend().accept( this, ( Void ) null ), ( DoubleOperation ) pdd.getDivisor().accept( this, ( Void ) null ) ); } public PolynomialOperation visit( PolynomialVariable pv, Void param ) { return pv; } public DoubleOperation visit( DoubleBinaryOperation dbop, Void param ) { DoubleOperation firstOperand = ( DoubleOperation ) dbop.getFirstOperand().accept( this, ( Void ) null ); DoubleOperation secondOperand = ( DoubleOperation ) dbop.getSecondOperand().accept( this, ( Void ) null ); return new DoubleBinaryOperation( dbop.getOperator(), firstOperand, secondOperand ); } public DoubleOperation visit( DoubleUnaryOperation duop, Void param ) { return new DoubleUnaryOperation( duop.getOperator(), ( DoubleOperation ) duop.getOperand().accept( this, ( Void ) null ) ); } public DoubleOperation visit( DoubleValue dv, Void param ) { return dv; } public DoubleOperation visit( DoubleVariable dv, Void param ) { return new DoubleVariable( dv.getName() ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/ClosedFormRootFinder.java000066400000000000000000000173371330553604100277450ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; /** * Calculates the roots of polynomials up to degree 4 by closed form solutions. * Implementation is a modified version of the code presented in Graphics Gems * (http://read.pudn.com/downloads21/sourcecode/graph/71499/gems/Roots3And4.c__.htm). * The solver reports m-fold roots m times. * @author stussak */ public class ClosedFormRootFinder implements RealRootFinder { public double[] findAllRoots( UnivariatePolynomial p ) { switch( p.degree() ) { case 0: return new double[ 0 ]; case 1: return solveLinear( p ); case 2: return solveQuadric( p ); case 3: return solveCubic( p ); case 4: return solveQuartic( p ); default: throw new IllegalArgumentException( "no closed form solution exists for polynomials of degree > 4" ); } } public double[] findAllRootsIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { return clip( findAllRoots( p ), lowerBound, upperBound ); } public double findFirstRootIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { double[] roots = clip( findAllRoots( p ), lowerBound, upperBound ); return roots.length > 0 ? roots[ 0 ] : java.lang.Double.NaN; } private double[] solveLinear( UnivariatePolynomial poly ) { double[] roots = new double[ 1 ]; roots[ 0 ] = -poly.getCoeff( 0 ) / poly.getCoeff( 1 ); return roots; } private double[] solveQuadric( UnivariatePolynomial poly ) { /* normal form: x^2 + px + q = 0 */ double p = poly.getCoeff( 1 ) / (2 * poly.getCoeff( 2 ) ); double q = poly.getCoeff( 0 ) / poly.getCoeff( 2 ); double D = p * p - q; int num_roots = 0; if( isZero( D ) ) return solutions( -p, -p ); else if (D < 0) return solutions(); else // D > 0 { double sqrt_D = Math.sqrt(D); return solutions( sqrt_D - p, - sqrt_D - p ); } } double[] solveCubic( UnivariatePolynomial poly ) { /* normal form: x^3 + Ax^2 + Bx + C = 0 */ double A = poly.getCoeff( 2 ) / poly.getCoeff( 3 ); double B = poly.getCoeff( 1 ) / poly.getCoeff( 3 ); double C = poly.getCoeff( 0 ) / poly.getCoeff( 3 ); /* substitute x = y - A/3 to eliminate quadric term: x^3 +px + q = 0 */ double sq_A = A * A; double p = 1.0/3 * (- 1.0/3 * sq_A + B); double q = 1.0/2 * (2.0/27 * A * sq_A - 1.0/3 * A * B + C); /* use Cardano's formula */ double cb_p = p * p * p; double D = q * q + cb_p; double[] roots; if( isZero( D ) ) { if( isZero( q ) ) /* one triple solution */ roots = solutions( 0.0, 0.0, 0.0 ); else /* one single and one double solution */ { double u = cbrt(-q ); roots = solutions( 2 * u, -u, -u ); } } else if( D < 0 ) /* Casus irreducibilis: three real solutions */ { double phi = 1.0/3 * Math.acos(-q / Math.sqrt(-cb_p)); double t = 2 * Math.sqrt(-p); roots = solutions( t * Math.cos(phi), - t * Math.cos(phi + Math.PI / 3 ), - t * Math.cos(phi - Math.PI / 3 )); } else /* one real solution */ { double sqrt_D = Math.sqrt(D); double u = cbrt(sqrt_D - q); roots = solutions( cbrt( sqrt_D - q ) - cbrt( sqrt_D + q ) ); } /* resubstitute */ double sub = 1.0/3 * A; for( int i = 0; i < roots.length; ++i ) roots[ i ] -= sub; return roots; } double[] solveQuartic( UnivariatePolynomial poly ) { /* normal form: x^4 + Ax^3 + Bx^2 + Cx + D = 0 */ double A = poly.getCoeff( 3 ) / poly.getCoeff( 4 ); double B = poly.getCoeff( 2 ) / poly.getCoeff( 4 ); double C = poly.getCoeff( 1 ) / poly.getCoeff( 4 ); double D = poly.getCoeff( 0 ) / poly.getCoeff( 4 ); /* substitute x = y - A/4 to eliminate cubic term: x^4 + px^2 + qx + r = 0 */ double sq_A = A * A; double p = - 3.0/8 * sq_A + B; double q = 1.0/8 * sq_A * A - 1.0/2 * A * B + C; double r = - 3.0/256*sq_A*sq_A + 1.0/16*sq_A*B - 1.0/4*A*C + D; double[] roots; if( isZero( r ) ) { /* no absolute term: y(y^3 + py + q) = 0 */ UnivariatePolynomial cubic = new UnivariatePolynomial( q, p, 0, 1 ); roots = solveCubic( cubic ); roots = solutions( roots[ 0 ], roots[ 1 ], roots[ 2 ], 0 ); } else { /* solve the resolvent cubic ... */ UnivariatePolynomial cubic = new UnivariatePolynomial( 1.0/2 * r * p - 1.0/8 * q * q, -r, - 1.0/2 * p, 1 ); roots = solveCubic( cubic ); /* ... and take the one real solution ... */ double z = roots[ 0 ]; /* ... to build two quadric equations */ double u = z * z - r; double v = 2 * z - p; if (isZero(u)) u = 0; else if (u > 0) u = Math.sqrt(u); else return solutions(); if (isZero(v)) v = 0; else if (v > 0) v = Math.sqrt(v); else return solutions(); UnivariatePolynomial quadric1 = new UnivariatePolynomial( z - u, q < 0 ? -v : v, 1 ); double[] roots1 = solveQuadric( quadric1 ); UnivariatePolynomial quadric2 = new UnivariatePolynomial( z + u, q < 0 ? v : -v, 1 ); double[] roots2 = solveQuadric( quadric2 ); roots = new double[ roots1.length + roots2.length ]; System.arraycopy( roots1, 0, roots, 0, roots1.length ); System.arraycopy( roots2, 0, roots, roots1.length, roots2.length ); } /* resubstitute */ double sub = 1.0/4 * A; for( int i = 0; i < roots.length; ++i ) roots[ i ] -= sub; java.util.Arrays.sort( roots ); return roots; } private static double cbrt( double x ) { return x >= 0.0 ? Math.pow( x , 1.0/3.0 ) : -Math.pow(-x, 1.0/3.0); } private static boolean isZero( double d ) { return -1e-20 < d && d < 1e-20; } //{ return -1e-9 < d && d < 1e-9; } public static double[] solutions( double ... s ) { java.util.Arrays.sort( s ); return s; } // simplified array initialization private static double[] clip( double[] d, double l, double u ) { double[] tmp_result = new double[ d.length ]; int length = 0; for( int i = 0; i < d.length; ++i ) if( l <= d[ i ] && d[ i ] <= u ) tmp_result[ length++ ] = d[ i ]; if( length == tmp_result.length ) return tmp_result; else { double[] result = new double[ length ]; System.arraycopy( tmp_result, 0, result, 0, length ); return result; } } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/CoefficientCalculator.java000066400000000000000000000014441330553604100301340ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public interface CoefficientCalculator { public UnivariatePolynomial calculateCoefficients( UnivariatePolynomial x, UnivariatePolynomial y, UnivariatePolynomial z ); } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/ColumnSubstitutor.java000066400000000000000000000013211330553604100274230ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public interface ColumnSubstitutor { public UnivariatePolynomial setU( double u ); } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/ColumnSubstitutorForGradient.java000066400000000000000000000013441330553604100315550ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public interface ColumnSubstitutorForGradient { public UnivariatePolynomialVector3d setU( double u ); } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/DChainRootFinder.java000066400000000000000000000273451330553604100270360ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class DChainRootFinder implements RealRootFinder { private class SearchStruct { UnivariatePolynomial poly; double smallestPossibleRoot; double valueAtSmallestPossibleRoot; public SearchStruct( UnivariatePolynomial poly, double smallestPossibleRoot ) { this.poly = poly; this.smallestPossibleRoot = smallestPossibleRoot; this.valueAtSmallestPossibleRoot = poly.evaluateAt( smallestPossibleRoot ); } } public double[] findAllRoots( UnivariatePolynomial p ) { double rootBound = 0.0; for( int i = 0; i < p.degree(); i++ ) rootBound = Math.max( rootBound, 2 * Math.pow( Math.abs( p.getCoeff( i ) / p.getCoeff( p.degree() ) ), 1.0 / ( p.degree() - i ) ) ); return findAllRootsIn( p, -rootBound, rootBound ); //return findAllRootsIn( p, -Double.MAX_VALUE, Double.MAX_VALUE ); } public double findFirstRootIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { switch( p.degree() ) { case 0: return java.lang.Double.NaN; case 1: { double[] roots = _solveLinear( p.getCoeff( 0 ), p.getCoeff( 1 ), lowerBound, upperBound ); return roots.length > 0 ? roots[ 0 ] : java.lang.Double.NaN; } case 2: { double[] roots = _solveQuadratic( p.getCoeff( 0 ), p.getCoeff( 1 ), p.getCoeff( 2 ), lowerBound, upperBound ); return roots.length > 0 ? roots[ 0 ] : java.lang.Double.NaN; } default: { // use special search algorithm, which calculates the roots // of the derivatives when needed and not always as the findAllRootsIn algorithm does double[] root = new double[ 1 ]; SearchStruct[] searchStruct = new SearchStruct[ p.degree() ]; for( int i = 0; i < searchStruct.length; i++ ) searchStruct[ i ] = new SearchStruct( ( i == 0 ) ? p : searchStruct[ i - 1 ].poly.derive(), lowerBound ); if( _findFirstRootIn( searchStruct, searchStruct.length - 1, upperBound, upperBound, root ) ) return root[ 0 ]; else return java.lang.Double.NaN; // // another possibility: calculate all roots in interval and choose smallest // double[] roots = findAllRootsIn( p, lowerBound, upperBound ); // return roots.length > 0 ? roots[ 0 ] : Double.NaN; } } } private boolean _findFirstRootIn( SearchStruct[] searchStructs, int startWith, double searchUpperBound, double largestPossibleRoot, double[] root ) { SearchStruct ss = searchStructs[ startWith ]; double divider = java.lang.Double.NaN; // calculate root of current polynomial in interval [lowerBound,upperBound) if( ss.poly.degree() == 1 ) { divider = - ss.poly.getCoeff( 0 ) / ss.poly.getCoeff( 1 ); if( divider < ss.smallestPossibleRoot || divider >= searchUpperBound ) divider = java.lang.Double.NaN; } else { double fl = ss.valueAtSmallestPossibleRoot; double fu = ss.poly.evaluateAt( searchUpperBound ); if( fl * fu < 0.0 ) // sign change in interval -> interval contains roots -> refine root with bisection divider = bisect( ss.poly, ss.smallestPossibleRoot, searchUpperBound, fl, fu ); else if( fl == 0.0 ) // root on lower interval bound divider = ss.smallestPossibleRoot; ss.smallestPossibleRoot = searchUpperBound; ss.valueAtSmallestPossibleRoot = fu; } // if base case isn't reached, search for root of lower derivate boolean dividerIsNotNaN = !java.lang.Double.isNaN( divider ); if( startWith == 0 && dividerIsNotNaN ) { root[ 0 ] = divider; return true; } else { return ( dividerIsNotNaN && _findFirstRootIn( searchStructs, startWith - 1, divider, largestPossibleRoot, root ) ) || ( ( searchUpperBound == largestPossibleRoot && startWith != 0 ) && _findFirstRootIn( searchStructs, startWith - 1, largestPossibleRoot, largestPossibleRoot, root ) ); } } public double[] findAllRootsIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { double[] result; switch( p.degree() ) { case 0: result = new double[ 0 ]; break; case 1: result = _solveLinear( p.getCoeff( 0 ), p.getCoeff( 1 ), lowerBound, upperBound ); break; case 2: result = _solveQuadratic( p.getCoeff( 0 ), p.getCoeff( 1 ), p.getCoeff( 2 ), lowerBound, upperBound ); break; default: int[] resultLength = new int[ 1 ]; double[] tmpResult = _findAllRootsIn( p, lowerBound, upperBound, resultLength ); result = new double[ resultLength[ 0 ] - 2 ]; System.arraycopy( tmpResult, 1, result, 0, resultLength[ 0 ] - 2 ); break; } return result; } private double[] _findAllRootsIn( UnivariatePolynomial p, double lowerBound, double upperBound, int[] resultLength ) { double[] roots; if( p.degree() == 1 ) { // base case: solve linear polynomial double root = - p.getCoeff( 0 ) / p.getCoeff( 1 ); roots = new double[ 3 ]; if( lowerBound < root && root < upperBound ) { roots[ 0 ] = lowerBound; roots[ 1 ] = root; roots[ 2 ] = upperBound; resultLength[ 0 ] = 3; } else { roots[ 0 ] = lowerBound; roots[ 1 ] = upperBound; resultLength[ 0 ] = 2; } } else { // find roots between roots of derivative // calculate derivative und its roots UnivariatePolynomial derivative = p.derive(); int[] dRootsLength = new int[ 1 ]; double[] dRoots = _findAllRootsIn( derivative, lowerBound, upperBound, dRootsLength ); roots = new double[ dRootsLength[ 0 ] + 1 ]; roots[ 0 ] = lowerBound; resultLength[ 0 ] = 1; // analyze each interval between roots of derivative for roots of p double fu = p.evaluateAt( dRoots[ 0 ] ); double fl; for( int i = 1; i < dRootsLength[ 0 ]; i++ ) { fl = fu; fu = p.evaluateAt( dRoots[ i ] ); if( fl * fu < 0.0 ) // sign change in interval -> interval contains roots -> refine root with bisection roots[ resultLength[ 0 ]++ ] = bisect( p, dRoots[ i - 1 ], dRoots[ i ], fl, fu ); else if( fl == 0.0 ) // root on lower interval bound roots[ resultLength[ 0 ]++ ] = dRoots[ i - 1 ]; } roots[ resultLength[ 0 ]++ ] = upperBound; } return roots; } private double[] _solveLinear( double a0, double a1, double lowerBound, double upperBound ) { double[] result; double root = - a0 / a1; if( lowerBound < root && root < upperBound ) { result = new double[ 1 ]; result[ 0 ] = root; } else { result = new double[ 0 ]; } return result; } private double[] _solveQuadratic( double a0, double a1, double a2, double lowerBound, double upperBound ) { double diskriminante = a1 * a1 - 4.0 * a2 * a0; if( diskriminante >= 0.0f ) { double q = -0.5 * ( a1 + ( a1 < 0.0 ? - 1.0 : 1.0 ) * Math.sqrt( diskriminante ) ); double r1 = q / a2; double r2 = a0 / q; if( r1 > r2 ) { double tmp = r1; r1 = r2; r2 = tmp; } int rootNum = 0; if( lowerBound < r1 && r1 < upperBound ) rootNum++; if( lowerBound < r2 && r2 < upperBound ) rootNum++; double[] result = new double[ rootNum ]; rootNum = 0; if( lowerBound < r1 && r1 < upperBound ) result[ rootNum++ ] = r1; if( lowerBound < r2 && r2 < upperBound ) result[ rootNum++ ] = r2; return result; } else { return new double[ 0 ]; } } private double newton( UnivariatePolynomial p, UnivariatePolynomial pDiff, double x ) { double epsilon = 2.22045e-016; // double precision machine epsilon double xOld = x * 2.0 + 1; for( int i = 0; i < 99; i++ ) { xOld = x; double f = p.evaluateAt( x ); x -= f / pDiff.evaluateAt( x ); if( Math.abs( x - xOld ) < epsilon || Math.abs( f ) < epsilon ) break; } return x; } private double bisect( UnivariatePolynomial p, double lowerBound, double upperBound, double fl, double fu ) { double epsilon = 2.22045e-016; // double precision machine epsilon double center = lowerBound; double[] a = p.getCoeffs(); //int numOfIterations = ( int ) ( Math.log( ( upperBound - lowerBound ) / epsilon ) / Math.log( 2.0 ) ); // guaranteed convergence criteria for newton iteration (from "Fundamental Problems of Algorithmic Algebra", 2000, p. 184) int m = p.degree(); double M = 0.0; for( int i = 0; i < a.length; i++ ) { double absCoeff = Math.abs( a[ i ] ); if( absCoeff > M ) absCoeff = M; } double delta = ( Math.pow( m, -3.0 * m - 9.0 ) * Math.pow( 1.0 + M, -6.0 * m ) ); int numOfIterations = Math.min( ( int ) ( Math.log( ( upperBound - lowerBound ) / epsilon ) / Math.log( 2.0 ) ), ( int ) ( Math.log( delta / epsilon ) / Math.log( 2.0 ) ) ); //numOfIterations = 14; for( ; numOfIterations > 0; numOfIterations-- ) { center = 0.5 * ( lowerBound + upperBound ); double fc = a[ a.length - 1 ]; for( int i = a.length - 2; i >= 0; i-- ) fc = fc * center + a[ i ]; if( fc * fl < 0.0 ) { upperBound = center; fu = fc; } else if( fc == 0.0 ) { return center; } else { lowerBound = center; fl = fc; } } return center; //return newton( p, p.derive(), center ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/DegreeCalculator.java000066400000000000000000000042551330553604100271140ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class DegreeCalculator extends AbstractVisitor< Integer, Void > { public Integer visit( PolynomialAddition pa, Void param ) { return Math.max( pa.getFirstOperand().accept( this, ( Void ) null ), pa.getSecondOperand().accept( this, ( Void ) null ) ); } public Integer visit( PolynomialSubtraction ps, Void param ) { return Math.max( ps.getFirstOperand().accept( this, ( Void ) null ), ps.getSecondOperand().accept( this, ( Void ) null ) ); } public Integer visit( PolynomialMultiplication pm, Void param ) { return pm.getFirstOperand().accept( this, ( Void ) null ) + pm.getSecondOperand().accept( this, ( Void ) null ); } public Integer visit( PolynomialPower pp, Void param ) { return pp.getExponent() * pp.getBase().accept( this, ( Void ) null ); } public Integer visit( PolynomialNegation pn, Void param ) { return pn.getOperand().accept( this, ( Void ) null ); } public Integer visit( PolynomialDoubleDivision pdd, Void param ) { return pdd.getDividend().accept( this, ( Void ) null ); } public Integer visit( PolynomialVariable pv, Void param ) { return 1; } public Integer visit( DoubleBinaryOperation dbop, Void param ) { return 0; } public Integer visit( DoubleUnaryOperation duop, Void param ) { return 0; } public Integer visit( DoubleValue dv, Void param ) { return 0; } public Integer visit( DoubleVariable dv, Void param ) { return 0; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/DescartesRootFinder.java000066400000000000000000000703111330553604100276140ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import java.util.*; import java.math.*; public class DescartesRootFinder implements RealRootFinder { public static final double EPSILON = 1e-7; boolean makeSquarefree; class PolyInterval { public double[] a; public boolean shift; public double l; public double u; public PolyInterval( double[] a, double l, double u ) { this.a = a; this.shift = false; this.l = l; this.u = u; } public PolyInterval( double[] a, boolean shift, double l, double u ) { this.a = a; this.shift = shift; this.l = l; this.u = u; } } public DescartesRootFinder( boolean makeSquarefree ) { this.makeSquarefree = makeSquarefree; } /** * Find all real roots of p. * @param p * @return */ public double[] findAllRoots( UnivariatePolynomial p ) { return findAllRootsIn( p, -p.stretch( -1.0 ).maxPositiveRootBound() * ( 1.0 + 2.220446049250313E-16 ), p.maxPositiveRootBound() * ( 1.0 + 2.220446049250313E-16 ) ); } public double[] findAllRootsIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { p = p.shrink(); if( makeSquarefree ) { // make p squarefree UnivariatePolynomial gcd = UnivariatePolynomial.gcd( p, p.derive() ); if( gcd.degree() > 0 ) // Polynomial not squarefree! p = p.div( gcd ); } double[] negRoots = findAllNegRootsIn( p, lowerBound, upperBound ); double[] posRoots = findAllPosRootsIn( p, lowerBound, upperBound ); double[] roots = new double[ negRoots.length + posRoots.length ]; System.arraycopy( negRoots, 0, roots, 0, negRoots.length ); System.arraycopy( posRoots, 0, roots, negRoots.length, posRoots.length ); return roots; } double[] findAllPosRootsIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { if( upperBound < 0.0 ) return new double[ 0 ]; double bound2 = nextPowerOfTwo( upperBound ); p = p.shrink(); double tlb = lowerBound / bound2; double tub = upperBound / bound2; // move all roots in (0,upperBound) into (0,1) p = p.stretch( bound2 ); double[] results = new double[ p.degree() ]; int results_length = 0; if( p.getCoeff( 0 ) == 0.0 ) { if( lowerBound <= 0.0 ) results[ results_length++ ] = 0.0; p = new UnivariatePolynomial( deflate0( p.getCoeffs() ) ); } if( lowerBound < 0.0 ) lowerBound = 0.0; if( results_length != results.length ) { // isolate and refine all roots in (0,1) PolyInterval[] cand = new PolyInterval[ 10 ]; int cand_length = 0; cand[ cand_length++ ] = new PolyInterval( p.getCoeff( 0 ) == 0.0 ? deflate0( p.getCoeffs() ) : p.getCoeffs(), 0.0, 1.0 ); while( cand_length != 0 ) { PolyInterval pi = cand[ --cand_length ]; if( pi.shift ) pi.a = shift1( pi.a ); if( pi.a[ 0 ] == 0.0 ) { double tmp_root = pi.l * bound2; if( lowerBound <= tmp_root && tmp_root <= upperBound ) results[ results_length++ ] = tmp_root; p = new UnivariatePolynomial( deflate( p.getCoeffs(), pi.l ) ); } if( results_length == results.length ) break; int v = descartesRuleOfSignReverseShift1( pi.a ); if( v == 1 ) { double tmp_root = adjustIntervalAndBisect( p, pi.l, pi.u, tlb, tub ) * bound2; if( !java.lang.Double.isNaN( tmp_root ) ) results[ results_length++ ] = tmp_root; } if( results_length == results.length ) break; else if( v > 1 ) { // evtl. mehr als eine NST in (0,1) -> teile Interval (0,1) in zwei teile double c = 0.5 * ( pi.l + pi.u ); if( Math.abs( pi.u - pi.l ) < 0.5 * EPSILON ) // we have reached maximum precision { if( pi.l <= tlb ) results[ results_length++ ] = lowerBound; else results[ results_length++ ] = pi.l * bound2; continue; } double[] stretchedA = stretchNormalize0_5( pi.a ); if( cand_length + 2 >= cand.length ) { // resize candidate stack PolyInterval[] newCand = new PolyInterval[ 2 * cand.length ]; System.arraycopy( cand, 0, newCand, 0, cand.length ); cand = newCand; } if( c <= tub ) cand[ cand_length++ ] = new PolyInterval( stretchedA, true, c, pi.u ); if( c >= tlb ) cand[ cand_length++ ] = new PolyInterval( stretchedA, false, pi.l, c ); } } } double[] roots = new double[ results_length ]; System.arraycopy( results, 0, roots, 0, results_length ); return roots; } double[] findAllNegRootsIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { if( lowerBound >= 0.0 ) return new double[ 0 ]; // map the negative roots on positive ones, find them and transform back p = p.stretch( -1.0 ); double[] roots = findAllPosRootsIn( p, -upperBound, -lowerBound ); for( int i = 0, j = roots.length - 1; i < ( roots.length + 1 ) / 2; ++i, --j ) { // reverse order and negate elements double tmp = -roots[ i ]; roots[ i ] = -roots[ j ]; roots[ j ] = tmp; } return roots; } enum WhichRoot { SMALLEST, LARGEST }; /** * Find the smallest real root of p within lowerBound and upperBound (bounds may or may not be included). * If no real root exists in this interval, Double.NaN ist returned. * @param p * @param lowerBound * @param upperBound * @return */ public double findFirstRootIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { if( makeSquarefree ) { // make p squarefree UnivariatePolynomial gcd = UnivariatePolynomial.gcd( p, p.derive() ); if( gcd.degree() > 0 ) // Polynomial not squarefree! p = p.div( gcd ); } double root = -findPosRootIn( p.stretch( -1.0 ), -upperBound, -lowerBound, WhichRoot.LARGEST ); return java.lang.Double.isNaN( root ) ? findPosRootIn( p, lowerBound, upperBound, WhichRoot.SMALLEST ) : root; } double findPosRootIn( UnivariatePolynomial p, double lowerBound, double upperBound, WhichRoot w ) { if( upperBound <= 0.0 || p.degree() == 0 ) return java.lang.Double.NaN; p = p.shrink(); double bound2 = nextPowerOfTwo( upperBound ); double tlb = lowerBound / bound2; double tub = upperBound / bound2; // move all roots in (0,bound2) into (0,1) p = p.stretch( bound2 ); double tmp_result = java.lang.Double.NaN; if( p.getCoeff( 0 ) == 0.0 ) { if( lowerBound <= 0.0 ) { if( w == WhichRoot.SMALLEST ) return 0.0; else tmp_result = 0.0; } p = new UnivariatePolynomial( deflate0( p.getCoeffs() ) ); } if( lowerBound <= 0.0 ) lowerBound = 0.0; // isolate and refine first root in (0,1) PolyInterval[] cand = new PolyInterval[ 10 ]; int cand_length = 0; cand[ cand_length++ ] = new PolyInterval( p.getCoeffs(), 0.0, 1.0 ); while( cand_length != 0 ) { PolyInterval pi = cand[ --cand_length ]; if( pi.shift ) pi.a = shift1( pi.a ); if( pi.a.length == 0 ) continue; if( pi.a[ 0 ] == 0.0 ) { double tmp_root = pi.l * bound2; if( lowerBound <= tmp_root && tmp_root <= upperBound ) { if( w == WhichRoot.SMALLEST ) return pi.l * bound2; else tmp_result = tmp_root; pi.a = deflate0( pi.a ); } } int v = descartesRuleOfSignReverseShift1( pi.a ); if( v == 1 ) { double tmp_root = adjustIntervalAndBisect( p, pi.l, pi.u, tlb, tub ) * bound2; if( !java.lang.Double.isNaN( tmp_root ) ) { if( w == WhichRoot.LARGEST && !java.lang.Double.isNaN( tmp_result ) && tmp_result > tmp_root ) return tmp_result; else return tmp_root; } } else if( v > 1 ) { // evtl. mehr als eine NST in (0,1) -> teile Interval (0,1) in zwei teile double c = 0.5 * ( pi.l + pi.u ); if( Math.abs( pi.u - pi.l ) < 0.5 * EPSILON ) // we have reached maximum precision { if( pi.l <= tlb ) return lowerBound; else return pi.l * bound2; } double[] stretchedA = stretchNormalize0_5( pi.a ); if( cand_length + 2 >= cand.length ) { // resize candidate stack PolyInterval[] newCand = new PolyInterval[ 2 * cand.length ]; System.arraycopy( cand, 0, newCand, 0, cand.length ); cand = newCand; } if( w == WhichRoot.SMALLEST ) { // search interval with smallest lower bound first if( c <= tub ) cand[ cand_length++ ] = new PolyInterval( stretchedA, true, c, pi.u ); if( c >= tlb ) cand[ cand_length++ ] = new PolyInterval( stretchedA, false, pi.l, c ); } else { // search interval with largest lower bound first if( c >= tlb ) cand[ cand_length++ ] = new PolyInterval( stretchedA, false, pi.l, c ); if( c <= tub ) cand[ cand_length++ ] = new PolyInterval( stretchedA, true, c, pi.u ); } } } return tmp_result; } private static double adjustIntervalAndBisect( UnivariatePolynomial p, double lowerBound, double upperBound, double strictLowerBound, double strictUpperBound ) { double fl = p.evaluateAt( lowerBound ); if( lowerBound < strictLowerBound ) { // intervals overlap if( upperBound < strictLowerBound ) return java.lang.Double.NaN; // search interval and strict interval do not overlap else { double fsl = p.evaluateAt( strictLowerBound ); if( fl * fsl < 0.0 || fl == 0.0 ) return java.lang.Double.NaN; // root is below strictLowerBound else { lowerBound = strictLowerBound; // root is between strictLowerBound and upperBound fl = fsl; } } } double fu = p.evaluateAt( upperBound ); if( strictUpperBound < upperBound ) { // intervals overlap if( strictUpperBound < lowerBound ) return java.lang.Double.NaN; // search interval and strict interval do not overlap else { double fsu = p.evaluateAt( strictUpperBound ); if( fu * fsu < 0.0 || fu == 0.0 ) return java.lang.Double.NaN; // root is above strictLowerBound else { upperBound = strictUpperBound; fu = fsu; } } } if( fl * fu <= 0.0 ) return bisect( p, lowerBound, upperBound, fl, fu ); else return java.lang.Double.NaN; } private static double bisect( UnivariatePolynomial p, double lowerBound, double upperBound ) { return bisect( p, lowerBound, upperBound, p.evaluateAt( lowerBound ), p.evaluateAt( upperBound ) ); } private static double bisect( UnivariatePolynomial p, double lowerBound, double upperBound, double fl, double fu ) { double[] a = p.getCoeffs(); assert fl * fu < 0.0 : "tried bisection on interval without sign change"; while( Math.abs( upperBound - lowerBound ) > EPSILON ) { double center = 0.5 * ( lowerBound + upperBound ); double fc = a[ a.length - 1 ]; for( int i = a.length - 2; i >= 0; i-- ) fc = fc * center + a[ i ]; if( fc * fl < 0.0 ) { upperBound = center; fu = fc; } else if( fc == 0.0 ) { return center; } else { lowerBound = center; fl = fc; } } return lowerBound; } /** * Computes 2^n*p(0.5*x). * @param a * @return */ public double[] stretchNormalize0_5( double[] a ) { double[] resultCoeffs = new double[ a.length ]; resultCoeffs[ resultCoeffs.length - 1 ] = a[ resultCoeffs.length - 1 ]; double multiplier = 2.0; for( int i = resultCoeffs.length - 2; i >= 0; i-- ) { resultCoeffs[ i ] = a[ i ] * multiplier; multiplier *= 2.0; } return resultCoeffs; } /** * Computes p(1+x). * @param a * @return */ private double[] shift1( double[] a ) { double[] hornerCoeffs = new double[ a.length ]; System.arraycopy( a, 0, hornerCoeffs, 0, a.length ); for( int i = 1; i <= hornerCoeffs.length; i++ ) for( int j = hornerCoeffs.length - 2; j >= i - 1; j-- ) hornerCoeffs[ j ] = hornerCoeffs[ j ] + hornerCoeffs[ j + 1 ]; return hornerCoeffs; } private double[] deflate0( double[] a ) { if( a.length == 0 ) return a; double[] deflated_a = new double[ a.length - 1 ]; System.arraycopy( a, 1, deflated_a, 0, deflated_a.length ); return deflated_a; } private double[] deflate( double[] a, double b ) { if( a.length == 0 ) return a; double[] result = new double[ a.length - 1 ]; result[ result.length - 1 ] = a[ a.length - 1 ]; for( int i = a.length - 3; i >= 0; --i ) result[ i ] = result[ i + 1 ] * b + a[ i + 1 ]; return result; } private int descartesRuleOfSignReverseShift1( double[] a ) { int signChanges = 0; double[] hornerCoeffs = new double[ a.length ]; for( int i = 0; i < a.length; i++ ) hornerCoeffs[ i ] = a[ a.length - i - 1 ]; double lastNonZeroCoeff = java.lang.Double.NaN; for( int i = 1; i <= a.length; i++ ) { for( int j = hornerCoeffs.length - 2; j >= i - 1; j-- ) hornerCoeffs[ j ] = hornerCoeffs[ j ] + hornerCoeffs[ j + 1 ]; if( hornerCoeffs[ i - 1 ] != 0.0 ) { if( hornerCoeffs[ i - 1 ] * lastNonZeroCoeff < 0.0 ) signChanges++; if( signChanges > 1 ) return signChanges; lastNonZeroCoeff = hornerCoeffs[ i - 1 ]; } } if( hornerCoeffs[ 0 ] == 0.0 ) ++signChanges; return signChanges; } static double nextPowerOfTwo( double d ) // computes the next power of two with respect to outward rounding { long bits = java.lang.Double.doubleToLongBits( d ); if( ( bits & 0x000fffffffffffffL ) != 0L ) { bits = java.lang.Double.doubleToLongBits( 2.0 * d ); // "round up" -> increase exponent by one bits &= 0xfff0000000000000L; // remove mantissa bits } return java.lang.Double.longBitsToDouble( bits ); } public static void main( String args[] ) { double[] coeffs1 = { java.lang.Double.longBitsToDouble( 4612077628474687022L ), java.lang.Double.longBitsToDouble( -4609042608566403538L ), java.lang.Double.longBitsToDouble( 4607182418800017408L ) }; double[] coeffs2 = { java.lang.Double.longBitsToDouble( 4601663213748960204L ), java.lang.Double.longBitsToDouble( 4609180317257780979L ), java.lang.Double.longBitsToDouble( 4607182418800017408L ) }; UnivariatePolynomial p = new UnivariatePolynomial( coeffs2 ); while( true ) new DescartesRootFinder( false ).findFirstRootIn( p, -2, 2 ); } /* public static void main( String[] args ) { UnivariatePolynomial p = new UnivariatePolynomial( 0.0, 0.05328577011823654, -0.2756684795022011, 0.0, -0.25 ); double[] roots = new DescartesRootFinder( false ).findAllRoots( p ); double[] root_values = new double[ roots.length ]; for( int i = 0; i < roots.length; i++ ) root_values[ i ] = p.evaluateAt( roots[ i ] ); System.out.println( Arrays.toString( roots ) ); System.out.println( Arrays.toString( root_values ) ); System.out.println( p.evaluateAt(0.1873343809)); } */ } // //class DescartesRootFinderBigDecimal //{ // class PolyInterval // { // public BigDecimal[] a; // public boolean shift; // public BigDecimal l; // public BigDecimal u; // public PolyInterval( BigDecimal[] a, BigDecimal l, BigDecimal u ) // { // this.a = a; // this.shift = false; // this.l = l; // this.u = u; // } // public PolyInterval( BigDecimal[] a, boolean shift, BigDecimal l, BigDecimal u ) // { // this.a = a; // this.shift = shift; // this.l = l; // this.u = u; // } // } // // public DescartesRootFinderBigDecimal() // { // } // // /** // * Find the smallest real root of p within lowerBound and upperBound (bounds may or may not be included). // * If no real root exists in this interval, BigDecimal.NaN ist returned. // * @param p // * @param lowerBound // * @param upperBound // * @return // */ // public BigDecimal findFirstRootIn( BigDecimal[] a, BigDecimal lowerBound, BigDecimal upperBound ) // { // a = shrink( a ); // // // move all roots in (lowerBound,upperBound) into (0,1) // a = stretch( shift( a, lowerBound ), upperBound.subtract( lowerBound ) ); // if( a[ 0 ].equals( BigDecimal.ZERO ) ) // return lowerBound; // // // isolate and refine first root in (0,1) // PolyInterval[] cand = new PolyInterval[ 10 ]; // int cand_length = 0; // cand[ cand_length++ ] = new PolyInterval( a, BigDecimal.ZERO, BigDecimal.ONE ); // while( cand_length != 0 ) // { // PolyInterval pi = cand[ --cand_length ]; // if( pi.shift ) // pi.a = shift1( pi.a ); // if( pi.a[ 0 ].equals( BigDecimal.ZERO ) ) // return pi.l; // int v = descartesRuleOfSignReverseShift1( pi.a ); // if( v == 1 ) // return bisect( a, pi.l, pi.u ).multiply( upperBound.subtract( lowerBound ) ).add( lowerBound ); // else if( v > 1 ) // { // // evtl. mehr als eine NST in (0,1) -> teile Interval (0,1) in zwei teile // BigDecimal c = new BigDecimal( 0.5 ).multiply( pi.l.add( pi.u ) ); // if( c == pi.l ) // we have reached maximum precision // return c; // BigDecimal[] stretchedA = stretchNormalize0_5( pi.a ); // if( cand_length + 2 >= cand.length ) // { // // resize candidate stack // PolyInterval[] newCand = new PolyInterval[ 2 * cand.length ]; // System.arraycopy( cand, 0, newCand, 0, cand.length ); // cand = newCand; // } // cand[ cand_length++ ] = new PolyInterval( stretchedA, true, c, pi.u ); // cand[ cand_length++ ] = new PolyInterval( stretchedA, false, pi.l, c ); // } // } // return BigDecimal.ZERO; // } // // private static BigDecimal bisect( BigDecimal[] a, BigDecimal lowerBound, BigDecimal upperBound ) // { // BigDecimal center = lowerBound; // BigDecimal fl = evaluateAt( a, lowerBound ); // BigDecimal fu = evaluateAt( a, upperBound ); // // while( upperBound.subtract( lowerBound ).compareTo( new BigDecimal( 0.0000000000000001 ) ) > 0 ) // { // center = new BigDecimal( 0.5 ).multiply( lowerBound.add( upperBound ) ); // BigDecimal fc = evaluateAt( a, center ); // // if( fc.signum() * fl.signum() < 0 ) // { // upperBound = center; // fu = fc; // } // else if( fc.equals( BigDecimal.ZERO ) ) // { // break; // } // else // { // lowerBound = center; // fl = fc; // } // } // return center; // } // // public BigDecimal[] shrink( BigDecimal[] a ) // { // int degree = a.length - 1; // while( a[ degree ].equals( BigDecimal.ZERO ) && degree > 0 ) // degree--; // if( degree != a.length - 1 ) // { // BigDecimal[] result = new BigDecimal[ degree + 1 ]; // System.arraycopy( a, 0, result, 0, result.length ); // return result; // } // else // return a; // } // // public static BigDecimal[] convertFromDouble( double[] a ) // { // BigDecimal[] result = new BigDecimal[ a.length ]; // for( int i = 0; i< a.length; ++i ) // result[ i ] = new BigDecimal( a[ i ]); // return result; // } // // public static BigDecimal evaluateAt( BigDecimal[] a, BigDecimal where ) // { // BigDecimal result = a[ a.length - 1 ]; // for( int i = a.length - 2; i >= 0; i-- ) // result = result.multiply( where ).add( a[ i ] ); // return result; // } // // private BigDecimal[] shift( BigDecimal[] a, BigDecimal s ) // { // // divide this polynomial repeatedly by ( x + a ) by using ruffini's rule // // and store the coeffs of the resulting polynomial and the remainder. // // the remainders give the coeffs of the shifted polynomial. // BigDecimal[] hornerCoeffs = new BigDecimal[ a.length ]; // // perform x -> x + a // System.arraycopy( a , 0, hornerCoeffs, 0, a.length ); // // for( int i = 1; i <= a.length; i++ ) // for( int j = hornerCoeffs.length - 2; j >= i - 1; j-- ) // hornerCoeffs[ j ] = hornerCoeffs[ j ].add( s.multiply( hornerCoeffs[ j + 1 ] ) ); // // return hornerCoeffs; // } // // public BigDecimal[] stretch( BigDecimal[] a, BigDecimal v ) // { // BigDecimal[] resultCoeffs = new BigDecimal[ a.length ]; // BigDecimal multiplier = BigDecimal.ONE; // for( int i = 0; i < resultCoeffs.length; i++ ) // { // resultCoeffs[ i ] = a[ i ].multiply( multiplier ); // multiplier = multiplier.multiply( v ); // } // return resultCoeffs; // } // // /** // * Computes 2^n*p(0.5*x). // * @param a // * @return // */ // public BigDecimal[] stretchNormalize0_5( BigDecimal[] a ) // { // BigDecimal[] resultCoeffs = new BigDecimal[ a.length ]; // resultCoeffs[ resultCoeffs.length - 1 ] = a[ resultCoeffs.length - 1 ]; // BigDecimal multiplier = new BigDecimal( 2.0 ); // for( int i = resultCoeffs.length - 2; i >= 0; i-- ) // { // resultCoeffs[ i ] = a[ i ].multiply( multiplier ); // multiplier = multiplier.multiply( new BigDecimal( 2.0 ) ); // } // // return resultCoeffs; // } // // /** // * Computes p(1+x). // * @param a // * @return // */ // private BigDecimal[] shift1( BigDecimal[] a ) // { // BigDecimal[] hornerCoeffs = new BigDecimal[ a.length ]; // System.arraycopy( a, 0, hornerCoeffs, 0, a.length ); // // for( int i = 1; i <= hornerCoeffs.length; i++ ) // for( int j = hornerCoeffs.length - 2; j >= i - 1; j-- ) // hornerCoeffs[ j ] = hornerCoeffs[ j ].add( hornerCoeffs[ j + 1 ] ); // // return hornerCoeffs; // } // // private BigDecimal[] deflate0( BigDecimal[] a ) // { // if( a.length == 0 ) // return a; // BigDecimal[] deflated_a = new BigDecimal[ a.length - 1 ]; // System.arraycopy( a, 1, deflated_a, 0, deflated_a.length ); // return deflated_a; // } // // private BigDecimal[] deflate( BigDecimal[] a, BigDecimal b ) // { // if( a.length == 0 ) // return a; // BigDecimal[] result = new BigDecimal[ a.length - 1 ]; // result[ result.length - 1 ] = a[ a.length - 1 ]; // for( int i = a.length - 3; i >= 0; i++ ) // result[ i ] = result[ i + 1 ].multiply( b ).add( a[ i + 1 ] ); // return result; // } // // private int descartesRuleOfSignReverseShift1( BigDecimal[] a ) // { // int signChanges = 0; // BigDecimal[] hornerCoeffs = new BigDecimal[ a.length ]; // for( int i = 0; i < a.length; i++ ) // hornerCoeffs[ i ] = a[ a.length - i - 1 ]; // // BigDecimal lastNonZeroCoeff = BigDecimal.ZERO; // for( int i = 1; i <= a.length; i++ ) // { // for( int j = hornerCoeffs.length - 2; j >= i - 1; j-- ) // hornerCoeffs[ j ] = hornerCoeffs[ j ].add( hornerCoeffs[ j + 1 ] ); // if( !hornerCoeffs[ i - 1 ].equals( BigDecimal.ZERO ) ) // { // if( hornerCoeffs[ i - 1 ].signum() * lastNonZeroCoeff.signum() < 0 ) // signChanges++; // if( signChanges > 1 ) // return signChanges; // lastNonZeroCoeff = hornerCoeffs[ i - 1 ]; // } // } // // return signChanges; // } // ///* // public static void main( String[] args ) // { // UnivariatePolynomial p = new UnivariatePolynomial( 0.0, 0.05328577011823654, -0.2756684795022011, 0.0, -0.25 ); // BigDecimal[] roots = new DescartesRootFinder( false ).findAllRoots( p ); // BigDecimal[] root_values = new BigDecimal[ roots.length ]; // for( int i = 0; i < roots.length; i++ ) // root_values[ i ] = p.evaluateAt( roots[ i ] ); // System.out.println( Arrays.toString( roots ) ); // System.out.println( Arrays.toString( root_values ) ); // System.out.println( p.evaluateAt(0.1873343809)); // } // */ //} // jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/Differentiator.java000066400000000000000000000076141330553604100266560ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class Differentiator extends AbstractVisitor< PolynomialOperation, Void > { private PolynomialVariable.Var var; public Differentiator( PolynomialVariable.Var var ) { this.var = var; } public PolynomialVariable.Var getVariable() { return this.var; } public void setVariable( PolynomialVariable.Var var ) { this.var = var; } public PolynomialOperation visit( PolynomialAddition pa, Void param ) { return new PolynomialAddition( pa.getFirstOperand().accept( this, ( Void ) null ), pa.getSecondOperand().accept( this, ( Void ) null ) ); } public PolynomialOperation visit( PolynomialSubtraction ps, Void param ) { return new PolynomialSubtraction( ps.getFirstOperand().accept( this, ( Void ) null ), ps.getSecondOperand().accept( this, ( Void ) null ) ); } public PolynomialOperation visit( PolynomialMultiplication pm, Void param ) { PolynomialOperation u = pm.getFirstOperand(); PolynomialOperation v = pm.getSecondOperand(); PolynomialOperation udiff = u.accept( this, ( Void ) null ); PolynomialOperation vdiff = v.accept( this, ( Void ) null ); return new PolynomialAddition( new PolynomialMultiplication( udiff, v ), new PolynomialMultiplication( u, vdiff ) ); } public PolynomialOperation visit( PolynomialPower pp, Void param ) { switch( pp.getExponent() ) { case 1: return new DoubleValue( 1.0 ); case 2: { PolynomialOperation u = pp.getBase(); PolynomialOperation udiff = u.accept( this, ( Void ) null ); return new PolynomialMultiplication( new PolynomialMultiplication( new DoubleValue( ( double ) pp.getExponent() ), u ), udiff ); } default: { PolynomialOperation u = pp.getBase(); PolynomialOperation udiff = u.accept( this, ( Void ) null ); return new PolynomialMultiplication( new PolynomialMultiplication( new DoubleValue( ( double ) pp.getExponent() ), new PolynomialPower( u, pp.getExponent() - 1 ) ), udiff ); } } } public PolynomialOperation visit( PolynomialNegation pn, Void param ) { return new PolynomialNegation( pn.getOperand().accept( this,( Void ) null ) ); } public PolynomialOperation visit( PolynomialDoubleDivision pdd, Void param ) { return new PolynomialDoubleDivision( pdd.getDividend().accept( this,( Void ) null ), pdd.getDivisor() ); } public PolynomialOperation visit( PolynomialVariable pv, Void param ) { if( pv.getVariable() == this.var ) return new DoubleValue( 1.0 ); else return new DoubleValue( 0.0 ); } public PolynomialOperation visit( DoubleBinaryOperation dbop, Void param ) { return new DoubleValue( 0.0 ); } public PolynomialOperation visit( DoubleUnaryOperation duop, Void param ) { return new DoubleValue( 0.0 ); } public PolynomialOperation visit( DoubleValue dv, Void param ) { return new DoubleValue( 0.0 ); } public PolynomialOperation visit( DoubleVariable dv, Void param ) { return new DoubleValue( 0.0 ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/DoubleBinaryOperation.java000066400000000000000000000034351330553604100301460ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class DoubleBinaryOperation implements DoubleOperation { public enum Op { add, sub, mult, div, pow; } private Op operator; private DoubleOperation firstOperand; private DoubleOperation secondOperand; private boolean hasParentheses; public DoubleBinaryOperation( Op operator, DoubleOperation firstOperand, DoubleOperation secondOperand ) { this( operator, firstOperand, secondOperand, false ); } public DoubleBinaryOperation( Op operator, DoubleOperation firstOperand, DoubleOperation secondOperand, boolean hasParentheses ) { this.operator = operator; this.firstOperand = firstOperand; this.secondOperand = secondOperand; this.hasParentheses = hasParentheses; } public Op getOperator() { return operator; } public DoubleOperation getFirstOperand() { return firstOperand; } public DoubleOperation getSecondOperand() { return secondOperand; } public boolean hasParentheses() { return hasParentheses; } public < RETURN_TYPE, PARAM_TYPE > RETURN_TYPE accept( Visitor< RETURN_TYPE, PARAM_TYPE > visitor, PARAM_TYPE arg ) { return visitor.visit( this, arg ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/DoubleOperation.java000066400000000000000000000012701330553604100267740ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public interface DoubleOperation extends PolynomialOperation {} jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/DoubleUnaryOperation.java000066400000000000000000000030721330553604100300150ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class DoubleUnaryOperation implements DoubleOperation { public enum Op { neg, sin, cos, tan, asin, acos, atan, exp, log, sqrt, ceil, floor, abs, sign; } private Op operator; private DoubleOperation operand; private boolean hasParentheses; public DoubleUnaryOperation( Op operator, DoubleOperation operand ) { this( operator, operand, false ); } public DoubleUnaryOperation( Op operator, DoubleOperation operand, boolean hasParentheses ) { this.operator = operator; this.operand = operand; this.hasParentheses = hasParentheses; } public Op getOperator() { return operator; } public DoubleOperation getOperand() { return operand; } public boolean hasParentheses() { return hasParentheses; } public < RETURN_TYPE, PARAM_TYPE > RETURN_TYPE accept( Visitor< RETURN_TYPE, PARAM_TYPE > visitor, PARAM_TYPE arg ) { return visitor.visit( this, arg ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/DoubleValue.java000066400000000000000000000034271330553604100261160ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class DoubleValue implements DoubleOperation { private double value; private String stringValue; private boolean hasParentheses; public DoubleValue( String stringValue ) { this( stringValue, false ); } public DoubleValue( String stringValue, boolean hasParentheses ) { this.stringValue = stringValue; this.value = Double.parseDouble( stringValue ); this.hasParentheses = hasParentheses; } public DoubleValue( double value ) { this( value, false ); } public DoubleValue( double value, boolean hasParentheses ) { this.value = value; this.stringValue = value == (int) value ? String.valueOf( (int) value ) : String.valueOf( value ); this.hasParentheses = hasParentheses; } public double getValue() { return value; } public boolean hasParentheses() { return hasParentheses; } public < RETURN_TYPE, PARAM_TYPE > RETURN_TYPE accept( Visitor< RETURN_TYPE, PARAM_TYPE > visitor, PARAM_TYPE arg ) { return visitor.visit( this, arg ); } @Override public String toString() { return this.stringValue; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/DoubleVariable.java000066400000000000000000000023661330553604100265700ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class DoubleVariable implements DoubleOperation { private String name; private boolean hasParentheses; public DoubleVariable( String name ) { this( name, false ); } public DoubleVariable( String name, boolean hasParentheses ) { this.name = name; this.hasParentheses = hasParentheses; } public String getName() { return name; } public boolean hasParentheses() { return hasParentheses; } public < RETURN_TYPE, PARAM_TYPE > RETURN_TYPE accept( Visitor< RETURN_TYPE, PARAM_TYPE > visitor, PARAM_TYPE arg ) { return visitor.visit( this, arg ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/DoubleVariableExtractor.java000066400000000000000000000054441330553604100304640ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import java.util.*; public class DoubleVariableExtractor extends AbstractVisitor< Set< String >, Void > { public Set< String > visit( PolynomialAddition pa, Void param ) { Set< String > s = pa.getFirstOperand().accept( this, ( Void ) null ); s.addAll( pa.getSecondOperand().accept( this, ( Void ) null ) ); return s; } public Set< String > visit( PolynomialSubtraction ps, Void param ) { Set< String > s = ps.getFirstOperand().accept( this, ( Void ) null ); s.addAll( ps.getSecondOperand().accept( this, ( Void ) null ) ); return s; } public Set< String > visit( PolynomialMultiplication pm, Void param ) { Set< String > s = pm.getFirstOperand().accept( this, ( Void ) null ); s.addAll( pm.getSecondOperand().accept( this, ( Void ) null ) ); return s; } public Set< String > visit( PolynomialPower pp, Void param ) { return pp.getBase().accept( this, ( Void ) null ); } public Set< String > visit( PolynomialNegation pn, Void param ) { return pn.getOperand().accept( this, ( Void ) null ); } public Set< String > visit( PolynomialDoubleDivision pdd, Void param ) { Set< String > s = pdd.getDividend().accept( this, ( Void ) null ); s.addAll( pdd.getDivisor().accept( this, ( Void ) null ) ); return s; } public Set< String > visit( PolynomialVariable pv, Void param ) { return new HashSet< String >(); } public Set< String > visit( DoubleBinaryOperation dbop, Void param ) { Set< String > s = dbop.getFirstOperand().accept( this, ( Void ) null ); s.addAll( dbop.getSecondOperand().accept( this, ( Void ) null ) ); return s; } public Set< String > visit( DoubleUnaryOperation duop, Void param ) { return duop.getOperand().accept( this, ( Void ) null ); } public Set< String > visit( DoubleValue dv, Void param ) { return new HashSet< String >(); } public Set< String > visit( DoubleVariable dv, Void param ) { HashSet< String > s = new HashSet< String >(); s.add( dv.getName() ); return s; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/DoubleVariableRenameVisitor.java000066400000000000000000000055161330553604100313000ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import java.util.*; public class DoubleVariableRenameVisitor extends AbstractVisitor< PolynomialOperation, Void > { private Map< String, String > m; public DoubleVariableRenameVisitor( Map< String, String > m ) { this.m = m; } public PolynomialOperation visit( PolynomialAddition pa, Void param ) { pa.getFirstOperand().accept( this, ( Void ) null ); pa.getSecondOperand().accept( this, ( Void ) null ); return pa; } public PolynomialOperation visit( PolynomialSubtraction ps, Void param ) { ps.getFirstOperand().accept( this, ( Void ) null ); ps.getSecondOperand().accept( this, ( Void ) null ); return ps; } public PolynomialOperation visit( PolynomialMultiplication pm, Void param ) { pm.getFirstOperand().accept( this, ( Void ) null ); pm.getSecondOperand().accept( this, ( Void ) null ); return pm; } public PolynomialOperation visit( PolynomialPower pp, Void param ) { return pp.getBase().accept( this, ( Void ) null ); } public PolynomialOperation visit( PolynomialNegation pn, Void param ) { pn.getOperand().accept( this, ( Void ) null ); return pn; } public PolynomialOperation visit( PolynomialDoubleDivision pdd, Void param ) { pdd.getDividend().accept( this, ( Void ) null ); pdd.getDivisor().accept( this, ( Void ) null ); return pdd; } public PolynomialOperation visit( PolynomialVariable pv, Void param ) { return pv; } public PolynomialOperation visit( DoubleBinaryOperation dbop, Void param ) { dbop.getFirstOperand().accept( this, ( Void ) null ); dbop.getSecondOperand().accept( this, ( Void ) null ); return dbop; } public PolynomialOperation visit( DoubleUnaryOperation duop, Void param ) { return duop.getOperand().accept( this, ( Void ) null ); } public PolynomialOperation visit( DoubleValue dv, Void param ) { return dv; } public PolynomialOperation visit( DoubleVariable dv, Void param ) { String new_name = m.get( dv.getName() ); return new DoubleVariable( new_name != null ? new_name : dv.getName() ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/EVALRootFinder.java000077500000000000000000000157001330553604100264320ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import java.util.*; import java.math.*; public class EVALRootFinder implements RealRootFinder { public static final double EPSILON = 1e-7; boolean makeSquarefree; public EVALRootFinder( boolean makeSquarefree ) { this.makeSquarefree = makeSquarefree; } /** * Find all real roots of p. * @param p * @return */ public double[] findAllRoots( UnivariatePolynomial p ) { return findAllRootsIn( p, -p.stretch( -1.0 ).maxPositiveRootBound() * ( 1.0 + 2.220446049250313E-16 ), p.maxPositiveRootBound() * ( 1.0 + 2.220446049250313E-16 ) ); } public double[] findAllRootsIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { p = p.shrink(); if( makeSquarefree ) { // make p squarefree UnivariatePolynomial gcd = UnivariatePolynomial.gcd( p, p.derive() ); if( gcd.degree() > 0 ) // Polynomial not squarefree! p = p.div( gcd ); } return null; } /** * Find the smallest real root of p within lowerBound and upperBound (bounds may or may not be included). * If no real root exists in this interval, Double.NaN ist returned. * @param p * @param lowerBound * @param upperBound * @return */ public double findFirstRootIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { if( makeSquarefree ) { // make p squarefree UnivariatePolynomial gcd = UnivariatePolynomial.gcd( p, p.derive() ); if( gcd.degree() > 0 ) // Polynomial not squarefree! p = p.div( gcd ); } return EVAL( p, lowerBound, upperBound, p.evaluateAt( lowerBound ), p.evaluateAt( upperBound ) ); } public double EVAL( UnivariatePolynomial p, double lowerBound, double upperBound, double fl, double fu ) { //System.out.println( "EVAL on (" + lowerBound + "," + upperBound + ") |-> (" + fl + "," + fu + ")" ); double m = ( lowerBound + upperBound ) / 2.0; double r = ( upperBound - lowerBound ) / 2.0; //System.out.println( "(m,r)=("+m+","+r+")" ); if( upperBound - lowerBound < EPSILON ) { // System.out.println( "epsilon reached" ); // prevent infinite loop (e.g. for non-squarefree polynomials) if( fl * fu < 0.0 ) return m; else return m;//java.lang.Double.NaN; } // test for exclusion predicate: no real root in (m-r,m+r) UnivariatePolynomial t = p.shift( m ); //System.out.println( "Taylor exp. of f(x-" + m + "): " + t ); double fm = t.getCoeff( 0 ); double ta[] = t.getCoeffs(); ta[ 0 ] = -Math.abs( ta[ 0 ] ); for( int i = 1; i < ta.length; ++i ) ta[ i ] = Math.abs( ta[ i ] ); if( 0.0 > new UnivariatePolynomial( ta ).evaluateAt( r ) ) return java.lang.Double.NaN; //System.out.println( "Exclusion predicate false" ); // test for inclusion predicate: exactly one real root in (m-r,m+r) UnivariatePolynomial t_der = p.derive().shift( m ); //System.out.println( "Taylor exp. of f'(x-" + m + "): " + t_der ); double ta_der[] = t_der.getCoeffs(); ta_der[ 0 ] = -Math.abs( ta_der[ 0 ] ); for( int i = 1; i < ta_der.length; ++i ) ta_der[ i ] = Math.abs( ta_der[ i ] ); if( fl*fu <= 0.0 && 0.0 > new UnivariatePolynomial( ta_der ).evaluateAt( r ) ) return bisect( p, lowerBound, upperBound, fl, fu ); //System.out.println( "Inclusion predicate false" ); System.out.println(); // bisect double result_left = EVAL( p, lowerBound, m, fl, fm ); if( !java.lang.Double.isNaN( result_left ) ) return result_left; else return EVAL( p, m, upperBound, fm, fu ); } private double evaluateAt( double a[], int start, double where ) { int deg = a.length - 1; if( Math.abs( where ) <= 1.0 ) { double result = a[ deg ]; for( int i = deg - 2; i >= start; i-- ) result = result * where + a[ i ]; return result; } else { double result = a[ 0 + start ]; for( int i = 1 + start; i < deg; i++ ) result = result / where + a[ i ]; return result * Math.pow( where, deg - start ); } } private static void taylor_exp( double a[], double r[], double x0 ) { double rr; int n = a.length - 1; rr = a[ n ]; for( int i = 0; i <= n; ++i ) r[ i ] = rr; for( int j = 1; j <= n; ++j ) { r[ n ] = r[ n ] * x0 + a[ j ]; for( int i = 1; i <= n - j; ++i ) r[ n - i ] = r[ n - i ] * x0 + r[ n - ( i - 1 ) ]; } } private static double bisect( UnivariatePolynomial p, double lowerBound, double upperBound ) { return bisect( p, lowerBound, upperBound, p.evaluateAt( lowerBound ), p.evaluateAt( upperBound ) ); } private static double bisect( UnivariatePolynomial p, double lowerBound, double upperBound, double fl, double fu ) { double[] a = p.getCoeffs(); assert fl * fu < 0.0 : "tried bisection on interval without sign change"; while( Math.abs( upperBound - lowerBound ) > EPSILON ) { double center = 0.5 * ( lowerBound + upperBound ); double fc = a[ a.length - 1 ]; for( int i = a.length - 2; i >= 0; i-- ) fc = fc * center + a[ i ]; if( fc * fl < 0.0 ) { upperBound = center; fu = fc; } else if( fc == 0.0 ) { return center; } else { lowerBound = center; fl = fc; } } return lowerBound; } public static void main( String args[] ) { double a[] = { -6, 11, -6, 1 }; EVALRootFinder rf = new EVALRootFinder( false ); rf.findFirstRootIn( new UnivariatePolynomial( a ), 0.0, 5.0 ); double t[] = new double[ a.length ]; taylor_exp( a, t, 0.0 ); System.out.println( java.util.Arrays.toString( t ) ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/Expand.java000066400000000000000000000065301330553604100251240ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class Expand extends AbstractVisitor< XYZPolynomial, Void > { private ValueCalculator valueCalculator; public Expand() { this.valueCalculator = new ValueCalculator( 0.0, 0.0, 0.0 ); } public XYZPolynomial visit( PolynomialAddition pa, Void param ) { XYZPolynomial first = pa.getFirstOperand().accept( this,( Void ) null ); XYZPolynomial second = pa.getSecondOperand().accept( this,( Void ) null ); return first.add( second ); } public XYZPolynomial visit( PolynomialSubtraction ps, Void param ) { XYZPolynomial first = ps.getFirstOperand().accept( this,( Void ) null ); XYZPolynomial second = ps.getSecondOperand().accept( this,( Void ) null ); return first.sub( second ); } public XYZPolynomial visit( PolynomialMultiplication pm, Void param ) { XYZPolynomial first = pm.getFirstOperand().accept( this,( Void ) null ); XYZPolynomial second = pm.getSecondOperand().accept( this,( Void ) null ); return first.mult( second ); } public XYZPolynomial visit( PolynomialPower pp, Void param ) { XYZPolynomial base = pp.getBase().accept( this,( Void ) null ); return base.pow( pp.getExponent() ); } public XYZPolynomial visit( PolynomialNegation pn, Void param ) { return pn.getOperand().accept( this,( Void ) null ).neg(); } public XYZPolynomial visit( PolynomialDoubleDivision pdd, Void param ) { XYZPolynomial dividend = pdd.getDividend().accept( this,( Void ) null ); double divisor = pdd.getDivisor().accept( this.valueCalculator, ( Void ) null ); return dividend.mult( 1.0 / divisor ); } public XYZPolynomial visit( PolynomialVariable pv, Void param ) { switch( pv.getVariable() ) { case x: return XYZPolynomial.X; case y: return XYZPolynomial.Y; case z: return XYZPolynomial.Z; default: throw new UnsupportedOperationException(); } } public XYZPolynomial visit( DoubleBinaryOperation dbop, Void param ) { return new XYZPolynomial( dbop.accept( this.valueCalculator, ( Void ) null ) ); } public XYZPolynomial visit( DoubleUnaryOperation duop, Void param ) { return new XYZPolynomial( duop.accept( this.valueCalculator, ( Void ) null ) ); } public XYZPolynomial visit( DoubleVariable dv, Void param ) { throw new UnsupportedOperationException( "no value has been assigned to parameter '" + dv.getName() + "'" ); } public XYZPolynomial visit( DoubleValue dv, Void param ) { return new XYZPolynomial( dv.getValue() ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/FastGradientCalculator.java000066400000000000000000000035771330553604100303020ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import javax.vecmath.*; public class FastGradientCalculator implements GradientCalculator { private XYZPolynomial gradientXPoly; private XYZPolynomial gradientYPoly; private XYZPolynomial gradientZPoly; public FastGradientCalculator( PolynomialOperation gradientXExpression, PolynomialOperation gradientYExpression, PolynomialOperation gradientZExpression ) { Expand e = new Expand(); try { this.gradientXPoly = gradientXExpression.accept( e, ( Void ) null ); this.gradientYPoly = gradientYExpression.accept( e, ( Void ) null ); this.gradientZPoly = gradientZExpression.accept( e, ( Void ) null ); } catch( Throwable t ) { t.printStackTrace(); } } public Vector3d calculateGradient( Point3d p ) { double x = gradientXPoly.evaluateXYZ( p.x, p.y, p.z ); double y = gradientYPoly.evaluateXYZ( p.x, p.y, p.z ); double z = gradientZPoly.evaluateXYZ( p.x, p.y, p.z ); return new Vector3d( x, y, z ); } public Vector3f calculateGradient( Point3f p ) { Vector3d g = calculateGradient( new Point3d( p.x, p.y, p.z ) ); return new Vector3f( ( float ) g.x, ( float ) g.y, ( float ) g.z ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/FastRowSubstitutorForGradient.java000066400000000000000000000051451330553604100317100ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import de.mfo.jsurf.rendering.cpu.Ray; import de.mfo.jsurf.rendering.cpu.RayCreator; import javax.vecmath.*; public class FastRowSubstitutorForGradient implements RowSubstitutorForGradient { private XYZPolynomial gradientXPoly; private XYZPolynomial gradientYPoly; private XYZPolynomial gradientZPoly; private RayCreator rc; public FastRowSubstitutorForGradient( PolynomialOperation gradientXExpression, PolynomialOperation gradientYExpression, PolynomialOperation gradientZExpression, RayCreator rc ) { this.rc = rc; Expand e = new Expand(); try { this.gradientXPoly = gradientXExpression.accept( e, ( Void ) null ); this.gradientYPoly = gradientYExpression.accept( e, ( Void ) null ); this.gradientZPoly = gradientZExpression.accept( e, ( Void ) null ); } catch( Throwable t ) { t.printStackTrace(); } } public ColumnSubstitutorForGradient setV( double v ) { return new FastColumnSubstitutorForGradient( v ); } class FastColumnSubstitutorForGradient implements ColumnSubstitutorForGradient { double v; public FastColumnSubstitutorForGradient( double v ) { this.v = v; } public UnivariatePolynomialVector3d setU( double u ) { return new myUnivariatePolynomialVector3d( rc.createSurfaceSpaceRay( u, v ) ); } } class myUnivariatePolynomialVector3d implements UnivariatePolynomialVector3d { Ray r; public myUnivariatePolynomialVector3d( Ray r ) { this.r = r; } @Override public Vector3d setT( double t ) { Point3d p = r.at( t ); Vector3d result = new Vector3d(); result.x = gradientXPoly.evaluateXYZ( p.x, p.y, p.z ); result.y = gradientYPoly.evaluateXYZ( p.x, p.y, p.z ); result.z = gradientZPoly.evaluateXYZ( p.x, p.y, p.z ); return result; } } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/GradientCalculator.java000066400000000000000000000021441330553604100274510ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import javax.vecmath.*; public interface GradientCalculator { /** * Calculates the surface normal in surface space. * @param p Point in surface space. * @return Surface normal in surface space. */ public Vector3d calculateGradient( Point3d p ); /** * Calculates the surface normal in surface space. * @param p Point in surface space. * @return Surface normal in surface space. */ public Vector3f calculateGradient( Point3f p ); } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/Helper.java000066400000000000000000000017541330553604100251270ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public final class Helper { public static double pow( double base, int exp ) { double result = 1.0; while( exp > 0 ) { if( ( exp & 1 ) == 1 ) { result = result * base; exp--; } base = base * base; exp /= 2; } return result; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/MultinomialCoefficients.java000066400000000000000000000044261330553604100305230ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class MultinomialCoefficients { static final long[][] binomialCoeffs; // lookup table for all binomial coeffs up to n = N and k = K static final int N = 100; static final int K = 100; static { binomialCoeffs = new long[ N + 1 ][ K + 1 ]; // base cases for( int k = 1; k <= K; k++ ) binomialCoeffs[ 0 ][ k ] = 0; for( int n = 0; n <= N; n++ ) binomialCoeffs[ n ][ 0 ] = 1; // bottom-up dynamic programming for (int n = 1; n <= N; n++) for (int k = 1; k <= K; k++) binomialCoeffs[n][k] = binomialCoeffs[n-1][k-1] + binomialCoeffs[n-1][k]; } public static long binomialCoefficient( int n, int k ) { if( n <= N && k <= K ) // return cached value return binomialCoeffs[ n ][ k ]; else // more expensive recursive computation return binomialCoefficient( n - 1, k - 1 ) + binomialCoefficient( n - 1, k ); } public static long multinomialCoefficient( int ... k ) { if( k.length == 0 ) return 1; long result = 1; int k_sum = k[ 0 ]; for( int i = 1; i < k.length; ++i ) { k_sum += k[ i ]; result *= binomialCoefficient( k_sum, k[ i ] ); } return result; } public static long trinomialCoefficient( int k1, int k2, int k3 ) { return multinomialCoefficient( makeArray( k1, k2, k3 ) ); } public static long quadrinomialCoefficient( int k1, int k2, int k3, int k4 ) { return multinomialCoefficient( makeArray( k1, k2, k3, k4 ) ); } private static int[] makeArray( int ... i ) { return i; } } NewtonInterpolationCoefficientCalculator.java000066400000000000000000000063461330553604100340260ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class NewtonInterpolationCoefficientCalculator implements CoefficientCalculator { private PolynomialOperation polynomialOperation; private int degree; private int size; public NewtonInterpolationCoefficientCalculator( PolynomialOperation polynomialOperation ) { this.polynomialOperation = polynomialOperation; this.degree = polynomialOperation.accept( new DegreeCalculator(), ( Void ) null ); this.size = this.degree + 1; } public UnivariatePolynomial calculateCoefficients( UnivariatePolynomial xPoly, UnivariatePolynomial yPoly, UnivariatePolynomial zPoly ) { double[] x = new double[ size ]; double[] y = new double[ size ]; double[] newton_basis = new double[ size ]; ValueCalculator valueCalculator = new ValueCalculator(); // DEGREE + 1 Stützpunkte auf Strahl eye + t * pos berechnen for( int i = 0; i <= degree; i++ ) { x[ i ] = -1.0 + ( 2.0 * i ) / degree; valueCalculator.setX( xPoly.getCoeff( 0 ) + xPoly.getCoeff( 1 ) * x[ i ] ); valueCalculator.setY( yPoly.getCoeff( 0 ) + yPoly.getCoeff( 1 ) * x[ i ] ); valueCalculator.setZ( zPoly.getCoeff( 0 ) + zPoly.getCoeff( 1 ) * x[ i ] ); y[ i ] = this.polynomialOperation.accept( valueCalculator, ( Void ) null ); } // dividierte Differenzen berechen for( int i = 1; i <= degree; i++ ) for( int j = degree; j >= i; j-- ) y[ j ] = ( y[ j ] - y[ j - 1 ] ) / ( x[ j ] - x[ j - i ] ); // schrittweise Koeffizienten mit Newton-Interpolationsformel berechnen double[] a = new double[ size ]; newton_basis[ degree ] = 1.0; a[ 0 ] = y[ 0 ]; for( int i = 1; i <= degree; i++ ) { // ( ai*x^i + ... + a0 ) + ( ai*x^i + ... + a0 ) * ( x - x[ i ] ) * y[ i ] = ( ai*x^i + ... + a0 ) * x - x[ i ] * y[ i ] * ( ai*x^i + ... + a0 ) berechnen // 1. Koeffizienten der Newton-Basis um eine Potenz erhöhen (=shiften) newton_basis[ degree - i ] = 0.0; a[ i ] = 0.0; // 2. alte Koeffizienten der Newton-Basis multipliziert mit x[ i - 1 ] subtrahieren for( int j = degree - i; j < degree; j++ ) newton_basis[ j ] = newton_basis[ j ] - newton_basis[ j + 1 ] * x[ i - 1 ]; // 3. y[ i ] * ( neue Newton-Basis ) auf alte Koeffizienten addieren for( int j = 0; j <= i; j++ ) a[ j ] += newton_basis[ degree - i + j ] * y[ i ]; } return new UnivariatePolynomial( a ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/PolynomialAddition.java000066400000000000000000000031661330553604100275060ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class PolynomialAddition implements PolynomialOperation { private PolynomialOperation firstOperand; private PolynomialOperation secondOperand; private boolean hasParentheses; public PolynomialAddition( PolynomialOperation firstOperand, PolynomialOperation secondOperand ) { this( firstOperand, secondOperand, false ); } public PolynomialAddition( PolynomialOperation firstOperand, PolynomialOperation secondOperand, boolean hasParentheses ) { this.firstOperand = firstOperand; this.secondOperand = secondOperand; this.hasParentheses = hasParentheses; } public PolynomialOperation getFirstOperand() { return firstOperand; } public PolynomialOperation getSecondOperand() { return secondOperand; } public boolean hasParentheses() { return hasParentheses; } public < RETURN_TYPE, PARAM_TYPE > RETURN_TYPE accept( Visitor< RETURN_TYPE, PARAM_TYPE > visitor, PARAM_TYPE arg ) { return visitor.visit( this, arg ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/PolynomialDoubleDivision.java000066400000000000000000000030501330553604100306620ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class PolynomialDoubleDivision implements PolynomialOperation { private PolynomialOperation dividend; private DoubleOperation divisor; private boolean hasParentheses; public PolynomialDoubleDivision( PolynomialOperation dividend, DoubleOperation divisor ) { this( dividend, divisor, false ); } public PolynomialDoubleDivision( PolynomialOperation dividend, DoubleOperation divisor, boolean hasParentheses ) { this.dividend = dividend; this.divisor = divisor; this.hasParentheses = hasParentheses; } public PolynomialOperation getDividend() { return dividend; } public DoubleOperation getDivisor() { return divisor; } public boolean hasParentheses() { return hasParentheses; } public < RETURN_TYPE, PARAM_TYPE > RETURN_TYPE accept( Visitor< RETURN_TYPE, PARAM_TYPE > visitor, PARAM_TYPE arg ) { return visitor.visit( this, arg ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/PolynomialExpansion.java000066400000000000000000000076511330553604100277220ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import java.util.*; public class PolynomialExpansion extends AbstractVisitor< UnivariatePolynomial, Void > { private UnivariatePolynomial x; private UnivariatePolynomial y; private UnivariatePolynomial z; private ValueCalculator valueCalculator; public PolynomialExpansion( UnivariatePolynomial x, UnivariatePolynomial y, UnivariatePolynomial z ) { this.x = x; this.y = y; this.z = z; this.valueCalculator = new ValueCalculator( 0.0, 0.0, 0.0 ); } public UnivariatePolynomial getX() { return this.x; } public UnivariatePolynomial getY() { return this.y; } public UnivariatePolynomial getZ() { return this.z; } public void setX( UnivariatePolynomial x ) { this.x = x; } public void setY( UnivariatePolynomial y ) { this.y = y; } public void setZ( UnivariatePolynomial z ) { this.z = z; } public void setXYZ( UnivariatePolynomial x, UnivariatePolynomial y, UnivariatePolynomial z ) { this.x = x; this.y = y; this.z = z; } public UnivariatePolynomial visit( PolynomialAddition pa, Void param ) { return pa.getFirstOperand().accept( this, ( Void ) null ).add( pa.getSecondOperand().accept( this, ( Void ) null ) ); } public UnivariatePolynomial visit( PolynomialSubtraction ps, Void param ) { return ps.getFirstOperand().accept( this, ( Void ) null ).sub( ps.getSecondOperand().accept( this, ( Void ) null ) ); } public UnivariatePolynomial visit( PolynomialMultiplication pm, Void param ) { return pm.getFirstOperand().accept( this, ( Void ) null ).mult( pm.getSecondOperand().accept( this, ( Void ) null ) ); } public UnivariatePolynomial visit( PolynomialPower pp, Void param ) { return pp.getBase().accept( this, ( Void ) null ).pow( pp.getExponent() ); } public UnivariatePolynomial visit( PolynomialNegation pn, Void param ) { return pn.getOperand().accept( this,( Void ) null ).neg(); } public UnivariatePolynomial visit( PolynomialDoubleDivision pdd, Void param ) { return pdd.getDividend().accept( this,( Void ) null ).div( pdd.getDivisor().accept( this.valueCalculator, ( Void ) null ) ); } public UnivariatePolynomial visit( PolynomialVariable pv, Void param ) { switch( pv.getVariable() ) { case x: return this.x; case y: return this.y; case z: return this.z; default: throw new UnsupportedOperationException(); } } public UnivariatePolynomial visit( DoubleBinaryOperation dbop, Void param ) { return new UnivariatePolynomial( dbop.accept( this.valueCalculator, ( Void ) null ) ); } public UnivariatePolynomial visit( DoubleUnaryOperation duop, Void param ) { return new UnivariatePolynomial( duop.accept( this.valueCalculator, ( Void ) null ) ); } public UnivariatePolynomial visit( DoubleVariable dv, Void param ) { throw new UnsupportedOperationException(); } public UnivariatePolynomial visit( DoubleValue dv, Void param ) { return new UnivariatePolynomial( dv.getValue() ); } } PolynomialExpansionCoefficientCalculator.java000066400000000000000000000022041330553604100340010ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class PolynomialExpansionCoefficientCalculator implements CoefficientCalculator { private PolynomialOperation polynomialOperation; public PolynomialExpansionCoefficientCalculator( PolynomialOperation po ) { this.polynomialOperation = po; } public UnivariatePolynomial calculateCoefficients( UnivariatePolynomial x, UnivariatePolynomial y, UnivariatePolynomial z ) { return this.polynomialOperation.accept( new PolynomialExpansion( x, y, z ), ( Void ) null ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/PolynomialExpansionRowSubstitutor.java000077500000000000000000000046211330553604100326770ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class PolynomialExpansionRowSubstitutor implements RowSubstitutor { private PolynomialOperation po; private XYZPolynomial xyzp; private XYZPolynomial x3, y3, z3; public PolynomialExpansionRowSubstitutor( PolynomialOperation po, PolynomialOperation rayXComponent, PolynomialOperation rayYComponent, PolynomialOperation rayZComponent ) { Expand expand = new Expand(); this.po = po; this.xyzp = po.accept( expand, ( Void ) null ); x3 = rayXComponent.accept( expand, ( Void ) null ); y3 = rayYComponent.accept( expand, ( Void ) null ); z3 = rayZComponent.accept( expand, ( Void ) null ); } private static class myColumnSubstitutor implements ColumnSubstitutor { private PolynomialOperation po; private XYZPolynomial xyzp; private XYPolynomial x2, y2, z2; private double v; public myColumnSubstitutor( PolynomialOperation po, XYZPolynomial xyzp, XYZPolynomial x3, XYZPolynomial y3, XYZPolynomial z3, double v ) { this.v = v; this.po = po; this.xyzp = xyzp; this.x2 = x3.evaluateZ( v ); this.y2 = y3.evaluateZ( v ); this.z2 = z3.evaluateZ( v ); } @Override public UnivariatePolynomial setU( double u ) { UnivariatePolynomial x = this.x2.evaluateY( u ); UnivariatePolynomial y = this.y2.evaluateY( u ); UnivariatePolynomial z = this.z2.evaluateY( u ); //return this.po.accept( new UnivariatePolynomialExpansion( x, y, z ), ( Void ) null ); return xyzp.substitute( x, y, z ); } } public ColumnSubstitutor setV( double v ) { return new myColumnSubstitutor( po, xyzp, x3, y3, z3, v ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/PolynomialMultiplication.java000066400000000000000000000032101330553604100307360ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class PolynomialMultiplication implements PolynomialOperation { private PolynomialOperation firstOperand; private PolynomialOperation secondOperand; private boolean hasParentheses; public PolynomialMultiplication( PolynomialOperation firstOperand, PolynomialOperation secondOperand ) { this( firstOperand, secondOperand, false ); } public PolynomialMultiplication( PolynomialOperation firstOperand, PolynomialOperation secondOperand, boolean hasParentheses ) { this.firstOperand = firstOperand; this.secondOperand = secondOperand; this.hasParentheses = hasParentheses; } public PolynomialOperation getFirstOperand() { return firstOperand; } public PolynomialOperation getSecondOperand() { return secondOperand; } public boolean hasParentheses() { return hasParentheses; } public < RETURN_TYPE, PARAM_TYPE > RETURN_TYPE accept( Visitor< RETURN_TYPE, PARAM_TYPE > visitor, PARAM_TYPE arg ) { return visitor.visit( this, arg ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/PolynomialNegation.java000066400000000000000000000025221330553604100275120ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class PolynomialNegation implements PolynomialOperation { private PolynomialOperation operand; private boolean hasParentheses; public PolynomialNegation( PolynomialOperation operand ) { this( operand, false ); } public PolynomialNegation( PolynomialOperation operand, boolean hasParentheses ) { this.operand = operand; this.hasParentheses = hasParentheses; } public PolynomialOperation getOperand() { return operand; } public boolean hasParentheses() { return hasParentheses; } public < RETURN_TYPE, PARAM_TYPE > RETURN_TYPE accept( Visitor< RETURN_TYPE, PARAM_TYPE > visitor, PARAM_TYPE arg ) { return visitor.visit( this, arg ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/PolynomialOperation.java000066400000000000000000000014771330553604100277160ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public interface PolynomialOperation { public boolean hasParentheses(); public < RETURN_TYPE, PARAM_TYPE > RETURN_TYPE accept( Visitor< RETURN_TYPE, PARAM_TYPE > visitor, PARAM_TYPE arg ); } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/PolynomialPower.java000066400000000000000000000030541330553604100270430ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class PolynomialPower implements PolynomialOperation { private PolynomialOperation base; private int exponent; private boolean hasParentheses; public PolynomialPower( PolynomialOperation base, int exponent ) { this( base, exponent, false ); } public PolynomialPower( PolynomialOperation base, int exponent, boolean hasParentheses ) { if( exponent < 0 ) throw new IllegalArgumentException( "exponent must be >= 0" ); this.base = base; this.exponent = exponent; this.hasParentheses = hasParentheses; } public PolynomialOperation getBase() { return base; } public int getExponent() { return exponent; } public boolean hasParentheses() { return hasParentheses; } public < RETURN_TYPE, PARAM_TYPE > RETURN_TYPE accept( Visitor< RETURN_TYPE, PARAM_TYPE > visitor, PARAM_TYPE arg ) { return visitor.visit( this, arg ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/PolynomialSubtraction.java000066400000000000000000000031771330553604100302520ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class PolynomialSubtraction implements PolynomialOperation { private PolynomialOperation firstOperand; private PolynomialOperation secondOperand; private boolean hasParentheses; public PolynomialSubtraction( PolynomialOperation firstOperand, PolynomialOperation secondOperand ) { this( firstOperand, secondOperand, false ); } public PolynomialSubtraction( PolynomialOperation firstOperand, PolynomialOperation secondOperand, boolean hasParentheses ) { this.firstOperand = firstOperand; this.secondOperand = secondOperand; this.hasParentheses = hasParentheses; } public PolynomialOperation getFirstOperand() { return firstOperand; } public PolynomialOperation getSecondOperand() { return secondOperand; } public boolean hasParentheses() { return hasParentheses; } public < RETURN_TYPE, PARAM_TYPE > RETURN_TYPE accept( Visitor< RETURN_TYPE, PARAM_TYPE > visitor, PARAM_TYPE arg ) { return visitor.visit( this, arg ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/PolynomialVariable.java000066400000000000000000000024731330553604100275000ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class PolynomialVariable implements PolynomialOperation { public enum Var { x, y, z; } private Var variable; private boolean hasParentheses; public PolynomialVariable( Var variable ) { this( variable, false ); } public PolynomialVariable( Var variable, boolean hasParentheses ) { this.variable = variable; this.hasParentheses = hasParentheses; } public Var getVariable() { return variable; } public boolean hasParentheses() { return hasParentheses; } public < RETURN_TYPE, PARAM_TYPE > RETURN_TYPE accept( Visitor< RETURN_TYPE, PARAM_TYPE > visitor, PARAM_TYPE arg ) { return visitor.visit( this, arg ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/RealRootFinder.java000066400000000000000000000027301330553604100265620ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public interface RealRootFinder { /** * Find all real roots of p. * @param p * @return */ public double[] findAllRoots( UnivariatePolynomial p ); /** * Find all real roots of p within lowerBound and upperBound (bounds may or may not be included). * @param p * @param lowerBound * @param upperBound * @return */ public double[] findAllRootsIn( UnivariatePolynomial p, double lowerBound, double upperBound ); /** * Find the smallest real root of p within lowerBound and upperBound (bounds may or may not be included). * If no real root exists in this interval, Double.NaN ist returned. * @param p * @param lowerBound * @param upperBound * @return */ public double findFirstRootIn( UnivariatePolynomial p, double lowerBound, double upperBound ); } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/RowSubstitutor.java000066400000000000000000000013131330553604100267360ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public interface RowSubstitutor { public ColumnSubstitutor setV( double v ); } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/RowSubstitutorForGradient.java000066400000000000000000000013771330553604100310750ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; /** * * @author stussak */ public interface RowSubstitutorForGradient { public ColumnSubstitutorForGradient setV( double v ); } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/SimpleGradientCalculator.java000066400000000000000000000034631330553604100306300ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import javax.vecmath.*; @Deprecated public class SimpleGradientCalculator implements GradientCalculator { private PolynomialOperation gradientXExpression; private PolynomialOperation gradientYExpression; private PolynomialOperation gradientZExpression; public SimpleGradientCalculator( PolynomialOperation gradientXExpression, PolynomialOperation gradientYExpression, PolynomialOperation gradientZExpression ) { this.gradientXExpression = gradientXExpression; this.gradientYExpression = gradientYExpression; this.gradientZExpression = gradientZExpression; } public Vector3d calculateGradient( Point3d p ) { ValueCalculator vc = new ValueCalculator( p.x, p.y, p.z ); double x = gradientXExpression.accept( vc, ( Void ) null ); double y = gradientYExpression.accept( vc, ( Void ) null ); double z = gradientZExpression.accept( vc, ( Void ) null ); return new Vector3d( x, y, z ); } public Vector3f calculateGradient( Point3f p ) { Vector3d g = calculateGradient( new Point3d( p.x, p.y, p.z ) ); return new Vector3f( ( float ) g.x, ( float ) g.y, ( float ) g.z ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/Simplificator.java000066400000000000000000000244611330553604100265150ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import java.util.*; public class Simplificator extends AbstractVisitor< PolynomialOperation, Void > { private Map< String, java.lang.Double > dict; public Simplificator() { this.dict = new HashMap< String, java.lang.Double >(); } public double getParameterValue( String name ) { return this.dict.get( name ); } public Set< String > getKnownParameterNames() { return this.dict.keySet(); } public Set< Map.Entry< String, java.lang.Double > > getKnownParameters() { return this.dict.entrySet(); } public void setParameterValue( String name, double value ) { this.dict.put( name, value ); } public void unsetParameterValue( String name ) { this.dict.remove(name); } public PolynomialOperation visit( PolynomialAddition pa, Void param ) { PolynomialOperation firstOperand = pa.getFirstOperand().accept( this, ( Void ) null ); PolynomialOperation secondOperand = pa.getSecondOperand().accept( this, ( Void ) null ); try { if( ( ( DoubleValue ) firstOperand ).getValue() == 0.0 ) return secondOperand; } catch( ClassCastException cce ) { } try { if( ( ( DoubleValue ) secondOperand ).getValue() == 0.0 ) return firstOperand; } catch( ClassCastException cce ) { } try { return new DoubleBinaryOperation( DoubleBinaryOperation.Op.add, ( DoubleOperation ) firstOperand, ( DoubleOperation ) secondOperand ); } catch( ClassCastException cce ) { } return new PolynomialAddition( firstOperand, secondOperand ); } public PolynomialOperation visit( PolynomialSubtraction ps, Void param ) { PolynomialOperation firstOperand = ps.getFirstOperand().accept( this, ( Void ) null ); PolynomialOperation secondOperand = ps.getSecondOperand().accept( this, ( Void ) null ); try { if( ( ( DoubleValue ) firstOperand ).getValue() == 0.0 ) return new PolynomialNegation( secondOperand ).accept( this, ( Void ) null ); } catch( ClassCastException cce ) { } try { if( ( ( DoubleValue ) secondOperand ).getValue() == 0.0 ) return firstOperand; } catch( ClassCastException cce ) { } try { return new DoubleBinaryOperation( DoubleBinaryOperation.Op.sub, ( DoubleOperation ) firstOperand, ( DoubleOperation ) secondOperand ); } catch( ClassCastException cce ) { } return new PolynomialSubtraction( firstOperand, secondOperand ); } public PolynomialOperation visit( PolynomialMultiplication pm, Void param ) { PolynomialOperation firstOperand = pm.getFirstOperand().accept( this, ( Void ) null ); PolynomialOperation secondOperand = pm.getSecondOperand().accept( this, ( Void ) null ); try { if( ( ( DoubleValue ) firstOperand ).getValue() == 0.0 ) return firstOperand; else if( ( ( DoubleValue ) firstOperand ).getValue() == 1.0 ) return secondOperand; } catch( ClassCastException cce ) { } try { if( ( ( DoubleValue ) secondOperand ).getValue() == 0.0 ) return secondOperand; else if( ( ( DoubleValue ) secondOperand ).getValue() == 1.0 ) return firstOperand; } catch( ClassCastException cce ) { } try { return new DoubleBinaryOperation( DoubleBinaryOperation.Op.mult, ( DoubleOperation ) firstOperand, ( DoubleOperation ) secondOperand ); } catch( ClassCastException cce ) { } return new PolynomialMultiplication( firstOperand, secondOperand ); } public PolynomialOperation visit( PolynomialPower pp, Void param ) { PolynomialOperation base = pp.getBase().accept( this, ( Void ) null ); if( pp.getExponent() == 0 ) { return new DoubleValue( 1.0 ); } else if( pp.getExponent() == 1 ) { return base; } else { } try { double dBase = ( ( DoubleValue ) base ).getValue(); return new DoubleValue( Math.pow( dBase, pp.getExponent() ) ); } catch( ClassCastException cce ) { } return new PolynomialPower( base, pp.getExponent() ); } public PolynomialOperation visit( PolynomialNegation pn, Void param ) { PolynomialOperation operand = pn.getOperand().accept( this, ( Void ) null ); try { return new DoubleValue( -( ( DoubleValue ) operand ).getValue() ); } catch( ClassCastException cce ) { return new PolynomialNegation( operand ); } } public PolynomialOperation visit( PolynomialDoubleDivision pdd, Void param ) { PolynomialOperation dividend = pdd.getDividend().accept( this, ( Void ) null ); PolynomialOperation divisor = pdd.getDivisor().accept( this, ( Void ) null ); try { return new DoubleValue( ( ( DoubleValue ) dividend ).getValue() / ( ( DoubleValue ) divisor ).getValue() ); } catch( ClassCastException cce1 ) { } try { return new DoubleBinaryOperation( DoubleBinaryOperation.Op.div, ( DoubleOperation ) dividend, ( DoubleOperation ) divisor ); } catch( ClassCastException cce2 ) { return new PolynomialDoubleDivision( dividend, ( DoubleOperation ) divisor ); } } public PolynomialOperation visit( PolynomialVariable pv, Void param ) { return pv; } public DoubleOperation visit( DoubleBinaryOperation dbop, Void param ) { DoubleOperation firstOperand = ( DoubleOperation ) dbop.getFirstOperand().accept( this, ( Void ) null ); DoubleOperation secondOperand = ( DoubleOperation ) dbop.getSecondOperand().accept( this, ( Void ) null ); try { double firstValue = ( ( DoubleValue ) firstOperand ).getValue(); double secondValue = ( ( DoubleValue ) secondOperand ).getValue(); double result; switch( dbop.getOperator() ) { case add: result = firstValue + secondValue; break; case sub: result = firstValue - secondValue; break; case mult: result = firstValue * secondValue; break; case div: result = firstValue / secondValue; break; case pow: result = Math.pow( firstValue, secondValue ); break; default: throw new UnsupportedOperationException(); } return new DoubleValue( result ); } catch( ClassCastException cce ) { return new DoubleBinaryOperation( dbop.getOperator(), firstOperand, secondOperand ); } } public DoubleOperation visit( DoubleUnaryOperation duop, Void param ) { DoubleOperation operand = ( DoubleOperation ) duop.getOperand().accept( this, ( Void ) null ); try { double value = ( ( DoubleValue ) operand ).getValue(); double result; switch( duop.getOperator() ) { case neg: result = -value; break; case sin: result = Math.sin( value ); break; case cos: result = Math.cos( value ); break; case tan: result = Math.tan( value ); break; case asin: result = Math.asin( value ); break; case acos: result = Math.acos( value ); break; case atan: result = Math.atan( value ); break; case exp: result = Math.exp( value ); break; case log: result = Math.log( value ); break; case sqrt: result = Math.sqrt( value ); break; case ceil: result = Math.ceil( value ); break; case floor: result = Math.floor( value ); break; case abs: result = Math.abs( value ); break; case sign: result = Math.signum( value ); break; default: throw new UnsupportedOperationException(); } return new DoubleValue( result ); } catch( ClassCastException cce ) { return new DoubleUnaryOperation( duop.getOperator(), operand ); } } public DoubleOperation visit( DoubleValue dv, Void param ) { return dv; } public DoubleOperation visit( DoubleVariable dv, Void param ) { try { return new DoubleValue( this.dict.get( dv.getName() ) ); } catch( NullPointerException npe ) { return dv; } } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/SturmChainRootFinder.java000066400000000000000000000333561330553604100277640ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import java.util.LinkedList; import java.util.List; public class SturmChainRootFinder implements RealRootFinder { /** * Find all real roots of p. * @param p * @return */ public double[] findAllRoots( UnivariatePolynomial p ) { assert false; return null; } /** * Find all real roots of p within lowerBound and upperBound (bounds may or may not be included). * @param p * @param lowerBound * @param upperBound * @return */ public double[] findAllRootsIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { assert false; return null; } /** * Find the smallest real root of p within lowerBound and upperBound (bounds may or may not be included). * If no real root exists in this interval, Double.NaN ist returned. * @param p * @param lowerBound * @param upperBound * @return */ public double findFirstRootIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { return Solve.solve( new MyPolynomial( p ), 1, lowerBound, upperBound, 20 ); } } interface Function { /** * Evaluates a function at a given point * * @param x * the point, at which the function has to be evaluated * @return the function value at x */ public double valueAt(double x); } abstract class SturmPolynomial implements Function { /** * Returns the coefficients array of the polynomial * * @return the coefficients array of the polynomial, where * result[n] is the coefficient before X^n */ public abstract double[] toArray(); /** * Calculates the first derivative of the polynomial * * @return the derivation */ public abstract SturmPolynomial diff(); /** * Calculates the remainder of the polynomial division of this * by other * * @param other * the divisor (must not be constant) * @return the remainder of the polynomial division */ public abstract SturmPolynomial mod(SturmPolynomial other); public abstract SturmPolynomial div(SturmPolynomial other); /** * Multiplies the polynomial by a real scalar * * @param scalar * the scalar to multiply the polynomial by * @return the multiplied polynomial */ public abstract SturmPolynomial multiply(double scalar); /** * Determines the degree of the polynomial * * @return the degree of the polynomial, where the degree of the zero * polynomial is defined as -1 */ public abstract int degree(); public static SturmPolynomial gcd( SturmPolynomial a, SturmPolynomial b ) { while( b.degree() != -1 ) { SturmPolynomial t = b; b = a.mod( b ); a = t; } return a; } } class MyPolynomial extends SturmPolynomial { UnivariatePolynomial p; public MyPolynomial( UnivariatePolynomial p ) { this.p = p; } public double valueAt( double x ) { return p.evaluateAt( x ); } public double[] toArray() { return p.getCoeffs(); } public SturmPolynomial diff() { return new MyPolynomial( p.derive() ); } private double[] reduce(double[] a, int degA, double[] b, int degB) { int degDiff = degA - degB; double[] result = new double[degA]; for (int i = degA - 1; i >= degDiff; i--) { result[i] = a[i] - b[i - degDiff] / b[degB] * a[degA]; } for (int i = 0; i < degDiff; i++) { result[i] = a[i]; } return result; } private double[] mod(double[] a, int degA, double[] b, int degB) { if (degB < 1) { // the illegal case if( degB == -1 ) { throw new IllegalArgumentException( "Cannot divide by constant polynomials"); } else { double[] result = new double[ 1 ]; result[ 0 ] = 0.0; return result; } } else if (degA < degB) { // the basic case return a; } else { // the recursion case // reduce a by b double[] result = reduce(a, degA, b, degB); // calculate the degree of the result int newDeg = degA - 1; while (newDeg >= 0 && result[newDeg] == 0) { newDeg--; } // do recursion return mod(result, newDeg, b, degB); } } public SturmPolynomial mod(SturmPolynomial other) { return new MyPolynomial( new UnivariatePolynomial( mod( toArray(), degree(), other.toArray(), other.degree() ) ) ); } public SturmPolynomial div(SturmPolynomial other) { return new MyPolynomial( new UnivariatePolynomial( reduce( toArray(), degree(), other.toArray(), other.degree() ) ) ); } public SturmPolynomial multiply(double scalar) { return new MyPolynomial( p.mult( scalar ) ); } public int degree() { double[] coeffs = p.getCoeffs(); int deg = -1; for( int i = 0; i < coeffs.length; i++ ) if( coeffs[ i ] != 0.0 ) deg++; return deg; } } class Solve { private static final double FLOATING_POINT_PRECISION = 0; /** * Search zeroes of a polynomial function by executing a bisection algorithm * using Sturm's theorem * * @param sturm * the function, whose zeroes are searched * @param num * the number of the wanted zero; counting starts from * lower * @param lower * lower bound of the interval, in which the zero is searched * @param upper * upper bound of the interval, in which the zero is searched * @param precision * tolerance in comparing function values * @param iterations * maximum number of iterations (the more iterations, the more * precise the result); the algorithm stops before that maximum * number, when it reaches sufficient precision (machine * precision) * @return the zero */ public static double solve(SturmPolynomial poly, int num, double lower, double upper, double precision, int iterations) { return bisection(calculateSturm(poly), num, lower, upper, precision, iterations); } /** * Search zeroes of a polynomial function by executing a bisection algorithm * using Sturm's theorem * * @param sturm * the function, whose zeroes are searched * @param num * the number of the wanted zero; counting starts from * lower * @param lower * lower bound of the interval, in which the zero is searched * @param upper * upper bound of the interval, in which the zero is searched * @param iterations * maximum number of iterations (the more iterations, the more * precise the result); the algorithm stops before that maximum * number, when it reaches sufficient precision (machine * precision) * @return the zero */ public static double solve(SturmPolynomial poly, int num, double lower, double upper, int iterations) { return bisection(calculateSturm(poly), num, lower, upper, FLOATING_POINT_PRECISION, iterations); } /** * Sturm's "w" function for counting zeroes * * @param sturm * the Sturm chain as array * @param x * where to evaluate the "w" function * @param precision * tolerance in comparing function values * @return the result of the "w" function defined by Sturm */ private static int w(SturmPolynomial[] sturm, double x, double precision) { int signChanges = 0; int lastNonZero = 0; // run through the array for (int i = 1; i < sturm.length; i++) { if (Math.abs(sturm[i].valueAt(x)) > precision) { // compare the sign to the last non-zero sign if (sturm[lastNonZero].valueAt(x) * sturm[i].valueAt(x) < 0) { // sign change found: count up signChanges++; } lastNonZero = i; } } return signChanges; } /** * Search zeroes of a polynomial function by executing a bisection algorithm * using Sturm's theorem * * @param sturm * the Sturm chain of the function * @param num * the number of the wanted zero; counting starts from * lower * @param lower * lower bound of the interval, in which the zero is searched * @param upper * upper bound of the interval, in which the zero is searched * @param precision * tolerance in comparing function values * @param iterations * maximum number of iterations (the more iterations, the more * precise the result); the algorithm stops before that maximum * number, when it reaches sufficient precision (machine * precision) * @return the zero */ private static double bisection(SturmPolynomial[] sturm, int num, double lower, double upper, double precision, int iterations) { SturmPolynomial p = sturm[ sturm.length - 1 ]; // define the point where to start counting the zeroes double t = lower; // do the maximum number or iterations (if necessary) for (int i = 0; i < iterations; i++) { // determine the middle of the interval double c = (upper + lower) / 2; // Check, if we have already reached machine precision if (upper <= lower || c <= lower || c >= upper) { return lower; } // Left or right interval? // Are there less than "num" zeroes between t and c? int sign_changes = w(sturm, t, precision) - w(sturm, c, precision); if ( sign_changes < num) { // right lower = c; } else { // left upper = c; } double fl = p.valueAt( lower ); double fu = p.valueAt( upper ); if( fl * fu < 0.0 ) return bisect( p, lower, upper, fl, fu ); } // the wanted zero lies in the intervall [lower, upper], // so the middle of this interval might be a good guess if (w(sturm, upper, precision) - w(sturm, t, precision) == 0 ) return java.lang.Double.NaN; else return (upper + lower) / 2; } private static double bisect( SturmPolynomial p, double lowerBound, double upperBound, double fl, double fu ) { double center = lowerBound; double old_center = java.lang.Double.NaN; double[] a = p.toArray(); //for( int it = 14; it > 0; it-- ) // 14 iterations work quite good in most cases while( center != old_center ) { old_center = center; center = 0.5 * ( lowerBound + upperBound ); double fc = a[ a.length - 1 ]; for( int i = a.length - 2; i >= 0; i-- ) fc = fc * center + a[ i ]; if( fc * fl < 0.0 ) { upperBound = center; fu = fc; } else if( fc == 0.0 ) { return center; } else { lowerBound = center; fl = fc; } } return center; } /** * Calculates the Sturm chain to a given polynomial * * @param function * the polynomial function * @return the Sturm chain of function as array */ public static SturmPolynomial[] calculateSturm(SturmPolynomial function) { List sturm = new LinkedList(); SturmPolynomial gcd = SturmPolynomial.gcd( function, function.diff() ); if( gcd.degree() > 0 ) // Polynomial not squarefree! function = function.div( gcd ); // add the original function and its derivation sturm.add(0, function); sturm.add(0, function.diff()); // iteratively perform polynomial divison while (sturm.get(0).degree() > 0) { sturm.add(0, sturm.get(1).mod(sturm.get(0)).multiply(-1)); } // convert the list to an array for efficiency purposes SturmPolynomial[] result = new MyPolynomial[sturm.size()]; int i = 0; for (SturmPolynomial poly : sturm) { result[i] = poly; i++; } return result; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/SturmChainRootFinder2.java000066400000000000000000000143151330553604100300400ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class SturmChainRootFinder2 implements RealRootFinder { /** * Find all real roots of p. * @param p * @return */ public double[] findAllRoots( UnivariatePolynomial p ) { return null; } /** * Find all real roots of p within lowerBound and upperBound (bounds may or may not be included). * @param p * @param lowerBound * @param upperBound * @return */ public double[] findAllRootsIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { return null; } /** * Find the smallest real root of p within lowerBound and upperBound (bounds may or may not be included). * If no real root exists in this interval, Double.NaN ist returned. * @param p * @param lowerBound * @param upperBound * @return */ public double findFirstRootIn( UnivariatePolynomial p, double lowerBound, double upperBound ) { return java.lang.Double.NaN; } /* // das hier irgendwie nach java übersetzen float epsilon = 0.0001; float sturm_chain[ ( SIZE * ( SIZE + 1 ) ) / 2 ]; int sc_index( int f_index, int c_index ) { //int result = 0; //for( int i = DEGREE; i > f_index; i-- ) // result += i; //return result + c_index; return ( SIZE * ( SIZE + 1 ) ) / 2 - 1 - ( ( f_index + 1 ) * ( f_index + 2 ) ) / 2 + c_index; } float eval_f( float where ) { float res = 0.0; for( int i = DEGREE; i >= 0; i-- ) res = sturm_chain[ sc_index( DEGREE, i ) ] + where * res; return res; } float bisection( float x0, float x1 ) { float f0 = eval_f( x0 ); float f1 = eval_f( x1 ); float x2 = x0; while( abs( x0 - x1 ) > epsilon ) { x2 = 0.5 * ( x0 + x1 ); float f2 = eval_f( x2 ); if( f2 * f0 < 0 ) { x1 = x2; f1 = f2; } else { x0 = x2; f0 = f2; } } return x2; } bool contains( const in vec2 interval, const in float value ) { return ( interval[ 0 ] < value && value < interval[ 1 ] ) || ( interval[ 0 ] > value && value > interval[ 1 ] ); } void polynom_div( int dividend, int divisor, int remainder ) { // copy dividend to be the current remainder int i; for( i = 0; i <= dividend; i++ ) sturm_chain[ sc_index( remainder, i )] = sturm_chain[ sc_index( dividend, i ) ]; int degree_diff = dividend - divisor; for( i = dividend; i >= divisor; i-- ) { // calculate quotient of highest coefficient float quotient = sturm_chain[ sc_index( remainder, i ) ] / sturm_chain[ sc_index( divisor, divisor ) ]; // after this step the highest coeff. of the old remainder is actually zero //sturm_chain[ remainder * SIZE + i ] = 0.0; // unnecessary calculation, because value is known // calculate new coeffs. of the remainder for( int j = 0; j < divisor; j++ ) sturm_chain[ sc_index( remainder, j + degree_diff ) ] = sturm_chain[ sc_index( remainder, j + degree_diff ) ] - sturm_chain[ sc_index( divisor, j ) ] * quotient; degree_diff--; } } void construct_sturm_chain() { // calculate first derivate of f int i; //sturm_chain[ DEGREE - 1 ][ DEGREE ] = 0.0f; for( i = 1; i <= DEGREE; i++ ) sturm_chain[ sc_index( DEGREE - 1, i - 1 ) ] = float( i ) * sturm_chain[ sc_index( DEGREE, i ) ];// / ( DEGREE * sturm_chain[ DEGREE ][ DEGREE ] ); // calculate sturm chain for( i = DEGREE - 2; i >= 0; i-- ) { // polynom division, which outputs the remainder to the sturm_chain-array polynom_div( i + 2, i + 1, i ); // flip the sign of the remainder and normalize polynom for( int j = 0; j <= i; j++ ) sturm_chain[ sc_index( i, j ) ] = -sturm_chain[ sc_index( i, j ) ]; } } float f_sturm( int num, float t ) { float res = 0.0; for( int i = num; i >= 0; i-- ) res = sturm_chain[ sc_index( num, i ) ] + t * res; return res; } int sign_change( float t ) { int sign_sum = 0; float last_sign, cur_sign; // #Vorzeichenwechsel an t berechnen last_sign = sign( f_sturm( DEGREE, t ) ); for( int i = DEGREE - 1; i >= 0; i-- ) { cur_sign = sign( f_sturm( i, t ) ); sign_sum += ( last_sign != cur_sign ) ? 1 : 0; if( cur_sign != 0.0 ) last_sign = cur_sign; } return sign_sum; } float bisection_sturm( float x0, float x1 ) { float x2 = x0 - 1.0; float sign_change_0 = sign_change( x0 ); float sign_change_1 = sign_change( x1 ); if( ( sign_change_0 - sign_change_1 ) != 0 ) { { float f0 = eval_f( x0 ); float f1 = eval_f( x1 ); while( !( sign_change_0 - sign_change_1 == 1 && f0 * f1 < 0.0 ) ) { x2 = 0.5 * ( x0 + x1 ); float sign_change_2 = sign_change( x2 ); float f2 = eval_f( x2 ); if( sign_change_0 - sign_change_2 > 0 ) { // there is a root in the first interval -> search in first x1 = x2; f1 = f2; sign_change_1 = sign_change_2; } else { // there is no root in the first interval -> search in second x0 = x2; f0 = f2; sign_change_0 = sign_change_2; } } } x2 = bisection( x0, x1 ); } return x2; } struct roots { float x[ DEGREE + 2 ]; bool valid[ DEGREE + 2 ]; }; roots solve( const in polynomial p, const in vec2 trace_interval ) { #if DEGREE > 1 // fill sturm chain array for( int i = 0; i < SIZE; i++ ) sturm_chain[ sc_index( DEGREE, i ) ] = p.a[ i ]; construct_sturm_chain(); #endif // init result array roots res; res.x[ 0 ] = trace_interval[ 0 ]; res.valid[ 0 ] = false; for( int i = 1; i < DEGREE + 2; i++ ) { res.x[ i ] = trace_interval[ 1 ]; res.valid[ i ] = false; } #if DEGREE > 1 // apply sturm's algorithm res.x[ 1 ] = bisection_sturm( trace_interval[ 0 ], trace_interval[ 1 ] ); #else // solve linear equation directly res.x[ 1 ] = -p.a[ 0 ] / p.a[ 1 ]; #endif res.valid[ 1 ] = contains( trace_interval, res.x[ 1 ] ); return res; } */ } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/ToStringVisitor.java000066400000000000000000000125611330553604100270370ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class ToStringVisitor extends AbstractVisitor< String, Void > { final static String LPAR = "("; final static String RPAR = ")"; private boolean onlyExplicitParentheses; public ToStringVisitor() { this( false ); } public ToStringVisitor( boolean onlyExplicitParentheses ) { this.onlyExplicitParentheses = onlyExplicitParentheses; } protected boolean getOnlyExplicitParentheses() { return onlyExplicitParentheses; } String lp( PolynomialOperation pop ) { return !onlyExplicitParentheses || pop.hasParentheses() ? LPAR : ""; } String rp( PolynomialOperation pop ) { return !onlyExplicitParentheses || pop.hasParentheses() ? RPAR : ""; } public String visit( PolynomialOperation pop, Void param ) { return lp(pop) + pop.toString() + rp(pop); } public String visit( PolynomialAddition pa, Void param ) { return lp(pa) + pa.getFirstOperand().accept( this, ( Void ) null ) + "+" + pa.getSecondOperand().accept( this, ( Void ) null ) + rp(pa); } public String visit( PolynomialSubtraction ps, Void param ) { return lp(ps) + ps.getFirstOperand().accept( this, ( Void ) null ) + "-" + ps.getSecondOperand().accept( this, ( Void ) null ) + rp(ps); } public String visit( PolynomialMultiplication pm, Void param ) { return lp(pm) + pm.getFirstOperand().accept( this, ( Void ) null ) + "*" + pm.getSecondOperand().accept( this, ( Void ) null ) + rp(pm); } public String visit( PolynomialPower pp, Void param ) { return lp(pp) + pp.getBase().accept( this, ( Void ) null ) + "^" + pp.getExponent() + rp(pp); } public String visit( PolynomialNegation pn, Void param ) { return lp(pn) + "-" + pn.getOperand().accept( this, ( Void ) null ) + rp(pn); } public String visit( PolynomialDoubleDivision pdd, Void param ) { return lp(pdd) + pdd.getDividend().accept( this,( Void ) null ) + "/" + pdd.getDivisor().accept( this,( Void ) null ) + rp(pdd); } public String visit( PolynomialVariable pv, Void param ) { return lp(pv) + pv.getVariable().toString() + rp(pv); } public String visit( DoubleOperation dop, Void param ) { return lp(dop) + dop.toString() + rp(dop); } public String visit( DoubleBinaryOperation dbop, Void param ) { String lp = lp(dbop); String rp = lp(dbop); String firstOperand = dbop.getFirstOperand().accept( this, ( Void ) null ); String secondOperand = dbop.getSecondOperand().accept( this, ( Void ) null ); switch( dbop.getOperator() ) { case add: return lp + firstOperand + "+" + secondOperand + rp; case sub: return lp + firstOperand + "-" + secondOperand + rp; case mult: return lp + firstOperand + "*" + secondOperand + rp; case div: return lp + firstOperand + "/" + secondOperand + rp; case pow: return lp + firstOperand + "^" + secondOperand + rp; default: throw new UnsupportedOperationException(); } } public String visit( DoubleUnaryOperation duop, Void param ) { String lp = lp(duop); String rp = lp(duop); String operand = duop.getOperand().accept( this, ( Void ) null ); switch( duop.getOperator() ) { case neg: return lp + "-" + operand + rp; case sin: return "sin" + lp + operand + rp; case cos: return "cos" + lp + operand + rp; case tan: return "tan" + lp + operand + rp; case asin: return "asin" + lp + operand + rp; case acos: return "acos" + lp + operand + rp; case atan: return "atan" + lp + operand + rp; case exp: return "exp" + lp + operand + rp; case log: return "log" + lp + operand + rp; case sqrt: return "sqrt" + lp + operand + rp; case ceil: return "ceil" + lp + operand + rp; case floor: return "floor" + lp + operand + rp; case abs: return "abs" + lp + operand + rp; case sign: return "signum" + lp + operand + rp; default: throw new UnsupportedOperationException(); } } public String visit( DoubleValue dv, Void param ) { return lp(dv) + dv.toString() + rp(dv); } public String visit( DoubleVariable dv, Void param ) { return lp(dv) + dv.getName() + rp(dv); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/TransformedPolynomialRowSubstitutor.java000066400000000000000000000053641330553604100332210ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import javax.vecmath.*; public class TransformedPolynomialRowSubstitutor implements RowSubstitutor { private XYZPolynomial tuvPolynomial; public TransformedPolynomialRowSubstitutor( PolynomialOperation po, PolynomialOperation rayXComponent, PolynomialOperation rayYComponent, PolynomialOperation rayZComponent ) { ToStringVisitor tsv = new ToStringVisitor(); //System.out.println(); //System.out.println( "x=" + rayXComponent.accept( tsv, null ) ); //System.out.println( "y=" + rayYComponent.accept( tsv, null ) ); //System.out.println( "z=" + rayZComponent.accept( tsv, null ) ); Expand expand = new Expand(); XYZPolynomial p = po.accept( expand, ( Void ) null ); //System.out.println( "p=" + p ); XYZPolynomial x = rayXComponent.accept( expand, ( Void ) null ); XYZPolynomial y = rayYComponent.accept( expand, ( Void ) null ); XYZPolynomial z = rayZComponent.accept( expand, ( Void ) null ); tuvPolynomial = p.substitute( x, y, z ); //System.out.println( tuvPolynomial ); } public TransformedPolynomialRowSubstitutor( XYZPolynomial p, XYZPolynomial rayXComponent, XYZPolynomial rayYComponent, XYZPolynomial rayZComponent ) { tuvPolynomial = p.substitute( rayXComponent, rayYComponent, rayZComponent ); } private static class myColumnSubstitutor implements ColumnSubstitutor { private XYPolynomial tuPolynomial; private double v; public myColumnSubstitutor( XYZPolynomial tvuPolynomial, double v ) { this.v = v; this.tuPolynomial = tvuPolynomial.evaluateZ( v ); //System.out.println( "coeffs at v=" + v + ":" + this.tuPolynomial ); } public UnivariatePolynomial setU( double u ) { //System.out.println( "coeffs at v=" +v+",u=" + u+ ":" + this.tuPolynomial.evaluateY( u ) ); return this.tuPolynomial.evaluateY( u ); } } public ColumnSubstitutor setV( double v ) { return new myColumnSubstitutor( tuvPolynomial, v ); } } TransformedPolynomialRowSubstitutorForGradient.java000066400000000000000000000065101330553604100352610ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import javax.vecmath.Vector3d; public class TransformedPolynomialRowSubstitutorForGradient implements RowSubstitutorForGradient { TransformedPolynomialRowSubstitutor tprs_px; TransformedPolynomialRowSubstitutor tprs_py; TransformedPolynomialRowSubstitutor tprs_pz; public TransformedPolynomialRowSubstitutorForGradient( PolynomialOperation pox, PolynomialOperation poy, PolynomialOperation poz, PolynomialOperation rayXComponent, PolynomialOperation rayYComponent, PolynomialOperation rayZComponent ) { Expand expand = new Expand(); XYZPolynomial px = pox.accept( expand, ( Void ) null ); XYZPolynomial py = poy.accept( expand, ( Void ) null ); XYZPolynomial pz = poz.accept( expand, ( Void ) null ); XYZPolynomial x = rayXComponent.accept( expand, ( Void ) null ); XYZPolynomial y = rayYComponent.accept( expand, ( Void ) null ); XYZPolynomial z = rayZComponent.accept( expand, ( Void ) null ); tprs_px = new TransformedPolynomialRowSubstitutor( px, x, y, z ); tprs_py = new TransformedPolynomialRowSubstitutor( py, x, y, z ); tprs_pz = new TransformedPolynomialRowSubstitutor( pz, x, y, z ); } class TransformedPolynomialColumnSubstitutorForGradient implements ColumnSubstitutorForGradient { double v; ColumnSubstitutor cs_px; ColumnSubstitutor cs_py; ColumnSubstitutor cs_pz; public TransformedPolynomialColumnSubstitutorForGradient( RowSubstitutor rs_x, RowSubstitutor rs_y, RowSubstitutor rs_z, double v ) { this.v = v; this.cs_px = rs_x.setV( v ); this.cs_py = rs_y.setV( v ); this.cs_pz = rs_z.setV( v ); } class myUnivariatePolynomialVector3d implements UnivariatePolynomialVector3d { private UnivariatePolynomial px; private UnivariatePolynomial py; private UnivariatePolynomial pz; public myUnivariatePolynomialVector3d( UnivariatePolynomial px, UnivariatePolynomial py, UnivariatePolynomial pz ) { this.px = px; this.py = py; this.pz = pz; } public Vector3d setT( double t ) { return new Vector3d( px.evaluateAt( t ), py.evaluateAt( t ), pz.evaluateAt( t ) ); } } public UnivariatePolynomialVector3d setU( double u ) { return new myUnivariatePolynomialVector3d( cs_px.setU( u ), cs_py.setU( u ), cs_pz.setU( u ) ); } } public ColumnSubstitutorForGradient setV( double v ) { return new TransformedPolynomialColumnSubstitutorForGradient( tprs_px, tprs_py, tprs_pz, v ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/UnivariatePolynomial.java000066400000000000000000000607141330553604100300640ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class UnivariatePolynomial { public static final UnivariatePolynomial ZERO; public static final UnivariatePolynomial ONE; static { ZERO = new UnivariatePolynomial( 0.0 ); ONE = new UnivariatePolynomial( 1.0 ); } private double[] a; private int degree; private UnivariatePolynomial() {} public UnivariatePolynomial( int degree ) { this.a = new double[ degree + 1 ]; this.degree = degree; } public UnivariatePolynomial( double... coeffs ) { this.setCoeffs( coeffs, false ); } public UnivariatePolynomial( double[] coeffs, boolean copy ) { if( copy ) { this.a = new double[ coeffs.length ]; System.arraycopy( coeffs, 0, this.a, 0, coeffs.length ); } else { this.a = coeffs; } this.degree = coeffs.length - 1; } public UnivariatePolynomial( UnivariatePolynomial p ) { this.setCoeffs( p.a, true ); } private UnivariatePolynomial( int degree, double[] coeffs ) { this.a = new double[ degree + 1 ]; System.arraycopy( coeffs, 0, this.a, 0, this.a.length ); this.degree = degree; } public boolean isZero() { for( double c : a ) if( c != 0.0 ) return false; return true; } public boolean isOne() { if( a[ 0 ] != 1.0 ) return false; for( int i = a.length - 1; i > 0; --i ) if( a[ i ] != 0.0 ) return false; return true; } private void setCoeff( int which, double value ) { this.a[ which ] = value; } private void setCoeffs( double[] coeffs, boolean copy ) { if( copy ) { this.a = new double[ coeffs.length ]; System.arraycopy( coeffs, 0, this.a, 0, coeffs.length ); } else { this.a = coeffs; } this.degree = coeffs.length - 1; } public double getCoeff( int which ) { return this.a[ which ]; } public double[] getCoeffs() { double[] result = new double[ a.length ]; System.arraycopy( a, 0, result, 0, a.length ); return result; } public int degree() { return this.degree; } public UnivariatePolynomial neg() { UnivariatePolynomial result = new UnivariatePolynomial( this.degree ); for( int i = 0; i < this.a.length; i++ ) result.a[ i ] = -this.a[ i ]; return result; } public UnivariatePolynomial add( UnivariatePolynomial p ) { UnivariatePolynomial result; UnivariatePolynomial summand; if( this.degree > p.degree ) { result = new UnivariatePolynomial( this ); summand = p; } else { result = new UnivariatePolynomial( p ); summand = this; } for( int i = 0; i < summand.a.length; i++ ) result.a[ i ] += summand.a[ i ]; return result.compact(); } public UnivariatePolynomial add( double d ) { if( d == 0.0 ) return this; UnivariatePolynomial result = new UnivariatePolynomial( this ); result.a[ 0 ] += d; return result.compact(); } public UnivariatePolynomial sub( UnivariatePolynomial p ) { return this.add( p.neg() ).compact(); } public UnivariatePolynomial sub( double d ) { if( d == 0.0 ) return this; else return this.add( -d ); } UnivariatePolynomial mult( UnivariatePolynomial p, int min_degree ) { if( p.degree == 1 ) { UnivariatePolynomial result = new UnivariatePolynomial( Math.max( this.degree + p.degree, min_degree + 1 ) ); result.a[ 0 ] = this.a[ 0 ] * p.a[ 0 ]; for( int i = 1; i < result.a.length - 1; i++ ) result.a[ i ] = this.a[ i ] * p.a[ 0 ] + this.a[ i - 1 ] * p.a[ 1 ]; result.a[ result.a.length - 1 ] = this.a[ this.degree ] * p.a[ 1 ]; return result.compact(); } else if( this.degree == 1 ) { return p.mult( this, min_degree ); } else { UnivariatePolynomial result = new UnivariatePolynomial( Math.max( this.degree + p.degree, min_degree + 1 ) ); for( int i = 0; i < this.a.length; i++ ) for( int j = 0; j < p.a.length; j++ ) result.a[ i + j ] += this.a[ i ] * p.a[ j ]; return result.compact(); } } public UnivariatePolynomial mult( UnivariatePolynomial p ) { if( p.isOne() || this.isZero() ) return this; else if( p.isZero() || this.isOne() ) return p; else return this.mult( p, 0 ); } public UnivariatePolynomial mult( double d ) { if( d == 0.0 ) return ZERO; else if( d == 1.0 ) return this; else { UnivariatePolynomial result = new UnivariatePolynomial( this.degree ); for( int i = 0; i < this.a.length; i++ ) result.a[ i ] = this.a[ i ] * d; return result.compact(); } } public UnivariatePolynomial mult_add( UnivariatePolynomial factor, double summand ) { UnivariatePolynomial result = this.mult( factor ); result.a[ 0 ] += summand; return result; } public UnivariatePolynomial mult_add( UnivariatePolynomial factor, UnivariatePolynomial summand ) { if( factor.isOne() || this.isZero() ) return this.add( summand ); else if( factor.isZero() || this.isOne() ) return factor.add( summand ); else { UnivariatePolynomial result = this.mult( factor, summand.degree ); for( int i = 0; i <= summand.degree; ++i ) result.a[ i ] += summand.a[ i ]; return result; } } public UnivariatePolynomial add_mult( double summand, UnivariatePolynomial factor ) { if( factor.isOne() ) return this.add( summand ); else if( factor.isZero() ) return ZERO; else { UnivariatePolynomial result = new UnivariatePolynomial( this.degree + factor.degree ); double tmp = this.a[ 0 ] + summand; for( int j = 0; j < factor.a.length; j++ ) result.a[ 0 + j ] += tmp * factor.a[ j ]; for( int i = 1; i < this.a.length; i++ ) for( int j = 0; j < factor.a.length; j++ ) result.a[ i + j ] += this.a[ i ] * factor.a[ j ]; return result.compact(); } } public UnivariatePolynomial pow( int exp ) { if( exp == 0 ) { return ONE; } else if( exp == 1 ) { return this; } else { if( this.degree == 1 ) { double a0 = a[ 0 ]; double a1 = a[ 1 ]; double[] powers_0 = new double[ exp + 1 ]; double[] powers_1 = new double[ exp + 1 ]; powers_0[ 0 ] = 1.0; powers_0[ 1 ] = a0; powers_1[ 0 ] = 1.0; powers_1[ 1 ] = a1; for( int i = 2; i <= exp; i++ ) { powers_0[ i ] = powers_0[ i - 1 ] * a0; powers_1[ i ] = powers_1[ i - 1 ] * a1; } // compute coefficients of polynomials by binomial expansion UnivariatePolynomial res = new UnivariatePolynomial( exp ); int a1_exp = exp; int a0_exp = 0; long bin_coeff = 1; for( int deg = exp; deg >= 0; deg-- ) { res.a[ deg ] = ( ( double ) bin_coeff ) * powers_1[ a1_exp ] * powers_0[ a0_exp ]; a0_exp++; bin_coeff = ( bin_coeff * a1_exp ) / a0_exp; a1_exp--; } return new UnivariatePolynomial( res ); } else { UnivariatePolynomial result = this; UnivariatePolynomial x = this; exp--; while( exp > 0 ) { if( ( exp & 1 ) == 1 ) { result = result.mult( x ); exp--; } x = x.mult( x ); exp /= 2; } return result.compact(); } } } public UnivariatePolynomial pow( int exp, UnivariatePolynomial[] cache ) { if( cache[ exp ] == null ) { if (exp == 0) { cache[ exp ] = ONE; } else if( exp == 1 ) { cache[ exp ] = this; } else { if( false && this.degree == 1 ) { double a0 = a[ 0 ]; double a1 = a[ 1 ]; double[] powers_0 = new double[ exp + 1 ]; double[] powers_1 = new double[ exp + 1 ]; powers_0[ 0 ] = 1.0; powers_0[ 1 ] = a0; powers_1[ 0 ] = 1.0; powers_1[ 1 ] = a1; for( int i = 2; i <= exp; i++ ) { powers_0[ i ] = powers_0[ i - 1 ] * a0; powers_1[ i ] = powers_1[ i - 1 ] * a1; } // compute coefficients of polynomials by binomial expansion UnivariatePolynomial res = new UnivariatePolynomial( exp ); int a1_exp = exp; int a0_exp = 0; long bin_coeff = 1; for( int deg = exp; deg >= 0; deg-- ) { res.a[ deg ] = ( ( double ) bin_coeff ) * powers_1[ a1_exp ] * powers_0[ a0_exp ]; a0_exp++; bin_coeff = ( bin_coeff * a1_exp ) / a0_exp; a1_exp--; } return new UnivariatePolynomial( res ); } else { UnivariatePolynomial sqrt = pow( exp / 2, cache ); cache[ exp ] = sqrt.mult( sqrt ); if( ( exp & 1 ) == 1 ) cache[ exp ] = cache[ exp ].mult( this ); } } } return cache[ exp ]; } public UnivariatePolynomial substitute( UnivariatePolynomial xPoly ) { UnivariatePolynomial result = new UnivariatePolynomial( a[ a.length - 1 ] ); for( int i = a.length - 2; i >= 0; --i ) result = result.mult( xPoly ).add( a[ i ] ); return result; } public UnivariatePolynomial div( double d ) { UnivariatePolynomial result = new UnivariatePolynomial( this ); for( int i = 0; i < result.a.length; i++ ) result.a[ i ] = result.a[ i ] / d; return result.compact(); } private double[] _reduce(double[] a, int degA, double[] b, int degB) { int degDiff = degA - degB; double[] result = new double[degA]; for (int i = degA - 1; i >= degDiff; i--) { result[i] = a[i] - b[i - degDiff] / b[degB] * a[degA]; } for (int i = 0; i < degDiff; i++) { result[i] = a[i]; } return result; } private double[] _mod(double[] a, int degA, double[] b, int degB) { if (degB < 1) { // the illegal case if( degB == -1 ) { throw new IllegalArgumentException( "Cannot divide by constant polynomials"); } else { double[] result = new double[ 1 ]; result[ 0 ] = 0.0; return result; } } else if (degA < degB) { // the basic case return a; } else { // the recursion case // reduce a by b double[] result = _reduce(a, degA, b, degB); // calculate the degree of the result int newDeg = degA - 1; while (newDeg >= 0 && result[newDeg] == 0) { newDeg--; } // do recursion return _mod(result, newDeg, b, degB); } } public UnivariatePolynomial mod( UnivariatePolynomial other ) { return new UnivariatePolynomial( _mod( this.a, degree(), other.a, other.degree() ), false ).compact(); } public UnivariatePolynomial div( UnivariatePolynomial other) { return new UnivariatePolynomial( _reduce( this.a, degree(), other.a, other.degree() ), false ).compact(); } public double evaluateAt( double where ) { if( Math.abs( where ) <= 1.0 ) { double result = this.a[ this.a.length - 1 ]; for( int i = this.a.length - 2; i >= 0; i-- ) result = result * where + this.a[ i ]; return result; } else { double result = this.a[ 0 ]; for( int i = 1; i < this.a.length; i++ ) result = result / where + this.a[ i ]; return result * Math.pow( where, this.a.length - 1 ); } } public UnivariatePolynomial shrink() { while( this.a[ this.degree ] == 0.0 && this.degree > 0 ) this.degree--; UnivariatePolynomial result = new UnivariatePolynomial(); result.a = new double[ this.degree + 1 ]; result.degree = result.a.length - 1; System.arraycopy( a, 0, result.a, 0, result.a.length ); return result; } public UnivariatePolynomial derive() { UnivariatePolynomial result = new UnivariatePolynomial( Math.max( 0, this.degree - 1 ) ); for( int i = 1; i < this.a.length; i++ ) result.a[ i - 1 ] = i * this.a[ i ]; return result; } /** * Shifts the polynomial to position {@link a}. The new origin is at {@link a}. * map: x -> x - a */ public UnivariatePolynomial shift2( double a ) { double[] shiftedDerValues = evaluateDerivativesAt( a ); double[] result = new double[ this.a.length ]; double fac = 1.0; result[ 0 ] = shiftedDerValues[ 0 ]; for( int i = 1; i < shiftedDerValues.length; i++ ) { fac *= i; result[ i ] = shiftedDerValues[ i ] / fac; } return new UnivariatePolynomial( result ); } /** * Shifts the polynomial to position {@link where}. The new origin is at {@link where}. * map: x -> x - where */ public UnivariatePolynomial shift( double a ) { return _shift( a, false ); } /** * Performs the transformation x -> 1 / ( x + a ) */ public UnivariatePolynomial reverseShift( double a ) { return _shift( a, true ); } private UnivariatePolynomial _shift( double a, boolean revert ) { // divide this polynomial repeatedly by ( x + a ) by using ruffini's rule // and store the coeffs of the resulting polynomial and the remainder. // the remainders give the coeffs of the shifted polynomial. double[] hornerCoeffs = new double[ this.a.length ]; if( revert ) // perform x -> 1 / ( x + a ) for( int i = 0; i < this.a.length; i++ ) hornerCoeffs[ i ] = this.a[ this.a.length - i - 1 ]; else // perform x -> x + a System.arraycopy( this.a , 0, hornerCoeffs, 0, this.a.length ); for( int i = 1; i <= this.a.length; i++ ) for( int j = hornerCoeffs.length - 2; j >= i - 1; j-- ) hornerCoeffs[ j ] = hornerCoeffs[ j ] + a * hornerCoeffs[ j + 1 ]; return new UnivariatePolynomial( hornerCoeffs, false ); } /** * simplified _shift( 1.0, false ) */ public UnivariatePolynomial shift1() { double[] hornerCoeffs = new double[ this.a.length ]; System.arraycopy( this.a , 0, hornerCoeffs, 0, this.a.length ); for( int i = 1; i <= this.a.length; i++ ) for( int j = hornerCoeffs.length - 2; j >= i - 1; j-- ) hornerCoeffs[ j ] = hornerCoeffs[ j ] + hornerCoeffs[ j + 1 ]; return new UnivariatePolynomial( hornerCoeffs, false ); } /** * simplified _shift( 1.0, true ) */ public UnivariatePolynomial reverseShift1() { double[] hornerCoeffs = new double[ this.a.length ]; for( int i = 0; i < this.a.length; i++ ) hornerCoeffs[ i ] = this.a[ this.a.length - i - 1 ]; for( int i = 1; i <= this.a.length; i++ ) for( int j = hornerCoeffs.length - 2; j >= i - 1; j-- ) hornerCoeffs[ j ] = hornerCoeffs[ j ] + hornerCoeffs[ j + 1 ]; return new UnivariatePolynomial( hornerCoeffs, false ); } public int descartesRuleOfSignShift1() { int signChanges = 0; double[] hornerCoeffs = new double[ this.a.length ]; System.arraycopy( this.a , 0, hornerCoeffs, 0, this.a.length ); double lastNonZeroCoeff = java.lang.Double.NaN; for( int i = 1; i <= this.a.length; i++ ) { for( int j = hornerCoeffs.length - 2; j >= i - 1; j-- ) hornerCoeffs[ j ] = hornerCoeffs[ j ] + hornerCoeffs[ j + 1 ]; if( hornerCoeffs[ i - 1 ] != 0.0 ) { if( hornerCoeffs[ i - 1 ] * lastNonZeroCoeff < 0.0 ) signChanges++; if( signChanges > 1 ) return signChanges; lastNonZeroCoeff = hornerCoeffs[ i - 1 ]; } } return signChanges; } public int descartesRuleOfSignReverseShift1() { int signChanges = 0; double[] hornerCoeffs = new double[ this.a.length ]; for( int i = 0; i < this.a.length; i++ ) hornerCoeffs[ i ] = this.a[ this.a.length - i - 1 ]; double lastNonZeroCoeff = java.lang.Double.NaN; for( int i = 1; i <= this.a.length; i++ ) { for( int j = hornerCoeffs.length - 2; j >= i - 1; j-- ) hornerCoeffs[ j ] = hornerCoeffs[ j ] + hornerCoeffs[ j + 1 ]; if( hornerCoeffs[ i - 1 ] != 0.0 ) { if( hornerCoeffs[ i - 1 ] * lastNonZeroCoeff < 0.0 ) signChanges++; if( signChanges > 1 ) return signChanges; lastNonZeroCoeff = hornerCoeffs[ i - 1 ]; } } return signChanges; } /** * Performs the transformation x -> 1/x. */ public UnivariatePolynomial revert() { UnivariatePolynomial result = new UnivariatePolynomial( this.degree() ); for( int i = 0; i < this.a.length; i++ ) result.a[ i ] = this.a[ this.a.length - 1 - i ]; return result; } public UnivariatePolynomial stretch( double v ) { double[] resultCoeffs = new double[ this.a.length ]; double multiplier = 1.0; for( int i = 0; i < resultCoeffs.length; i++ ) { resultCoeffs[ i ] = this.a[ i ] * multiplier; multiplier *= v; } return new UnivariatePolynomial( resultCoeffs, false ); } public double[] evaluateDerivativesAt( double where ) { double[] c = this.a; int nc = this.degree(); double x = where; int nd = nc; double[] pd = new double[ nc + 1 ]; double cnst = 1.0; pd[ 0 ] = c[ nc ]; for( int j = 1; j <= nd; j++ ) pd[ j ] = 0.0; for( int i = nc - 1; i >= 0; i-- ) { int nnd = ( nd < ( nc - i ) ? nd : nc - i ); for( int j = nnd; j >= 1; j-- ) pd[ j ] = pd[ j ] * x + pd[ j - 1 ]; pd[ 0 ] = pd[ 0 ] * x + c[ i ]; } for( int i = 2; i <= nd; i++ ) { cnst *= i; pd[ i ] *= cnst; } UnivariatePolynomial der = this; for( int i = 0; i < nc; i++ ) { pd[ i ] = der.evaluateAt( x ); der = der.derive(); } return pd; } public int coeffSignChanges() { int signChanges = 0; double lastNonZeroCoeff = this.a[ this.a.length - 1 ]; for( int i = this.a.length - 2; i >= 0; i-- ) { if( this.a[ i ] != 0.0 ) { if( this.a[ i ] * lastNonZeroCoeff < 0.0 ) signChanges++; lastNonZeroCoeff = this.a[ i ]; } } return signChanges; } public double rootBound() { double rootBound = 0.0; for( int i = 0; i < a.length - 1; i++ ) rootBound = Math.max( rootBound, 2 * Math.pow( Math.abs( a[ i ] / a[ a.length - 1 ] ), 1.0 / ( this.degree() - i ) ) ); return rootBound; } public double maxPositiveRootBound() { double[] normCoeff = new double[ this.a.length ]; for( int i = 0; i < this.a.length - 1; i++ ) normCoeff[ i ] = this.a[ i ] / this.a[ this.a.length - 1 ]; int negCoeffs = 0; for( int i = 0; i < normCoeff.length - 1; i++ ) if( normCoeff[ i ] < 0.0 ) negCoeffs++; double rootBound = 0.0; negCoeffs = -negCoeffs; for( int i = 0; i < normCoeff.length - 1; i++ ) if( normCoeff[ i ] < 0.0 ) rootBound = Math.max( rootBound, Math.pow( negCoeffs * normCoeff[ i ], 1.0 / ( this.degree - i ) ) ); return rootBound; } public double minPositiveRootBound() { int negCoeffs = 0; for( int i = 0; i < this.a.length; i++ ) if( this.a[ i ] < 0.0 ) negCoeffs++; double rootBound = 0.0; negCoeffs = -negCoeffs; for( int i = 1; i < this.a.length; i++ ) { if( this.a[ this.degree() - i ] < 0.0 ) { double tempRootBound = Math.pow( negCoeffs * this.a[ i ], 1.0 / i ); if( rootBound < tempRootBound ) rootBound = tempRootBound; } } return 1.0 / rootBound; } @Override public String toString() { String s = "" + a[ 0 ]; for( int i = 1; i < a.length; ++i ) if( a[ i ] < 0.0 ) s = s + "-" + (-a[ i ] ) + "x" + ( i == 1 ? "" : "^" + i ); else s = s + "+" + a[ i ] + "x" + ( i == 1 ? "" : "^" + i ); return s; } public static UnivariatePolynomial fromRealRoots( double ... roots ) { UnivariatePolynomial result = new UnivariatePolynomial( 1.0 ); for( int i = 0; i < roots.length; i++ ) result = result.mult( new UnivariatePolynomial( -roots[ i ], 1.0 ) ); return result; } public static UnivariatePolynomial gcd( UnivariatePolynomial a, UnivariatePolynomial b ) { while( !( b.degree() == 0 && b.getCoeff( 0 ) == 0.0 ) ) { UnivariatePolynomial t = b; b = a.mod( b ); a = t; } return a; } // returns either this or a new polynomial with the leading zero coefficients removed UnivariatePolynomial compact() { int newDegree = degree; for( ; newDegree > 0 && a[ newDegree ] == 0.0; --newDegree ) { /* just find the true degree */ } return newDegree == degree ? this : new UnivariatePolynomial( newDegree, a ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/UnivariatePolynomialExpansion.java000066400000000000000000000100021330553604100317320ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import java.util.*; public class UnivariatePolynomialExpansion extends AbstractVisitor< UnivariatePolynomial, Void > { private UnivariatePolynomial x; private UnivariatePolynomial y; private UnivariatePolynomial z; private ValueCalculator valueCalculator; public UnivariatePolynomialExpansion( UnivariatePolynomial x, UnivariatePolynomial y, UnivariatePolynomial z ) { this.x = x; this.y = y; this.z = z; this.valueCalculator = new ValueCalculator( 0.0, 0.0, 0.0 ); } public UnivariatePolynomial getX() { return this.x; } public UnivariatePolynomial getY() { return this.y; } public UnivariatePolynomial getZ() { return this.z; } public void setX( UnivariatePolynomial x ) { this.x = x; } public void setY( UnivariatePolynomial y ) { this.y = y; } public void setZ( UnivariatePolynomial z ) { this.z = z; } public void setXYZ( UnivariatePolynomial x, UnivariatePolynomial y, UnivariatePolynomial z ) { this.x = x; this.y = y; this.z = z; } public UnivariatePolynomial visit( PolynomialAddition pa, Void param ) { return pa.getFirstOperand().accept( this, ( Void ) null ).add( pa.getSecondOperand().accept( this, ( Void ) null ) ); } public UnivariatePolynomial visit( PolynomialSubtraction ps, Void param ) { return ps.getFirstOperand().accept( this, ( Void ) null ).sub( ps.getSecondOperand().accept( this, ( Void ) null ) ); } public UnivariatePolynomial visit( PolynomialMultiplication pm, Void param ) { return pm.getFirstOperand().accept( this, ( Void ) null ).mult( pm.getSecondOperand().accept( this, ( Void ) null ) ); } public UnivariatePolynomial visit( PolynomialPower pp, Void param ) { return pp.getBase().accept( this, ( Void ) null ).pow( pp.getExponent() ); } public UnivariatePolynomial visit( PolynomialNegation pn, Void param ) { return pn.getOperand().accept( this,( Void ) null ).neg(); } public UnivariatePolynomial visit( PolynomialDoubleDivision pdd, Void param ) { return pdd.getDividend().accept( this,( Void ) null ).div( pdd.getDivisor().accept( this.valueCalculator, ( Void ) null ) ); } public UnivariatePolynomial visit( PolynomialVariable pv, Void param ) { switch( pv.getVariable() ) { case x: return this.x; case y: return this.y; case z: return this.z; default: throw new UnsupportedOperationException(); } } public UnivariatePolynomial visit( DoubleBinaryOperation dbop, Void param ) { return new UnivariatePolynomial( dbop.accept( this.valueCalculator, ( Void ) null ) ); } public UnivariatePolynomial visit( DoubleUnaryOperation duop, Void param ) { return new UnivariatePolynomial( duop.accept( this.valueCalculator, ( Void ) null ) ); } public UnivariatePolynomial visit( DoubleVariable dv, Void param ) { throw new UnsupportedOperationException( "no value has been assigned to parameter '" + dv.getName() + "'" ); } public UnivariatePolynomial visit( DoubleValue dv, Void param ) { return new UnivariatePolynomial( dv.getValue() ); } } UnivariatePolynomialExpansionCoefficientCalculator.java000066400000000000000000000022421330553604100360330ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class UnivariatePolynomialExpansionCoefficientCalculator implements CoefficientCalculator { private PolynomialOperation polynomialOperation; public UnivariatePolynomialExpansionCoefficientCalculator( PolynomialOperation po ) { this.polynomialOperation = po; } public UnivariatePolynomial calculateCoefficients( UnivariatePolynomial x, UnivariatePolynomial y, UnivariatePolynomial z ) { return this.polynomialOperation.accept( new UnivariatePolynomialExpansion( x, y, z ), ( Void ) null ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/UnivariatePolynomialVector3d.java000066400000000000000000000013601330553604100314660ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import javax.vecmath.Vector3d; public interface UnivariatePolynomialVector3d { public Vector3d setT( double t ); } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/ValueCalculator.java000066400000000000000000000136121330553604100267720ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import java.util.*; public class ValueCalculator extends AbstractVisitor< java.lang.Double, Void > { private double x; private double y; private double z; private Map< String, java.lang.Double > dict; public ValueCalculator() { this( 0.0, 0.0, 0.0 ); } public ValueCalculator( double x, double y, double z ) { this.x = x; this.y = y; this.z = z; this.dict = new HashMap< String, java.lang.Double >(); } public double getX() { return this.x; } public double getY() { return this.y; } public double getZ() { return this.z; } public void setX( double x ) { this.x = x; } public void setY( double y ) { this.y = y; } public void setZ( double z ) { this.z = z; } public void setXYZ( double x, double y, double z ) { this.x = x; this.y = y; this.z = z; } public double getParameterValue( String name ) { try { return this.dict.get( name ); } catch( NullPointerException npe ) { return java.lang.Double.NaN; } } public Set< String > getParameters() { return this.dict.keySet(); } public void setParameterValue( String name, double value ) { this.dict.put( name, value ); } public java.lang.Double visit( PolynomialAddition pa, Void param ) { return pa.getFirstOperand().accept( this, ( Void ) null ) + pa.getSecondOperand().accept( this, ( Void ) null ); } public java.lang.Double visit( PolynomialSubtraction ps, Void param ) { return ps.getFirstOperand().accept( this, ( Void ) null ) - ps.getSecondOperand().accept( this, ( Void ) null ); } public java.lang.Double visit( PolynomialMultiplication pm, Void param ) { return pm.getFirstOperand().accept( this, ( Void ) null ) * pm.getSecondOperand().accept( this, ( Void ) null ); } public java.lang.Double visit( PolynomialPower pp, Void param ) { return Math.pow( pp.getBase().accept( this, ( Void ) null ), ( double ) pp.getExponent() ); } public java.lang.Double visit( PolynomialNegation pn, Void param ) { return -pn.getOperand().accept( this, ( Void ) null ); } public java.lang.Double visit( PolynomialDoubleDivision pdd, Void param ) { return pdd.getDividend().accept( this,( Void ) null ) / pdd.getDivisor().accept( this,( Void ) null ); } public java.lang.Double visit( PolynomialVariable pv, Void param ) { switch( pv.getVariable() ) { case x: return this.x; case y: return this.y; case z: return this.z; default: throw new UnsupportedOperationException(); } } public java.lang.Double visit( DoubleBinaryOperation dbop, Void param ) { double firstOperand = dbop.getFirstOperand().accept( this, ( Void ) null ); double secondOperand = dbop.getSecondOperand().accept( this, ( Void ) null ); switch( dbop.getOperator() ) { case add: return firstOperand + secondOperand; case sub: return firstOperand - secondOperand; case mult: return firstOperand * secondOperand; case div: return firstOperand / secondOperand; case pow: return Math.pow( firstOperand, secondOperand ); default: throw new UnsupportedOperationException(); } } public java.lang.Double visit( DoubleUnaryOperation duop, Void param ) { double operand = duop.getOperand().accept( this, ( Void ) null ); switch( duop.getOperator() ) { case neg: return -operand; case sin: return Math.sin( operand ); case cos: return Math.cos( operand ); case tan: return Math.tan( operand ); case asin: return Math.asin( operand ); case acos: return Math.acos( operand ); case atan: return Math.atan( operand ); case exp: return Math.exp( operand ); case log: return Math.log( operand ); case sqrt: return Math.sqrt( operand ); case ceil: return Math.ceil( operand ); case floor: return Math.floor( operand ); case abs: return Math.abs( operand ); case sign: return Math.signum( operand ); default: throw new UnsupportedOperationException(); } } public java.lang.Double visit( DoubleVariable dv, Void param ) { java.lang.Double d = this.dict.get( dv.getName() ); if( d == null ) throw new UnsupportedOperationException( "no value has been assigned to parameter '" + dv.getName() + "'" ); return d; } public java.lang.Double visit( DoubleValue dv, Void param ) { return dv.getValue(); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/VariableSubstitutor.java000066400000000000000000000061771330553604100277310ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public class VariableSubstitutor extends AbstractVisitor< PolynomialOperation, Void > { PolynomialOperation xSubstitute; PolynomialOperation ySubstitute; PolynomialOperation zSubstitute; public VariableSubstitutor( PolynomialOperation xSubstitute, PolynomialOperation ySubstitute, PolynomialOperation zSubstitute ) { this.xSubstitute = xSubstitute; this.ySubstitute = ySubstitute; this.zSubstitute = zSubstitute; } public PolynomialOperation visit( PolynomialAddition pa, Void param ) { return new PolynomialAddition( pa.getFirstOperand().accept( this, ( Void ) null ), pa.getSecondOperand().accept( this, ( Void ) null ) ); } public PolynomialOperation visit( PolynomialSubtraction ps, Void param ) { return new PolynomialSubtraction( ps.getFirstOperand().accept( this, ( Void ) null ), ps.getSecondOperand().accept( this, ( Void ) null ) ); } public PolynomialOperation visit( PolynomialMultiplication pm, Void param ) { return new PolynomialMultiplication( pm.getFirstOperand().accept( this, ( Void ) null ), pm.getSecondOperand().accept( this, ( Void ) null ) ); } public PolynomialOperation visit( PolynomialPower pp, Void param ) { return new PolynomialPower( pp.getBase().accept( this, ( Void ) null ), pp.getExponent() ); } public PolynomialOperation visit( PolynomialNegation pn, Void param ) { return new PolynomialNegation( pn.getOperand().accept( this, ( Void ) null ) ); } public PolynomialOperation visit( PolynomialDoubleDivision pdd, Void param ) { return new PolynomialDoubleDivision( pdd.getDividend().accept( this, ( Void ) null ), pdd.getDivisor() ); } public PolynomialOperation visit( PolynomialVariable pv, Void param ) { switch( pv.getVariable() ) { case x: return xSubstitute; case y: return ySubstitute; case z: return zSubstitute; default: throw new UnsupportedOperationException(); } } public PolynomialOperation visit( DoubleBinaryOperation dbop, Void param ) { return dbop; } public PolynomialOperation visit( DoubleUnaryOperation duop, Void param ) { return duop; } public PolynomialOperation visit( DoubleValue dv, Void param ) { return dv; } public PolynomialOperation visit( DoubleVariable dv, Void param ) { return dv; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/Visitor.java000066400000000000000000000031611330553604100253410ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; public interface Visitor< RETURN_TYPE, PARAM_TYPE > { public RETURN_TYPE visit( PolynomialOperation pop, PARAM_TYPE param ); public RETURN_TYPE visit( PolynomialAddition pa, PARAM_TYPE param ); public RETURN_TYPE visit( PolynomialSubtraction ps, PARAM_TYPE param ); public RETURN_TYPE visit( PolynomialMultiplication pm, PARAM_TYPE param ); public RETURN_TYPE visit( PolynomialPower pp, PARAM_TYPE param ); public RETURN_TYPE visit( PolynomialNegation pn, PARAM_TYPE param ); public RETURN_TYPE visit( PolynomialDoubleDivision pdd, PARAM_TYPE param ); public RETURN_TYPE visit( PolynomialVariable pv, PARAM_TYPE param ); public RETURN_TYPE visit( DoubleOperation dop, PARAM_TYPE param ); public RETURN_TYPE visit( DoubleBinaryOperation dbop, PARAM_TYPE param ); public RETURN_TYPE visit( DoubleUnaryOperation duop, PARAM_TYPE param ); public RETURN_TYPE visit( DoubleValue dv, PARAM_TYPE param ); public RETURN_TYPE visit( DoubleVariable dv, PARAM_TYPE param ); } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/XYPolynomial.java000066400000000000000000000312411330553604100263060ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import java.util.*; public class XYPolynomial { public static final XYPolynomial X; public static final XYPolynomial Y; static { X = new XYPolynomial( 1.0, (byte) 1, (byte) 0 ); Y = new XYPolynomial( 1.0, (byte) 0, (byte) 1 ); } //private Term[] terms; // ordered list of terms, such that terms[ i ].lexCompare( terms[ i + 1 ] ) < 0 private double[] coeffs; private byte[] xExps; private byte[] yExps; private byte xDegree; private byte yDegree; private byte degree; static byte[] byteArray( byte ... b ) { return b; } static double[] doubleArray( double ... d ) { return d; } public XYPolynomial() { this( 0.0 ); } public XYPolynomial( double value ) { coeffs = doubleArray( value ); xExps = byteArray( (byte) 0 ); yExps = byteArray( (byte) 0 ); calculateDegree(); } public XYPolynomial( double value, byte xExp, byte yExp ) { coeffs = doubleArray( value ); xExps = byteArray( xExp ); yExps = byteArray( yExp ); calculateDegree(); } XYPolynomial( double[] coeffs, byte[] xExps, byte[] yExps, int from, int length ) { createArrays( length ); System.arraycopy( coeffs, from, this.coeffs, 0, length ); System.arraycopy( xExps, from, this.xExps, 0, length ); System.arraycopy( yExps, from, this.yExps, 0, length ); calculateDegree(); } XYPolynomial( double[] coeffs, byte[] xExps, byte[] yExps, boolean copy ) { if( copy ) { createArrays( coeffs.length ); System.arraycopy( coeffs, 0, this.coeffs, 0, coeffs.length ); System.arraycopy( xExps, 0, this.xExps, 0, coeffs.length ); System.arraycopy( yExps, 0, this.yExps, 0, coeffs.length ); } else { this.coeffs = coeffs; this.xExps = xExps; this.yExps = yExps; } calculateDegree(); } XYPolynomial( double[] coeffs, byte[] xExps, byte[] yExps ) { this( coeffs, xExps, yExps, true ); } XYPolynomial( int length ) { createArrays( length ); } private void createArrays( int length ) { this.coeffs = new double[ length ]; this.xExps = new byte[ length ]; this.yExps = new byte[ length ]; } private void calculateDegree() { xDegree = xExps[ xExps.length - 1 ]; yDegree = 0; int yDegreePos = this.coeffs.length - 1; degree = 0; for( int i = this.coeffs.length - 1; i >= 0; --i ) { if( yExps[ i ] > yDegree ) { yDegree = yExps[ i ]; yDegreePos = i; } } degree = ( byte ) Math.max( xExps[ yDegreePos ] + yDegree, xDegree + yExps[ xExps.length - 1 ] ); } public static int lexCompare( XYPolynomial p1, XYPolynomial p2, int pos1, int pos2 ) { int result = p1.xExps[ pos1 ] < p2.xExps[ pos2 ] ? -4 : ( p1.xExps[ pos1 ] > p2.xExps[ pos2 ] ? 4 : 0 ); if( result == 0 ) result += p1.yExps[ pos1 ] < p2.yExps[ pos2 ] ? -2 : ( p1.yExps[ pos1 ] > p2.yExps[ pos2 ] ? 2 : 0 ); return result; } public XYPolynomial neg() { double[] negCoeffs = new double[ this.coeffs.length ]; for( int i = 0; i < this.coeffs.length; ++i ) negCoeffs[ i ] = -coeffs[ i ]; return new XYPolynomial( negCoeffs, xExps, yExps, false ); } public XYPolynomial sub( XYPolynomial p ) { return this.add( p.neg() ); } public XYPolynomial add( XYPolynomial p ) { double[] result_coeffs = new double[ this.coeffs.length + p.coeffs.length ]; byte[] result_xExps = new byte[ this.coeffs.length + p.coeffs.length ]; byte[] result_yExps = new byte[ this.coeffs.length + p.coeffs.length ]; // merge term lists and sum terms of same order int result_i = 0; int i1 = 0; int i2 = 0; while( i1 < coeffs.length && i2 < p.coeffs.length ) { int lexCompare = lexCompare( this, p, i1, i2 ); if( lexCompare < 0 ) { result_coeffs[ result_i ] = this.coeffs[ i1 ]; result_xExps[ result_i ] = this.xExps[ i1 ]; result_yExps[ result_i ] = this.yExps[ i1 ]; ++result_i; ++i1; } else if( lexCompare > 0 ) { result_coeffs[ result_i ] = p.coeffs[ i2 ]; result_xExps[ result_i ] = p.xExps[ i2 ]; result_yExps[ result_i ] = p.yExps[ i2 ]; ++result_i; ++i2; } else { // add terms result_coeffs[ result_i ] = this.coeffs[ i1 ] + p.coeffs[ i2 ]; result_xExps[ result_i ] = this.xExps[ i1 ]; result_yExps[ result_i ] = this.yExps[ i1 ]; ++result_i; ++i1; ++i2; } } while( i1 < this.coeffs.length ) { result_coeffs[ result_i ] = this.coeffs[ i1 ]; result_xExps[ result_i ] = this.xExps[ i1 ]; result_yExps[ result_i ] = this.yExps[ i1 ]; ++result_i; ++i1; } while( i2 < p.coeffs.length ) { result_coeffs[ result_i ] = p.coeffs[ i2 ]; result_xExps[ result_i ] = p.xExps[ i2 ]; result_yExps[ result_i ] = p.yExps[ i2 ]; ++result_i; ++i2; } if( result_i == result_coeffs.length ) return new XYPolynomial( result_coeffs, xExps, yExps, false ); else return new XYPolynomial( result_coeffs, xExps, yExps, 0, result_i ); } public XYPolynomial mult( XYPolynomial p ) { XYPolynomial result = new XYPolynomial(); for( int j = 0; j < this.coeffs.length; ++j ) { XYPolynomial partialProduct = new XYPolynomial( p.coeffs.length ); for( int i = 0; i < p.coeffs.length; i++ ) { partialProduct.coeffs[ i ] = this.coeffs[ j ] * p.coeffs[ i ]; partialProduct.xExps[ i ] = ( byte ) ( this.xExps[ j ] + p.xExps[ i ] ); partialProduct.yExps[ i ] = ( byte ) ( this.yExps[ j ] + p.yExps[ i ] ); } partialProduct.calculateDegree(); result = result.add( partialProduct ); } return result; } public XYPolynomial mult( double d ) { double[] newCoeffs = new double[ this.coeffs.length ]; for( int i = 0; i < this.coeffs.length; ++i ) newCoeffs[ i ] = d * coeffs[ i ]; return new XYPolynomial( newCoeffs, xExps, yExps, false ); } public XYPolynomial pow( int exp ) { if( exp == 0 ) { return new XYPolynomial( 1.0 ); } else { XYPolynomial result = this; XYPolynomial x = this; exp--; while( exp > 0 ) { if( ( exp & 1 ) == 1 ) { result = result.mult( x ); exp--; } x = x.mult( x ); exp /= 2; } return result; } } public double evaluateXY( double x, double y ) { double result = 0.0; for( int i = 0; i < this.coeffs.length; ++i ) result += coeffs[ i ] * Math.pow( x, xExps[ i ] ) * Math.pow( y, yExps[ i ] ); return result; } public UnivariatePolynomial evaluateY( double y ) { if( this.coeffs.length == 0 ) return new UnivariatePolynomial( 0.0 ); /* if( !isCompact ) { terms = collect( terms, true ); isCompact = true; } */ double[] yPowers = new double[ yDegree * 2 + 1 ]; for( int i = 0; i <= yDegree; ++i ) yPowers[ yDegree + i ] = Math.pow( y, i ); int term_index, incr, last_index; if( Math.abs( y ) > 1.0 ) { term_index = 0; incr = 1; last_index = coeffs.length - 1; for( int i = 1; i <= yDegree; ++i ) yPowers[ yDegree - i ] = 1.0 / yPowers[ yDegree + i ]; } else { term_index = coeffs.length - 1; incr = -1; last_index = 0; } int last_xExp = xExps[ term_index ]; int last_yExp = yExps[ term_index ]; double a[] = new double[ xExps[ coeffs.length - 1 ] + 1 ]; double cur_coeff = coeffs[ term_index ]; //java.math.BigDecimal c_bd = new java.math.BigDecimal( last_t.coeff ); //java.math.BigDecimal y_bd = new java.math.BigDecimal( y ); while( incr * term_index < incr * last_index ) { term_index += incr; int xExp = xExps[ term_index ]; int yExp = yExps[ term_index ]; if( last_xExp == xExp ) { cur_coeff = cur_coeff * yPowers[ yDegree + ( last_yExp - yExp ) ] + coeffs[ term_index ]; // stardard Horner step for abs(z)<=1.0, inverser Horner otherwise (mult with 1/y) //c_bd = c_bd.multiply( y_bd.pow( last_t.yExp - t.yExp ) ).add( new java.math.BigDecimal( t.coeff ) ); } else { cur_coeff = cur_coeff * yPowers[ yDegree + last_yExp ]; // finalize term //c_bd = c_bd.multiply( y_bd.pow( last_t.yExp ) ); //a[ last_t.xExp ] = c_bd.doubleValue(); a[ last_xExp ] = cur_coeff; cur_coeff = coeffs[ term_index ]; //c_bd = new java.math.BigDecimal( t.coeff ); } last_xExp = xExp; last_yExp = yExp; } // finalize last term cur_coeff = cur_coeff * yPowers[ yDegree + last_yExp ]; // finalize term a[ last_xExp ] = cur_coeff; //c_bd = c_bd.multiply( y_bd.pow( last_t.yExp ) ); //a[ last_t.xExp ] = c_bd.doubleValue(); UnivariatePolynomial result = new UnivariatePolynomial( a, false ); return result; } /** * * @return This polynomial without non-constant terms that have a zero coefficient. */ public XYPolynomial eliminateZeroTerms() { XYPolynomial tmp_result = new XYPolynomial( this.coeffs.length ); int j = 0; for( int i = 0; i < this.coeffs.length; i++ ) { if( this.coeffs[ i ] != 0.0 ) { tmp_result.coeffs[ j ] = this.coeffs[ i ]; tmp_result.xExps[ j ] = this.xExps[ i ]; tmp_result.yExps[ j ] = this.yExps[ i ]; ++j; } } if( j == 0 ) ++j; return new XYPolynomial( tmp_result.coeffs, tmp_result.xExps, tmp_result.yExps, 0, j ); } public String toString() { StringBuffer sb = new StringBuffer(); for( int i = 0; i < this.coeffs.length; ++i ) sb.append( termToString( i ) ); return sb.toString(); } private String termToStringShort( int i ) { StringBuffer result = new StringBuffer(); if( coeffs[ i ] != 1.0 ) { if( coeffs[ i ] == -1.0 && !( xExps[ i ] == 0 && yExps[ i ] == 0 ) ) result.append( '-' ); else result.append( coeffs[ i ] ); } if( xExps[ i ] >= 1 ) result.append( 'x' ); if( xExps[ i ] > 1 ) result.append( "^" + xExps[ i ] ); if( yExps[ i ] >= 1 ) result.append( 'y' ); if( yExps[ i ] > 1 ) result.append( "^" + yExps[ i ] ); return result.toString(); } private String termToString( int i ) { StringBuffer result = new StringBuffer(); if( coeffs[ i ] >= 0.0 ) result.append( '+' ); result.append( coeffs[ i ] ); result.append( "x^" + xExps[ i ] ); result.append( "y^" + yExps[ i ] ); return result.toString(); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/algebra/XYZPolynomial.java000066400000000000000000000662351330553604100264530ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.algebra; import java.util.*; public class XYZPolynomial { public static final XYZPolynomial X; public static final XYZPolynomial Y; public static final XYZPolynomial Z; public static final XYZPolynomial ZERO; public static final XYZPolynomial ONE; static { X = new XYZPolynomial( new Term( 1.0, (byte) 1, (byte) 0, (byte) 0 ) ); Y = new XYZPolynomial( new Term( 1.0, (byte) 0, (byte) 1, (byte) 0 ) ); Z = new XYZPolynomial( new Term( 1.0, (byte) 0, (byte) 0, (byte) 1 ) ); ZERO = new XYZPolynomial( 0.0 ); ONE = new XYZPolynomial( 1.0 ); } public static class Term implements Comparable< Term > { double coeff; byte xExp; byte yExp; byte zExp; public Term( Term t ) { this.coeff = t.coeff; this.xExp = t.xExp; this.yExp = t.yExp; this.zExp = t.zExp; } public Term( double coeff, byte xExp, byte yExp, byte zExp ) { this.coeff = coeff; this.xExp = xExp; this.yExp = yExp; this.zExp = zExp; } public int lexCompare( Term t ) { int result = this.xExp < t.xExp ? -4 : ( this.xExp > t.xExp ? 4 : 0 ); if( result == 0 ) { result += this.yExp < t.yExp ? -2 : ( this.yExp > t.yExp ? 2 : 0 ); if( result == 0 ) { result += this.zExp < t.zExp ? -1 : ( this.zExp > t.zExp ? 1 : 0 ); } } return result; } public int compareTo( Term t ) { int result = this.xExp < t.xExp ? -8 : ( this.xExp > t.xExp ? 8 : 0 ); if( result == 0 ) { result += this.yExp < t.yExp ? -4 : ( this.yExp > t.yExp ? 4 : 0 ); if( result == 0 ) { result += this.zExp < t.zExp ? -2 : ( this.zExp > t.zExp ? 2 : 0 ); if( result == 0 ) { result += this.coeff < t.coeff ? -1 : ( this.coeff > t.coeff ? 2 : 0 ); } } } return result; } public Term mult( Term t ) { return new Term( this.coeff * t.coeff, (byte) ( this.xExp + t.xExp ), (byte) ( this.yExp + t.yExp ), (byte) ( this.zExp + t.zExp ) ); } public Term mult( double d ) { Term result = new Term( this ); result.coeff *= d; return result; } public Term pow( int exp ) { return new Term( Math.pow( this.coeff, exp ), (byte) ( this.xExp * exp ), (byte) ( this.yExp * exp ), (byte) ( this.zExp * exp ) ); } public double evaluateAt( double x, double y, double z ) { return coeff * Helper.pow( x, xExp ) * Helper.pow( y, yExp ) * Helper.pow( z, zExp ); } public String toString() { StringBuffer result = new StringBuffer(); if( coeff != 1.0 ) { if( coeff == -1.0 && !( xExp == 0 && yExp == 0 && zExp == 0 ) ) result.append( '-' ); else result.append( coeff ); } if( xExp >= 1 ) result.append( 'x' ); if( xExp > 1 ) result.append( "^" + xExp ); if( yExp >= 1 ) result.append( 'y' ); if( yExp > 1 ) result.append( "^" + yExp ); if( zExp >= 1 ) result.append( 'z' ); if( zExp > 1 ) result.append( "^" + zExp ); return result.toString(); } public String longToString() { StringBuffer result = new StringBuffer(); if( coeff >= 0.0 ) result.append( '+' ); result.append( coeff ); result.append( "x^" + xExp + "y^" + yExp + "z^" + zExp ); return result.toString(); } public boolean equals( Term t ) { return this.coeff == t.coeff && this.xExp == t.xExp && this.yExp == t.yExp && this.zExp == t.zExp; } public int hashCode() { return ( ( int ) ( Double.doubleToRawLongBits( this.coeff ) % 0x00000000FFFFFFFFL ) ) & ( ( int ) this.xExp ) & ( ( int ) this.xExp ) << 8 & ( ( int ) this.xExp ) << 16; } } private Term[] terms; // ordered list of terms, such that terms[ i ].lexCompare( terms[ i + 1 ] ) < 0 private byte xDegree; private byte yDegree; private byte zDegree; private byte minDegree; private byte maxDegree; private byte degree; private int numXyTerms; // number of terms in result of evaluateZ private boolean isCompact = false; private static final Term[] dummyTermArray = new Term[ 0 ]; public XYZPolynomial() { this( 0.0 ); } public XYZPolynomial( double value ) { this( new Term( value, (byte) 0, (byte) 0, (byte) 0 ) ); } public XYZPolynomial( XYZPolynomial p ) { this.terms = new Term[ p.terms.length ]; for( int i = 0; i < this.terms.length; i++ ) this.terms[ i ] = new Term( p.terms[ i ] ); calculateDegree(); } public XYZPolynomial( Term t ) { terms = new Term[ 1 ]; terms[ 0 ] = new Term( t ); calculateDegree(); } XYZPolynomial( Term[] terms ) { this.terms = terms; calculateDegree(); } private void calculateDegree() { xDegree = terms[ terms.length - 1 ].xExp; yDegree = 0; zDegree = 0; numXyTerms = 1; Term last_t = terms[ 0 ]; for( Term t : this.terms ) { yDegree = (byte) Math.max( yDegree, t.yExp ); zDegree = (byte) Math.max( zDegree, t.zExp ); degree = (byte) Math.max( degree, t.xExp + t.yExp + t.zExp ); if( last_t.xExp != t.xExp || last_t.yExp != t.yExp ) { last_t = t; ++numXyTerms; } } minDegree = (byte) Math.min( xDegree, Math.min( yDegree, zDegree ) ); maxDegree = (byte) Math.max( xDegree, Math.max( yDegree, zDegree ) ); } Term[] getTerms() { return this.terms; } public XYZPolynomial neg() { Term[] resultTerms = new Term[ this.terms.length ]; for( int i = 0; i < this.terms.length; i++ ) { Term t = this.terms[ i ]; resultTerms[ i ] = new Term( -t.coeff, t.xExp, t.yExp, t.zExp ); } return new XYZPolynomial( resultTerms ); } public XYZPolynomial sub( XYZPolynomial p ) { return this.add( p.neg() ); } public XYZPolynomial add( XYZPolynomial p ) { LinkedList< Term > resultTerms = new LinkedList< Term >(); // merge term lists and sum terms of same order Term[] terms1 = this.terms; Term[] terms2 = p.terms; int i1 = 0; int i2 = 0; while( i1 < terms1.length && i2 < terms2.length ) { int lexCompare = terms1[ i1 ].lexCompare( terms2[ i2 ] ); if( lexCompare < 0 ) { resultTerms.add( new Term( terms1 [ i1++ ] ) ); } else if( lexCompare > 0 ) { resultTerms.add( new Term( terms2 [ i2++ ] ) ); } else { // add terms Term sum = new Term( terms1 [ i1++ ] ); sum.coeff += terms2[ i2++ ].coeff; resultTerms.add( sum ); } } while( i1 < terms1.length ) resultTerms.add( new Term( terms1 [ i1++ ] ) ); while( i2 < terms2.length ) resultTerms.add( new Term( terms2 [ i2++ ] ) ); return new XYZPolynomial( resultTerms.toArray( XYZPolynomial.dummyTermArray ) ); } public XYZPolynomial mult( XYZPolynomial p ) { return mult( this, p ); /* XYZPolynomial result = new XYZPolynomial(); for( Term t1 : this.terms ) { Term[] partialProductTerms = new Term[ p.terms.length ]; for( int i = 0; i < p.terms.length; i++ ) { Term t2 = p.terms[ i ]; partialProductTerms[ i ] = t1.mult( t2 ); } result = result.add( new XYZPolynomial( partialProductTerms ) ); } return result; */ } private static XYZPolynomial mult( XYZPolynomial p1, XYZPolynomial p2 ) { LinkedList< Term > resultTerms = new LinkedList< Term >(); for( Term t1 : p1.terms ) { for( int i = 0; i < p2.terms.length; i++ ) resultTerms.add( t1.mult( p2.terms[ i ] ) ); } return new XYZPolynomial( collect( resultTerms.toArray( XYZPolynomial.dummyTermArray ), true ) ); } // // standard polynomial multiplication (faster, but less numerically stable) // private static XYZPolynomial mult( XYZPolynomial p1, XYZPolynomial p2 ) // { // XYZPolynomial result = new XYZPolynomial(); // for( Term t1 : p1.terms ) // { // Term[] partialProductTerms = new Term[ p2.terms.length ]; // for( int i = 0; i < p2.terms.length; i++ ) // { // Term t2 = p2.terms[ i ]; // partialProductTerms[ i ] = t1.mult( t2 ); // } // result = result.add( new XYZPolynomial( partialProductTerms ) ); // } // return result; // } public XYZPolynomial mult( double d ) { Term[] resultTerms = new Term[ this.terms.length ]; for( int i = 0; i < this.terms.length; i++ ) { Term t = this.terms[ i ]; resultTerms[ i ] = new Term( d * t.coeff, t.xExp, t.yExp, t.zExp ); } return new XYZPolynomial( resultTerms ); } public XYZPolynomial pow( int exp ) { if( exp == 0 ) return ONE; else if( exp == 1 ) return this; else { XYZPolynomial result = this; XYZPolynomial x = this; exp--; while( exp > 0 ) { if( ( exp & 1 ) == 1 ) { result = result.mult( x ); exp--; } x = x.mult( x ); exp /= 2; } return result; } } public double evaluateXYZ( double x, double y, double z ) { double[] xPowers = new double[ maxDegree + 1 ]; double[] yPowers = new double[ maxDegree + 1 ]; double[] zPowers = new double[ maxDegree + 1 ]; xPowers[ 0 ] = 1.0; yPowers[ 0 ] = 1.0; zPowers[ 0 ] = 1.0; for( int i = 1; i <= maxDegree; i++ ) { xPowers[ i ] = xPowers[ i - 1 ] * x; yPowers[ i ] = yPowers[ i - 1 ] * y; zPowers[ i ] = zPowers[ i - 1 ] * z; } double result = 0.0; for( Term t : this.terms ) result += t.coeff * xPowers[ t.xExp ] * yPowers[ t.yExp ] * zPowers[ t.zExp ]; return result; } public XYPolynomial evaluateZ( double z ) { if( terms.length == 0 ) return new XYPolynomial( 0.0 ); if( !isCompact ) { terms = collect( terms, true ); isCompact = true; } double[] zPowers = new double[ zDegree * 2 + 1 ]; for( int i = 0; i <= zDegree; ++i ) zPowers[ zDegree + i ] = Math.pow( z, i ); double[] xy_coeffs = new double[ numXyTerms ]; byte[] xy_xExps = new byte[ numXyTerms ]; byte[] xy_yExps = new byte[ numXyTerms ]; int term_index, incr, last_index; int xy_term_index; if( Math.abs( z ) > 1.0 ) { term_index = 0; // iterate forwards incr = 1; last_index = terms.length - 1; xy_term_index = 0; for( int i = 1; i <= zDegree; ++i ) zPowers[ zDegree - i ] = 1.0 / zPowers[ zDegree + i ]; } else { term_index = terms.length - 1; // iterate backwards incr = -1; last_index = 0; xy_term_index = xy_coeffs.length - 1; } Term last_t = terms[ term_index ]; Term t = last_t; double xy_coeff = last_t.coeff; xy_xExps[ xy_term_index ] = last_t.xExp; xy_yExps[ xy_term_index ] = last_t.yExp; //java.math.BigDecimal xyt_bd = new java.math.BigDecimal( last_t.coeff ); //java.math.BigDecimal z_bd = new java.math.BigDecimal( z ); while( incr * term_index < incr * last_index ) { term_index += incr; t = terms[ term_index ]; if( last_t.xExp == t.xExp && last_t.yExp == t.yExp ) { xy_coeff = xy_coeff * zPowers[ zDegree + ( last_t.zExp - t.zExp ) ] + t.coeff; // stardard Horner step for abs(z)<=1.0, inverser Horner otherwise (mult with 1/z) //xyt_bd = xyt_bd.multiply( z_bd.pow( last_t.zExp - t.zExp ) ).add( new java.math.BigDecimal( t.coeff ) ); } else { xy_coeff = xy_coeff * zPowers[ zDegree + last_t.zExp ]; // finalize term //xyt_bd = xyt_bd.multiply( z_bd.pow( last_t.zExp ) ); //xyt.coeff = xyt_bd.doubleValue(); xy_coeffs[ xy_term_index ] = xy_coeff; xy_term_index += incr; xy_coeff = t.coeff; xy_xExps[ xy_term_index ] = t.xExp; xy_yExps[ xy_term_index ] = t.yExp; //xyt_bd = new java.math.BigDecimal( t.coeff ); } last_t = t; } // finalize last term xy_coeff = xy_coeff * zPowers[ zDegree + last_t.zExp ]; xy_coeffs[ xy_term_index ] = xy_coeff; //xyt_bd = xyt_bd.multiply( z_bd.pow( last_t.zExp ) ); //xyt.coeff = xyt_bd.doubleValue(); return new XYPolynomial( xy_coeffs, xy_xExps, xy_yExps, false ); } /* public XYPolynomial evaluateZ( double z ) { double[] zPowers = new double[ zDegree + 1 ]; zPowers[ 0 ] = 1.0; for( int i = 1; i < zPowers.length; i++ ) zPowers[ i ] = zPowers[ i - 1 ] * z; XYPolynomial.Term[] xyTerms = new XYPolynomial.Term[ this.xyTermsLength ]; xyTerms[ 0 ] = new XYPolynomial.Term( 0.0, this.terms[ 0 ].xExp, this.terms[ 0 ].yExp ); int xyTermsIndex = 0; for( Term t : this.terms ) if( t.xExp == xyTerms[ xyTermsIndex ].xExp && t.yExp == xyTerms[ xyTermsIndex ].yExp ) xyTerms[ xyTermsIndex ].coeff += t.coeff * zPowers[ t.zExp ]; else xyTerms[ ++xyTermsIndex ] = new XYPolynomial.Term( t.coeff * zPowers[ t.zExp ], t.xExp, t.yExp ); return new XYPolynomial( xyTerms, false, 0, 0 ); } */ /** * * @return This polynomial without non-constant terms that have a zero coefficient. */ public XYZPolynomial eliminateZeroTerms() { int j = 0; for( int i = 0; i < this.terms.length; i++ ) if( this.terms[ i ].coeff != 0.0 ) this.terms[ j++ ] = this.terms[ i ]; if( j == 0 ) this.terms[ j++ ] = new Term( 0.0, (byte) 0, (byte) 0, (byte) 0 ); Term[] resultTerms = new Term[ j ]; System.arraycopy( this.terms, 0, resultTerms, 0, resultTerms.length ); this.terms = resultTerms; // degree of polynomial may have changed -> renew stored values calculateDegree(); return this; } public UnivariatePolynomial substitute( UnivariatePolynomial xPoly, UnivariatePolynomial yPoly, UnivariatePolynomial zPoly ) { if( terms.length == 0 ) return new UnivariatePolynomial(); if( !isCompact ) { terms = collect( terms, true ); isCompact = true; } int term_index = terms.length; Term last_t = terms[ --term_index ]; UnivariatePolynomial x_result = UnivariatePolynomial.ZERO; UnivariatePolynomial y_result = UnivariatePolynomial.ZERO; UnivariatePolynomial z_result = new UnivariatePolynomial( last_t.coeff ); UnivariatePolynomial[] xPolyPowers = new UnivariatePolynomial[ this.xDegree + 1 ]; UnivariatePolynomial[] yPolyPowers = new UnivariatePolynomial[ this.yDegree + 1 ]; UnivariatePolynomial[] zPolyPowers = new UnivariatePolynomial[ this.zDegree + 1 ]; Term t = last_t; while( term_index > 0 ) { t = terms[ --term_index ]; boolean x_equal = last_t.xExp == t.xExp; boolean y_equal = last_t.yExp == t.yExp; if( x_equal && y_equal ) z_result = z_result.mult_add( zPoly.pow( last_t.zExp - t.zExp, zPolyPowers ), t.coeff ); // horner step for z else { z_result = z_result.mult( zPoly.pow( last_t.zExp, zPolyPowers ) ); // finalize z_result if( x_equal ) { y_result = y_result.add( z_result ).mult( yPoly.pow( last_t.yExp - t.yExp, yPolyPowers ) ); // horner step for y } else { y_result = y_result.add( z_result ).mult( yPoly.pow( last_t.yExp, yPolyPowers ) ); // finalize y_result x_result = x_result.add( y_result ).mult( xPoly.pow( last_t.xExp - t.xExp, xPolyPowers ) ); // horner step for x y_result = UnivariatePolynomial.ZERO; } z_result = new UnivariatePolynomial( t.coeff ); } last_t = t; } // finalize last term z_result = z_result.mult( zPoly.pow( last_t.zExp, zPolyPowers ) ); // finalize z_result y_result = y_result.add( z_result ).mult( yPoly.pow( last_t.yExp, yPolyPowers ) ); // finalize y_result x_result = x_result.add( y_result ).mult( xPoly.pow( last_t.xExp, zPolyPowers ) ); // finalize x_result return x_result; } /* // mutlivariate polynomial substitution by multinomial expansion public XYZPolynomial substitute( XYZPolynomial xPoly, XYZPolynomial yPoly, XYZPolynomial zPoly ) { assert xPoly.terms.length == 4; LinkedList< Term > result_terms = new LinkedList< Term >(); for( Term t : this.terms ) { XYZPolynomial x_subst = new XYZPolynomial( multinomialExpansion( xPoly.terms, t.xExp ) ); XYZPolynomial y_subst = new XYZPolynomial( multinomialExpansion( yPoly.terms, t.yExp ) ); XYZPolynomial z_subst = new XYZPolynomial( multinomialExpansion( zPoly.terms, t.zExp ) ); result_terms.addAll( Arrays.asList( x_subst.mult( y_subst ).mult( z_subst ).mult( t.coeff ).terms ) ); } return new XYZPolynomial( collect( result_terms.toArray( new Term[ result_terms.size() ] ), true ) ); } static Term[] multinomialExpansion( Term[] terms, int exp ) { synchronized( System.out ) { System.out.println( "(" + new XYZPolynomial( terms ) + ")^" + exp ); assert terms.length == 4; Term A = terms[ 0 ]; Term B = terms[ 1 ]; Term C = terms[ 2 ]; Term D = terms[ 3 ]; LinkedList< Term > result_terms = new LinkedList< Term >(); for( int i = 0; i <= exp; ++i ) { long exp_i = MultinomialCoefficients.binomialCoefficient( exp, i ); for( int j = 0; j <= i; ++j ) { long i_j = MultinomialCoefficients.binomialCoefficient( i, j ); for( int k = 0; k <= j; ++k ) { long j_k = MultinomialCoefficients.binomialCoefficient( j, k ); result_terms.add( A.pow( exp - i ).mult( B.pow( i - j ) ).mult( C.pow( j - k ) ).mult( D.pow( k ) ).mult( ( double ) ( exp_i * i_j * j_k ) ) ); } } } System.out.println( "=" + new XYZPolynomial( result_terms.toArray( new Term[ result_terms.size() ] ) ) ); System.out.println(); System.out.flush(); return result_terms.toArray( new Term[ result_terms.size() ] ); } } */ // multivariate polynomial substitution by horner evaluation public XYZPolynomial substitute( XYZPolynomial xPoly, XYZPolynomial yPoly, XYZPolynomial zPoly ) { if( terms.length == 0 ) return new XYZPolynomial(); if( !isCompact ) { terms = collect( terms, true ); isCompact = true; } int term_index = terms.length; Term last_t = terms[ --term_index ]; XYZPolynomial x_result = new XYZPolynomial(); XYZPolynomial y_result = new XYZPolynomial(); XYZPolynomial z_result = new XYZPolynomial( last_t.coeff ); //System.out.println( "z_result=" + z_result ); //System.out.println( "y_result=" + y_result ); //System.out.println( "x_result=" + x_result ); Term t = last_t; while( term_index > 0 ) { t = terms[ --term_index ]; boolean x_equal = last_t.xExp == t.xExp; boolean y_equal = last_t.yExp == t.yExp; if( x_equal && y_equal ) z_result = z_result.mult( zPoly.pow( last_t.zExp - t.zExp ) ).add( new XYZPolynomial( t.coeff ) ); // horner step for z else { z_result = z_result.mult( zPoly.pow( last_t.zExp ) ); // finalize z_result if( x_equal ) { y_result = y_result.add( z_result ).mult( yPoly.pow( last_t.yExp - t.yExp ) ); // horner step for y } else { y_result = y_result.add( z_result ).mult( yPoly.pow( last_t.yExp ) ); // finalize y_result x_result = x_result.add( y_result ).mult( xPoly.pow( last_t.xExp - t.xExp ) ); // horner step for x y_result = new XYZPolynomial(); } z_result = new XYZPolynomial( t.coeff ); } last_t = t; } //System.out.println( "last_t=" + last_t.longToString() ); //System.out.println( "z_result=" + z_result ); //System.out.println( "y_result=" + y_result ); //System.out.println( "x_result=" + x_result ); // finalize last term z_result = z_result.mult( zPoly.pow( last_t.zExp ) ); // finalize z_result //System.out.println( z_result ); y_result = y_result.add( z_result ).mult( yPoly.pow( last_t.yExp ) ); // finalize y_result //System.out.println( y_result ); x_result = x_result.add( y_result ).mult( xPoly.pow( last_t.xExp ) ); // finalize x_result //System.out.println( x_result ); return x_result; } /* // trivial way to substitute the multivariate polynomials into this public XYZPolynomial substitute( XYZPolynomial xPoly, XYZPolynomial yPoly, XYZPolynomial zPoly ) { LinkedList< Term > terms = new LinkedList< Term >(); for( Term t : this.terms ) { XYZPolynomial xPolyXExp = xPoly.pow( t.xExp ); XYZPolynomial yPolyYExp = yPoly.pow( t.yExp ); XYZPolynomial zPolyZExp = zPoly.pow( t.zExp ); XYZPolynomial expandedTerm = ( xPolyXExp.mult( yPolyYExp ).mult( zPolyZExp ) ).mult( t.coeff ); for( Term e : expandedTerm.terms ) terms.add( e ); } XYZPolynomial result = new XYZPolynomial( collect( terms.toArray( XYZPolynomial.dummyTermArray ), true ) ); return result; } */ private static Term[] collect( Term[] terms, boolean sort ) { if( terms.length > 0 ) { if( sort ) Arrays.sort( terms, null ); LinkedList< Term > resultTerms = new LinkedList< Term >(); int j = 0, i = 1; for( ; i < terms.length; i++ ) { if( terms[ j ].lexCompare( terms[ i ] ) != 0 ) { double kahanSum = kahanSum( terms, j, i - j ); if( kahanSum != 0.0 ) resultTerms.add( new Term( kahanSum, terms[ j ].xExp, terms[ j ].yExp, terms[ j ].zExp ) ); j = i; } } if( j != i ) { double kahanSum = kahanSum( terms, j, i - j ); if( kahanSum != 0.0 ) resultTerms.add( new Term( kahanSum, terms[ j ].xExp, terms[ j ].yExp, terms[ j ].zExp ) ); } if( resultTerms.size() == 0 ) resultTerms.add( new Term( 0.0, (byte) 0, (byte) 0, (byte) 0 ) ); return resultTerms.toArray( XYZPolynomial.dummyTermArray ); } else { return terms; } } // numerical stable sum over an array of numbers private static double kahanSum( Term[] terms, int from, int num ) { double sum = 0.0; if( num != 0 ) { sum = terms[ from ].coeff; double c = 0.0; for( int i = from + 1; i < from + num; i++ ) { double y = terms[ i ].coeff - c; double t = sum + y; c = ( t - sum ) - y; sum = t; } } return sum; } public String toString() { StringBuffer sb = new StringBuffer(); for( Term t : this.terms ) sb.append( ( t.coeff > 0.0 ? "+" : "" ) + t ); if( sb.charAt( 0 ) == '+' ) sb.deleteCharAt( 0 ); return sb.toString(); } public double[][][] recursiveView() { double[][][] a = new double[ zDegree + 1 ][][]; for( int i = 0; i <= zDegree; ++i ) { double[][] tmp = new double[ yDegree + 1 ][]; for( int j = 0; j <= yDegree; ++j ) tmp[ j ] = new double[ xDegree ]; a[ i ] = tmp; } for( Term t : this.terms ) a[ t.zExp ][ t.yExp ][ t.xExp ] = t.coeff; return a; } public boolean equals( XYZPolynomial p ) { if( this.terms.length != p.terms.length ) return false; for( int i = 0; i < this.terms.length; ++i ) if( !this.terms[ i ].equals( p.terms[ i ] ) ) return false; return true; } public int hashCode() { int c = 0; for( int i = 0; i < this.terms.length; ++i ) c += this.terms[ i ].hashCode(); return c; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/debug/000077500000000000000000000000001330553604100225275ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/debug/Globals.java000066400000000000000000000014251330553604100247570ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.debug; import java.awt.*; public class Globals { public static Point mousePos; public static boolean pause = false; public static void dummy() {} } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/grid/000077500000000000000000000000001330553604100223665ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/grid/RotationGrid.java000066400000000000000000000272171330553604100256470ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.grid; import de.mfo.jsurf.algebra.*; import de.mfo.jsurf.parser.*; import de.mfo.jsurf.rendering.*; import de.mfo.jsurf.rendering.cpu.*; import de.mfo.jsurf.util.*; import static de.mfo.jsurf.rendering.cpu.CPUAlgebraicSurfaceRenderer.AntiAliasingMode; import java.awt.Graphics2D; import java.awt.image.*; import java.awt.Point; import java.awt.geom.*; import javax.vecmath.*; import javax.imageio.*; // input/output import java.net.URL; import java.util.*; import java.io.*; import org.apache.commons.cli.*; public class RotationGrid { static CPUAlgebraicSurfaceRenderer asr; static Matrix4d additional_rotation; static Matrix4d basic_rotation; static Matrix4d scale; static int size; static AntiAliasingMode aam; static AntiAliasingPattern aap; public static BufferedImage renderAnimGrid( int xAngleMin, int xAngleMax, int xSteps, int yAngleMin, int yAngleMax, int ySteps ) { BufferedImage grid = new BufferedImage( ySteps * size, xSteps * size, BufferedImage.TYPE_INT_RGB ); Graphics2D g2 = (Graphics2D) grid.getGraphics(); for( int x = 0; x < xSteps; ++x ) { double xAngle = xAngleMin + ( xAngleMax - xAngleMin ) * ( xSteps == 1 ? 0.5 : ( x / ( double ) (xSteps - 1) ) ); Matrix4d matRotX = new Matrix4d(); matRotX.setIdentity(); matRotX.rotX( Math.toRadians( xAngle ) ); for( int y = 0; y < ySteps; ++y ) { double yAngle = yAngleMin + ( yAngleMax - yAngleMin ) * ( ySteps == 1 ? 0.5 : ( y / ( double ) (ySteps - 1) ) ); Matrix4d matRotY = new Matrix4d(); matRotY.setIdentity(); matRotY.rotY( Math.toRadians( yAngle ) ); additional_rotation.mul( matRotY, matRotX ); BufferedImage bi = createBufferedImageFromRGB( draw( size, size, aam, aap )); g2.drawImage( bi, new AffineTransformOp( new AffineTransform(), AffineTransformOp.TYPE_NEAREST_NEIGHBOR ), ( ySteps - 1 - y ) * size, x * size ); } } return grid; } public static ImgBuffer draw( int width, int height, CPUAlgebraicSurfaceRenderer.AntiAliasingMode aam, AntiAliasingPattern aap ) { // create color buffer ImgBuffer ib = new ImgBuffer( width, height ); // do rendering Matrix4d transform = new Matrix4d(); transform.mul( basic_rotation, additional_rotation ); asr.setTransform( transform ); asr.setSurfaceTransform( scale ); asr.setAntiAliasingMode( aam ); asr.setAntiAliasingPattern( aap ); setOptimalCameraDistance( asr.getCamera() ); try { asr.draw( ib.rgbBuffer, width, height ); return ib; } catch( RenderingInterruptedException rie ) { return null; } catch( Throwable t ) { t.printStackTrace(); return null; } } public static void setScale( double scaleFactor ) { scaleFactor= Math.pow( 10, scaleFactor); scale.setScale( scaleFactor ); } static BufferedImage createBufferedImageFromRGB( ImgBuffer ib ) { int w = ib.width; int h = ib.height; DirectColorModel colormodel = new DirectColorModel( 24, 0xff0000, 0xff00, 0xff ); SampleModel sampleModel = colormodel.createCompatibleSampleModel( w, h ); DataBufferInt data = new DataBufferInt( ib.rgbBuffer, w * h ); WritableRaster raster = WritableRaster.createWritableRaster( sampleModel, data, new Point( 0, 0 ) ); return new BufferedImage( colormodel, raster, false, null ); } public static void saveToPNG( OutputStream os, BufferedImage bufferedImage ) throws java.io.IOException { AffineTransform tx = AffineTransform.getScaleInstance(1, -1); tx.translate(0, -bufferedImage.getHeight(null)); AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); bufferedImage = op.filter(bufferedImage, null); javax.imageio.ImageIO.write( bufferedImage, "png", os ); } protected static void setOptimalCameraDistance( Camera c ) { float cameraDistance; switch( c.getCameraType() ) { case ORTHOGRAPHIC_CAMERA: cameraDistance = 1.0f; break; case PERSPECTIVE_CAMERA: cameraDistance = ( float ) ( 1.0 / Math.sin( ( Math.PI / 180.0 ) * ( c.getFoVY() / 2.0 ) ) ); break; default: throw new RuntimeException(); } c.lookAt( new Point3d( 0, 0, cameraDistance ), new Point3d( 0, 0, -1 ), new Vector3d( 0, 1, 0 ) ); } public static void loadFromString( String s ) throws Exception { Properties props = new Properties(); props.load( new ByteArrayInputStream( s.getBytes() ) ); loadFromProperties( props ); } public static void loadFromFile( URL url ) throws IOException, Exception { Properties props = new Properties(); props.load( url.openStream() ); loadFromProperties( props ); } public static void loadFromProperties( Properties props ) throws Exception { asr.setSurfaceFamily( props.getProperty( "surface_equation" ) ); Set< Map.Entry< Object, Object > > entries = props.entrySet(); String parameter_prefix = "surface_parameter_"; for( Map.Entry< Object, Object > entry : entries ) { String name = (String) entry.getKey(); if( name.startsWith( parameter_prefix ) ) { String parameterName = name.substring( parameter_prefix.length() ); asr.setParameterValue( parameterName, Float.parseFloat( ( String ) entry.getValue() ) ); } } asr.getCamera().loadProperties( props, "camera_", "" ); asr.getFrontMaterial().loadProperties(props, "front_material_", ""); asr.getBackMaterial().loadProperties(props, "back_material_", ""); for( int i = 0; i < asr.MAX_LIGHTS; i++ ) { asr.getLightSource( i ).setStatus(LightSource.Status.OFF); asr.getLightSource( i ).loadProperties( props, "light_", "_" + i ); } asr.setBackgroundColor( BasicIO.fromColor3fString( props.getProperty( "background_color" ) ) ); setScale( Float.parseFloat( props.getProperty( "scale_factor" ) ) ); basic_rotation = BasicIO.fromMatrix4dString( props.getProperty( "rotation_matrix" ) ); } public static void main( String args[] ) { size = 100; int xAngleMin = -90; int xAngleMax = 90; int xSteps = 11; int yAngleMin = -90; int yAngleMax = 90; int ySteps = 11; String jsurf_filename = ""; String output_filename = null; Options options = new Options(); options.addOption("s","size", true, "width (and height) of a tile image (default: " + size + ")"); options.addOption("minXAngle", true, "minimum rotation in x direction (default: " + xAngleMin + ")"); options.addOption("maxXAngle", true, "maximum rotation in x direction (default: " + xAngleMax + ")"); options.addOption("stepsX",true,"number of steps in x range of rotation (default: " + ySteps + ")"); options.addOption("minYAngle", true, "minimum rotation in y direction (default: " + yAngleMin + ")"); options.addOption("maxYAngle", true, "maximum rotation in y direction (default: " + yAngleMax + ")"); options.addOption("stepsY",true,"number of steps in y range of rotation (default: " + ySteps + ")"); options.addOption("q","quality",true,"quality of the rendering: 0 (low), 1 (medium, default), 2 (high), 3 (extreme)"); options.addOption("o","output",true,"output PNG into this file (otherwise STDOUT)"); CommandLineParser parser = new PosixParser(); HelpFormatter formatter = new HelpFormatter(); String help_header = "RotationGrid [options] jsurf_file"; try { CommandLine cmd = parser.parse( options, args ); if( cmd.getArgs().length > 0) jsurf_filename = cmd.getArgs()[ 0 ]; else { formatter.printHelp( help_header, options ); return; } if( cmd.hasOption( "output" ) ) output_filename = cmd.getOptionValue("output"); if( cmd.hasOption("size") ) size = Integer.parseInt( cmd.getOptionValue("size") ); if( cmd.hasOption("minXAngle") ) xAngleMin = Integer.parseInt( cmd.getOptionValue("minXAngle") ); if( cmd.hasOption("maxXAngle") ) xAngleMax = Integer.parseInt( cmd.getOptionValue("maxXAngle") ); if( cmd.hasOption("stepsX") ) xSteps = Integer.parseInt( cmd.getOptionValue("stepsX") ); if( cmd.hasOption("minYAngle") ) yAngleMin = Integer.parseInt( cmd.getOptionValue("minYAngle") ); if( cmd.hasOption("maxYAngle") ) yAngleMax = Integer.parseInt( cmd.getOptionValue("maxYAngle") ); if( cmd.hasOption("stepsY") ) ySteps = Integer.parseInt( cmd.getOptionValue("stepsY") ); if( cmd.hasOption("stepsY") ) ySteps = Integer.parseInt( cmd.getOptionValue("stepsY") ); int quality = 1; if( cmd.hasOption("quality") ) quality = Integer.parseInt( cmd.getOptionValue( "quality" ) ); switch( quality ) { case 0: aam = AntiAliasingMode.ADAPTIVE_SUPERSAMPLING; aap = AntiAliasingPattern.OG_1x1; break; case 2: aam = AntiAliasingMode.ADAPTIVE_SUPERSAMPLING; aap = AntiAliasingPattern.OG_4x4; break; case 3: aam = AntiAliasingMode.SUPERSAMPLING; aap = AntiAliasingPattern.OG_4x4; break; case 1: aam = AntiAliasingMode.ADAPTIVE_SUPERSAMPLING; aap = AntiAliasingPattern.QUINCUNX; } } catch( ParseException exp ) { System.out.println( "Unexpected exception:" + exp.getMessage() ); } catch( NumberFormatException nfe ) { formatter.printHelp( "RotationGrid", options ); } asr = new CPUAlgebraicSurfaceRenderer(); scale = new Matrix4d(); scale.setIdentity(); setScale(0.0); basic_rotation = new Matrix4d(); basic_rotation.setIdentity(); additional_rotation = new Matrix4d(); additional_rotation.setIdentity(); try { loadFromFile( new File( jsurf_filename ).toURI().toURL() ); } catch( Exception e ) { e.printStackTrace(); } setOptimalCameraDistance( asr.getCamera() ); try { BufferedImage bi = renderAnimGrid( xAngleMin, xAngleMax, xSteps, yAngleMin, yAngleMax, ySteps ); if( output_filename == null ) saveToPNG( System.out, bi ); else saveToPNG( new FileOutputStream( new File( "test.png" ) ), bi ); } catch( Exception e ) { e.printStackTrace(); } } } class ImgBuffer { public int[] rgbBuffer; public int width; public int height; public ImgBuffer( int w, int h ) { rgbBuffer = new int[ 3 * w * h ]; width = w; height = h; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/pointcloud/000077500000000000000000000000001330553604100236215ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/pointcloud/CSVPointExporter.java000066400000000000000000000022601330553604100276620ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.pointcloud; import javax.vecmath.*; import java.io.*; public class CSVPointExporter implements Exporter { PrintStream ps; public CSVPointExporter( File file ) throws IOException { ps = new PrintStream( new FileOutputStream( file ) ); } public void startExport() {} public void export( Point3d p, Vector3d normal ) { ps.println( p.x + "," + p.y + "," + p.z ); } public void exportBBox( double size ) {} public void finishExport() { ps.flush(); ps.close(); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/pointcloud/Exporter.java000066400000000000000000000015221330553604100262740ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.pointcloud; import javax.vecmath.*; public interface Exporter { public void startExport(); public void export( Point3d p, Vector3d normal ); public void exportBBox( double size ); public void finishExport(); } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/pointcloud/OBJExporter.java000066400000000000000000000050521330553604100266310ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.pointcloud; import javax.vecmath.*; import java.io.*; public class OBJExporter implements Exporter { PrintStream ps; int counter; public OBJExporter( File file ) throws IOException { ps = new PrintStream( new FileOutputStream( file ) ); counter = 1; } public void startExport() {} public void export( Point3d p, Vector3d normal ) { double nLength = normal.length(); ps.println( "v " + p.x + " " + p.y + " " + p.z ); ps.println( "vn " + normal.x / nLength + " " + normal.y / nLength + " " + normal.z / nLength ); ps.println( "p " + counter + "//" + counter ); counter++; } public void exportBBox( double size ) { double[][] points = { { 1, 1, 1 }, { 1, 1, -1 }, { 1, -1, 1 }, { 1, -1, -1 }, { -1, 1, 1 }, { -1, 1, -1 }, { -1, -1, 1 }, { -1, -1, -1 } }; // export vertices ps.println(); for( int i = 0; i < points.length; i++ ) ps.println( "v " + points[ i ][ 0 ] + " " + points[ i ][ 1 ] + " " + points[ i ][ 2 ] ); // export faces exportBBoxFace( counter, 0, 4, 6, 2 ); // front face exportBBoxFace( counter, 1, 3, 7, 5 ); // back face exportBBoxFace( counter, 5, 7, 6, 4 ); // left face exportBBoxFace( counter, 0, 2, 3, 1 ); // right face exportBBoxFace( counter, 2, 6, 7, 3 ); // bottom face exportBBoxFace( counter, 0, 1, 5, 4 ); // top face counter += 8; } private void exportBBoxFace( int offset, int i1, int i2, int i3, int i4 ) { i1 += offset; i2 += offset; i3 += offset; i4 += offset; ps.println( "f " + i1 + " " + i2 + " " + i3 + " " + i4 ); } public void finishExport() { ps.flush(); ps.close(); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/pointcloud/PointCloudCreator.java000066400000000000000000000244401330553604100300700ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.pointcloud; import de.mfo.jsurf.algebra.*; import de.mfo.jsurf.parser.*; import javax.vecmath.*; import java.io.*; import java.util.*; import javax.swing.*; import javax.swing.filechooser.*; public class PointCloudCreator // implements Runnable { /* SimpleGUI gui; * * public void run() * { * gui = new SimpleGUI(); * gui.setVisible( true ); * } * */ public static void createPointCloud( String expression, int numSamples, double scale, boolean clipToSphere, boolean showProgress, PointContainer container ) { PolynomialOperation po; PolynomialOperation gradientX; PolynomialOperation gradientY; PolynomialOperation gradientZ; try { Simplificator simplificator = new Simplificator(); po = AlgebraicExpressionParser.parse( expression ); po = po.accept( simplificator, ( Void ) null ); // calculate grad_x and simplify gradientX = po.accept( new Differentiator( PolynomialVariable.Var.x ), ( Void ) null ); gradientX = gradientX.accept( simplificator, ( Void ) null ); // calculate grad_y and simplify gradientY = po.accept( new Differentiator( PolynomialVariable.Var.y ), ( Void ) null ); gradientY = gradientY.accept( simplificator, ( Void ) null ); // calculate grad_z and simplify gradientZ = po.accept( new Differentiator( PolynomialVariable.Var.z ), ( Void ) null ); gradientZ = gradientZ.accept( simplificator, ( Void ) null ); } catch( Throwable t ) { throw new RuntimeException( "Error in Expression", t ); } PolynomialExpansionCoefficientCalculator pecc = new PolynomialExpansionCoefficientCalculator( po ); DChainRootFinder dcrf = new DChainRootFinder(); GradientCalculator gc = new SimpleGradientCalculator( gradientX, gradientY, gradientZ ); Vector3d dir; Point3d origin; Vector3d uDir; Vector3d vDir; Random r = new Random( System.currentTimeMillis() ); double pixelDiscRadius = 0.75 / ( numSamples - 1 ); long maxSamples = 3 * numSamples * numSamples; long currentSample = 0; /* ProgressMonitor progressMonitor = null; if( showProgress ) { progressMonitor = new ProgressMonitor( null, "Constructing point cloud ...", "sample 0 of " + maxSamples, 0, 100 ); progressMonitor.setMillisToDecideToPopup( 0 ); progressMonitor.setMillisToPopup( 0 ); } */ for( int run = 0; run < 3; run++ ) { switch( run ) { case 0: dir = new Vector3d( 0.0, 0.0, 1.0 ); uDir = new Vector3d( 1.0, 0.0, 0.0 ); vDir = new Vector3d( 0.0, 1.0, 0.0 ); break; case 1: dir = new Vector3d( 0.0, 1.0, 0.0 ); uDir = new Vector3d( 1.0, 0.0, 0.0 ); vDir = new Vector3d( 0.0, 0.0, 1.0 ); break; case 2: dir = new Vector3d( 1.0, 0.0, 0.0 ); uDir = new Vector3d( 0.0, 1.0, 0.0 ); vDir = new Vector3d( 0.0, 0.0, 1.0 ); break; default: throw new RuntimeException( "This should never happen." ); } for( int u = 0; u < numSamples; u++ ) { double ud = -1.0 + 2.0 * ( ( double ) u ) / ( numSamples - 1 ); for( int v = 0; v < numSamples; v++ ) { double vd = -1.0 + 2.0 * ( ( double ) v ) / ( numSamples - 1 ); double uRandomOffset = r.nextGaussian() * pixelDiscRadius; double vRandomOffset = r.nextGaussian() * pixelDiscRadius; origin = new Point3d( uDir ); origin.scale( ud + uRandomOffset ); origin.scaleAdd( vd + vRandomOffset, vDir, origin ); Vector2d searchInterval = new Vector2d( -1.0, 1.0 ); if( !clipToSphere || clipToSphere( origin, dir, searchInterval ) ) { UnivariatePolynomial xPoly = new UnivariatePolynomial( origin.x / scale, dir.x / scale ); UnivariatePolynomial yPoly = new UnivariatePolynomial( origin.y / scale, dir.y / scale ); UnivariatePolynomial zPoly = new UnivariatePolynomial( origin.z / scale, dir.z / scale ); UnivariatePolynomial p = pecc.calculateCoefficients( xPoly, yPoly, zPoly ); double[] roots = dcrf.findAllRootsIn( p, searchInterval.x, searchInterval.y ); for( int i = 0; i < roots.length; i++ ) { Point3d surfacePoint = new Point3d(); surfacePoint.scaleAdd( roots[ i ], dir, origin ); Vector3d normal = gc.calculateGradient( surfacePoint ); container.add( surfacePoint, normal ); } } currentSample++; /* if( showProgress ) { long progress = ( 100 * currentSample ) / ( maxSamples - 1 ); if( progress != ( 100 * ( currentSample - 1 ) ) / ( maxSamples - 1 ) ) setProgress( progressMonitor, ( int ) progress, "sample " + currentSample + " of " + maxSamples ); } */ } } } /* if( showProgress ) progressMonitor.setProgress( 100 ); */ } /* private static void setProgress( final ProgressMonitor progressMonitor, final int progress, final String note ) { SwingUtilities.invokeLater( new Runnable() { public void run() { progressMonitor.setProgress( progress ); progressMonitor.setNote( note ); } } ); } */ public static void export( String expression, int numSamples, double scale, boolean clipToSphere ) { FileNameExtensionFilter csvFilter = new FileNameExtensionFilter( "Comma separated points (.csv)", "csv" ); FileNameExtensionFilter objFilter = new FileNameExtensionFilter( "WaveFront OBJ (.obj)", "obj" ); FileNameExtensionFilter ntpsFilter = new FileNameExtensionFilter( "PoissonRecon (.npts)", "npts" ); JFileChooser fc = new JFileChooser(); fc.setAcceptAllFileFilterUsed( false ); fc.addChoosableFileFilter( csvFilter ); fc.addChoosableFileFilter( objFilter ); fc.addChoosableFileFilter( ntpsFilter ); fc.setFileFilter( csvFilter ); if( fc.showSaveDialog( null ) == JFileChooser.APPROVE_OPTION ) { File file = fc.getSelectedFile(); if( file.exists() ) if( JOptionPane.CANCEL_OPTION == JOptionPane.showConfirmDialog( fc, "Overwrite existing file?", "Confirm Overwrite", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE ) ) return; final Exporter exporter; try { String defaultExtension = "." + ( ( FileNameExtensionFilter ) fc.getFileFilter() ).getExtensions()[ 0 ]; if( !file.getPath().endsWith( defaultExtension ) ) file = new File( file.getPath() + defaultExtension ); if( fc.getFileFilter() == csvFilter ) exporter = new CSVPointExporter( file ); else if( fc.getFileFilter() == objFilter ) exporter = new OBJExporter( file ); else if( fc.getFileFilter() == ntpsFilter ) exporter = new PoissonReconExporter( file ); else return; } catch( IOException ioe ) { JOptionPane.showMessageDialog( null, "Could not write to file " + file.getPath() ); return; } // Point container, that writes the points immediately into the exporter PointContainer pc = new PointContainer() { public void add( Point3d p, Vector3d n ) { exporter.export( p, n ); } }; createPointCloud( expression, numSamples, scale, clipToSphere, true, pc ); exporter.finishExport(); } } /* public static void main( String[] args ) { try { UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() ); } catch (Exception e) { } //Schedule a job for the event-dispatching thread: //creating and showing this application's GUI. javax.swing.SwingUtilities.invokeLater( new PointCloudCreator() ); } */ public static boolean clipToSphere( Point3d o, Vector3d d, Vector2d interval ) { Vector3d my_o = new Vector3d( o ); Vector3d my_d = new Vector3d( d ); double length = my_d.length(); my_d.scale( 1.0f / length ); // solve algebraic double B = -my_o.dot( my_d ); double C = my_o.dot( my_o ) - 1.0f; double D = B * B - C; if( D < 0.0 ) return false; double sqrtD = Math.sqrt( D ); interval.set( B - sqrtD, B + sqrtD ); interval.scale( 1.0f / length ); return true; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/pointcloud/PointContainer.java000066400000000000000000000013531330553604100274220ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.pointcloud; import javax.vecmath.*; public interface PointContainer { public void add( Point3d p, Vector3d normal ); } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/pointcloud/PoissonReconExporter.java000066400000000000000000000025001330553604100306330ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.pointcloud; import javax.vecmath.*; import java.io.*; /** * Exports points and normals for usage with the PoissonRecon mesh reconstructor. */ public class PoissonReconExporter implements Exporter { PrintStream ps; public PoissonReconExporter( File file ) throws IOException { ps = new PrintStream( new FileOutputStream( file ) ); } public void startExport() {} public void export( Point3d p, Vector3d normal ) { ps.print( p.x + " " + p.y + " " + p.z + " " + normal.x + " " + normal.y + " " + normal.z + " "); } public void exportBBox( double size ) {} public void finishExport() { ps.flush(); ps.close(); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/000077500000000000000000000000001330553604100234165ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/AlgebraicSurfaceRenderer.java000066400000000000000000000205761330553604100311440ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering; import de.mfo.jsurf.algebra.*; import de.mfo.jsurf.parser.*; import de.mfo.jsurf.util.BasicIO; import javax.vecmath.*; import java.util.*; public abstract class AlgebraicSurfaceRenderer { public static final int MAX_LIGHTS = 8; private String surfaceExpressionFamilyString; private PolynomialOperation surfaceExpressionFamily; private int surfaceTotalDegree; private PolynomialOperation surfaceExpression; private PolynomialOperation gradientXExpression; private PolynomialOperation gradientYExpression; private PolynomialOperation gradientZExpression; private Simplificator parameterSubstitutor; private Camera camera; private Material frontMaterial; private Material backMaterial; private LightSource[] lightSources; private Matrix4d transform; private Matrix4d surfaceTransform; private Color3f backgroundColor; public AlgebraicSurfaceRenderer() { this.parameterSubstitutor = new Simplificator(); this.camera = new Camera(); this.frontMaterial = new Material(); this.backMaterial = new Material(); this.lightSources = new LightSource[ MAX_LIGHTS ]; this.lightSources[ 0 ] = new LightSource(); for( int i = 1; i < this.lightSources.length; i++ ) { this.lightSources[ i ] = new LightSource(); this.lightSources[ i ].setStatus(LightSource.Status.OFF); } this.transform = new Matrix4d(); this.transform.setIdentity(); this.surfaceTransform = new Matrix4d(); this.surfaceTransform.setIdentity(); this.backgroundColor = new Color3f( 1.0f, 1.0f, 1.0f ); this.setSurfaceFamily( new PolynomialVariable( PolynomialVariable.Var.z ) ); } public abstract void draw( int[] colorBuffer, int width, int height ); @Deprecated public void setSurfaceExpression( PolynomialOperation expression ) { this.setSurfaceFamily( expression ); } private void setSurfaceFamily( PolynomialOperation expression, String expressionString ) { this.surfaceExpressionFamily = expression; this.surfaceExpressionFamilyString = expressionString; this.clearExpressionCache(); this.parameterSubstitutor = new Simplificator(); // forget about old values of parameters this.surfaceTotalDegree = this.surfaceExpressionFamily.accept( new DegreeCalculator(), ( Void ) null ); } public void setSurfaceFamily( PolynomialOperation expression ) { setSurfaceFamily( expression, expression.accept( new ToStringVisitor(), (Void) null) ); } public void setSurfaceFamily( String expression ) throws Exception { setSurfaceFamily( AlgebraicExpressionParser.parse( expression ), expression ); } private void clearExpressionCache() { this.surfaceExpression = null; // clear cache version of concrete surface expression, where all parameters have been set this.gradientXExpression = null; this.gradientYExpression = null; this.gradientZExpression = null; } public PolynomialOperation getSurfaceFamily() { return this.surfaceExpressionFamily; } public String getSurfaceFamilyString() { return this.surfaceExpressionFamilyString; } public PolynomialOperation getSurfaceExpression() { if( this.surfaceExpression == null ) this.surfaceExpression = this.surfaceExpressionFamily.accept( parameterSubstitutor, ( Void ) null ); return this.surfaceExpression; } public PolynomialOperation getGradientXExpression() { if( this.gradientXExpression == null ) this.gradientXExpression = getSurfaceExpression().accept( new Differentiator( PolynomialVariable.Var.x ), ( Void ) null ); return this.gradientXExpression; } public PolynomialOperation getGradientYExpression() { if( this.gradientYExpression == null ) this.gradientYExpression = getSurfaceExpression().accept( new Differentiator( PolynomialVariable.Var.y ), ( Void ) null ); return this.gradientYExpression; } public PolynomialOperation getGradientZExpression() { if( this.gradientZExpression == null ) this.gradientZExpression = getSurfaceExpression().accept( new Differentiator( PolynomialVariable.Var.z ), ( Void ) null ); return this.gradientZExpression; } public int getSurfaceTotalDegree() { return this.surfaceTotalDegree; } public void setParameterValue( String name, double value ) { this.parameterSubstitutor.setParameterValue( name, value ); clearExpressionCache(); } public void unsetParameter( String name ) { this.parameterSubstitutor.unsetParameterValue(name); clearExpressionCache(); } public double getParameterValue( String name ) { return this.parameterSubstitutor.getParameterValue( name ); } public Set< Map.Entry< String, java.lang.Double > > getAssignedParameters() { return this.parameterSubstitutor.getKnownParameters(); } public Set< String > getAllParameterNames() { return this.surfaceExpressionFamily.accept( new DoubleVariableExtractor(), ( Void ) null ); } public void setCamera( Camera camera ) throws NullPointerException { if( camera == null ) throw new NullPointerException(); this.camera = camera; } public Camera getCamera() { return this.camera; } public void setTransform( Matrix4d m ) throws NullPointerException { if( m == null ) throw new NullPointerException(); this.transform = new Matrix4d( m ); } public Matrix4d getTransform() { return new Matrix4d( this.transform ); } public void setSurfaceTransform( Matrix4d m ) throws NullPointerException { if( m == null ) throw new NullPointerException(); this.surfaceTransform = new Matrix4d( m ); } public Matrix4d getSurfaceTransform() { return new Matrix4d( this.surfaceTransform ); } /** * Set light source number @code{which}. If @code{which >= }@link{MAX_LIGHTS} * or @code{which < 0}, then nothing is done. Using @code{null} disables * a light source. * @param which * @param s */ public void setLightSource( int which, LightSource s ) { if( 0 <= which && which < MAX_LIGHTS ) this.lightSources[ which ] = s; } /** * Returns the light source associated with index @code{which}. * The result may be @code{null}. * @param which * @return The light source associated with index @code{which}. May be @code{null}. */ public LightSource getLightSource( int which ) { if( 0 <= which && which < MAX_LIGHTS ) return this.lightSources[ which ]; else return null; } public void setFrontMaterial( Material m ) throws NullPointerException { if( m == null ) throw new NullPointerException(); this.frontMaterial = m; } public Material getFrontMaterial() { return this.frontMaterial; } public void setBackMaterial( Material m ) throws NullPointerException { if( m == null ) throw new NullPointerException(); this.backMaterial = m; } public Material getBackMaterial() { return this.backMaterial; } public void setBackgroundColor( Color3f c ) throws NullPointerException { if( c == null ) throw new NullPointerException(); this.backgroundColor = c; } public Color3f getBackgroundColor() { return this.backgroundColor; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/Camera.java000066400000000000000000000072411330553604100254550ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering; import javax.vecmath.*; import java.util.Properties; import de.mfo.jsurf.util.BasicIO; public class Camera { public enum CameraType { ORTHOGRAPHIC_CAMERA, PERSPECTIVE_CAMERA } private CameraType cameraType; private double fovY; private double height; private Matrix4d transform; public Camera() { this.cameraType = CameraType.ORTHOGRAPHIC_CAMERA; this.fovY = 60.0; this.height = 2.0; this.transform = new Matrix4d(); this.transform.setIdentity(); } public void lookAt( Point3d camPosition, Point3d pointOfInterest, Vector3d upVector ) { Vector3d x = new Vector3d(); Vector3d y = new Vector3d(); Vector3d z = new Vector3d(); z.sub( camPosition, pointOfInterest ); z.normalize(); x.cross( upVector, z ); x.normalize(); y.cross( z, x ); this.transform.setColumn( 0, new Vector4d( x ) ); this.transform.setColumn( 1, new Vector4d( y ) ); this.transform.setColumn( 2, new Vector4d( z ) ); this.transform.setColumn( 3, new Vector4d( -camPosition.x, -camPosition.y, -camPosition.z, 1f ) ); } public void setCameraType( CameraType camType ) { this.cameraType = camType; } public CameraType getCameraType() { return this.cameraType; } public void setFoVY( float fovy ) { this.fovY = fovy; } public double getFoVY() { return this.fovY; } public void setHeight( double height ) { this.height = height; } public double getHeight() { return this.height; } public Matrix4d getTransform() { return this.transform; } public Properties saveProperties( Properties props, String prefix, String suffix ) { props.setProperty( prefix + "type" + suffix, cameraType.toString() ); props.setProperty( prefix + "fov_y" + suffix, "" + fovY ); props.setProperty( prefix + "height" + suffix, "" + height ); props.setProperty( prefix + "transform" + suffix, BasicIO.toString( transform ) ); return props; } public void loadProperties( Properties props, String prefix, String suffix ) { String camera_type_key = prefix + "type" + suffix; if( props.containsKey( camera_type_key ) ) cameraType = CameraType.valueOf( props.getProperty( camera_type_key ) ); String fov_y_key = prefix + "fov_y" + suffix; if( props.containsKey( fov_y_key ) ) fovY = Double.parseDouble( props.getProperty( fov_y_key ) ); String height_key = prefix + "height" + suffix; if( props.containsKey( height_key ) ) height = Double.parseDouble( props.getProperty( height_key ) ); String transform_key = prefix + "transform" + suffix; if( props.containsKey( transform_key ) ) transform = BasicIO.fromMatrix4dString( props.getProperty( transform_key ) ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/LightProducts.java000066400000000000000000000035231330553604100270570ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering; import javax.vecmath.*; public class LightProducts { private LightSource lightSource; private Material material; private Color3f diffuseProduct; private Color3f specularProduct; public LightProducts( LightSource lightSource, Material material ) { this.lightSource = lightSource; this.material = material; this.diffuseProduct = new Color3f( material.getColor() ); this.diffuseProduct.x *= lightSource.getColor().x; this.diffuseProduct.y *= lightSource.getColor().y; this.diffuseProduct.z *= lightSource.getColor().z; this.diffuseProduct.scale( material.getDiffuseIntensity() * lightSource.getIntensity() ); this.specularProduct = new Color3f( lightSource.getColor() ); this.specularProduct.scale( material.getSpecularIntensity() * lightSource.getIntensity() ); } public LightSource getLightSource() { return this.lightSource; } public Material getMaterial() { return this.material; } public Color3f getDiffuseProduct() { return this.diffuseProduct; } public Color3f getSpecularProduct() { return this.specularProduct; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/LightSource.java000066400000000000000000000062771330553604100265250ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering; import javax.vecmath.*; import java.util.Properties; import de.mfo.jsurf.util.BasicIO; public class LightSource { public enum Status { ON, OFF } private Status status; private Point3d position; private Color3f color; private float intensity; public LightSource() { this.status = Status.ON; this.position = new Point3d( 0.0, 0.0, 0.0 ); this.color = new Color3f( 1.0f, 1.0f, 1.0f ); this.intensity = 1.0f; } public void setStatus( Status status ) { this.status = status; } public Status getStatus() { return this.status; } public void setPosition(Point3d position) throws NullPointerException { if (position == null) { throw new NullPointerException(); } this.position = position; } public Point3d getPosition() { return position; } public void setColor(Color3f color) throws NullPointerException { if (color == null) { throw new NullPointerException(); } this.color = color; } public Color3f getColor() { return color; } public void setIntensity(float intensity) { this.intensity = intensity; } public float getIntensity() { return intensity; } public Properties saveProperties( Properties props, String prefix, String suffix ) { props.setProperty( prefix + "status" + suffix, status.name() ); props.setProperty( prefix + "position" + suffix, BasicIO.toString( position ) ); props.setProperty( prefix + "color" + suffix, "" + BasicIO.toString( color ) ); props.setProperty( prefix + "intensity" + suffix, "" + intensity ); return props; } public void loadProperties( Properties props, String prefix, String suffix ) { String status_key = prefix + "status" + suffix; if( props.containsKey( status_key ) ) status = Status.valueOf( props.getProperty( status_key ) ); String position_key = prefix + "position" + suffix; if( props.containsKey( position_key ) ) position = BasicIO.fromPoint3dString( props.getProperty( position_key ) ); String color_key = prefix + "color" + suffix; if( props.containsKey( color_key ) ) color = BasicIO.fromColor3fString( props.getProperty( color_key ) ); String intensity_key = prefix + "intensity" + suffix; if( props.containsKey( intensity_key ) ) intensity = Float.parseFloat( props.getProperty( intensity_key ) ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/Material.java000066400000000000000000000106151330553604100260220ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering; import javax.vecmath.*; import java.util.Properties; import de.mfo.jsurf.util.BasicIO; public class Material { private Color3f color; private float ambientIntensity; private float diffuseIntensity; private float specularIntensity; private float shininess; public Material() { this.color = new Color3f( 0.5f, 0.5f, 0.5f ); this.ambientIntensity = 0.1f; this.diffuseIntensity = 0.23232f; this.specularIntensity = 0.9f; this.shininess = 1.0f; } public Color3f getColor() { return color; } public void setColor(Color3f color) throws NullPointerException { if (color == null) { throw new NullPointerException(); } this.color = color; } public float getAmbientIntensity() { return this.ambientIntensity; } public void setAmbientIntensity(float intensity) { this.ambientIntensity = intensity; } public float getDiffuseIntensity() { return this.diffuseIntensity; } public void setDiffuseIntensity(float intensity) { this.diffuseIntensity = intensity; } public float getSpecularIntensity() { return specularIntensity; } public void setSpecularIntensity(float specularIntensity) { this.specularIntensity = specularIntensity; } public float getShininess() { return this.shininess; } public void setShininess(float shininess) { this.shininess = shininess; } private static float lerp( float f1, float f2, float t ) { return f1 * ( 1.0f - t ) + t * f2; } public static Material lerp( Material m1, Material m2, float t ) { Material m = new Material(); m.color.interpolate( m1.color, m2.color, t ); m.ambientIntensity = lerp( m1.ambientIntensity, m2.ambientIntensity, t ); m.diffuseIntensity = lerp( m1.diffuseIntensity, m2.diffuseIntensity, t ); m.specularIntensity = lerp( m1.specularIntensity, m2.specularIntensity, t ); m.shininess = lerp( m1.shininess, m2.shininess, t ); return m; } public Properties saveProperties( Properties props, String prefix, String suffix ) { props.setProperty( prefix + "color" + suffix, BasicIO.toString( color ) ); props.setProperty( prefix + "ambient_intensity" + suffix, "" + ambientIntensity ); props.setProperty( prefix + "diffuse_intensity" + suffix, "" + diffuseIntensity ); props.setProperty( prefix + "specular_intensity" + suffix, "" + specularIntensity ); props.setProperty( prefix + "shininess" + suffix, "" + shininess ); return props; } public void loadProperties( Properties props, String prefix, String suffix ) { String color_key = prefix + "color" + suffix; if( props.containsKey( color_key ) ) color = BasicIO.fromColor3fString( props.getProperty( color_key ) ); String ambient_intensity_key = prefix + "ambient_intensity" + suffix; if( props.containsKey( ambient_intensity_key ) ) ambientIntensity = Float.parseFloat( props.getProperty( ambient_intensity_key ) ); String diffuse_intensity_key = prefix + "diffuse_intensity" + suffix; if( props.containsKey( diffuse_intensity_key ) ) diffuseIntensity = Float.parseFloat( props.getProperty( diffuse_intensity_key ) ); String specular_intensity_key = prefix + "specular_intensity" + suffix; if( props.containsKey( specular_intensity_key ) ) specularIntensity = Float.parseFloat( props.getProperty( specular_intensity_key ) ); String shininess_key = prefix + "shininess" + suffix; if( props.containsKey( shininess_key ) ) shininess = Float.parseFloat( props.getProperty( shininess_key ) ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/RenderingInterruptedException.java000077500000000000000000000020041330553604100323020ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering; public class RenderingInterruptedException extends RuntimeException { public RenderingInterruptedException() { super(); } public RenderingInterruptedException( String message ) { super( message ); } public RenderingInterruptedException( String message, Throwable cause ) { super( message, cause ); } public RenderingInterruptedException( Throwable cause ) { super( cause ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/cpu/000077500000000000000000000000001330553604100242055ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/cpu/AntiAliasingPattern.java000066400000000000000000000243531330553604100307600ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering.cpu; import java.util.Iterator; import java.util.NoSuchElementException; public enum AntiAliasingPattern implements Iterable< AntiAliasingPattern.SamplingPoint > { OG_1x1( getOGSSPattern( 1 ) ), OG_2x2( getOGSSPattern( 2 ) ), OG_3x3( getOGSSPattern( 3 ) ), OG_4x4( getOGSSPattern( 4 ) ), OG_5x5( getOGSSPattern( 5 ) ), OG_6x6( getOGSSPattern( 6 ) ), OG_7x7( getOGSSPattern( 7 ) ), OG_8x8( getOGSSPattern( 8 ) ), RG_2x2( getRGSSPattern() ), QUINCUNX( getQuincunxPattern() ); private final SamplingPoint[] points; public static class SamplingPoint { private float u, v, weight; private SamplingPoint( float u, float v, float weight ) { this.u = u; this.v = v; this.weight = weight; } public float getU() { return u;} public float getV() { return v; } public float getWeight() { return weight; } } private class SamplingPointIterator implements Iterator< SamplingPoint > { SamplingPoint[] points; int position; public SamplingPointIterator( SamplingPoint[] points ) { this.points = points; position = 0; } public boolean hasNext() { return this.position < this.points.length; } public SamplingPoint next() throws NoSuchElementException { try { return points[ position++ ]; } catch( ArrayIndexOutOfBoundsException e ) { throw new NoSuchElementException( "No more elements" ); } } public void remove() throws UnsupportedOperationException { throw new UnsupportedOperationException( "Operation is not supported" ); } } private AntiAliasingPattern( SamplingPoint[] points ) { this.points = points; } public Iterator< SamplingPoint > iterator() { return new SamplingPointIterator( this.points ); } private static SamplingPoint[] getOGSSPattern( int size ) { assert size > 0; // symmetric anti aliasing patterns final float[][][] ogss_weights = { { {} }, { {1.0f} }, { {0.25f, 0.25f}, {0.25f, 0.25f} }, { {0.0625f, 0.125f, 0.0625f}, {0.125f, 0.25f, 0.125f}, {0.0625f, 0.125f, 0.0625f} }, { {0.027777778f, 0.055555556f, 0.055555556f, 0.027777778f}, {0.055555556f, 0.11111111f, 0.11111111f, 0.055555556f}, {0.055555556f, 0.11111111f, 0.11111111f, 0.055555556f}, {0.027777778f, 0.055555556f, 0.055555556f, 0.027777778f} }, { {0.012345679f, 0.024691358f, 0.037037037f, 0.024691358f, 0.012345679f}, {0.024691358f, 0.049382716f, 0.074074075f, 0.049382716f, 0.024691358f}, {0.037037037f, 0.074074075f, 0.11111111f, 0.074074075f, 0.037037037f}, {0.024691358f, 0.049382716f, 0.074074075f, 0.049382716f, 0.024691358f}, {0.012345679f, 0.024691358f, 0.037037037f, 0.024691358f, 0.012345679f} }, { {0.0069444445f, 0.013888889f, 0.020833334f, 0.020833334f, 0.013888889f, 0.0069444445f}, {0.013888889f, 0.027777778f, 0.041666668f, 0.041666668f, 0.027777778f, 0.013888889f}, {0.020833334f, 0.041666668f, 0.0625f, 0.0625f, 0.041666668f, 0.020833334f}, {0.020833334f, 0.041666668f, 0.0625f, 0.0625f, 0.041666668f, 0.020833334f}, {0.013888889f, 0.027777778f, 0.041666668f, 0.041666668f, 0.027777778f, 0.013888889f}, {0.0069444445f, 0.013888889f, 0.020833334f, 0.020833334f, 0.013888889f, 0.0069444445f} }, { {0.00390625f, 0.0078125f, 0.01171875f, 0.015625f, 0.01171875f, 0.0078125f, 0.00390625f}, {0.0078125f, 0.015625f, 0.0234375f, 0.03125f, 0.0234375f, 0.015625f, 0.0078125f}, {0.01171875f, 0.0234375f, 0.03515625f, 0.046875f, 0.03515625f, 0.0234375f, 0.01171875f}, {0.015625f, 0.03125f, 0.046875f, 0.0625f, 0.046875f, 0.03125f, 0.015625f}, {0.01171875f, 0.0234375f, 0.03515625f, 0.046875f, 0.03515625f, 0.0234375f, 0.01171875f}, {0.0078125f, 0.015625f, 0.0234375f, 0.03125f, 0.0234375f, 0.015625f, 0.0078125f}, {0.00390625f, 0.0078125f, 0.01171875f, 0.015625f, 0.01171875f, 0.0078125f, 0.00390625f} }, { {0.0024875621f, 0.0049751243f, 0.0074626864f, 0.0099502485f, 0.0099502485f, 0.0074626864f, 0.0049751243f, 0.0024875621f}, {0.0049751243f, 0.0099502485f, 0.014925373f, 0.019900497f, 0.019900497f, 0.014925373f, 0.0099502485f, 0.0049751243f}, {0.0074626864f, 0.014925373f, 0.02238806f, 0.029850746f, 0.029850746f, 0.02238806f, 0.017412934f, 0.0074626864f}, {0.0099502485f, 0.019900497f, 0.029850746f, 0.039800994f, 0.039800994f, 0.029850746f, 0.019900497f, 0.0099502485f}, {0.0099502485f, 0.019900497f, 0.029850746f, 0.039800994f, 0.039800994f, 0.029850746f, 0.019900497f, 0.0099502485f}, {0.0074626864f, 0.014925373f, 0.02238806f, 0.029850746f, 0.029850746f, 0.02238806f, 0.017412934f, 0.0074626864f}, {0.0049751243f, 0.0099502485f, 0.014925373f, 0.019900497f, 0.019900497f, 0.014925373f, 0.0099502485f, 0.0049751243f}, {0.0024875621f, 0.0049751243f, 0.0074626864f, 0.0099502485f, 0.0099502485f, 0.0074626864f, 0.0049751243f, 0.0024875621f} } }; /* // same as above, but not normalized { { { 1 } }, { { 1, 1 }, { 1, 1 }, }, { { 1, 2, 1 }, { 2, 4, 2 }, { 1, 2, 1 } }, { { 1, 2, 2, 1 }, { 2, 4, 4, 2 }, { 2, 4, 4, 2 }, { 1, 2, 2, 1 } }, { { 1, 2, 3, 2, 1 }, { 2, 4, 6, 4, 2 }, { 3, 6, 9, 6, 3 }, { 2, 4, 6, 4, 2 }, { 1, 2, 3, 2, 1 } }, { { 1, 2, 3, 3, 2, 1 }, { 2, 4, 6, 6, 4, 2 }, { 3, 6, 9, 9, 6, 3 }, { 3, 6, 9, 9, 6, 3 }, { 2, 4, 6, 6, 4, 2 }, { 1, 2, 3, 3, 2, 1 } }, { { 1, 2, 3, 4, 3, 2, 1 }, { 2, 4, 6, 8, 6, 4, 2 }, { 3, 6, 9, 12, 9, 6, 3 }, { 4, 8, 12, 16, 12, 8, 4 }, { 3, 6, 9, 12, 9, 6, 3 }, { 2, 4, 6, 8, 6, 4, 2 }, { 1, 2, 3, 4, 3, 2, 1 } }, { { 1, 2, 3, 4, 4, 3, 2, 1 }, { 2, 4, 6, 8, 8, 6, 4, 2 }, { 3, 6, 9, 12, 12, 9, 7, 3 }, { 4, 8, 12, 16, 16, 12, 8, 4 }, { 4, 8, 12, 16, 16, 12, 8, 4 }, { 3, 6, 9, 12, 12, 9, 7, 3 }, { 2, 4, 6, 8, 8, 6, 4, 2 }, { 1, 2, 3, 4, 4, 3, 2, 1 } } }; */ SamplingPoint[] points = new SamplingPoint[ size * size ]; try { if( size == 1 ) { points[ 0 ] = new SamplingPoint( 0.5f, 0.5f, ogss_weights[ size ][ 0 ][ 0 ] ); } else { float divisor = size - 1; for( int i = 0; i < size; ++i ) for( int j = 0; j < size; j++ ) points[ i * size + j ] = new SamplingPoint( i / divisor, j / divisor, ogss_weights[ size ][ i ][ j ] ); } } catch( Exception e ) { e.printStackTrace(); } return points; } private static SamplingPoint[] getRGSSPattern() { // 4 rotated grid samples + 4 samples at pixel corners (that are usually known anyway) SamplingPoint[] points = new SamplingPoint[ 4 * 2 ]; float inner_w = 0.15f; float outer_w = 0.25f * ( 1.0f - 4.0f * inner_w ); points[ 0 ] = new SamplingPoint( 185.416f / 1000f, 282.652f / 1000f, inner_w ); points[ 1 ] = new SamplingPoint( 282.62799f / 1000f, 234.047f / 1000f, inner_w ); points[ 2 ] = new SamplingPoint( 136.813f / 1000f, 185.44099f / 1000f, inner_w ); points[ 3 ] = new SamplingPoint( 234.026f / 1000f, 136.838f / 1000f, inner_w ); points[ 4 ] = new SamplingPoint( 0.0f, 0.0f, outer_w ); points[ 5 ] = new SamplingPoint( 0.0f, 1.0f, outer_w ); points[ 6 ] = new SamplingPoint( 1.0f, 1.0f, outer_w ); points[ 7 ] = new SamplingPoint( 1.0f, 0.0f, outer_w ); return points; } private static SamplingPoint[] getQuincunxPattern() { /* * x x * x * x x */ SamplingPoint[] points = new SamplingPoint[ 5 ]; float bw = 0.0625f + 0.25f / 3.0f; points[ 0 ] = new SamplingPoint( 0.0f, 0.0f, bw ); points[ 1 ] = new SamplingPoint( 0.0f, 1.0f, bw ); points[ 2 ] = new SamplingPoint( 1.0f, 1.0f, bw ); points[ 3 ] = new SamplingPoint( 1.0f, 0.0f, bw ); points[ 4 ] = new SamplingPoint( 0.5f, 0.5f, 1.0f - 4.0f * bw ); return points; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/cpu/CPUAlgebraicSurfaceRenderer.java000066400000000000000000000202261330553604100322730ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering.cpu; import de.mfo.jsurf.algebra.*; import de.mfo.jsurf.debug.*; import de.mfo.jsurf.rendering.*; import de.mfo.jsurf.rendering.cpu.clipping.*; import javax.vecmath.*; import java.util.concurrent.*; import java.util.*; public class CPUAlgebraicSurfaceRenderer extends AlgebraicSurfaceRenderer { ExecutorService threadPoolExecutor; List< FutureTask< Boolean > > renderingTasks; synchronized DrawcallStaticData collectDrawCallStaticData( int[] colorBuffer, int width, int height ) { DrawcallStaticData dcsd = new DrawcallStaticData(); dcsd.colorBuffer = colorBuffer; dcsd.width = width; dcsd.height = height; dcsd.coefficientCalculator = new PolynomialExpansionCoefficientCalculator( getSurfaceExpression() ); if( this.getSurfaceTotalDegree() < 2 ) dcsd.realRootFinder = new ClosedFormRootFinder(); else // dcsd.realRootFinder = new DChainRootFinder(); // dcsd.realRootFinder = new SturmChainRootFinder(); dcsd.realRootFinder = new DescartesRootFinder( false ); //dcsd.realRootFinder = new EVALRootFinder( false ); //dcsd.realRootFinder = new ClosedFormRootFinder(); // dcsd.realRootFinder = new GPUSuitableDescartesRootFinder2( false ); //dcsd.realRootFinder = new BernsteinDescartesRootFinder( false ); dcsd.frontAmbientColor = new Color3f( getFrontMaterial().getColor() ); dcsd.frontAmbientColor.scale( getFrontMaterial().getAmbientIntensity() ); dcsd.backAmbientColor = new Color3f( getBackMaterial().getColor() ); dcsd.backAmbientColor.scale( getFrontMaterial().getAmbientIntensity() ); int numOfLightSources = 0; for( int i = 0; i < MAX_LIGHTS; i++ ) if( getLightSource( i ) != null && getLightSource( i ).getStatus() == LightSource.Status.ON ) numOfLightSources++; dcsd.lightSources = new LightSource[ numOfLightSources ]; dcsd.frontLightProducts = new LightProducts[ numOfLightSources ]; dcsd.backLightProducts = new LightProducts[ numOfLightSources ]; int lightSourceIndex = 0; for( int i = 0; i < MAX_LIGHTS; i++ ) { LightSource lightSource = getLightSource( i ); if( lightSource != null && lightSource.getStatus() == LightSource.Status.ON ) { dcsd.lightSources[lightSourceIndex] = lightSource; dcsd.frontLightProducts[lightSourceIndex] = new LightProducts( lightSource, getFrontMaterial() ); dcsd.backLightProducts[lightSourceIndex] = new LightProducts( lightSource, getBackMaterial() ); lightSourceIndex++; } } dcsd.backgroundColor = getBackgroundColor(); dcsd.antiAliasingPattern = getAntiAliasingPattern(); dcsd.antiAliasingThreshold = aaThreshold; dcsd.rayCreator = RayCreator.createRayCreator( getTransform(), getSurfaceTransform(), getCamera(), width, height ); dcsd.rayClipper = new ClipToSphere(); //dcsd.rayClipper = new ClipToTorus( 0.5, 0.5 ); //dcsd.rayClipper = new ClipBlowUpSurface( 1.0, 1.0 ); //dcsd.someA = new PolynomialExpansionRowSubstitutor( getSurfaceExpression(), dcsd.rayCreator.getXForSomeA(), dcsd.rayCreator.getYForSomeA(), dcsd.rayCreator.getZForSomeA() ); dcsd.surfaceRowSubstitutor = new TransformedPolynomialRowSubstitutor( getSurfaceExpression(), dcsd.rayCreator.getXForSomeA(), dcsd.rayCreator.getYForSomeA(), dcsd.rayCreator.getZForSomeA() ); dcsd.gradientRowSubstitutor = new TransformedPolynomialRowSubstitutorForGradient( getGradientXExpression(), getGradientYExpression(), getGradientZExpression(), dcsd.rayCreator.getXForSomeA(), dcsd.rayCreator.getYForSomeA(), dcsd.rayCreator.getZForSomeA() ); //dcsd.gradientRowSubstitutor = new FastRowSubstitutorForGradient( getGradientXExpression(), getGradientYExpression(), getGradientZExpression(), dcsd.rayCreator ); //System.out.println( getSurfaceExpression().accept( new ToStringVisitor(), null ) ); // fill img with bg color int bg = dcsd.backgroundColor.get().getRGB(); java.util.Arrays.fill( dcsd.colorBuffer, bg ); return dcsd; } public CPUAlgebraicSurfaceRenderer() { super(); this.setAntiAliasingMode( AntiAliasingMode.ADAPTIVE_SUPERSAMPLING ); this.setAntiAliasingPattern( AntiAliasingPattern.OG_4x4 ); final ThreadGroup tg = new ThreadGroup( "Group of rendering threads of " + this ); class PriorityThreadFactory implements ThreadFactory { public Thread newThread(Runnable r) { Thread t = new Thread( tg, r ); t.setDaemon( true ); t.setPriority( Thread.MIN_PRIORITY ); return t; } } this.threadPoolExecutor = Executors.newFixedThreadPool( 2 * Runtime.getRuntime().availableProcessors(), new PriorityThreadFactory() ); this.renderingTasks = new LinkedList< FutureTask< Boolean > >(); } public enum AntiAliasingMode { SUPERSAMPLING, ADAPTIVE_SUPERSAMPLING; } private AntiAliasingMode aaMode; private float aaThreshold; private AntiAliasingPattern aaPattern; public void setAntiAliasingMode( AntiAliasingMode mode ) { this.aaMode = mode; if( mode == AntiAliasingMode.SUPERSAMPLING ) this.aaThreshold = 0.0f; else this.aaThreshold = 0.3f; } public AntiAliasingMode getAntiAliasingMode() { return this.aaMode; } public void setAntiAliasingPattern( AntiAliasingPattern pattern ) { this.aaPattern = pattern; } public AntiAliasingPattern getAntiAliasingPattern() { return this.aaPattern; } public synchronized void draw( int[] colorBuffer, int width, int height ) { if( width == 0 || height == 0 ) return; DrawcallStaticData dcsd = collectDrawCallStaticData( colorBuffer, width, height ); int xStep = width / Math.min( width, Math.max( 2, Runtime.getRuntime().availableProcessors() ) ); int yStep = height / Math.min( height, 3 );//Math.max( 2, Runtime.getRuntime().availableProcessors() ) ); boolean success = true; LinkedList< FutureTask< Boolean > > tasks = new LinkedList< FutureTask< Boolean > >(); for( int x = 0; x < width; x += xStep ) for( int y = 0; y < height; y += yStep ) tasks.add( new FutureTask< Boolean >( new RenderingTask( dcsd, x, y, Math.min( x + xStep, width - 1 ), Math.min( y + yStep, height - 1 ) ) ) ); renderingTasks = tasks; try { for( FutureTask< Boolean > task : tasks ) threadPoolExecutor.execute( task ); for( FutureTask< Boolean > task : tasks ) success = success && task.get(); } catch( ExecutionException ie ) { success = false; } catch( InterruptedException ie ) { success = false; } catch( RejectedExecutionException ree ) { success = false; } catch( CancellationException ree ) { success = false; } finally { if( !success || Thread.interrupted() ) throw new RenderingInterruptedException( "Rendering interrupted" ); } } public void stopDrawing() { for( FutureTask< Boolean > f : renderingTasks ) f.cancel( true ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/cpu/DrawcallStaticData.java000066400000000000000000000025531330553604100305500ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering.cpu; import de.mfo.jsurf.algebra.*; import de.mfo.jsurf.rendering.*; import de.mfo.jsurf.rendering.cpu.clipping.*; import javax.vecmath.*; class DrawcallStaticData { int[] colorBuffer; int width; int height; CoefficientCalculator coefficientCalculator; RowSubstitutor surfaceRowSubstitutor; RowSubstitutorForGradient gradientRowSubstitutor; RealRootFinder realRootFinder; LightSource[] lightSources; Color3f frontAmbientColor; Color3f backAmbientColor; LightProducts[] frontLightProducts; LightProducts[] backLightProducts; Color3f backgroundColor; AntiAliasingPattern antiAliasingPattern; float antiAliasingThreshold; RayCreator rayCreator; Clipper rayClipper; } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/cpu/Helper.java000066400000000000000000000020411330553604100262640ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering.cpu; import javax.vecmath.*; final class Helper { static Point3d interpolate1D( Point3d p, Vector3d d, double t ) { return new Point3d( p.x + d.x * t, p.y + d.y * t, p.z + d.z * t ); } static Point3d interpolate2D( Point3d p, Vector3d dx, Vector3d dy, double u, double v ) { return new Point3d( p.x + dx.x * u + dy.x * v, p.y + dx.y * u + dy.y * v, p.z + dx.z * u + dy.z * v ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/cpu/OrthographicCameraRayCreator.java000066400000000000000000000225271330553604100326160ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering.cpu; import javax.vecmath.*; import de.mfo.jsurf.algebra.*; import de.mfo.jsurf.rendering.*; public class OrthographicCameraRayCreator extends RayCreator { Point3d rayOrigin; Vector3d rayDir; Vector3d du; Vector3d dv; Point3d surfaceRayOrigin; Vector3d surfaceRayDir; Vector3d surfaceDu; Vector3d surfaceDv; Point3d clippingRayOrigin; Vector3d clippingRayDir; Vector3d clippingDu; Vector3d clippingDv; double uscale; double vscale; double uoffset; double voffset; double eyeLocationOnRay; public OrthographicCameraRayCreator( Matrix4d transformMatrix, Matrix4d surfaceTransformMatrix, Camera cam, double width, double height ) { // call constructor of superclass super( transformMatrix, surfaceTransformMatrix, cam ); // create orthographic camera width default properties (origion is (0,0,0)) dv = new Vector3d( 0.0, cam.getHeight() / 2.0, 0.0 ); du = new Vector3d( ( dv.y * width ) / height, 0.0, 0.0 ); rayDir = new Vector3d( 0, 0, -1 ); // transform view plane spanning vectors to surface space surfaceDu = cameraSpaceToSurfaceSpace( du ); surfaceDv = cameraSpaceToSurfaceSpace( dv ); uscale = surfaceDu.length(); vscale = surfaceDv.length(); surfaceDu.scale( 1.0 / uscale ); surfaceDv.scale( 1.0 / vscale ); surfaceRayDir = cameraSpaceToSurfaceSpace( rayDir ); double rayDirScale = surfaceRayDir.length(); surfaceRayDir.scale( 1.0 / rayDirScale ); surfaceRayOrigin = cameraSpaceToSurfaceSpace( new Point3d( 0, 0, 0 ) ); double planeDistance = surfaceRayDir.dot( new Vector3d( surfaceRayOrigin ) ); Vector3d projCamOrigin = new Vector3d(); // project the cam origin onto the surface space viewing plane (which starts at (0,0,0) in surface space) projCamOrigin.scaleAdd( -planeDistance, surfaceRayDir, surfaceRayOrigin ); // decompose projCamOrigin into uoffset * surfaceDu + voffset * surfaceDv uoffset = projCamOrigin.dot( surfaceDu ); voffset = projCamOrigin.dot( surfaceDv ); surfaceRayOrigin = new Point3d( 0, 0, 0 ); // adjust camera parameters in camera space du.scale( 1.0 / uscale ); dv.scale( 1.0 / vscale ); rayDir.scale( 1.0 / rayDirScale ); rayOrigin = new Point3d( rayDir ); rayOrigin.scale( -planeDistance ); rayOrigin.scaleAdd( uoffset, du, rayOrigin ); rayOrigin.scaleAdd( voffset, dv, rayOrigin ); clippingRayOrigin = cameraSpaceToClippingSpace( rayOrigin ); clippingDu = cameraSpaceToClippingSpace( du ); clippingDv = cameraSpaceToClippingSpace( dv ); clippingRayDir = cameraSpaceToClippingSpace( rayDir ); eyeLocationOnRay = planeDistance; /* // create orthographic camera width default properties this.upperLeft = new Point3d(); this.upperLeft.y = cam.getHeight() / 2.0; this.upperLeft.x = ( this.upperLeft.y * width ) / height; this.upperLeft.z = 0.0f; this.dx = new Vector3d( 2.0 * this.upperLeft.x, 0.0, 0.0 ); this.dy = new Vector3d( 0.0, 2.0 * this.upperLeft.y, 0.0 ); // transform camera parameters to surface space this.surfaceUpperLeft = cameraSpaceToSurfaceSpace( this.upperLeft ); this.surfaceDx = cameraSpaceToSurfaceSpace( this.dx ); this.surfaceDy = cameraSpaceToSurfaceSpace( this.dy ); // adjust camera parameters to give a simple representation in this.clippingUpperLeft = cameraSpaceToClippingSpace( this.upperLeft ); this.clippingDx = cameraSpaceToClippingSpace( this.dx ); this.clippingDy = cameraSpaceToClippingSpace( this.dy ); // ray direction is always the same for all rays of this orthographic camera this.rayDir = new Vector3d( 0.0, 0.0, -1.0 ); this.clippingRayDir = cameraSpaceToClippingSpace( this.rayDir ); this.surfaceRayDir = cameraSpaceToSurfaceSpace( this.rayDir ); double myscale = 1.0 / this.clippingRayDir.length(); this.rayDir.scale( myscale ); this.clippingRayDir.scale( myscale ); this.surfaceRayDir.scale( myscale ); // clipping ray dir has unit length // optimize camera properties, so that the origin of the surface // ray is near the centre of the clipping sphere and // that the length of the surface ray direction is about 0.5 double bestStart = -new Vector3d( createClippingSpaceRay( -0.5, -0.5 ).o ).dot( this.clippingRayDir ); double scale = 1.0 / surfaceRayDir.length(); // apply optimized camera properties this.upperLeft = Helper.interpolate1D( this.upperLeft, this.rayDir, bestStart ); this.rayDir.scale( scale ); this.clippingUpperLeft = Helper.interpolate1D( this.clippingUpperLeft, this.clippingRayDir, bestStart ); this.clippingRayDir.scale( scale ); this.surfaceUpperLeft = Helper.interpolate1D( this.surfaceUpperLeft, this.surfaceRayDir, bestStart ); this.surfaceRayDir.scale( scale ); // save original ray configuration (sometimes the original camera position is needed) this.eyeLocation = -bestStart / scale; * */ } @Override public Ray createCameraSpaceRay( double u, double v ) { return new Ray( Helper.interpolate2D( this.rayOrigin, this.du, this.dv, u, v ), this.rayDir ); } @Override public Ray createSurfaceSpaceRay( double u, double v ) { return new Ray( Helper.interpolate2D( this.surfaceRayOrigin, this.surfaceDu, this.surfaceDv, u, v ), this.surfaceRayDir ); } @Override public Ray createClippingSpaceRay( double u, double v ) { return new Ray( Helper.interpolate2D( this.clippingRayOrigin, this.clippingDu, this.clippingDv, u, v ), this.clippingRayDir ); } @Override public double getEyeLocationOnRay() { return this.eyeLocationOnRay; } @Override public PolynomialOperation getXForSomeA() { PolynomialOperation result = new DoubleValue( this.surfaceRayOrigin.x ); result = new PolynomialAddition( result, new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.z ), new DoubleValue( this.surfaceDv.x ) ) ); result = new PolynomialAddition( result, new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.y ), new DoubleValue( this.surfaceDu.x ) ) ); result = new PolynomialAddition( result, new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.x ), new DoubleValue( this.surfaceRayDir.x ) ) ); return result; } @Override public PolynomialOperation getYForSomeA() { PolynomialOperation result = new DoubleValue( this.surfaceRayOrigin.y ); result = new PolynomialAddition( result, new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.z ), new DoubleValue( this.surfaceDv.y ) ) ); result = new PolynomialAddition( result, new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.y ), new DoubleValue( this.surfaceDu.y ) ) ); result = new PolynomialAddition( result, new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.x ), new DoubleValue( this.surfaceRayDir.y ) ) ); return result; } @Override public PolynomialOperation getZForSomeA() { PolynomialOperation result = new DoubleValue( this.surfaceRayOrigin.z ); result = new PolynomialAddition( result, new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.z ), new DoubleValue( this.surfaceDv.z ) ) ); result = new PolynomialAddition( result, new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.y ), new DoubleValue( this.surfaceDu.z ) ) ); result = new PolynomialAddition( result, new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.x ), new DoubleValue( this.surfaceRayDir.z ) ) ); return result; } @Override public Vector2d getUInterval() { return new Vector2d( uoffset - uscale, uoffset + uscale ); } @Override public Vector2d getVInterval() { return new Vector2d( voffset - vscale, voffset + vscale ); } @Override public double transformU( double u ) { double uout = uoffset + uscale * ( 2.0 * u - 1.0 ); //System.out.println( "uin=" + u ); //System.out.println( "uout=" + uout ); return uout;//uoffset + uscale * ( 2.0 * u - 1.0 ); } @Override public double transformV( double v ) { double vout = voffset + vscale * ( 2.0 * v - 1.0 ); //System.out.println( "vin=" + v ); //System.out.println( "vout=" + vout ); return vout;//uoffset + uscale * ( 2.0 * u - 1.0 ); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/cpu/PerspectiveCameraRayCreator.java000066400000000000000000000176171330553604100324620ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering.cpu; import javax.vecmath.*; import de.mfo.jsurf.algebra.*; import de.mfo.jsurf.rendering.*; public class PerspectiveCameraRayCreator extends RayCreator { private Point3d upperLeft; private Vector3d dx; private Vector3d dy; private Point3d clippingUpperLeft; private Vector3d clippingDx; private Vector3d clippingDy; private Point3d surfaceUpperLeft; private Vector3d surfaceDx; private Vector3d surfaceDy; private Point3d rayOrigin; private Point3d clippingRayOrigin; private Point3d surfaceRayOrigin; private double bestStart; private double scale; private PolynomialOperation optimizedSubstitute; public PerspectiveCameraRayCreator( Matrix4d transformMatrix, Matrix4d surfaceTransformMatrix, Camera cam, double width, double height ) { // call constructor of superclass super( transformMatrix, surfaceTransformMatrix, cam ); // create orthographic camera width default properties this.upperLeft = new Point3d(); this.upperLeft.y = ( float ) Math.tan( Math.PI / 180.0 * ( cam.getFoVY() / 2.0 ) ); this.upperLeft.x = ( this.upperLeft.y * width ) / height; this.upperLeft.z = -1.0; this.dx = new Vector3d( 2.0 * this.upperLeft.x, 0.0, 0.0 ); this.dy = new Vector3d( 0.0, 2.0 * this.upperLeft.y, 0.0 ); // transform properties for usage with clipping ... this.clippingUpperLeft = cameraSpaceToClippingSpace( this.upperLeft ); this.clippingDx = cameraSpaceToClippingSpace( this.dx ); this.clippingDy = cameraSpaceToClippingSpace( this.dy ); // ... and intersection algorithms this.surfaceUpperLeft = cameraSpaceToSurfaceSpace( this.upperLeft ); this.surfaceDx = cameraSpaceToSurfaceSpace( this.dx ); this.surfaceDy = cameraSpaceToSurfaceSpace( this.dy ); // ray origin is always the same for all rays of this perpectiive camera this.rayOrigin = new Point3d( 0.0, 0.0, 0.0 ); this.clippingRayOrigin = cameraSpaceToClippingSpace( this.rayOrigin ); this.surfaceRayOrigin = cameraSpaceToSurfaceSpace( this.rayOrigin ); // calculate optimal camera properties, so that the origin of the surface // ray is near the centre of the clipping sphere and // that the length of the surface ray direction is about 0.5 Vector3d clippingRayDir = new Vector3d( Helper.interpolate2D( this.clippingUpperLeft, this.clippingDx, this.clippingDy, 0.5, 0.5 ) ); clippingRayDir.sub( this.clippingRayOrigin ); Vector3d surfaceRayDir = new Vector3d( Helper.interpolate2D( this.surfaceUpperLeft, this.surfaceDx, this.surfaceDy, 0.5, 0.5 ) ); this.bestStart = -new Vector3d( this.clippingUpperLeft ).dot( clippingRayDir ) / clippingRayDir.dot( clippingRayDir ); scale = ( 0.5 * surfaceRayDir.length() ); // 1.0 / ( 2.0 * surfaceRayDir.length() ); this.optimizedSubstitute = new PolynomialMultiplication( new DoubleValue( this.scale ), new PolynomialVariable( PolynomialVariable.Var.x ) ); this.optimizedSubstitute = new PolynomialAddition( optimizedSubstitute, new DoubleValue( this.bestStart ) ); } @Override public Ray createCameraSpaceRay( double u, double v ) { Vector3d dir = new Vector3d( Helper.interpolate2D( this.upperLeft, this.dx, this.dy, u, v ) ); dir.sub( this.rayOrigin ); Ray result = new Ray( this.rayOrigin, dir ); result.o = Helper.interpolate1D( result.o, result.d, bestStart ); result.d.scale( scale ); return result; } @Override public Ray createSurfaceSpaceRay( double u, double v ) { Vector3d dir = new Vector3d( Helper.interpolate2D( this.surfaceUpperLeft, this.surfaceDx, this.surfaceDy, u, v ) ); dir.sub( this.surfaceRayOrigin ); Ray result = new Ray( this.surfaceRayOrigin, dir ); result.o = Helper.interpolate1D( result.o, result.d, bestStart ); result.d.scale( scale ); return result; } @Override public Ray createClippingSpaceRay( double u, double v ) { Vector3d dir = new Vector3d( Helper.interpolate2D( this.clippingUpperLeft, this.clippingDx, this.clippingDy, u, v ) ); dir.sub( this.clippingRayOrigin ); Ray result = new Ray( this.clippingRayOrigin, dir ); result.o = Helper.interpolate1D( result.o, result.d, bestStart ); result.d.scale( scale ); return result; } @Override public double getEyeLocationOnRay() { return -this.bestStart; } @Override public PolynomialOperation getXForSomeA() { PolynomialOperation result = new DoubleValue( this.surfaceUpperLeft.x ); result = new PolynomialAddition( result, new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.z ), new DoubleValue( this.surfaceDy.x ) ) ); result = new PolynomialAddition( result, new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.y ), new DoubleValue( this.surfaceDx.x ) ) ); result = new PolynomialSubtraction( result, new DoubleValue( this.surfaceRayOrigin.x ) ); result = new PolynomialMultiplication( result, optimizedSubstitute ); result = new PolynomialAddition( result, new DoubleValue( this.surfaceRayOrigin.x ) ); return result; } @Override public PolynomialOperation getYForSomeA() { PolynomialOperation result = new DoubleValue( this.surfaceUpperLeft.y ); result = new PolynomialAddition( result, new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.z ), new DoubleValue( this.surfaceDy.y ) ) ); result = new PolynomialAddition( result, new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.y ), new DoubleValue( this.surfaceDx.y ) ) ); result = new PolynomialSubtraction( result, new DoubleValue( this.surfaceRayOrigin.y ) ); result = new PolynomialMultiplication( result, optimizedSubstitute ); result = new PolynomialAddition( result, new DoubleValue( this.surfaceRayOrigin.y ) ); return result; } @Override public PolynomialOperation getZForSomeA() { PolynomialOperation result = new DoubleValue( this.surfaceUpperLeft.z ); result = new PolynomialAddition( result, new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.z ), new DoubleValue( this.surfaceDy.z ) ) ); result = new PolynomialAddition( result, new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.y ), new DoubleValue( this.surfaceDx.z ) ) ); result = new PolynomialSubtraction( result, new DoubleValue( this.surfaceRayOrigin.z ) ); result = new PolynomialMultiplication( result, optimizedSubstitute ); result = new PolynomialAddition( result, new DoubleValue( this.surfaceRayOrigin.z ) ); return result; } // get the intervals, for which u and v are in the viewport @Override public Vector2d getUInterval() { return new Vector2d( 0.0, 1.0 ); } @Override public Vector2d getVInterval() { return new Vector2d( 0.0, 1.0 ); } // transform (u,v) \in [0,1]^2 into local viewport coordinates @Override public double transformU( double u ) { return u; } @Override public double transformV( double v ) { return v; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/cpu/Ray.java000066400000000000000000000017631330553604100256120ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering.cpu; import javax.vecmath.*; public class Ray { public Point3d o; public Vector3d d; public Ray( Point3d o, Vector3d d ) { this.o = o; this.d = d; } public Point3d at( double t ) { return Helper.interpolate1D( o, d, t ); } public String toString() { return o.toString() + "+t*" + d.toString(); } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/cpu/RayCreator.java000066400000000000000000000115721330553604100271310ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering.cpu; import javax.vecmath.*; import de.mfo.jsurf.algebra.*; import de.mfo.jsurf.rendering.*; public abstract class RayCreator { Matrix4d cameraSpaceToSurfaceSpaceMatrix; Matrix4d cameraSpaceToClippingSpaceMatrix; Matrix4d surfaceSpaceNormalToCameraSpaceNormalMatrix; RayCreator( Matrix4d transformMatrix, Matrix4d surfaceTransformMatrix, Camera cam ) { Matrix4d c_i = new Matrix4d( cam.getTransform() ); c_i.invert(); cameraSpaceToClippingSpaceMatrix = new Matrix4d( transformMatrix ); cameraSpaceToClippingSpaceMatrix.mul( c_i ); cameraSpaceToSurfaceSpaceMatrix = new Matrix4d( surfaceTransformMatrix ); cameraSpaceToSurfaceSpaceMatrix.mul( cameraSpaceToClippingSpaceMatrix ); surfaceSpaceNormalToCameraSpaceNormalMatrix = new Matrix4d( cameraSpaceToSurfaceSpaceMatrix ); surfaceSpaceNormalToCameraSpaceNormalMatrix.invert(); } public static RayCreator createRayCreator( Matrix4d transformMatrix, Matrix4d surfaceTransformMatrix, Camera cam, int width, int height ) { switch( cam.getCameraType() ) { case ORTHOGRAPHIC_CAMERA: return new OrthographicCameraRayCreator( transformMatrix, surfaceTransformMatrix, cam, width, height ); case PERSPECTIVE_CAMERA: return new PerspectiveCameraRayCreator( transformMatrix, surfaceTransformMatrix, cam, width, height ); default: throw new UnsupportedOperationException(); } } public Vector3d cameraSpaceToSurfaceSpace( Vector3d v ) { Vector4d t_v = new Vector4d( v ); cameraSpaceToSurfaceSpaceMatrix.transform( t_v ); return new Vector3d( t_v.x, t_v.y, t_v.z ); } public Point3d cameraSpaceToSurfaceSpace( Point3d p ) { Point3d t_p = new Point3d( p ); cameraSpaceToSurfaceSpaceMatrix.transform( t_p ); return t_p; } public Vector3d cameraSpaceToClippingSpace( Vector3d v ) { Vector4d t_v = new Vector4d( v ); cameraSpaceToClippingSpaceMatrix.transform( t_v ); return new Vector3d( t_v.x, t_v.y, t_v.z ); } public Point3d cameraSpaceToClippingSpace( Point3d p ) { Point3d t_p = new Point3d( p ); cameraSpaceToClippingSpaceMatrix.transform( t_p ); return t_p; } public Vector3d surfaceSpaceNormalToCameraSpaceNormal( Vector3d n ) { Vector3d t_n = new Vector3d( n ); surfaceSpaceNormalToCameraSpaceNormalMatrix.transform( t_n ); return t_n; } public abstract Ray createCameraSpaceRay( double u, double v ); public abstract Ray createSurfaceSpaceRay( double u, double v ); public abstract Ray createClippingSpaceRay( double u, double v ); public abstract double getEyeLocationOnRay(); public abstract PolynomialOperation getXForSomeA(); public abstract PolynomialOperation getYForSomeA(); public abstract PolynomialOperation getZForSomeA(); // get the intervals, for which u and v are in the viewport public abstract Vector2d getUInterval(); public abstract Vector2d getVInterval(); // transform (u,v) \in [0,1]^2 into local viewport coordinates public abstract double transformU( double u ); public abstract double transformV( double v ); public static void decomposeTRS( Matrix4d A, Matrix4d T, Matrix4d R, Matrix4d S ) { assert A.m03 == 0.0 && A.m13 == 0.0 && A.m23 == 0.0 : "projective transformations are currently not supported"; AffineDecomposition.AffineParts ap = AffineDecomposition.decompAffine( A ); T.setIdentity(); T.setTranslation( ap.t ); R.setIdentity(); R.setRotation( ap.q ); S.setIdentity(); S.m00 = ap.k.x; S.m11 = ap.k.y; S.m22 = ap.k.z; { Matrix4d stretch_rotation = new Matrix4d(); stretch_rotation.setIdentity(); stretch_rotation.setRotation( ap.u ); Matrix4d rotated_stretch = new Matrix4d( stretch_rotation ); rotated_stretch.mul( S ); stretch_rotation.transpose(); rotated_stretch.mul( stretch_rotation ); assert S.epsilonEquals( rotated_stretch, 1e-10 ) : "shear transformations are currently not supported"; } } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/cpu/RenderingTask.java000066400000000000000000000437461330553604100276260ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering.cpu; import de.mfo.jsurf.algebra.*; import de.mfo.jsurf.debug.*; import de.mfo.jsurf.rendering.*; import javax.vecmath.*; import java.util.concurrent.*; import java.util.*; public class RenderingTask implements Callable { // initialized by the constructor private int xStart; private int yStart; private int xEnd; private int yEnd; private DrawcallStaticData dcsd; public RenderingTask( DrawcallStaticData dcsd, int xStart, int yStart, int xEnd, int yEnd ) { this.dcsd = dcsd; this.xStart = xStart; this.yStart = yStart; this.xEnd = xEnd; this.yEnd = yEnd; } public Boolean call() { try { render(); return true; } catch( RenderingInterruptedException rie ) { // rendering interrupted .. that's ok //System.err.println( "... interrupted" ); } catch( Throwable t ) { t.printStackTrace(); } finally { //Thread.interrupted(); // clear the interruption flag } return false; } private class ColumnSubstitutorPair { ColumnSubstitutorPair( ColumnSubstitutor scs, ColumnSubstitutorForGradient gcs ) { this.scs = scs; this.gcs = gcs; } ColumnSubstitutor scs; ColumnSubstitutorForGradient gcs; } protected void render() throws RenderingInterruptedException { switch( dcsd.antiAliasingPattern ) { case OG_1x1: { // no antialising -> sample pixel center int internal_width = xEnd - xStart + 1; int internal_height = yEnd - yStart + 1; double u_start = dcsd.rayCreator.transformU( xStart / ( dcsd.width - 1.0 ) ); double v_start = dcsd.rayCreator.transformV( yStart / ( dcsd.height - 1.0 ) ); double u_incr = ( dcsd.rayCreator.getUInterval().y - dcsd.rayCreator.getUInterval().x ) / ( dcsd.width - 1.0 ); double v_incr = ( dcsd.rayCreator.getVInterval().y - dcsd.rayCreator.getVInterval().x ) / ( dcsd.height - 1.0 ); for( int y = 0; y < internal_height; y++ ) { double v = v_start + y * v_incr; ColumnSubstitutor scs = dcsd.surfaceRowSubstitutor.setV( v ); ColumnSubstitutorForGradient gcs = dcsd.gradientRowSubstitutor.setV( v ); for( int x = 0; x < internal_width; x++ ) { if( Thread.currentThread().isInterrupted() ) throw new RenderingInterruptedException(); double u = u_start + x * u_incr; dcsd.colorBuffer[ dcsd.width * ( yStart + y ) + xStart + x ] = tracePolynomial( scs, gcs, u, v ).get().getRGB(); //dcsd.colorBuffer[ dcsd.width * y + x ] = traceRay( u, v ).get().getRGB(); } } break; } default: { // all other antialiasing modes // first sample canvas at pixel corners and cast primary rays int internal_width = xEnd - xStart + 2; int internal_height = yEnd - yStart + 2; Color3f[] internalColorBuffer = new Color3f[ internal_width * internal_height ]; ColumnSubstitutor scs = null; ColumnSubstitutorForGradient gcs = null; HashMap< java.lang.Double, ColumnSubstitutorPair > csp_hm = new HashMap< java.lang.Double, ColumnSubstitutorPair >(); double u_start = dcsd.rayCreator.transformU( ( xStart - 0.5 ) / ( dcsd.width - 1.0 ) ); double v_start = dcsd.rayCreator.transformV( ( yStart - 0.5 ) / ( dcsd.height - 1.0 ) ); double u_incr = ( dcsd.rayCreator.getUInterval().y - dcsd.rayCreator.getUInterval().x ) / ( dcsd.width - 1.0 ); double v_incr = ( dcsd.rayCreator.getVInterval().y - dcsd.rayCreator.getVInterval().x ) / ( dcsd.height - 1.0 ); double v = 0.0; for( int y = 0; y < internal_height; ++y ) { csp_hm.clear(); csp_hm.put( v, new ColumnSubstitutorPair( scs, gcs ) ); v = v_start + y * v_incr; scs = dcsd.surfaceRowSubstitutor.setV( v ); gcs = dcsd.gradientRowSubstitutor.setV( v ); csp_hm.put( v, new ColumnSubstitutorPair( scs, gcs ) ); for( int x = 0; x < internal_width; ++x ) { if( Thread.currentThread().isInterrupted() ) throw new RenderingInterruptedException(); // current position on viewing plane double u = u_start + x * u_incr; // trace rays corresponding to (u,v)-coordinates on viewing plane internalColorBuffer[ y * internal_width + x ] = tracePolynomial( scs, gcs, u, v ); if( x > 0 && y > 0 ) { Color3f ulColor = internalColorBuffer[ y * internal_width + x - 1 ]; Color3f urColor = internalColorBuffer[ y * internal_width + x ]; Color3f llColor = internalColorBuffer[ ( y - 1 ) * internal_width + x - 1]; Color3f lrColor = internalColorBuffer[ ( y - 1 ) * internal_width + x ]; dcsd.colorBuffer[ ( yStart + y - 1 ) * dcsd.width + ( xStart + x - 1 ) ] = antiAliasPixel( u - u_incr, v - v_incr, u_incr, v_incr, dcsd.antiAliasingPattern, ulColor, urColor, llColor, lrColor, csp_hm ).get().getRGB(); } } } } } } private Color3f antiAliasPixel( double ll_u, double ll_v, double u_incr, double v_incr, AntiAliasingPattern aap, Color3f ulColor, Color3f urColor, Color3f llColor, Color3f lrColor, HashMap< java.lang.Double, ColumnSubstitutorPair > csp_hm ) { // first average pixel-corner colors Color3f finalColor; // adaptive supersampling float thresholdSqr = dcsd.antiAliasingThreshold * dcsd.antiAliasingThreshold; if( aap != AntiAliasingPattern.OG_2x2 && ( colorDiffSqr( ulColor, urColor ) >= thresholdSqr || colorDiffSqr( ulColor, llColor ) >= thresholdSqr || colorDiffSqr( ulColor, lrColor ) >= thresholdSqr || colorDiffSqr( urColor, llColor ) >= thresholdSqr || colorDiffSqr( urColor, lrColor ) >= thresholdSqr || colorDiffSqr( llColor, lrColor ) >= thresholdSqr ) ) { // anti-alias pixel with advanced sampling pattern finalColor = new Color3f(); for( AntiAliasingPattern.SamplingPoint sp : aap ) { if( Thread.currentThread().isInterrupted() ) throw new RenderingInterruptedException(); Color3f ss_color; if( sp.getU() == 0.0 && sp.getV() == 0.0 ) ss_color = llColor; else if( sp.getU() == 0.0 && sp.getV() == 1.0 ) ss_color = ulColor; else if( sp.getU() == 1.0 && sp.getV() == 1.0 ) ss_color = urColor; else if( sp.getU() == 1.0 && sp.getV() == 0.0 ) ss_color = lrColor; else { // color of this sample point is not known -> calculate double v = ll_v + sp.getV() * v_incr; double u = ll_u + sp.getU() * u_incr; ColumnSubstitutorPair csp = csp_hm.get( v ); if( csp == null ) { csp = new ColumnSubstitutorPair( dcsd.surfaceRowSubstitutor.setV( v ), dcsd.gradientRowSubstitutor.setV( v ) ); csp_hm.put( v, csp ); } ss_color = tracePolynomial( csp.scs, csp.gcs, u, v ); } finalColor.scaleAdd( sp.getWeight(), ss_color, finalColor ); if( false ) return new Color3f( 0, 0, 0 ); // paint pixels, that are supposed to be anti-aliased in black } } else { finalColor = new Color3f( ulColor ); finalColor.add( urColor ); finalColor.add( llColor ); finalColor.add( lrColor ); finalColor.scale( 0.25f ); } // clamp color, because floating point operations may yield values outside [0,1] finalColor.clamp( 0f, 1f ); return finalColor; } private Color3f tracePolynomial( ColumnSubstitutor scs, ColumnSubstitutorForGradient gcs, double u, double v ) { // create rays Ray ray = dcsd.rayCreator.createCameraSpaceRay( u, v ); Ray clippingRay = dcsd.rayCreator.createClippingSpaceRay( u, v ); Ray surfaceRay = dcsd.rayCreator.createSurfaceSpaceRay( u, v ); Point3d eye = ray.at( dcsd.rayCreator.getEyeLocationOnRay() ); UnivariatePolynomialVector3d gradientPolys = null; // optimize rays and root-finder parameters //optimizeRays( ray, clippingRay, surfaceRay ); // clip ray List< Vector2d > intervals = dcsd.rayClipper.clipRay( clippingRay ); if( !intervals.isEmpty() ) { UnivariatePolynomial surfacePoly = scs.setU( u ); for( Vector2d interval : intervals ) { // adjust interval, so that it does not start before the eye point double eyeLocation = dcsd.rayCreator.getEyeLocationOnRay(); if( interval.x < eyeLocation && eyeLocation < interval.y ) interval.x = Math.max( interval.x, eyeLocation ); // intersect ray with surface and shade pixel //double[] hits = hits = dcsd.realRootFinder.findAllRootsIn( surfacePoly, interval.x, interval.y ); double[] hits = { dcsd.realRootFinder.findFirstRootIn( surfacePoly, interval.x, interval.y ) }; if( java.lang.Double.isNaN( hits[ 0 ] )) hits = new double[ 0 ]; for( double hit : hits ) { if( dcsd.rayClipper.clipPoint( surfaceRay.at( hit ), true ) ) { if( gradientPolys == null ) gradientPolys = gcs.setU( u ); Vector3d n_surfaceSpace = gradientPolys.setT( hit ); Vector3d n_cameraSpace = dcsd.rayCreator.surfaceSpaceNormalToCameraSpaceNormal( n_surfaceSpace ); return shade( ray.at( hit ), n_cameraSpace, eye ); } } } } return dcsd.backgroundColor; } // private Color3f traceRay( double u, double v ) // { // // create rays // Ray ray = dcsd.rayCreator.createCameraSpaceRay( u, v ); // Ray clippingRay = dcsd.rayCreator.createClippingSpaceRay( u, v ); // Ray surfaceRay = dcsd.rayCreator.createSurfaceSpaceRay( u, v ); // // Point3d eye = Helper.interpolate1D( ray.o, ray.d, dcsd.rayCreator.getEyeLocationOnRay() ); // UnivariatePolynomialVector3d gradientPolys = null; // // // optimize rays and root-finder parameters // //optimizeRays( ray, clippingRay, surfaceRay ); // // //System.out.println( u + "," + v + ":("+surfaceRay.o.x+","+surfaceRay.o.y+","+surfaceRay.o.z+")"+"("+surfaceRay.d.x+","+surfaceRay.d.y+","+surfaceRay.d.z+")t" ); // // // clip ray // List< Vector2d > intervals = dcsd.rayClipper.clipRay( clippingRay ); // for( Vector2d interval : intervals ) // { // // adjust interval, so that it does not start before the eye point // double eyeLocation = dcsd.rayCreator.getEyeLocationOnRay(); // // if( interval.x < eyeLocation && eyeLocation < interval.y ) // interval.x = Math.max( interval.x, eyeLocation ); // // // intersect ray with surface and shade pixel // double[] hit = new double[ 1 ]; // if( intersect( surfaceRay, interval.x, interval.y, hit ) ) // if( dcsd.rayClipper.clipPoint( surfaceRay.at( hit[ 0 ] ), true ) ) // { // if( gradientPolys == null ) // gradientPolys = gcs.setU( u ); // Vector3d n_surfaceSpace = gradientPolys.setT( hit ); // Vector3d n_cameraSpace = dcsd.rayCreator.surfaceSpaceNormalToCameraSpaceNormal( n_surfaceSpace ); // // return shade( ray.at( hit ), n_cameraSpace, eye ); // } // return shade( ray, surfaceRay, hit[ 0 ], eye ); // } // return dcsd.backgroundColor; // } private float colorDiffSqr( Color3f c1, Color3f c2 ) { Vector3f diff = new Vector3f( c1 ); diff.sub( c2 ); return diff.dot( diff ); } protected boolean intersectPolynomial( UnivariatePolynomial p, double rayStart, double rayEnd, double[] hit ) { //System.out.println( p ); hit[ 0 ] = dcsd.realRootFinder.findFirstRootIn( p, rayStart, rayEnd ); return !java.lang.Double.isNaN( hit[ 0 ] ); } protected boolean intersect( Ray r, double rayStart, double rayEnd, double[] hit ) { UnivariatePolynomial x = new UnivariatePolynomial( r.o.x, r.d.x ); UnivariatePolynomial y = new UnivariatePolynomial( r.o.y, r.d.y ); UnivariatePolynomial z = new UnivariatePolynomial( r.o.z, r.d.z ); UnivariatePolynomial p = dcsd.coefficientCalculator.calculateCoefficients( x, y, z ); p = p.shrink(); hit[ 0 ] = ( float ) dcsd.realRootFinder.findFirstRootIn( p, rayStart, rayEnd ); return !java.lang.Double.isNaN( hit[ 0 ] ); } boolean blowUpChooseMaterial( Point3d p ) { double R; if( dcsd.rayClipper instanceof de.mfo.jsurf.rendering.cpu.clipping.ClipBlowUpSurface ) R = ( ( de.mfo.jsurf.rendering.cpu.clipping.ClipBlowUpSurface ) dcsd.rayClipper ).get_R(); else R = 1.0; double u = p.x; double tmp = Math.sqrt( p.y*p.y + p.z*p.z ); double v = R + tmp; double dist = u * u + v * v; if( dist > 1.0 ) v = R - tmp; // choose the solution inside the disc return ( 3.0 * dist ) % 2.0 < 1.0; } /** * Calculates the shading in camera space * @param p The hit point on the surface in camera space. * @param n The surface normal at the hit point in camera space. * @param eye The eye point in camera space. * @return */ protected Color3f shade( Point3d p, Vector3d n, Point3d eye ) { // normalize only if point is not singular float nLength = (float) n.length(); if( nLength != 0.0f ) n.scale( 1.0f / nLength ); // compute view vector Vector3d v = new Vector3d( eye ); v.sub( p ); v.normalize(); /* // special coloring for blowup-visualization if( n.dot( v ) < 0.0f ) n.negate(); if( blowUpChooseMaterial( dcsd.rayCreator.cameraSpaceToSurfaceSpace( p ) ) ) { return shadeWithMaterial( p, v, n, dcsd.frontAmbientColor, dcsd.frontLightProducts ); } else { return shadeWithMaterial( p, v, n, dcsd.backAmbientColor, dcsd.backLightProducts ); } */ // compute, which material to use if( n.dot( v ) > 0.0f ) { return shadeWithMaterial( p, v, n, dcsd.frontAmbientColor, dcsd.frontLightProducts ); } else { n.negate(); return shadeWithMaterial( p, v, n, dcsd.backAmbientColor, dcsd.backLightProducts ); } } /** * Shades a point with the same algorithm used by the * {@link surf raytracer}. * @param hitPoint Intersection point. * @param v View vector (from intersection point to eye). * @param n Surface normal. * @param material Surface material. * @return */ protected Color3f shadeWithMaterial( Point3d hitPoint, Vector3d v, Vector3d n, Color3f ambientColor, LightProducts[] lightProducts ) { Vector3d l = new Vector3d(); Vector3d h = new Vector3d(); Color3f color = new Color3f( ambientColor ); for( int i = 0; i < dcsd.lightSources.length; i++ ) { LightSource lightSource = dcsd.lightSources[i]; l.sub( lightSource.getPosition(), hitPoint ); l.normalize(); float lambertTerm = (float) n.dot( l ); if( lambertTerm > 0.0f ) { // compute diffuse color component color.scaleAdd( lambertTerm, lightProducts[i].getDiffuseProduct(), color ); // compute specular color component h.add( l, v ); h.normalize(); color.scaleAdd( ( float ) Math.pow( Math.max( 0.0f, n.dot( h ) ), lightProducts[i].getMaterial().getShininess() ), lightProducts[i].getSpecularProduct(), color ); } } color.clampMax( 1.0f ); return color; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/cpu/clipping/000077500000000000000000000000001330553604100260125ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/cpu/clipping/ClipBlowUpSurface.java000077500000000000000000000050421330553604100322120ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering.cpu.clipping; import javax.vecmath.*; public class ClipBlowUpSurface extends ClipToTorus { public ClipBlowUpSurface() { super(); } public ClipBlowUpSurface( double R, double r ) { super( R, r ); } @Override public boolean clipPoint( Point3d p ) { double u = p.x; double tmp = Math.sqrt( p.y*p.y + p.z*p.z ); double v = R + tmp; double v_inside, v_outside; if( u * u + v * v < R * R ) { v_inside = v; v_outside = R - tmp; } else { v_inside = R - tmp; v_outside = v; } if( u * u + v_inside * v_inside > r * r ) return false; // outside of cylinder/torus double blowup_eps = 0.0001; if( false ) { // first variant double f = blowup_f( u, v_inside ); double g = blowup_g( u, v_inside ); return Math.max( Math.abs( p.z * ( g*g + f*f ) - 2.0 * ( R - v_inside ) * f * g ), Math.abs( p.y * ( g*g + f*f ) + ( R - v_inside ) * ( g * g - f * f ) ) ) <= blowup_eps * ( g*g + f*f ); } else { // second variant double f = blowup_f( u, v_outside ); double g = blowup_g( u, v_outside ); boolean p_inside = Math.max( Math.abs( p.z * ( g*g + f*f ) - 2.0 * ( R - v_outside ) * f * g ), Math.abs( p.y * ( g*g + f*f ) + ( R - v_outside ) * ( g * g - f * f ) ) ) >= blowup_eps * ( g*g + f*f ); if( p_inside ) return true; else { // p seems to originate from part of surface out the disc // -> if gradient is small, we might be at a self intersection //return length( gradient( p ) ) <= 0.001; return false; } } } double blowup_f( double u, double v ) { return u * u - 0.25; } double blowup_g( double u, double v ) { return v * v - 0.25; } // abstract double blowup_f( double u, double v ); // abstract double blowup_g( double u, double v ); @Override public boolean pointClippingNecessary() { return true; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/cpu/clipping/ClipToSphere.java000066400000000000000000000035551330553604100312260ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering.cpu.clipping; import java.util.List; import java.util.LinkedList; import javax.vecmath.*; import de.mfo.jsurf.rendering.*; import de.mfo.jsurf.rendering.cpu.*; public class ClipToSphere extends Clipper { double radius; public ClipToSphere() { this( 1.0 ); } public ClipToSphere( double radius ) { super(); this.radius = radius; } @Override public List< Vector2d > clipRay( Ray r ) { Vector3d my_o = new Vector3d( r.o ); Vector3d my_d = new Vector3d( r.d ); double length = my_d.length(); my_d.scale( 1.0f / length ); // solve algebraic double B = -my_o.dot( my_d ); double C = my_o.dot( my_o ) - radius * radius; double D = B * B - C; List< Vector2d > intervals = new LinkedList< Vector2d >(); if( D >= 0.0 ) { double sqrtD = Math.sqrt( D ); Vector2d result = new Vector2d( B - sqrtD, B + sqrtD ); result.scale( 1.0 / length ); intervals.add( result ); } return intervals; } @Override public boolean clipPoint( Point3d p ) { return p.x*p.x+p.y*p.y+p.z*p.z <= radius * radius; } @Override public boolean pointClippingNecessary() { return false; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/cpu/clipping/ClipToTorus.java000066400000000000000000000047521330553604100311140ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering.cpu.clipping; import java.util.List; import java.util.LinkedList; import javax.vecmath.*; import de.mfo.jsurf.algebra.*; import de.mfo.jsurf.rendering.cpu.*; public class ClipToTorus extends Clipper { double R; double r; double Rsqr; double rsqr; ClosedFormRootFinder cfrf; public ClipToTorus() { this( 1.0, 1.0 ); } public ClipToTorus( double R, double r ) { super(); this.R = R; this.r = r; this.Rsqr = R * R; this.rsqr = r * r; this.cfrf = new ClosedFormRootFinder(); } public double get_R() { return R; } public double get_r() { return r; } @Override public List< Vector2d > clipRay( Ray r ) { UnivariatePolynomial x = new UnivariatePolynomial( r.o.x, r.d.x ); UnivariatePolynomial y = new UnivariatePolynomial( r.o.y, r.d.y ); UnivariatePolynomial z = new UnivariatePolynomial( r.o.z, r.d.z ); UnivariatePolynomial xsqr = x.mult( x ); UnivariatePolynomial ysqr = y.mult( y ); UnivariatePolynomial zsqr = z.mult( z ); UnivariatePolynomial torusPolynomial = xsqr.add( ysqr ).add( zsqr ).add( Rsqr-rsqr ); torusPolynomial = torusPolynomial.mult( torusPolynomial ).sub( ysqr.add( zsqr ).mult( 4 * Rsqr ) ); double[] roots = cfrf.findAllRoots( torusPolynomial ); // will return 0, 2 or 4 roots, even if there are multiple roots LinkedList< Vector2d > result = new LinkedList< Vector2d >(); for( int i = 0; i < roots.length; i += 2 ) result.add( new Vector2d( roots[ i ], roots[ i + 1 ] ) ); return result; } @Override public boolean clipPoint( Point3d p ) { double term1 = ( p.x*p.x+p.y*p.y+p.z*p.z+R*R-r*r ); return term1 * term1 <= 4 * R * R *( p.y*p.y+p.z*p.z ); } @Override public boolean pointClippingNecessary() { return false; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/rendering/cpu/clipping/Clipper.java000066400000000000000000000047731330553604100302660ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.rendering.cpu.clipping; import java.util.List; import java.util.LinkedList; import javax.vecmath.*; import de.mfo.jsurf.rendering.*; import de.mfo.jsurf.rendering.cpu.*; public abstract class Clipper { // returns sorted list of disjoint intervals public abstract List< Vector2d > clipRay( Ray r ); // returns true, if the point is not clipped public abstract boolean clipPoint( Point3d p ); // returns true, if additional point clipping is necessary after ray clipping public abstract boolean pointClippingNecessary(); public List< Vector2d > clipRay( Ray r, Vector2d interval ) { List< Vector2d > intervals = clipRay( r ); LinkedList< Vector2d > trimmed_intervals = new LinkedList< Vector2d >(); for( Vector2d i : intervals ) { Vector2d trimmedInterval = intersect( i, interval ); if( trimmedInterval != null ) trimmed_intervals.add( trimmedInterval ); } return trimmed_intervals; } public boolean clipPoint( Point3d p, boolean clippedAgainstRay ) { return clippedAgainstRay && !pointClippingNecessary() ? true : clipPoint( p ); } public List< Point3d > clipPoints( List< Point3d > l ) { LinkedList< Point3d > result = new LinkedList< Point3d >(); for( Point3d p : l ) if( clipPoint( p ) ) result.add( p ); return result; } public List< Point3d > clipPoints( List< Point3d > l, boolean clippedAgainstRay ) { return clippedAgainstRay && !pointClippingNecessary() ? l : clipPoints( l ); } // set intersection of both intervals, i1 will be overwritten // return null, if intervals are disjoint static Vector2d intersect( Vector2d i1, Vector2d i2 ) { i1.x = Math.max( i1.x, i2.x ); i1.y = Math.min( i1.y, i2.y ); return i1.y < i1.x ? null : i1; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/util/000077500000000000000000000000001330553604100224165ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/util/BasicIO.java000066400000000000000000000054421330553604100245370ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.util; import java.util.Locale; import java.util.Scanner; import javax.vecmath.*; public class BasicIO { public static String toString( Tuple3d t ) { return t.x + " " + t.y + " " + t.z; } public static String toString( Tuple3f t ) { return t.x + " " + t.y + " " + t.z; } public static Color3f fromColor3fString( String s ) { Scanner scanner = new Scanner( s ); scanner.useLocale(Locale.US); Color3f c = new Color3f(); c.x = scanner.nextFloat(); c.y = scanner.nextFloat(); c.z = scanner.nextFloat(); return c; } public static Point3d fromPoint3dString( String s ) { Scanner scanner = new Scanner( s ); scanner.useLocale(Locale.US); Point3d c = new Point3d(); c.x = scanner.nextDouble(); c.y = scanner.nextDouble(); c.z = scanner.nextDouble(); return c; } public static Vector3d fromVector3dString( String s ) { return new Vector3d( fromPoint3dString( s ) ); } public static String toString( Matrix4d m ) { return m.m00 + " " + m.m01 + " " + m.m02 + " " + m.m03 + " " + m.m10 + " " + m.m11 + " " + m.m12 + " " + m.m13 + " " + m.m20 + " " + m.m21 + " " + m.m22 + " " + m.m23 + " " + m.m30 + " " + m.m31 + " " + m.m32 + " " + m.m33; } public static Matrix4d fromMatrix4dString( String s ) { Scanner scanner = new Scanner( s ); scanner.useLocale(Locale.US); Matrix4d m = new Matrix4d(); m.m00 = scanner.nextDouble(); m.m01 = scanner.nextDouble(); m.m02 = scanner.nextDouble(); m.m03 = scanner.nextDouble(); m.m10 = scanner.nextDouble(); m.m11 = scanner.nextDouble(); m.m12 = scanner.nextDouble(); m.m13 = scanner.nextDouble(); m.m20 = scanner.nextDouble(); m.m21 = scanner.nextDouble(); m.m22 = scanner.nextDouble(); m.m23 = scanner.nextDouble(); m.m30 = scanner.nextDouble(); m.m31 = scanner.nextDouble(); m.m32 = scanner.nextDouble(); m.m33 = scanner.nextDouble(); return m; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/util/FileFormat.java000066400000000000000000000117461330553604100253220ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.util; import java.util.Map; import java.util.Properties; import java.util.Set; import javax.vecmath.Matrix3d; import javax.vecmath.Matrix4d; import de.mfo.jsurf.rendering.AlgebraicSurfaceRenderer; import de.mfo.jsurf.rendering.LightSource; public class FileFormat { public static Properties addDefaults( Properties jsurf, Properties defaults ) { Properties result = new Properties( jsurf ); for( Map.Entry me : defaults.entrySet() ) { if( !jsurf.containsKey( me.getKey() ) ) jsurf.setProperty( ( String ) me.getKey(), ( String ) me.getValue() ); } return jsurf; } public static void load( Properties jsurf, AlgebraicSurfaceRenderer asr ) throws Exception { asr.setSurfaceFamily( jsurf.getProperty( "surface_equation" ) ); Set< Map.Entry< Object, Object > > entries = jsurf.entrySet(); String parameter_key_prefix = "surface_parameter_"; for( Map.Entry< Object, Object > entry : entries ) { String name = (String) entry.getKey(); if( name.startsWith( parameter_key_prefix ) ) { String parameterName = name.substring( parameter_key_prefix.length() ); asr.setParameterValue( parameterName, Float.parseFloat( ( String ) entry.getValue() ) ); } } asr.getCamera().loadProperties( jsurf, "camera_", "" ); asr.getFrontMaterial().loadProperties(jsurf, "front_material_", ""); asr.getBackMaterial().loadProperties(jsurf, "back_material_", ""); for( int i = 0; i < AlgebraicSurfaceRenderer.MAX_LIGHTS; i++ ) { asr.getLightSource( i ).setStatus(LightSource.Status.OFF); asr.getLightSource( i ).loadProperties( jsurf, "light_", "_" + i ); } asr.setBackgroundColor( BasicIO.fromColor3fString( jsurf.getProperty( "background_color" ) ) ); Matrix4d transform; try { transform = BasicIO.fromMatrix4dString( jsurf.getProperty( "transform_matrix" ) ); } catch( Exception e ) { // if the property isn't there initialize with identity matrix transform = new Matrix4d(); transform.setIdentity(); } try { Matrix4d rotation_matrix = BasicIO.fromMatrix4dString( jsurf.getProperty( "rotation_matrix" ) ); transform.mul( rotation_matrix ); } catch( Exception e ) { } asr.setTransform( transform ); Matrix4d surface_transform; try { surface_transform = BasicIO.fromMatrix4dString( jsurf.getProperty( "surface_transform_matrix" ) ); } catch( Exception e ) { // if the property isn't there initialize with identity matrix surface_transform = new Matrix4d(); surface_transform.setIdentity(); } try { Matrix4d scale_matrix = new Matrix4d(); scale_matrix.setIdentity(); scale_matrix.setScale( Math.pow( 10, Double.parseDouble( jsurf.getProperty( "scale_factor" ) ) ) ); surface_transform.mul( scale_matrix ); } catch( Exception e ) { } asr.setSurfaceTransform( surface_transform ); } public static Properties save( AlgebraicSurfaceRenderer asr ) { Properties jsurf = new Properties(); jsurf.setProperty( "surface_equation", asr.getSurfaceFamilyString() ); Set< String > paramNames = asr.getAllParameterNames(); for( String paramName : paramNames ) { try { jsurf.setProperty( "surface_parameter_" + paramName, "" + asr.getParameterValue( paramName ) ); } catch( Exception e ) {} } asr.getCamera().saveProperties( jsurf, "camera_", "" ); asr.getFrontMaterial().saveProperties(jsurf, "front_material_", ""); asr.getBackMaterial().saveProperties(jsurf, "back_material_", ""); for( int i = 0; i < AlgebraicSurfaceRenderer.MAX_LIGHTS; i++ ) asr.getLightSource( i ).saveProperties( jsurf, "light_", "_" + i ); jsurf.setProperty( "background_color", BasicIO.toString( asr.getBackgroundColor() ) ); jsurf.setProperty( "transform_matrix", BasicIO.toString( asr.getTransform() ) ); jsurf.setProperty( "surface_transform_matrix", BasicIO.toString( asr.getSurfaceTransform() ) ); return jsurf; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/util/RotateSphericalDragger.java000066400000000000000000000045251330553604100276540ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.util; import java.awt.Point; import javax.vecmath.*; public class RotateSphericalDragger { Point lastLocation; Matrix4d rotation; double xSpeed; double ySpeed; boolean isDragging; public RotateSphericalDragger() { this( 1, 1 ); } public RotateSphericalDragger( double xSpeed, double ySpeed ) { isDragging = false; lastLocation = new Point(); rotation = new Matrix4d(); rotation.setIdentity(); this.xSpeed = xSpeed; this.ySpeed = ySpeed; } public void startDrag( Point p ) { isDragging = true; lastLocation = new Point( p ); } public void dragTo( Point p ) { if( !isDragging ) return; double xAngle = ( lastLocation.x - p.x ) * xSpeed; double yAngle = ( lastLocation.y - p.y ) * ySpeed; Matrix4d rotX = new Matrix4d(); rotX.setIdentity(); rotX.rotX( ( Math.PI / 180.0 ) * yAngle ); Matrix4d rotY = new Matrix4d(); rotY.setIdentity(); rotY.rotY( ( Math.PI / 180.0 ) * xAngle ); rotation.mul( rotX ); rotation.mul( rotY ); lastLocation = new Point( p ); } public void stopDrag() { isDragging = false; } public Matrix4d getRotation() { return new Matrix4d( rotation ); } public void setRotation( Matrix4d m ) { rotation = new Matrix4d( m ); } public double getXSpeed() { return xSpeed; } public void setXSpeed( double xSpeed ) { this.xSpeed = xSpeed; } public double getYSpeed() { return ySpeed; } public void setYSpeed( double ySpeed ) { this.ySpeed = ySpeed; } } jsurf-alggeo-0.4.1+ds/src/main/java/de/mfo/jsurf/util/Texify.java000077500000000000000000000057771330553604100245540ustar00rootroot00000000000000/* * Copyright 2008 Christian Stussak * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.mfo.jsurf.util; public class Texify { private static int matchParenthesis( StringBuffer sb, int par_pos ) { int par_count = 1; for( ; par_pos < sb.length(); par_pos++ ) { if( sb.charAt( par_pos ) == '(' ) par_count++; else if ( sb.charAt( par_pos ) == ')' ) par_count--; //System.out.println( sb.charAt( par_pos ) + " at " + par_pos + " gives " +par_count ); if( par_count == 0 ) break; } return par_pos < sb.length() ? par_pos : -1; } public static String texify( String s ) { // remove whitespace s = s.replaceAll( "\\p{Space}", "" ); // special treatment of sqrt StringBuffer sb = new StringBuffer( s ); int sqrt_pos = 0; while( ( sqrt_pos = sb.indexOf( "sqrt(", sqrt_pos ) ) != -1 ) { int par_pos = matchParenthesis( sb, sqrt_pos + 5 ); if( par_pos != -1 ) { sb.setCharAt( sqrt_pos + 4, '{' ); sb.setCharAt( par_pos, '}' ); } sqrt_pos++; } // special treatment of ^(...) int exp_pos = 0; while( ( exp_pos = sb.indexOf( "^(", exp_pos ) ) != -1 ) { int par_pos = matchParenthesis( sb, exp_pos + 2 ); if( par_pos != -1 ) { sb.setCharAt( exp_pos + 1, '{' ); sb.setCharAt( par_pos, '}' ); } exp_pos++; } s = sb.toString(); // texify paranthesis s = s.replaceAll( "([a-zA-Z]+)\\(", "{$1(" ); // opname(...) -> {opname(...)} s = s.replaceAll( "([+-/\\*\\^])\\(", "$1{(" ); // infixop( -> infixop{( while( s.matches( ".*\\(\\(.*" ) ) { s = s.replaceAll( "\\(\\(", "({(" ); // (( --> ({( } s = s.replaceAll( "^\\(", "{(" ); // ( at beginning -> {( s = s.replaceAll( "\\)", ")}" ); // ) -> )} s = s.replaceAll( "\\(", "\\\\left(" ); s = s.replaceAll( "\\)", "\\\\right)" ); // replace * s = s.replaceAll( "\\*", "\\\\cdot{}" ); // texify numerical exponents s = s.replaceAll( "\\^(\\d+)", "\\^{$1}" ); // texify special operators String[] ops1 = { "sin", "cos", "tan", "exp", "log", "sqrt" }; String[] ops2 = { "neg", "ceil", "floor", "abs", "sign", "atan2" }; String[] ops3 = { "asin", "acos", "atan" }; for( int i = 0; i < ops1.length; i++ ) s = s.replaceAll( ops1[ i ], "\\\\" + ops1[ i ] ); for( int i = 0; i < ops2.length; i++ ) s = s.replaceAll( ops2[ i ], "\\\\operatorname{" + ops1[ i ] + "}" ); for( int i = 0; i < ops3.length; i++ ) s = s.replaceAll( ops3[ i ], "\\\\" + ops1[ i ] + "^{-1}" ); return "\\ensuremath{" + s + "}"; } } jsurf-alggeo-0.4.1+ds/src/test/000077500000000000000000000000001330553604100162515ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/test/java/000077500000000000000000000000001330553604100171725ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/test/java/de/000077500000000000000000000000001330553604100175625ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/test/java/de/mfo/000077500000000000000000000000001330553604100203435ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/test/java/de/mfo/jsurf/000077500000000000000000000000001330553604100214745ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/test/java/de/mfo/jsurf/test/000077500000000000000000000000001330553604100224535ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/test/java/de/mfo/jsurf/test/TestJSurf.java000066400000000000000000000074701330553604100252170ustar00rootroot00000000000000package de.mfo.jsurf.test; import org.junit.*; import de.mfo.jsurf.rendering.cpu.CPUAlgebraicSurfaceRenderer; import de.mfo.jsurf.rendering.RenderingInterruptedException; import de.mfo.jsurf.algebra.*; import de.mfo.jsurf.parser.*; import de.mfo.jsurf.util.FileFormat; import java.util.Properties; import javax.swing.SwingWorker; public class TestJSurf { @Test public void stopDrawingShouldInterruptRendering() throws java.io.IOException, Exception { final CPUAlgebraicSurfaceRenderer asr = new CPUAlgebraicSurfaceRenderer(); Properties jsurf = new Properties(); jsurf.load( this.getClass().getResourceAsStream( "tutorial_wuerfel.jsurf" ) ); FileFormat.load( jsurf, asr ); final int width = 1024; final int height = 1024; class BackgroundRenderer extends SwingWorker< Void, Void > { @Override public Void doInBackground() { try { asr.draw( new int[ 3 * width * height ], width, height ); } catch( RenderingInterruptedException rie ) { System.out.println( "Rendering interrupted" ); } return null; } } BackgroundRenderer br = new BackgroundRenderer(); System.out.println( "Starting background rendering" ); br.execute(); long t = System.currentTimeMillis(); Thread.sleep( 100 ); System.out.println( "Attempting to stop rendering" ); asr.stopDrawing(); br.get(); t = System.currentTimeMillis() - t; System.out.println( "Render method finished after " + t + "ms" ); Assert.assertTrue( "stopDrawing must interrupt and stop the rendering process", t < 200 ); } @Test public void XYZPolynomialAddShouldNotAffectMethodParameters() { XYZPolynomial X = new XYZPolynomial( XYZPolynomial.X ); XYZPolynomial.X.add( XYZPolynomial.X ); Assert.assertTrue( "XYZPolynomial.add changes values of its parameters", X.equals( XYZPolynomial.X ) ); } @Test public void testDivisionInParser() { PolynomialOperation div = new PolynomialDoubleDivision( new PolynomialVariable( PolynomialVariable.Var.x ), new DoubleValue( 2.0 ) ); PolynomialOperation mult = new PolynomialMultiplication( new PolynomialVariable( PolynomialVariable.Var.x ), new DoubleValue( 0.5 ) ); XYZPolynomial expanded_div = div.accept( new Expand(), ( Void ) null ); XYZPolynomial expanded_mult = mult.accept( new Expand(), ( Void ) null ); Assert.assertTrue( "x/2.0 and x*0.5 should both expand to 0.5x, but x/2.0 expands to " + expanded_div + " and x*0.5 expands to " + expanded_mult, expanded_div.equals( expanded_mult ) ); } @Test public void testIfParenthesesAreCorrectlyRecognized() throws Exception { String input = "(x)"; PolynomialOperation op = AlgebraicExpressionParser.parse( input ); Assert.assertNotNull( "op must not be null", op ); Assert.assertTrue( "Tree node should have parentheses", op.hasParentheses() ); } @Test public void testParserInputAndToStringVisitorOutputShouldMatch() throws Exception { String[] inputs = { "x-(x)", "sin(1)", "x+y+z+x*(y+x)", "a*0.99*(64*(0.5*z)^7-112*(0.5*z)^5+56*(0.5*z)^3-7*(0.5*z)-1)+(0.7818314825-0.3765101982*y-0.7818314825*x)*(0.7818314824-0.8460107361*y-0.1930964297*x)*(0.7818314825-0.6784479340*y+0.5410441731*x)*(0.7818314825+0.8677674789*x)*(0.7818314824+0.6784479339*y+0.541044172*x)*(0.7818314824+0.8460107358*y-0.193096429*x)*(0.7818314821+0.3765101990*y-0.781831483*x)" }; for( String input : inputs ) { String output = AlgebraicExpressionParser.parse( input ).accept( new ToStringVisitor( true ), ( Void ) null ); Assert.assertEquals( "Output of ToStringVisitor should be identical to input", input, output ); } } } jsurf-alggeo-0.4.1+ds/src/test/resources/000077500000000000000000000000001330553604100202635ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/test/resources/de/000077500000000000000000000000001330553604100206535ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/test/resources/de/mfo/000077500000000000000000000000001330553604100214345ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/test/resources/de/mfo/jsurf/000077500000000000000000000000001330553604100225655ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/test/resources/de/mfo/jsurf/test/000077500000000000000000000000001330553604100235445ustar00rootroot00000000000000jsurf-alggeo-0.4.1+ds/src/test/resources/de/mfo/jsurf/test/tutorial_wuerfel.jsurf000066400000000000000000000031071330553604100302140ustar00rootroot00000000000000#jSurfer surface description #Fri Jul 08 17:07:01 CEST 2011 front_material_specular_iIntensity=0.5 camera_type=ORTHOGRAPHIC_CAMERA back_material_specular_iIntensity=0.5 light_position_7=0.0 0.0 0.0 light_position_6=0.0 0.0 0.0 light_position_5=0.0 0.0 0.0 light_position_4=0.0 0.0 0.0 light_position_3=0.0 0.0 0.0 light_position_2=0.0 -100.0 100.0 camera_fov_y=60.0 light_position_1=100.0 100.0 100.0 light_position_0=-100.0 100.0 100.0 front_material_color=0.92156863 0.27058825 0.06666667 background_color=1.0 1.0 1.0 light_intensity_7=1.0 front_material_ambient_intensity=0.4 light_intensity_6=1.0 scale_factor=0.2202897 light_intensity_5=1.0 light_intensity_4=1.0 light_intensity_3=1.0 light_intensity_2=0.3 light_intensity_1=0.7 light_intensity_0=0.5 rotation_matrix=0.6629907 -0.35071582 -0.6613998 0.0 -0.4165067 0.56132054 -0.715156 0.0 0.6220731 0.74961746 0.22607408 0.0 0.0 0.0 0.0 1.0 light_color_7=1.0 1.0 1.0 light_color_6=1.0 1.0 1.0 front_material_diffuse_intensity=0.8 light_color_5=1.0 1.0 1.0 light_color_4=1.0 1.0 1.0 light_color_3=1.0 1.0 1.0 light_color_2=1.0 1.0 1.0 light_color_1=1.0 1.0 1.0 light_color_0=1.0 1.0 1.0 light_status_7=OFF light_status_6=OFF light_status_5=OFF light_status_4=OFF front_material_shininess=30.0 light_status_3=OFF light_status_2=ON light_status_1=ON light_status_0=ON camera_height=2.0 surface_equation=x^6+y^6+z^6-1 camera_transform=1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -1.0 0.0 0.0 0.0 1.0 back_material_ambient_intensity=0.4 back_material_color=0.7019608 0.39607844 0.16470589 back_material_shininess=30.0 back_material_diffuse_intensity=0.8