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,122 @@
|
|
|
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.color;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Compares 2 colors by one of their CMYK component values.
|
|
32
|
+
*/
|
|
33
|
+
public class CMYKAccessor extends AccessCriteria {
|
|
34
|
+
|
|
35
|
+
private final int component;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
*
|
|
39
|
+
* @param comp
|
|
40
|
+
*/
|
|
41
|
+
public CMYKAccessor(int comp) {
|
|
42
|
+
component = comp;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* @param a
|
|
48
|
+
* @param b
|
|
49
|
+
* @return
|
|
50
|
+
*/
|
|
51
|
+
@Override
|
|
52
|
+
public int compare(ReadonlyTColor a, ReadonlyTColor b) {
|
|
53
|
+
float ca, cb;
|
|
54
|
+
switch (component) {
|
|
55
|
+
case 0:
|
|
56
|
+
ca = a.cyan();
|
|
57
|
+
cb = b.cyan();
|
|
58
|
+
break;
|
|
59
|
+
case 1:
|
|
60
|
+
ca = a.magenta();
|
|
61
|
+
cb = b.magenta();
|
|
62
|
+
break;
|
|
63
|
+
case 2:
|
|
64
|
+
ca = a.yellow();
|
|
65
|
+
cb = b.yellow();
|
|
66
|
+
break;
|
|
67
|
+
case 3:
|
|
68
|
+
default:
|
|
69
|
+
ca = a.black();
|
|
70
|
+
cb = b.black();
|
|
71
|
+
}
|
|
72
|
+
return Float.compare(ca, cb);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
*
|
|
77
|
+
* @param col
|
|
78
|
+
* @return
|
|
79
|
+
*/
|
|
80
|
+
@Override
|
|
81
|
+
public float getComponentValueFor(ReadonlyTColor col) {
|
|
82
|
+
float comp;
|
|
83
|
+
switch (component) {
|
|
84
|
+
case 0:
|
|
85
|
+
comp = col.cyan();
|
|
86
|
+
break;
|
|
87
|
+
case 1:
|
|
88
|
+
comp = col.magenta();
|
|
89
|
+
break;
|
|
90
|
+
case 2:
|
|
91
|
+
comp = col.yellow();
|
|
92
|
+
break;
|
|
93
|
+
case 3:
|
|
94
|
+
default:
|
|
95
|
+
comp = col.black();
|
|
96
|
+
}
|
|
97
|
+
return comp;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
*
|
|
102
|
+
* @param col
|
|
103
|
+
* @param val
|
|
104
|
+
*/
|
|
105
|
+
@Override
|
|
106
|
+
public void setComponentValueFor(TColor col, float val) {
|
|
107
|
+
switch (component) {
|
|
108
|
+
case 0:
|
|
109
|
+
col.setCyan(val);
|
|
110
|
+
break;
|
|
111
|
+
case 1:
|
|
112
|
+
col.setMagenta(val);
|
|
113
|
+
break;
|
|
114
|
+
case 2:
|
|
115
|
+
col.setYellow(val);
|
|
116
|
+
break;
|
|
117
|
+
case 3:
|
|
118
|
+
default:
|
|
119
|
+
col.setBlack(val);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
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.color;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Implements the {@link DistanceProxy} interface to sort colors by CMYK
|
|
32
|
+
* distance (used by {@link ColorList#sortByDistance(DistanceProxy, boolean)}).
|
|
33
|
+
*/
|
|
34
|
+
public class CMYKDistanceProxy implements DistanceProxy {
|
|
35
|
+
|
|
36
|
+
public float distanceBetween(ReadonlyTColor a, ReadonlyTColor b) {
|
|
37
|
+
return a.distanceToCMYK(b);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
}
|
|
@@ -0,0 +1,260 @@
|
|
|
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.color;
|
|
29
|
+
|
|
30
|
+
import java.util.ArrayList;
|
|
31
|
+
import java.util.Iterator;
|
|
32
|
+
import java.util.List;
|
|
33
|
+
import java.util.TreeSet;
|
|
34
|
+
|
|
35
|
+
import toxi.math.InterpolateStrategy;
|
|
36
|
+
import toxi.math.LinearInterpolation;
|
|
37
|
+
import toxi.math.MathUtils;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* This class can be used to calculate multi-color gradients with colors
|
|
41
|
+
* positioned along an imaginary axis.
|
|
42
|
+
*/
|
|
43
|
+
public class ColorGradient {
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
*/
|
|
48
|
+
protected static final class GradPoint implements Comparable<GradPoint> {
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
*
|
|
52
|
+
*/
|
|
53
|
+
protected float pos;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
*/
|
|
58
|
+
protected ReadonlyTColor color;
|
|
59
|
+
|
|
60
|
+
GradPoint(float p, ReadonlyTColor c) {
|
|
61
|
+
pos = p;
|
|
62
|
+
color = c;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
*
|
|
67
|
+
* @param p
|
|
68
|
+
* @return
|
|
69
|
+
*/
|
|
70
|
+
@Override
|
|
71
|
+
public int compareTo(GradPoint p) {
|
|
72
|
+
if (Float.compare(p.pos, pos) == 0) {
|
|
73
|
+
return 0;
|
|
74
|
+
} else {
|
|
75
|
+
return pos < p.pos ? -1 : 1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
*
|
|
81
|
+
* @return
|
|
82
|
+
*/
|
|
83
|
+
public ReadonlyTColor getColor() {
|
|
84
|
+
return color;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
*
|
|
89
|
+
* @return
|
|
90
|
+
*/
|
|
91
|
+
public float getPosition() {
|
|
92
|
+
return pos;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
*
|
|
98
|
+
*/
|
|
99
|
+
protected TreeSet<GradPoint> gradient;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
*
|
|
103
|
+
*/
|
|
104
|
+
protected float maxDither;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
*
|
|
108
|
+
*/
|
|
109
|
+
protected InterpolateStrategy interpolator = new LinearInterpolation();
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Constructs a new empty gradient.
|
|
113
|
+
*/
|
|
114
|
+
public ColorGradient() {
|
|
115
|
+
gradient = new TreeSet<>();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Adds a new color at specified position.
|
|
120
|
+
*
|
|
121
|
+
* @param p
|
|
122
|
+
* @param c
|
|
123
|
+
*/
|
|
124
|
+
public void addColorAt(float p, ReadonlyTColor c) {
|
|
125
|
+
gradient.add(new GradPoint(p, c));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
*
|
|
130
|
+
* @return
|
|
131
|
+
*/
|
|
132
|
+
public ColorList calcGradient() {
|
|
133
|
+
float start = gradient.first().getPosition();
|
|
134
|
+
return calcGradient(start,
|
|
135
|
+
(int) (gradient.last().getPosition() - start));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Calculates the gradient from specified position.
|
|
140
|
+
*
|
|
141
|
+
* @param pos
|
|
142
|
+
* @param width
|
|
143
|
+
* @return list of interpolated gradient colors
|
|
144
|
+
*/
|
|
145
|
+
public ColorList calcGradient(float pos, int width) {
|
|
146
|
+
ColorList result = new ColorList();
|
|
147
|
+
|
|
148
|
+
if (gradient.isEmpty()) {
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
float frac = 0;
|
|
153
|
+
GradPoint currPoint = null;
|
|
154
|
+
GradPoint nextPoint = null;
|
|
155
|
+
float endPos = pos + width;
|
|
156
|
+
// find 1st color needed, clamp start position to positive values only
|
|
157
|
+
for (GradPoint gp : gradient) {
|
|
158
|
+
if (gp.pos < pos) {
|
|
159
|
+
currPoint = gp;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
boolean isPremature = currPoint == null;
|
|
163
|
+
TreeSet<GradPoint> activeGradient = null;
|
|
164
|
+
if (!isPremature) {
|
|
165
|
+
activeGradient = (TreeSet<GradPoint>) gradient.tailSet(currPoint);
|
|
166
|
+
} else {
|
|
167
|
+
// start position is before 1st gradient color, so use whole
|
|
168
|
+
// gradient
|
|
169
|
+
activeGradient = gradient;
|
|
170
|
+
currPoint = activeGradient.first();
|
|
171
|
+
}
|
|
172
|
+
float currWidth = 0;
|
|
173
|
+
Iterator<GradPoint> iter = activeGradient.iterator();
|
|
174
|
+
if (currPoint != activeGradient.last()) {
|
|
175
|
+
nextPoint = iter.next();
|
|
176
|
+
if (isPremature) {
|
|
177
|
+
float d = currPoint.pos - pos;
|
|
178
|
+
currWidth = MathUtils.abs(d) > 0 ? 1f / d : 1;
|
|
179
|
+
} else {
|
|
180
|
+
if (nextPoint.pos - currPoint.pos > 0) {
|
|
181
|
+
currWidth = 1f / (nextPoint.pos - currPoint.pos);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
while (pos < endPos) {
|
|
186
|
+
if (isPremature) {
|
|
187
|
+
frac = 1 - (currPoint.pos - pos) * currWidth;
|
|
188
|
+
} else {
|
|
189
|
+
frac = (pos - currPoint.pos) * currWidth;
|
|
190
|
+
}
|
|
191
|
+
// switch to next color?
|
|
192
|
+
if (frac > 1.0) {
|
|
193
|
+
currPoint = nextPoint;
|
|
194
|
+
isPremature = false;
|
|
195
|
+
if (iter.hasNext()) {
|
|
196
|
+
nextPoint = iter.next();
|
|
197
|
+
if (currPoint != activeGradient.last()) {
|
|
198
|
+
currWidth = 1f / (nextPoint.pos - currPoint.pos);
|
|
199
|
+
} else {
|
|
200
|
+
currWidth = 0;
|
|
201
|
+
}
|
|
202
|
+
frac = (pos - currPoint.pos) * currWidth;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (currPoint != activeGradient.last()) {
|
|
206
|
+
float ditheredFrac = MathUtils
|
|
207
|
+
.clip(frac + MathUtils.normalizedRandom() * maxDither,
|
|
208
|
+
0f, 1f);
|
|
209
|
+
ditheredFrac = interpolator.interpolate(0, 1, ditheredFrac);
|
|
210
|
+
result.add(currPoint.color.getBlended(nextPoint.color,
|
|
211
|
+
ditheredFrac));
|
|
212
|
+
} else {
|
|
213
|
+
result.add(currPoint.color.copy());
|
|
214
|
+
}
|
|
215
|
+
pos++;
|
|
216
|
+
}
|
|
217
|
+
return result;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
*
|
|
222
|
+
* @return
|
|
223
|
+
*/
|
|
224
|
+
public List<GradPoint> getGradientPoints() {
|
|
225
|
+
return new ArrayList<>(gradient);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* @return the interpolator
|
|
230
|
+
*/
|
|
231
|
+
public InterpolateStrategy getInterpolator() {
|
|
232
|
+
return interpolator;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* @return the maximum dither amount.
|
|
237
|
+
*/
|
|
238
|
+
public float getMaxDither() {
|
|
239
|
+
return maxDither;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* @param interpolator
|
|
244
|
+
* the interpolator to set
|
|
245
|
+
*/
|
|
246
|
+
public void setInterpolator(InterpolateStrategy interpolator) {
|
|
247
|
+
this.interpolator = interpolator;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Sets the maximum dither amount. Setting this to values >0 will jitter the
|
|
252
|
+
* interpolated colors in the calculated gradient. The value range for this
|
|
253
|
+
* parameter is 0.0 (off) to 1.0 (100%).
|
|
254
|
+
*
|
|
255
|
+
* @param maxDither
|
|
256
|
+
*/
|
|
257
|
+
public void setMaxDither(float maxDither) {
|
|
258
|
+
this.maxDither = MathUtils.clip(maxDither, 0f, 1f);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
@@ -0,0 +1,699 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Some classes in this package have been partly inspired by & bits ported from
|
|
3
|
+
* Python code written by Tom De Smedt & Frederik De Bleser for the "colors" library
|
|
4
|
+
* of Nodebox.net.
|
|
5
|
+
*
|
|
6
|
+
* http://nodebox.net/code/index.php/Colors
|
|
7
|
+
*
|
|
8
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
9
|
+
*
|
|
10
|
+
* This library is free software; you can redistribute it and/or
|
|
11
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
12
|
+
* License as published by the Free Software Foundation; either
|
|
13
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
14
|
+
*
|
|
15
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
16
|
+
*
|
|
17
|
+
* This library is distributed in the hope that it will be useful,
|
|
18
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
20
|
+
* Lesser General Public License for more details.
|
|
21
|
+
*
|
|
22
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
23
|
+
* License along with this library; if not, write to the Free Software
|
|
24
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
package toxi.color;
|
|
28
|
+
|
|
29
|
+
import java.util.ArrayList;
|
|
30
|
+
import java.util.Collection;
|
|
31
|
+
import java.util.Collections;
|
|
32
|
+
import java.util.Comparator;
|
|
33
|
+
import java.util.Iterator;
|
|
34
|
+
import java.util.List;
|
|
35
|
+
|
|
36
|
+
import javax.xml.bind.annotation.XmlElement;
|
|
37
|
+
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
|
38
|
+
|
|
39
|
+
import toxi.color.theory.ColorTheoryRegistry;
|
|
40
|
+
import toxi.color.theory.ColorTheoryStrategy;
|
|
41
|
+
import toxi.math.MathUtils;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* A container class of concrete colors. ColorLists can be built manually and
|
|
45
|
+
* are also created when working with {@link ColorRange}s. The class has various
|
|
46
|
+
* methods to manipulate all colors in the list in parallel, as well as sort
|
|
47
|
+
* them by various criteria.
|
|
48
|
+
*
|
|
49
|
+
* @see ColorRange
|
|
50
|
+
* @see AccessCriteria
|
|
51
|
+
*/
|
|
52
|
+
public class ColorList implements Iterable<TColor> {
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Factory method. Creates a new ColorList of colors sampled from the given
|
|
56
|
+
* ARGB image array. If the number of samples equals or exceeds the number
|
|
57
|
+
* of pixels in the image and no unique colors are required, the function
|
|
58
|
+
* will simply return the same as {@link #ColorList(int[])}.
|
|
59
|
+
*
|
|
60
|
+
* @param pixels
|
|
61
|
+
* int array of ARGB pixels
|
|
62
|
+
* @param num
|
|
63
|
+
* number of colors samples (clipped automatically to number of
|
|
64
|
+
* pixels in the image)
|
|
65
|
+
* @param uniqueOnly
|
|
66
|
+
* flag if only unique samples are to be taken (doesn't guarantee
|
|
67
|
+
* unique colors though)
|
|
68
|
+
* @return new color list
|
|
69
|
+
*/
|
|
70
|
+
public static final ColorList createFromARGBArray(int[] pixels, int num,
|
|
71
|
+
boolean uniqueOnly) {
|
|
72
|
+
return createFromARGBArray(pixels, num, uniqueOnly, 100);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Factory method. Creates a new ColorList of colors randomly sampled from
|
|
77
|
+
* the given ARGB image array. If the number of samples equals or exceeds
|
|
78
|
+
* the number of pixels in the source image and no unique colors are
|
|
79
|
+
* required, the function will simply return the same as
|
|
80
|
+
* {@link #ColorList(int[])}.
|
|
81
|
+
*
|
|
82
|
+
* @param pixels
|
|
83
|
+
* int array of ARGB pixels
|
|
84
|
+
* @param num
|
|
85
|
+
* number of colors samples (clipped automatically to number of
|
|
86
|
+
* pixels in the image)
|
|
87
|
+
* @param uniqueOnly
|
|
88
|
+
* flag if only unique samples are to be taken (doesn't guarantee
|
|
89
|
+
* unique colors though)
|
|
90
|
+
* @param maxIterations
|
|
91
|
+
* max number of attempts to find a unique color. If no more
|
|
92
|
+
* unique colors can be found the search is terminated.
|
|
93
|
+
* @return new color list of samples
|
|
94
|
+
*/
|
|
95
|
+
public static final ColorList createFromARGBArray(int[] pixels, int num,
|
|
96
|
+
boolean uniqueOnly, int maxIterations) {
|
|
97
|
+
num = MathUtils.min(num, pixels.length);
|
|
98
|
+
if (!uniqueOnly && num == pixels.length) {
|
|
99
|
+
return new ColorList(pixels);
|
|
100
|
+
}
|
|
101
|
+
List<TColor> colors = new ArrayList<>();
|
|
102
|
+
TColor temp = TColor.BLACK.copy();
|
|
103
|
+
for (int i = 0; i < num; i++) {
|
|
104
|
+
int idx;
|
|
105
|
+
if (uniqueOnly) {
|
|
106
|
+
boolean isUnique = true;
|
|
107
|
+
int numTries = 0;
|
|
108
|
+
do {
|
|
109
|
+
idx = MathUtils.random(pixels.length);
|
|
110
|
+
temp.setARGB(pixels[idx]);
|
|
111
|
+
isUnique = !colors.contains(temp);
|
|
112
|
+
} while (!isUnique && ++numTries < maxIterations);
|
|
113
|
+
if (numTries < maxIterations) {
|
|
114
|
+
colors.add(temp.copy());
|
|
115
|
+
} else {
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
idx = MathUtils.random(pixels.length);
|
|
120
|
+
colors.add(TColor.newARGB(pixels[idx]));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return new ColorList(colors);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Factory method. Creates a new ColorList based on the given
|
|
128
|
+
* {@link ColorTheoryStrategy} instance and the given source color. The
|
|
129
|
+
* number of colors returned will vary with the strategy chosen.
|
|
130
|
+
*
|
|
131
|
+
* @param strategy
|
|
132
|
+
* @param c
|
|
133
|
+
* @return new list
|
|
134
|
+
*/
|
|
135
|
+
public static final ColorList createUsingStrategy(
|
|
136
|
+
ColorTheoryStrategy strategy, TColor c) {
|
|
137
|
+
return strategy.createListFromColor(c);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Factory method. Creates a ColorList based on the name of a
|
|
142
|
+
* {@link ColorTheoryStrategy} and the given source color.
|
|
143
|
+
*
|
|
144
|
+
* @param name
|
|
145
|
+
* strategy name
|
|
146
|
+
* @param c
|
|
147
|
+
* @return new color list or null, if the supplied strategy name is not
|
|
148
|
+
* mapped to a registered implementation.
|
|
149
|
+
*/
|
|
150
|
+
public static final ColorList createUsingStrategy(String name, TColor c) {
|
|
151
|
+
ColorTheoryStrategy strategy = ColorTheoryRegistry
|
|
152
|
+
.getStrategyForName(name);
|
|
153
|
+
ColorList list = null;
|
|
154
|
+
if (strategy != null) {
|
|
155
|
+
list = strategy.createListFromColor(c);
|
|
156
|
+
}
|
|
157
|
+
return list;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
*
|
|
162
|
+
*/
|
|
163
|
+
@XmlElement(name = "col")
|
|
164
|
+
@XmlJavaTypeAdapter(TColorAdapter.class)
|
|
165
|
+
protected List<TColor> colors;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Creates an empty list.
|
|
169
|
+
*/
|
|
170
|
+
public ColorList() {
|
|
171
|
+
this.colors = new ArrayList<>();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Creates a ColorList by wrapping the given ArrayList of colors. No copies
|
|
176
|
+
* of the given colors are created (shallow copy only).
|
|
177
|
+
*
|
|
178
|
+
* @param colors
|
|
179
|
+
*/
|
|
180
|
+
public ColorList(Collection<TColor> colors) {
|
|
181
|
+
this.colors = new ArrayList<>();
|
|
182
|
+
this.colors.addAll(colors);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Creates a deep copy of the given ColorList. Manipulating the new list or
|
|
187
|
+
* its color entries does NOT change the colors of the original.
|
|
188
|
+
*
|
|
189
|
+
* @param list
|
|
190
|
+
* source list to copy
|
|
191
|
+
*/
|
|
192
|
+
public ColorList(ColorList list) {
|
|
193
|
+
this.colors = new ArrayList<>();
|
|
194
|
+
for (TColor c : list) {
|
|
195
|
+
this.colors.add(c.copy());
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Creates a new color list from the array of ARGB int values. In most cases
|
|
201
|
+
* this will be the pixel buffer of an image.
|
|
202
|
+
*
|
|
203
|
+
* @param argbArray
|
|
204
|
+
*/
|
|
205
|
+
public ColorList(int[] argbArray) {
|
|
206
|
+
this.colors = new ArrayList<>();
|
|
207
|
+
for (int c : argbArray) {
|
|
208
|
+
colors.add(TColor.newARGB(c));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Creates new ColorList from the given colors. Copies of the given colors
|
|
214
|
+
* are created. This is a varargs constructor allowing these two parameter
|
|
215
|
+
* formats:
|
|
216
|
+
*
|
|
217
|
+
* <pre>
|
|
218
|
+
* // individual parameters
|
|
219
|
+
* ColorList cols=new ColorList(TColor.BLACK,TColor.WHITE,TColor.newRGB(1,0,0));
|
|
220
|
+
*
|
|
221
|
+
* // or array of colors
|
|
222
|
+
* ReadonlyTColor[] colArray=new ReadonlyTColor[] {
|
|
223
|
+
* TColor.BLACK,TColor.WHITE,TColor.newRGB(1,0,0);
|
|
224
|
+
* };
|
|
225
|
+
* ColorList cols=new ColorList(colArray);
|
|
226
|
+
* </pre>
|
|
227
|
+
*
|
|
228
|
+
* @param colorArray
|
|
229
|
+
*/
|
|
230
|
+
public ColorList(ReadonlyTColor... colorArray) {
|
|
231
|
+
this.colors = new ArrayList<>();
|
|
232
|
+
for (ReadonlyTColor c : colorArray) {
|
|
233
|
+
colors.add(c.copy());
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Adds a copy of the given color to the list
|
|
239
|
+
*
|
|
240
|
+
* @param c
|
|
241
|
+
* @return itself
|
|
242
|
+
*/
|
|
243
|
+
public ColorList add(ReadonlyTColor c) {
|
|
244
|
+
colors.add(c.copy());
|
|
245
|
+
return this;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Adds all entries of the TColor collection to the list (shallow copy only,
|
|
250
|
+
* manipulating the new list will modify the original colors).
|
|
251
|
+
*
|
|
252
|
+
* @param collection
|
|
253
|
+
* @return itself
|
|
254
|
+
*/
|
|
255
|
+
public ColorList addAll(Collection<TColor> collection) {
|
|
256
|
+
colors.addAll(collection);
|
|
257
|
+
return this;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Adjusts the brightness component of all list colors by the given amount.
|
|
262
|
+
*
|
|
263
|
+
* @param step
|
|
264
|
+
* adjustment value
|
|
265
|
+
* @return itself
|
|
266
|
+
*/
|
|
267
|
+
public ColorList adjustBrightness(float step) {
|
|
268
|
+
for (TColor c : colors) {
|
|
269
|
+
c.lighten(step);
|
|
270
|
+
}
|
|
271
|
+
return this;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Adjusts the saturation component of all list colors by the given amount.
|
|
276
|
+
*
|
|
277
|
+
* @param step
|
|
278
|
+
* adjustment value
|
|
279
|
+
* @return itself
|
|
280
|
+
*/
|
|
281
|
+
public ColorList adjustSaturation(float step) {
|
|
282
|
+
for (TColor c : colors) {
|
|
283
|
+
c.saturate(step);
|
|
284
|
+
}
|
|
285
|
+
return this;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Sorts the list based on two criteria to create clusters/segments within
|
|
290
|
+
* the list.
|
|
291
|
+
*
|
|
292
|
+
* @param clusterCriteria
|
|
293
|
+
* main sort criteria
|
|
294
|
+
* @param subClusterCriteria
|
|
295
|
+
* secondary sort criteria
|
|
296
|
+
* @param numClusters
|
|
297
|
+
* number of clusters
|
|
298
|
+
* @param isReversed
|
|
299
|
+
* true, if reversed sort
|
|
300
|
+
* @return itself
|
|
301
|
+
*/
|
|
302
|
+
public ColorList clusterSort(AccessCriteria clusterCriteria,
|
|
303
|
+
AccessCriteria subClusterCriteria, int numClusters,
|
|
304
|
+
boolean isReversed) {
|
|
305
|
+
ArrayList<TColor> sorted = new ArrayList<>(colors);
|
|
306
|
+
Collections.sort(sorted, clusterCriteria);
|
|
307
|
+
Collections.reverse(sorted);
|
|
308
|
+
ArrayList<TColor> clusters = new ArrayList<>();
|
|
309
|
+
|
|
310
|
+
float d = 1;
|
|
311
|
+
int i = 0;
|
|
312
|
+
int num = sorted.size();
|
|
313
|
+
for (int j = 0; j < num; j++) {
|
|
314
|
+
ReadonlyTColor c = sorted.get(j);
|
|
315
|
+
if (c.getComponentValue(clusterCriteria) < d) {
|
|
316
|
+
ArrayList<TColor> slice = new ArrayList<>();
|
|
317
|
+
slice.addAll(sorted.subList(i, j));
|
|
318
|
+
Collections.sort(slice, subClusterCriteria);
|
|
319
|
+
clusters.addAll(slice);
|
|
320
|
+
d -= 1.0f / numClusters;
|
|
321
|
+
i = j;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
ArrayList<TColor> slice = new ArrayList<>();
|
|
325
|
+
slice.addAll(sorted.subList(i, sorted.size()));
|
|
326
|
+
Collections.sort(slice, subClusterCriteria);
|
|
327
|
+
clusters.addAll(slice);
|
|
328
|
+
if (isReversed) {
|
|
329
|
+
Collections.reverse(clusters);
|
|
330
|
+
}
|
|
331
|
+
colors = clusters;
|
|
332
|
+
return this;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Switches all list colors to their complementary color.
|
|
337
|
+
*
|
|
338
|
+
* @return itself
|
|
339
|
+
*/
|
|
340
|
+
public ColorList complement() {
|
|
341
|
+
for (TColor c : colors) {
|
|
342
|
+
c.complement();
|
|
343
|
+
}
|
|
344
|
+
return this;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Checks if the given color is part of the list. Check is done by value,
|
|
349
|
+
* not instance.
|
|
350
|
+
*
|
|
351
|
+
* @param color
|
|
352
|
+
* @return true, if the color is present.
|
|
353
|
+
*/
|
|
354
|
+
public boolean contains(ReadonlyTColor color) {
|
|
355
|
+
for (ReadonlyTColor c : colors) {
|
|
356
|
+
if (c.equals(color)) {
|
|
357
|
+
return true;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Returns the color at the given index. This function follows Python
|
|
365
|
+
* convention, in that if the index is negative, it is considered relative
|
|
366
|
+
* to the list end. Therefore the color at index -1 is the last color in the
|
|
367
|
+
* list.
|
|
368
|
+
*
|
|
369
|
+
* @param i
|
|
370
|
+
* index
|
|
371
|
+
* @return color
|
|
372
|
+
*/
|
|
373
|
+
public TColor get(int i) {
|
|
374
|
+
if (i < 0) {
|
|
375
|
+
i += colors.size();
|
|
376
|
+
}
|
|
377
|
+
return colors.get(i);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Calculates and returns the average color of the list.
|
|
382
|
+
*
|
|
383
|
+
* @return average color or null, if there're no entries yet.
|
|
384
|
+
*/
|
|
385
|
+
public ReadonlyTColor getAverage() {
|
|
386
|
+
float r = 0;
|
|
387
|
+
float g = 0;
|
|
388
|
+
float b = 0;
|
|
389
|
+
float a = 0;
|
|
390
|
+
for (TColor c : colors) {
|
|
391
|
+
r += c.rgb[0];
|
|
392
|
+
g += c.rgb[1];
|
|
393
|
+
b += c.rgb[2];
|
|
394
|
+
a += c.alpha;
|
|
395
|
+
}
|
|
396
|
+
int num = colors.size();
|
|
397
|
+
if (num > 0) {
|
|
398
|
+
return TColor.newRGBA(r / num, g / num, b / num, a / num);
|
|
399
|
+
} else {
|
|
400
|
+
return null;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Creates a new ColorList by blending all colors in the list with each
|
|
406
|
+
* other (successive indices only)
|
|
407
|
+
*
|
|
408
|
+
* @param amount
|
|
409
|
+
* blend amount
|
|
410
|
+
* @return new color list
|
|
411
|
+
*/
|
|
412
|
+
public ColorList getBlended(float amount) {
|
|
413
|
+
TColor[] clrs = new TColor[colors.size()];
|
|
414
|
+
for (int i = 0; i < clrs.length; i++) {
|
|
415
|
+
TColor c = colors.get(i > 0 ? i - 1 : clrs.length - 1);
|
|
416
|
+
clrs[i] = colors.get(i).getBlended(c, amount);
|
|
417
|
+
}
|
|
418
|
+
return new ColorList(clrs);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Finds and returns the darkest color of the list.
|
|
423
|
+
*
|
|
424
|
+
* @return darkest color or null if there're no entries yet.
|
|
425
|
+
*/
|
|
426
|
+
public TColor getDarkest() {
|
|
427
|
+
TColor darkest = null;
|
|
428
|
+
float minBrightness = Float.MAX_VALUE;
|
|
429
|
+
for (TColor c : colors) {
|
|
430
|
+
float luma = c.luminance();
|
|
431
|
+
if (luma < minBrightness) {
|
|
432
|
+
darkest = c;
|
|
433
|
+
minBrightness = luma;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
return darkest;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Finds and returns the lightest (luminance) color of the list.
|
|
441
|
+
*
|
|
442
|
+
* @return lightest color or null, if there're no entries yet.
|
|
443
|
+
*/
|
|
444
|
+
public ReadonlyTColor getLightest() {
|
|
445
|
+
ReadonlyTColor lightest = null;
|
|
446
|
+
float maxBrightness = Float.MIN_VALUE;
|
|
447
|
+
for (ReadonlyTColor c : colors) {
|
|
448
|
+
float luma = c.luminance();
|
|
449
|
+
if (luma > maxBrightness) {
|
|
450
|
+
lightest = c;
|
|
451
|
+
maxBrightness = luma;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
return lightest;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
*
|
|
459
|
+
* @return
|
|
460
|
+
*/
|
|
461
|
+
public TColor getRandom() {
|
|
462
|
+
return colors.get(MathUtils.random(colors.size()));
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Returns a reversed copy of the current list.
|
|
467
|
+
*
|
|
468
|
+
* @return reversed copy of the list
|
|
469
|
+
*/
|
|
470
|
+
public ColorList getReverse() {
|
|
471
|
+
return new ColorList(colors).reverse();
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Inverts all colors in the list.
|
|
476
|
+
*
|
|
477
|
+
* @return itself
|
|
478
|
+
*/
|
|
479
|
+
public ColorList invert() {
|
|
480
|
+
for (TColor c : colors) {
|
|
481
|
+
c.invert();
|
|
482
|
+
}
|
|
483
|
+
return this;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Returns an iterator over the internal list. This means the list can be
|
|
488
|
+
* accessed via standard Iterator loops.
|
|
489
|
+
*
|
|
490
|
+
* @return list iterator
|
|
491
|
+
*/
|
|
492
|
+
@Override
|
|
493
|
+
public Iterator<TColor> iterator() {
|
|
494
|
+
return colors.iterator();
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* Reverses the current order of the list.
|
|
499
|
+
*
|
|
500
|
+
* @return itself
|
|
501
|
+
*/
|
|
502
|
+
public ColorList reverse() {
|
|
503
|
+
Collections.reverse(colors);
|
|
504
|
+
return this;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Rotates the hues of all colors in the list by the given amount.
|
|
509
|
+
*
|
|
510
|
+
* @param theta
|
|
511
|
+
* rotation angle in radians
|
|
512
|
+
* @return itself
|
|
513
|
+
*/
|
|
514
|
+
public ColorList rotateRYB(float theta) {
|
|
515
|
+
rotateImplementation(MathUtils.degrees(theta));
|
|
516
|
+
return this;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Rotates the hues of all colors in the list by the given amount.
|
|
521
|
+
*
|
|
522
|
+
* @param angle
|
|
523
|
+
* rotation angle in degrees
|
|
524
|
+
* @return itself
|
|
525
|
+
*/
|
|
526
|
+
public ColorList rotateRYB(int angle) {
|
|
527
|
+
rotateImplementation(angle);
|
|
528
|
+
return this;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Rotates the hues of all colors in the list by the given amount.
|
|
533
|
+
*
|
|
534
|
+
* @param angle
|
|
535
|
+
* rotation angle in degrees
|
|
536
|
+
*/
|
|
537
|
+
private void rotateImplementation(float angle) {
|
|
538
|
+
for (TColor c : colors) {
|
|
539
|
+
c.rotateRYB(angle);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* @return the number of colors in the list
|
|
545
|
+
*/
|
|
546
|
+
public int size() {
|
|
547
|
+
return colors.size();
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Convenience method. Sorts the list by hue.
|
|
552
|
+
*
|
|
553
|
+
* @return itself
|
|
554
|
+
*/
|
|
555
|
+
public ColorList sort() {
|
|
556
|
+
return sortByCriteria(AccessCriteria.HUE, false);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* Sorts the list using the given comparator.
|
|
561
|
+
*
|
|
562
|
+
* @param comp
|
|
563
|
+
* comparator
|
|
564
|
+
* @param isReversed
|
|
565
|
+
* true, if reversed sort
|
|
566
|
+
* @return itself
|
|
567
|
+
*/
|
|
568
|
+
public ColorList sortByComparator(Comparator<ReadonlyTColor> comp,
|
|
569
|
+
boolean isReversed) {
|
|
570
|
+
Collections.sort(colors, comp);
|
|
571
|
+
if (isReversed) {
|
|
572
|
+
Collections.reverse(colors);
|
|
573
|
+
}
|
|
574
|
+
return this;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Sorts the list using the given {@link AccessCriteria}.
|
|
579
|
+
*
|
|
580
|
+
* @param criteria
|
|
581
|
+
* sort criteria
|
|
582
|
+
* @param isReversed
|
|
583
|
+
* true, if reversed sort
|
|
584
|
+
* @return itself
|
|
585
|
+
*/
|
|
586
|
+
public ColorList sortByCriteria(AccessCriteria criteria, boolean isReversed) {
|
|
587
|
+
return sortByComparator(criteria, isReversed);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* Sorts the list by relative distance to each predecessor, starting with
|
|
592
|
+
* the darkest color in the list.
|
|
593
|
+
*
|
|
594
|
+
* @param isReversed
|
|
595
|
+
* true, if list is to be sorted in reverse.
|
|
596
|
+
* @return itself
|
|
597
|
+
*/
|
|
598
|
+
public ColorList sortByDistance(boolean isReversed) {
|
|
599
|
+
return sortByDistance(new HSVDistanceProxy(), isReversed);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Sorts the list by relative distance to each predecessor, starting with
|
|
604
|
+
* the darkest color in the list.
|
|
605
|
+
*
|
|
606
|
+
* @param proxy
|
|
607
|
+
* @param isReversed
|
|
608
|
+
* true, if list is to be sorted in reverse.
|
|
609
|
+
* @return itself
|
|
610
|
+
*/
|
|
611
|
+
public ColorList sortByDistance(DistanceProxy proxy, boolean isReversed) {
|
|
612
|
+
if (colors.isEmpty()) {
|
|
613
|
+
return this;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
TColor root = getDarkest();
|
|
617
|
+
|
|
618
|
+
// Remove the darkest color from the stack,
|
|
619
|
+
// put it in the sorted list as starting element.
|
|
620
|
+
ArrayList<TColor> stack = new ArrayList<>(colors);
|
|
621
|
+
stack.remove(root);
|
|
622
|
+
ArrayList<TColor> sorted = new ArrayList<>(colors.size());
|
|
623
|
+
sorted.add(root);
|
|
624
|
+
|
|
625
|
+
// Now find the color in the stack closest to that color.
|
|
626
|
+
// Take this color from the stack and add it to the sorted list.
|
|
627
|
+
// Now find the color closest to that color, etc.
|
|
628
|
+
int sortedCount = 0;
|
|
629
|
+
while (stack.size() > 1) {
|
|
630
|
+
TColor closest = stack.get(0);
|
|
631
|
+
TColor lastSorted = sorted.get(sortedCount);
|
|
632
|
+
float distance = proxy.distanceBetween(closest, lastSorted);
|
|
633
|
+
for (int i = stack.size() - 1; i >= 0; i--) {
|
|
634
|
+
TColor c = stack.get(i);
|
|
635
|
+
float d = proxy.distanceBetween(c, lastSorted);
|
|
636
|
+
if (d < distance) {
|
|
637
|
+
closest = c;
|
|
638
|
+
distance = d;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
stack.remove(closest);
|
|
642
|
+
sorted.add(closest);
|
|
643
|
+
sortedCount++;
|
|
644
|
+
}
|
|
645
|
+
sorted.add(stack.get(0));
|
|
646
|
+
if (isReversed) {
|
|
647
|
+
Collections.reverse(sorted);
|
|
648
|
+
}
|
|
649
|
+
colors = sorted;
|
|
650
|
+
return this;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Sorts the list by proximity to the given target color (using RGB distance
|
|
655
|
+
* metrics).
|
|
656
|
+
*
|
|
657
|
+
* @see #sortByProximityTo(ReadonlyTColor, DistanceProxy, boolean)
|
|
658
|
+
* @param target
|
|
659
|
+
* color
|
|
660
|
+
* @param isReversed
|
|
661
|
+
* true, if reverse sorted
|
|
662
|
+
* @return sorted list
|
|
663
|
+
*/
|
|
664
|
+
public ColorList sortByProximityTo(ReadonlyTColor target, boolean isReversed) {
|
|
665
|
+
return sortByProximityTo(target, new RGBDistanceProxy(), isReversed);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* Sorts the list by proximity to the given target color using the given
|
|
670
|
+
* {@link DistanceProxy} implementation.
|
|
671
|
+
*
|
|
672
|
+
* @param target
|
|
673
|
+
* color
|
|
674
|
+
* @param proxy
|
|
675
|
+
* distance metrics
|
|
676
|
+
* @param isReversed
|
|
677
|
+
* true, if reverse sorted
|
|
678
|
+
* @return sorted list
|
|
679
|
+
*/
|
|
680
|
+
public ColorList sortByProximityTo(ReadonlyTColor target,
|
|
681
|
+
DistanceProxy proxy, boolean isReversed) {
|
|
682
|
+
return sortByComparator(new ProximityComparator(target, proxy),
|
|
683
|
+
isReversed);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Creates an ARGB integer array of the list items.
|
|
688
|
+
*
|
|
689
|
+
* @return all list colors as ARGB values
|
|
690
|
+
*/
|
|
691
|
+
public int[] toARGBArray() {
|
|
692
|
+
int[] array = new int[colors.size()];
|
|
693
|
+
int i = 0;
|
|
694
|
+
for (ReadonlyTColor c : colors) {
|
|
695
|
+
array[i++] = c.toARGB();
|
|
696
|
+
}
|
|
697
|
+
return array;
|
|
698
|
+
}
|
|
699
|
+
}
|