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.
- checksums.yaml +4 -4
- data/.gitignore +16 -0
- data/CHANGELOG.md +4 -0
- data/LICENSE +675 -0
- data/README.md +12 -5
- data/Rakefile +25 -82
- data/examples/attract_repel/attract_repel.rb +30 -0
- data/examples/attract_repel/attractor.rb +23 -0
- data/examples/attract_repel/particle.rb +27 -0
- data/examples/data/ti_yong.png +0 -0
- data/examples/force_directed/cluster.rb +76 -0
- data/examples/force_directed/force_directed_graph.rb +92 -0
- data/examples/force_directed/node.rb +26 -0
- data/examples/gray_scott_image.rb +75 -0
- data/examples/gray_scott_tone_map.rb +77 -0
- data/examples/implicit.rb +139 -0
- data/examples/inflate_mesh.rb +89 -0
- data/examples/model_align.rb +44 -0
- data/examples/povmesh/ftest.rb +46 -0
- data/examples/povmesh/tentacle.rb +73 -0
- data/examples/simple_cluster/cluster.rb +47 -0
- data/examples/simple_cluster/node.rb +27 -0
- data/examples/simple_cluster/simple_cluster.rb +60 -0
- data/examples/soft_body/blanket.rb +45 -0
- data/examples/soft_body/connection.rb +16 -0
- data/examples/soft_body/particle.rb +22 -0
- data/examples/soft_body/soft_body_square_adapted.rb +55 -0
- data/lib/toxiclibs.jar +0 -0
- data/lib/toxiclibs.rb +91 -32
- data/lib/toxiclibs/version.rb +1 -1
- data/pom.xml +122 -0
- data/src/com/toxi/net/ClientListener.java +41 -0
- data/src/com/toxi/net/ServerListener.java +70 -0
- data/src/com/toxi/net/ServerListenerAdapter.java +47 -0
- data/src/com/toxi/net/ServerState.java +18 -0
- data/src/com/toxi/net/UDPConnection.java +66 -0
- data/src/com/toxi/net/UDPSyncClient.java +81 -0
- data/src/com/toxi/net/UDPSyncServer.java +450 -0
- data/src/com/toxi/nio/UDPClient.java +121 -0
- data/src/com/toxi/nio/UDPClientState.java +32 -0
- data/src/com/toxi/nio/UDPServer.java +129 -0
- data/src/toxi/color/AccessCriteria.java +114 -0
- data/src/toxi/color/AlphaAccessor.java +67 -0
- data/src/toxi/color/CMYKAccessor.java +122 -0
- data/src/toxi/color/CMYKDistanceProxy.java +40 -0
- data/src/toxi/color/ColorGradient.java +260 -0
- data/src/toxi/color/ColorList.java +699 -0
- data/src/toxi/color/ColorRange.java +671 -0
- data/src/toxi/color/ColorTheme.java +163 -0
- data/src/toxi/color/DistanceProxy.java +44 -0
- data/src/toxi/color/HSVAccessor.java +113 -0
- data/src/toxi/color/HSVDistanceProxy.java +40 -0
- data/src/toxi/color/HistEntry.java +85 -0
- data/src/toxi/color/Histogram.java +185 -0
- data/src/toxi/color/Hue.java +249 -0
- data/src/toxi/color/LuminanceAccessor.java +78 -0
- data/src/toxi/color/NamedColor.java +935 -0
- data/src/toxi/color/ProximityComparator.java +70 -0
- data/src/toxi/color/RGBAccessor.java +113 -0
- data/src/toxi/color/RGBDistanceProxy.java +41 -0
- data/src/toxi/color/ReadonlyTColor.java +296 -0
- data/src/toxi/color/TColor.java +1677 -0
- data/src/toxi/color/TColorAdapter.java +68 -0
- data/src/toxi/color/ToneMap.java +218 -0
- data/src/toxi/color/theory/AnalogousStrategy.java +140 -0
- data/src/toxi/color/theory/ColorTheoryRegistry.java +139 -0
- data/src/toxi/color/theory/ColorTheoryStrategy.java +56 -0
- data/src/toxi/color/theory/ComplementaryStrategy.java +111 -0
- data/src/toxi/color/theory/CompoundTheoryStrategy.java +143 -0
- data/src/toxi/color/theory/LeftSplitComplementaryStrategy.java +82 -0
- data/src/toxi/color/theory/MonochromeTheoryStrategy.java +103 -0
- data/src/toxi/color/theory/RightSplitComplementaryStrategy.java +82 -0
- data/src/toxi/color/theory/SingleComplementStrategy.java +76 -0
- data/src/toxi/color/theory/SplitComplementaryStrategy.java +77 -0
- data/src/toxi/color/theory/TetradTheoryStrategy.java +114 -0
- data/src/toxi/color/theory/TriadTheoryStrategy.java +77 -0
- data/src/toxi/data/csv/CSVAdapter.java +74 -0
- data/src/toxi/data/csv/CSVFieldMapper.java +212 -0
- data/src/toxi/data/csv/CSVListener.java +61 -0
- data/src/toxi/data/csv/CSVParser.java +202 -0
- data/src/toxi/data/feeds/AtomAuthor.java +49 -0
- data/src/toxi/data/feeds/AtomContent.java +50 -0
- data/src/toxi/data/feeds/AtomEntry.java +111 -0
- data/src/toxi/data/feeds/AtomFeed.java +129 -0
- data/src/toxi/data/feeds/AtomLink.java +62 -0
- data/src/toxi/data/feeds/RSSChannel.java +88 -0
- data/src/toxi/data/feeds/RSSEnclosure.java +60 -0
- data/src/toxi/data/feeds/RSSFeed.java +99 -0
- data/src/toxi/data/feeds/RSSItem.java +104 -0
- data/src/toxi/data/feeds/util/EntityStripper.java +2480 -0
- data/src/toxi/data/feeds/util/Iso8601DateAdapter.java +101 -0
- data/src/toxi/data/feeds/util/Rfc822DateAdapter.java +93 -0
- data/src/toxi/geom/AABB.java +658 -0
- data/src/toxi/geom/Axis3D.java +116 -0
- data/src/toxi/geom/AxisAlignedCylinder.java +163 -0
- data/src/toxi/geom/BernsteinPolynomial.java +94 -0
- data/src/toxi/geom/BezierCurve2D.java +159 -0
- data/src/toxi/geom/BezierCurve3D.java +148 -0
- data/src/toxi/geom/BooleanShapeBuilder.java +185 -0
- data/src/toxi/geom/BoxIntersector.java +52 -0
- data/src/toxi/geom/Circle.java +230 -0
- data/src/toxi/geom/CircleIntersector.java +85 -0
- data/src/toxi/geom/Cone.java +150 -0
- data/src/toxi/geom/ConvexPolygonClipper.java +136 -0
- data/src/toxi/geom/CoordinateExtractor.java +16 -0
- data/src/toxi/geom/Ellipse.java +250 -0
- data/src/toxi/geom/GMatrix.java +2599 -0
- data/src/toxi/geom/GVector.java +833 -0
- data/src/toxi/geom/GlobalGridTesselator.java +54 -0
- data/src/toxi/geom/GridTesselator.java +108 -0
- data/src/toxi/geom/Intersector2D.java +49 -0
- data/src/toxi/geom/Intersector3D.java +51 -0
- data/src/toxi/geom/IsectData2D.java +103 -0
- data/src/toxi/geom/IsectData3D.java +103 -0
- data/src/toxi/geom/Line2D.java +534 -0
- data/src/toxi/geom/Line3D.java +471 -0
- data/src/toxi/geom/LineStrip2D.java +430 -0
- data/src/toxi/geom/LineStrip3D.java +230 -0
- data/src/toxi/geom/LocalGridTesselator.java +57 -0
- data/src/toxi/geom/Matrix3d.java +3048 -0
- data/src/toxi/geom/Matrix4f.java +3446 -0
- data/src/toxi/geom/Matrix4x4.java +1076 -0
- data/src/toxi/geom/MatrixSizeException.java +58 -0
- data/src/toxi/geom/OctreeVisitor.java +44 -0
- data/src/toxi/geom/Origin3D.java +148 -0
- data/src/toxi/geom/Plane.java +293 -0
- data/src/toxi/geom/PlaneIntersector.java +57 -0
- data/src/toxi/geom/PointCloud3D.java +253 -0
- data/src/toxi/geom/PointOctree.java +502 -0
- data/src/toxi/geom/PointQuadtree.java +375 -0
- data/src/toxi/geom/Polygon2D.java +1038 -0
- data/src/toxi/geom/PolygonClipper2D.java +45 -0
- data/src/toxi/geom/PolygonTesselator.java +20 -0
- data/src/toxi/geom/QuadtreeVisitor.java +44 -0
- data/src/toxi/geom/Quaternion.java +641 -0
- data/src/toxi/geom/Ray2D.java +146 -0
- data/src/toxi/geom/Ray3D.java +150 -0
- data/src/toxi/geom/Ray3DIntersector.java +75 -0
- data/src/toxi/geom/ReadonlyVec2D.java +575 -0
- data/src/toxi/geom/ReadonlyVec3D.java +628 -0
- data/src/toxi/geom/ReadonlyVec4D.java +431 -0
- data/src/toxi/geom/Rect.java +720 -0
- data/src/toxi/geom/Reflector3D.java +58 -0
- data/src/toxi/geom/Shape2D.java +94 -0
- data/src/toxi/geom/Shape3D.java +42 -0
- data/src/toxi/geom/SingularMatrixException.java +57 -0
- data/src/toxi/geom/SpatialBins.java +182 -0
- data/src/toxi/geom/SpatialIndex.java +61 -0
- data/src/toxi/geom/Sphere.java +224 -0
- data/src/toxi/geom/SphereIntersectorReflector.java +196 -0
- data/src/toxi/geom/Spline2D.java +349 -0
- data/src/toxi/geom/Spline3D.java +351 -0
- data/src/toxi/geom/SutherlandHodgemanClipper.java +151 -0
- data/src/toxi/geom/Triangle2D.java +422 -0
- data/src/toxi/geom/Triangle3D.java +456 -0
- data/src/toxi/geom/TriangleIntersector.java +105 -0
- data/src/toxi/geom/Vec2D.java +1328 -0
- data/src/toxi/geom/Vec3D.java +1832 -0
- data/src/toxi/geom/Vec4D.java +985 -0
- data/src/toxi/geom/VecMathUtil.java +100 -0
- data/src/toxi/geom/XAxisCylinder.java +64 -0
- data/src/toxi/geom/YAxisCylinder.java +65 -0
- data/src/toxi/geom/ZAxisCylinder.java +64 -0
- data/src/toxi/geom/mesh/BezierPatch.java +200 -0
- data/src/toxi/geom/mesh/BoxSelector.java +62 -0
- data/src/toxi/geom/mesh/DefaultSTLColorModel.java +67 -0
- data/src/toxi/geom/mesh/DefaultSelector.java +50 -0
- data/src/toxi/geom/mesh/Face.java +176 -0
- data/src/toxi/geom/mesh/LaplacianSmooth.java +80 -0
- data/src/toxi/geom/mesh/MaterialiseSTLColorModel.java +150 -0
- data/src/toxi/geom/mesh/Mesh3D.java +224 -0
- data/src/toxi/geom/mesh/MeshIntersector.java +91 -0
- data/src/toxi/geom/mesh/OBJWriter.java +194 -0
- data/src/toxi/geom/mesh/PLYWriter.java +167 -0
- data/src/toxi/geom/mesh/PlaneSelector.java +90 -0
- data/src/toxi/geom/mesh/STLColorModel.java +54 -0
- data/src/toxi/geom/mesh/STLReader.java +185 -0
- data/src/toxi/geom/mesh/STLWriter.java +323 -0
- data/src/toxi/geom/mesh/SphereFunction.java +156 -0
- data/src/toxi/geom/mesh/SphericalHarmonics.java +110 -0
- data/src/toxi/geom/mesh/SuperEllipsoid.java +110 -0
- data/src/toxi/geom/mesh/SurfaceFunction.java +75 -0
- data/src/toxi/geom/mesh/SurfaceMeshBuilder.java +149 -0
- data/src/toxi/geom/mesh/Terrain.java +451 -0
- data/src/toxi/geom/mesh/TriangleMesh.java +1201 -0
- data/src/toxi/geom/mesh/Vertex.java +78 -0
- data/src/toxi/geom/mesh/VertexSelector.java +193 -0
- data/src/toxi/geom/mesh/WEFace.java +100 -0
- data/src/toxi/geom/mesh/WEMeshFilterStrategy.java +51 -0
- data/src/toxi/geom/mesh/WETriangleMesh.java +761 -0
- data/src/toxi/geom/mesh/WEVertex.java +134 -0
- data/src/toxi/geom/mesh/WingedEdge.java +115 -0
- data/src/toxi/geom/mesh/subdiv/CentroidSubdiv.java +37 -0
- data/src/toxi/geom/mesh/subdiv/DisplacementSubdivision.java +85 -0
- data/src/toxi/geom/mesh/subdiv/DualDisplacementSubdivision.java +94 -0
- data/src/toxi/geom/mesh/subdiv/DualSubdivision.java +49 -0
- data/src/toxi/geom/mesh/subdiv/EdgeLengthComparator.java +50 -0
- data/src/toxi/geom/mesh/subdiv/FaceCountComparator.java +51 -0
- data/src/toxi/geom/mesh/subdiv/MidpointDisplacementSubdivision.java +80 -0
- data/src/toxi/geom/mesh/subdiv/MidpointSubdiv.java +42 -0
- data/src/toxi/geom/mesh/subdiv/MidpointSubdivision.java +48 -0
- data/src/toxi/geom/mesh/subdiv/NewSubdivStrategy.java +23 -0
- data/src/toxi/geom/mesh/subdiv/NormalDisplacementSubdivision.java +74 -0
- data/src/toxi/geom/mesh/subdiv/SubdivisionStrategy.java +83 -0
- data/src/toxi/geom/mesh/subdiv/TriSubdivision.java +51 -0
- data/src/toxi/geom/mesh2d/DelaunayTriangle.java +222 -0
- data/src/toxi/geom/mesh2d/DelaunayTriangulation.java +327 -0
- data/src/toxi/geom/mesh2d/DelaunayVertex.java +560 -0
- data/src/toxi/geom/mesh2d/Voronoi.java +149 -0
- data/src/toxi/geom/nurbs/BasicNurbsCurve.java +210 -0
- data/src/toxi/geom/nurbs/BasicNurbsSurface.java +233 -0
- data/src/toxi/geom/nurbs/ControlNet.java +148 -0
- data/src/toxi/geom/nurbs/CurveCreator.java +112 -0
- data/src/toxi/geom/nurbs/CurveUtils.java +259 -0
- data/src/toxi/geom/nurbs/InterpolationException.java +65 -0
- data/src/toxi/geom/nurbs/KnotVector.java +333 -0
- data/src/toxi/geom/nurbs/NurbsCreator.java +815 -0
- data/src/toxi/geom/nurbs/NurbsCurve.java +120 -0
- data/src/toxi/geom/nurbs/NurbsMeshCreator.java +145 -0
- data/src/toxi/geom/nurbs/NurbsSurface.java +147 -0
- data/src/toxi/image/util/Filter8bit.java +331 -0
- data/src/toxi/image/util/TiledFrameExporter.java +162 -0
- data/src/toxi/math/BezierInterpolation.java +102 -0
- data/src/toxi/math/CircularInterpolation.java +88 -0
- data/src/toxi/math/CosineInterpolation.java +51 -0
- data/src/toxi/math/DecimatedInterpolation.java +77 -0
- data/src/toxi/math/ExponentialInterpolation.java +68 -0
- data/src/toxi/math/InterpolateStrategy.java +60 -0
- data/src/toxi/math/Interpolation2D.java +93 -0
- data/src/toxi/math/LinearInterpolation.java +46 -0
- data/src/toxi/math/MathUtils.java +990 -0
- data/src/toxi/math/NonLinearScaleMap.java +101 -0
- data/src/toxi/math/ScaleMap.java +183 -0
- data/src/toxi/math/SigmoidInterpolation.java +78 -0
- data/src/toxi/math/SinCosLUT.java +141 -0
- data/src/toxi/math/ThresholdInterpolation.java +58 -0
- data/src/toxi/math/ZoomLensInterpolation.java +126 -0
- data/src/toxi/math/conversion/UnitTranslator.java +161 -0
- data/src/toxi/math/noise/PerlinNoise.java +281 -0
- data/src/toxi/math/noise/SimplexNoise.java +542 -0
- data/src/toxi/math/waves/AMFMSineWave.java +143 -0
- data/src/toxi/math/waves/AbstractWave.java +248 -0
- data/src/toxi/math/waves/ConstantWave.java +48 -0
- data/src/toxi/math/waves/FMHarmonicSquareWave.java +155 -0
- data/src/toxi/math/waves/FMSawtoothWave.java +144 -0
- data/src/toxi/math/waves/FMSineWave.java +142 -0
- data/src/toxi/math/waves/FMSquareWave.java +143 -0
- data/src/toxi/math/waves/FMTriangleWave.java +126 -0
- data/src/toxi/math/waves/SineWave.java +81 -0
- data/src/toxi/math/waves/Wave2D.java +68 -0
- data/src/toxi/math/waves/WaveState.java +69 -0
- data/src/toxi/music/scale/AbstractScale.java +117 -0
- data/src/toxi/music/scale/GenericScale.java +66 -0
- data/src/toxi/music/scale/MajorScale.java +41 -0
- data/src/toxi/newmesh/AttributedEdge.java +106 -0
- data/src/toxi/newmesh/AttributedFace.java +63 -0
- data/src/toxi/newmesh/IndexedTriangleMesh.java +809 -0
- data/src/toxi/newmesh/MeshAttributeCompiler.java +45 -0
- data/src/toxi/newmesh/MeshFaceNormalCompiler.java +52 -0
- data/src/toxi/newmesh/MeshUVCompiler.java +52 -0
- data/src/toxi/newmesh/MeshVertexColorCompiler.java +49 -0
- data/src/toxi/newmesh/MeshVertexCompiler.java +54 -0
- data/src/toxi/newmesh/MeshVertexNormalCompiler.java +55 -0
- data/src/toxi/newmesh/SpatialIndex.java +78 -0
- data/src/toxi/physics2d/ParticlePath2D.java +100 -0
- data/src/toxi/physics2d/ParticleString2D.java +184 -0
- data/src/toxi/physics2d/PullBackSpring2D.java +51 -0
- data/src/toxi/physics2d/VerletConstrainedSpring2D.java +89 -0
- data/src/toxi/physics2d/VerletMinDistanceSpring2D.java +57 -0
- data/src/toxi/physics2d/VerletParticle2D.java +457 -0
- data/src/toxi/physics2d/VerletPhysics2D.java +448 -0
- data/src/toxi/physics2d/VerletSpring2D.java +181 -0
- data/src/toxi/physics2d/behaviors/AttractionBehavior2D.java +212 -0
- data/src/toxi/physics2d/behaviors/ConstantForceBehavior2D.java +112 -0
- data/src/toxi/physics2d/behaviors/GravityBehavior2D.java +61 -0
- data/src/toxi/physics2d/behaviors/ParticleBehavior2D.java +66 -0
- data/src/toxi/physics2d/constraints/AngularConstraint.java +83 -0
- data/src/toxi/physics2d/constraints/AxisConstraint.java +71 -0
- data/src/toxi/physics2d/constraints/CircularConstraint.java +69 -0
- data/src/toxi/physics2d/constraints/MaxConstraint.java +66 -0
- data/src/toxi/physics2d/constraints/MinConstraint.java +66 -0
- data/src/toxi/physics2d/constraints/ParticleConstraint2D.java +47 -0
- data/src/toxi/physics2d/constraints/PolygonConstraint.java +93 -0
- data/src/toxi/physics2d/constraints/RectConstraint.java +114 -0
- data/src/toxi/physics3d/ParticlePath3D.java +100 -0
- data/src/toxi/physics3d/ParticleString3D.java +184 -0
- data/src/toxi/physics3d/PullBackSpring3D.java +50 -0
- data/src/toxi/physics3d/VerletConstrainedSpring3D.java +88 -0
- data/src/toxi/physics3d/VerletMinDistanceSpring3D.java +56 -0
- data/src/toxi/physics3d/VerletParticle3D.java +385 -0
- data/src/toxi/physics3d/VerletPhysics3D.java +417 -0
- data/src/toxi/physics3d/VerletSpring3D.java +180 -0
- data/src/toxi/physics3d/behaviors/AttractionBehavior3D.java +182 -0
- data/src/toxi/physics3d/behaviors/ConstantForceBehavior3D.java +92 -0
- data/src/toxi/physics3d/behaviors/GravityBehavior3D.java +61 -0
- data/src/toxi/physics3d/behaviors/ParticleBehavior3D.java +52 -0
- data/src/toxi/physics3d/constraints/AxisConstraint.java +68 -0
- data/src/toxi/physics3d/constraints/BoxConstraint.java +121 -0
- data/src/toxi/physics3d/constraints/CylinderConstraint.java +87 -0
- data/src/toxi/physics3d/constraints/MaxConstraint.java +65 -0
- data/src/toxi/physics3d/constraints/MinConstraint.java +65 -0
- data/src/toxi/physics3d/constraints/ParticleConstraint3D.java +49 -0
- data/src/toxi/physics3d/constraints/PlaneConstraint.java +78 -0
- data/src/toxi/physics3d/constraints/SoftBoxConstraint.java +87 -0
- data/src/toxi/physics3d/constraints/SphereConstraint.java +108 -0
- data/src/toxi/processing/ArrowModifier.java +116 -0
- data/src/toxi/processing/DashedLineModifier.java +48 -0
- data/src/toxi/processing/DeltaOrientationMapper.java +57 -0
- data/src/toxi/processing/Line2DRenderModifier.java +18 -0
- data/src/toxi/processing/MeshToVBO.java +94 -0
- data/src/toxi/processing/NormalMapper.java +18 -0
- data/src/toxi/processing/POVInterface.java +121 -0
- data/src/toxi/processing/POVMesh.java +219 -0
- data/src/toxi/processing/POVWriter.java +460 -0
- data/src/toxi/processing/RCOpaque.java +77 -0
- data/src/toxi/processing/RCTransp.java +78 -0
- data/src/toxi/processing/TextureBuilder.java +232 -0
- data/src/toxi/processing/Textures.java +110 -0
- data/src/toxi/processing/ToxiclibsSupport.java +1239 -0
- data/src/toxi/processing/Tracing.java +25 -0
- data/src/toxi/processing/XYZNormalMapper.java +30 -0
- data/src/toxi/sim/automata/CAMatrix.java +297 -0
- data/src/toxi/sim/automata/CARule.java +76 -0
- data/src/toxi/sim/automata/CARule2D.java +354 -0
- data/src/toxi/sim/automata/CAWolfram1D.java +309 -0
- data/src/toxi/sim/automata/EvolvableMatrix.java +61 -0
- data/src/toxi/sim/automata/MatrixEvolver.java +42 -0
- data/src/toxi/sim/dla/BottomUpOrder.java +76 -0
- data/src/toxi/sim/dla/DLA.java +497 -0
- data/src/toxi/sim/dla/DLAConfiguration.java +364 -0
- data/src/toxi/sim/dla/DLAEventAdapter.java +64 -0
- data/src/toxi/sim/dla/DLAEventListener.java +57 -0
- data/src/toxi/sim/dla/DLAGuideLines.java +219 -0
- data/src/toxi/sim/dla/DLAParticle.java +102 -0
- data/src/toxi/sim/dla/DLASegment.java +88 -0
- data/src/toxi/sim/dla/PipelineOrder.java +50 -0
- data/src/toxi/sim/dla/RadialDistanceOrder.java +92 -0
- data/src/toxi/sim/erosion/ErosionFunction.java +122 -0
- data/src/toxi/sim/erosion/TalusAngleErosion.java +145 -0
- data/src/toxi/sim/erosion/ThermalErosion.java +75 -0
- data/src/toxi/sim/fluids/FluidSolver2D.java +762 -0
- data/src/toxi/sim/fluids/FluidSolver3D.java +326 -0
- data/src/toxi/sim/grayscott/GrayScott.java +469 -0
- data/src/toxi/util/DateUtils.java +141 -0
- data/src/toxi/util/FileSequenceDescriptor.java +181 -0
- data/src/toxi/util/FileUtils.java +467 -0
- data/src/toxi/util/datatypes/ArraySet.java +128 -0
- data/src/toxi/util/datatypes/ArrayUtil.java +404 -0
- data/src/toxi/util/datatypes/BiasedDoubleRange.java +141 -0
- data/src/toxi/util/datatypes/BiasedFloatRange.java +141 -0
- data/src/toxi/util/datatypes/BiasedIntegerRange.java +141 -0
- data/src/toxi/util/datatypes/DoubleRange.java +251 -0
- data/src/toxi/util/datatypes/FloatRange.java +251 -0
- data/src/toxi/util/datatypes/GenericSet.java +215 -0
- data/src/toxi/util/datatypes/IntegerRange.java +247 -0
- data/src/toxi/util/datatypes/IntegerSet.java +149 -0
- data/src/toxi/util/datatypes/ItemIndex.java +72 -0
- data/src/toxi/util/datatypes/SingletonRegistry.java +91 -0
- data/src/toxi/util/datatypes/TypedProperties.java +291 -0
- data/src/toxi/util/datatypes/UndirectedGraph.java +134 -0
- data/src/toxi/util/datatypes/UniqueItemIndex.java +223 -0
- data/src/toxi/util/datatypes/WeightedRandomEntry.java +76 -0
- data/src/toxi/util/datatypes/WeightedRandomSet.java +125 -0
- data/src/toxi/util/events/EventDispatcher.java +86 -0
- data/src/toxi/volume/AdditiveBrush.java +19 -0
- data/src/toxi/volume/ArrayIsoSurface.java +297 -0
- data/src/toxi/volume/BoxBrush.java +100 -0
- data/src/toxi/volume/BrushMode.java +16 -0
- data/src/toxi/volume/HashIsoSurface.java +354 -0
- data/src/toxi/volume/IsoSurface.java +59 -0
- data/src/toxi/volume/MarchingCubesIndex.java +312 -0
- data/src/toxi/volume/MeshLatticeBuilder.java +358 -0
- data/src/toxi/volume/MeshVoxelizer.java +216 -0
- data/src/toxi/volume/MultiplyBrush.java +20 -0
- data/src/toxi/volume/PeakBrush.java +21 -0
- data/src/toxi/volume/ReplaceBrush.java +19 -0
- data/src/toxi/volume/RoundBrush.java +113 -0
- data/src/toxi/volume/VolumetricBrush.java +160 -0
- data/src/toxi/volume/VolumetricHashMap.java +179 -0
- data/src/toxi/volume/VolumetricSpace.java +195 -0
- data/src/toxi/volume/VolumetricSpaceArray.java +214 -0
- data/toxiclibs.gemspec +34 -0
- metadata +424 -27
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* __ .__ .__ ._____.
|
|
3
|
+
* _/ |_ _______ __|__| ____ | | |__\_ |__ ______
|
|
4
|
+
* \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
|
|
5
|
+
* | | ( <_> > <| \ \___| |_| || \_\ \\___ \
|
|
6
|
+
* |__| \____/__/\_ \__|\___ >____/__||___ /____ >
|
|
7
|
+
* \/ \/ \/ \/
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
10
|
+
*
|
|
11
|
+
* This library is free software; you can redistribute it and/or
|
|
12
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
* License as published by the Free Software Foundation; either
|
|
14
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
*
|
|
16
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
17
|
+
*
|
|
18
|
+
* This library is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
21
|
+
* Lesser General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
24
|
+
* License along with this library; if not, write to the Free Software
|
|
25
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
package toxi.geom;
|
|
29
|
+
|
|
30
|
+
import javax.xml.bind.annotation.XmlAccessType;
|
|
31
|
+
import javax.xml.bind.annotation.XmlAccessorType;
|
|
32
|
+
import javax.xml.bind.annotation.XmlAttribute;
|
|
33
|
+
|
|
34
|
+
import toxi.geom.mesh.Mesh3D;
|
|
35
|
+
import toxi.geom.mesh.SphereFunction;
|
|
36
|
+
import toxi.geom.mesh.SurfaceMeshBuilder;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
*
|
|
40
|
+
* @author tux
|
|
41
|
+
*/
|
|
42
|
+
@XmlAccessorType(XmlAccessType.FIELD)
|
|
43
|
+
public class Sphere extends Vec3D implements Shape3D {
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Earth's mean radius in km
|
|
47
|
+
* (http://en.wikipedia.org/wiki/Earth_radius#Mean_radii)
|
|
48
|
+
*/
|
|
49
|
+
public static final float EARTH_RADIUS = (float) ((2 * 6378.1370 + 6356.752314245) / 3.0);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
*
|
|
53
|
+
*/
|
|
54
|
+
@XmlAttribute(required = true)
|
|
55
|
+
public float radius;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
*
|
|
59
|
+
*/
|
|
60
|
+
public Sphere() {
|
|
61
|
+
this(new Vec3D(), 1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
*
|
|
66
|
+
* @param radius
|
|
67
|
+
*/
|
|
68
|
+
public Sphere(float radius) {
|
|
69
|
+
this(new Vec3D(), radius);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
*
|
|
74
|
+
* @param v
|
|
75
|
+
* @param r
|
|
76
|
+
*/
|
|
77
|
+
public Sphere(ReadonlyVec3D v, float r) {
|
|
78
|
+
super(v);
|
|
79
|
+
radius = r;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
*
|
|
84
|
+
* @param s
|
|
85
|
+
*/
|
|
86
|
+
public Sphere(Sphere s) {
|
|
87
|
+
this(s, s.radius);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@Override
|
|
91
|
+
public boolean containsPoint(ReadonlyVec3D p) {
|
|
92
|
+
float d = this.sub(p).magSquared();
|
|
93
|
+
return (d <= radius * radius);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Alternative to {@link SphereIntersectorReflector}. Computes primary &
|
|
98
|
+
* secondary intersection points of this sphere with the given ray. If no
|
|
99
|
+
* intersection is found the method returns null. In all other cases, the
|
|
100
|
+
* returned array will contain the distance to the primary intersection
|
|
101
|
+
* point (i.e. the closest in the direction of the ray) as its first index
|
|
102
|
+
* and the other one as its second. If any of distance values is negative,
|
|
103
|
+
* the intersection point lies in the opposite ray direction (might be
|
|
104
|
+
* useful to know). To get the actual intersection point coordinates, simply
|
|
105
|
+
* pass the returned values to {@link Ray3D#getPointAtDistance(float)}.
|
|
106
|
+
*
|
|
107
|
+
* @param ray
|
|
108
|
+
* @return 2-element float array of intersection points or null if ray
|
|
109
|
+
* doesn't intersect sphere at all.
|
|
110
|
+
*/
|
|
111
|
+
public float[] intersectRay(Ray3D ray) {
|
|
112
|
+
float[] result = null;
|
|
113
|
+
ReadonlyVec3D q = ray.sub(this);
|
|
114
|
+
float distSquared = q.magSquared();
|
|
115
|
+
float v = -q.dot(ray.getDirection());
|
|
116
|
+
float d = radius * radius - (distSquared - v * v);
|
|
117
|
+
if (d >= 0.0) {
|
|
118
|
+
d = (float) Math.sqrt(d);
|
|
119
|
+
float a = v + d;
|
|
120
|
+
float b = v - d;
|
|
121
|
+
if (!(a < 0 && b < 0)) {
|
|
122
|
+
if (a > 0 && b > 0) {
|
|
123
|
+
if (a > b) {
|
|
124
|
+
float t = a;
|
|
125
|
+
a = b;
|
|
126
|
+
b = t;
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
if (b > 0) {
|
|
130
|
+
float t = a;
|
|
131
|
+
a = b;
|
|
132
|
+
b = t;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
result = new float[] {
|
|
137
|
+
a, b
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Considers the current vector as centre of a collision sphere with radius
|
|
145
|
+
* r and checks if the triangle abc intersects with this sphere. The Vec3D p
|
|
146
|
+
* The point on abc closest to the sphere center is returned via the
|
|
147
|
+
* supplied result vector argument.
|
|
148
|
+
*
|
|
149
|
+
* @param t
|
|
150
|
+
* triangle to check for intersection
|
|
151
|
+
* @param result
|
|
152
|
+
* a non-null vector for storing the result
|
|
153
|
+
* @return true, if sphere intersects triangle ABC
|
|
154
|
+
*/
|
|
155
|
+
public boolean intersectSphereTriangle(Triangle3D t, Vec3D result) {
|
|
156
|
+
// Find Vec3D P on triangle ABC closest to sphere center
|
|
157
|
+
result.set(t.closestPointOnSurface(this));
|
|
158
|
+
|
|
159
|
+
// Sphere and triangle intersect if the (squared) distance from sphere
|
|
160
|
+
// center to Vec3D p is less than the (squared) sphere radius
|
|
161
|
+
ReadonlyVec3D v = result.sub(this);
|
|
162
|
+
return v.magSquared() <= radius * radius;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Computes the surface distance on this sphere between two points given as
|
|
167
|
+
* lon/lat coordinates. The x component of each vector needs to contain the
|
|
168
|
+
* longitude and the y component the latitude (both in radians).
|
|
169
|
+
*
|
|
170
|
+
* Algorithm from: http://www.csgnetwork.com/gpsdistcalc.html
|
|
171
|
+
*
|
|
172
|
+
* @param p
|
|
173
|
+
* @param q
|
|
174
|
+
* @return distance on the sphere surface
|
|
175
|
+
*/
|
|
176
|
+
public double surfaceDistanceBetween(Vec2D p, Vec2D q) {
|
|
177
|
+
double t1 = Math.sin(p.y) * Math.sin(q.y);
|
|
178
|
+
double t2 = Math.cos(p.y) * Math.cos(q.y);
|
|
179
|
+
double t3 = Math.cos(p.x - q.x);
|
|
180
|
+
double t4 = t2 * t3;
|
|
181
|
+
double t5 = t1 + t4;
|
|
182
|
+
double dist = Math.atan(-t5 / Math.sqrt(-t5 * t5 + 1)) + 2
|
|
183
|
+
* Math.atan(1);
|
|
184
|
+
if (Double.isNaN(dist)) {
|
|
185
|
+
dist = 0;
|
|
186
|
+
} else {
|
|
187
|
+
dist *= radius;
|
|
188
|
+
}
|
|
189
|
+
return dist;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Calculates the normal vector on the sphere in the direction of the
|
|
194
|
+
* current point.
|
|
195
|
+
*
|
|
196
|
+
* @param q
|
|
197
|
+
* @return a unit normal vector to the tangent plane of the ellipsoid in the
|
|
198
|
+
* point.
|
|
199
|
+
*/
|
|
200
|
+
public Vec3D tangentPlaneNormalAt(ReadonlyVec3D q) {
|
|
201
|
+
return q.sub(this).normalize();
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
*
|
|
206
|
+
* @param res
|
|
207
|
+
* @return
|
|
208
|
+
*/
|
|
209
|
+
public Mesh3D toMesh(int res) {
|
|
210
|
+
return toMesh(null, res);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
*
|
|
215
|
+
* @param mesh
|
|
216
|
+
* @param res
|
|
217
|
+
* @return
|
|
218
|
+
*/
|
|
219
|
+
public Mesh3D toMesh(Mesh3D mesh, int res) {
|
|
220
|
+
SurfaceMeshBuilder builder = new SurfaceMeshBuilder(new SphereFunction(
|
|
221
|
+
this));
|
|
222
|
+
return builder.createMesh(mesh, res, 1);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* __ .__ .__ ._____.
|
|
3
|
+
* _/ |_ _______ __|__| ____ | | |__\_ |__ ______
|
|
4
|
+
* \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
|
|
5
|
+
* | | ( <_> > <| \ \___| |_| || \_\ \\___ \
|
|
6
|
+
* |__| \____/__/\_ \__|\___ >____/__||___ /____ >
|
|
7
|
+
* \/ \/ \/ \/
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
10
|
+
*
|
|
11
|
+
* This library is free software; you can redistribute it and/or
|
|
12
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
* License as published by the Free Software Foundation; either
|
|
14
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
*
|
|
16
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
17
|
+
*
|
|
18
|
+
* This library is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
21
|
+
* Lesser General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
24
|
+
* License along with this library; if not, write to the Free Software
|
|
25
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
package toxi.geom;
|
|
29
|
+
|
|
30
|
+
import toxi.math.MathUtils;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @author tux
|
|
35
|
+
*/
|
|
36
|
+
public class SphereIntersectorReflector implements Intersector3D, Reflector3D {
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
*
|
|
40
|
+
*/
|
|
41
|
+
protected Sphere sphere;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
*
|
|
45
|
+
*/
|
|
46
|
+
protected IsectData3D isectData;
|
|
47
|
+
|
|
48
|
+
protected ReadonlyVec3D reflectedDir,
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
*
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
*
|
|
56
|
+
*/
|
|
57
|
+
reflectedPos;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
*
|
|
61
|
+
*/
|
|
62
|
+
protected float reflectTheta;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
*
|
|
66
|
+
* @param s
|
|
67
|
+
*/
|
|
68
|
+
public SphereIntersectorReflector(Sphere s) {
|
|
69
|
+
sphere = s;
|
|
70
|
+
isectData = new IsectData3D();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
*
|
|
75
|
+
* @param o
|
|
76
|
+
* @param r
|
|
77
|
+
*/
|
|
78
|
+
public SphereIntersectorReflector(Vec3D o, float r) {
|
|
79
|
+
this(new Sphere(o, r));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@Override
|
|
83
|
+
public IsectData3D getIntersectionData() {
|
|
84
|
+
return isectData;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/*
|
|
88
|
+
* (non-Javadoc)
|
|
89
|
+
*
|
|
90
|
+
* @see toxi.geom.Reflector3D#getReflectedRayPointAtDistance(float)
|
|
91
|
+
*/
|
|
92
|
+
@Override
|
|
93
|
+
public ReadonlyVec3D getReflectedRayPointAtDistance(float dist) {
|
|
94
|
+
if (reflectedDir != null) {
|
|
95
|
+
return isectData.pos.add(reflectedDir.scale(dist));
|
|
96
|
+
} else {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/*
|
|
102
|
+
* (non-Javadoc)
|
|
103
|
+
*
|
|
104
|
+
* @see toxi.geom.Reflector3D#getReflectionAngle()
|
|
105
|
+
*/
|
|
106
|
+
@Override
|
|
107
|
+
public float getReflectionAngle() {
|
|
108
|
+
return reflectTheta;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @return the sphere
|
|
113
|
+
*/
|
|
114
|
+
public Sphere getSphere() {
|
|
115
|
+
return sphere;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Calculates the distance of the vector to the given sphere in the
|
|
120
|
+
* specified direction. A sphere is defined by a 3D point and a radius.
|
|
121
|
+
* Normalized directional vectors expected.
|
|
122
|
+
*
|
|
123
|
+
* @param ray
|
|
124
|
+
* intersection ray
|
|
125
|
+
* @return distance to sphere in world units, -1 if no intersection.
|
|
126
|
+
*/
|
|
127
|
+
|
|
128
|
+
public float intersectRayDistance(Ray3D ray) {
|
|
129
|
+
ReadonlyVec3D q = sphere.sub(ray);
|
|
130
|
+
float distSquared = q.magSquared();
|
|
131
|
+
float v = q.dot(ray.dir);
|
|
132
|
+
float d = sphere.radius * sphere.radius - (distSquared - v * v);
|
|
133
|
+
|
|
134
|
+
// If there was no intersection, return -1
|
|
135
|
+
if (d < 0.0) {
|
|
136
|
+
return -1;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Return the distance to the [first] intersecting point
|
|
140
|
+
return v - (float) Math.sqrt(d);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@Override
|
|
144
|
+
public boolean intersectsRay(Ray3D ray) {
|
|
145
|
+
isectData.dist = intersectRayDistance(ray);
|
|
146
|
+
isectData.isIntersection = isectData.dist >= 0;
|
|
147
|
+
if (isectData.isIntersection) {
|
|
148
|
+
// get the intersection point
|
|
149
|
+
isectData.pos = ray.add(ray.getDirection().scale(isectData.dist));
|
|
150
|
+
// calculate the direction from our point to the intersection pos
|
|
151
|
+
isectData.dir = isectData.pos.sub(ray);
|
|
152
|
+
isectData.normal = sphere.tangentPlaneNormalAt(isectData.pos);
|
|
153
|
+
}
|
|
154
|
+
return isectData.isIntersection;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/*
|
|
158
|
+
* (non-Javadoc)
|
|
159
|
+
*
|
|
160
|
+
* @see toxi.geom.Reflector3D#reflectRay(toxi.geom.Vec3D, toxi.geom.Vec3D)
|
|
161
|
+
*/
|
|
162
|
+
@Override
|
|
163
|
+
public Ray3D reflectRay(Ray3D ray) {
|
|
164
|
+
if (intersectsRay(ray)) {
|
|
165
|
+
// compute the normal vector of the sphere at the intersection
|
|
166
|
+
// position
|
|
167
|
+
// compute the reflection angle
|
|
168
|
+
reflectTheta = isectData.dir.angleBetween(isectData.normal, true)
|
|
169
|
+
* 2 + MathUtils.PI;
|
|
170
|
+
// then form a perpendicular vector standing on the plane spanned by
|
|
171
|
+
// isectDir and sphereNormal
|
|
172
|
+
// this vector will be used to mirror the ray around the
|
|
173
|
+
// intersection point
|
|
174
|
+
Vec3D reflectNormal = isectData.dir.getNormalized()
|
|
175
|
+
.cross(isectData.normal).normalize();
|
|
176
|
+
if (!reflectNormal.isZeroVector()) {
|
|
177
|
+
// compute the reflected ray direction
|
|
178
|
+
reflectedDir = isectData.dir.getNormalized().rotateAroundAxis(
|
|
179
|
+
reflectNormal, reflectTheta);
|
|
180
|
+
} else {
|
|
181
|
+
reflectedDir = isectData.dir.getInverted();
|
|
182
|
+
}
|
|
183
|
+
return new Ray3D(isectData.pos, reflectedDir);
|
|
184
|
+
} else {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* @param sphere
|
|
191
|
+
* the sphere to set
|
|
192
|
+
*/
|
|
193
|
+
public void setSphere(Sphere sphere) {
|
|
194
|
+
this.sphere = sphere;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* __ .__ .__ ._____.
|
|
3
|
+
* _/ |_ _______ __|__| ____ | | |__\_ |__ ______
|
|
4
|
+
* \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
|
|
5
|
+
* | | ( <_> > <| \ \___| |_| || \_\ \\___ \
|
|
6
|
+
* |__| \____/__/\_ \__|\___ >____/__||___ /____ >
|
|
7
|
+
* \/ \/ \/ \/
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
10
|
+
*
|
|
11
|
+
* This library is free software; you can redistribute it and/or
|
|
12
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
* License as published by the Free Software Foundation; either
|
|
14
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
*
|
|
16
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
17
|
+
*
|
|
18
|
+
* This library is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
21
|
+
* Lesser General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
24
|
+
* License along with this library; if not, write to the Free Software
|
|
25
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
package toxi.geom;
|
|
29
|
+
|
|
30
|
+
import java.util.ArrayList;
|
|
31
|
+
import java.util.Arrays;
|
|
32
|
+
import java.util.List;
|
|
33
|
+
|
|
34
|
+
import javax.xml.bind.annotation.XmlAccessType;
|
|
35
|
+
import javax.xml.bind.annotation.XmlAccessorType;
|
|
36
|
+
import javax.xml.bind.annotation.XmlAttribute;
|
|
37
|
+
import javax.xml.bind.annotation.XmlElement;
|
|
38
|
+
import javax.xml.bind.annotation.XmlTransient;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* <p>
|
|
42
|
+
* This is a generic 3D B-Spline class for curves of arbitrary length, control
|
|
43
|
+
* handles and patches are created and joined automatically as described here:
|
|
44
|
+
* <a
|
|
45
|
+
* href="http://www.ibiblio.org/e-notes/Splines/Bint.htm">ibiblio.org/e-notes/
|
|
46
|
+
* Splines/Bint.htm</a>
|
|
47
|
+
* </p>
|
|
48
|
+
*
|
|
49
|
+
* <p>
|
|
50
|
+
* Thanks to a bug report by Aaron Meyers (http://universaloscillation.com) the
|
|
51
|
+
* {@linkplain #toLineStrip2D(int)} method has a slightly changed behaviour from
|
|
52
|
+
* version 0014 onwards. In earlier versions erroneous duplicate points would be
|
|
53
|
+
* added near each given control point, which lead to various weird results.
|
|
54
|
+
* </p>
|
|
55
|
+
*
|
|
56
|
+
* <p>
|
|
57
|
+
* The new behaviour of the curve interpolation/computation is described in the
|
|
58
|
+
* docs for the {@linkplain #toLineStrip2D(int)} method below.
|
|
59
|
+
* </p>
|
|
60
|
+
*
|
|
61
|
+
* @version 0014 Added user adjustable curve tightness control
|
|
62
|
+
* @version 0015 Added JAXB annotations and List support for dynamic building of
|
|
63
|
+
* spline
|
|
64
|
+
*/
|
|
65
|
+
@XmlAccessorType(XmlAccessType.FIELD)
|
|
66
|
+
public class Spline2D {
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
*
|
|
70
|
+
*/
|
|
71
|
+
public static final float DEFAULT_TIGHTNESS = 0.25f;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
*
|
|
75
|
+
*/
|
|
76
|
+
public static final int DEFAULT_RES = 16;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
*
|
|
80
|
+
*/
|
|
81
|
+
@XmlTransient
|
|
82
|
+
protected Vec2D[] points;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
*
|
|
86
|
+
*/
|
|
87
|
+
@XmlElement(name = "p")
|
|
88
|
+
public List<Vec2D> pointList = new ArrayList<>();
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
*
|
|
92
|
+
*/
|
|
93
|
+
@XmlTransient
|
|
94
|
+
public BernsteinPolynomial bernstein;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
*
|
|
98
|
+
*/
|
|
99
|
+
@XmlTransient
|
|
100
|
+
public Vec2D[] delta;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
*
|
|
104
|
+
*/
|
|
105
|
+
@XmlTransient
|
|
106
|
+
public Vec2D[] coeffA;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
*
|
|
110
|
+
*/
|
|
111
|
+
@XmlTransient
|
|
112
|
+
public float[] bi;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
*
|
|
116
|
+
*/
|
|
117
|
+
@XmlAttribute
|
|
118
|
+
protected float tightness;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
*
|
|
122
|
+
*/
|
|
123
|
+
@XmlTransient
|
|
124
|
+
protected float invTightness;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Constructs an empty spline container with default curve tightness. You
|
|
128
|
+
* need to populate the spline manually by using {@link #add(ReadonlyVec2D)}
|
|
129
|
+
* .
|
|
130
|
+
*/
|
|
131
|
+
public Spline2D() {
|
|
132
|
+
setTightness(DEFAULT_TIGHTNESS);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @param rawPoints
|
|
137
|
+
* list of control point vectors
|
|
138
|
+
*/
|
|
139
|
+
public Spline2D(List<Vec2D> rawPoints) {
|
|
140
|
+
this(rawPoints, null, DEFAULT_TIGHTNESS);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @param rawPoints
|
|
145
|
+
* list of control point vectors
|
|
146
|
+
* @param b
|
|
147
|
+
* predefined Bernstein polynomial (good for reusing)
|
|
148
|
+
* @param tightness
|
|
149
|
+
* default curve tightness used for the interpolated vertices
|
|
150
|
+
* {@linkplain #setTightness(float)}
|
|
151
|
+
*/
|
|
152
|
+
public Spline2D(List<Vec2D> rawPoints, BernsteinPolynomial b,
|
|
153
|
+
float tightness) {
|
|
154
|
+
pointList.addAll(rawPoints);
|
|
155
|
+
bernstein = b;
|
|
156
|
+
setTightness(tightness);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* @param pointArray
|
|
161
|
+
* array of control point vectors
|
|
162
|
+
*/
|
|
163
|
+
public Spline2D(Vec2D[] pointArray) {
|
|
164
|
+
this(pointArray, null, DEFAULT_TIGHTNESS);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @param pointArray
|
|
169
|
+
* array of control point vectors
|
|
170
|
+
* @param b
|
|
171
|
+
* predefined Bernstein polynomial (good for reusing)
|
|
172
|
+
* @param tightness
|
|
173
|
+
* default curve tightness used for the interpolated vertices
|
|
174
|
+
* {@linkplain #setTightness(float)}
|
|
175
|
+
*/
|
|
176
|
+
public Spline2D(Vec2D[] pointArray, BernsteinPolynomial b, float tightness) {
|
|
177
|
+
this(Arrays.asList(pointArray), b, tightness);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
*
|
|
182
|
+
* @param x
|
|
183
|
+
* @param y
|
|
184
|
+
* @return
|
|
185
|
+
*/
|
|
186
|
+
public Spline2D add(float x, float y) {
|
|
187
|
+
return add(new Vec2D(x, y));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Adds a copy of the given point to the list of control points.
|
|
192
|
+
*
|
|
193
|
+
* @param p
|
|
194
|
+
* @return itself
|
|
195
|
+
*/
|
|
196
|
+
public Spline2D add(ReadonlyVec2D p) {
|
|
197
|
+
pointList.add(p.copy());
|
|
198
|
+
return this;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
*
|
|
203
|
+
*/
|
|
204
|
+
protected void findCPoints() {
|
|
205
|
+
bi[1] = -tightness;
|
|
206
|
+
coeffA[1].set((points[2].x - points[0].x - delta[0].x) * tightness,
|
|
207
|
+
(points[2].y - points[0].y - delta[0].y) * tightness);
|
|
208
|
+
final int numP = getNumPoints();
|
|
209
|
+
for (int i = 2; i < numP - 1; i++) {
|
|
210
|
+
bi[i] = -1 / (invTightness + bi[i - 1]);
|
|
211
|
+
coeffA[i].set(
|
|
212
|
+
-(points[i + 1].x - points[i - 1].x - coeffA[i - 1].x)
|
|
213
|
+
* bi[i],
|
|
214
|
+
-(points[i + 1].y - points[i - 1].y - coeffA[i - 1].y)
|
|
215
|
+
* bi[i]);
|
|
216
|
+
}
|
|
217
|
+
for (int i = numP - 2; i > 0; i--) {
|
|
218
|
+
delta[i].set(coeffA[i].x + delta[i + 1].x * bi[i], coeffA[i].y
|
|
219
|
+
+ delta[i + 1].y * bi[i]);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Returns the number of control points.
|
|
225
|
+
*
|
|
226
|
+
* @return the numP
|
|
227
|
+
*/
|
|
228
|
+
public final int getNumPoints() {
|
|
229
|
+
return pointList.size();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* @return the pointList
|
|
234
|
+
*/
|
|
235
|
+
public List<Vec2D> getPointList() {
|
|
236
|
+
return pointList;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* @see #setTightness(float)
|
|
241
|
+
* @return the spline3d tightness
|
|
242
|
+
* @since 0014 (rev.216)
|
|
243
|
+
*/
|
|
244
|
+
public float getTightness() {
|
|
245
|
+
return tightness;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Overrides the current control points with the given list.
|
|
250
|
+
*
|
|
251
|
+
* @param plist
|
|
252
|
+
* the pointList to set
|
|
253
|
+
* @return itself
|
|
254
|
+
*/
|
|
255
|
+
public Spline2D setPointList(List<Vec2D> plist) {
|
|
256
|
+
pointList.clear();
|
|
257
|
+
for (ReadonlyVec2D p : plist) {
|
|
258
|
+
pointList.add(p.copy());
|
|
259
|
+
}
|
|
260
|
+
return this;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Sets the tightness for future curve interpolation calls. Default value is
|
|
265
|
+
* 0.25. A value of 0.0 equals linear interpolation between the given curve
|
|
266
|
+
* input points. Curve behaviour for values outside the 0.0 .. 0.5 interval
|
|
267
|
+
* is unspecified and becomes increasingly less intuitive. Negative values
|
|
268
|
+
* are possible too and create interesting results (in some cases).
|
|
269
|
+
*
|
|
270
|
+
* @param tightness
|
|
271
|
+
* the tightness value used for the next call to
|
|
272
|
+
* {@link #toLineStrip2D(int)}
|
|
273
|
+
* @return
|
|
274
|
+
* @since 0014 (rev. 216)
|
|
275
|
+
*/
|
|
276
|
+
public final Spline2D setTightness(float tightness) {
|
|
277
|
+
this.tightness = tightness;
|
|
278
|
+
this.invTightness = 1f / tightness;
|
|
279
|
+
return this;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* <p>
|
|
284
|
+
* Computes all curve vertices based on the resolution/number of
|
|
285
|
+
* subdivisions requested. The higher, the more vertices are computed:
|
|
286
|
+
* </p>
|
|
287
|
+
* <p>
|
|
288
|
+
* <strong>(number of control points - 1) * resolution + 1</strong>
|
|
289
|
+
* </p>
|
|
290
|
+
* <p>
|
|
291
|
+
* Since version 0014 the automatic placement of the curve handles can also
|
|
292
|
+
* be manipulated via the {@linkplain #setTightness(float)} method.
|
|
293
|
+
* </p>
|
|
294
|
+
*
|
|
295
|
+
* @param res
|
|
296
|
+
* the number of vertices to be computed per segment between
|
|
297
|
+
* original control points (incl. control point always at the
|
|
298
|
+
* start of each segment)
|
|
299
|
+
* @return list of Vec2D vertices along the curve
|
|
300
|
+
*/
|
|
301
|
+
public LineStrip2D toLineStrip2D(int res) {
|
|
302
|
+
updateCoefficients();
|
|
303
|
+
if (res < 1) {
|
|
304
|
+
res = 1;
|
|
305
|
+
}
|
|
306
|
+
res++;
|
|
307
|
+
if (bernstein == null || bernstein.resolution != res) {
|
|
308
|
+
bernstein = new BernsteinPolynomial(res);
|
|
309
|
+
}
|
|
310
|
+
findCPoints();
|
|
311
|
+
Vec2D deltaP = new Vec2D();
|
|
312
|
+
Vec2D deltaQ = new Vec2D();
|
|
313
|
+
res--;
|
|
314
|
+
LineStrip2D strip = new LineStrip2D();
|
|
315
|
+
for (int i = 0, numP = getNumPoints(); i < numP - 1; i++) {
|
|
316
|
+
Vec2D p = points[i];
|
|
317
|
+
Vec2D q = points[i + 1];
|
|
318
|
+
deltaP.set(delta[i]).addSelf(p);
|
|
319
|
+
deltaQ.set(q).subSelf(delta[i + 1]);
|
|
320
|
+
for (int k = 0; k < res; k++) {
|
|
321
|
+
float x = p.x * bernstein.b0[k] + deltaP.x * bernstein.b1[k]
|
|
322
|
+
+ deltaQ.x * bernstein.b2[k] + q.x * bernstein.b3[k];
|
|
323
|
+
float y = p.y * bernstein.b0[k] + deltaP.y * bernstein.b1[k]
|
|
324
|
+
+ deltaQ.y * bernstein.b2[k] + q.y * bernstein.b3[k];
|
|
325
|
+
strip.add(new Vec2D(x, y));
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
strip.add(points[points.length - 1].copy());
|
|
329
|
+
return strip;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
*
|
|
334
|
+
*/
|
|
335
|
+
public void updateCoefficients() {
|
|
336
|
+
final int numP = getNumPoints();
|
|
337
|
+
if (points == null || (points != null && points.length != numP)) {
|
|
338
|
+
coeffA = new Vec2D[numP];
|
|
339
|
+
delta = new Vec2D[numP];
|
|
340
|
+
bi = new float[numP];
|
|
341
|
+
for (int i = 0; i < numP; i++) {
|
|
342
|
+
coeffA[i] = new Vec2D();
|
|
343
|
+
delta[i] = new Vec2D();
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
setTightness(tightness);
|
|
347
|
+
points = pointList.toArray(new Vec2D[numP]);
|
|
348
|
+
}
|
|
349
|
+
}
|