vispy 0.15.0__cp313-cp313-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of vispy might be problematic. Click here for more details.
- vispy/__init__.py +33 -0
- vispy/app/__init__.py +15 -0
- vispy/app/_default_app.py +76 -0
- vispy/app/_detect_eventloop.py +148 -0
- vispy/app/application.py +263 -0
- vispy/app/backends/__init__.py +52 -0
- vispy/app/backends/_egl.py +264 -0
- vispy/app/backends/_glfw.py +513 -0
- vispy/app/backends/_jupyter_rfb.py +278 -0
- vispy/app/backends/_offscreen_util.py +121 -0
- vispy/app/backends/_osmesa.py +235 -0
- vispy/app/backends/_pyglet.py +451 -0
- vispy/app/backends/_pyqt4.py +36 -0
- vispy/app/backends/_pyqt5.py +36 -0
- vispy/app/backends/_pyqt6.py +40 -0
- vispy/app/backends/_pyside.py +37 -0
- vispy/app/backends/_pyside2.py +52 -0
- vispy/app/backends/_pyside6.py +53 -0
- vispy/app/backends/_qt.py +1003 -0
- vispy/app/backends/_sdl2.py +444 -0
- vispy/app/backends/_template.py +244 -0
- vispy/app/backends/_test.py +8 -0
- vispy/app/backends/_tk.py +800 -0
- vispy/app/backends/_wx.py +476 -0
- vispy/app/backends/tests/__init__.py +0 -0
- vispy/app/backends/tests/test_offscreen_util.py +52 -0
- vispy/app/backends/tests/test_rfb.py +77 -0
- vispy/app/base.py +294 -0
- vispy/app/canvas.py +828 -0
- vispy/app/qt.py +92 -0
- vispy/app/tests/__init__.py +0 -0
- vispy/app/tests/qt-designer.ui +58 -0
- vispy/app/tests/test_app.py +442 -0
- vispy/app/tests/test_backends.py +164 -0
- vispy/app/tests/test_canvas.py +122 -0
- vispy/app/tests/test_context.py +92 -0
- vispy/app/tests/test_qt.py +47 -0
- vispy/app/tests/test_simultaneous.py +134 -0
- vispy/app/timer.py +174 -0
- vispy/color/__init__.py +17 -0
- vispy/color/_color_dict.py +193 -0
- vispy/color/color_array.py +447 -0
- vispy/color/color_space.py +181 -0
- vispy/color/colormap.py +1213 -0
- vispy/color/tests/__init__.py +0 -0
- vispy/color/tests/test_color.py +378 -0
- vispy/conftest.py +12 -0
- vispy/ext/__init__.py +0 -0
- vispy/ext/cocoapy.py +1522 -0
- vispy/ext/cubehelix.py +138 -0
- vispy/ext/egl.py +375 -0
- vispy/ext/fontconfig.py +118 -0
- vispy/ext/gdi32plus.py +206 -0
- vispy/ext/osmesa.py +105 -0
- vispy/geometry/__init__.py +23 -0
- vispy/geometry/_triangulation_debugger.py +171 -0
- vispy/geometry/calculations.py +162 -0
- vispy/geometry/curves.py +399 -0
- vispy/geometry/generation.py +643 -0
- vispy/geometry/isocurve.py +175 -0
- vispy/geometry/isosurface.py +465 -0
- vispy/geometry/meshdata.py +700 -0
- vispy/geometry/normals.py +78 -0
- vispy/geometry/parametric.py +56 -0
- vispy/geometry/polygon.py +137 -0
- vispy/geometry/rect.py +210 -0
- vispy/geometry/tests/__init__.py +0 -0
- vispy/geometry/tests/test_calculations.py +23 -0
- vispy/geometry/tests/test_generation.py +56 -0
- vispy/geometry/tests/test_meshdata.py +106 -0
- vispy/geometry/tests/test_triangulation.py +594 -0
- vispy/geometry/torusknot.py +142 -0
- vispy/geometry/triangulation.py +876 -0
- vispy/gloo/__init__.py +56 -0
- vispy/gloo/buffer.py +505 -0
- vispy/gloo/context.py +272 -0
- vispy/gloo/framebuffer.py +257 -0
- vispy/gloo/gl/__init__.py +234 -0
- vispy/gloo/gl/_constants.py +332 -0
- vispy/gloo/gl/_es2.py +986 -0
- vispy/gloo/gl/_gl2.py +1365 -0
- vispy/gloo/gl/_proxy.py +499 -0
- vispy/gloo/gl/_pyopengl2.py +362 -0
- vispy/gloo/gl/dummy.py +24 -0
- vispy/gloo/gl/es2.py +62 -0
- vispy/gloo/gl/gl2.py +98 -0
- vispy/gloo/gl/glplus.py +168 -0
- vispy/gloo/gl/pyopengl2.py +97 -0
- vispy/gloo/gl/tests/__init__.py +0 -0
- vispy/gloo/gl/tests/test_basics.py +282 -0
- vispy/gloo/gl/tests/test_functionality.py +568 -0
- vispy/gloo/gl/tests/test_names.py +246 -0
- vispy/gloo/gl/tests/test_use.py +71 -0
- vispy/gloo/glir.py +1824 -0
- vispy/gloo/globject.py +101 -0
- vispy/gloo/preprocessor.py +67 -0
- vispy/gloo/program.py +543 -0
- vispy/gloo/tests/__init__.py +0 -0
- vispy/gloo/tests/test_buffer.py +558 -0
- vispy/gloo/tests/test_context.py +119 -0
- vispy/gloo/tests/test_framebuffer.py +195 -0
- vispy/gloo/tests/test_glir.py +307 -0
- vispy/gloo/tests/test_globject.py +35 -0
- vispy/gloo/tests/test_program.py +302 -0
- vispy/gloo/tests/test_texture.py +732 -0
- vispy/gloo/tests/test_use_gloo.py +187 -0
- vispy/gloo/tests/test_util.py +60 -0
- vispy/gloo/tests/test_wrappers.py +261 -0
- vispy/gloo/texture.py +1046 -0
- vispy/gloo/util.py +129 -0
- vispy/gloo/wrappers.py +762 -0
- vispy/glsl/__init__.py +42 -0
- vispy/glsl/antialias/antialias.glsl +7 -0
- vispy/glsl/antialias/cap-butt.glsl +31 -0
- vispy/glsl/antialias/cap-round.glsl +29 -0
- vispy/glsl/antialias/cap-square.glsl +30 -0
- vispy/glsl/antialias/cap-triangle-in.glsl +30 -0
- vispy/glsl/antialias/cap-triangle-out.glsl +30 -0
- vispy/glsl/antialias/cap.glsl +67 -0
- vispy/glsl/antialias/caps.glsl +67 -0
- vispy/glsl/antialias/filled.glsl +50 -0
- vispy/glsl/antialias/outline.glsl +40 -0
- vispy/glsl/antialias/stroke.glsl +43 -0
- vispy/glsl/arrowheads/angle.glsl +99 -0
- vispy/glsl/arrowheads/arrowheads.frag +60 -0
- vispy/glsl/arrowheads/arrowheads.glsl +12 -0
- vispy/glsl/arrowheads/arrowheads.vert +83 -0
- vispy/glsl/arrowheads/curved.glsl +48 -0
- vispy/glsl/arrowheads/inhibitor.glsl +26 -0
- vispy/glsl/arrowheads/stealth.glsl +46 -0
- vispy/glsl/arrowheads/triangle.glsl +97 -0
- vispy/glsl/arrowheads/util.glsl +13 -0
- vispy/glsl/arrows/angle-30.glsl +12 -0
- vispy/glsl/arrows/angle-60.glsl +12 -0
- vispy/glsl/arrows/angle-90.glsl +12 -0
- vispy/glsl/arrows/arrow.frag +39 -0
- vispy/glsl/arrows/arrow.vert +49 -0
- vispy/glsl/arrows/arrows.glsl +17 -0
- vispy/glsl/arrows/common.glsl +187 -0
- vispy/glsl/arrows/curved.glsl +63 -0
- vispy/glsl/arrows/stealth.glsl +50 -0
- vispy/glsl/arrows/triangle-30.glsl +12 -0
- vispy/glsl/arrows/triangle-60.glsl +12 -0
- vispy/glsl/arrows/triangle-90.glsl +12 -0
- vispy/glsl/arrows/util.glsl +98 -0
- vispy/glsl/build_spatial_filters.py +660 -0
- vispy/glsl/collections/agg-fast-path.frag +20 -0
- vispy/glsl/collections/agg-fast-path.vert +78 -0
- vispy/glsl/collections/agg-glyph.frag +60 -0
- vispy/glsl/collections/agg-glyph.vert +33 -0
- vispy/glsl/collections/agg-marker.frag +35 -0
- vispy/glsl/collections/agg-marker.vert +48 -0
- vispy/glsl/collections/agg-path.frag +55 -0
- vispy/glsl/collections/agg-path.vert +166 -0
- vispy/glsl/collections/agg-point.frag +21 -0
- vispy/glsl/collections/agg-point.vert +35 -0
- vispy/glsl/collections/agg-segment.frag +32 -0
- vispy/glsl/collections/agg-segment.vert +75 -0
- vispy/glsl/collections/marker.frag +38 -0
- vispy/glsl/collections/marker.vert +48 -0
- vispy/glsl/collections/raw-path.frag +15 -0
- vispy/glsl/collections/raw-path.vert +24 -0
- vispy/glsl/collections/raw-point.frag +14 -0
- vispy/glsl/collections/raw-point.vert +31 -0
- vispy/glsl/collections/raw-segment.frag +18 -0
- vispy/glsl/collections/raw-segment.vert +26 -0
- vispy/glsl/collections/raw-triangle.frag +13 -0
- vispy/glsl/collections/raw-triangle.vert +26 -0
- vispy/glsl/collections/sdf-glyph-ticks.vert +69 -0
- vispy/glsl/collections/sdf-glyph.frag +80 -0
- vispy/glsl/collections/sdf-glyph.vert +59 -0
- vispy/glsl/collections/tick-labels.vert +71 -0
- vispy/glsl/colormaps/autumn.glsl +20 -0
- vispy/glsl/colormaps/blues.glsl +20 -0
- vispy/glsl/colormaps/color-space.glsl +17 -0
- vispy/glsl/colormaps/colormaps.glsl +24 -0
- vispy/glsl/colormaps/cool.glsl +20 -0
- vispy/glsl/colormaps/fire.glsl +21 -0
- vispy/glsl/colormaps/gray.glsl +20 -0
- vispy/glsl/colormaps/greens.glsl +20 -0
- vispy/glsl/colormaps/hot.glsl +22 -0
- vispy/glsl/colormaps/ice.glsl +20 -0
- vispy/glsl/colormaps/icefire.glsl +23 -0
- vispy/glsl/colormaps/parse.py +40 -0
- vispy/glsl/colormaps/reds.glsl +20 -0
- vispy/glsl/colormaps/spring.glsl +20 -0
- vispy/glsl/colormaps/summer.glsl +20 -0
- vispy/glsl/colormaps/user.glsl +22 -0
- vispy/glsl/colormaps/util.glsl +41 -0
- vispy/glsl/colormaps/wheel.glsl +21 -0
- vispy/glsl/colormaps/winter.glsl +20 -0
- vispy/glsl/lines/agg.frag +320 -0
- vispy/glsl/lines/agg.vert +241 -0
- vispy/glsl/markers/arrow.glsl +12 -0
- vispy/glsl/markers/asterisk.glsl +16 -0
- vispy/glsl/markers/chevron.glsl +14 -0
- vispy/glsl/markers/clover.glsl +20 -0
- vispy/glsl/markers/club.glsl +31 -0
- vispy/glsl/markers/cross.glsl +17 -0
- vispy/glsl/markers/diamond.glsl +12 -0
- vispy/glsl/markers/disc.glsl +9 -0
- vispy/glsl/markers/ellipse.glsl +67 -0
- vispy/glsl/markers/hbar.glsl +9 -0
- vispy/glsl/markers/heart.glsl +15 -0
- vispy/glsl/markers/infinity.glsl +15 -0
- vispy/glsl/markers/marker-sdf.frag +74 -0
- vispy/glsl/markers/marker-sdf.vert +41 -0
- vispy/glsl/markers/marker.frag +36 -0
- vispy/glsl/markers/marker.vert +46 -0
- vispy/glsl/markers/markers.glsl +24 -0
- vispy/glsl/markers/pin.glsl +18 -0
- vispy/glsl/markers/ring.glsl +11 -0
- vispy/glsl/markers/spade.glsl +28 -0
- vispy/glsl/markers/square.glsl +10 -0
- vispy/glsl/markers/tag.glsl +11 -0
- vispy/glsl/markers/triangle.glsl +14 -0
- vispy/glsl/markers/vbar.glsl +9 -0
- vispy/glsl/math/circle-through-2-points.glsl +30 -0
- vispy/glsl/math/constants.glsl +48 -0
- vispy/glsl/math/double.glsl +114 -0
- vispy/glsl/math/functions.glsl +20 -0
- vispy/glsl/math/point-to-line-distance.glsl +31 -0
- vispy/glsl/math/point-to-line-projection.glsl +29 -0
- vispy/glsl/math/signed-line-distance.glsl +27 -0
- vispy/glsl/math/signed-segment-distance.glsl +30 -0
- vispy/glsl/misc/regular-grid.frag +244 -0
- vispy/glsl/misc/spatial-filters.frag +1407 -0
- vispy/glsl/misc/viewport-NDC.glsl +20 -0
- vispy/glsl/transforms/azimuthal-equal-area.glsl +32 -0
- vispy/glsl/transforms/azimuthal-equidistant.glsl +38 -0
- vispy/glsl/transforms/hammer.glsl +44 -0
- vispy/glsl/transforms/identity.glsl +6 -0
- vispy/glsl/transforms/identity_forward.glsl +23 -0
- vispy/glsl/transforms/identity_inverse.glsl +23 -0
- vispy/glsl/transforms/linear-scale.glsl +127 -0
- vispy/glsl/transforms/log-scale.glsl +126 -0
- vispy/glsl/transforms/mercator-transverse-forward.glsl +40 -0
- vispy/glsl/transforms/mercator-transverse-inverse.glsl +40 -0
- vispy/glsl/transforms/panzoom.glsl +10 -0
- vispy/glsl/transforms/polar.glsl +41 -0
- vispy/glsl/transforms/position.glsl +44 -0
- vispy/glsl/transforms/power-scale.glsl +139 -0
- vispy/glsl/transforms/projection.glsl +7 -0
- vispy/glsl/transforms/pvm.glsl +13 -0
- vispy/glsl/transforms/rotate.glsl +45 -0
- vispy/glsl/transforms/trackball.glsl +15 -0
- vispy/glsl/transforms/translate.glsl +35 -0
- vispy/glsl/transforms/transverse_mercator.glsl +38 -0
- vispy/glsl/transforms/viewport-clipping.glsl +14 -0
- vispy/glsl/transforms/viewport-transform.glsl +16 -0
- vispy/glsl/transforms/viewport.glsl +50 -0
- vispy/glsl/transforms/x.glsl +24 -0
- vispy/glsl/transforms/y.glsl +19 -0
- vispy/glsl/transforms/z.glsl +14 -0
- vispy/io/__init__.py +20 -0
- vispy/io/_data/spatial-filters.npy +0 -0
- vispy/io/datasets.py +94 -0
- vispy/io/image.py +231 -0
- vispy/io/mesh.py +122 -0
- vispy/io/stl.py +167 -0
- vispy/io/tests/__init__.py +0 -0
- vispy/io/tests/test_image.py +47 -0
- vispy/io/tests/test_io.py +121 -0
- vispy/io/wavefront.py +350 -0
- vispy/plot/__init__.py +36 -0
- vispy/plot/fig.py +58 -0
- vispy/plot/plotwidget.py +522 -0
- vispy/plot/tests/__init__.py +0 -0
- vispy/plot/tests/test_plot.py +46 -0
- vispy/scene/__init__.py +43 -0
- vispy/scene/cameras/__init__.py +27 -0
- vispy/scene/cameras/_base.py +38 -0
- vispy/scene/cameras/arcball.py +105 -0
- vispy/scene/cameras/base_camera.py +551 -0
- vispy/scene/cameras/fly.py +474 -0
- vispy/scene/cameras/magnify.py +163 -0
- vispy/scene/cameras/panzoom.py +311 -0
- vispy/scene/cameras/perspective.py +338 -0
- vispy/scene/cameras/tests/__init__.py +0 -0
- vispy/scene/cameras/tests/test_cameras.py +27 -0
- vispy/scene/cameras/tests/test_link.py +53 -0
- vispy/scene/cameras/tests/test_perspective.py +122 -0
- vispy/scene/cameras/turntable.py +183 -0
- vispy/scene/canvas.py +639 -0
- vispy/scene/events.py +85 -0
- vispy/scene/node.py +644 -0
- vispy/scene/subscene.py +20 -0
- vispy/scene/tests/__init__.py +0 -0
- vispy/scene/tests/test_canvas.py +119 -0
- vispy/scene/tests/test_node.py +142 -0
- vispy/scene/tests/test_visuals.py +141 -0
- vispy/scene/visuals.py +276 -0
- vispy/scene/widgets/__init__.py +18 -0
- vispy/scene/widgets/anchor.py +25 -0
- vispy/scene/widgets/axis.py +88 -0
- vispy/scene/widgets/colorbar.py +176 -0
- vispy/scene/widgets/console.py +351 -0
- vispy/scene/widgets/grid.py +509 -0
- vispy/scene/widgets/label.py +50 -0
- vispy/scene/widgets/tests/__init__.py +0 -0
- vispy/scene/widgets/tests/test_colorbar.py +47 -0
- vispy/scene/widgets/viewbox.py +199 -0
- vispy/scene/widgets/widget.py +478 -0
- vispy/testing/__init__.py +51 -0
- vispy/testing/_runners.py +448 -0
- vispy/testing/_testing.py +416 -0
- vispy/testing/image_tester.py +494 -0
- vispy/testing/rendered_array_tester.py +85 -0
- vispy/testing/tests/__init__.py +0 -0
- vispy/testing/tests/test_testing.py +20 -0
- vispy/util/__init__.py +32 -0
- vispy/util/bunch.py +15 -0
- vispy/util/check_environment.py +57 -0
- vispy/util/config.py +490 -0
- vispy/util/dpi/__init__.py +19 -0
- vispy/util/dpi/_linux.py +69 -0
- vispy/util/dpi/_quartz.py +26 -0
- vispy/util/dpi/_win32.py +34 -0
- vispy/util/dpi/tests/__init__.py +0 -0
- vispy/util/dpi/tests/test_dpi.py +16 -0
- vispy/util/eq.py +41 -0
- vispy/util/event.py +774 -0
- vispy/util/fetching.py +276 -0
- vispy/util/filter.py +44 -0
- vispy/util/fonts/__init__.py +14 -0
- vispy/util/fonts/_freetype.py +73 -0
- vispy/util/fonts/_quartz.py +192 -0
- vispy/util/fonts/_triage.py +36 -0
- vispy/util/fonts/_vispy_fonts.py +20 -0
- vispy/util/fonts/_win32.py +105 -0
- vispy/util/fonts/data/OpenSans-Bold.ttf +0 -0
- vispy/util/fonts/data/OpenSans-BoldItalic.ttf +0 -0
- vispy/util/fonts/data/OpenSans-Italic.ttf +0 -0
- vispy/util/fonts/data/OpenSans-Regular.ttf +0 -0
- vispy/util/fonts/tests/__init__.py +0 -0
- vispy/util/fonts/tests/test_font.py +45 -0
- vispy/util/fourier.py +69 -0
- vispy/util/frozen.py +25 -0
- vispy/util/gallery_scraper.py +268 -0
- vispy/util/keys.py +91 -0
- vispy/util/logs.py +358 -0
- vispy/util/osmesa_gl.py +17 -0
- vispy/util/profiler.py +135 -0
- vispy/util/ptime.py +16 -0
- vispy/util/quaternion.py +229 -0
- vispy/util/svg/__init__.py +18 -0
- vispy/util/svg/base.py +20 -0
- vispy/util/svg/color.py +219 -0
- vispy/util/svg/element.py +51 -0
- vispy/util/svg/geometry.py +478 -0
- vispy/util/svg/group.py +66 -0
- vispy/util/svg/length.py +81 -0
- vispy/util/svg/number.py +25 -0
- vispy/util/svg/path.py +332 -0
- vispy/util/svg/shapes.py +57 -0
- vispy/util/svg/style.py +59 -0
- vispy/util/svg/svg.py +40 -0
- vispy/util/svg/transform.py +223 -0
- vispy/util/svg/transformable.py +28 -0
- vispy/util/svg/viewport.py +73 -0
- vispy/util/tests/__init__.py +0 -0
- vispy/util/tests/test_config.py +58 -0
- vispy/util/tests/test_docstring_parameters.py +123 -0
- vispy/util/tests/test_emitter_group.py +262 -0
- vispy/util/tests/test_event_emitter.py +743 -0
- vispy/util/tests/test_fourier.py +35 -0
- vispy/util/tests/test_gallery_scraper.py +112 -0
- vispy/util/tests/test_import.py +127 -0
- vispy/util/tests/test_key.py +22 -0
- vispy/util/tests/test_logging.py +45 -0
- vispy/util/tests/test_run.py +14 -0
- vispy/util/tests/test_transforms.py +42 -0
- vispy/util/tests/test_vispy.py +48 -0
- vispy/util/transforms.py +201 -0
- vispy/util/wrappers.py +155 -0
- vispy/version.py +21 -0
- vispy/visuals/__init__.py +50 -0
- vispy/visuals/_scalable_textures.py +487 -0
- vispy/visuals/axis.py +678 -0
- vispy/visuals/border.py +208 -0
- vispy/visuals/box.py +79 -0
- vispy/visuals/collections/__init__.py +30 -0
- vispy/visuals/collections/agg_fast_path_collection.py +219 -0
- vispy/visuals/collections/agg_path_collection.py +197 -0
- vispy/visuals/collections/agg_point_collection.py +52 -0
- vispy/visuals/collections/agg_segment_collection.py +142 -0
- vispy/visuals/collections/array_list.py +401 -0
- vispy/visuals/collections/base_collection.py +482 -0
- vispy/visuals/collections/collection.py +253 -0
- vispy/visuals/collections/path_collection.py +23 -0
- vispy/visuals/collections/point_collection.py +19 -0
- vispy/visuals/collections/polygon_collection.py +25 -0
- vispy/visuals/collections/raw_path_collection.py +119 -0
- vispy/visuals/collections/raw_point_collection.py +113 -0
- vispy/visuals/collections/raw_polygon_collection.py +77 -0
- vispy/visuals/collections/raw_segment_collection.py +112 -0
- vispy/visuals/collections/raw_triangle_collection.py +78 -0
- vispy/visuals/collections/segment_collection.py +19 -0
- vispy/visuals/collections/triangle_collection.py +16 -0
- vispy/visuals/collections/util.py +168 -0
- vispy/visuals/colorbar.py +699 -0
- vispy/visuals/cube.py +41 -0
- vispy/visuals/ellipse.py +162 -0
- vispy/visuals/filters/__init__.py +10 -0
- vispy/visuals/filters/base_filter.py +242 -0
- vispy/visuals/filters/clipper.py +60 -0
- vispy/visuals/filters/clipping_planes.py +122 -0
- vispy/visuals/filters/color.py +181 -0
- vispy/visuals/filters/markers.py +28 -0
- vispy/visuals/filters/mesh.py +801 -0
- vispy/visuals/filters/picking.py +60 -0
- vispy/visuals/filters/tests/__init__.py +3 -0
- vispy/visuals/filters/tests/test_primitive_picking_filters.py +70 -0
- vispy/visuals/filters/tests/test_wireframe_filter.py +16 -0
- vispy/visuals/glsl/__init__.py +1 -0
- vispy/visuals/glsl/antialiasing.py +133 -0
- vispy/visuals/glsl/color.py +63 -0
- vispy/visuals/graphs/__init__.py +1 -0
- vispy/visuals/graphs/graph.py +240 -0
- vispy/visuals/graphs/layouts/__init__.py +55 -0
- vispy/visuals/graphs/layouts/circular.py +49 -0
- vispy/visuals/graphs/layouts/force_directed.py +211 -0
- vispy/visuals/graphs/layouts/networkx_layout.py +87 -0
- vispy/visuals/graphs/layouts/random.py +52 -0
- vispy/visuals/graphs/tests/__init__.py +1 -0
- vispy/visuals/graphs/tests/test_layouts.py +139 -0
- vispy/visuals/graphs/tests/test_networkx_layout.py +47 -0
- vispy/visuals/graphs/util.py +120 -0
- vispy/visuals/gridlines.py +161 -0
- vispy/visuals/gridmesh.py +98 -0
- vispy/visuals/histogram.py +58 -0
- vispy/visuals/image.py +701 -0
- vispy/visuals/image_complex.py +130 -0
- vispy/visuals/infinite_line.py +199 -0
- vispy/visuals/instanced_mesh.py +152 -0
- vispy/visuals/isocurve.py +213 -0
- vispy/visuals/isoline.py +241 -0
- vispy/visuals/isosurface.py +113 -0
- vispy/visuals/line/__init__.py +6 -0
- vispy/visuals/line/arrow.py +289 -0
- vispy/visuals/line/dash_atlas.py +90 -0
- vispy/visuals/line/line.py +545 -0
- vispy/visuals/line_plot.py +135 -0
- vispy/visuals/linear_region.py +199 -0
- vispy/visuals/markers.py +819 -0
- vispy/visuals/mesh.py +373 -0
- vispy/visuals/mesh_normals.py +159 -0
- vispy/visuals/plane.py +54 -0
- vispy/visuals/polygon.py +145 -0
- vispy/visuals/rectangle.py +196 -0
- vispy/visuals/regular_polygon.py +56 -0
- vispy/visuals/scrolling_lines.py +197 -0
- vispy/visuals/shaders/__init__.py +17 -0
- vispy/visuals/shaders/compiler.py +206 -0
- vispy/visuals/shaders/expression.py +99 -0
- vispy/visuals/shaders/function.py +788 -0
- vispy/visuals/shaders/multiprogram.py +145 -0
- vispy/visuals/shaders/parsing.py +140 -0
- vispy/visuals/shaders/program.py +161 -0
- vispy/visuals/shaders/shader_object.py +162 -0
- vispy/visuals/shaders/tests/__init__.py +0 -0
- vispy/visuals/shaders/tests/test_function.py +486 -0
- vispy/visuals/shaders/tests/test_multiprogram.py +78 -0
- vispy/visuals/shaders/tests/test_parsing.py +57 -0
- vispy/visuals/shaders/variable.py +272 -0
- vispy/visuals/spectrogram.py +169 -0
- vispy/visuals/sphere.py +80 -0
- vispy/visuals/surface_plot.py +192 -0
- vispy/visuals/tests/__init__.py +0 -0
- vispy/visuals/tests/test_arrows.py +109 -0
- vispy/visuals/tests/test_axis.py +120 -0
- vispy/visuals/tests/test_collections.py +15 -0
- vispy/visuals/tests/test_colorbar.py +179 -0
- vispy/visuals/tests/test_colormap.py +97 -0
- vispy/visuals/tests/test_ellipse.py +122 -0
- vispy/visuals/tests/test_gridlines.py +30 -0
- vispy/visuals/tests/test_histogram.py +24 -0
- vispy/visuals/tests/test_image.py +392 -0
- vispy/visuals/tests/test_image_complex.py +36 -0
- vispy/visuals/tests/test_infinite_line.py +53 -0
- vispy/visuals/tests/test_instanced_mesh.py +50 -0
- vispy/visuals/tests/test_isosurface.py +22 -0
- vispy/visuals/tests/test_linear_region.py +152 -0
- vispy/visuals/tests/test_markers.py +54 -0
- vispy/visuals/tests/test_mesh.py +261 -0
- vispy/visuals/tests/test_mesh_normals.py +218 -0
- vispy/visuals/tests/test_polygon.py +112 -0
- vispy/visuals/tests/test_rectangle.py +163 -0
- vispy/visuals/tests/test_regular_polygon.py +111 -0
- vispy/visuals/tests/test_scalable_textures.py +196 -0
- vispy/visuals/tests/test_sdf.py +73 -0
- vispy/visuals/tests/test_spectrogram.py +42 -0
- vispy/visuals/tests/test_surface_plot.py +57 -0
- vispy/visuals/tests/test_text.py +95 -0
- vispy/visuals/tests/test_volume.py +542 -0
- vispy/visuals/tests/test_windbarb.py +33 -0
- vispy/visuals/text/__init__.py +7 -0
- vispy/visuals/text/_sdf_cpu.cpython-313-darwin.so +0 -0
- vispy/visuals/text/_sdf_cpu.pyx +112 -0
- vispy/visuals/text/_sdf_gpu.py +316 -0
- vispy/visuals/text/text.py +675 -0
- vispy/visuals/transforms/__init__.py +34 -0
- vispy/visuals/transforms/_util.py +191 -0
- vispy/visuals/transforms/base_transform.py +233 -0
- vispy/visuals/transforms/chain.py +300 -0
- vispy/visuals/transforms/interactive.py +98 -0
- vispy/visuals/transforms/linear.py +564 -0
- vispy/visuals/transforms/nonlinear.py +398 -0
- vispy/visuals/transforms/tests/__init__.py +0 -0
- vispy/visuals/transforms/tests/test_transforms.py +243 -0
- vispy/visuals/transforms/transform_system.py +339 -0
- vispy/visuals/tube.py +173 -0
- vispy/visuals/visual.py +923 -0
- vispy/visuals/volume.py +1366 -0
- vispy/visuals/windbarb.py +291 -0
- vispy/visuals/xyz_axis.py +34 -0
- vispy-0.15.0.dist-info/METADATA +243 -0
- vispy-0.15.0.dist-info/RECORD +521 -0
- vispy-0.15.0.dist-info/WHEEL +6 -0
- vispy-0.15.0.dist-info/licenses/LICENSE.txt +36 -0
- vispy-0.15.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
# Anti-Grain Geometry - Version 2.4
|
|
2
|
+
# Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
|
|
3
|
+
#
|
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
|
5
|
+
# modification, are permitted provided that the following conditions
|
|
6
|
+
# are met:
|
|
7
|
+
#
|
|
8
|
+
# 1. Redistributions of source code must retain the above copyright
|
|
9
|
+
# notice, this list of conditions and the following disclaimer.
|
|
10
|
+
#
|
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
|
12
|
+
# notice, this list of conditions and the following disclaimer in
|
|
13
|
+
# the documentation and/or other materials provided with the
|
|
14
|
+
# distribution.
|
|
15
|
+
#
|
|
16
|
+
# 3. The name of the author may not be used to endorse or promote
|
|
17
|
+
# products derived from this software without specific prior
|
|
18
|
+
# written permission.
|
|
19
|
+
#
|
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
21
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
22
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
23
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
|
24
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
25
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
27
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
28
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|
29
|
+
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
30
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
# ----------------------------------------------------------------------------
|
|
32
|
+
#
|
|
33
|
+
# Python translation by Nicolas P. Rougier
|
|
34
|
+
# Copyright (C) 2013 Nicolas P. Rougier. All rights reserved.
|
|
35
|
+
#
|
|
36
|
+
# Redistribution and use in source and binary forms, with or without
|
|
37
|
+
# modification, are permitted provided that the following conditions are met:
|
|
38
|
+
#
|
|
39
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
|
40
|
+
# this list of conditions and the following disclaimer.
|
|
41
|
+
#
|
|
42
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
|
43
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
44
|
+
# documentation and/or other materials provided with the distribution.
|
|
45
|
+
#
|
|
46
|
+
# THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
|
47
|
+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
48
|
+
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
49
|
+
# EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
50
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
51
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
52
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
53
|
+
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
54
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
55
|
+
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
56
|
+
#
|
|
57
|
+
# The views and conclusions contained in the software and documentation are
|
|
58
|
+
# those of the authors and should not be interpreted as representing official
|
|
59
|
+
# policies, either expressed or implied, of Nicolas P. Rougier.
|
|
60
|
+
#
|
|
61
|
+
# ----------------------------------------------------------------------------
|
|
62
|
+
import math
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
curve_distance_epsilon = 1e-30
|
|
66
|
+
curve_collinearity_epsilon = 1e-30
|
|
67
|
+
curve_angle_tolerance_epsilon = 0.01
|
|
68
|
+
curve_recursion_limit = 32
|
|
69
|
+
m_cusp_limit = 0.0
|
|
70
|
+
m_angle_tolerance = 10 * math.pi / 180.0
|
|
71
|
+
m_approximation_scale = 1.0
|
|
72
|
+
m_distance_tolerance_square = (0.5 / m_approximation_scale)**2
|
|
73
|
+
epsilon = 1e-10
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def calc_sq_distance(x1, y1, x2, y2):
|
|
77
|
+
dx = x2 - x1
|
|
78
|
+
dy = y2 - y1
|
|
79
|
+
return dx * dx + dy * dy
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def quadratic_recursive(points, x1, y1, x2, y2, x3, y3, level=0):
|
|
83
|
+
if level > curve_recursion_limit:
|
|
84
|
+
return
|
|
85
|
+
|
|
86
|
+
# Calculate all the mid-points of the line segments
|
|
87
|
+
# -------------------------------------------------
|
|
88
|
+
x12 = (x1 + x2) / 2.
|
|
89
|
+
y12 = (y1 + y2) / 2.
|
|
90
|
+
x23 = (x2 + x3) / 2.
|
|
91
|
+
y23 = (y2 + y3) / 2.
|
|
92
|
+
x123 = (x12 + x23) / 2.
|
|
93
|
+
y123 = (y12 + y23) / 2.
|
|
94
|
+
|
|
95
|
+
dx = x3 - x1
|
|
96
|
+
dy = y3 - y1
|
|
97
|
+
d = math.fabs((x2 - x3) * dy - (y2 - y3) * dx)
|
|
98
|
+
|
|
99
|
+
if d > curve_collinearity_epsilon:
|
|
100
|
+
# Regular case
|
|
101
|
+
# ------------
|
|
102
|
+
if d * d <= m_distance_tolerance_square * (dx * dx + dy * dy):
|
|
103
|
+
# If the curvature doesn't exceed the distance_tolerance value
|
|
104
|
+
# we tend to finish subdivisions.
|
|
105
|
+
if m_angle_tolerance < curve_angle_tolerance_epsilon:
|
|
106
|
+
points.append((x123, y123))
|
|
107
|
+
return
|
|
108
|
+
|
|
109
|
+
# Angle & Cusp Condition
|
|
110
|
+
da = math.fabs(
|
|
111
|
+
math.atan2(y3 - y2, x3 - x2) - math.atan2(y2 - y1, x2 - x1))
|
|
112
|
+
if da >= math.pi:
|
|
113
|
+
da = 2 * math.pi - da
|
|
114
|
+
|
|
115
|
+
if da < m_angle_tolerance:
|
|
116
|
+
# Finally we can stop the recursion
|
|
117
|
+
points.append((x123, y123))
|
|
118
|
+
return
|
|
119
|
+
else:
|
|
120
|
+
# Collinear case
|
|
121
|
+
# --------------
|
|
122
|
+
da = dx * dx + dy * dy
|
|
123
|
+
if da == 0:
|
|
124
|
+
d = calc_sq_distance(x1, y1, x2, y2)
|
|
125
|
+
else:
|
|
126
|
+
d = ((x2 - x1) * dx + (y2 - y1) * dy) / da
|
|
127
|
+
if d > 0 and d < 1:
|
|
128
|
+
# Simple collinear case, 1---2---3, we can leave just two
|
|
129
|
+
# endpoints
|
|
130
|
+
return
|
|
131
|
+
if(d <= 0):
|
|
132
|
+
d = calc_sq_distance(x2, y2, x1, y1)
|
|
133
|
+
elif d >= 1:
|
|
134
|
+
d = calc_sq_distance(x2, y2, x3, y3)
|
|
135
|
+
else:
|
|
136
|
+
d = calc_sq_distance(x2, y2, x1 + d * dx, y1 + d * dy)
|
|
137
|
+
|
|
138
|
+
if d < m_distance_tolerance_square:
|
|
139
|
+
points.append((x2, y2))
|
|
140
|
+
return
|
|
141
|
+
|
|
142
|
+
# Continue subdivision
|
|
143
|
+
# --------------------
|
|
144
|
+
quadratic_recursive(points, x1, y1, x12, y12, x123, y123, level + 1)
|
|
145
|
+
quadratic_recursive(points, x123, y123, x23, y23, x3, y3, level + 1)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def cubic_recursive(points, x1, y1, x2, y2, x3, y3, x4, y4, level=0):
|
|
149
|
+
if level > curve_recursion_limit:
|
|
150
|
+
return
|
|
151
|
+
|
|
152
|
+
# Calculate all the mid-points of the line segments
|
|
153
|
+
# -------------------------------------------------
|
|
154
|
+
x12 = (x1 + x2) / 2.
|
|
155
|
+
y12 = (y1 + y2) / 2.
|
|
156
|
+
x23 = (x2 + x3) / 2.
|
|
157
|
+
y23 = (y2 + y3) / 2.
|
|
158
|
+
x34 = (x3 + x4) / 2.
|
|
159
|
+
y34 = (y3 + y4) / 2.
|
|
160
|
+
x123 = (x12 + x23) / 2.
|
|
161
|
+
y123 = (y12 + y23) / 2.
|
|
162
|
+
x234 = (x23 + x34) / 2.
|
|
163
|
+
y234 = (y23 + y34) / 2.
|
|
164
|
+
x1234 = (x123 + x234) / 2.
|
|
165
|
+
y1234 = (y123 + y234) / 2.
|
|
166
|
+
|
|
167
|
+
# Try to approximate the full cubic curve by a single straight line
|
|
168
|
+
# -----------------------------------------------------------------
|
|
169
|
+
dx = x4 - x1
|
|
170
|
+
dy = y4 - y1
|
|
171
|
+
d2 = math.fabs(((x2 - x4) * dy - (y2 - y4) * dx))
|
|
172
|
+
d3 = math.fabs(((x3 - x4) * dy - (y3 - y4) * dx))
|
|
173
|
+
|
|
174
|
+
s = int((d2 > curve_collinearity_epsilon) << 1) + \
|
|
175
|
+
int(d3 > curve_collinearity_epsilon)
|
|
176
|
+
|
|
177
|
+
if s == 0:
|
|
178
|
+
# All collinear OR p1==p4
|
|
179
|
+
# ----------------------
|
|
180
|
+
k = dx * dx + dy * dy
|
|
181
|
+
if k == 0:
|
|
182
|
+
d2 = calc_sq_distance(x1, y1, x2, y2)
|
|
183
|
+
d3 = calc_sq_distance(x4, y4, x3, y3)
|
|
184
|
+
|
|
185
|
+
else:
|
|
186
|
+
k = 1. / k
|
|
187
|
+
da1 = x2 - x1
|
|
188
|
+
da2 = y2 - y1
|
|
189
|
+
d2 = k * (da1 * dx + da2 * dy)
|
|
190
|
+
da1 = x3 - x1
|
|
191
|
+
da2 = y3 - y1
|
|
192
|
+
d3 = k * (da1 * dx + da2 * dy)
|
|
193
|
+
if d2 > 0 and d2 < 1 and d3 > 0 and d3 < 1:
|
|
194
|
+
# Simple collinear case, 1---2---3---4
|
|
195
|
+
# We can leave just two endpoints
|
|
196
|
+
return
|
|
197
|
+
|
|
198
|
+
if d2 <= 0:
|
|
199
|
+
d2 = calc_sq_distance(x2, y2, x1, y1)
|
|
200
|
+
elif d2 >= 1:
|
|
201
|
+
d2 = calc_sq_distance(x2, y2, x4, y4)
|
|
202
|
+
else:
|
|
203
|
+
d2 = calc_sq_distance(x2, y2, x1 + d2 * dx, y1 + d2 * dy)
|
|
204
|
+
|
|
205
|
+
if d3 <= 0:
|
|
206
|
+
d3 = calc_sq_distance(x3, y3, x1, y1)
|
|
207
|
+
elif d3 >= 1:
|
|
208
|
+
d3 = calc_sq_distance(x3, y3, x4, y4)
|
|
209
|
+
else:
|
|
210
|
+
d3 = calc_sq_distance(x3, y3, x1 + d3 * dx, y1 + d3 * dy)
|
|
211
|
+
|
|
212
|
+
if d2 > d3:
|
|
213
|
+
if d2 < m_distance_tolerance_square:
|
|
214
|
+
points.append((x2, y2))
|
|
215
|
+
return
|
|
216
|
+
else:
|
|
217
|
+
if d3 < m_distance_tolerance_square:
|
|
218
|
+
points.append((x3, y3))
|
|
219
|
+
return
|
|
220
|
+
|
|
221
|
+
elif s == 1:
|
|
222
|
+
# p1,p2,p4 are collinear, p3 is significant
|
|
223
|
+
# -----------------------------------------
|
|
224
|
+
if d3 * d3 <= m_distance_tolerance_square * (dx * dx + dy * dy):
|
|
225
|
+
if m_angle_tolerance < curve_angle_tolerance_epsilon:
|
|
226
|
+
points.append((x23, y23))
|
|
227
|
+
return
|
|
228
|
+
|
|
229
|
+
# Angle Condition
|
|
230
|
+
# ---------------
|
|
231
|
+
da1 = math.fabs(
|
|
232
|
+
math.atan2(y4 - y3, x4 - x3) - math.atan2(y3 - y2, x3 - x2))
|
|
233
|
+
if da1 >= math.pi:
|
|
234
|
+
da1 = 2 * math.pi - da1
|
|
235
|
+
|
|
236
|
+
if da1 < m_angle_tolerance:
|
|
237
|
+
points.extend([(x2, y2), (x3, y3)])
|
|
238
|
+
return
|
|
239
|
+
|
|
240
|
+
if m_cusp_limit != 0.0:
|
|
241
|
+
if da1 > m_cusp_limit:
|
|
242
|
+
points.append((x3, y3))
|
|
243
|
+
return
|
|
244
|
+
|
|
245
|
+
elif s == 2:
|
|
246
|
+
# p1,p3,p4 are collinear, p2 is significant
|
|
247
|
+
# -----------------------------------------
|
|
248
|
+
if d2 * d2 <= m_distance_tolerance_square * (dx * dx + dy * dy):
|
|
249
|
+
if m_angle_tolerance < curve_angle_tolerance_epsilon:
|
|
250
|
+
points.append((x23, y23))
|
|
251
|
+
return
|
|
252
|
+
|
|
253
|
+
# Angle Condition
|
|
254
|
+
# ---------------
|
|
255
|
+
da1 = math.fabs(
|
|
256
|
+
math.atan2(y3 - y2, x3 - x2) - math.atan2(y2 - y1, x2 - x1))
|
|
257
|
+
if da1 >= math.pi:
|
|
258
|
+
da1 = 2 * math.pi - da1
|
|
259
|
+
|
|
260
|
+
if da1 < m_angle_tolerance:
|
|
261
|
+
points.extend([(x2, y2), (x3, y3)])
|
|
262
|
+
return
|
|
263
|
+
|
|
264
|
+
if m_cusp_limit != 0.0:
|
|
265
|
+
if da1 > m_cusp_limit:
|
|
266
|
+
points.append((x2, y2))
|
|
267
|
+
return
|
|
268
|
+
|
|
269
|
+
elif s == 3:
|
|
270
|
+
# Regular case
|
|
271
|
+
# ------------
|
|
272
|
+
if (d2 + d3) * (d2 + d3) <= m_distance_tolerance_square * (dx * dx + dy * dy): # noqa
|
|
273
|
+
# If the curvature doesn't exceed the distance_tolerance value
|
|
274
|
+
# we tend to finish subdivisions.
|
|
275
|
+
|
|
276
|
+
if m_angle_tolerance < curve_angle_tolerance_epsilon:
|
|
277
|
+
points.append((x23, y23))
|
|
278
|
+
return
|
|
279
|
+
|
|
280
|
+
# Angle & Cusp Condition
|
|
281
|
+
# ----------------------
|
|
282
|
+
k = math.atan2(y3 - y2, x3 - x2)
|
|
283
|
+
da1 = math.fabs(k - math.atan2(y2 - y1, x2 - x1))
|
|
284
|
+
da2 = math.fabs(math.atan2(y4 - y3, x4 - x3) - k)
|
|
285
|
+
if da1 >= math.pi:
|
|
286
|
+
da1 = 2 * math.pi - da1
|
|
287
|
+
if da2 >= math.pi:
|
|
288
|
+
da2 = 2 * math.pi - da2
|
|
289
|
+
|
|
290
|
+
if da1 + da2 < m_angle_tolerance:
|
|
291
|
+
# Finally we can stop the recursion
|
|
292
|
+
# ---------------------------------
|
|
293
|
+
points.append((x23, y23))
|
|
294
|
+
return
|
|
295
|
+
|
|
296
|
+
if m_cusp_limit != 0.0:
|
|
297
|
+
if da1 > m_cusp_limit:
|
|
298
|
+
points.append((x2, y2))
|
|
299
|
+
return
|
|
300
|
+
|
|
301
|
+
if da2 > m_cusp_limit:
|
|
302
|
+
points.append((x3, y3))
|
|
303
|
+
return
|
|
304
|
+
|
|
305
|
+
# Continue subdivision
|
|
306
|
+
# --------------------
|
|
307
|
+
cubic_recursive(
|
|
308
|
+
points, x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1)
|
|
309
|
+
cubic_recursive(
|
|
310
|
+
points, x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1)
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def quadratic(p1, p2, p3):
|
|
314
|
+
x1, y1 = p1
|
|
315
|
+
x2, y2 = p2
|
|
316
|
+
x3, y3 = p3
|
|
317
|
+
points = []
|
|
318
|
+
quadratic_recursive(points, x1, y1, x2, y2, x3, y3)
|
|
319
|
+
|
|
320
|
+
dx, dy = points[0][0] - x1, points[0][1] - y1
|
|
321
|
+
if (dx * dx + dy * dy) > epsilon:
|
|
322
|
+
points.insert(0, (x1, y1))
|
|
323
|
+
|
|
324
|
+
dx, dy = points[-1][0] - x3, points[-1][1] - y3
|
|
325
|
+
if (dx * dx + dy * dy) > epsilon:
|
|
326
|
+
points.append((x3, y3))
|
|
327
|
+
|
|
328
|
+
return points
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def cubic(p1, p2, p3, p4):
|
|
332
|
+
x1, y1 = p1
|
|
333
|
+
x2, y2 = p2
|
|
334
|
+
x3, y3 = p3
|
|
335
|
+
x4, y4 = p4
|
|
336
|
+
points = []
|
|
337
|
+
cubic_recursive(points, x1, y1, x2, y2, x3, y3, x4, y4)
|
|
338
|
+
|
|
339
|
+
dx, dy = points[0][0] - x1, points[0][1] - y1
|
|
340
|
+
if (dx * dx + dy * dy) > epsilon:
|
|
341
|
+
points.insert(0, (x1, y1))
|
|
342
|
+
dx, dy = points[-1][0] - x4, points[-1][1] - y4
|
|
343
|
+
if (dx * dx + dy * dy) > epsilon:
|
|
344
|
+
points.append((x4, y4))
|
|
345
|
+
|
|
346
|
+
return points
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def arc(cx, cy, rx, ry, a1, a2, ccw=False):
|
|
350
|
+
scale = 1.0
|
|
351
|
+
ra = (abs(rx) + abs(ry)) / 2.0
|
|
352
|
+
da = math.acos(ra / (ra + 0.125 / scale)) * 2.0
|
|
353
|
+
if ccw:
|
|
354
|
+
while a2 < a1:
|
|
355
|
+
a2 += math.pi * 2.0
|
|
356
|
+
else:
|
|
357
|
+
while a1 < a2:
|
|
358
|
+
a1 += math.pi * 2.0
|
|
359
|
+
da = -da
|
|
360
|
+
a_start = a1
|
|
361
|
+
a_end = a2
|
|
362
|
+
|
|
363
|
+
vertices = []
|
|
364
|
+
angle = a_start
|
|
365
|
+
while (angle < a_end - da / 4) == ccw:
|
|
366
|
+
x = cx + math.cos(angle) * rx
|
|
367
|
+
y = cy + math.sin(angle) * ry
|
|
368
|
+
vertices.append((x, y))
|
|
369
|
+
angle += da
|
|
370
|
+
x = cx + math.cos(a_end) * rx
|
|
371
|
+
y = cy + math.sin(a_end) * ry
|
|
372
|
+
vertices.append((x, y))
|
|
373
|
+
return vertices
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
def elliptical_arc(x0, y0, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2):
|
|
377
|
+
radii_ok = True
|
|
378
|
+
cos_a = math.cos(angle)
|
|
379
|
+
sin_a = math.sin(angle)
|
|
380
|
+
if rx < 0.0:
|
|
381
|
+
rx = -rx
|
|
382
|
+
if ry < 0.0:
|
|
383
|
+
ry = -rx
|
|
384
|
+
|
|
385
|
+
# Calculate the middle point between
|
|
386
|
+
# the current and the final points
|
|
387
|
+
# ------------------------
|
|
388
|
+
dx2 = (x0 - x2) / 2.0
|
|
389
|
+
dy2 = (y0 - y2) / 2.0
|
|
390
|
+
|
|
391
|
+
# Calculate (x1, y1)
|
|
392
|
+
# ------------------------
|
|
393
|
+
x1 = cos_a * dx2 + sin_a * dy2
|
|
394
|
+
y1 = -sin_a * dx2 + cos_a * dy2
|
|
395
|
+
|
|
396
|
+
# Check that radii are large enough
|
|
397
|
+
# ------------------------
|
|
398
|
+
prx, pry = rx * rx, ry * ry
|
|
399
|
+
px1, py1 = x1 * x1, y1 * y1
|
|
400
|
+
|
|
401
|
+
radii_check = px1 / prx + py1 / pry
|
|
402
|
+
if radii_check > 1.0:
|
|
403
|
+
rx = math.sqrt(radii_check) * rx
|
|
404
|
+
ry = math.sqrt(radii_check) * ry
|
|
405
|
+
prx = rx * rx
|
|
406
|
+
pry = ry * ry
|
|
407
|
+
if radii_check > 10.0:
|
|
408
|
+
radii_ok = False # noqa
|
|
409
|
+
|
|
410
|
+
# Calculate (cx1, cy1)
|
|
411
|
+
# ------------------------
|
|
412
|
+
if large_arc_flag == sweep_flag:
|
|
413
|
+
sign = -1
|
|
414
|
+
else:
|
|
415
|
+
sign = +1
|
|
416
|
+
sq = (prx * pry - prx * py1 - pry * px1) / (prx * py1 + pry * px1)
|
|
417
|
+
coef = sign * math.sqrt(max(sq, 0))
|
|
418
|
+
cx1 = coef * ((rx * y1) / ry)
|
|
419
|
+
cy1 = coef * -((ry * x1) / rx)
|
|
420
|
+
|
|
421
|
+
# Calculate (cx, cy) from (cx1, cy1)
|
|
422
|
+
# ------------------------
|
|
423
|
+
sx2 = (x0 + x2) / 2.0
|
|
424
|
+
sy2 = (y0 + y2) / 2.0
|
|
425
|
+
cx = sx2 + (cos_a * cx1 - sin_a * cy1)
|
|
426
|
+
cy = sy2 + (sin_a * cx1 + cos_a * cy1)
|
|
427
|
+
|
|
428
|
+
# Calculate the start_angle (angle1) and the sweep_angle (dangle)
|
|
429
|
+
# ------------------------
|
|
430
|
+
ux = (x1 - cx1) / rx
|
|
431
|
+
uy = (y1 - cy1) / ry
|
|
432
|
+
vx = (-x1 - cx1) / rx
|
|
433
|
+
vy = (-y1 - cy1) / ry
|
|
434
|
+
|
|
435
|
+
# Calculate the angle start
|
|
436
|
+
# ------------------------
|
|
437
|
+
n = math.sqrt(ux * ux + uy * uy)
|
|
438
|
+
p = ux
|
|
439
|
+
if uy < 0:
|
|
440
|
+
sign = -1.0
|
|
441
|
+
else:
|
|
442
|
+
sign = +1.0
|
|
443
|
+
v = p / n
|
|
444
|
+
if v < -1.0:
|
|
445
|
+
v = -1.0
|
|
446
|
+
if v > 1.0:
|
|
447
|
+
v = 1.0
|
|
448
|
+
start_angle = sign * math.acos(v)
|
|
449
|
+
|
|
450
|
+
# Calculate the sweep angle
|
|
451
|
+
# ------------------------
|
|
452
|
+
n = math.sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy))
|
|
453
|
+
p = ux * vx + uy * vy
|
|
454
|
+
if ux * vy - uy * vx < 0:
|
|
455
|
+
sign = -1.0
|
|
456
|
+
else:
|
|
457
|
+
sign = +1.0
|
|
458
|
+
v = p / n
|
|
459
|
+
v = min(max(v, -1.0), +1.0)
|
|
460
|
+
sweep_angle = sign * math.acos(v)
|
|
461
|
+
if not sweep_flag and sweep_angle > 0:
|
|
462
|
+
sweep_angle -= math.pi * 2.0
|
|
463
|
+
elif sweep_flag and sweep_angle < 0:
|
|
464
|
+
sweep_angle += math.pi * 2.0
|
|
465
|
+
|
|
466
|
+
start_angle = math.fmod(start_angle, 2.0 * math.pi)
|
|
467
|
+
if sweep_angle >= 2.0 * math.pi:
|
|
468
|
+
sweep_angle = 2.0 * math.pi
|
|
469
|
+
if sweep_angle <= -2.0 * math.pi:
|
|
470
|
+
sweep_angle = -2.0 * math.pi
|
|
471
|
+
|
|
472
|
+
V = arc(cx, cy, rx, ry, start_angle, start_angle + sweep_angle, sweep_flag)
|
|
473
|
+
c = math.cos(angle)
|
|
474
|
+
s = math.sin(angle)
|
|
475
|
+
X, Y = V[:, 0] - cx, V[:, 1] - cy
|
|
476
|
+
V[:, 0] = c * X - s * Y + cx
|
|
477
|
+
V[:, 1] = s * X + c * Y + cy
|
|
478
|
+
return V
|
vispy/util/svg/group.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# -----------------------------------------------------------------------------
|
|
3
|
+
# Copyright (c) 2014, Nicolas P. Rougier. All rights reserved.
|
|
4
|
+
# Distributed under the terms of the new BSD License.
|
|
5
|
+
# -----------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
import copy
|
|
8
|
+
from ...util import logger
|
|
9
|
+
from . path import Path
|
|
10
|
+
from . base import namespace
|
|
11
|
+
from . transformable import Transformable
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Group(Transformable):
|
|
15
|
+
|
|
16
|
+
def __init__(self, content=None, parent=None):
|
|
17
|
+
Transformable.__init__(self, content, parent)
|
|
18
|
+
|
|
19
|
+
self._items = []
|
|
20
|
+
for element in content:
|
|
21
|
+
if not element.tag.startswith(namespace):
|
|
22
|
+
continue
|
|
23
|
+
tag = element.tag[len(namespace):]
|
|
24
|
+
if tag == "g":
|
|
25
|
+
item = Group(element, self)
|
|
26
|
+
elif tag == "path":
|
|
27
|
+
item = Path(element, self)
|
|
28
|
+
else:
|
|
29
|
+
logger.warn("Unhandled SVG tag (%s)" % tag)
|
|
30
|
+
continue
|
|
31
|
+
self._items.append(item)
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def flatten(self):
|
|
35
|
+
i = 0
|
|
36
|
+
L = copy.deepcopy(self._items)
|
|
37
|
+
while i < len(L):
|
|
38
|
+
while isinstance(L[i], Group) and len(L[i]._items):
|
|
39
|
+
L[i:i + 1] = L[i]._items
|
|
40
|
+
i += 1
|
|
41
|
+
return L
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def paths(self):
|
|
45
|
+
return [item for item in self.flatten if isinstance(item, Path)]
|
|
46
|
+
|
|
47
|
+
def __repr__(self):
|
|
48
|
+
s = ""
|
|
49
|
+
for item in self._items:
|
|
50
|
+
s += repr(item)
|
|
51
|
+
return s
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def xml(self):
|
|
55
|
+
return self._xml()
|
|
56
|
+
|
|
57
|
+
def _xml(self, prefix=""):
|
|
58
|
+
s = prefix + "<g "
|
|
59
|
+
s += 'id="%s" ' % self._id
|
|
60
|
+
s += self._transform.xml
|
|
61
|
+
s += self._style.xml
|
|
62
|
+
s += ">\n"
|
|
63
|
+
for item in self._items:
|
|
64
|
+
s += item._xml(prefix=prefix + " ")
|
|
65
|
+
s += prefix + "</g>\n"
|
|
66
|
+
return s
|
vispy/util/svg/length.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# -----------------------------------------------------------------------------
|
|
3
|
+
# Copyright (c) 2014, Nicolas P. Rougier
|
|
4
|
+
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
|
|
5
|
+
# -----------------------------------------------------------------------------
|
|
6
|
+
import re
|
|
7
|
+
import math
|
|
8
|
+
|
|
9
|
+
from . base import units
|
|
10
|
+
from .. import logger
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Length(object):
|
|
14
|
+
|
|
15
|
+
def __init__(self, content, mode='x', parent=None):
|
|
16
|
+
|
|
17
|
+
if not content:
|
|
18
|
+
self._unit = None
|
|
19
|
+
self._value = 0
|
|
20
|
+
self._computed_value = 0
|
|
21
|
+
return
|
|
22
|
+
|
|
23
|
+
re_number = r'[-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?'
|
|
24
|
+
re_unit = r'em|ex|px|in|cm|mm|pt|pc|%'
|
|
25
|
+
re_length = r'(?P<value>%s)\s*(?P<unit>%s)*' % (re_number, re_unit)
|
|
26
|
+
match = re.match(re_length, content)
|
|
27
|
+
|
|
28
|
+
if match:
|
|
29
|
+
self._value = float(match.group("value"))
|
|
30
|
+
self._unit = match.group("unit") or "px"
|
|
31
|
+
else:
|
|
32
|
+
self._value = 0.0
|
|
33
|
+
self._unit = None
|
|
34
|
+
|
|
35
|
+
scale = 1
|
|
36
|
+
if self._unit == '%':
|
|
37
|
+
if not parent:
|
|
38
|
+
logger.warn("No parent for computing length using percent")
|
|
39
|
+
elif hasattr(parent, 'viewport'):
|
|
40
|
+
w, h = parent.viewport
|
|
41
|
+
if mode == 'x':
|
|
42
|
+
scale = w
|
|
43
|
+
elif mode == 'y':
|
|
44
|
+
scale = h
|
|
45
|
+
elif mode == 'xy':
|
|
46
|
+
scale = math.sqrt(w * w + h * h) / math.sqrt(2.0)
|
|
47
|
+
else:
|
|
48
|
+
logger.warn("Parent doesn't have a viewport")
|
|
49
|
+
|
|
50
|
+
self._computed_value = self._value * units[self._unit] * scale
|
|
51
|
+
|
|
52
|
+
def __float__(self):
|
|
53
|
+
return self._computed_value
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def value(self):
|
|
57
|
+
return self._computed_value
|
|
58
|
+
|
|
59
|
+
def __repr__(self):
|
|
60
|
+
if self._unit:
|
|
61
|
+
return "%g%s" % (self._value, self._unit)
|
|
62
|
+
else:
|
|
63
|
+
return "%g" % (self._value)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class XLength(Length):
|
|
67
|
+
|
|
68
|
+
def __init__(self, content, parent=None):
|
|
69
|
+
Length.__init__(self, content, 'x', parent)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class YLength(Length):
|
|
73
|
+
|
|
74
|
+
def __init__(self, content, parent=None):
|
|
75
|
+
Length.__init__(self, content, 'y', parent)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class XYLength(Length):
|
|
79
|
+
|
|
80
|
+
def __init__(self, content, parent=None):
|
|
81
|
+
Length.__init__(self, content, 'xy', parent)
|
vispy/util/svg/number.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# -----------------------------------------------------------------------------
|
|
3
|
+
# Copyright (c) 2014, Nicolas P. Rougier
|
|
4
|
+
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
|
|
5
|
+
# -----------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Number(object):
|
|
9
|
+
|
|
10
|
+
def __init__(self, content):
|
|
11
|
+
if not content:
|
|
12
|
+
self._value = 0
|
|
13
|
+
else:
|
|
14
|
+
content = content.strip()
|
|
15
|
+
self._value = float(content)
|
|
16
|
+
|
|
17
|
+
def __float__(self):
|
|
18
|
+
return self._value
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def value(self):
|
|
22
|
+
return self._value
|
|
23
|
+
|
|
24
|
+
def __repr__(self):
|
|
25
|
+
return repr(self._value)
|