toxiclibs 0.2-java → 0.5.0-java

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.
Files changed (383) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +16 -0
  3. data/CHANGELOG.md +4 -0
  4. data/LICENSE +675 -0
  5. data/README.md +12 -5
  6. data/Rakefile +25 -82
  7. data/examples/attract_repel/attract_repel.rb +30 -0
  8. data/examples/attract_repel/attractor.rb +23 -0
  9. data/examples/attract_repel/particle.rb +27 -0
  10. data/examples/data/ti_yong.png +0 -0
  11. data/examples/force_directed/cluster.rb +76 -0
  12. data/examples/force_directed/force_directed_graph.rb +92 -0
  13. data/examples/force_directed/node.rb +26 -0
  14. data/examples/gray_scott_image.rb +75 -0
  15. data/examples/gray_scott_tone_map.rb +77 -0
  16. data/examples/implicit.rb +139 -0
  17. data/examples/inflate_mesh.rb +89 -0
  18. data/examples/model_align.rb +44 -0
  19. data/examples/povmesh/ftest.rb +46 -0
  20. data/examples/povmesh/tentacle.rb +73 -0
  21. data/examples/simple_cluster/cluster.rb +47 -0
  22. data/examples/simple_cluster/node.rb +27 -0
  23. data/examples/simple_cluster/simple_cluster.rb +60 -0
  24. data/examples/soft_body/blanket.rb +45 -0
  25. data/examples/soft_body/connection.rb +16 -0
  26. data/examples/soft_body/particle.rb +22 -0
  27. data/examples/soft_body/soft_body_square_adapted.rb +55 -0
  28. data/lib/toxiclibs.jar +0 -0
  29. data/lib/toxiclibs.rb +91 -32
  30. data/lib/toxiclibs/version.rb +1 -1
  31. data/pom.xml +122 -0
  32. data/src/com/toxi/net/ClientListener.java +41 -0
  33. data/src/com/toxi/net/ServerListener.java +70 -0
  34. data/src/com/toxi/net/ServerListenerAdapter.java +47 -0
  35. data/src/com/toxi/net/ServerState.java +18 -0
  36. data/src/com/toxi/net/UDPConnection.java +66 -0
  37. data/src/com/toxi/net/UDPSyncClient.java +81 -0
  38. data/src/com/toxi/net/UDPSyncServer.java +450 -0
  39. data/src/com/toxi/nio/UDPClient.java +121 -0
  40. data/src/com/toxi/nio/UDPClientState.java +32 -0
  41. data/src/com/toxi/nio/UDPServer.java +129 -0
  42. data/src/toxi/color/AccessCriteria.java +114 -0
  43. data/src/toxi/color/AlphaAccessor.java +67 -0
  44. data/src/toxi/color/CMYKAccessor.java +122 -0
  45. data/src/toxi/color/CMYKDistanceProxy.java +40 -0
  46. data/src/toxi/color/ColorGradient.java +260 -0
  47. data/src/toxi/color/ColorList.java +699 -0
  48. data/src/toxi/color/ColorRange.java +671 -0
  49. data/src/toxi/color/ColorTheme.java +163 -0
  50. data/src/toxi/color/DistanceProxy.java +44 -0
  51. data/src/toxi/color/HSVAccessor.java +113 -0
  52. data/src/toxi/color/HSVDistanceProxy.java +40 -0
  53. data/src/toxi/color/HistEntry.java +85 -0
  54. data/src/toxi/color/Histogram.java +185 -0
  55. data/src/toxi/color/Hue.java +249 -0
  56. data/src/toxi/color/LuminanceAccessor.java +78 -0
  57. data/src/toxi/color/NamedColor.java +935 -0
  58. data/src/toxi/color/ProximityComparator.java +70 -0
  59. data/src/toxi/color/RGBAccessor.java +113 -0
  60. data/src/toxi/color/RGBDistanceProxy.java +41 -0
  61. data/src/toxi/color/ReadonlyTColor.java +296 -0
  62. data/src/toxi/color/TColor.java +1677 -0
  63. data/src/toxi/color/TColorAdapter.java +68 -0
  64. data/src/toxi/color/ToneMap.java +218 -0
  65. data/src/toxi/color/theory/AnalogousStrategy.java +140 -0
  66. data/src/toxi/color/theory/ColorTheoryRegistry.java +139 -0
  67. data/src/toxi/color/theory/ColorTheoryStrategy.java +56 -0
  68. data/src/toxi/color/theory/ComplementaryStrategy.java +111 -0
  69. data/src/toxi/color/theory/CompoundTheoryStrategy.java +143 -0
  70. data/src/toxi/color/theory/LeftSplitComplementaryStrategy.java +82 -0
  71. data/src/toxi/color/theory/MonochromeTheoryStrategy.java +103 -0
  72. data/src/toxi/color/theory/RightSplitComplementaryStrategy.java +82 -0
  73. data/src/toxi/color/theory/SingleComplementStrategy.java +76 -0
  74. data/src/toxi/color/theory/SplitComplementaryStrategy.java +77 -0
  75. data/src/toxi/color/theory/TetradTheoryStrategy.java +114 -0
  76. data/src/toxi/color/theory/TriadTheoryStrategy.java +77 -0
  77. data/src/toxi/data/csv/CSVAdapter.java +74 -0
  78. data/src/toxi/data/csv/CSVFieldMapper.java +212 -0
  79. data/src/toxi/data/csv/CSVListener.java +61 -0
  80. data/src/toxi/data/csv/CSVParser.java +202 -0
  81. data/src/toxi/data/feeds/AtomAuthor.java +49 -0
  82. data/src/toxi/data/feeds/AtomContent.java +50 -0
  83. data/src/toxi/data/feeds/AtomEntry.java +111 -0
  84. data/src/toxi/data/feeds/AtomFeed.java +129 -0
  85. data/src/toxi/data/feeds/AtomLink.java +62 -0
  86. data/src/toxi/data/feeds/RSSChannel.java +88 -0
  87. data/src/toxi/data/feeds/RSSEnclosure.java +60 -0
  88. data/src/toxi/data/feeds/RSSFeed.java +99 -0
  89. data/src/toxi/data/feeds/RSSItem.java +104 -0
  90. data/src/toxi/data/feeds/util/EntityStripper.java +2480 -0
  91. data/src/toxi/data/feeds/util/Iso8601DateAdapter.java +101 -0
  92. data/src/toxi/data/feeds/util/Rfc822DateAdapter.java +93 -0
  93. data/src/toxi/geom/AABB.java +658 -0
  94. data/src/toxi/geom/Axis3D.java +116 -0
  95. data/src/toxi/geom/AxisAlignedCylinder.java +163 -0
  96. data/src/toxi/geom/BernsteinPolynomial.java +94 -0
  97. data/src/toxi/geom/BezierCurve2D.java +159 -0
  98. data/src/toxi/geom/BezierCurve3D.java +148 -0
  99. data/src/toxi/geom/BooleanShapeBuilder.java +185 -0
  100. data/src/toxi/geom/BoxIntersector.java +52 -0
  101. data/src/toxi/geom/Circle.java +230 -0
  102. data/src/toxi/geom/CircleIntersector.java +85 -0
  103. data/src/toxi/geom/Cone.java +150 -0
  104. data/src/toxi/geom/ConvexPolygonClipper.java +136 -0
  105. data/src/toxi/geom/CoordinateExtractor.java +16 -0
  106. data/src/toxi/geom/Ellipse.java +250 -0
  107. data/src/toxi/geom/GMatrix.java +2599 -0
  108. data/src/toxi/geom/GVector.java +833 -0
  109. data/src/toxi/geom/GlobalGridTesselator.java +54 -0
  110. data/src/toxi/geom/GridTesselator.java +108 -0
  111. data/src/toxi/geom/Intersector2D.java +49 -0
  112. data/src/toxi/geom/Intersector3D.java +51 -0
  113. data/src/toxi/geom/IsectData2D.java +103 -0
  114. data/src/toxi/geom/IsectData3D.java +103 -0
  115. data/src/toxi/geom/Line2D.java +534 -0
  116. data/src/toxi/geom/Line3D.java +471 -0
  117. data/src/toxi/geom/LineStrip2D.java +430 -0
  118. data/src/toxi/geom/LineStrip3D.java +230 -0
  119. data/src/toxi/geom/LocalGridTesselator.java +57 -0
  120. data/src/toxi/geom/Matrix3d.java +3048 -0
  121. data/src/toxi/geom/Matrix4f.java +3446 -0
  122. data/src/toxi/geom/Matrix4x4.java +1076 -0
  123. data/src/toxi/geom/MatrixSizeException.java +58 -0
  124. data/src/toxi/geom/OctreeVisitor.java +44 -0
  125. data/src/toxi/geom/Origin3D.java +148 -0
  126. data/src/toxi/geom/Plane.java +293 -0
  127. data/src/toxi/geom/PlaneIntersector.java +57 -0
  128. data/src/toxi/geom/PointCloud3D.java +253 -0
  129. data/src/toxi/geom/PointOctree.java +502 -0
  130. data/src/toxi/geom/PointQuadtree.java +375 -0
  131. data/src/toxi/geom/Polygon2D.java +1038 -0
  132. data/src/toxi/geom/PolygonClipper2D.java +45 -0
  133. data/src/toxi/geom/PolygonTesselator.java +20 -0
  134. data/src/toxi/geom/QuadtreeVisitor.java +44 -0
  135. data/src/toxi/geom/Quaternion.java +641 -0
  136. data/src/toxi/geom/Ray2D.java +146 -0
  137. data/src/toxi/geom/Ray3D.java +150 -0
  138. data/src/toxi/geom/Ray3DIntersector.java +75 -0
  139. data/src/toxi/geom/ReadonlyVec2D.java +575 -0
  140. data/src/toxi/geom/ReadonlyVec3D.java +628 -0
  141. data/src/toxi/geom/ReadonlyVec4D.java +431 -0
  142. data/src/toxi/geom/Rect.java +720 -0
  143. data/src/toxi/geom/Reflector3D.java +58 -0
  144. data/src/toxi/geom/Shape2D.java +94 -0
  145. data/src/toxi/geom/Shape3D.java +42 -0
  146. data/src/toxi/geom/SingularMatrixException.java +57 -0
  147. data/src/toxi/geom/SpatialBins.java +182 -0
  148. data/src/toxi/geom/SpatialIndex.java +61 -0
  149. data/src/toxi/geom/Sphere.java +224 -0
  150. data/src/toxi/geom/SphereIntersectorReflector.java +196 -0
  151. data/src/toxi/geom/Spline2D.java +349 -0
  152. data/src/toxi/geom/Spline3D.java +351 -0
  153. data/src/toxi/geom/SutherlandHodgemanClipper.java +151 -0
  154. data/src/toxi/geom/Triangle2D.java +422 -0
  155. data/src/toxi/geom/Triangle3D.java +456 -0
  156. data/src/toxi/geom/TriangleIntersector.java +105 -0
  157. data/src/toxi/geom/Vec2D.java +1328 -0
  158. data/src/toxi/geom/Vec3D.java +1832 -0
  159. data/src/toxi/geom/Vec4D.java +985 -0
  160. data/src/toxi/geom/VecMathUtil.java +100 -0
  161. data/src/toxi/geom/XAxisCylinder.java +64 -0
  162. data/src/toxi/geom/YAxisCylinder.java +65 -0
  163. data/src/toxi/geom/ZAxisCylinder.java +64 -0
  164. data/src/toxi/geom/mesh/BezierPatch.java +200 -0
  165. data/src/toxi/geom/mesh/BoxSelector.java +62 -0
  166. data/src/toxi/geom/mesh/DefaultSTLColorModel.java +67 -0
  167. data/src/toxi/geom/mesh/DefaultSelector.java +50 -0
  168. data/src/toxi/geom/mesh/Face.java +176 -0
  169. data/src/toxi/geom/mesh/LaplacianSmooth.java +80 -0
  170. data/src/toxi/geom/mesh/MaterialiseSTLColorModel.java +150 -0
  171. data/src/toxi/geom/mesh/Mesh3D.java +224 -0
  172. data/src/toxi/geom/mesh/MeshIntersector.java +91 -0
  173. data/src/toxi/geom/mesh/OBJWriter.java +194 -0
  174. data/src/toxi/geom/mesh/PLYWriter.java +167 -0
  175. data/src/toxi/geom/mesh/PlaneSelector.java +90 -0
  176. data/src/toxi/geom/mesh/STLColorModel.java +54 -0
  177. data/src/toxi/geom/mesh/STLReader.java +185 -0
  178. data/src/toxi/geom/mesh/STLWriter.java +323 -0
  179. data/src/toxi/geom/mesh/SphereFunction.java +156 -0
  180. data/src/toxi/geom/mesh/SphericalHarmonics.java +110 -0
  181. data/src/toxi/geom/mesh/SuperEllipsoid.java +110 -0
  182. data/src/toxi/geom/mesh/SurfaceFunction.java +75 -0
  183. data/src/toxi/geom/mesh/SurfaceMeshBuilder.java +149 -0
  184. data/src/toxi/geom/mesh/Terrain.java +451 -0
  185. data/src/toxi/geom/mesh/TriangleMesh.java +1201 -0
  186. data/src/toxi/geom/mesh/Vertex.java +78 -0
  187. data/src/toxi/geom/mesh/VertexSelector.java +193 -0
  188. data/src/toxi/geom/mesh/WEFace.java +100 -0
  189. data/src/toxi/geom/mesh/WEMeshFilterStrategy.java +51 -0
  190. data/src/toxi/geom/mesh/WETriangleMesh.java +761 -0
  191. data/src/toxi/geom/mesh/WEVertex.java +134 -0
  192. data/src/toxi/geom/mesh/WingedEdge.java +115 -0
  193. data/src/toxi/geom/mesh/subdiv/CentroidSubdiv.java +37 -0
  194. data/src/toxi/geom/mesh/subdiv/DisplacementSubdivision.java +85 -0
  195. data/src/toxi/geom/mesh/subdiv/DualDisplacementSubdivision.java +94 -0
  196. data/src/toxi/geom/mesh/subdiv/DualSubdivision.java +49 -0
  197. data/src/toxi/geom/mesh/subdiv/EdgeLengthComparator.java +50 -0
  198. data/src/toxi/geom/mesh/subdiv/FaceCountComparator.java +51 -0
  199. data/src/toxi/geom/mesh/subdiv/MidpointDisplacementSubdivision.java +80 -0
  200. data/src/toxi/geom/mesh/subdiv/MidpointSubdiv.java +42 -0
  201. data/src/toxi/geom/mesh/subdiv/MidpointSubdivision.java +48 -0
  202. data/src/toxi/geom/mesh/subdiv/NewSubdivStrategy.java +23 -0
  203. data/src/toxi/geom/mesh/subdiv/NormalDisplacementSubdivision.java +74 -0
  204. data/src/toxi/geom/mesh/subdiv/SubdivisionStrategy.java +83 -0
  205. data/src/toxi/geom/mesh/subdiv/TriSubdivision.java +51 -0
  206. data/src/toxi/geom/mesh2d/DelaunayTriangle.java +222 -0
  207. data/src/toxi/geom/mesh2d/DelaunayTriangulation.java +327 -0
  208. data/src/toxi/geom/mesh2d/DelaunayVertex.java +560 -0
  209. data/src/toxi/geom/mesh2d/Voronoi.java +149 -0
  210. data/src/toxi/geom/nurbs/BasicNurbsCurve.java +210 -0
  211. data/src/toxi/geom/nurbs/BasicNurbsSurface.java +233 -0
  212. data/src/toxi/geom/nurbs/ControlNet.java +148 -0
  213. data/src/toxi/geom/nurbs/CurveCreator.java +112 -0
  214. data/src/toxi/geom/nurbs/CurveUtils.java +259 -0
  215. data/src/toxi/geom/nurbs/InterpolationException.java +65 -0
  216. data/src/toxi/geom/nurbs/KnotVector.java +333 -0
  217. data/src/toxi/geom/nurbs/NurbsCreator.java +815 -0
  218. data/src/toxi/geom/nurbs/NurbsCurve.java +120 -0
  219. data/src/toxi/geom/nurbs/NurbsMeshCreator.java +145 -0
  220. data/src/toxi/geom/nurbs/NurbsSurface.java +147 -0
  221. data/src/toxi/image/util/Filter8bit.java +331 -0
  222. data/src/toxi/image/util/TiledFrameExporter.java +162 -0
  223. data/src/toxi/math/BezierInterpolation.java +102 -0
  224. data/src/toxi/math/CircularInterpolation.java +88 -0
  225. data/src/toxi/math/CosineInterpolation.java +51 -0
  226. data/src/toxi/math/DecimatedInterpolation.java +77 -0
  227. data/src/toxi/math/ExponentialInterpolation.java +68 -0
  228. data/src/toxi/math/InterpolateStrategy.java +60 -0
  229. data/src/toxi/math/Interpolation2D.java +93 -0
  230. data/src/toxi/math/LinearInterpolation.java +46 -0
  231. data/src/toxi/math/MathUtils.java +990 -0
  232. data/src/toxi/math/NonLinearScaleMap.java +101 -0
  233. data/src/toxi/math/ScaleMap.java +183 -0
  234. data/src/toxi/math/SigmoidInterpolation.java +78 -0
  235. data/src/toxi/math/SinCosLUT.java +141 -0
  236. data/src/toxi/math/ThresholdInterpolation.java +58 -0
  237. data/src/toxi/math/ZoomLensInterpolation.java +126 -0
  238. data/src/toxi/math/conversion/UnitTranslator.java +161 -0
  239. data/src/toxi/math/noise/PerlinNoise.java +281 -0
  240. data/src/toxi/math/noise/SimplexNoise.java +542 -0
  241. data/src/toxi/math/waves/AMFMSineWave.java +143 -0
  242. data/src/toxi/math/waves/AbstractWave.java +248 -0
  243. data/src/toxi/math/waves/ConstantWave.java +48 -0
  244. data/src/toxi/math/waves/FMHarmonicSquareWave.java +155 -0
  245. data/src/toxi/math/waves/FMSawtoothWave.java +144 -0
  246. data/src/toxi/math/waves/FMSineWave.java +142 -0
  247. data/src/toxi/math/waves/FMSquareWave.java +143 -0
  248. data/src/toxi/math/waves/FMTriangleWave.java +126 -0
  249. data/src/toxi/math/waves/SineWave.java +81 -0
  250. data/src/toxi/math/waves/Wave2D.java +68 -0
  251. data/src/toxi/math/waves/WaveState.java +69 -0
  252. data/src/toxi/music/scale/AbstractScale.java +117 -0
  253. data/src/toxi/music/scale/GenericScale.java +66 -0
  254. data/src/toxi/music/scale/MajorScale.java +41 -0
  255. data/src/toxi/newmesh/AttributedEdge.java +106 -0
  256. data/src/toxi/newmesh/AttributedFace.java +63 -0
  257. data/src/toxi/newmesh/IndexedTriangleMesh.java +809 -0
  258. data/src/toxi/newmesh/MeshAttributeCompiler.java +45 -0
  259. data/src/toxi/newmesh/MeshFaceNormalCompiler.java +52 -0
  260. data/src/toxi/newmesh/MeshUVCompiler.java +52 -0
  261. data/src/toxi/newmesh/MeshVertexColorCompiler.java +49 -0
  262. data/src/toxi/newmesh/MeshVertexCompiler.java +54 -0
  263. data/src/toxi/newmesh/MeshVertexNormalCompiler.java +55 -0
  264. data/src/toxi/newmesh/SpatialIndex.java +78 -0
  265. data/src/toxi/physics2d/ParticlePath2D.java +100 -0
  266. data/src/toxi/physics2d/ParticleString2D.java +184 -0
  267. data/src/toxi/physics2d/PullBackSpring2D.java +51 -0
  268. data/src/toxi/physics2d/VerletConstrainedSpring2D.java +89 -0
  269. data/src/toxi/physics2d/VerletMinDistanceSpring2D.java +57 -0
  270. data/src/toxi/physics2d/VerletParticle2D.java +457 -0
  271. data/src/toxi/physics2d/VerletPhysics2D.java +448 -0
  272. data/src/toxi/physics2d/VerletSpring2D.java +181 -0
  273. data/src/toxi/physics2d/behaviors/AttractionBehavior2D.java +212 -0
  274. data/src/toxi/physics2d/behaviors/ConstantForceBehavior2D.java +112 -0
  275. data/src/toxi/physics2d/behaviors/GravityBehavior2D.java +61 -0
  276. data/src/toxi/physics2d/behaviors/ParticleBehavior2D.java +66 -0
  277. data/src/toxi/physics2d/constraints/AngularConstraint.java +83 -0
  278. data/src/toxi/physics2d/constraints/AxisConstraint.java +71 -0
  279. data/src/toxi/physics2d/constraints/CircularConstraint.java +69 -0
  280. data/src/toxi/physics2d/constraints/MaxConstraint.java +66 -0
  281. data/src/toxi/physics2d/constraints/MinConstraint.java +66 -0
  282. data/src/toxi/physics2d/constraints/ParticleConstraint2D.java +47 -0
  283. data/src/toxi/physics2d/constraints/PolygonConstraint.java +93 -0
  284. data/src/toxi/physics2d/constraints/RectConstraint.java +114 -0
  285. data/src/toxi/physics3d/ParticlePath3D.java +100 -0
  286. data/src/toxi/physics3d/ParticleString3D.java +184 -0
  287. data/src/toxi/physics3d/PullBackSpring3D.java +50 -0
  288. data/src/toxi/physics3d/VerletConstrainedSpring3D.java +88 -0
  289. data/src/toxi/physics3d/VerletMinDistanceSpring3D.java +56 -0
  290. data/src/toxi/physics3d/VerletParticle3D.java +385 -0
  291. data/src/toxi/physics3d/VerletPhysics3D.java +417 -0
  292. data/src/toxi/physics3d/VerletSpring3D.java +180 -0
  293. data/src/toxi/physics3d/behaviors/AttractionBehavior3D.java +182 -0
  294. data/src/toxi/physics3d/behaviors/ConstantForceBehavior3D.java +92 -0
  295. data/src/toxi/physics3d/behaviors/GravityBehavior3D.java +61 -0
  296. data/src/toxi/physics3d/behaviors/ParticleBehavior3D.java +52 -0
  297. data/src/toxi/physics3d/constraints/AxisConstraint.java +68 -0
  298. data/src/toxi/physics3d/constraints/BoxConstraint.java +121 -0
  299. data/src/toxi/physics3d/constraints/CylinderConstraint.java +87 -0
  300. data/src/toxi/physics3d/constraints/MaxConstraint.java +65 -0
  301. data/src/toxi/physics3d/constraints/MinConstraint.java +65 -0
  302. data/src/toxi/physics3d/constraints/ParticleConstraint3D.java +49 -0
  303. data/src/toxi/physics3d/constraints/PlaneConstraint.java +78 -0
  304. data/src/toxi/physics3d/constraints/SoftBoxConstraint.java +87 -0
  305. data/src/toxi/physics3d/constraints/SphereConstraint.java +108 -0
  306. data/src/toxi/processing/ArrowModifier.java +116 -0
  307. data/src/toxi/processing/DashedLineModifier.java +48 -0
  308. data/src/toxi/processing/DeltaOrientationMapper.java +57 -0
  309. data/src/toxi/processing/Line2DRenderModifier.java +18 -0
  310. data/src/toxi/processing/MeshToVBO.java +94 -0
  311. data/src/toxi/processing/NormalMapper.java +18 -0
  312. data/src/toxi/processing/POVInterface.java +121 -0
  313. data/src/toxi/processing/POVMesh.java +219 -0
  314. data/src/toxi/processing/POVWriter.java +460 -0
  315. data/src/toxi/processing/RCOpaque.java +77 -0
  316. data/src/toxi/processing/RCTransp.java +78 -0
  317. data/src/toxi/processing/TextureBuilder.java +232 -0
  318. data/src/toxi/processing/Textures.java +110 -0
  319. data/src/toxi/processing/ToxiclibsSupport.java +1239 -0
  320. data/src/toxi/processing/Tracing.java +25 -0
  321. data/src/toxi/processing/XYZNormalMapper.java +30 -0
  322. data/src/toxi/sim/automata/CAMatrix.java +297 -0
  323. data/src/toxi/sim/automata/CARule.java +76 -0
  324. data/src/toxi/sim/automata/CARule2D.java +354 -0
  325. data/src/toxi/sim/automata/CAWolfram1D.java +309 -0
  326. data/src/toxi/sim/automata/EvolvableMatrix.java +61 -0
  327. data/src/toxi/sim/automata/MatrixEvolver.java +42 -0
  328. data/src/toxi/sim/dla/BottomUpOrder.java +76 -0
  329. data/src/toxi/sim/dla/DLA.java +497 -0
  330. data/src/toxi/sim/dla/DLAConfiguration.java +364 -0
  331. data/src/toxi/sim/dla/DLAEventAdapter.java +64 -0
  332. data/src/toxi/sim/dla/DLAEventListener.java +57 -0
  333. data/src/toxi/sim/dla/DLAGuideLines.java +219 -0
  334. data/src/toxi/sim/dla/DLAParticle.java +102 -0
  335. data/src/toxi/sim/dla/DLASegment.java +88 -0
  336. data/src/toxi/sim/dla/PipelineOrder.java +50 -0
  337. data/src/toxi/sim/dla/RadialDistanceOrder.java +92 -0
  338. data/src/toxi/sim/erosion/ErosionFunction.java +122 -0
  339. data/src/toxi/sim/erosion/TalusAngleErosion.java +145 -0
  340. data/src/toxi/sim/erosion/ThermalErosion.java +75 -0
  341. data/src/toxi/sim/fluids/FluidSolver2D.java +762 -0
  342. data/src/toxi/sim/fluids/FluidSolver3D.java +326 -0
  343. data/src/toxi/sim/grayscott/GrayScott.java +469 -0
  344. data/src/toxi/util/DateUtils.java +141 -0
  345. data/src/toxi/util/FileSequenceDescriptor.java +181 -0
  346. data/src/toxi/util/FileUtils.java +467 -0
  347. data/src/toxi/util/datatypes/ArraySet.java +128 -0
  348. data/src/toxi/util/datatypes/ArrayUtil.java +404 -0
  349. data/src/toxi/util/datatypes/BiasedDoubleRange.java +141 -0
  350. data/src/toxi/util/datatypes/BiasedFloatRange.java +141 -0
  351. data/src/toxi/util/datatypes/BiasedIntegerRange.java +141 -0
  352. data/src/toxi/util/datatypes/DoubleRange.java +251 -0
  353. data/src/toxi/util/datatypes/FloatRange.java +251 -0
  354. data/src/toxi/util/datatypes/GenericSet.java +215 -0
  355. data/src/toxi/util/datatypes/IntegerRange.java +247 -0
  356. data/src/toxi/util/datatypes/IntegerSet.java +149 -0
  357. data/src/toxi/util/datatypes/ItemIndex.java +72 -0
  358. data/src/toxi/util/datatypes/SingletonRegistry.java +91 -0
  359. data/src/toxi/util/datatypes/TypedProperties.java +291 -0
  360. data/src/toxi/util/datatypes/UndirectedGraph.java +134 -0
  361. data/src/toxi/util/datatypes/UniqueItemIndex.java +223 -0
  362. data/src/toxi/util/datatypes/WeightedRandomEntry.java +76 -0
  363. data/src/toxi/util/datatypes/WeightedRandomSet.java +125 -0
  364. data/src/toxi/util/events/EventDispatcher.java +86 -0
  365. data/src/toxi/volume/AdditiveBrush.java +19 -0
  366. data/src/toxi/volume/ArrayIsoSurface.java +297 -0
  367. data/src/toxi/volume/BoxBrush.java +100 -0
  368. data/src/toxi/volume/BrushMode.java +16 -0
  369. data/src/toxi/volume/HashIsoSurface.java +354 -0
  370. data/src/toxi/volume/IsoSurface.java +59 -0
  371. data/src/toxi/volume/MarchingCubesIndex.java +312 -0
  372. data/src/toxi/volume/MeshLatticeBuilder.java +358 -0
  373. data/src/toxi/volume/MeshVoxelizer.java +216 -0
  374. data/src/toxi/volume/MultiplyBrush.java +20 -0
  375. data/src/toxi/volume/PeakBrush.java +21 -0
  376. data/src/toxi/volume/ReplaceBrush.java +19 -0
  377. data/src/toxi/volume/RoundBrush.java +113 -0
  378. data/src/toxi/volume/VolumetricBrush.java +160 -0
  379. data/src/toxi/volume/VolumetricHashMap.java +179 -0
  380. data/src/toxi/volume/VolumetricSpace.java +195 -0
  381. data/src/toxi/volume/VolumetricSpaceArray.java +214 -0
  382. data/toxiclibs.gemspec +34 -0
  383. metadata +424 -27
@@ -0,0 +1,77 @@
1
+ require 'toxiclibs'
2
+
3
+ #
4
+ # <p>GrayScottToneMap shows how to use the ColorGradient & ToneMap classes of the
5
+ # colorutils package to create a tone map for rendering the results of
6
+ # the Gray-Scott reaction-diffusion.</p>
7
+ #
8
+ # <p><strong>Usage:</strong><ul>
9
+ # <li>click + drag mouse to draw dots used as simulation seed</li>
10
+ # <li>press any key to reset</li>
11
+ # </ul></p>
12
+ #
13
+ # Copyright (c) 2010 Karsten Schmidt, JRubyArt Version (c) 2015 Martin Prout
14
+ # Easily modified to run with ruby-processing.
15
+ #
16
+ # This demo & library is free software you can redistribute it and/or
17
+ # modify it under the terms of the GNU Lesser General Public
18
+ # License as published by the Free Software Foundation either
19
+ # version 2.1 of the License, or (at your option) any later version.
20
+ #
21
+ # http://creativecommons.org/licenses/LGPL/2.1/
22
+ #
23
+ # This library is distributed in the hope that it will be useful,
24
+ # but WITHOUT ANY WARRANTY without even the implied warranty of
25
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26
+ # Lesser General Public License for more details.
27
+ #
28
+ # You should have received a copy of the GNU Lesser General Public
29
+ # License along with this library if not, write to the Free Software
30
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31
+ #
32
+
33
+ NUM_ITERATIONS = 10
34
+ attr_reader :gs, :tone_map
35
+
36
+ def settings
37
+ size 256, 256, P2D
38
+ end
39
+
40
+ def setup
41
+ sketch_title 'Gray Scott Tone Map'
42
+ @gs = Simulation::GrayScott.new width, height, false
43
+ @gs.set_coefficients 0.021, 0.076, 0.12, 0.06
44
+ # create a color gradient for 256 values
45
+ grad = Toxi::ColorGradient.new
46
+ # NamedColors are preset colors, but any TColor can be added
47
+ # see javadocs for list of names:
48
+ # http://toxiclibs.org/docs/colorutils/toxi/color/NamedColor::html
49
+ # NB: use '::' in place of '.' here for these java constants
50
+ grad.add_color_at(0, Toxi::NamedColor::BLACK)
51
+ grad.add_color_at(128, Toxi::NamedColor::RED)
52
+ grad.add_color_at(192, Toxi::NamedColor::YELLOW)
53
+ grad.add_color_at(255, Toxi::NamedColor::WHITE)
54
+ # this gradient is used to map simulation values to colors
55
+ # the first 2 parameters define the min/max values of the
56
+ # input range (Gray-Scott produces values in the interval of 0.0 - 0.5)
57
+ # setting the max = 0.33 increases the contrast
58
+ @tone_map = Toxi::ToneMap.new 0, 0.33, grad
59
+ end
60
+
61
+ def draw
62
+ @gs.set_rect(mouse_x, mouse_y, 20, 20) if mouse_pressed?
63
+ load_pixels
64
+ # update the simulation a few time steps
65
+ NUM_ITERATIONS.times { @gs.update(1) }
66
+ # read out the V result array
67
+ # and use tone map to render colours
68
+ gs.v.length.times do |i|
69
+ # NB: don't camel case convert here
70
+ pixels[i] = tone_map.getARGBToneFor(gs.v[i])
71
+ end
72
+ update_pixels
73
+ end
74
+
75
+ def key_pressed
76
+ @gs.reset
77
+ end
@@ -0,0 +1,139 @@
1
+
2
+ #
3
+ # This example implements a custom VolumetricSpace uMath.sing an implicit function
4
+ # to calculate each voxel. This is slower than the default array or HashMap
5
+ # based implementations, but also has much less memory requirements and so might
6
+ # be an interesting and more viable approach for very highres voxel spaces
7
+ # (e.g. >32 million voxels). This implementation here also demonstrates how to
8
+ # achieve an upper boundary on the iso value (in addition to the one given and
9
+ # acting as lower threshold when computing the iso surface)
10
+ #
11
+ # Usage:
12
+ # drag mouse to rotate camera
13
+ # mouse wheel zoom in/out
14
+ # l: apply laplacian mesh smooth
15
+ #
16
+ #
17
+
18
+ #
19
+ # Copyright (c) 2010 Karsten Schmidt & ruby-procesMath.sing version Martin Prout 2013
20
+ # This sketch relies on a custom ruby-procesMath.sing mesh_to_vbo library
21
+ #
22
+ # This library is free software you can redistribute it and/or
23
+ # modify it under the terms of the GNU Lesser General Public
24
+ # License as published by the Free Software Foundation either
25
+ # version 2.1 of the License, or (at your option) any later version.
26
+ #
27
+ # http://creativecommons.org/licenses/LGPL/2.1/
28
+ #
29
+ # This library is distributed in the hope that it will be useful,
30
+ # but WITHOUT ANY WARRANTY without even the implied warranty of
31
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
32
+ # Lesser General Public License for more details.
33
+ #
34
+ # You should have received a copy of the GNU Lesser General Public
35
+ # License along with this library if not, write to the Free Software
36
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
37
+ #
38
+ require 'toxiclibs'
39
+
40
+ RES = 64
41
+ ISO = 0.2
42
+ MAX_ISO = 0.66
43
+
44
+ attr_reader :mesh, :vbo, :curr_zoom, :implicit
45
+
46
+ def settings
47
+ size(720, 720, P3D)
48
+ end
49
+
50
+ def setup
51
+ sketch_title 'Implicit Surface'
52
+ Processing::ArcBall.init(self)
53
+ @vbo = Gfx::MeshToVBO.new(self)
54
+ @curr_zoom = 1
55
+ vol = EvaluatingVolume.new(TVec3D.new(400, 400, 400), RES, RES, RES, MAX_ISO)
56
+ surface = Volume::HashIsoSurface.new(vol)
57
+ @mesh = WETriangleMesh.new
58
+ surface.compute_surface_mesh(mesh, ISO)
59
+ @is_wire_frame = false
60
+ no_stroke
61
+ @implicit = vbo.mesh_to_shape(mesh, true)
62
+ implicit.setFill(color(222, 222, 222))
63
+ implicit.setAmbient(color(50, 50, 50))
64
+ implicit.setShininess(color(10, 10, 10))
65
+ implicit.setSpecular(color(50, 50, 50))
66
+ end
67
+
68
+ def draw
69
+ background(0)
70
+ lights
71
+ define_lights
72
+ shape(implicit)
73
+ end
74
+
75
+ def key_pressed
76
+ case key
77
+ when 'l', 'L'
78
+ LaplacianSmooth.new.filter(mesh, 1)
79
+ @implicit = vbo.mesh_to_shape(mesh, true)
80
+ # new mesh so need to set finish
81
+ implicit.setFill(color(222, 222, 222))
82
+ implicit.setAmbient(color(50, 50, 50))
83
+ implicit.setShininess(color(10, 10, 10))
84
+ implicit.setSpecular(color(50, 50, 50))
85
+ when 's', 'S'
86
+ save_frame("implicit.png")
87
+ when 'p', 'P'
88
+ no_loop
89
+ pm = Gfx::POVMesh.new(self)
90
+ file = java.io.File.new('implicit.inc')
91
+ pm.begin_save(file)
92
+ pm.set_texture(Gfx::Textures::WHITE)
93
+ pm.saveAsPOV(mesh, true)
94
+ pm.end_save
95
+ puts 'finisded'
96
+ end
97
+ end
98
+
99
+ def define_lights
100
+ ambient_light(50, 50, 50)
101
+ point_light(30, 30, 30, 200, -150, 0)
102
+ directional_light(0, 30, 50, 1, 0, 0)
103
+ spot_light(30, 30, 30, 0, 40, 200, 0, -0.5, -0.5, PI / 2, 2)
104
+ end
105
+
106
+ # Custom evaluating Volume Class
107
+ class EvaluatingVolume < Volume::VolumetricSpace
108
+
109
+ attr_reader :upper_bound
110
+ FREQ = Math::PI * 3.8
111
+
112
+ def initialize(scal_vec, resX, resY, resZ, upper_limit)
113
+ super(scal_vec, resX, resY, resZ)
114
+ @upper_bound = upper_limit
115
+ end
116
+
117
+ def clear
118
+ # nothing to do here
119
+ end
120
+
121
+ def getVoxelAt(i)
122
+ getVoxel(i % resX, (i % sliceRes) / resX, i / sliceRes)
123
+ end
124
+
125
+ def getVoxel(x, y, z) # can't overload so we renamed
126
+ val = 0
127
+ if (x > 0 && x < resX1 && y > 0 && y < resY1 && z > 0 && z < resZ1)
128
+ xx = x * 1.0 / resX - 0.5 # NB: careful about integer division !!!
129
+ yy = y * 1.0 / resY - 0.5
130
+ zz = z * 1.0 / resZ - 0.5
131
+ #val = Math.sin(xx * FREQ) + Math.cos(yy * FREQ) + Math.sin(zz * FREQ)
132
+ val = Math.cos(xx * FREQ) * Math.sin(yy* FREQ) + Math.cos(yy* FREQ) * Math.sin(zz* FREQ) + Math.cos(zz* FREQ)* Math.sin(xx* FREQ)
133
+ if (val > upper_bound)
134
+ val = 0
135
+ end
136
+ end
137
+ return val
138
+ end
139
+ end
@@ -0,0 +1,89 @@
1
+
2
+ require 'toxiclibs'
3
+ # A JRubyArt sketch needs refactoring for ruby-processing
4
+ #
5
+ # Copyright (c) 2010 Karsten Schmidt & JRubyArt version Martin Prout 2015
6
+ # This library is free software you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License as published by the Free Software Foundation either
9
+ # version 2.1 of the License, or (at your option) any later version.
10
+ #
11
+ # http://creativecommons.org/licenses/LGPL/2.1/
12
+ #
13
+ # This library is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
+ # Lesser General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU Lesser General Public
19
+ # License along with this library if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ #
22
+
23
+ attr_reader :mesh, :gfx, :physics, :render, :box, :pm, :inflate
24
+
25
+ def settings
26
+ size(680, 382, P3D)
27
+ end
28
+
29
+ def setup
30
+ sketch_title 'Inflate Mesh'
31
+ Processing::ArcBall.init(self)
32
+ @gfx = Gfx::ToxiclibsSupport.new(self)
33
+ init_physics
34
+ end
35
+
36
+ def draw
37
+ physics.update
38
+ box.vertices.values.each { |v| v.set(physics.particles.get(v.id)) }
39
+ box.center(nil)
40
+ box.vertices.values.each { |v| physics.particles.get(v.id).set(v) }
41
+ box.compute_face_normals
42
+ box.face_outwards
43
+ box.compute_vertex_normals
44
+ background(51)
45
+ no_fill
46
+ lights
47
+ directional_light(255, 255, 255, -200, 1000, 500)
48
+ specular(255)
49
+ shininess(16)
50
+ gfx.origin(Vec3D.new, 50)
51
+ fill(192)
52
+ no_stroke
53
+ gfx.mesh(box, true, 5)
54
+ end
55
+
56
+ def init_physics
57
+ @box = WETriangleMesh.new
58
+ # create a simple start mesh
59
+ # box.addMesh(Toxi::Cone.new(TVec3D.new(0, 0, 0), TVec3D.new(0, 1, 0), 10, 50, 100).to_mesh(4))
60
+ box.add_mesh(AABB.new(TVec3D.new, 50).to_mesh)
61
+ # then subdivide a few times...
62
+ 4.times { box.subdivide }
63
+ @physics = Physics::VerletPhysics3D.new
64
+ physics.set_world_bounds(AABB.new(TVec3D.new, 180))
65
+ # turn mesh vertices into physics particles
66
+ box.vertices.values.each { |v| physics.add_particle(Physics::VerletParticle3D.new(v)) }
67
+ # turn mesh edges into springs
68
+ box.edges.values.each do |e|
69
+ a = physics.particles.get((e.a).id)
70
+ b = physics.particles.get((e.b).id)
71
+ physics.add_spring(Physics::VerletSpring3D.new(a, b, a.distance_to(b), 0.005))
72
+ end
73
+ end
74
+
75
+ def key_pressed
76
+ case key
77
+ when 'r', 'R'
78
+ init_physics
79
+ end
80
+ end
81
+
82
+ def mouse_pressed
83
+ @inflate = Physics::AttractionBehavior3D.new(TVec3D.new, 400, -0.3, 0.001)
84
+ physics.add_behavior(inflate)
85
+ end
86
+
87
+ def mouse_released
88
+ physics.remove_behavior(inflate)
89
+ end
@@ -0,0 +1,44 @@
1
+ # This example demonstrates how to rotate a number of meshes
2
+ # so that each points towards a common & user controlled focal point.
3
+ #
4
+ # Requires toxiclibs-0.5.0+ gem
5
+ #
6
+ # (c) 2012 Karsten Schmidt / LGPL2 licensed
7
+ #
8
+ require 'toxiclibs'
9
+
10
+ # container for mesh positions
11
+
12
+ attr_reader :gfx, :positions
13
+
14
+ def settings
15
+ size(640, 480, P3D)
16
+ end
17
+
18
+ def setup
19
+ sketch_title 'Model Align'
20
+ Processing::ArcBall.init(self)
21
+ @gfx = Gfx::ToxiclibsSupport.new(self)
22
+ # compute mesh positions on circle in XZ plane
23
+ @positions = (Toxi::Circle.new(200).toPolygon2D(8)).map{ |p| p.to3DXZ }
24
+ end
25
+
26
+ def draw
27
+ background(51)
28
+ lights
29
+ no_stroke
30
+ # create manual focal point in XY plane
31
+ focus = TVec3D.new((mouse_x - width/2), (mouse_y - height/2), 0)
32
+ # create mesh prototype to draw at all generated positions
33
+ # the mesh is a simple box placed at the world origin
34
+ m = AABB.new(25).to_mesh
35
+ # draw focus
36
+ gfx.box(AABB.new(focus, 5))
37
+ # align the positive z-axis of mesh to point at focus
38
+ # mesh needs to be located at world origin for it to work correctly
39
+ # only once rotated, move it to actual position
40
+ positions.map { |p| gfx.mesh(m.copy.pointTowards(focus.sub(p), TVec3D::Z_AXIS).translate(p)) }
41
+ # draw connections from mesh centers to focal point
42
+ stroke(0,255,255)
43
+ positions.map { |p| gfx.line(p, focus) }
44
+ end
@@ -0,0 +1,46 @@
1
+ require 'toxiclibs'
2
+
3
+ attr_reader :gfx, :mesh0, :mesh1, :mesh2
4
+
5
+ def settings
6
+ size(200, 200, P3D)
7
+ smooth 4
8
+ end
9
+
10
+ def setup
11
+ sketch_title('FTest')
12
+ @gfx = Gfx::ToxiclibsSupport.new(self)
13
+ # define a rounded cube using the SuperEllipsoid surface function
14
+ vert = AABB.fromMinMax(TVec3D.new(-1.0, -3.5, -1.0), TVec3D.new(1.0, 3.5, 1.0))
15
+ box = AABB.fromMinMax(TVec3D.new(1.0, -1.5, -1.0), TVec3D.new(3.0, -3.5, 1.0))
16
+ box2 = AABB.fromMinMax(TVec3D.new(1.0, 2.0, -1.0), TVec3D.new(3.0, 0.0, 1.0))
17
+ @mesh0 = box.to_mesh
18
+ @mesh1 = vert.to_mesh
19
+ @mesh2 = box2.to_mesh
20
+ mesh0.add_mesh(mesh1)
21
+ mesh0.add_mesh(mesh2)
22
+ mesh0.compute_face_normals
23
+ mesh0.compute_vertex_normals
24
+ fileID = 'FTest'
25
+ pm = Gfx::POVMesh.new(self)
26
+ file = java.io.File.new(sketchPath(fileID + '.inc'))
27
+ pm.begin_save(file)
28
+ pm.set_texture(Gfx::Textures::CHROME)
29
+ pm.saveAsPOV(mesh0.faceOutwards, false)
30
+ # pm.set_texture(Textures::RED)
31
+ # pm.saveAsPOV(mesh1, false)
32
+ # pm.set_texture(Textures::WHITE)
33
+ # pm.saveAsPOV(mesh2, false)
34
+ pm.end_save
35
+ # exit
36
+ end
37
+
38
+ def draw
39
+ background 50, 50, 200
40
+ lights
41
+ translate(width / 2, height / 2)
42
+ scale(10)
43
+ rotateY(20.radians)
44
+ gfx.choose_stroke_fill(false, Toxi::TColor::WHITE, Toxi::TColor::RED)
45
+ gfx.mesh(mesh0)
46
+ end
@@ -0,0 +1,73 @@
1
+ require 'toxiclibs'
2
+
3
+ # A 3D Tentacle by Nikolaus Gradwohl http://www.local-guru.net
4
+ # Adapted for JRubyArt and mesh to PShape, and mesh2 export by Martin Prout
5
+
6
+ attr_reader :mesh, :gfx, :tentacle
7
+
8
+ def settings
9
+ size(500, 500, P3D)
10
+ end
11
+
12
+ def setup
13
+ sketch_title 'Tentacle'
14
+ ArcBall.init(self)
15
+ @gfx = Gfx::MeshToVBO.new(self)
16
+ volume = VolumetricSpaceArray.new(TVec3D.new(100, 200, 100), 100, 100, 100)
17
+ surface = ArrayIsoSurface.new(volume)
18
+ @mesh = TriangleMesh.new
19
+ brush = RoundBrush.new(volume, 10)
20
+ 20.times do |i|
21
+ brush.set_size(i * 1.2 + 6)
22
+ x = cos(i * TWO_PI / 20) * 10
23
+ y = sin(i * TWO_PI / 20) * 10
24
+ brush.draw_at_absolute_pos(TVec3D.new(x, -25 + i * 7, y), 1)
25
+ end
26
+ (4..20).step(4) do |i|
27
+ brush.set_size(i / 1.5 + 4)
28
+ x = cos(i * TWO_PI / 20) * (i * 1.2 + 16)
29
+ y = sin(i * TWO_PI / 20) * (i * 1.2 + 16)
30
+ brush.draw_at_absolute_pos(TVec3D.new(x, -25 + i * 7, y), 1)
31
+ brush.set_size(i / 2 + 2)
32
+ x2 = cos(i * TWO_PI / 20) * (i * 1.2 + 18)
33
+ y2 = sin(i * TWO_PI / 20) * (i * 1.2 + 18)
34
+ brush.draw_at_absolute_pos(TVec3D.new(x2, -25 + i * 7, y2), -1.4)
35
+ end
36
+ volume.close_sides
37
+ surface.reset
38
+ surface.compute_surface_mesh(mesh, 0.5)
39
+ no_stroke
40
+ @tentacle = gfx.mesh_to_shape(mesh, true)
41
+ tentacle.set_fill(color(200, 10, 10))
42
+ tentacle.set_ambient(80)
43
+ tentacle.set_specular(80)
44
+ end
45
+
46
+ def draw
47
+ background(150)
48
+ lights
49
+ setup_lights
50
+ shape(tentacle)
51
+ end
52
+
53
+ def setup_lights
54
+ lights
55
+ ambient_light(100, 100, 100)
56
+ directional_light(100, 100, 100, -1, -1, 1)
57
+ light_specular(50, 50, 50)
58
+ end
59
+
60
+ def key_pressed
61
+ case key
62
+ when 'p', 'P'
63
+ fileID = 'Tentacle'
64
+ pm = Gfx::POVMesh.new(self)
65
+ pm.begin_save(java.io.File.new(fileID + '.inc'))
66
+ pm.set_texture(Gfx::Textures::RED) # red with Phong texture
67
+ pm.saveAsPOV(mesh, true)
68
+ pm.end_save
69
+ exit
70
+ when 's', 'S'
71
+ save_frame('Tentacle.png')
72
+ end
73
+ end