vispy 0.14.0__cp311-cp311-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.

Files changed (519) hide show
  1. vispy/__init__.py +33 -0
  2. vispy/app/__init__.py +15 -0
  3. vispy/app/_default_app.py +76 -0
  4. vispy/app/_detect_eventloop.py +148 -0
  5. vispy/app/application.py +263 -0
  6. vispy/app/backends/__init__.py +52 -0
  7. vispy/app/backends/_egl.py +264 -0
  8. vispy/app/backends/_glfw.py +513 -0
  9. vispy/app/backends/_jupyter_rfb.py +278 -0
  10. vispy/app/backends/_offscreen_util.py +121 -0
  11. vispy/app/backends/_osmesa.py +235 -0
  12. vispy/app/backends/_pyglet.py +451 -0
  13. vispy/app/backends/_pyqt4.py +36 -0
  14. vispy/app/backends/_pyqt5.py +36 -0
  15. vispy/app/backends/_pyqt6.py +40 -0
  16. vispy/app/backends/_pyside.py +37 -0
  17. vispy/app/backends/_pyside2.py +52 -0
  18. vispy/app/backends/_pyside6.py +53 -0
  19. vispy/app/backends/_qt.py +968 -0
  20. vispy/app/backends/_sdl2.py +444 -0
  21. vispy/app/backends/_template.py +244 -0
  22. vispy/app/backends/_test.py +8 -0
  23. vispy/app/backends/_tk.py +800 -0
  24. vispy/app/backends/_wx.py +476 -0
  25. vispy/app/backends/tests/__init__.py +0 -0
  26. vispy/app/backends/tests/test_offscreen_util.py +52 -0
  27. vispy/app/backends/tests/test_rfb.py +77 -0
  28. vispy/app/base.py +294 -0
  29. vispy/app/canvas.py +828 -0
  30. vispy/app/qt.py +92 -0
  31. vispy/app/tests/__init__.py +0 -0
  32. vispy/app/tests/qt-designer.ui +58 -0
  33. vispy/app/tests/test_app.py +442 -0
  34. vispy/app/tests/test_backends.py +164 -0
  35. vispy/app/tests/test_canvas.py +122 -0
  36. vispy/app/tests/test_context.py +92 -0
  37. vispy/app/tests/test_qt.py +47 -0
  38. vispy/app/tests/test_simultaneous.py +134 -0
  39. vispy/app/timer.py +174 -0
  40. vispy/color/__init__.py +17 -0
  41. vispy/color/_color_dict.py +193 -0
  42. vispy/color/color_array.py +447 -0
  43. vispy/color/color_space.py +181 -0
  44. vispy/color/colormap.py +1134 -0
  45. vispy/color/tests/__init__.py +0 -0
  46. vispy/color/tests/test_color.py +352 -0
  47. vispy/conftest.py +12 -0
  48. vispy/ext/__init__.py +0 -0
  49. vispy/ext/cocoapy.py +1542 -0
  50. vispy/ext/cubehelix.py +138 -0
  51. vispy/ext/egl.py +375 -0
  52. vispy/ext/fontconfig.py +118 -0
  53. vispy/ext/gdi32plus.py +206 -0
  54. vispy/ext/osmesa.py +105 -0
  55. vispy/geometry/__init__.py +23 -0
  56. vispy/geometry/_triangulation_debugger.py +171 -0
  57. vispy/geometry/calculations.py +134 -0
  58. vispy/geometry/curves.py +399 -0
  59. vispy/geometry/generation.py +643 -0
  60. vispy/geometry/isocurve.py +175 -0
  61. vispy/geometry/isosurface.py +465 -0
  62. vispy/geometry/meshdata.py +698 -0
  63. vispy/geometry/normals.py +78 -0
  64. vispy/geometry/parametric.py +56 -0
  65. vispy/geometry/polygon.py +137 -0
  66. vispy/geometry/rect.py +210 -0
  67. vispy/geometry/tests/__init__.py +0 -0
  68. vispy/geometry/tests/test_calculations.py +23 -0
  69. vispy/geometry/tests/test_generation.py +56 -0
  70. vispy/geometry/tests/test_meshdata.py +106 -0
  71. vispy/geometry/tests/test_triangulation.py +506 -0
  72. vispy/geometry/torusknot.py +142 -0
  73. vispy/geometry/triangulation.py +876 -0
  74. vispy/gloo/__init__.py +56 -0
  75. vispy/gloo/buffer.py +505 -0
  76. vispy/gloo/context.py +272 -0
  77. vispy/gloo/framebuffer.py +257 -0
  78. vispy/gloo/gl/__init__.py +234 -0
  79. vispy/gloo/gl/_constants.py +332 -0
  80. vispy/gloo/gl/_es2.py +986 -0
  81. vispy/gloo/gl/_gl2.py +1365 -0
  82. vispy/gloo/gl/_proxy.py +499 -0
  83. vispy/gloo/gl/_pyopengl2.py +362 -0
  84. vispy/gloo/gl/dummy.py +24 -0
  85. vispy/gloo/gl/es2.py +62 -0
  86. vispy/gloo/gl/gl2.py +98 -0
  87. vispy/gloo/gl/glplus.py +168 -0
  88. vispy/gloo/gl/pyopengl2.py +97 -0
  89. vispy/gloo/gl/tests/__init__.py +0 -0
  90. vispy/gloo/gl/tests/test_basics.py +282 -0
  91. vispy/gloo/gl/tests/test_functionality.py +566 -0
  92. vispy/gloo/gl/tests/test_names.py +246 -0
  93. vispy/gloo/gl/tests/test_use.py +71 -0
  94. vispy/gloo/glir.py +1816 -0
  95. vispy/gloo/globject.py +101 -0
  96. vispy/gloo/preprocessor.py +67 -0
  97. vispy/gloo/program.py +543 -0
  98. vispy/gloo/tests/__init__.py +0 -0
  99. vispy/gloo/tests/test_buffer.py +558 -0
  100. vispy/gloo/tests/test_context.py +119 -0
  101. vispy/gloo/tests/test_framebuffer.py +195 -0
  102. vispy/gloo/tests/test_glir.py +307 -0
  103. vispy/gloo/tests/test_globject.py +35 -0
  104. vispy/gloo/tests/test_program.py +302 -0
  105. vispy/gloo/tests/test_texture.py +732 -0
  106. vispy/gloo/tests/test_use_gloo.py +187 -0
  107. vispy/gloo/tests/test_util.py +60 -0
  108. vispy/gloo/tests/test_wrappers.py +261 -0
  109. vispy/gloo/texture.py +1045 -0
  110. vispy/gloo/util.py +129 -0
  111. vispy/gloo/wrappers.py +762 -0
  112. vispy/glsl/__init__.py +42 -0
  113. vispy/glsl/antialias/antialias.glsl +7 -0
  114. vispy/glsl/antialias/cap-butt.glsl +31 -0
  115. vispy/glsl/antialias/cap-round.glsl +29 -0
  116. vispy/glsl/antialias/cap-square.glsl +30 -0
  117. vispy/glsl/antialias/cap-triangle-in.glsl +30 -0
  118. vispy/glsl/antialias/cap-triangle-out.glsl +30 -0
  119. vispy/glsl/antialias/cap.glsl +67 -0
  120. vispy/glsl/antialias/caps.glsl +67 -0
  121. vispy/glsl/antialias/filled.glsl +50 -0
  122. vispy/glsl/antialias/outline.glsl +40 -0
  123. vispy/glsl/antialias/stroke.glsl +43 -0
  124. vispy/glsl/arrowheads/angle.glsl +99 -0
  125. vispy/glsl/arrowheads/arrowheads.frag +60 -0
  126. vispy/glsl/arrowheads/arrowheads.glsl +12 -0
  127. vispy/glsl/arrowheads/arrowheads.vert +83 -0
  128. vispy/glsl/arrowheads/curved.glsl +48 -0
  129. vispy/glsl/arrowheads/inhibitor.glsl +26 -0
  130. vispy/glsl/arrowheads/stealth.glsl +46 -0
  131. vispy/glsl/arrowheads/triangle.glsl +97 -0
  132. vispy/glsl/arrowheads/util.glsl +13 -0
  133. vispy/glsl/arrows/angle-30.glsl +12 -0
  134. vispy/glsl/arrows/angle-60.glsl +12 -0
  135. vispy/glsl/arrows/angle-90.glsl +12 -0
  136. vispy/glsl/arrows/arrow.frag +39 -0
  137. vispy/glsl/arrows/arrow.vert +49 -0
  138. vispy/glsl/arrows/arrows.glsl +17 -0
  139. vispy/glsl/arrows/common.glsl +187 -0
  140. vispy/glsl/arrows/curved.glsl +63 -0
  141. vispy/glsl/arrows/stealth.glsl +50 -0
  142. vispy/glsl/arrows/triangle-30.glsl +12 -0
  143. vispy/glsl/arrows/triangle-60.glsl +12 -0
  144. vispy/glsl/arrows/triangle-90.glsl +12 -0
  145. vispy/glsl/arrows/util.glsl +98 -0
  146. vispy/glsl/build_spatial_filters.py +660 -0
  147. vispy/glsl/collections/agg-fast-path.frag +20 -0
  148. vispy/glsl/collections/agg-fast-path.vert +78 -0
  149. vispy/glsl/collections/agg-glyph.frag +60 -0
  150. vispy/glsl/collections/agg-glyph.vert +33 -0
  151. vispy/glsl/collections/agg-marker.frag +35 -0
  152. vispy/glsl/collections/agg-marker.vert +48 -0
  153. vispy/glsl/collections/agg-path.frag +55 -0
  154. vispy/glsl/collections/agg-path.vert +166 -0
  155. vispy/glsl/collections/agg-point.frag +21 -0
  156. vispy/glsl/collections/agg-point.vert +35 -0
  157. vispy/glsl/collections/agg-segment.frag +32 -0
  158. vispy/glsl/collections/agg-segment.vert +75 -0
  159. vispy/glsl/collections/marker.frag +38 -0
  160. vispy/glsl/collections/marker.vert +48 -0
  161. vispy/glsl/collections/raw-path.frag +15 -0
  162. vispy/glsl/collections/raw-path.vert +24 -0
  163. vispy/glsl/collections/raw-point.frag +14 -0
  164. vispy/glsl/collections/raw-point.vert +31 -0
  165. vispy/glsl/collections/raw-segment.frag +18 -0
  166. vispy/glsl/collections/raw-segment.vert +26 -0
  167. vispy/glsl/collections/raw-triangle.frag +13 -0
  168. vispy/glsl/collections/raw-triangle.vert +26 -0
  169. vispy/glsl/collections/sdf-glyph-ticks.vert +69 -0
  170. vispy/glsl/collections/sdf-glyph.frag +80 -0
  171. vispy/glsl/collections/sdf-glyph.vert +59 -0
  172. vispy/glsl/collections/tick-labels.vert +71 -0
  173. vispy/glsl/colormaps/autumn.glsl +20 -0
  174. vispy/glsl/colormaps/blues.glsl +20 -0
  175. vispy/glsl/colormaps/color-space.glsl +17 -0
  176. vispy/glsl/colormaps/colormaps.glsl +24 -0
  177. vispy/glsl/colormaps/cool.glsl +20 -0
  178. vispy/glsl/colormaps/fire.glsl +21 -0
  179. vispy/glsl/colormaps/gray.glsl +20 -0
  180. vispy/glsl/colormaps/greens.glsl +20 -0
  181. vispy/glsl/colormaps/hot.glsl +22 -0
  182. vispy/glsl/colormaps/ice.glsl +20 -0
  183. vispy/glsl/colormaps/icefire.glsl +23 -0
  184. vispy/glsl/colormaps/parse.py +40 -0
  185. vispy/glsl/colormaps/reds.glsl +20 -0
  186. vispy/glsl/colormaps/spring.glsl +20 -0
  187. vispy/glsl/colormaps/summer.glsl +20 -0
  188. vispy/glsl/colormaps/user.glsl +22 -0
  189. vispy/glsl/colormaps/util.glsl +41 -0
  190. vispy/glsl/colormaps/wheel.glsl +21 -0
  191. vispy/glsl/colormaps/winter.glsl +20 -0
  192. vispy/glsl/lines/agg.frag +320 -0
  193. vispy/glsl/lines/agg.vert +241 -0
  194. vispy/glsl/markers/arrow.glsl +12 -0
  195. vispy/glsl/markers/asterisk.glsl +16 -0
  196. vispy/glsl/markers/chevron.glsl +14 -0
  197. vispy/glsl/markers/clover.glsl +20 -0
  198. vispy/glsl/markers/club.glsl +31 -0
  199. vispy/glsl/markers/cross.glsl +17 -0
  200. vispy/glsl/markers/diamond.glsl +12 -0
  201. vispy/glsl/markers/disc.glsl +9 -0
  202. vispy/glsl/markers/ellipse.glsl +67 -0
  203. vispy/glsl/markers/hbar.glsl +9 -0
  204. vispy/glsl/markers/heart.glsl +15 -0
  205. vispy/glsl/markers/infinity.glsl +15 -0
  206. vispy/glsl/markers/marker-sdf.frag +74 -0
  207. vispy/glsl/markers/marker-sdf.vert +41 -0
  208. vispy/glsl/markers/marker.frag +36 -0
  209. vispy/glsl/markers/marker.vert +46 -0
  210. vispy/glsl/markers/markers.glsl +24 -0
  211. vispy/glsl/markers/pin.glsl +18 -0
  212. vispy/glsl/markers/ring.glsl +11 -0
  213. vispy/glsl/markers/spade.glsl +28 -0
  214. vispy/glsl/markers/square.glsl +10 -0
  215. vispy/glsl/markers/tag.glsl +11 -0
  216. vispy/glsl/markers/triangle.glsl +14 -0
  217. vispy/glsl/markers/vbar.glsl +9 -0
  218. vispy/glsl/math/circle-through-2-points.glsl +30 -0
  219. vispy/glsl/math/constants.glsl +48 -0
  220. vispy/glsl/math/double.glsl +114 -0
  221. vispy/glsl/math/functions.glsl +20 -0
  222. vispy/glsl/math/point-to-line-distance.glsl +31 -0
  223. vispy/glsl/math/point-to-line-projection.glsl +29 -0
  224. vispy/glsl/math/signed-line-distance.glsl +27 -0
  225. vispy/glsl/math/signed-segment-distance.glsl +30 -0
  226. vispy/glsl/misc/regular-grid.frag +244 -0
  227. vispy/glsl/misc/spatial-filters.frag +1407 -0
  228. vispy/glsl/misc/viewport-NDC.glsl +20 -0
  229. vispy/glsl/transforms/azimuthal-equal-area.glsl +32 -0
  230. vispy/glsl/transforms/azimuthal-equidistant.glsl +38 -0
  231. vispy/glsl/transforms/hammer.glsl +44 -0
  232. vispy/glsl/transforms/identity.glsl +6 -0
  233. vispy/glsl/transforms/identity_forward.glsl +23 -0
  234. vispy/glsl/transforms/identity_inverse.glsl +23 -0
  235. vispy/glsl/transforms/linear-scale.glsl +127 -0
  236. vispy/glsl/transforms/log-scale.glsl +126 -0
  237. vispy/glsl/transforms/mercator-transverse-forward.glsl +40 -0
  238. vispy/glsl/transforms/mercator-transverse-inverse.glsl +40 -0
  239. vispy/glsl/transforms/panzoom.glsl +10 -0
  240. vispy/glsl/transforms/polar.glsl +41 -0
  241. vispy/glsl/transforms/position.glsl +44 -0
  242. vispy/glsl/transforms/power-scale.glsl +139 -0
  243. vispy/glsl/transforms/projection.glsl +7 -0
  244. vispy/glsl/transforms/pvm.glsl +13 -0
  245. vispy/glsl/transforms/rotate.glsl +45 -0
  246. vispy/glsl/transforms/trackball.glsl +15 -0
  247. vispy/glsl/transforms/translate.glsl +35 -0
  248. vispy/glsl/transforms/transverse_mercator.glsl +38 -0
  249. vispy/glsl/transforms/viewport-clipping.glsl +14 -0
  250. vispy/glsl/transforms/viewport-transform.glsl +16 -0
  251. vispy/glsl/transforms/viewport.glsl +50 -0
  252. vispy/glsl/transforms/x.glsl +24 -0
  253. vispy/glsl/transforms/y.glsl +19 -0
  254. vispy/glsl/transforms/z.glsl +14 -0
  255. vispy/io/__init__.py +20 -0
  256. vispy/io/_data/spatial-filters.npy +0 -0
  257. vispy/io/datasets.py +94 -0
  258. vispy/io/image.py +231 -0
  259. vispy/io/mesh.py +122 -0
  260. vispy/io/stl.py +167 -0
  261. vispy/io/tests/__init__.py +0 -0
  262. vispy/io/tests/test_image.py +47 -0
  263. vispy/io/tests/test_io.py +121 -0
  264. vispy/io/wavefront.py +350 -0
  265. vispy/plot/__init__.py +36 -0
  266. vispy/plot/fig.py +58 -0
  267. vispy/plot/plotwidget.py +522 -0
  268. vispy/plot/tests/__init__.py +0 -0
  269. vispy/plot/tests/test_plot.py +46 -0
  270. vispy/scene/__init__.py +43 -0
  271. vispy/scene/cameras/__init__.py +27 -0
  272. vispy/scene/cameras/_base.py +38 -0
  273. vispy/scene/cameras/arcball.py +106 -0
  274. vispy/scene/cameras/base_camera.py +538 -0
  275. vispy/scene/cameras/fly.py +474 -0
  276. vispy/scene/cameras/magnify.py +163 -0
  277. vispy/scene/cameras/panzoom.py +308 -0
  278. vispy/scene/cameras/perspective.py +333 -0
  279. vispy/scene/cameras/tests/__init__.py +0 -0
  280. vispy/scene/cameras/tests/test_cameras.py +27 -0
  281. vispy/scene/cameras/tests/test_link.py +53 -0
  282. vispy/scene/cameras/tests/test_perspective.py +122 -0
  283. vispy/scene/cameras/turntable.py +173 -0
  284. vispy/scene/canvas.py +639 -0
  285. vispy/scene/events.py +85 -0
  286. vispy/scene/node.py +644 -0
  287. vispy/scene/subscene.py +20 -0
  288. vispy/scene/tests/__init__.py +0 -0
  289. vispy/scene/tests/test_canvas.py +119 -0
  290. vispy/scene/tests/test_node.py +142 -0
  291. vispy/scene/tests/test_visuals.py +141 -0
  292. vispy/scene/visuals.py +276 -0
  293. vispy/scene/widgets/__init__.py +18 -0
  294. vispy/scene/widgets/anchor.py +25 -0
  295. vispy/scene/widgets/axis.py +88 -0
  296. vispy/scene/widgets/colorbar.py +176 -0
  297. vispy/scene/widgets/console.py +351 -0
  298. vispy/scene/widgets/grid.py +509 -0
  299. vispy/scene/widgets/label.py +50 -0
  300. vispy/scene/widgets/tests/__init__.py +0 -0
  301. vispy/scene/widgets/tests/test_colorbar.py +47 -0
  302. vispy/scene/widgets/viewbox.py +199 -0
  303. vispy/scene/widgets/widget.py +478 -0
  304. vispy/testing/__init__.py +51 -0
  305. vispy/testing/_runners.py +446 -0
  306. vispy/testing/_testing.py +416 -0
  307. vispy/testing/image_tester.py +473 -0
  308. vispy/testing/rendered_array_tester.py +85 -0
  309. vispy/testing/tests/__init__.py +0 -0
  310. vispy/testing/tests/test_testing.py +20 -0
  311. vispy/util/__init__.py +17 -0
  312. vispy/util/bunch.py +15 -0
  313. vispy/util/check_environment.py +57 -0
  314. vispy/util/config.py +490 -0
  315. vispy/util/dpi/__init__.py +19 -0
  316. vispy/util/dpi/_linux.py +69 -0
  317. vispy/util/dpi/_quartz.py +26 -0
  318. vispy/util/dpi/_win32.py +34 -0
  319. vispy/util/dpi/tests/__init__.py +0 -0
  320. vispy/util/dpi/tests/test_dpi.py +16 -0
  321. vispy/util/eq.py +41 -0
  322. vispy/util/event.py +774 -0
  323. vispy/util/fetching.py +276 -0
  324. vispy/util/filter.py +44 -0
  325. vispy/util/fonts/__init__.py +14 -0
  326. vispy/util/fonts/_freetype.py +73 -0
  327. vispy/util/fonts/_quartz.py +192 -0
  328. vispy/util/fonts/_triage.py +36 -0
  329. vispy/util/fonts/_vispy_fonts.py +20 -0
  330. vispy/util/fonts/_win32.py +105 -0
  331. vispy/util/fonts/data/OpenSans-Bold.ttf +0 -0
  332. vispy/util/fonts/data/OpenSans-BoldItalic.ttf +0 -0
  333. vispy/util/fonts/data/OpenSans-Italic.ttf +0 -0
  334. vispy/util/fonts/data/OpenSans-Regular.ttf +0 -0
  335. vispy/util/fonts/tests/__init__.py +0 -0
  336. vispy/util/fonts/tests/test_font.py +45 -0
  337. vispy/util/fourier.py +69 -0
  338. vispy/util/frozen.py +25 -0
  339. vispy/util/gallery_scraper.py +268 -0
  340. vispy/util/keys.py +91 -0
  341. vispy/util/logs.py +358 -0
  342. vispy/util/osmesa_gl.py +17 -0
  343. vispy/util/profiler.py +135 -0
  344. vispy/util/ptime.py +16 -0
  345. vispy/util/quaternion.py +229 -0
  346. vispy/util/svg/__init__.py +18 -0
  347. vispy/util/svg/base.py +20 -0
  348. vispy/util/svg/color.py +219 -0
  349. vispy/util/svg/element.py +51 -0
  350. vispy/util/svg/geometry.py +478 -0
  351. vispy/util/svg/group.py +66 -0
  352. vispy/util/svg/length.py +81 -0
  353. vispy/util/svg/number.py +25 -0
  354. vispy/util/svg/path.py +332 -0
  355. vispy/util/svg/shapes.py +57 -0
  356. vispy/util/svg/style.py +59 -0
  357. vispy/util/svg/svg.py +40 -0
  358. vispy/util/svg/transform.py +223 -0
  359. vispy/util/svg/transformable.py +28 -0
  360. vispy/util/svg/viewport.py +73 -0
  361. vispy/util/tests/__init__.py +0 -0
  362. vispy/util/tests/test_config.py +58 -0
  363. vispy/util/tests/test_docstring_parameters.py +123 -0
  364. vispy/util/tests/test_emitter_group.py +262 -0
  365. vispy/util/tests/test_event_emitter.py +743 -0
  366. vispy/util/tests/test_fourier.py +35 -0
  367. vispy/util/tests/test_gallery_scraper.py +112 -0
  368. vispy/util/tests/test_import.py +127 -0
  369. vispy/util/tests/test_key.py +22 -0
  370. vispy/util/tests/test_logging.py +45 -0
  371. vispy/util/tests/test_run.py +14 -0
  372. vispy/util/tests/test_transforms.py +42 -0
  373. vispy/util/tests/test_vispy.py +48 -0
  374. vispy/util/transforms.py +201 -0
  375. vispy/util/wrappers.py +155 -0
  376. vispy/version.py +4 -0
  377. vispy/visuals/__init__.py +50 -0
  378. vispy/visuals/_scalable_textures.py +485 -0
  379. vispy/visuals/axis.py +678 -0
  380. vispy/visuals/border.py +208 -0
  381. vispy/visuals/box.py +79 -0
  382. vispy/visuals/collections/__init__.py +30 -0
  383. vispy/visuals/collections/agg_fast_path_collection.py +219 -0
  384. vispy/visuals/collections/agg_path_collection.py +197 -0
  385. vispy/visuals/collections/agg_point_collection.py +52 -0
  386. vispy/visuals/collections/agg_segment_collection.py +142 -0
  387. vispy/visuals/collections/array_list.py +401 -0
  388. vispy/visuals/collections/base_collection.py +482 -0
  389. vispy/visuals/collections/collection.py +253 -0
  390. vispy/visuals/collections/path_collection.py +23 -0
  391. vispy/visuals/collections/point_collection.py +19 -0
  392. vispy/visuals/collections/polygon_collection.py +25 -0
  393. vispy/visuals/collections/raw_path_collection.py +119 -0
  394. vispy/visuals/collections/raw_point_collection.py +113 -0
  395. vispy/visuals/collections/raw_polygon_collection.py +77 -0
  396. vispy/visuals/collections/raw_segment_collection.py +112 -0
  397. vispy/visuals/collections/raw_triangle_collection.py +78 -0
  398. vispy/visuals/collections/segment_collection.py +19 -0
  399. vispy/visuals/collections/triangle_collection.py +16 -0
  400. vispy/visuals/collections/util.py +168 -0
  401. vispy/visuals/colorbar.py +699 -0
  402. vispy/visuals/cube.py +41 -0
  403. vispy/visuals/ellipse.py +163 -0
  404. vispy/visuals/filters/__init__.py +10 -0
  405. vispy/visuals/filters/base_filter.py +242 -0
  406. vispy/visuals/filters/clipper.py +60 -0
  407. vispy/visuals/filters/clipping_planes.py +122 -0
  408. vispy/visuals/filters/color.py +181 -0
  409. vispy/visuals/filters/markers.py +28 -0
  410. vispy/visuals/filters/mesh.py +796 -0
  411. vispy/visuals/filters/picking.py +60 -0
  412. vispy/visuals/filters/tests/__init__.py +3 -0
  413. vispy/visuals/filters/tests/test_primitive_picking_filters.py +70 -0
  414. vispy/visuals/filters/tests/test_wireframe_filter.py +16 -0
  415. vispy/visuals/glsl/__init__.py +1 -0
  416. vispy/visuals/glsl/antialiasing.py +133 -0
  417. vispy/visuals/glsl/color.py +63 -0
  418. vispy/visuals/graphs/__init__.py +1 -0
  419. vispy/visuals/graphs/graph.py +240 -0
  420. vispy/visuals/graphs/layouts/__init__.py +55 -0
  421. vispy/visuals/graphs/layouts/circular.py +49 -0
  422. vispy/visuals/graphs/layouts/force_directed.py +211 -0
  423. vispy/visuals/graphs/layouts/networkx_layout.py +87 -0
  424. vispy/visuals/graphs/layouts/random.py +52 -0
  425. vispy/visuals/graphs/tests/__init__.py +1 -0
  426. vispy/visuals/graphs/tests/test_layouts.py +139 -0
  427. vispy/visuals/graphs/tests/test_networkx_layout.py +47 -0
  428. vispy/visuals/graphs/util.py +120 -0
  429. vispy/visuals/gridlines.py +105 -0
  430. vispy/visuals/gridmesh.py +98 -0
  431. vispy/visuals/histogram.py +58 -0
  432. vispy/visuals/image.py +688 -0
  433. vispy/visuals/image_complex.py +130 -0
  434. vispy/visuals/infinite_line.py +199 -0
  435. vispy/visuals/instanced_mesh.py +152 -0
  436. vispy/visuals/isocurve.py +213 -0
  437. vispy/visuals/isoline.py +241 -0
  438. vispy/visuals/isosurface.py +113 -0
  439. vispy/visuals/line/__init__.py +6 -0
  440. vispy/visuals/line/arrow.py +289 -0
  441. vispy/visuals/line/dash_atlas.py +90 -0
  442. vispy/visuals/line/line.py +545 -0
  443. vispy/visuals/line_plot.py +135 -0
  444. vispy/visuals/linear_region.py +199 -0
  445. vispy/visuals/markers.py +810 -0
  446. vispy/visuals/mesh.py +373 -0
  447. vispy/visuals/mesh_normals.py +159 -0
  448. vispy/visuals/plane.py +54 -0
  449. vispy/visuals/polygon.py +145 -0
  450. vispy/visuals/rectangle.py +196 -0
  451. vispy/visuals/regular_polygon.py +56 -0
  452. vispy/visuals/scrolling_lines.py +197 -0
  453. vispy/visuals/shaders/__init__.py +17 -0
  454. vispy/visuals/shaders/compiler.py +206 -0
  455. vispy/visuals/shaders/expression.py +99 -0
  456. vispy/visuals/shaders/function.py +788 -0
  457. vispy/visuals/shaders/multiprogram.py +145 -0
  458. vispy/visuals/shaders/parsing.py +140 -0
  459. vispy/visuals/shaders/program.py +161 -0
  460. vispy/visuals/shaders/shader_object.py +162 -0
  461. vispy/visuals/shaders/tests/__init__.py +0 -0
  462. vispy/visuals/shaders/tests/test_function.py +486 -0
  463. vispy/visuals/shaders/tests/test_multiprogram.py +78 -0
  464. vispy/visuals/shaders/tests/test_parsing.py +57 -0
  465. vispy/visuals/shaders/variable.py +272 -0
  466. vispy/visuals/spectrogram.py +169 -0
  467. vispy/visuals/sphere.py +80 -0
  468. vispy/visuals/surface_plot.py +192 -0
  469. vispy/visuals/tests/__init__.py +0 -0
  470. vispy/visuals/tests/test_arrows.py +109 -0
  471. vispy/visuals/tests/test_axis.py +120 -0
  472. vispy/visuals/tests/test_collections.py +15 -0
  473. vispy/visuals/tests/test_colorbar.py +179 -0
  474. vispy/visuals/tests/test_colormap.py +97 -0
  475. vispy/visuals/tests/test_ellipse.py +122 -0
  476. vispy/visuals/tests/test_histogram.py +24 -0
  477. vispy/visuals/tests/test_image.py +390 -0
  478. vispy/visuals/tests/test_image_complex.py +36 -0
  479. vispy/visuals/tests/test_infinite_line.py +53 -0
  480. vispy/visuals/tests/test_instanced_mesh.py +50 -0
  481. vispy/visuals/tests/test_isosurface.py +22 -0
  482. vispy/visuals/tests/test_linear_region.py +152 -0
  483. vispy/visuals/tests/test_markers.py +54 -0
  484. vispy/visuals/tests/test_mesh.py +261 -0
  485. vispy/visuals/tests/test_mesh_normals.py +218 -0
  486. vispy/visuals/tests/test_polygon.py +112 -0
  487. vispy/visuals/tests/test_rectangle.py +163 -0
  488. vispy/visuals/tests/test_regular_polygon.py +111 -0
  489. vispy/visuals/tests/test_scalable_textures.py +180 -0
  490. vispy/visuals/tests/test_sdf.py +73 -0
  491. vispy/visuals/tests/test_spectrogram.py +42 -0
  492. vispy/visuals/tests/test_text.py +95 -0
  493. vispy/visuals/tests/test_volume.py +542 -0
  494. vispy/visuals/tests/test_windbarb.py +33 -0
  495. vispy/visuals/text/__init__.py +7 -0
  496. vispy/visuals/text/_sdf_cpu.cpython-311-darwin.so +0 -0
  497. vispy/visuals/text/_sdf_cpu.pyx +110 -0
  498. vispy/visuals/text/_sdf_gpu.py +316 -0
  499. vispy/visuals/text/text.py +675 -0
  500. vispy/visuals/transforms/__init__.py +34 -0
  501. vispy/visuals/transforms/_util.py +191 -0
  502. vispy/visuals/transforms/base_transform.py +233 -0
  503. vispy/visuals/transforms/chain.py +300 -0
  504. vispy/visuals/transforms/interactive.py +98 -0
  505. vispy/visuals/transforms/linear.py +564 -0
  506. vispy/visuals/transforms/nonlinear.py +398 -0
  507. vispy/visuals/transforms/tests/__init__.py +0 -0
  508. vispy/visuals/transforms/tests/test_transforms.py +243 -0
  509. vispy/visuals/transforms/transform_system.py +339 -0
  510. vispy/visuals/tube.py +173 -0
  511. vispy/visuals/visual.py +923 -0
  512. vispy/visuals/volume.py +1335 -0
  513. vispy/visuals/windbarb.py +291 -0
  514. vispy/visuals/xyz_axis.py +34 -0
  515. vispy-0.14.0.dist-info/LICENSE.txt +36 -0
  516. vispy-0.14.0.dist-info/METADATA +218 -0
  517. vispy-0.14.0.dist-info/RECORD +519 -0
  518. vispy-0.14.0.dist-info/WHEEL +5 -0
  519. vispy-0.14.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,506 @@
1
+ import sys
2
+ from unittest import SkipTest
3
+
4
+ import numpy as np
5
+ from numpy.testing import assert_array_almost_equal
6
+
7
+ from vispy.testing import run_tests_if_main
8
+ from vispy.geometry.triangulation import Triangulation as T
9
+
10
+
11
+ def assert_array_eq(a, b):
12
+ assert a.shape == b.shape
13
+ assert a.dtype == b.dtype
14
+ mask = np.isnan(a)
15
+ assert np.all(np.isnan(b[mask]))
16
+ assert np.all(a[~mask] == b[~mask])
17
+
18
+
19
+ def test_intersect_edge_arrays():
20
+ global t
21
+ pts = np.array([
22
+ [0., 0.],
23
+ [0., 10.],
24
+ [5., 0.],
25
+ [-5., 0.],
26
+ [-1., 11.],
27
+ [1., 9.],
28
+ ])
29
+ edges = np.array([
30
+ [0, 1],
31
+ [2, 3],
32
+ [0, 3],
33
+ [4, 5],
34
+ [4, 1],
35
+ [0, 1],
36
+ ])
37
+
38
+ lines = pts[edges]
39
+ t = T(pts, edges)
40
+
41
+ # intersect array of one edge with a array of many edges
42
+ intercepts = t._intersect_edge_arrays(lines[0:1], lines[1:])
43
+ expect = np.array([0.5, 0.0, 0.5, 1.0, np.nan])
44
+ assert_array_eq(intercepts, expect)
45
+
46
+ # intersect every line with every line
47
+ intercepts = t._intersect_edge_arrays(lines[:, np.newaxis, ...],
48
+ lines[np.newaxis, ...])
49
+ for i in range(lines.shape[0]):
50
+ int2 = t._intersect_edge_arrays(lines[i], lines)
51
+ assert_array_eq(intercepts[i], int2)
52
+
53
+
54
+ def test_edge_intersections():
55
+ global t
56
+ pts = np.array([
57
+ [0, 0],
58
+ [1, 0],
59
+ [1, 1],
60
+ [0, 1],
61
+ [0, 0.5], # three edges intersect here
62
+ [2, 0.5],
63
+ [-1, 0.2],
64
+ [2, 0.8],
65
+ [-1, 1],
66
+ [0, 0.5],
67
+ ])
68
+ edges = np.array([
69
+ [0, 1],
70
+ [1, 2],
71
+ [2, 3],
72
+ [3, 0],
73
+ [4, 5],
74
+ [6, 7],
75
+ [8, 9],
76
+ ])
77
+
78
+ t = T(pts, edges)
79
+
80
+ # first test find_edge_intersections
81
+ cuts = t._find_edge_intersections()
82
+ expect = {
83
+ 0: [],
84
+ 1: [(0.5, [1., 0.5]),
85
+ (0.6, [1., 0.6])],
86
+ 2: [],
87
+ 3: [(0.5, [0., 0.5]),
88
+ (0.6, [0., 0.4])],
89
+ 4: [(0.25, [0.5, 0.5]),
90
+ (0.5, [1., 0.5])],
91
+ 5: [(1./3., [0., 0.4]),
92
+ (0.5, [0.5, 0.5]),
93
+ (2./3., [1., 0.6])],
94
+ }
95
+
96
+ assert len(expect) == len(cuts)
97
+ for k, v in expect.items():
98
+ assert len(v) == len(cuts[k])
99
+ for i, ecut in enumerate(v):
100
+ vcut = cuts[k][i]
101
+ assert len(vcut) == len(ecut)
102
+ for j in range(len(vcut)):
103
+ assert_array_almost_equal(np.array(ecut[j]), np.array(vcut[j]))
104
+
105
+ # next test that we can split the edges correctly
106
+ t._split_intersecting_edges()
107
+ pts = np.array([[0., 0.],
108
+ [1., 0.],
109
+ [1., 1.],
110
+ [0., 1.],
111
+ [0., 0.5],
112
+ [2., 0.5],
113
+ [-1., 0.2],
114
+ [2., 0.8],
115
+ [-1., 1.],
116
+ [0., 0.5],
117
+ [1., 0.5],
118
+ [1., 0.6],
119
+ [0., 0.5],
120
+ [0., 0.4],
121
+ [0.5, 0.5],
122
+ [1., 0.5],
123
+ [0., 0.4],
124
+ [0.5, 0.5],
125
+ [1., 0.6]])
126
+ edges = np.array([[0, 1],
127
+ [1, 10],
128
+ [2, 3],
129
+ [3, 12],
130
+ [4, 14],
131
+ [6, 16],
132
+ [8, 9],
133
+ [10, 11],
134
+ [11, 2],
135
+ [12, 13],
136
+ [13, 0],
137
+ [14, 15],
138
+ [15, 5],
139
+ [16, 17],
140
+ [17, 18],
141
+ [18, 7]])
142
+
143
+ if sys.version[0] == '3':
144
+ raise SkipTest('Triangulation differences on Py3k')
145
+ assert_array_almost_equal(pts, t.pts)
146
+ assert np.all(edges == t.edges)
147
+
148
+ # Test _nearly_ parallel lines.
149
+ pts = np.array([[0., 0.],
150
+ [1.62434542, 0.],
151
+ [1.62434542, -0.61175638],
152
+ [1.09617364, -0.61175638]])
153
+
154
+ edges = np.array([[0, 1], [1, 2], [2, 3], [3, 0]])
155
+ t = T(pts, edges)
156
+ for edge, cuts in t._find_edge_intersections().items():
157
+ assert len(cuts) == 0
158
+
159
+
160
+ def test_merge_duplicate_points():
161
+ global t
162
+ pts = np.array([
163
+ [0, 0],
164
+ [1, 1],
165
+ [0.1, 0.7],
166
+ [2, 3],
167
+ [0, 0],
168
+ [0.1, 0.7],
169
+ [5, 6],
170
+ ])
171
+ edges = np.array([
172
+ [0, 6],
173
+ [1, 5],
174
+ [2, 4],
175
+ [3, 6],
176
+ [4, 5],
177
+ ])
178
+
179
+ t = T(pts, edges)
180
+ t._merge_duplicate_points()
181
+
182
+ pts = np.array([
183
+ [0, 0],
184
+ [1, 1],
185
+ [0.1, 0.7],
186
+ [2, 3],
187
+ [5, 6],
188
+ ])
189
+ edges = np.array([
190
+ [0, 4],
191
+ [1, 2],
192
+ [2, 0],
193
+ [3, 4],
194
+ [0, 2],
195
+ ])
196
+ assert np.allclose(t.pts, pts)
197
+ assert np.all(t.edges == edges)
198
+
199
+
200
+ def test_initialize():
201
+ # check points are correctly sorted
202
+ # check artificial points are outside bounds of all others
203
+ # check tops / bottoms
204
+ pass
205
+
206
+
207
+ def test_utility_methods():
208
+ global t
209
+ pts = np.array([
210
+ [0, 0],
211
+ [1, 0],
212
+ [2, 0],
213
+ [3, 0],
214
+ [1.5, 2],
215
+ [1.5, -2],
216
+ ])
217
+ edges = np.array([
218
+ [4, 5], # edge cuts through triangle (1, 2, 4)
219
+ ])
220
+
221
+ t = T(pts, edges)
222
+ # skip initialization and just simulate being part-way through
223
+ # triangulation
224
+ for tri in [[0, 1, 4], [1, 2, 4], [2, 3, 4]]:
225
+ t._add_tri(*tri)
226
+
227
+ # find_cut_triangle
228
+ assert t._find_cut_triangle((4, 5)) == (4, 1, 2)
229
+
230
+ # orientation
231
+ assert t._orientation((4, 5), 0) == 1
232
+ assert t._orientation((4, 5), 1) == 1
233
+ assert t._orientation((4, 5), 2) == -1
234
+ assert t._orientation((4, 5), 3) == -1
235
+ assert t._orientation((4, 5), 4) == 0
236
+ assert t._orientation((4, 5), 5) == 0
237
+
238
+ # adjacent_tri
239
+ assert t._adjacent_tri((1, 4), 0) == (4, 1, 2)
240
+ assert t._adjacent_tri((0, 4), 1) is None
241
+ assert t._adjacent_tri((1, 4), (1, 4, 0)) == (4, 1, 2)
242
+ assert t._adjacent_tri((0, 4), (1, 4, 0)) is None
243
+ try:
244
+ t._adjacent_tri((1, 4), 5)
245
+ except RuntimeError:
246
+ pass
247
+ else:
248
+ raise Exception("Expected RuntimeError.")
249
+
250
+ # edges_intersect
251
+ assert not t._edges_intersect((0, 1), (1, 2))
252
+ assert not t._edges_intersect((0, 2), (1, 2))
253
+ assert t._edges_intersect((4, 5), (1, 2))
254
+
255
+ # is_constraining_edge
256
+ assert t._is_constraining_edge((4, 5))
257
+ assert t._is_constraining_edge((5, 4))
258
+ assert not t._is_constraining_edge((3, 5))
259
+ assert not t._is_constraining_edge((3, 2))
260
+
261
+
262
+ def test_projection():
263
+ pts = np.array([[0, 0],
264
+ [5, 0],
265
+ [1, 2],
266
+ [3, 4]])
267
+ t = T(pts, np.zeros((0, 2)))
268
+
269
+ a, b, c, d = pts
270
+ assert np.allclose(t._projection(a, c, b), [1, 0])
271
+ assert np.allclose(t._projection(b, c, a), [1, 0])
272
+ assert np.allclose(t._projection(a, d, b), [3, 0])
273
+ assert np.allclose(t._projection(b, d, a), [3, 0])
274
+ assert np.allclose(t._projection(a, b, c), [1, 2])
275
+ assert np.allclose(t._projection(c, b, a), [1, 2])
276
+
277
+
278
+ def test_random():
279
+ # Just test that these triangulate without exception.
280
+ # TODO: later on, we can turn this same test into an image comparison
281
+ # with Polygon.
282
+ N = 10
283
+ np.random.seed(0)
284
+
285
+ for i in range(4):
286
+ pts = np.random.normal(size=(N, 2))
287
+ edges = np.zeros((N, 2), dtype=int)
288
+ edges[:, 0] = np.arange(N)
289
+ edges[:, 1] = np.arange(1, N+1) % N
290
+
291
+ t = T(pts, edges)
292
+ t.triangulate()
293
+
294
+ theta = np.linspace(0, 2*np.pi, 11)[:-1]
295
+ pts = np.hstack([np.cos(theta)[:, np.newaxis],
296
+ np.sin(theta)[:, np.newaxis]])
297
+ pts[::2] *= 0.4
298
+ edges = np.empty((pts.shape[0], 2), dtype=np.uint)
299
+ edges[:, 0] = np.arange(pts.shape[0])
300
+ edges[:, 1] = edges[:, 0] + 1
301
+ edges[-1, 1] = 0
302
+ t = T(pts, edges)
303
+ t.triangulate()
304
+
305
+ # much larger test
306
+ # this should pass, but takes forever..
307
+ # N = 4000
308
+ # pts = np.random.normal(size=(N, 2))
309
+ # pts = np.cumsum(pts, axis=0)
310
+ # edges = np.zeros((N, 2), dtype=int)
311
+ # edges[:,0] = np.arange(N)
312
+ # edges[:,1] = np.arange(1,N+1) % N
313
+
314
+ # t = T(pts, edges)
315
+ # t.triangulate()
316
+
317
+
318
+ def test_orthogonal():
319
+ # make lines that are entirely vertical / horizontal
320
+ np.random.seed(1)
321
+ N = 100
322
+ pts = [[0, 0]]
323
+ for i in range(N - 1):
324
+ p = pts[-1][:]
325
+ p[i % 2] += np.random.normal()
326
+ pts.append(p)
327
+ pts = np.array(pts)
328
+ edges = np.zeros((N, 2), dtype=int)
329
+ edges[:, 0] = np.arange(N)
330
+ edges[:, 1] = np.arange(1, N + 1) % N
331
+
332
+ t = T(pts, edges)
333
+ t.triangulate()
334
+
335
+
336
+ def test_edge_event():
337
+ # mode 1
338
+ pts = np.array([[0, 0],
339
+ [5, -10],
340
+ [10, 0],
341
+ [6, -5],
342
+ [5, 5],
343
+ ])
344
+ inds = np.arange(pts.shape[0])[:, np.newaxis]
345
+ edges = np.hstack([inds, np.roll(inds, -1)])
346
+
347
+ t = T(pts, edges)
348
+ t.triangulate()
349
+
350
+ t = T(pts * [-1, 1], edges)
351
+ t.triangulate()
352
+
353
+ # mode 2
354
+ pts = np.array([[0, 0],
355
+ [10, 0],
356
+ [20, 0],
357
+ [5, 11],
358
+ ])
359
+ inds = np.arange(pts.shape[0])[:, np.newaxis]
360
+ edges = np.hstack([inds, np.roll(inds, -1)])
361
+
362
+ t = T(pts, edges)
363
+ t.triangulate()
364
+
365
+ t = T(pts * [-1, 1], edges)
366
+ t.triangulate()
367
+
368
+ # mode 1, 2
369
+ pts = np.array([[0, 0],
370
+ [10, 0],
371
+ [20, 0],
372
+ [5, 11],
373
+ [9, 10],
374
+ [0, 20],
375
+ ])
376
+ inds = np.arange(pts.shape[0])[:, np.newaxis]
377
+ edges = np.hstack([inds, np.roll(inds, -1)])
378
+
379
+ t = T(pts, edges)
380
+ t.triangulate()
381
+
382
+ t = T(pts * [-1, 1], edges)
383
+ t.triangulate()
384
+
385
+ # mode 2, 1
386
+ pts = np.array([[0, 0],
387
+ [10, 0],
388
+ [20, 0],
389
+ [15, 8],
390
+ [15, 1],
391
+ [-5, 10],
392
+ ])
393
+ inds = np.arange(pts.shape[0])[:, np.newaxis]
394
+ edges = np.hstack([inds, np.roll(inds, -1)])
395
+
396
+ t = T(pts, edges)
397
+ t.triangulate()
398
+
399
+ t = T(pts * [-1, 1], edges)
400
+ t.triangulate()
401
+
402
+ # mode 2, 1 with many triangles
403
+ pts = np.array([[0, 10],
404
+ [2, 8],
405
+ [4, 6],
406
+ [6, 4],
407
+ [8, 2],
408
+ [10, 0],
409
+
410
+ [20, 5],
411
+ [20, 20],
412
+
413
+ [2, 13],
414
+ [4, 11],
415
+ [6, 9],
416
+ [8, 7],
417
+ [10, 5],
418
+
419
+ [10, 1],
420
+ [0, 15],
421
+ ])
422
+ inds = np.arange(pts.shape[0])[:, np.newaxis]
423
+ edges = np.hstack([inds, np.roll(inds, -1)])
424
+
425
+ t = T(pts, edges)
426
+ t.triangulate()
427
+
428
+ t = T(pts * [-1, 1], edges)
429
+ t.triangulate()
430
+
431
+ # mode 1, 2, 1, 2, 1
432
+ pts = np.array([[0, 10],
433
+ [2, 9],
434
+ [4, 8],
435
+ [6, 7],
436
+ [8, 6],
437
+ [10, 5],
438
+
439
+ [20, 5],
440
+ [20, 20],
441
+
442
+ [2, 11],
443
+ [19, 19],
444
+ [6, 9],
445
+ [19, 18],
446
+ [10, 7],
447
+
448
+ [11, 5.1],
449
+ [0, 11.1],
450
+ ])
451
+ inds = np.arange(pts.shape[0])[:, np.newaxis]
452
+ edges = np.hstack([inds, np.roll(inds, -1)])
453
+
454
+ t = T(pts, edges)
455
+ t.triangulate()
456
+
457
+ t = T(pts * [-1, 1], edges)
458
+ t.triangulate()
459
+
460
+ # mode 2, 1, 2, 1
461
+ pts = np.array([[0, 10],
462
+ [2, 9],
463
+ [4, 8],
464
+ [6, 7],
465
+ [8, 6],
466
+ [10, 5],
467
+
468
+ [20, 5],
469
+ [20, 20],
470
+
471
+ [6, 9],
472
+ [19, 18],
473
+ [10, 7],
474
+
475
+ [11, 5.1],
476
+ [0, 11.1],
477
+ ])
478
+ inds = np.arange(pts.shape[0])[:, np.newaxis]
479
+ edges = np.hstack([inds, np.roll(inds, -1)])
480
+
481
+ t = T(pts, edges)
482
+ t.triangulate()
483
+
484
+ t = T(pts * [-1, 1], edges)
485
+ t.triangulate()
486
+
487
+ # 1, 2 upper/lower polygon order check
488
+ pts = np.array([[-5, 0],
489
+ [-3, 0],
490
+ [10, 0],
491
+ [15, 15],
492
+ [4, 9],
493
+ [6, 8.8],
494
+ [9, 10],
495
+ ])
496
+ inds = np.arange(pts.shape[0])[:, np.newaxis]
497
+ edges = np.hstack([inds, np.roll(inds, -1)])
498
+
499
+ t = T(pts, edges)
500
+ t.triangulate()
501
+
502
+ t = T(pts * [-1, 1], edges)
503
+ t.triangulate()
504
+
505
+
506
+ run_tests_if_main()
@@ -0,0 +1,142 @@
1
+ from __future__ import division
2
+
3
+ import numpy as np
4
+ from math import gcd
5
+
6
+
7
+ class TorusKnot(object):
8
+ """Representation of a torus knot or link.
9
+
10
+ A torus knot is one that can be drawn on the surface of a
11
+ torus. It is parameterised by two integers p and q as below; in
12
+ fact this returns a single knot (a single curve) only if p and q
13
+ are coprime, otherwise it describes multiple linked curves.
14
+
15
+ Parameters
16
+ ----------
17
+ p : int
18
+ The number of times the knot winds around the outside of the
19
+ torus. Defaults to 2.
20
+ q : int
21
+ The number of times the knot passes through the hole in the
22
+ centre of the torus. Defaults to 3.
23
+ num_points : int
24
+ The number of points in the returned piecewise linear
25
+ curve. If there are multiple curves (i.e. a torus link), this
26
+ is the number of points in *each* curve. Defaults to 100.
27
+ major_radius : float
28
+ Distance from the center of the torus tube to the center of the torus.
29
+ Defaults to 10.
30
+ minor_radius : float
31
+ The radius of the torus tube. Defaults to 5.
32
+
33
+ """
34
+
35
+ def __init__(self, p=3, q=2, num_points=100, major_radius=10.,
36
+ minor_radius=5.):
37
+ self._p = p
38
+ self._q = q
39
+ self._num_points = num_points
40
+ self._major_radius = major_radius
41
+ self._minor_radius = minor_radius
42
+
43
+ self._calculate_vertices()
44
+
45
+ def _calculate_vertices(self):
46
+ angles = np.linspace(0, 2*np.pi, self._num_points)
47
+
48
+ num_components = self.num_components
49
+
50
+ divisions = (np.max([self._q, self._p]) *
51
+ np.min([self._q, self._p]) // self.num_components)
52
+ starting_angles = np.linspace(
53
+ 0, 2*np.pi, divisions + 1)[
54
+ :num_components]
55
+ q = self._q / num_components
56
+ p = self._p / num_components
57
+
58
+ components = []
59
+ for starting_angle in starting_angles:
60
+ vertices = np.zeros((self._num_points, 3))
61
+ local_angles = angles + starting_angle
62
+ radii = (self._minor_radius * np.cos(q * angles) +
63
+ self._major_radius)
64
+ vertices[:, 0] = radii * np.cos(p * local_angles)
65
+ vertices[:, 1] = radii * np.sin(p * local_angles)
66
+ vertices[:, 2] = (self._minor_radius * -1 *
67
+ np.sin(q * angles))
68
+ components.append(vertices)
69
+
70
+ self._components = components
71
+
72
+ @property
73
+ def first_component(self):
74
+ """The vertices of the first component line of the torus knot or link."""
75
+ return self._components[0]
76
+
77
+ @property
78
+ def components(self):
79
+ """A list of the vertices in each line of the torus knot or link.
80
+ Even if p and q are coprime, this is a list with just one
81
+ entry.
82
+ """
83
+ return self._components
84
+
85
+ @property
86
+ def num_components(self):
87
+ """The number of component lines in the torus link. This is equal
88
+ to the greatest common divisor of p and q.
89
+ """
90
+ return gcd(self._p, self._q)
91
+
92
+ @property
93
+ def q(self):
94
+ """The q parameter of the torus knot or link."""
95
+ return self._q
96
+
97
+ @q.setter
98
+ def q(self, q):
99
+ self._q = q
100
+ self._calculate_vertices()
101
+
102
+ @property
103
+ def p(self):
104
+ """The p parameter of the torus knot or link."""
105
+ return self._p
106
+
107
+ @p.setter
108
+ def p(self, p):
109
+ self._p = p
110
+ self._calculate_vertices()
111
+
112
+ @property
113
+ def minor_radius(self):
114
+ """The minor radius of the torus."""
115
+ return self._minor_radius
116
+
117
+ @minor_radius.setter
118
+ def minor_radius(self, r):
119
+ self._minor_radius = r
120
+ self._calculate_vertices()
121
+
122
+ @property
123
+ def major_radius(self):
124
+ """The major radius of the torus."""
125
+ return self._major_radius
126
+
127
+ @major_radius.setter
128
+ def major_radius(self, r):
129
+ self._major_radius = r
130
+ self._calculate_vertices()
131
+
132
+ @property
133
+ def num_points(self):
134
+ """The number of points in the vertices returned for each knot/link
135
+ component
136
+ """
137
+ return self._num_points
138
+
139
+ @num_points.setter
140
+ def num_points(self, r):
141
+ self._num_points = r
142
+ self._calculate_vertices()