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,422 @@
|
|
|
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.Collections;
|
|
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.XmlElement;
|
|
37
|
+
import javax.xml.bind.annotation.XmlTransient;
|
|
38
|
+
|
|
39
|
+
import toxi.geom.Line2D.LineIntersection.Type;
|
|
40
|
+
import toxi.math.MathUtils;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
*
|
|
44
|
+
* @author tux
|
|
45
|
+
*/
|
|
46
|
+
@XmlAccessorType(XmlAccessType.FIELD)
|
|
47
|
+
public class Triangle2D implements Shape2D {
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
*
|
|
51
|
+
* @param a
|
|
52
|
+
* @param b
|
|
53
|
+
* @return
|
|
54
|
+
*/
|
|
55
|
+
public static Triangle2D createEquilateralFrom(ReadonlyVec2D a,
|
|
56
|
+
ReadonlyVec2D b) {
|
|
57
|
+
Vec2D c = a.interpolateTo(b, 0.5f);
|
|
58
|
+
Vec2D dir = a.sub(b);
|
|
59
|
+
Vec2D n = dir.getPerpendicular();
|
|
60
|
+
c.addSelf(n.normalizeTo(dir.magnitude() * MathUtils.SQRT3 / 2));
|
|
61
|
+
return new Triangle2D(a, b, c);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
*
|
|
66
|
+
* @param a
|
|
67
|
+
* @param b
|
|
68
|
+
* @param c
|
|
69
|
+
* @return
|
|
70
|
+
*/
|
|
71
|
+
public static boolean isClockwise(Vec2D a, Vec2D b, Vec2D c) {
|
|
72
|
+
float determ = (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
|
|
73
|
+
return (determ > 0.0);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@XmlElement(required = true)
|
|
77
|
+
public Vec2D a,
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
*
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
*
|
|
85
|
+
*/
|
|
86
|
+
b,
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
*
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
*
|
|
94
|
+
*/
|
|
95
|
+
c;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
*
|
|
99
|
+
*/
|
|
100
|
+
@XmlTransient
|
|
101
|
+
public Vec2D centroid;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
*
|
|
105
|
+
*/
|
|
106
|
+
public Triangle2D() {
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
*
|
|
111
|
+
* @param a
|
|
112
|
+
* @param b
|
|
113
|
+
* @param c
|
|
114
|
+
*/
|
|
115
|
+
public Triangle2D(ReadonlyVec2D a, ReadonlyVec2D b, ReadonlyVec2D c) {
|
|
116
|
+
this.a = a.copy();
|
|
117
|
+
this.b = b.copy();
|
|
118
|
+
this.c = c.copy();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
*
|
|
123
|
+
* @param offset
|
|
124
|
+
* @return
|
|
125
|
+
*/
|
|
126
|
+
public Triangle2D adjustTriangleSizeBy(float offset) {
|
|
127
|
+
return adjustTriangleSizeBy(offset, offset, offset);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
*
|
|
132
|
+
* @param offAB
|
|
133
|
+
* @param offBC
|
|
134
|
+
* @param offCA
|
|
135
|
+
* @return
|
|
136
|
+
*/
|
|
137
|
+
public Triangle2D adjustTriangleSizeBy(float offAB, float offBC, float offCA) {
|
|
138
|
+
computeCentroid();
|
|
139
|
+
Line2D ab = new Line2D(a.copy(), b.copy()).offsetAndGrowBy(offAB,
|
|
140
|
+
100000, centroid);
|
|
141
|
+
Line2D bc = new Line2D(b.copy(), c.copy()).offsetAndGrowBy(offBC,
|
|
142
|
+
100000, centroid);
|
|
143
|
+
Line2D ca = new Line2D(c.copy(), a.copy()).offsetAndGrowBy(offCA,
|
|
144
|
+
100000, centroid);
|
|
145
|
+
a = ab.intersectLine(ca).getPos();
|
|
146
|
+
b = ab.intersectLine(bc).getPos();
|
|
147
|
+
c = bc.intersectLine(ca).getPos();
|
|
148
|
+
computeCentroid();
|
|
149
|
+
return this;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
*
|
|
154
|
+
* @return
|
|
155
|
+
*/
|
|
156
|
+
public Vec2D computeCentroid() {
|
|
157
|
+
centroid = a.add(b).addSelf(c).scaleSelf(1f / 3);
|
|
158
|
+
return centroid;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Checks if the given point is inside the triangle created by the points a,
|
|
163
|
+
* b and c. The triangle vertices are inclusive themselves.
|
|
164
|
+
*
|
|
165
|
+
* @param p
|
|
166
|
+
* @return true, if point is in triangle.
|
|
167
|
+
*/
|
|
168
|
+
@Override
|
|
169
|
+
public boolean containsPoint(ReadonlyVec2D p) {
|
|
170
|
+
Vec2D v1 = p.sub(a);
|
|
171
|
+
Vec2D v2 = p.sub(b);
|
|
172
|
+
Vec2D v3 = p.sub(c);
|
|
173
|
+
if (v1.isZeroVector() || v2.isZeroVector() || v3.isZeroVector()) {
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
v1.normalize();
|
|
177
|
+
v2.normalize();
|
|
178
|
+
v3.normalize();
|
|
179
|
+
double total_angles = Math.acos(v1.dot(v2));
|
|
180
|
+
total_angles += Math.acos(v2.dot(v3));
|
|
181
|
+
total_angles += Math.acos(v3.dot(v1));
|
|
182
|
+
return (MathUtils.abs(total_angles - MathUtils.TWO_PI) <= 0.001);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
*
|
|
187
|
+
* @return
|
|
188
|
+
*/
|
|
189
|
+
public Triangle2D copy() {
|
|
190
|
+
return new Triangle2D(a.copy(), b.copy(), c.copy());
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
*
|
|
195
|
+
* @return
|
|
196
|
+
*/
|
|
197
|
+
public Triangle2D flipVertexOrder() {
|
|
198
|
+
Vec2D t = a;
|
|
199
|
+
a = c;
|
|
200
|
+
c = t;
|
|
201
|
+
return this;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
*
|
|
206
|
+
* @param p
|
|
207
|
+
* @return
|
|
208
|
+
*/
|
|
209
|
+
public Vec2D fromBarycentric(ReadonlyVec3D p) {
|
|
210
|
+
return new Vec2D(a.x * p.x() + b.x * p.y() + c.x * p.z(), a.y * p.x()
|
|
211
|
+
+ b.y * p.y() + c.y * p.z());
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
@Override
|
|
215
|
+
public float getArea() {
|
|
216
|
+
return b.sub(a).cross(c.sub(a)) * 0.5f;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
@Override
|
|
220
|
+
public Circle getBoundingCircle() {
|
|
221
|
+
return Circle.from3Points(a, b, c);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
@Override
|
|
225
|
+
public Rect getBounds() {
|
|
226
|
+
return new Rect(Vec2D.min(Vec2D.min(a, b), c), Vec2D.max(
|
|
227
|
+
Vec2D.max(a, b), c));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
*
|
|
232
|
+
* @return
|
|
233
|
+
*/
|
|
234
|
+
public Circle getCircumCircle() {
|
|
235
|
+
Vec3D cr = a.bisect(b).cross(b.bisect(c));
|
|
236
|
+
Vec2D circ = new Vec2D(cr.x / cr.z, cr.y / cr.z);
|
|
237
|
+
float sa = a.distanceTo(b);
|
|
238
|
+
float sb = b.distanceTo(c);
|
|
239
|
+
float sc = c.distanceTo(a);
|
|
240
|
+
float radius = sa
|
|
241
|
+
* sb
|
|
242
|
+
* sc
|
|
243
|
+
/ (float) Math.sqrt((sa + sb + sc) * (-sa + sb + sc)
|
|
244
|
+
* (sa - sb + sc) * (sa + sb - sc));
|
|
245
|
+
return new Circle(circ, radius);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
@Override
|
|
249
|
+
public float getCircumference() {
|
|
250
|
+
return a.distanceTo(b) + b.distanceTo(c) + c.distanceTo(a);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Finds and returns the closest point on any of the triangle edges to the
|
|
255
|
+
* point given.
|
|
256
|
+
*
|
|
257
|
+
* @param p
|
|
258
|
+
* point to check
|
|
259
|
+
* @return closest point
|
|
260
|
+
*/
|
|
261
|
+
public Vec2D getClosestPointTo(ReadonlyVec2D p) {
|
|
262
|
+
Line2D edge = new Line2D(a, b);
|
|
263
|
+
Vec2D Rab = edge.closestPointTo(p);
|
|
264
|
+
Vec2D Rbc = edge.set(b, c).closestPointTo(p);
|
|
265
|
+
Vec2D Rca = edge.set(c, a).closestPointTo(p);
|
|
266
|
+
|
|
267
|
+
float dAB = p.sub(Rab).magSquared();
|
|
268
|
+
float dBC = p.sub(Rbc).magSquared();
|
|
269
|
+
float dCA = p.sub(Rca).magSquared();
|
|
270
|
+
|
|
271
|
+
float min = dAB;
|
|
272
|
+
Vec2D result = Rab;
|
|
273
|
+
|
|
274
|
+
if (dBC < min) {
|
|
275
|
+
min = dBC;
|
|
276
|
+
result = Rbc;
|
|
277
|
+
}
|
|
278
|
+
if (dCA < min) {
|
|
279
|
+
result = Rca;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return result;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
@Override
|
|
286
|
+
public List<Line2D> getEdges() {
|
|
287
|
+
return toPolygon2D().getEdges();
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Creates a random point within the triangle using barycentric coordinates.
|
|
292
|
+
*
|
|
293
|
+
* @return Vec2D
|
|
294
|
+
*/
|
|
295
|
+
@Override
|
|
296
|
+
public Vec2D getRandomPoint() {
|
|
297
|
+
List<Float> barycentric = new ArrayList<>(3);
|
|
298
|
+
barycentric.add(MathUtils.random(1f));
|
|
299
|
+
barycentric.add(MathUtils.random(1f - barycentric.get(0)));
|
|
300
|
+
barycentric.add(1 - (barycentric.get(0) + barycentric.get(1)));
|
|
301
|
+
Collections.shuffle(barycentric);
|
|
302
|
+
return fromBarycentric(new Vec3D(barycentric.get(0),
|
|
303
|
+
barycentric.get(1), barycentric.get(2)));
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
*
|
|
308
|
+
* @return
|
|
309
|
+
*/
|
|
310
|
+
public Vec2D[] getVertexArray() {
|
|
311
|
+
return getVertexArray(null, 0);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
*
|
|
316
|
+
* @param array
|
|
317
|
+
* @param offset
|
|
318
|
+
* @return
|
|
319
|
+
*/
|
|
320
|
+
public Vec2D[] getVertexArray(Vec2D[] array, int offset) {
|
|
321
|
+
if (array == null) {
|
|
322
|
+
array = new Vec2D[3];
|
|
323
|
+
}
|
|
324
|
+
array[offset++] = a;
|
|
325
|
+
array[offset++] = b;
|
|
326
|
+
array[offset] = c;
|
|
327
|
+
return array;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Checks if this triangle intersects the given one. The check handles both
|
|
332
|
+
* partial and total containment as well as intersections of all edges.
|
|
333
|
+
*
|
|
334
|
+
* @param tri
|
|
335
|
+
* @return true, if intersecting
|
|
336
|
+
*/
|
|
337
|
+
public boolean intersectsTriangle(Triangle2D tri) {
|
|
338
|
+
if (containsPoint(tri.a) || containsPoint(tri.b)
|
|
339
|
+
|| containsPoint(tri.c)) {
|
|
340
|
+
return true;
|
|
341
|
+
}
|
|
342
|
+
if (tri.containsPoint(a) || tri.containsPoint(b)
|
|
343
|
+
|| tri.containsPoint(c)) {
|
|
344
|
+
return true;
|
|
345
|
+
}
|
|
346
|
+
Line2D[] ea = new Line2D[] {
|
|
347
|
+
new Line2D(a, b), new Line2D(b, c), new Line2D(c, a)
|
|
348
|
+
};
|
|
349
|
+
Line2D[] eb = new Line2D[] {
|
|
350
|
+
new Line2D(tri.a, tri.b), new Line2D(tri.b, tri.c),
|
|
351
|
+
new Line2D(tri.c, tri.a)
|
|
352
|
+
};
|
|
353
|
+
for (Line2D la : ea) {
|
|
354
|
+
for (Line2D lb : eb) {
|
|
355
|
+
Type type = la.intersectLine(lb).getType();
|
|
356
|
+
if (type != Type.NON_INTERSECTING && type != Type.PARALLEL) {
|
|
357
|
+
return true;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
*
|
|
366
|
+
* @return
|
|
367
|
+
*/
|
|
368
|
+
public boolean isClockwise() {
|
|
369
|
+
return Triangle2D.isClockwise(a, b, c);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
*
|
|
374
|
+
* @param a2
|
|
375
|
+
* @param b2
|
|
376
|
+
* @param c2
|
|
377
|
+
*/
|
|
378
|
+
public void set(Vec2D a2, Vec2D b2, Vec2D c2) {
|
|
379
|
+
a = a2;
|
|
380
|
+
b = b2;
|
|
381
|
+
c = c2;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Produces the barycentric coordinates of the given point within this
|
|
386
|
+
* triangle. These coordinates can then be used to re-project the point into
|
|
387
|
+
* a different triangle using its {@link #fromBarycentric(ReadonlyVec3D)}
|
|
388
|
+
* method.
|
|
389
|
+
*
|
|
390
|
+
* @param p
|
|
391
|
+
* point in world space
|
|
392
|
+
* @return barycentric coords as {@link Vec3D}
|
|
393
|
+
*/
|
|
394
|
+
public Vec3D toBarycentric(ReadonlyVec2D p) {
|
|
395
|
+
return new Triangle3D(a.to3DXY(), b.to3DXY(), c.to3DXY())
|
|
396
|
+
.toBarycentric(p.to3DXY());
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Creates a {@link Polygon2D} instance of the triangle. The vertices of
|
|
401
|
+
* this polygon are disconnected from the ones defining this triangle.
|
|
402
|
+
*
|
|
403
|
+
* @return triangle as polygon
|
|
404
|
+
*/
|
|
405
|
+
@Override
|
|
406
|
+
public Polygon2D toPolygon2D() {
|
|
407
|
+
Polygon2D poly = new Polygon2D();
|
|
408
|
+
poly.add(a.copy());
|
|
409
|
+
poly.add(b.copy());
|
|
410
|
+
poly.add(c.copy());
|
|
411
|
+
return poly;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
*
|
|
416
|
+
* @return
|
|
417
|
+
*/
|
|
418
|
+
@Override
|
|
419
|
+
public String toString() {
|
|
420
|
+
return "Triangle2D: " + a + "," + b + "," + c;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
@@ -0,0 +1,456 @@
|
|
|
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.XmlElement;
|
|
33
|
+
import javax.xml.bind.annotation.XmlTransient;
|
|
34
|
+
|
|
35
|
+
import toxi.math.MathUtils;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
*
|
|
39
|
+
* @author tux
|
|
40
|
+
*/
|
|
41
|
+
@XmlAccessorType(XmlAccessType.FIELD)
|
|
42
|
+
public class Triangle3D implements Shape3D {
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
*
|
|
46
|
+
* @param a
|
|
47
|
+
* @param b
|
|
48
|
+
* @return
|
|
49
|
+
*/
|
|
50
|
+
public static Triangle3D createEquilateralFrom(Vec3D a, Vec3D b) {
|
|
51
|
+
Vec3D c = a.interpolateTo(b, 0.5f);
|
|
52
|
+
Vec3D dir = b.sub(a);
|
|
53
|
+
Vec3D n = a.cross(dir.normalize());
|
|
54
|
+
c.addSelf(n.normalizeTo(dir.magnitude() * MathUtils.SQRT3 / 2));
|
|
55
|
+
return new Triangle3D(a, b, c);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
*
|
|
60
|
+
* @param a
|
|
61
|
+
* @param b
|
|
62
|
+
* @param c
|
|
63
|
+
* @return
|
|
64
|
+
*/
|
|
65
|
+
public static boolean isClockwiseInXY(Vec3D a, Vec3D b, Vec3D c) {
|
|
66
|
+
float determ = (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
|
|
67
|
+
return (determ < 0.0);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
*
|
|
72
|
+
* @param a
|
|
73
|
+
* @param b
|
|
74
|
+
* @param c
|
|
75
|
+
* @return
|
|
76
|
+
*/
|
|
77
|
+
public static boolean isClockwiseInXZ(Vec3D a, Vec3D b, Vec3D c) {
|
|
78
|
+
float determ = (b.x - a.x) * (c.z - a.z) - (c.x - a.x) * (b.z - a.z);
|
|
79
|
+
return (determ < 0.0);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
*
|
|
84
|
+
* @param a
|
|
85
|
+
* @param b
|
|
86
|
+
* @param c
|
|
87
|
+
* @return
|
|
88
|
+
*/
|
|
89
|
+
public static boolean isClockwiseInYZ(Vec3D a, Vec3D b, Vec3D c) {
|
|
90
|
+
float determ = (b.y - a.y) * (c.z - a.z) - (c.y - a.y) * (b.z - a.z);
|
|
91
|
+
return (determ < 0.0);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@XmlElement(required = true)
|
|
95
|
+
public Vec3D a,
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
*
|
|
99
|
+
*/
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
*
|
|
103
|
+
*/
|
|
104
|
+
b,
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
*
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
*
|
|
112
|
+
*/
|
|
113
|
+
c;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
*
|
|
117
|
+
*/
|
|
118
|
+
@XmlElement(required = true)
|
|
119
|
+
public Vec3D normal;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
*
|
|
123
|
+
*/
|
|
124
|
+
@XmlTransient
|
|
125
|
+
public Vec3D centroid;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
*
|
|
129
|
+
*/
|
|
130
|
+
public Triangle3D() {
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
*
|
|
135
|
+
* @param a
|
|
136
|
+
* @param b
|
|
137
|
+
* @param c
|
|
138
|
+
*/
|
|
139
|
+
public Triangle3D(Vec3D a, Vec3D b, Vec3D c) {
|
|
140
|
+
this.a = a;
|
|
141
|
+
this.b = b;
|
|
142
|
+
this.c = c;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Computes the the point closest to the current vector on the surface of
|
|
147
|
+
* triangle abc.
|
|
148
|
+
*
|
|
149
|
+
* From Real-Time Collision Detection by Christer Ericson, published by
|
|
150
|
+
* Morgan Kaufmann Publishers, Copyright 2005 Elsevier Inc
|
|
151
|
+
*
|
|
152
|
+
* @param p
|
|
153
|
+
* @return closest point on triangle (result may also be one of a, b or c)
|
|
154
|
+
*/
|
|
155
|
+
public Vec3D closestPointOnSurface(Vec3D p) {
|
|
156
|
+
Vec3D ab = b.sub(a);
|
|
157
|
+
Vec3D ac = c.sub(a);
|
|
158
|
+
Vec3D bc = c.sub(b);
|
|
159
|
+
|
|
160
|
+
ReadonlyVec3D pa = p.sub(a);
|
|
161
|
+
ReadonlyVec3D pb = p.sub(b);
|
|
162
|
+
ReadonlyVec3D pc = p.sub(c);
|
|
163
|
+
|
|
164
|
+
Vec3D ap = a.sub(p);
|
|
165
|
+
Vec3D bp = b.sub(p);
|
|
166
|
+
Vec3D cp = c.sub(p);
|
|
167
|
+
|
|
168
|
+
// Compute parametric position s for projection P' of P on AB,
|
|
169
|
+
// P' = A + s*AB, s = snom/(snom+sdenom)
|
|
170
|
+
float snom = pa.dot(ab);
|
|
171
|
+
|
|
172
|
+
// Compute parametric position t for projection P' of P on AC,
|
|
173
|
+
// P' = A + t*AC, s = tnom/(tnom+tdenom)
|
|
174
|
+
float tnom = pa.dot(ac);
|
|
175
|
+
|
|
176
|
+
if (snom <= 0.0f && tnom <= 0.0f) {
|
|
177
|
+
return a; // Vertex region early out
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
float sdenom = pb.dot(a.sub(b));
|
|
181
|
+
float tdenom = pc.dot(a.sub(c));
|
|
182
|
+
|
|
183
|
+
// Compute parametric position u for projection P' of P on BC,
|
|
184
|
+
// P' = B + u*BC, u = unom/(unom+udenom)
|
|
185
|
+
float unom = pb.dot(bc);
|
|
186
|
+
float udenom = pc.dot(b.sub(c));
|
|
187
|
+
|
|
188
|
+
if (sdenom <= 0.0f && unom <= 0.0f) {
|
|
189
|
+
return b; // Vertex region early out
|
|
190
|
+
}
|
|
191
|
+
if (tdenom <= 0.0f && udenom <= 0.0f) {
|
|
192
|
+
return c; // Vertex region early out
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// P is outside (or on) AB if the triple scalar product [N PA PB] <= 0
|
|
196
|
+
ReadonlyVec3D n = ab.cross(ac);
|
|
197
|
+
float vc = n.dot(ap.crossSelf(bp));
|
|
198
|
+
|
|
199
|
+
// If P outside AB and within feature region of AB,
|
|
200
|
+
// return projection of P onto AB
|
|
201
|
+
if (vc <= 0.0f && snom >= 0.0f && sdenom >= 0.0f) {
|
|
202
|
+
// return a + snom / (snom + sdenom) * ab;
|
|
203
|
+
return a.add(ab.scaleSelf(snom / (snom + sdenom)));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// P is outside (or on) BC if the triple scalar product [N PB PC] <= 0
|
|
207
|
+
float va = n.dot(bp.crossSelf(cp));
|
|
208
|
+
// If P outside BC and within feature region of BC,
|
|
209
|
+
// return projection of P onto BC
|
|
210
|
+
if (va <= 0.0f && unom >= 0.0f && udenom >= 0.0f) {
|
|
211
|
+
// return b + unom / (unom + udenom) * bc;
|
|
212
|
+
return b.add(bc.scaleSelf(unom / (unom + udenom)));
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// P is outside (or on) CA if the triple scalar product [N PC PA] <= 0
|
|
216
|
+
float vb = n.dot(cp.crossSelf(ap));
|
|
217
|
+
// If P outside CA and within feature region of CA,
|
|
218
|
+
// return projection of P onto CA
|
|
219
|
+
if (vb <= 0.0f && tnom >= 0.0f && tdenom >= 0.0f) {
|
|
220
|
+
// return a + tnom / (tnom + tdenom) * ac;
|
|
221
|
+
return a.add(ac.scaleSelf(tnom / (tnom + tdenom)));
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// P must project inside face region. Compute Q using barycentric
|
|
225
|
+
// coordinates
|
|
226
|
+
float u = va / (va + vb + vc);
|
|
227
|
+
float v = vb / (va + vb + vc);
|
|
228
|
+
float w = 1.0f - u - v; // = vc / (va + vb + vc)
|
|
229
|
+
// return u * a + v * b + w * c;
|
|
230
|
+
return a.scale(u).addSelf(b.scale(v)).addSelf(c.scale(w));
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
*
|
|
235
|
+
* @return
|
|
236
|
+
*/
|
|
237
|
+
public Vec3D computeCentroid() {
|
|
238
|
+
centroid = a.add(b).addSelf(c).scaleSelf(1f / 3);
|
|
239
|
+
return centroid;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
*
|
|
244
|
+
* @return
|
|
245
|
+
*/
|
|
246
|
+
public Vec3D computeNormal() {
|
|
247
|
+
normal = a.sub(c).crossSelf(a.sub(b)).normalize();
|
|
248
|
+
return normal;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Checks if point vector is inside the triangle created by the points a, b
|
|
253
|
+
* and c. These points will create a plane and the point checked will have
|
|
254
|
+
* to be on this plane in the region between a,b,c (triangle vertices
|
|
255
|
+
* inclusive).
|
|
256
|
+
*
|
|
257
|
+
* @param p
|
|
258
|
+
* @return true, if point is in triangle.
|
|
259
|
+
*/
|
|
260
|
+
@Override
|
|
261
|
+
public boolean containsPoint(ReadonlyVec3D p) {
|
|
262
|
+
Vec3D v0 = c.sub(a);
|
|
263
|
+
Vec3D v1 = b.sub(a);
|
|
264
|
+
Vec3D v2 = p.sub(a);
|
|
265
|
+
|
|
266
|
+
// Compute dot products
|
|
267
|
+
float dot00 = v0.dot(v0);
|
|
268
|
+
float dot01 = v0.dot(v1);
|
|
269
|
+
float dot02 = v0.dot(v2);
|
|
270
|
+
float dot11 = v1.dot(v1);
|
|
271
|
+
float dot12 = v1.dot(v2);
|
|
272
|
+
|
|
273
|
+
// Compute barycentric coordinates
|
|
274
|
+
float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01);
|
|
275
|
+
float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
|
276
|
+
float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
|
277
|
+
|
|
278
|
+
// Check if point is in triangle
|
|
279
|
+
return (u >= 0.0) && (v >= 0.0) && (u + v <= 1.0);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
*
|
|
284
|
+
* @return
|
|
285
|
+
*/
|
|
286
|
+
public Triangle3D flipVertexOrder() {
|
|
287
|
+
Vec3D t = a;
|
|
288
|
+
a = c;
|
|
289
|
+
c = t;
|
|
290
|
+
return this;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
*
|
|
295
|
+
* @param p
|
|
296
|
+
* @return
|
|
297
|
+
*/
|
|
298
|
+
public Vec3D fromBarycentric(ReadonlyVec3D p) {
|
|
299
|
+
return new Vec3D(a.x * p.x() + b.x * p.y() + c.x * p.z(), a.y * p.x()
|
|
300
|
+
+ b.y * p.y() + c.y * p.z(), a.z * p.x() + b.z * p.y() + c.z
|
|
301
|
+
* p.z());
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
*
|
|
306
|
+
* @return
|
|
307
|
+
*/
|
|
308
|
+
public AABB getBoundingBox() {
|
|
309
|
+
Vec3D min = Vec3D.min(Vec3D.min(a, b), c);
|
|
310
|
+
Vec3D max = Vec3D.max(Vec3D.max(a, b), c);
|
|
311
|
+
return AABB.fromMinMax(min, max);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Finds and returns the closest point on any of the triangle edges to the
|
|
316
|
+
* point given.
|
|
317
|
+
*
|
|
318
|
+
* @param p
|
|
319
|
+
* point to check
|
|
320
|
+
* @return closest point
|
|
321
|
+
*/
|
|
322
|
+
|
|
323
|
+
public Vec3D getClosestPointTo(ReadonlyVec3D p) {
|
|
324
|
+
Line3D edge = new Line3D(a, b);
|
|
325
|
+
final Vec3D Rab = edge.closestPointTo(p);
|
|
326
|
+
final Vec3D Rbc = edge.set(b, c).closestPointTo(p);
|
|
327
|
+
final Vec3D Rca = edge.set(c, a).closestPointTo(p);
|
|
328
|
+
|
|
329
|
+
final float dAB = p.sub(Rab).magSquared();
|
|
330
|
+
final float dBC = p.sub(Rbc).magSquared();
|
|
331
|
+
final float dCA = p.sub(Rca).magSquared();
|
|
332
|
+
|
|
333
|
+
float min = dAB;
|
|
334
|
+
Vec3D result = Rab;
|
|
335
|
+
|
|
336
|
+
if (dBC < min) {
|
|
337
|
+
min = dBC;
|
|
338
|
+
result = Rbc;
|
|
339
|
+
}
|
|
340
|
+
if (dCA < min) {
|
|
341
|
+
result = Rca;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return result;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
*
|
|
349
|
+
* @return
|
|
350
|
+
*/
|
|
351
|
+
public Vec3D[] getVertexArray() {
|
|
352
|
+
return getVertexArray(null, 0);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
*
|
|
357
|
+
* @param array
|
|
358
|
+
* @param offset
|
|
359
|
+
* @return
|
|
360
|
+
*/
|
|
361
|
+
public Vec3D[] getVertexArray(Vec3D[] array, int offset) {
|
|
362
|
+
if (array == null) {
|
|
363
|
+
array = new Vec3D[3];
|
|
364
|
+
}
|
|
365
|
+
array[offset++] = a;
|
|
366
|
+
array[offset++] = b;
|
|
367
|
+
array[offset] = c;
|
|
368
|
+
return array;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
*
|
|
373
|
+
* @return
|
|
374
|
+
*/
|
|
375
|
+
public boolean isClockwiseInXY() {
|
|
376
|
+
return Triangle3D.isClockwiseInXY(a, b, c);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
*
|
|
381
|
+
* @return
|
|
382
|
+
*/
|
|
383
|
+
public boolean isClockwiseInXZ() {
|
|
384
|
+
return Triangle3D.isClockwiseInXY(a, b, c);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
*
|
|
389
|
+
* @return
|
|
390
|
+
*/
|
|
391
|
+
public boolean isClockwiseInYZ() {
|
|
392
|
+
return Triangle3D.isClockwiseInXY(a, b, c);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
private boolean isSameClockDir(Vec3D a, Vec3D b, ReadonlyVec3D p, Vec3D norm) {
|
|
396
|
+
float bax = b.x - a.x;
|
|
397
|
+
float bay = b.y - a.y;
|
|
398
|
+
float baz = b.z - a.z;
|
|
399
|
+
float pax = p.x() - a.x;
|
|
400
|
+
float pay = p.y() - a.y;
|
|
401
|
+
float paz = p.z() - a.z;
|
|
402
|
+
float nx = bay * paz - pay * baz;
|
|
403
|
+
float ny = baz * pax - paz * bax;
|
|
404
|
+
float nz = bax * pay - pax * bay;
|
|
405
|
+
float dotprod = nx * norm.x + ny * norm.y + nz * norm.z;
|
|
406
|
+
return dotprod < 0;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
*
|
|
411
|
+
* @param a2
|
|
412
|
+
* @param b2
|
|
413
|
+
* @param c2
|
|
414
|
+
*/
|
|
415
|
+
public void set(Vec3D a2, Vec3D b2, Vec3D c2) {
|
|
416
|
+
a = a2;
|
|
417
|
+
b = b2;
|
|
418
|
+
c = c2;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
*
|
|
423
|
+
* @param p
|
|
424
|
+
* @return
|
|
425
|
+
*/
|
|
426
|
+
public Vec3D toBarycentric(ReadonlyVec3D p) {
|
|
427
|
+
Vec3D e = b.sub(a).cross(c.sub(a));
|
|
428
|
+
Vec3D n = e.getNormalized();
|
|
429
|
+
|
|
430
|
+
// Compute twice area of triangle ABC
|
|
431
|
+
float areaABC = n.dot(e);
|
|
432
|
+
// Compute lambda1
|
|
433
|
+
float areaPBC = n.dot(b.sub(p).cross(c.sub(p)));
|
|
434
|
+
float l1 = areaPBC / areaABC;
|
|
435
|
+
|
|
436
|
+
// Compute lambda2
|
|
437
|
+
float areaPCA = n.dot(c.sub(p).cross(a.sub(p)));
|
|
438
|
+
float l2 = areaPCA / areaABC;
|
|
439
|
+
|
|
440
|
+
// Compute lambda3
|
|
441
|
+
float l3 = 1.0f - l1 - l2;
|
|
442
|
+
|
|
443
|
+
return new Vec3D(l1, l2, l3);
|
|
444
|
+
// return new Vec3D(a.x * l1 + b.x * l2 + c.x * l3, a.y * l1 + b.y * l2
|
|
445
|
+
// + c.y * l3, a.z * l1 + b.z * l2 + c.z * l3);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
*
|
|
450
|
+
* @return
|
|
451
|
+
*/
|
|
452
|
+
@Override
|
|
453
|
+
public String toString() {
|
|
454
|
+
return "Triangle3D: " + a + "," + b + "," + c;
|
|
455
|
+
}
|
|
456
|
+
}
|