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,57 @@
|
|
|
1
|
+
package toxi.geom;
|
|
2
|
+
|
|
3
|
+
import java.util.ArrayList;
|
|
4
|
+
import java.util.List;
|
|
5
|
+
|
|
6
|
+
import toxi.math.ScaleMap;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A concrete implementation of the abstract {@link GridTesselator} using a grid
|
|
10
|
+
* in polygon-local coordinate space for generating additional points within a
|
|
11
|
+
* polygon. The resolution setting of this class defines number of desired grid
|
|
12
|
+
* points in X & Y direction. E.g. a resolution of 10 means up to 10x10 grid
|
|
13
|
+
* points are created a within the polygon bounding rect. For smaller polygons,
|
|
14
|
+
* the resulting triangles will simply be smaller too. This resolution is used
|
|
15
|
+
* independently on polygon size. Use the {@link GlobalGridTesselator} for an
|
|
16
|
+
* alternative behavior, resulting in more uniformly sized triangles.
|
|
17
|
+
*
|
|
18
|
+
* @see GridTesselator
|
|
19
|
+
* @see GlobalGridTesselator
|
|
20
|
+
* @see PolygonTesselator
|
|
21
|
+
*/
|
|
22
|
+
public class LocalGridTesselator extends GridTesselator {
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
* @param res
|
|
27
|
+
*/
|
|
28
|
+
public LocalGridTesselator(int res) {
|
|
29
|
+
super(res);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @param poly
|
|
35
|
+
* @param bounds
|
|
36
|
+
* @return
|
|
37
|
+
*/
|
|
38
|
+
@Override
|
|
39
|
+
protected List<Vec2D> createInsidePoints(Polygon2D poly, Rect bounds) {
|
|
40
|
+
List<Vec2D> points = new ArrayList<>();
|
|
41
|
+
int ires = (int) res;
|
|
42
|
+
ScaleMap xmap = new ScaleMap(0, ires, bounds.getLeft(),
|
|
43
|
+
bounds.getRight());
|
|
44
|
+
ScaleMap ymap = new ScaleMap(0, ires, bounds.getTop(),
|
|
45
|
+
bounds.getBottom());
|
|
46
|
+
for (int y = 0; y < ires; y++) {
|
|
47
|
+
float yy = (float) ymap.getMappedValueFor(y);
|
|
48
|
+
for (int x = 0; x < ires; x++) {
|
|
49
|
+
Vec2D p = new Vec2D((float) xmap.getMappedValueFor(x), yy);
|
|
50
|
+
if (poly.containsPoint(p)) {
|
|
51
|
+
points.add(p);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return points;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,3048 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* $RCSfile$
|
|
3
|
+
*
|
|
4
|
+
* Copyright 1996-2008 Sun Microsystems, Inc. All Rights Reserved.
|
|
5
|
+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
6
|
+
*
|
|
7
|
+
* This code is free software; you can redistribute it and/or modify it
|
|
8
|
+
* under the terms of the GNU General Public License version 2 only, as
|
|
9
|
+
* published by the Free Software Foundation. Sun designates this
|
|
10
|
+
* particular file as subject to the "Classpath" exception as provided
|
|
11
|
+
* by Sun in the LICENSE file that accompanied this code.
|
|
12
|
+
*
|
|
13
|
+
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
14
|
+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
15
|
+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
16
|
+
* version 2 for more details (a copy is included in the LICENSE file that
|
|
17
|
+
* accompanied this code).
|
|
18
|
+
*
|
|
19
|
+
* You should have received a copy of the GNU General Public License version
|
|
20
|
+
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
21
|
+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
22
|
+
*
|
|
23
|
+
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
24
|
+
* CA 95054 USA or visit www.sun.com if you need additional information or
|
|
25
|
+
* have any questions.
|
|
26
|
+
*
|
|
27
|
+
* $Revision: 127 $
|
|
28
|
+
* $Date: 2008-02-28 20:18:51 +0000 (Thu, 28 Feb 2008) $
|
|
29
|
+
* $State$
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
package toxi.geom;
|
|
33
|
+
|
|
34
|
+
import toxi.math.MathUtils;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* A double precision floating point 3 by 3 matrix. Primarily to support 3D
|
|
38
|
+
* rotations.
|
|
39
|
+
*/
|
|
40
|
+
public class Matrix3d implements java.io.Serializable, Cloneable {
|
|
41
|
+
|
|
42
|
+
// Compatible with 1.1
|
|
43
|
+
static final long serialVersionUID = 6837536777072402710L;
|
|
44
|
+
|
|
45
|
+
private static boolean almostEqual(double a, double b) {
|
|
46
|
+
if (a == b) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
final double EPSILON_ABSOLUTE = 1.0e-6;
|
|
51
|
+
final double EPSILON_RELATIVE = 1.0e-4;
|
|
52
|
+
double diff = Math.abs(a - b);
|
|
53
|
+
double absA = Math.abs(a);
|
|
54
|
+
double absB = Math.abs(b);
|
|
55
|
+
double max = (absA >= absB) ? absA : absB;
|
|
56
|
+
|
|
57
|
+
if (diff < EPSILON_ABSOLUTE) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
return ((diff / max) < EPSILON_RELATIVE);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static int compute_2X2(double f, double g, double h,
|
|
64
|
+
double[] single_values, double[] snl, double[] csl, double[] snr,
|
|
65
|
+
double[] csr, int index) {
|
|
66
|
+
|
|
67
|
+
double c_b3 = 2.;
|
|
68
|
+
double c_b4 = 1.;
|
|
69
|
+
|
|
70
|
+
double d__1;
|
|
71
|
+
int pmax;
|
|
72
|
+
double temp;
|
|
73
|
+
boolean swap;
|
|
74
|
+
double a, d, l, m, r, s, t, tsign, fa, ga, ha;
|
|
75
|
+
double ft, gt, ht, mm;
|
|
76
|
+
boolean gasmal;
|
|
77
|
+
double tt, clt, crt, slt, srt;
|
|
78
|
+
double ssmin, ssmax;
|
|
79
|
+
|
|
80
|
+
ssmax = single_values[0];
|
|
81
|
+
ssmin = single_values[1];
|
|
82
|
+
clt = 0.0;
|
|
83
|
+
crt = 0.0;
|
|
84
|
+
slt = 0.0;
|
|
85
|
+
srt = 0.0;
|
|
86
|
+
tsign = 0.0;
|
|
87
|
+
|
|
88
|
+
ft = f;
|
|
89
|
+
fa = Math.abs(ft);
|
|
90
|
+
ht = h;
|
|
91
|
+
ha = Math.abs(h);
|
|
92
|
+
pmax = 1;
|
|
93
|
+
swap = ha > fa;
|
|
94
|
+
|
|
95
|
+
if (swap) {
|
|
96
|
+
pmax = 3;
|
|
97
|
+
temp = ft;
|
|
98
|
+
ft = ht;
|
|
99
|
+
ht = temp;
|
|
100
|
+
temp = fa;
|
|
101
|
+
fa = ha;
|
|
102
|
+
ha = temp;
|
|
103
|
+
|
|
104
|
+
}
|
|
105
|
+
gt = g;
|
|
106
|
+
ga = Math.abs(gt);
|
|
107
|
+
if (ga == 0.) {
|
|
108
|
+
|
|
109
|
+
single_values[1] = ha;
|
|
110
|
+
single_values[0] = fa;
|
|
111
|
+
clt = 1.;
|
|
112
|
+
crt = 1.;
|
|
113
|
+
slt = 0.;
|
|
114
|
+
srt = 0.;
|
|
115
|
+
} else {
|
|
116
|
+
gasmal = true;
|
|
117
|
+
|
|
118
|
+
if (ga > fa) {
|
|
119
|
+
pmax = 2;
|
|
120
|
+
if (fa / ga < EPS) {
|
|
121
|
+
|
|
122
|
+
gasmal = false;
|
|
123
|
+
ssmax = ga;
|
|
124
|
+
if (ha > 1.) {
|
|
125
|
+
ssmin = fa / (ga / ha);
|
|
126
|
+
} else {
|
|
127
|
+
ssmin = fa / ga * ha;
|
|
128
|
+
}
|
|
129
|
+
clt = 1.;
|
|
130
|
+
slt = ht / gt;
|
|
131
|
+
srt = 1.;
|
|
132
|
+
crt = ft / gt;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (gasmal) {
|
|
136
|
+
|
|
137
|
+
d = fa - ha;
|
|
138
|
+
if (d == fa) {
|
|
139
|
+
|
|
140
|
+
l = 1.;
|
|
141
|
+
} else {
|
|
142
|
+
l = d / fa;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
m = gt / ft;
|
|
146
|
+
|
|
147
|
+
t = 2. - l;
|
|
148
|
+
|
|
149
|
+
mm = m * m;
|
|
150
|
+
tt = t * t;
|
|
151
|
+
s = Math.sqrt(tt + mm);
|
|
152
|
+
|
|
153
|
+
if (l == 0.) {
|
|
154
|
+
r = Math.abs(m);
|
|
155
|
+
} else {
|
|
156
|
+
r = Math.sqrt(l * l + mm);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
a = (s + r) * .5;
|
|
160
|
+
|
|
161
|
+
if (ga > fa) {
|
|
162
|
+
pmax = 2;
|
|
163
|
+
if (fa / ga < EPS) {
|
|
164
|
+
|
|
165
|
+
gasmal = false;
|
|
166
|
+
ssmax = ga;
|
|
167
|
+
if (ha > 1.) {
|
|
168
|
+
ssmin = fa / (ga / ha);
|
|
169
|
+
} else {
|
|
170
|
+
ssmin = fa / ga * ha;
|
|
171
|
+
}
|
|
172
|
+
clt = 1.;
|
|
173
|
+
slt = ht / gt;
|
|
174
|
+
srt = 1.;
|
|
175
|
+
crt = ft / gt;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (gasmal) {
|
|
179
|
+
|
|
180
|
+
d = fa - ha;
|
|
181
|
+
if (d == fa) {
|
|
182
|
+
|
|
183
|
+
l = 1.;
|
|
184
|
+
} else {
|
|
185
|
+
l = d / fa;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
m = gt / ft;
|
|
189
|
+
|
|
190
|
+
t = 2. - l;
|
|
191
|
+
|
|
192
|
+
mm = m * m;
|
|
193
|
+
tt = t * t;
|
|
194
|
+
s = Math.sqrt(tt + mm);
|
|
195
|
+
|
|
196
|
+
if (l == 0.) {
|
|
197
|
+
r = Math.abs(m);
|
|
198
|
+
} else {
|
|
199
|
+
r = Math.sqrt(l * l + mm);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
a = (s + r) * .5;
|
|
203
|
+
|
|
204
|
+
ssmin = ha / a;
|
|
205
|
+
ssmax = fa * a;
|
|
206
|
+
if (mm == 0.) {
|
|
207
|
+
|
|
208
|
+
if (l == 0.) {
|
|
209
|
+
t = MathUtils.dualSign(c_b3, ft)
|
|
210
|
+
* MathUtils.dualSign(c_b4, gt);
|
|
211
|
+
} else {
|
|
212
|
+
t = gt / MathUtils.dualSign(d, ft) + m / t;
|
|
213
|
+
}
|
|
214
|
+
} else {
|
|
215
|
+
t = (m / (s + t) + m / (r + l)) * (a + 1.);
|
|
216
|
+
}
|
|
217
|
+
l = Math.sqrt(t * t + 4.);
|
|
218
|
+
crt = 2. / l;
|
|
219
|
+
srt = t / l;
|
|
220
|
+
clt = (crt + srt * m) / a;
|
|
221
|
+
slt = ht / ft * srt / a;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (swap) {
|
|
225
|
+
csl[0] = srt;
|
|
226
|
+
snl[0] = crt;
|
|
227
|
+
csr[0] = slt;
|
|
228
|
+
snr[0] = clt;
|
|
229
|
+
} else {
|
|
230
|
+
csl[0] = clt;
|
|
231
|
+
snl[0] = slt;
|
|
232
|
+
csr[0] = crt;
|
|
233
|
+
snr[0] = srt;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (pmax == 1) {
|
|
237
|
+
tsign = MathUtils.dualSign(c_b4, csr[0])
|
|
238
|
+
* MathUtils.dualSign(c_b4, csl[0])
|
|
239
|
+
* MathUtils.dualSign(c_b4, f);
|
|
240
|
+
}
|
|
241
|
+
if (pmax == 2) {
|
|
242
|
+
tsign = MathUtils.dualSign(c_b4, snr[0])
|
|
243
|
+
* MathUtils.dualSign(c_b4, csl[0])
|
|
244
|
+
* MathUtils.dualSign(c_b4, g);
|
|
245
|
+
}
|
|
246
|
+
if (pmax == 3) {
|
|
247
|
+
tsign = MathUtils.dualSign(c_b4, snr[0])
|
|
248
|
+
* MathUtils.dualSign(c_b4, snl[0])
|
|
249
|
+
* MathUtils.dualSign(c_b4, h);
|
|
250
|
+
}
|
|
251
|
+
single_values[index] = MathUtils.dualSign(ssmax, tsign);
|
|
252
|
+
d__1 = tsign * MathUtils.dualSign(c_b4, f)
|
|
253
|
+
* MathUtils.dualSign(c_b4, h);
|
|
254
|
+
single_values[index + 1] = MathUtils.dualSign(ssmin, d__1);
|
|
255
|
+
|
|
256
|
+
}
|
|
257
|
+
return 0;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
static int compute_qr(double[] s, double[] e, double[] u, double[] v) {
|
|
261
|
+
int k;
|
|
262
|
+
boolean converged;
|
|
263
|
+
double shift, r;
|
|
264
|
+
double[] cosl = new double[2];
|
|
265
|
+
double[] cosr = new double[2];
|
|
266
|
+
double[] sinl = new double[2];
|
|
267
|
+
double[] sinr = new double[2];
|
|
268
|
+
double[] m = new double[9];
|
|
269
|
+
|
|
270
|
+
double utemp, vtemp;
|
|
271
|
+
double f, g;
|
|
272
|
+
|
|
273
|
+
final int MAX_INTERATIONS = 10;
|
|
274
|
+
final double CONVERGE_TOL = 4.89E-15;
|
|
275
|
+
|
|
276
|
+
double c_b48 = 1.;
|
|
277
|
+
int first;
|
|
278
|
+
converged = false;
|
|
279
|
+
|
|
280
|
+
first = 1;
|
|
281
|
+
|
|
282
|
+
if (Math.abs(e[1]) < CONVERGE_TOL || Math.abs(e[0]) < CONVERGE_TOL) {
|
|
283
|
+
converged = true;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
for (k = 0; k < MAX_INTERATIONS && !converged; k++) {
|
|
287
|
+
shift = compute_shift(s[1], e[1], s[2]);
|
|
288
|
+
f = (Math.abs(s[0]) - shift)
|
|
289
|
+
* (MathUtils.dualSign(c_b48, s[0]) + shift / s[0]);
|
|
290
|
+
g = e[0];
|
|
291
|
+
r = compute_rot(f, g, sinr, cosr, 0, first);
|
|
292
|
+
f = cosr[0] * s[0] + sinr[0] * e[0];
|
|
293
|
+
e[0] = cosr[0] * e[0] - sinr[0] * s[0];
|
|
294
|
+
g = sinr[0] * s[1];
|
|
295
|
+
s[1] = cosr[0] * s[1];
|
|
296
|
+
|
|
297
|
+
r = compute_rot(f, g, sinl, cosl, 0, first);
|
|
298
|
+
first = 0;
|
|
299
|
+
s[0] = r;
|
|
300
|
+
f = cosl[0] * e[0] + sinl[0] * s[1];
|
|
301
|
+
s[1] = cosl[0] * s[1] - sinl[0] * e[0];
|
|
302
|
+
g = sinl[0] * e[1];
|
|
303
|
+
e[1] = cosl[0] * e[1];
|
|
304
|
+
|
|
305
|
+
r = compute_rot(f, g, sinr, cosr, 1, first);
|
|
306
|
+
e[0] = r;
|
|
307
|
+
f = cosr[1] * s[1] + sinr[1] * e[1];
|
|
308
|
+
e[1] = cosr[1] * e[1] - sinr[1] * s[1];
|
|
309
|
+
g = sinr[1] * s[2];
|
|
310
|
+
s[2] = cosr[1] * s[2];
|
|
311
|
+
|
|
312
|
+
r = compute_rot(f, g, sinl, cosl, 1, first);
|
|
313
|
+
s[1] = r;
|
|
314
|
+
f = cosl[1] * e[1] + sinl[1] * s[2];
|
|
315
|
+
s[2] = cosl[1] * s[2] - sinl[1] * e[1];
|
|
316
|
+
e[1] = f;
|
|
317
|
+
|
|
318
|
+
// update u matrices
|
|
319
|
+
utemp = u[0];
|
|
320
|
+
u[0] = cosl[0] * utemp + sinl[0] * u[3];
|
|
321
|
+
u[3] = -sinl[0] * utemp + cosl[0] * u[3];
|
|
322
|
+
utemp = u[1];
|
|
323
|
+
u[1] = cosl[0] * utemp + sinl[0] * u[4];
|
|
324
|
+
u[4] = -sinl[0] * utemp + cosl[0] * u[4];
|
|
325
|
+
utemp = u[2];
|
|
326
|
+
u[2] = cosl[0] * utemp + sinl[0] * u[5];
|
|
327
|
+
u[5] = -sinl[0] * utemp + cosl[0] * u[5];
|
|
328
|
+
|
|
329
|
+
utemp = u[3];
|
|
330
|
+
u[3] = cosl[1] * utemp + sinl[1] * u[6];
|
|
331
|
+
u[6] = -sinl[1] * utemp + cosl[1] * u[6];
|
|
332
|
+
utemp = u[4];
|
|
333
|
+
u[4] = cosl[1] * utemp + sinl[1] * u[7];
|
|
334
|
+
u[7] = -sinl[1] * utemp + cosl[1] * u[7];
|
|
335
|
+
utemp = u[5];
|
|
336
|
+
u[5] = cosl[1] * utemp + sinl[1] * u[8];
|
|
337
|
+
u[8] = -sinl[1] * utemp + cosl[1] * u[8];
|
|
338
|
+
|
|
339
|
+
// update v matrices
|
|
340
|
+
|
|
341
|
+
vtemp = v[0];
|
|
342
|
+
v[0] = cosr[0] * vtemp + sinr[0] * v[1];
|
|
343
|
+
v[1] = -sinr[0] * vtemp + cosr[0] * v[1];
|
|
344
|
+
vtemp = v[3];
|
|
345
|
+
v[3] = cosr[0] * vtemp + sinr[0] * v[4];
|
|
346
|
+
v[4] = -sinr[0] * vtemp + cosr[0] * v[4];
|
|
347
|
+
vtemp = v[6];
|
|
348
|
+
v[6] = cosr[0] * vtemp + sinr[0] * v[7];
|
|
349
|
+
v[7] = -sinr[0] * vtemp + cosr[0] * v[7];
|
|
350
|
+
|
|
351
|
+
vtemp = v[1];
|
|
352
|
+
v[1] = cosr[1] * vtemp + sinr[1] * v[2];
|
|
353
|
+
v[2] = -sinr[1] * vtemp + cosr[1] * v[2];
|
|
354
|
+
vtemp = v[4];
|
|
355
|
+
v[4] = cosr[1] * vtemp + sinr[1] * v[5];
|
|
356
|
+
v[5] = -sinr[1] * vtemp + cosr[1] * v[5];
|
|
357
|
+
vtemp = v[7];
|
|
358
|
+
v[7] = cosr[1] * vtemp + sinr[1] * v[8];
|
|
359
|
+
v[8] = -sinr[1] * vtemp + cosr[1] * v[8];
|
|
360
|
+
|
|
361
|
+
m[0] = s[0];
|
|
362
|
+
m[1] = e[0];
|
|
363
|
+
m[2] = 0.0;
|
|
364
|
+
m[3] = 0.0;
|
|
365
|
+
m[4] = s[1];
|
|
366
|
+
m[5] = e[1];
|
|
367
|
+
m[6] = 0.0;
|
|
368
|
+
m[7] = 0.0;
|
|
369
|
+
m[8] = s[2];
|
|
370
|
+
|
|
371
|
+
if (Math.abs(e[1]) < CONVERGE_TOL || Math.abs(e[0]) < CONVERGE_TOL) {
|
|
372
|
+
converged = true;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (Math.abs(e[1]) < CONVERGE_TOL) {
|
|
377
|
+
compute_2X2(s[0], e[0], s[1], s, sinl, cosl, sinr, cosr, 0);
|
|
378
|
+
|
|
379
|
+
utemp = u[0];
|
|
380
|
+
u[0] = cosl[0] * utemp + sinl[0] * u[3];
|
|
381
|
+
u[3] = -sinl[0] * utemp + cosl[0] * u[3];
|
|
382
|
+
utemp = u[1];
|
|
383
|
+
u[1] = cosl[0] * utemp + sinl[0] * u[4];
|
|
384
|
+
u[4] = -sinl[0] * utemp + cosl[0] * u[4];
|
|
385
|
+
utemp = u[2];
|
|
386
|
+
u[2] = cosl[0] * utemp + sinl[0] * u[5];
|
|
387
|
+
u[5] = -sinl[0] * utemp + cosl[0] * u[5];
|
|
388
|
+
|
|
389
|
+
// update v matrices
|
|
390
|
+
|
|
391
|
+
vtemp = v[0];
|
|
392
|
+
v[0] = cosr[0] * vtemp + sinr[0] * v[1];
|
|
393
|
+
v[1] = -sinr[0] * vtemp + cosr[0] * v[1];
|
|
394
|
+
vtemp = v[3];
|
|
395
|
+
v[3] = cosr[0] * vtemp + sinr[0] * v[4];
|
|
396
|
+
v[4] = -sinr[0] * vtemp + cosr[0] * v[4];
|
|
397
|
+
vtemp = v[6];
|
|
398
|
+
v[6] = cosr[0] * vtemp + sinr[0] * v[7];
|
|
399
|
+
v[7] = -sinr[0] * vtemp + cosr[0] * v[7];
|
|
400
|
+
} else {
|
|
401
|
+
compute_2X2(s[1], e[1], s[2], s, sinl, cosl, sinr, cosr, 1);
|
|
402
|
+
|
|
403
|
+
utemp = u[3];
|
|
404
|
+
u[3] = cosl[0] * utemp + sinl[0] * u[6];
|
|
405
|
+
u[6] = -sinl[0] * utemp + cosl[0] * u[6];
|
|
406
|
+
utemp = u[4];
|
|
407
|
+
u[4] = cosl[0] * utemp + sinl[0] * u[7];
|
|
408
|
+
u[7] = -sinl[0] * utemp + cosl[0] * u[7];
|
|
409
|
+
utemp = u[5];
|
|
410
|
+
u[5] = cosl[0] * utemp + sinl[0] * u[8];
|
|
411
|
+
u[8] = -sinl[0] * utemp + cosl[0] * u[8];
|
|
412
|
+
|
|
413
|
+
// update v matrices
|
|
414
|
+
|
|
415
|
+
vtemp = v[1];
|
|
416
|
+
v[1] = cosr[0] * vtemp + sinr[0] * v[2];
|
|
417
|
+
v[2] = -sinr[0] * vtemp + cosr[0] * v[2];
|
|
418
|
+
vtemp = v[4];
|
|
419
|
+
v[4] = cosr[0] * vtemp + sinr[0] * v[5];
|
|
420
|
+
v[5] = -sinr[0] * vtemp + cosr[0] * v[5];
|
|
421
|
+
vtemp = v[7];
|
|
422
|
+
v[7] = cosr[0] * vtemp + sinr[0] * v[8];
|
|
423
|
+
v[8] = -sinr[0] * vtemp + cosr[0] * v[8];
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
return (0);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
static double compute_rot(double f, double g, double[] sin, double[] cos,
|
|
430
|
+
int index, int first) {
|
|
431
|
+
double cs, sn;
|
|
432
|
+
int i;
|
|
433
|
+
double scale;
|
|
434
|
+
int count;
|
|
435
|
+
double f1, g1;
|
|
436
|
+
double r;
|
|
437
|
+
final double safmn2 = 2.002083095183101E-146;
|
|
438
|
+
final double safmx2 = 4.994797680505588E+145;
|
|
439
|
+
|
|
440
|
+
if (g == 0.) {
|
|
441
|
+
cs = 1.;
|
|
442
|
+
sn = 0.;
|
|
443
|
+
r = f;
|
|
444
|
+
} else if (f == 0.) {
|
|
445
|
+
cs = 0.;
|
|
446
|
+
sn = 1.;
|
|
447
|
+
r = g;
|
|
448
|
+
} else {
|
|
449
|
+
f1 = f;
|
|
450
|
+
g1 = g;
|
|
451
|
+
scale = MathUtils.max(MathUtils.abs(f1), MathUtils.abs(g1));
|
|
452
|
+
if (scale >= safmx2) {
|
|
453
|
+
count = 0;
|
|
454
|
+
while (scale >= safmx2) {
|
|
455
|
+
++count;
|
|
456
|
+
f1 *= safmn2;
|
|
457
|
+
g1 *= safmn2;
|
|
458
|
+
scale = MathUtils.max(MathUtils.abs(f1), MathUtils.abs(g1));
|
|
459
|
+
}
|
|
460
|
+
r = Math.sqrt(f1 * f1 + g1 * g1);
|
|
461
|
+
cs = f1 / r;
|
|
462
|
+
sn = g1 / r;
|
|
463
|
+
for (i = 1; i <= count; ++i) {
|
|
464
|
+
r *= safmx2;
|
|
465
|
+
}
|
|
466
|
+
} else if (scale <= safmn2) {
|
|
467
|
+
count = 0;
|
|
468
|
+
while (scale <= safmn2) {
|
|
469
|
+
++count;
|
|
470
|
+
f1 *= safmx2;
|
|
471
|
+
g1 *= safmx2;
|
|
472
|
+
scale = MathUtils.max(MathUtils.abs(f1), MathUtils.abs(g1));
|
|
473
|
+
}
|
|
474
|
+
r = Math.sqrt(f1 * f1 + g1 * g1);
|
|
475
|
+
cs = f1 / r;
|
|
476
|
+
sn = g1 / r;
|
|
477
|
+
for (i = 1; i <= count; ++i) {
|
|
478
|
+
r *= safmn2;
|
|
479
|
+
}
|
|
480
|
+
} else {
|
|
481
|
+
r = Math.sqrt(f1 * f1 + g1 * g1);
|
|
482
|
+
cs = f1 / r;
|
|
483
|
+
sn = g1 / r;
|
|
484
|
+
}
|
|
485
|
+
if (Math.abs(f) > Math.abs(g) && cs < 0.) {
|
|
486
|
+
cs = -cs;
|
|
487
|
+
sn = -sn;
|
|
488
|
+
r = -r;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
sin[index] = sn;
|
|
492
|
+
cos[index] = cs;
|
|
493
|
+
return r;
|
|
494
|
+
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
static double compute_shift(double f, double g, double h) {
|
|
498
|
+
double d__1, d__2;
|
|
499
|
+
double fhmn, fhmx, c, fa, ga, ha, as, at, au;
|
|
500
|
+
double ssmin;
|
|
501
|
+
|
|
502
|
+
fa = Math.abs(f);
|
|
503
|
+
ga = Math.abs(g);
|
|
504
|
+
ha = Math.abs(h);
|
|
505
|
+
fhmn = MathUtils.min(fa, ha);
|
|
506
|
+
fhmx = MathUtils.max(fa, ha);
|
|
507
|
+
if (fhmn == 0.) {
|
|
508
|
+
ssmin = 0.;
|
|
509
|
+
if (fhmx == 0.) {
|
|
510
|
+
} else {
|
|
511
|
+
d__1 = MathUtils.min(fhmx, ga) / MathUtils.max(fhmx, ga);
|
|
512
|
+
}
|
|
513
|
+
} else {
|
|
514
|
+
if (ga < fhmx) {
|
|
515
|
+
as = fhmn / fhmx + 1.;
|
|
516
|
+
at = (fhmx - fhmn) / fhmx;
|
|
517
|
+
d__1 = ga / fhmx;
|
|
518
|
+
au = d__1 * d__1;
|
|
519
|
+
c = 2. / (Math.sqrt(as * as + au) + Math.sqrt(at * at + au));
|
|
520
|
+
ssmin = fhmn * c;
|
|
521
|
+
} else {
|
|
522
|
+
au = fhmx / ga;
|
|
523
|
+
if (au == 0.) {
|
|
524
|
+
ssmin = fhmn * fhmx / ga;
|
|
525
|
+
} else {
|
|
526
|
+
as = fhmn / fhmx + 1.;
|
|
527
|
+
at = (fhmx - fhmn) / fhmx;
|
|
528
|
+
d__1 = as * au;
|
|
529
|
+
d__2 = at * au;
|
|
530
|
+
c = 1. / (Math.sqrt(d__1 * d__1 + 1.) + Math.sqrt(d__2
|
|
531
|
+
* d__2 + 1.));
|
|
532
|
+
ssmin = fhmn * c * au;
|
|
533
|
+
ssmin += ssmin;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
return (ssmin);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
static void compute_svd(double[] m, double[] outScale, double[] outRot) {
|
|
542
|
+
int i;
|
|
543
|
+
double g;
|
|
544
|
+
double[] u1 = new double[9];
|
|
545
|
+
double[] v1 = new double[9];
|
|
546
|
+
double[] t1 = new double[9];
|
|
547
|
+
double[] t2 = new double[9];
|
|
548
|
+
|
|
549
|
+
double[] tmp = t1;
|
|
550
|
+
double[] single_values = t2;
|
|
551
|
+
|
|
552
|
+
double[] rot = new double[9];
|
|
553
|
+
double[] e = new double[3];
|
|
554
|
+
double[] scales = new double[3];
|
|
555
|
+
|
|
556
|
+
int negCnt = 0;
|
|
557
|
+
double c1, c2, c3, c4;
|
|
558
|
+
double s1, s2, s3, s4;
|
|
559
|
+
|
|
560
|
+
for (i = 0; i < 9; i++) {
|
|
561
|
+
rot[i] = m[i];
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// u1
|
|
565
|
+
|
|
566
|
+
if (m[3] * m[3] < EPS) {
|
|
567
|
+
u1[0] = 1.0;
|
|
568
|
+
u1[1] = 0.0;
|
|
569
|
+
u1[2] = 0.0;
|
|
570
|
+
u1[3] = 0.0;
|
|
571
|
+
u1[4] = 1.0;
|
|
572
|
+
u1[5] = 0.0;
|
|
573
|
+
u1[6] = 0.0;
|
|
574
|
+
u1[7] = 0.0;
|
|
575
|
+
u1[8] = 1.0;
|
|
576
|
+
} else if (m[0] * m[0] < EPS) {
|
|
577
|
+
tmp[0] = m[0];
|
|
578
|
+
tmp[1] = m[1];
|
|
579
|
+
tmp[2] = m[2];
|
|
580
|
+
m[0] = m[3];
|
|
581
|
+
m[1] = m[4];
|
|
582
|
+
m[2] = m[5];
|
|
583
|
+
|
|
584
|
+
m[3] = -tmp[0]; // zero
|
|
585
|
+
m[4] = -tmp[1];
|
|
586
|
+
m[5] = -tmp[2];
|
|
587
|
+
|
|
588
|
+
u1[0] = 0.0;
|
|
589
|
+
u1[1] = 1.0;
|
|
590
|
+
u1[2] = 0.0;
|
|
591
|
+
u1[3] = -1.0;
|
|
592
|
+
u1[4] = 0.0;
|
|
593
|
+
u1[5] = 0.0;
|
|
594
|
+
u1[6] = 0.0;
|
|
595
|
+
u1[7] = 0.0;
|
|
596
|
+
u1[8] = 1.0;
|
|
597
|
+
} else {
|
|
598
|
+
g = 1.0 / Math.sqrt(m[0] * m[0] + m[3] * m[3]);
|
|
599
|
+
c1 = m[0] * g;
|
|
600
|
+
s1 = m[3] * g;
|
|
601
|
+
tmp[0] = c1 * m[0] + s1 * m[3];
|
|
602
|
+
tmp[1] = c1 * m[1] + s1 * m[4];
|
|
603
|
+
tmp[2] = c1 * m[2] + s1 * m[5];
|
|
604
|
+
|
|
605
|
+
m[3] = -s1 * m[0] + c1 * m[3]; // zero
|
|
606
|
+
m[4] = -s1 * m[1] + c1 * m[4];
|
|
607
|
+
m[5] = -s1 * m[2] + c1 * m[5];
|
|
608
|
+
|
|
609
|
+
m[0] = tmp[0];
|
|
610
|
+
m[1] = tmp[1];
|
|
611
|
+
m[2] = tmp[2];
|
|
612
|
+
u1[0] = c1;
|
|
613
|
+
u1[1] = s1;
|
|
614
|
+
u1[2] = 0.0;
|
|
615
|
+
u1[3] = -s1;
|
|
616
|
+
u1[4] = c1;
|
|
617
|
+
u1[5] = 0.0;
|
|
618
|
+
u1[6] = 0.0;
|
|
619
|
+
u1[7] = 0.0;
|
|
620
|
+
u1[8] = 1.0;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// u2
|
|
624
|
+
|
|
625
|
+
if (m[6] * m[6] < EPS) {
|
|
626
|
+
} else if (m[0] * m[0] < EPS) {
|
|
627
|
+
tmp[0] = m[0];
|
|
628
|
+
tmp[1] = m[1];
|
|
629
|
+
tmp[2] = m[2];
|
|
630
|
+
m[0] = m[6];
|
|
631
|
+
m[1] = m[7];
|
|
632
|
+
m[2] = m[8];
|
|
633
|
+
|
|
634
|
+
m[6] = -tmp[0]; // zero
|
|
635
|
+
m[7] = -tmp[1];
|
|
636
|
+
m[8] = -tmp[2];
|
|
637
|
+
|
|
638
|
+
tmp[0] = u1[0];
|
|
639
|
+
tmp[1] = u1[1];
|
|
640
|
+
tmp[2] = u1[2];
|
|
641
|
+
u1[0] = u1[6];
|
|
642
|
+
u1[1] = u1[7];
|
|
643
|
+
u1[2] = u1[8];
|
|
644
|
+
|
|
645
|
+
u1[6] = -tmp[0]; // zero
|
|
646
|
+
u1[7] = -tmp[1];
|
|
647
|
+
u1[8] = -tmp[2];
|
|
648
|
+
} else {
|
|
649
|
+
g = 1.0 / Math.sqrt(m[0] * m[0] + m[6] * m[6]);
|
|
650
|
+
c2 = m[0] * g;
|
|
651
|
+
s2 = m[6] * g;
|
|
652
|
+
tmp[0] = c2 * m[0] + s2 * m[6];
|
|
653
|
+
tmp[1] = c2 * m[1] + s2 * m[7];
|
|
654
|
+
tmp[2] = c2 * m[2] + s2 * m[8];
|
|
655
|
+
|
|
656
|
+
m[6] = -s2 * m[0] + c2 * m[6];
|
|
657
|
+
m[7] = -s2 * m[1] + c2 * m[7];
|
|
658
|
+
m[8] = -s2 * m[2] + c2 * m[8];
|
|
659
|
+
m[0] = tmp[0];
|
|
660
|
+
m[1] = tmp[1];
|
|
661
|
+
m[2] = tmp[2];
|
|
662
|
+
|
|
663
|
+
tmp[0] = c2 * u1[0];
|
|
664
|
+
tmp[1] = c2 * u1[1];
|
|
665
|
+
u1[2] = s2;
|
|
666
|
+
|
|
667
|
+
tmp[6] = -u1[0] * s2;
|
|
668
|
+
tmp[7] = -u1[1] * s2;
|
|
669
|
+
u1[8] = c2;
|
|
670
|
+
u1[0] = tmp[0];
|
|
671
|
+
u1[1] = tmp[1];
|
|
672
|
+
u1[6] = tmp[6];
|
|
673
|
+
u1[7] = tmp[7];
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// v1
|
|
677
|
+
|
|
678
|
+
if (m[2] * m[2] < EPS) {
|
|
679
|
+
v1[0] = 1.0;
|
|
680
|
+
v1[1] = 0.0;
|
|
681
|
+
v1[2] = 0.0;
|
|
682
|
+
v1[3] = 0.0;
|
|
683
|
+
v1[4] = 1.0;
|
|
684
|
+
v1[5] = 0.0;
|
|
685
|
+
v1[6] = 0.0;
|
|
686
|
+
v1[7] = 0.0;
|
|
687
|
+
v1[8] = 1.0;
|
|
688
|
+
} else if (m[1] * m[1] < EPS) {
|
|
689
|
+
tmp[2] = m[2];
|
|
690
|
+
tmp[5] = m[5];
|
|
691
|
+
tmp[8] = m[8];
|
|
692
|
+
m[2] = -m[1];
|
|
693
|
+
m[5] = -m[4];
|
|
694
|
+
m[8] = -m[7];
|
|
695
|
+
|
|
696
|
+
m[1] = tmp[2]; // zero
|
|
697
|
+
m[4] = tmp[5];
|
|
698
|
+
m[7] = tmp[8];
|
|
699
|
+
|
|
700
|
+
v1[0] = 1.0;
|
|
701
|
+
v1[1] = 0.0;
|
|
702
|
+
v1[2] = 0.0;
|
|
703
|
+
v1[3] = 0.0;
|
|
704
|
+
v1[4] = 0.0;
|
|
705
|
+
v1[5] = -1.0;
|
|
706
|
+
v1[6] = 0.0;
|
|
707
|
+
v1[7] = 1.0;
|
|
708
|
+
v1[8] = 0.0;
|
|
709
|
+
} else {
|
|
710
|
+
g = 1.0 / Math.sqrt(m[1] * m[1] + m[2] * m[2]);
|
|
711
|
+
c3 = m[1] * g;
|
|
712
|
+
s3 = m[2] * g;
|
|
713
|
+
tmp[1] = c3 * m[1] + s3 * m[2]; // can assign to m[1]?
|
|
714
|
+
m[2] = -s3 * m[1] + c3 * m[2]; // zero
|
|
715
|
+
m[1] = tmp[1];
|
|
716
|
+
|
|
717
|
+
tmp[4] = c3 * m[4] + s3 * m[5];
|
|
718
|
+
m[5] = -s3 * m[4] + c3 * m[5];
|
|
719
|
+
m[4] = tmp[4];
|
|
720
|
+
|
|
721
|
+
tmp[7] = c3 * m[7] + s3 * m[8];
|
|
722
|
+
m[8] = -s3 * m[7] + c3 * m[8];
|
|
723
|
+
m[7] = tmp[7];
|
|
724
|
+
|
|
725
|
+
v1[0] = 1.0;
|
|
726
|
+
v1[1] = 0.0;
|
|
727
|
+
v1[2] = 0.0;
|
|
728
|
+
v1[3] = 0.0;
|
|
729
|
+
v1[4] = c3;
|
|
730
|
+
v1[5] = -s3;
|
|
731
|
+
v1[6] = 0.0;
|
|
732
|
+
v1[7] = s3;
|
|
733
|
+
v1[8] = c3;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// u3
|
|
737
|
+
|
|
738
|
+
if (m[7] * m[7] < EPS) {
|
|
739
|
+
} else if (m[4] * m[4] < EPS) {
|
|
740
|
+
tmp[3] = m[3];
|
|
741
|
+
tmp[4] = m[4];
|
|
742
|
+
tmp[5] = m[5];
|
|
743
|
+
m[3] = m[6]; // zero
|
|
744
|
+
m[4] = m[7];
|
|
745
|
+
m[5] = m[8];
|
|
746
|
+
|
|
747
|
+
m[6] = -tmp[3]; // zero
|
|
748
|
+
m[7] = -tmp[4]; // zero
|
|
749
|
+
m[8] = -tmp[5];
|
|
750
|
+
|
|
751
|
+
tmp[3] = u1[3];
|
|
752
|
+
tmp[4] = u1[4];
|
|
753
|
+
tmp[5] = u1[5];
|
|
754
|
+
u1[3] = u1[6];
|
|
755
|
+
u1[4] = u1[7];
|
|
756
|
+
u1[5] = u1[8];
|
|
757
|
+
|
|
758
|
+
u1[6] = -tmp[3]; // zero
|
|
759
|
+
u1[7] = -tmp[4];
|
|
760
|
+
u1[8] = -tmp[5];
|
|
761
|
+
|
|
762
|
+
} else {
|
|
763
|
+
g = 1.0 / Math.sqrt(m[4] * m[4] + m[7] * m[7]);
|
|
764
|
+
c4 = m[4] * g;
|
|
765
|
+
s4 = m[7] * g;
|
|
766
|
+
tmp[3] = c4 * m[3] + s4 * m[6];
|
|
767
|
+
m[6] = -s4 * m[3] + c4 * m[6]; // zero
|
|
768
|
+
m[3] = tmp[3];
|
|
769
|
+
|
|
770
|
+
tmp[4] = c4 * m[4] + s4 * m[7];
|
|
771
|
+
m[7] = -s4 * m[4] + c4 * m[7];
|
|
772
|
+
m[4] = tmp[4];
|
|
773
|
+
|
|
774
|
+
tmp[5] = c4 * m[5] + s4 * m[8];
|
|
775
|
+
m[8] = -s4 * m[5] + c4 * m[8];
|
|
776
|
+
m[5] = tmp[5];
|
|
777
|
+
|
|
778
|
+
tmp[3] = c4 * u1[3] + s4 * u1[6];
|
|
779
|
+
u1[6] = -s4 * u1[3] + c4 * u1[6];
|
|
780
|
+
u1[3] = tmp[3];
|
|
781
|
+
|
|
782
|
+
tmp[4] = c4 * u1[4] + s4 * u1[7];
|
|
783
|
+
u1[7] = -s4 * u1[4] + c4 * u1[7];
|
|
784
|
+
u1[4] = tmp[4];
|
|
785
|
+
|
|
786
|
+
tmp[5] = c4 * u1[5] + s4 * u1[8];
|
|
787
|
+
u1[8] = -s4 * u1[5] + c4 * u1[8];
|
|
788
|
+
u1[5] = tmp[5];
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
single_values[0] = m[0];
|
|
792
|
+
single_values[1] = m[4];
|
|
793
|
+
single_values[2] = m[8];
|
|
794
|
+
e[0] = m[1];
|
|
795
|
+
e[1] = m[5];
|
|
796
|
+
|
|
797
|
+
if (e[0] * e[0] < EPS && e[1] * e[1] < EPS) {
|
|
798
|
+
|
|
799
|
+
} else {
|
|
800
|
+
compute_qr(single_values, e, u1, v1);
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
scales[0] = single_values[0];
|
|
804
|
+
scales[1] = single_values[1];
|
|
805
|
+
scales[2] = single_values[2];
|
|
806
|
+
|
|
807
|
+
// Do some optimization here. If scale is unity, simply return the
|
|
808
|
+
// rotation matric.
|
|
809
|
+
if (almostEqual(Math.abs(scales[0]), 1.0)
|
|
810
|
+
&& almostEqual(Math.abs(scales[1]), 1.0)
|
|
811
|
+
&& almostEqual(Math.abs(scales[2]), 1.0)) {
|
|
812
|
+
for (i = 0; i < 3; i++) {
|
|
813
|
+
if (scales[i] < 0.0) {
|
|
814
|
+
negCnt++;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
if ((negCnt == 0) || (negCnt == 2)) {
|
|
819
|
+
outScale[0] = outScale[1] = outScale[2] = 1.0;
|
|
820
|
+
for (i = 0; i < 9; i++) {
|
|
821
|
+
outRot[i] = rot[i];
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
transpose_mat(u1, t1);
|
|
829
|
+
transpose_mat(v1, t2);
|
|
830
|
+
|
|
831
|
+
svdReorder(m, t1, t2, scales, outRot, outScale);
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
/**
|
|
835
|
+
* Solves a set of linear equations. The input parameters "matrix1", and
|
|
836
|
+
* "row_perm" come from luDecompostionD3x3 and do not change here. The
|
|
837
|
+
* parameter "matrix2" is a set of column vectors assembled into a 3x3
|
|
838
|
+
* matrix of floating-point values. The procedure takes each column of
|
|
839
|
+
* "matrix2" in turn and treats it as the right-hand side of the matrix
|
|
840
|
+
* equation Ax = LUx = b. The solution vector replaces the original column
|
|
841
|
+
* of the matrix.
|
|
842
|
+
*
|
|
843
|
+
* If "matrix2" is the identity matrix, the procedure replaces its contents
|
|
844
|
+
* with the inverse of the matrix from which "matrix1" was originally
|
|
845
|
+
* derived.
|
|
846
|
+
*/
|
|
847
|
+
//
|
|
848
|
+
// Reference: Press, Flannery, Teukolsky, Vetterling,
|
|
849
|
+
// _Numerical_Recipes_in_C_, Cambridge University Press,
|
|
850
|
+
// 1988, pp 44-45.
|
|
851
|
+
//
|
|
852
|
+
static void luBacksubstitution(double[] matrix1, int[] row_perm,
|
|
853
|
+
double[] matrix2) {
|
|
854
|
+
|
|
855
|
+
int i, ii, ip, j, k;
|
|
856
|
+
int rp;
|
|
857
|
+
int cv, rv;
|
|
858
|
+
|
|
859
|
+
// rp = row_perm;
|
|
860
|
+
rp = 0;
|
|
861
|
+
|
|
862
|
+
// For each column vector of matrix2 ...
|
|
863
|
+
for (k = 0; k < 3; k++) {
|
|
864
|
+
// cv = &(matrix2[0][k]);
|
|
865
|
+
cv = k;
|
|
866
|
+
ii = -1;
|
|
867
|
+
|
|
868
|
+
// Forward substitution
|
|
869
|
+
for (i = 0; i < 3; i++) {
|
|
870
|
+
double sum;
|
|
871
|
+
|
|
872
|
+
ip = row_perm[rp + i];
|
|
873
|
+
sum = matrix2[cv + 3 * ip];
|
|
874
|
+
matrix2[cv + 3 * ip] = matrix2[cv + 3 * i];
|
|
875
|
+
if (ii >= 0) {
|
|
876
|
+
// rv = &(matrix1[i][0]);
|
|
877
|
+
rv = i * 3;
|
|
878
|
+
for (j = ii; j <= i - 1; j++) {
|
|
879
|
+
sum -= matrix1[rv + j] * matrix2[cv + 3 * j];
|
|
880
|
+
}
|
|
881
|
+
} else if (sum != 0.0) {
|
|
882
|
+
ii = i;
|
|
883
|
+
}
|
|
884
|
+
matrix2[cv + 3 * i] = sum;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
// Backsubstitution
|
|
888
|
+
// rv = &(matrix1[3][0]);
|
|
889
|
+
rv = 2 * 3;
|
|
890
|
+
matrix2[cv + 3 * 2] /= matrix1[rv + 2];
|
|
891
|
+
|
|
892
|
+
rv -= 3;
|
|
893
|
+
matrix2[cv + 3 * 1] = (matrix2[cv + 3 * 1] - matrix1[rv + 2]
|
|
894
|
+
* matrix2[cv + 3 * 2])
|
|
895
|
+
/ matrix1[rv + 1];
|
|
896
|
+
|
|
897
|
+
rv -= 3;
|
|
898
|
+
matrix2[cv + 4 * 0] = (matrix2[cv + 3 * 0] - matrix1[rv + 1]
|
|
899
|
+
* matrix2[cv + 3 * 1] - matrix1[rv + 2]
|
|
900
|
+
* matrix2[cv + 3 * 2])
|
|
901
|
+
/ matrix1[rv + 0];
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
static void mat_mul(double[] m1, double[] m2, double[] m3) {
|
|
906
|
+
int i;
|
|
907
|
+
double[] tmp = new double[9];
|
|
908
|
+
|
|
909
|
+
tmp[0] = m1[0] * m2[0] + m1[1] * m2[3] + m1[2] * m2[6];
|
|
910
|
+
tmp[1] = m1[0] * m2[1] + m1[1] * m2[4] + m1[2] * m2[7];
|
|
911
|
+
tmp[2] = m1[0] * m2[2] + m1[1] * m2[5] + m1[2] * m2[8];
|
|
912
|
+
|
|
913
|
+
tmp[3] = m1[3] * m2[0] + m1[4] * m2[3] + m1[5] * m2[6];
|
|
914
|
+
tmp[4] = m1[3] * m2[1] + m1[4] * m2[4] + m1[5] * m2[7];
|
|
915
|
+
tmp[5] = m1[3] * m2[2] + m1[4] * m2[5] + m1[5] * m2[8];
|
|
916
|
+
|
|
917
|
+
tmp[6] = m1[6] * m2[0] + m1[7] * m2[3] + m1[8] * m2[6];
|
|
918
|
+
tmp[7] = m1[6] * m2[1] + m1[7] * m2[4] + m1[8] * m2[7];
|
|
919
|
+
tmp[8] = m1[6] * m2[2] + m1[7] * m2[5] + m1[8] * m2[8];
|
|
920
|
+
|
|
921
|
+
for (i = 0; i < 9; i++) {
|
|
922
|
+
m3[i] = tmp[i];
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
static void print_det(double[] mat) {
|
|
927
|
+
double det;
|
|
928
|
+
|
|
929
|
+
det = mat[0] * mat[4] * mat[8] + mat[1] * mat[5] * mat[6] + mat[2]
|
|
930
|
+
* mat[3] * mat[7] - mat[2] * mat[4] * mat[6] - mat[0] * mat[5]
|
|
931
|
+
* mat[7] - mat[1] * mat[3] * mat[8];
|
|
932
|
+
System.out.println("det= " + det);
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
static void print_mat(double[] mat) {
|
|
936
|
+
int i;
|
|
937
|
+
for (i = 0; i < 3; i++) {
|
|
938
|
+
System.out.println(mat[i * 3 + 0] + " " + mat[i * 3 + 1] + " "
|
|
939
|
+
+ mat[i * 3 + 2] + "\n");
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
static void svdReorder(double[] m, double[] t1, double[] t2,
|
|
945
|
+
double[] scales, double[] outRot, double[] outScale) {
|
|
946
|
+
|
|
947
|
+
int[] out = new int[3];
|
|
948
|
+
int[] in = new int[3];
|
|
949
|
+
int in0, in1, in2, index, i;
|
|
950
|
+
double[] mag = new double[3];
|
|
951
|
+
double[] rot = new double[9];
|
|
952
|
+
|
|
953
|
+
// check for rotation information in the scales
|
|
954
|
+
if (scales[0] < 0.0) { // move the rotation info to rotation matrix
|
|
955
|
+
scales[0] = -scales[0];
|
|
956
|
+
t2[0] = -t2[0];
|
|
957
|
+
t2[1] = -t2[1];
|
|
958
|
+
t2[2] = -t2[2];
|
|
959
|
+
}
|
|
960
|
+
if (scales[1] < 0.0) { // move the rotation info to rotation matrix
|
|
961
|
+
scales[1] = -scales[1];
|
|
962
|
+
t2[3] = -t2[3];
|
|
963
|
+
t2[4] = -t2[4];
|
|
964
|
+
t2[5] = -t2[5];
|
|
965
|
+
}
|
|
966
|
+
if (scales[2] < 0.0) { // move the rotation info to rotation matrix
|
|
967
|
+
scales[2] = -scales[2];
|
|
968
|
+
t2[6] = -t2[6];
|
|
969
|
+
t2[7] = -t2[7];
|
|
970
|
+
t2[8] = -t2[8];
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
mat_mul(t1, t2, rot);
|
|
974
|
+
|
|
975
|
+
// check for equal scales case and do not reorder
|
|
976
|
+
if (almostEqual(Math.abs(scales[0]), Math.abs(scales[1]))
|
|
977
|
+
&& almostEqual(Math.abs(scales[1]), Math.abs(scales[2]))) {
|
|
978
|
+
for (i = 0; i < 9; i++) {
|
|
979
|
+
outRot[i] = rot[i];
|
|
980
|
+
}
|
|
981
|
+
for (i = 0; i < 3; i++) {
|
|
982
|
+
outScale[i] = scales[i];
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
} else {
|
|
986
|
+
|
|
987
|
+
// sort the order of the results of SVD
|
|
988
|
+
if (scales[0] > scales[1]) {
|
|
989
|
+
if (scales[0] > scales[2]) {
|
|
990
|
+
if (scales[2] > scales[1]) {
|
|
991
|
+
out[0] = 0;
|
|
992
|
+
out[1] = 2;
|
|
993
|
+
out[2] = 1; // xzy
|
|
994
|
+
} else {
|
|
995
|
+
out[0] = 0;
|
|
996
|
+
out[1] = 1;
|
|
997
|
+
out[2] = 2; // xyz
|
|
998
|
+
}
|
|
999
|
+
} else {
|
|
1000
|
+
out[0] = 2;
|
|
1001
|
+
out[1] = 0;
|
|
1002
|
+
out[2] = 1; // zxy
|
|
1003
|
+
}
|
|
1004
|
+
} else { // y > x
|
|
1005
|
+
if (scales[1] > scales[2]) {
|
|
1006
|
+
if (scales[2] > scales[0]) {
|
|
1007
|
+
out[0] = 1;
|
|
1008
|
+
out[1] = 2;
|
|
1009
|
+
out[2] = 0; // yzx
|
|
1010
|
+
} else {
|
|
1011
|
+
out[0] = 1;
|
|
1012
|
+
out[1] = 0;
|
|
1013
|
+
out[2] = 2; // yxz
|
|
1014
|
+
}
|
|
1015
|
+
} else {
|
|
1016
|
+
out[0] = 2;
|
|
1017
|
+
out[1] = 1;
|
|
1018
|
+
out[2] = 0; // zyx
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
/*
|
|
1023
|
+
* System.out.println("\nscales="+scales[0]+" "+scales[1]+" "+scales[
|
|
1024
|
+
* 2]); System.out.println("\nrot="+rot[0]+" "+rot[1]+" "+rot[2]);
|
|
1025
|
+
* System.out.println("rot="+rot[3]+" "+rot[4]+" "+rot[5]);
|
|
1026
|
+
* System.out.println("rot="+rot[6]+" "+rot[7]+" "+rot[8]);
|
|
1027
|
+
*/
|
|
1028
|
+
|
|
1029
|
+
// sort the order of the input matrix
|
|
1030
|
+
mag[0] = (m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
|
|
1031
|
+
mag[1] = (m[3] * m[3] + m[4] * m[4] + m[5] * m[5]);
|
|
1032
|
+
mag[2] = (m[6] * m[6] + m[7] * m[7] + m[8] * m[8]);
|
|
1033
|
+
|
|
1034
|
+
if (mag[0] > mag[1]) {
|
|
1035
|
+
if (mag[0] > mag[2]) {
|
|
1036
|
+
if (mag[2] > mag[1]) {
|
|
1037
|
+
// 0 - 2 - 1
|
|
1038
|
+
in0 = 0;
|
|
1039
|
+
in2 = 1;
|
|
1040
|
+
in1 = 2;// xzy
|
|
1041
|
+
} else {
|
|
1042
|
+
// 0 - 1 - 2
|
|
1043
|
+
in0 = 0;
|
|
1044
|
+
in1 = 1;
|
|
1045
|
+
in2 = 2; // xyz
|
|
1046
|
+
}
|
|
1047
|
+
} else {
|
|
1048
|
+
// 2 - 0 - 1
|
|
1049
|
+
in2 = 0;
|
|
1050
|
+
in0 = 1;
|
|
1051
|
+
in1 = 2; // zxy
|
|
1052
|
+
}
|
|
1053
|
+
} else { // y > x 1>0
|
|
1054
|
+
if (mag[1] > mag[2]) {
|
|
1055
|
+
if (mag[2] > mag[0]) {
|
|
1056
|
+
// 1 - 2 - 0
|
|
1057
|
+
in1 = 0;
|
|
1058
|
+
in2 = 1;
|
|
1059
|
+
in0 = 2; // yzx
|
|
1060
|
+
} else {
|
|
1061
|
+
// 1 - 0 - 2
|
|
1062
|
+
in1 = 0;
|
|
1063
|
+
in0 = 1;
|
|
1064
|
+
in2 = 2; // yxz
|
|
1065
|
+
}
|
|
1066
|
+
} else {
|
|
1067
|
+
// 2 - 1 - 0
|
|
1068
|
+
in2 = 0;
|
|
1069
|
+
in1 = 1;
|
|
1070
|
+
in0 = 2; // zyx
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
index = out[in0];
|
|
1075
|
+
outScale[0] = scales[index];
|
|
1076
|
+
|
|
1077
|
+
index = out[in1];
|
|
1078
|
+
outScale[1] = scales[index];
|
|
1079
|
+
|
|
1080
|
+
index = out[in2];
|
|
1081
|
+
outScale[2] = scales[index];
|
|
1082
|
+
|
|
1083
|
+
index = out[in0];
|
|
1084
|
+
outRot[0] = rot[index];
|
|
1085
|
+
|
|
1086
|
+
index = out[in0] + 3;
|
|
1087
|
+
outRot[0 + 3] = rot[index];
|
|
1088
|
+
|
|
1089
|
+
index = out[in0] + 6;
|
|
1090
|
+
outRot[0 + 6] = rot[index];
|
|
1091
|
+
|
|
1092
|
+
index = out[in1];
|
|
1093
|
+
outRot[1] = rot[index];
|
|
1094
|
+
|
|
1095
|
+
index = out[in1] + 3;
|
|
1096
|
+
outRot[1 + 3] = rot[index];
|
|
1097
|
+
|
|
1098
|
+
index = out[in1] + 6;
|
|
1099
|
+
outRot[1 + 6] = rot[index];
|
|
1100
|
+
|
|
1101
|
+
index = out[in2];
|
|
1102
|
+
outRot[2] = rot[index];
|
|
1103
|
+
|
|
1104
|
+
index = out[in2] + 3;
|
|
1105
|
+
outRot[2 + 3] = rot[index];
|
|
1106
|
+
|
|
1107
|
+
index = out[in2] + 6;
|
|
1108
|
+
outRot[2 + 6] = rot[index];
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
static void transpose_mat(double[] in, double[] out) {
|
|
1113
|
+
out[0] = in[0];
|
|
1114
|
+
out[1] = in[3];
|
|
1115
|
+
out[2] = in[6];
|
|
1116
|
+
|
|
1117
|
+
out[3] = in[1];
|
|
1118
|
+
out[4] = in[4];
|
|
1119
|
+
out[5] = in[7];
|
|
1120
|
+
|
|
1121
|
+
out[6] = in[2];
|
|
1122
|
+
out[7] = in[5];
|
|
1123
|
+
out[8] = in[8];
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
/**
|
|
1127
|
+
* The first matrix element in the first row.
|
|
1128
|
+
*/
|
|
1129
|
+
public double m00;
|
|
1130
|
+
|
|
1131
|
+
/**
|
|
1132
|
+
* The second matrix element in the first row.
|
|
1133
|
+
*/
|
|
1134
|
+
public double m01;
|
|
1135
|
+
|
|
1136
|
+
/**
|
|
1137
|
+
* The third matrix element in the first row.
|
|
1138
|
+
*/
|
|
1139
|
+
public double m02;
|
|
1140
|
+
|
|
1141
|
+
/**
|
|
1142
|
+
* The first matrix element in the second row.
|
|
1143
|
+
*/
|
|
1144
|
+
public double m10;
|
|
1145
|
+
|
|
1146
|
+
/**
|
|
1147
|
+
* The second matrix element in the second row.
|
|
1148
|
+
*/
|
|
1149
|
+
public double m11;
|
|
1150
|
+
|
|
1151
|
+
/**
|
|
1152
|
+
* The third matrix element in the second row.
|
|
1153
|
+
*/
|
|
1154
|
+
public double m12;
|
|
1155
|
+
|
|
1156
|
+
/**
|
|
1157
|
+
* The first matrix element in the third row.
|
|
1158
|
+
*/
|
|
1159
|
+
public double m20;
|
|
1160
|
+
|
|
1161
|
+
/**
|
|
1162
|
+
* The second matrix element in the third row.
|
|
1163
|
+
*/
|
|
1164
|
+
public double m21;
|
|
1165
|
+
|
|
1166
|
+
/**
|
|
1167
|
+
* The third matrix element in the third row.
|
|
1168
|
+
*/
|
|
1169
|
+
public double m22;
|
|
1170
|
+
|
|
1171
|
+
// double[] tmp = new double[9]; // scratch matrix
|
|
1172
|
+
// double[] tmp_rot = new double[9]; // scratch matrix
|
|
1173
|
+
// double[] tmp_scale = new double[3]; // scratch matrix
|
|
1174
|
+
private static final double EPS = 1.110223024E-16;
|
|
1175
|
+
|
|
1176
|
+
private static final double ERR_EPS = 1.0E-8;
|
|
1177
|
+
|
|
1178
|
+
private static double xin, yin, zin, xout, yout, zout;
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* Constructs and initializes a Matrix3d to all zeros.
|
|
1182
|
+
*/
|
|
1183
|
+
public Matrix3d() {
|
|
1184
|
+
this.m00 = 0.0;
|
|
1185
|
+
this.m01 = 0.0;
|
|
1186
|
+
this.m02 = 0.0;
|
|
1187
|
+
|
|
1188
|
+
this.m10 = 0.0;
|
|
1189
|
+
this.m11 = 0.0;
|
|
1190
|
+
this.m12 = 0.0;
|
|
1191
|
+
|
|
1192
|
+
this.m20 = 0.0;
|
|
1193
|
+
this.m21 = 0.0;
|
|
1194
|
+
this.m22 = 0.0;
|
|
1195
|
+
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
/**
|
|
1199
|
+
* Constructs and initializes a Matrix3d from the specified nine values.
|
|
1200
|
+
*
|
|
1201
|
+
* @param m00
|
|
1202
|
+
* the [0][0] element
|
|
1203
|
+
* @param m01
|
|
1204
|
+
* the [0][1] element
|
|
1205
|
+
* @param m02
|
|
1206
|
+
* the [0][2] element
|
|
1207
|
+
* @param m10
|
|
1208
|
+
* the [1][0] element
|
|
1209
|
+
* @param m11
|
|
1210
|
+
* the [1][1] element
|
|
1211
|
+
* @param m12
|
|
1212
|
+
* the [1][2] element
|
|
1213
|
+
* @param m20
|
|
1214
|
+
* the [2][0] element
|
|
1215
|
+
* @param m21
|
|
1216
|
+
* the [2][1] element
|
|
1217
|
+
* @param m22
|
|
1218
|
+
* the [2][2] element
|
|
1219
|
+
*/
|
|
1220
|
+
public Matrix3d(double m00, double m01, double m02, double m10, double m11,
|
|
1221
|
+
double m12, double m20, double m21, double m22) {
|
|
1222
|
+
this.m00 = m00;
|
|
1223
|
+
this.m01 = m01;
|
|
1224
|
+
this.m02 = m02;
|
|
1225
|
+
|
|
1226
|
+
this.m10 = m10;
|
|
1227
|
+
this.m11 = m11;
|
|
1228
|
+
this.m12 = m12;
|
|
1229
|
+
|
|
1230
|
+
this.m20 = m20;
|
|
1231
|
+
this.m21 = m21;
|
|
1232
|
+
this.m22 = m22;
|
|
1233
|
+
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
/**
|
|
1237
|
+
* Constructs and initializes a Matrix3d from the specified nine- element
|
|
1238
|
+
* array.
|
|
1239
|
+
*
|
|
1240
|
+
* @param v
|
|
1241
|
+
* the array of length 9 containing in order
|
|
1242
|
+
*/
|
|
1243
|
+
public Matrix3d(double[] v) {
|
|
1244
|
+
this.m00 = v[0];
|
|
1245
|
+
this.m01 = v[1];
|
|
1246
|
+
this.m02 = v[2];
|
|
1247
|
+
|
|
1248
|
+
this.m10 = v[3];
|
|
1249
|
+
this.m11 = v[4];
|
|
1250
|
+
this.m12 = v[5];
|
|
1251
|
+
|
|
1252
|
+
this.m20 = v[6];
|
|
1253
|
+
this.m21 = v[7];
|
|
1254
|
+
this.m22 = v[8];
|
|
1255
|
+
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
/**
|
|
1259
|
+
* Constructs a new matrix with the same values as the Matrix3d parameter.
|
|
1260
|
+
*
|
|
1261
|
+
* @param m1
|
|
1262
|
+
* the source matrix
|
|
1263
|
+
*/
|
|
1264
|
+
public Matrix3d(Matrix3d m1) {
|
|
1265
|
+
this.m00 = m1.m00;
|
|
1266
|
+
this.m01 = m1.m01;
|
|
1267
|
+
this.m02 = m1.m02;
|
|
1268
|
+
|
|
1269
|
+
this.m10 = m1.m10;
|
|
1270
|
+
this.m11 = m1.m11;
|
|
1271
|
+
this.m12 = m1.m12;
|
|
1272
|
+
|
|
1273
|
+
this.m20 = m1.m20;
|
|
1274
|
+
this.m21 = m1.m21;
|
|
1275
|
+
this.m22 = m1.m22;
|
|
1276
|
+
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
/**
|
|
1280
|
+
* Adds a scalar to each component of this matrix.
|
|
1281
|
+
*
|
|
1282
|
+
* @param scalar
|
|
1283
|
+
* the scalar adder
|
|
1284
|
+
*/
|
|
1285
|
+
public final void add(double scalar) {
|
|
1286
|
+
m00 += scalar;
|
|
1287
|
+
m01 += scalar;
|
|
1288
|
+
m02 += scalar;
|
|
1289
|
+
|
|
1290
|
+
m10 += scalar;
|
|
1291
|
+
m11 += scalar;
|
|
1292
|
+
m12 += scalar;
|
|
1293
|
+
|
|
1294
|
+
m20 += scalar;
|
|
1295
|
+
m21 += scalar;
|
|
1296
|
+
m22 += scalar;
|
|
1297
|
+
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
/**
|
|
1301
|
+
* Adds a scalar to each component of the matrix m1 and places the result
|
|
1302
|
+
* into this. Matrix m1 is not modified.
|
|
1303
|
+
*
|
|
1304
|
+
* @param scalar
|
|
1305
|
+
* the scalar adder
|
|
1306
|
+
* @param m1
|
|
1307
|
+
* the original matrix values
|
|
1308
|
+
*/
|
|
1309
|
+
public final void add(double scalar, Matrix3d m1) {
|
|
1310
|
+
this.m00 = m1.m00 + scalar;
|
|
1311
|
+
this.m01 = m1.m01 + scalar;
|
|
1312
|
+
this.m02 = m1.m02 + scalar;
|
|
1313
|
+
|
|
1314
|
+
this.m10 = m1.m10 + scalar;
|
|
1315
|
+
this.m11 = m1.m11 + scalar;
|
|
1316
|
+
this.m12 = m1.m12 + scalar;
|
|
1317
|
+
|
|
1318
|
+
this.m20 = m1.m20 + scalar;
|
|
1319
|
+
this.m21 = m1.m21 + scalar;
|
|
1320
|
+
this.m22 = m1.m22 + scalar;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
/**
|
|
1324
|
+
* Sets the value of this matrix to the sum of itself and matrix m1.
|
|
1325
|
+
*
|
|
1326
|
+
* @param m1
|
|
1327
|
+
* the other matrix
|
|
1328
|
+
*/
|
|
1329
|
+
public final void add(Matrix3d m1) {
|
|
1330
|
+
this.m00 += m1.m00;
|
|
1331
|
+
this.m01 += m1.m01;
|
|
1332
|
+
this.m02 += m1.m02;
|
|
1333
|
+
|
|
1334
|
+
this.m10 += m1.m10;
|
|
1335
|
+
this.m11 += m1.m11;
|
|
1336
|
+
this.m12 += m1.m12;
|
|
1337
|
+
|
|
1338
|
+
this.m20 += m1.m20;
|
|
1339
|
+
this.m21 += m1.m21;
|
|
1340
|
+
this.m22 += m1.m22;
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
/**
|
|
1344
|
+
* Sets the value of this matrix to the matrix sum of matrices m1 and m2.
|
|
1345
|
+
*
|
|
1346
|
+
* @param m1
|
|
1347
|
+
* the first matrix
|
|
1348
|
+
* @param m2
|
|
1349
|
+
* the second matrix
|
|
1350
|
+
*/
|
|
1351
|
+
public final void add(Matrix3d m1, Matrix3d m2) {
|
|
1352
|
+
this.m00 = m1.m00 + m2.m00;
|
|
1353
|
+
this.m01 = m1.m01 + m2.m01;
|
|
1354
|
+
this.m02 = m1.m02 + m2.m02;
|
|
1355
|
+
|
|
1356
|
+
this.m10 = m1.m10 + m2.m10;
|
|
1357
|
+
this.m11 = m1.m11 + m2.m11;
|
|
1358
|
+
this.m12 = m1.m12 + m2.m12;
|
|
1359
|
+
|
|
1360
|
+
this.m20 = m1.m20 + m2.m20;
|
|
1361
|
+
this.m21 = m1.m21 + m2.m21;
|
|
1362
|
+
this.m22 = m1.m22 + m2.m22;
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
/**
|
|
1366
|
+
* Creates a new object of the same class as this object.
|
|
1367
|
+
*
|
|
1368
|
+
* @return a clone of this instance.
|
|
1369
|
+
* @exception OutOfMemoryError
|
|
1370
|
+
* if there is not enough memory.
|
|
1371
|
+
* @see java.lang.Cloneable
|
|
1372
|
+
* @since vecmath 1.3
|
|
1373
|
+
*/
|
|
1374
|
+
// public Object clone() {
|
|
1375
|
+
// Matrix3d m1 = null;
|
|
1376
|
+
// try {
|
|
1377
|
+
// m1 = (Matrix3d) super.clone();
|
|
1378
|
+
// } catch (CloneNotSupportedException e) {
|
|
1379
|
+
// // this shouldn't happen, since we are Cloneable
|
|
1380
|
+
// throw new InternalError();
|
|
1381
|
+
// }
|
|
1382
|
+
|
|
1383
|
+
// Also need to create new tmp arrays (no need to actually clone them)
|
|
1384
|
+
// return m1;
|
|
1385
|
+
// }
|
|
1386
|
+
|
|
1387
|
+
/**
|
|
1388
|
+
* Computes the determinant of this matrix.
|
|
1389
|
+
*
|
|
1390
|
+
* @return the determinant of the matrix
|
|
1391
|
+
*/
|
|
1392
|
+
public final double determinant() {
|
|
1393
|
+
double total;
|
|
1394
|
+
|
|
1395
|
+
total = this.m00 * (this.m11 * this.m22 - this.m12 * this.m21)
|
|
1396
|
+
+ this.m01 * (this.m12 * this.m20 - this.m10 * this.m22)
|
|
1397
|
+
+ this.m02 * (this.m10 * this.m21 - this.m11 * this.m20);
|
|
1398
|
+
return total;
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
/**
|
|
1402
|
+
* Returns true if the L-infinite distance between this matrix and matrix m1
|
|
1403
|
+
* is less than or equal to the epsilon parameter, otherwise returns false.
|
|
1404
|
+
* The L-infinite distance is equal to MAX[i=0,1,2 ; j=0,1,2 ;
|
|
1405
|
+
* abs(this.m(i,j) - m1.m(i,j)]
|
|
1406
|
+
*
|
|
1407
|
+
* @param m1
|
|
1408
|
+
* the matrix to be compared to this matrix
|
|
1409
|
+
* @param epsilon
|
|
1410
|
+
* the threshold value
|
|
1411
|
+
* @return
|
|
1412
|
+
*/
|
|
1413
|
+
public boolean epsilonEquals(Matrix3d m1, double epsilon) {
|
|
1414
|
+
double diff;
|
|
1415
|
+
|
|
1416
|
+
diff = m00 - m1.m00;
|
|
1417
|
+
if ((diff < 0 ? -diff : diff) > epsilon) {
|
|
1418
|
+
return false;
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
diff = m01 - m1.m01;
|
|
1422
|
+
if ((diff < 0 ? -diff : diff) > epsilon) {
|
|
1423
|
+
return false;
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
diff = m02 - m1.m02;
|
|
1427
|
+
if ((diff < 0 ? -diff : diff) > epsilon) {
|
|
1428
|
+
return false;
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
diff = m10 - m1.m10;
|
|
1432
|
+
if ((diff < 0 ? -diff : diff) > epsilon) {
|
|
1433
|
+
return false;
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
diff = m11 - m1.m11;
|
|
1437
|
+
if ((diff < 0 ? -diff : diff) > epsilon) {
|
|
1438
|
+
return false;
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
diff = m12 - m1.m12;
|
|
1442
|
+
if ((diff < 0 ? -diff : diff) > epsilon) {
|
|
1443
|
+
return false;
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
diff = m20 - m1.m20;
|
|
1447
|
+
if ((diff < 0 ? -diff : diff) > epsilon) {
|
|
1448
|
+
return false;
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
diff = m21 - m1.m21;
|
|
1452
|
+
if ((diff < 0 ? -diff : diff) > epsilon) {
|
|
1453
|
+
return false;
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
diff = m22 - m1.m22;
|
|
1457
|
+
return (diff < 0 ? -diff : diff) <= epsilon;
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
/**
|
|
1461
|
+
* Returns true if all of the data members of Matrix3d m1 are equal to the
|
|
1462
|
+
* corresponding data members in this Matrix3d.
|
|
1463
|
+
*
|
|
1464
|
+
* @param m1
|
|
1465
|
+
* the matrix with which the comparison is made
|
|
1466
|
+
* @return true or false
|
|
1467
|
+
*/
|
|
1468
|
+
public boolean equals(Matrix3d m1) {
|
|
1469
|
+
try {
|
|
1470
|
+
return (this.m00 == m1.m00 && this.m01 == m1.m01
|
|
1471
|
+
&& this.m02 == m1.m02 && this.m10 == m1.m10
|
|
1472
|
+
&& this.m11 == m1.m11 && this.m12 == m1.m12
|
|
1473
|
+
&& this.m20 == m1.m20 && this.m21 == m1.m21 && this.m22 == m1.m22);
|
|
1474
|
+
} catch (NullPointerException e2) {
|
|
1475
|
+
return false;
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
/**
|
|
1481
|
+
* Returns true if the Object t1 is of type Matrix3d and all of the data
|
|
1482
|
+
* members of t1 are equal to the corresponding data members in this
|
|
1483
|
+
* Matrix3d.
|
|
1484
|
+
*
|
|
1485
|
+
* @param t1
|
|
1486
|
+
* the matrix with which the comparison is made
|
|
1487
|
+
* @return true or false
|
|
1488
|
+
*/
|
|
1489
|
+
@Override
|
|
1490
|
+
public boolean equals(Object t1) {
|
|
1491
|
+
if (t1 instanceof Matrix3d) {
|
|
1492
|
+
Matrix3d m2 = (Matrix3d) t1;
|
|
1493
|
+
return (this.m00 == m2.m00 && this.m01 == m2.m01
|
|
1494
|
+
&& this.m02 == m2.m02 && this.m10 == m2.m10
|
|
1495
|
+
&& this.m11 == m2.m11 && this.m12 == m2.m12
|
|
1496
|
+
&& this.m20 == m2.m20 && this.m21 == m2.m21 && this.m22 == m2.m22);
|
|
1497
|
+
}
|
|
1498
|
+
return false;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
/**
|
|
1502
|
+
* Retrieves the value at the specified row and column of the specified
|
|
1503
|
+
* matrix.
|
|
1504
|
+
*
|
|
1505
|
+
* @param row
|
|
1506
|
+
* the row number to be retrieved (zero indexed)
|
|
1507
|
+
* @param column
|
|
1508
|
+
* the column number to be retrieved (zero indexed)
|
|
1509
|
+
* @return the value at the indexed element.
|
|
1510
|
+
*/
|
|
1511
|
+
public final double get(int row, int column) {
|
|
1512
|
+
switch (row) {
|
|
1513
|
+
case 0:
|
|
1514
|
+
switch (column) {
|
|
1515
|
+
case 0:
|
|
1516
|
+
return (this.m00);
|
|
1517
|
+
case 1:
|
|
1518
|
+
return (this.m01);
|
|
1519
|
+
case 2:
|
|
1520
|
+
return (this.m02);
|
|
1521
|
+
default:
|
|
1522
|
+
break;
|
|
1523
|
+
}
|
|
1524
|
+
break;
|
|
1525
|
+
case 1:
|
|
1526
|
+
switch (column) {
|
|
1527
|
+
case 0:
|
|
1528
|
+
return (this.m10);
|
|
1529
|
+
case 1:
|
|
1530
|
+
return (this.m11);
|
|
1531
|
+
case 2:
|
|
1532
|
+
return (this.m12);
|
|
1533
|
+
default:
|
|
1534
|
+
break;
|
|
1535
|
+
}
|
|
1536
|
+
break;
|
|
1537
|
+
|
|
1538
|
+
case 2:
|
|
1539
|
+
switch (column) {
|
|
1540
|
+
case 0:
|
|
1541
|
+
return (this.m20);
|
|
1542
|
+
case 1:
|
|
1543
|
+
return (this.m21);
|
|
1544
|
+
case 2:
|
|
1545
|
+
return (this.m22);
|
|
1546
|
+
default:
|
|
1547
|
+
break;
|
|
1548
|
+
}
|
|
1549
|
+
break;
|
|
1550
|
+
|
|
1551
|
+
default:
|
|
1552
|
+
break;
|
|
1553
|
+
}
|
|
1554
|
+
throw new ArrayIndexOutOfBoundsException();
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
/**
|
|
1558
|
+
* Copies the matrix values in the specified column into the array
|
|
1559
|
+
* parameter.
|
|
1560
|
+
*
|
|
1561
|
+
* @param column
|
|
1562
|
+
* the matrix column
|
|
1563
|
+
* @param v
|
|
1564
|
+
* the array into which the matrix row values will be copied
|
|
1565
|
+
*/
|
|
1566
|
+
public final void getColumn(int column, double v[]) {
|
|
1567
|
+
if (column == 0) {
|
|
1568
|
+
v[0] = m00;
|
|
1569
|
+
v[1] = m10;
|
|
1570
|
+
v[2] = m20;
|
|
1571
|
+
} else if (column == 1) {
|
|
1572
|
+
v[0] = m01;
|
|
1573
|
+
v[1] = m11;
|
|
1574
|
+
v[2] = m21;
|
|
1575
|
+
} else if (column == 2) {
|
|
1576
|
+
v[0] = m02;
|
|
1577
|
+
v[1] = m12;
|
|
1578
|
+
v[2] = m22;
|
|
1579
|
+
} else {
|
|
1580
|
+
throw new ArrayIndexOutOfBoundsException();
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
/**
|
|
1586
|
+
* Copies the matrix values in the specified column into the vector
|
|
1587
|
+
* parameter.
|
|
1588
|
+
*
|
|
1589
|
+
* @param column
|
|
1590
|
+
* the matrix column
|
|
1591
|
+
* @param v
|
|
1592
|
+
* the vector into which the matrix row values will be copied
|
|
1593
|
+
*/
|
|
1594
|
+
public final void getColumn(int column, Vec3D v) {
|
|
1595
|
+
if (column == 0) {
|
|
1596
|
+
v.x = (float) m00;
|
|
1597
|
+
v.y = (float) m10;
|
|
1598
|
+
v.z = (float) m20;
|
|
1599
|
+
} else if (column == 1) {
|
|
1600
|
+
v.x = (float) m01;
|
|
1601
|
+
v.y = (float) m11;
|
|
1602
|
+
v.z = (float) m21;
|
|
1603
|
+
} else if (column == 2) {
|
|
1604
|
+
v.x = (float) m02;
|
|
1605
|
+
v.y = (float) m12;
|
|
1606
|
+
v.z = (float) m22;
|
|
1607
|
+
} else {
|
|
1608
|
+
throw new ArrayIndexOutOfBoundsException();
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
/**
|
|
1614
|
+
* Copies the matrix values in the specified row into the array parameter.
|
|
1615
|
+
*
|
|
1616
|
+
* @param row
|
|
1617
|
+
* the matrix row
|
|
1618
|
+
* @param v
|
|
1619
|
+
* the array into which the matrix row values will be copied
|
|
1620
|
+
*/
|
|
1621
|
+
public final void getRow(int row, double v[]) {
|
|
1622
|
+
if (row == 0) {
|
|
1623
|
+
v[0] = m00;
|
|
1624
|
+
v[1] = m01;
|
|
1625
|
+
v[2] = m02;
|
|
1626
|
+
} else if (row == 1) {
|
|
1627
|
+
v[0] = m10;
|
|
1628
|
+
v[1] = m11;
|
|
1629
|
+
v[2] = m12;
|
|
1630
|
+
} else if (row == 2) {
|
|
1631
|
+
v[0] = m20;
|
|
1632
|
+
v[1] = m21;
|
|
1633
|
+
v[2] = m22;
|
|
1634
|
+
} else {
|
|
1635
|
+
throw new ArrayIndexOutOfBoundsException();
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
/**
|
|
1640
|
+
* Copies the matrix values in the specified row into the vector parameter.
|
|
1641
|
+
*
|
|
1642
|
+
* @param row
|
|
1643
|
+
* the matrix row
|
|
1644
|
+
* @param v
|
|
1645
|
+
* the vector into which the matrix row values will be copied
|
|
1646
|
+
*/
|
|
1647
|
+
public final void getRow(int row, Vec3D v) {
|
|
1648
|
+
if (row == 0) {
|
|
1649
|
+
v.x = (float) m00;
|
|
1650
|
+
v.y = (float) m01;
|
|
1651
|
+
v.z = (float) m02;
|
|
1652
|
+
} else if (row == 1) {
|
|
1653
|
+
v.x = (float) m10;
|
|
1654
|
+
v.y = (float) m11;
|
|
1655
|
+
v.z = (float) m12;
|
|
1656
|
+
} else if (row == 2) {
|
|
1657
|
+
v.x = (float) m20;
|
|
1658
|
+
v.y = (float) m21;
|
|
1659
|
+
v.z = (float) m22;
|
|
1660
|
+
} else {
|
|
1661
|
+
throw new ArrayIndexOutOfBoundsException();
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1666
|
+
/**
|
|
1667
|
+
* Performs an SVD normalization of this matrix to calculate and return the
|
|
1668
|
+
* uniform scale factor. If the matrix has non-uniform scale factors, the
|
|
1669
|
+
* largest of the x, y, and z scale factors will be returned. This matrix is
|
|
1670
|
+
* not modified.
|
|
1671
|
+
*
|
|
1672
|
+
* @return the scale factor of this matrix
|
|
1673
|
+
*/
|
|
1674
|
+
public final double getScale() {
|
|
1675
|
+
double[] tmp_scale = new double[3];
|
|
1676
|
+
double[] tmp_rot = new double[9];
|
|
1677
|
+
getScaleRotate(tmp_scale, tmp_rot);
|
|
1678
|
+
return (MathUtils.max(tmp_scale));
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
/**
|
|
1682
|
+
* perform SVD (if necessary to get rotational component
|
|
1683
|
+
*/
|
|
1684
|
+
final void getScaleRotate(double scales[], double rots[]) {
|
|
1685
|
+
double[] tmp = new double[9];
|
|
1686
|
+
tmp[0] = m00;
|
|
1687
|
+
tmp[1] = m01;
|
|
1688
|
+
tmp[2] = m02;
|
|
1689
|
+
|
|
1690
|
+
tmp[3] = m10;
|
|
1691
|
+
tmp[4] = m11;
|
|
1692
|
+
tmp[5] = m12;
|
|
1693
|
+
|
|
1694
|
+
tmp[6] = m20;
|
|
1695
|
+
tmp[7] = m21;
|
|
1696
|
+
tmp[8] = m22;
|
|
1697
|
+
compute_svd(tmp, scales, rots);
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
/**
|
|
1701
|
+
* Returns a hash code value based on the data values in this object. Two
|
|
1702
|
+
* different Matrix3d objects with identical data values (i.e.,
|
|
1703
|
+
* Matrix3d.equals returns true) will return the same hash code value. Two
|
|
1704
|
+
* objects with different data members may return the same hash value,
|
|
1705
|
+
* although this is not likely.
|
|
1706
|
+
*
|
|
1707
|
+
* @return the integer hash code value
|
|
1708
|
+
*/
|
|
1709
|
+
@Override
|
|
1710
|
+
public int hashCode() {
|
|
1711
|
+
long bits = 1L;
|
|
1712
|
+
bits = 31L * bits + VecMathUtil.doubleToLongBits(m00);
|
|
1713
|
+
bits = 31L * bits + VecMathUtil.doubleToLongBits(m01);
|
|
1714
|
+
bits = 31L * bits + VecMathUtil.doubleToLongBits(m02);
|
|
1715
|
+
bits = 31L * bits + VecMathUtil.doubleToLongBits(m10);
|
|
1716
|
+
bits = 31L * bits + VecMathUtil.doubleToLongBits(m11);
|
|
1717
|
+
bits = 31L * bits + VecMathUtil.doubleToLongBits(m12);
|
|
1718
|
+
bits = 31L * bits + VecMathUtil.doubleToLongBits(m20);
|
|
1719
|
+
bits = 31L * bits + VecMathUtil.doubleToLongBits(m21);
|
|
1720
|
+
bits = 31L * bits + VecMathUtil.doubleToLongBits(m22);
|
|
1721
|
+
return (int) (bits ^ (bits >> 32));
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
/**
|
|
1725
|
+
* Inverts this matrix in place.
|
|
1726
|
+
*/
|
|
1727
|
+
public final void invert() {
|
|
1728
|
+
invertGeneral(this);
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
/**
|
|
1732
|
+
* Sets the value of this matrix to the matrix inverse of the passed matrix
|
|
1733
|
+
* m1.
|
|
1734
|
+
*
|
|
1735
|
+
* @param m1
|
|
1736
|
+
* the matrix to be inverted
|
|
1737
|
+
*/
|
|
1738
|
+
public final void invert(Matrix3d m1) {
|
|
1739
|
+
invertGeneral(m1);
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
/**
|
|
1743
|
+
* General invert routine. Inverts m1 and places the result in "this". Note
|
|
1744
|
+
* that this routine handles both the "this" version and the non-"this"
|
|
1745
|
+
* version.
|
|
1746
|
+
*
|
|
1747
|
+
* Also note that since this routine is slow anyway, we won't worry about
|
|
1748
|
+
* allocating a little bit of garbage.
|
|
1749
|
+
*/
|
|
1750
|
+
private void invertGeneral(Matrix3d m1) {
|
|
1751
|
+
double result[] = new double[9];
|
|
1752
|
+
int row_perm[] = new int[3];
|
|
1753
|
+
int i, r, c;
|
|
1754
|
+
double[] tmp = new double[9]; // scratch matrix
|
|
1755
|
+
|
|
1756
|
+
// Use LU decomposition and backsubstitution code specifically
|
|
1757
|
+
// for floating-point 3x3 matrices.
|
|
1758
|
+
|
|
1759
|
+
// Copy source matrix to t1tmp
|
|
1760
|
+
tmp[0] = m1.m00;
|
|
1761
|
+
tmp[1] = m1.m01;
|
|
1762
|
+
tmp[2] = m1.m02;
|
|
1763
|
+
|
|
1764
|
+
tmp[3] = m1.m10;
|
|
1765
|
+
tmp[4] = m1.m11;
|
|
1766
|
+
tmp[5] = m1.m12;
|
|
1767
|
+
|
|
1768
|
+
tmp[6] = m1.m20;
|
|
1769
|
+
tmp[7] = m1.m21;
|
|
1770
|
+
tmp[8] = m1.m22;
|
|
1771
|
+
|
|
1772
|
+
// Calculate LU decomposition: Is the matrix singular?
|
|
1773
|
+
if (!Matrix4x4.LUDecomposition(tmp, row_perm, 3)) {
|
|
1774
|
+
// Matrix has no inverse
|
|
1775
|
+
throw new SingularMatrixException();
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
// Perform back substitution on the identity matrix
|
|
1779
|
+
for (i = 0; i < 9; i++) {
|
|
1780
|
+
result[i] = 0.0;
|
|
1781
|
+
}
|
|
1782
|
+
result[0] = 1.0;
|
|
1783
|
+
result[4] = 1.0;
|
|
1784
|
+
result[8] = 1.0;
|
|
1785
|
+
luBacksubstitution(tmp, row_perm, result);
|
|
1786
|
+
|
|
1787
|
+
this.m00 = result[0];
|
|
1788
|
+
this.m01 = result[1];
|
|
1789
|
+
this.m02 = result[2];
|
|
1790
|
+
|
|
1791
|
+
this.m10 = result[3];
|
|
1792
|
+
this.m11 = result[4];
|
|
1793
|
+
this.m12 = result[5];
|
|
1794
|
+
|
|
1795
|
+
this.m20 = result[6];
|
|
1796
|
+
this.m21 = result[7];
|
|
1797
|
+
this.m22 = result[8];
|
|
1798
|
+
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
/**
|
|
1802
|
+
* Multiplies each element of this matrix by a scalar.
|
|
1803
|
+
*
|
|
1804
|
+
* @param scalar
|
|
1805
|
+
* The scalar multiplier.
|
|
1806
|
+
*/
|
|
1807
|
+
public final void mul(double scalar) {
|
|
1808
|
+
m00 *= scalar;
|
|
1809
|
+
m01 *= scalar;
|
|
1810
|
+
m02 *= scalar;
|
|
1811
|
+
|
|
1812
|
+
m10 *= scalar;
|
|
1813
|
+
m11 *= scalar;
|
|
1814
|
+
m12 *= scalar;
|
|
1815
|
+
|
|
1816
|
+
m20 *= scalar;
|
|
1817
|
+
m21 *= scalar;
|
|
1818
|
+
m22 *= scalar;
|
|
1819
|
+
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
/**
|
|
1823
|
+
* Multiplies each element of matrix m1 by a scalar and places the result
|
|
1824
|
+
* into this. Matrix m1 is not modified.
|
|
1825
|
+
*
|
|
1826
|
+
* @param scalar
|
|
1827
|
+
* the scalar multiplier
|
|
1828
|
+
* @param m1
|
|
1829
|
+
* the original matrix
|
|
1830
|
+
*/
|
|
1831
|
+
public final void mul(double scalar, Matrix3d m1) {
|
|
1832
|
+
this.m00 = scalar * m1.m00;
|
|
1833
|
+
this.m01 = scalar * m1.m01;
|
|
1834
|
+
this.m02 = scalar * m1.m02;
|
|
1835
|
+
|
|
1836
|
+
this.m10 = scalar * m1.m10;
|
|
1837
|
+
this.m11 = scalar * m1.m11;
|
|
1838
|
+
this.m12 = scalar * m1.m12;
|
|
1839
|
+
|
|
1840
|
+
this.m20 = scalar * m1.m20;
|
|
1841
|
+
this.m21 = scalar * m1.m21;
|
|
1842
|
+
this.m22 = scalar * m1.m22;
|
|
1843
|
+
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
/**
|
|
1847
|
+
* Sets the value of this matrix to the result of multiplying itself with
|
|
1848
|
+
* matrix m1.
|
|
1849
|
+
*
|
|
1850
|
+
* @param m1
|
|
1851
|
+
* the other matrix
|
|
1852
|
+
*/
|
|
1853
|
+
public final void mul(Matrix3d m1) {
|
|
1854
|
+
double tm00, tm01, tm02, tm10, tm11, tm12, tm20, tm21, tm22;
|
|
1855
|
+
|
|
1856
|
+
tm00 = this.m00 * m1.m00 + this.m01 * m1.m10 + this.m02 * m1.m20;
|
|
1857
|
+
tm01 = this.m00 * m1.m01 + this.m01 * m1.m11 + this.m02 * m1.m21;
|
|
1858
|
+
tm02 = this.m00 * m1.m02 + this.m01 * m1.m12 + this.m02 * m1.m22;
|
|
1859
|
+
|
|
1860
|
+
tm10 = this.m10 * m1.m00 + this.m11 * m1.m10 + this.m12 * m1.m20;
|
|
1861
|
+
tm11 = this.m10 * m1.m01 + this.m11 * m1.m11 + this.m12 * m1.m21;
|
|
1862
|
+
tm12 = this.m10 * m1.m02 + this.m11 * m1.m12 + this.m12 * m1.m22;
|
|
1863
|
+
|
|
1864
|
+
tm20 = this.m20 * m1.m00 + this.m21 * m1.m10 + this.m22 * m1.m20;
|
|
1865
|
+
tm21 = this.m20 * m1.m01 + this.m21 * m1.m11 + this.m22 * m1.m21;
|
|
1866
|
+
tm22 = this.m20 * m1.m02 + this.m21 * m1.m12 + this.m22 * m1.m22;
|
|
1867
|
+
|
|
1868
|
+
this.m00 = tm00;
|
|
1869
|
+
this.m01 = tm01;
|
|
1870
|
+
this.m02 = tm02;
|
|
1871
|
+
this.m10 = tm10;
|
|
1872
|
+
this.m11 = tm11;
|
|
1873
|
+
this.m12 = tm12;
|
|
1874
|
+
this.m20 = tm20;
|
|
1875
|
+
this.m21 = tm21;
|
|
1876
|
+
this.m22 = tm22;
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
/**
|
|
1880
|
+
* Sets the value of this matrix to the result of multiplying the two
|
|
1881
|
+
* argument matrices together.
|
|
1882
|
+
*
|
|
1883
|
+
* @param m1
|
|
1884
|
+
* the first matrix
|
|
1885
|
+
* @param m2
|
|
1886
|
+
* the second matrix
|
|
1887
|
+
*/
|
|
1888
|
+
public final void mul(Matrix3d m1, Matrix3d m2) {
|
|
1889
|
+
if (this != m1 && this != m2) {
|
|
1890
|
+
this.m00 = m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20;
|
|
1891
|
+
this.m01 = m1.m00 * m2.m01 + m1.m01 * m2.m11 + m1.m02 * m2.m21;
|
|
1892
|
+
this.m02 = m1.m00 * m2.m02 + m1.m01 * m2.m12 + m1.m02 * m2.m22;
|
|
1893
|
+
|
|
1894
|
+
this.m10 = m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20;
|
|
1895
|
+
this.m11 = m1.m10 * m2.m01 + m1.m11 * m2.m11 + m1.m12 * m2.m21;
|
|
1896
|
+
this.m12 = m1.m10 * m2.m02 + m1.m11 * m2.m12 + m1.m12 * m2.m22;
|
|
1897
|
+
|
|
1898
|
+
this.m20 = m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20;
|
|
1899
|
+
this.m21 = m1.m20 * m2.m01 + m1.m21 * m2.m11 + m1.m22 * m2.m21;
|
|
1900
|
+
this.m22 = m1.m20 * m2.m02 + m1.m21 * m2.m12 + m1.m22 * m2.m22;
|
|
1901
|
+
} else {
|
|
1902
|
+
double tm00, tm01, tm02, tm10, tm11, tm12, tm20, tm21, tm22; // vars for temp
|
|
1903
|
+
// result matrix
|
|
1904
|
+
|
|
1905
|
+
tm00 = m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20;
|
|
1906
|
+
tm01 = m1.m00 * m2.m01 + m1.m01 * m2.m11 + m1.m02 * m2.m21;
|
|
1907
|
+
tm02 = m1.m00 * m2.m02 + m1.m01 * m2.m12 + m1.m02 * m2.m22;
|
|
1908
|
+
|
|
1909
|
+
tm10 = m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20;
|
|
1910
|
+
tm11 = m1.m10 * m2.m01 + m1.m11 * m2.m11 + m1.m12 * m2.m21;
|
|
1911
|
+
tm12 = m1.m10 * m2.m02 + m1.m11 * m2.m12 + m1.m12 * m2.m22;
|
|
1912
|
+
|
|
1913
|
+
tm20 = m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20;
|
|
1914
|
+
tm21 = m1.m20 * m2.m01 + m1.m21 * m2.m11 + m1.m22 * m2.m21;
|
|
1915
|
+
tm22 = m1.m20 * m2.m02 + m1.m21 * m2.m12 + m1.m22 * m2.m22;
|
|
1916
|
+
|
|
1917
|
+
this.m00 = tm00;
|
|
1918
|
+
this.m01 = tm01;
|
|
1919
|
+
this.m02 = tm02;
|
|
1920
|
+
this.m10 = tm10;
|
|
1921
|
+
this.m11 = tm11;
|
|
1922
|
+
this.m12 = tm12;
|
|
1923
|
+
this.m20 = tm20;
|
|
1924
|
+
this.m21 = tm21;
|
|
1925
|
+
this.m22 = tm22;
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1929
|
+
/**
|
|
1930
|
+
* Multiplies this matrix by matrix m1, does an SVD normalization of the
|
|
1931
|
+
* result, and places the result back into this matrix this =
|
|
1932
|
+
* SVDnorm(this*m1).
|
|
1933
|
+
*
|
|
1934
|
+
* @param m1
|
|
1935
|
+
* the matrix on the right hand side of the multiplication
|
|
1936
|
+
*/
|
|
1937
|
+
public final void mulNormalize(Matrix3d m1) {
|
|
1938
|
+
|
|
1939
|
+
double[] tmp = new double[9]; // scratch matrix
|
|
1940
|
+
double[] tmp_rot = new double[9]; // scratch matrix
|
|
1941
|
+
double[] tmp_scale = new double[3]; // scratch matrix
|
|
1942
|
+
|
|
1943
|
+
tmp[0] = this.m00 * m1.m00 + this.m01 * m1.m10 + this.m02 * m1.m20;
|
|
1944
|
+
tmp[1] = this.m00 * m1.m01 + this.m01 * m1.m11 + this.m02 * m1.m21;
|
|
1945
|
+
tmp[2] = this.m00 * m1.m02 + this.m01 * m1.m12 + this.m02 * m1.m22;
|
|
1946
|
+
|
|
1947
|
+
tmp[3] = this.m10 * m1.m00 + this.m11 * m1.m10 + this.m12 * m1.m20;
|
|
1948
|
+
tmp[4] = this.m10 * m1.m01 + this.m11 * m1.m11 + this.m12 * m1.m21;
|
|
1949
|
+
tmp[5] = this.m10 * m1.m02 + this.m11 * m1.m12 + this.m12 * m1.m22;
|
|
1950
|
+
|
|
1951
|
+
tmp[6] = this.m20 * m1.m00 + this.m21 * m1.m10 + this.m22 * m1.m20;
|
|
1952
|
+
tmp[7] = this.m20 * m1.m01 + this.m21 * m1.m11 + this.m22 * m1.m21;
|
|
1953
|
+
tmp[8] = this.m20 * m1.m02 + this.m21 * m1.m12 + this.m22 * m1.m22;
|
|
1954
|
+
|
|
1955
|
+
compute_svd(tmp, tmp_scale, tmp_rot);
|
|
1956
|
+
|
|
1957
|
+
this.m00 = tmp_rot[0];
|
|
1958
|
+
this.m01 = tmp_rot[1];
|
|
1959
|
+
this.m02 = tmp_rot[2];
|
|
1960
|
+
|
|
1961
|
+
this.m10 = tmp_rot[3];
|
|
1962
|
+
this.m11 = tmp_rot[4];
|
|
1963
|
+
this.m12 = tmp_rot[5];
|
|
1964
|
+
|
|
1965
|
+
this.m20 = tmp_rot[6];
|
|
1966
|
+
this.m21 = tmp_rot[7];
|
|
1967
|
+
this.m22 = tmp_rot[8];
|
|
1968
|
+
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
/**
|
|
1972
|
+
* Multiplies matrix m1 by matrix m2, does an SVD normalization of the
|
|
1973
|
+
* result, and places the result into this matrix this = SVDnorm(m1*m2).
|
|
1974
|
+
*
|
|
1975
|
+
* @param m1
|
|
1976
|
+
* the matrix on the left hand side of the multiplication
|
|
1977
|
+
* @param m2
|
|
1978
|
+
* the matrix on the right hand side of the multiplication
|
|
1979
|
+
*/
|
|
1980
|
+
public final void mulNormalize(Matrix3d m1, Matrix3d m2) {
|
|
1981
|
+
|
|
1982
|
+
double[] tmp = new double[9]; // scratch matrix
|
|
1983
|
+
double[] tmp_rot = new double[9]; // scratch matrix
|
|
1984
|
+
double[] tmp_scale = new double[3]; // scratch matrix
|
|
1985
|
+
|
|
1986
|
+
tmp[0] = m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20;
|
|
1987
|
+
tmp[1] = m1.m00 * m2.m01 + m1.m01 * m2.m11 + m1.m02 * m2.m21;
|
|
1988
|
+
tmp[2] = m1.m00 * m2.m02 + m1.m01 * m2.m12 + m1.m02 * m2.m22;
|
|
1989
|
+
|
|
1990
|
+
tmp[3] = m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20;
|
|
1991
|
+
tmp[4] = m1.m10 * m2.m01 + m1.m11 * m2.m11 + m1.m12 * m2.m21;
|
|
1992
|
+
tmp[5] = m1.m10 * m2.m02 + m1.m11 * m2.m12 + m1.m12 * m2.m22;
|
|
1993
|
+
|
|
1994
|
+
tmp[6] = m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20;
|
|
1995
|
+
tmp[7] = m1.m20 * m2.m01 + m1.m21 * m2.m11 + m1.m22 * m2.m21;
|
|
1996
|
+
tmp[8] = m1.m20 * m2.m02 + m1.m21 * m2.m12 + m1.m22 * m2.m22;
|
|
1997
|
+
|
|
1998
|
+
compute_svd(tmp, tmp_scale, tmp_rot);
|
|
1999
|
+
|
|
2000
|
+
this.m00 = tmp_rot[0];
|
|
2001
|
+
this.m01 = tmp_rot[1];
|
|
2002
|
+
this.m02 = tmp_rot[2];
|
|
2003
|
+
|
|
2004
|
+
this.m10 = tmp_rot[3];
|
|
2005
|
+
this.m11 = tmp_rot[4];
|
|
2006
|
+
this.m12 = tmp_rot[5];
|
|
2007
|
+
|
|
2008
|
+
this.m20 = tmp_rot[6];
|
|
2009
|
+
this.m21 = tmp_rot[7];
|
|
2010
|
+
this.m22 = tmp_rot[8];
|
|
2011
|
+
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
/**
|
|
2015
|
+
* Multiplies the transpose of matrix m1 times the transpose of matrix m2,
|
|
2016
|
+
* and places the result into this.
|
|
2017
|
+
*
|
|
2018
|
+
* @param m1
|
|
2019
|
+
* the matrix on the left hand side of the multiplication
|
|
2020
|
+
* @param m2
|
|
2021
|
+
* the matrix on the right hand side of the multiplication
|
|
2022
|
+
*/
|
|
2023
|
+
public final void mulTransposeBoth(Matrix3d m1, Matrix3d m2) {
|
|
2024
|
+
if (this != m1 && this != m2) {
|
|
2025
|
+
this.m00 = m1.m00 * m2.m00 + m1.m10 * m2.m01 + m1.m20 * m2.m02;
|
|
2026
|
+
this.m01 = m1.m00 * m2.m10 + m1.m10 * m2.m11 + m1.m20 * m2.m12;
|
|
2027
|
+
this.m02 = m1.m00 * m2.m20 + m1.m10 * m2.m21 + m1.m20 * m2.m22;
|
|
2028
|
+
|
|
2029
|
+
this.m10 = m1.m01 * m2.m00 + m1.m11 * m2.m01 + m1.m21 * m2.m02;
|
|
2030
|
+
this.m11 = m1.m01 * m2.m10 + m1.m11 * m2.m11 + m1.m21 * m2.m12;
|
|
2031
|
+
this.m12 = m1.m01 * m2.m20 + m1.m11 * m2.m21 + m1.m21 * m2.m22;
|
|
2032
|
+
|
|
2033
|
+
this.m20 = m1.m02 * m2.m00 + m1.m12 * m2.m01 + m1.m22 * m2.m02;
|
|
2034
|
+
this.m21 = m1.m02 * m2.m10 + m1.m12 * m2.m11 + m1.m22 * m2.m12;
|
|
2035
|
+
this.m22 = m1.m02 * m2.m20 + m1.m12 * m2.m21 + m1.m22 * m2.m22;
|
|
2036
|
+
} else {
|
|
2037
|
+
double tm00, tm01, tm02, tm10, tm11, tm12, tm20, tm21, tm22; // vars for temp
|
|
2038
|
+
// result matrix
|
|
2039
|
+
|
|
2040
|
+
tm00 = m1.m00 * m2.m00 + m1.m10 * m2.m01 + m1.m20 * m2.m02;
|
|
2041
|
+
tm01 = m1.m00 * m2.m10 + m1.m10 * m2.m11 + m1.m20 * m2.m12;
|
|
2042
|
+
tm02 = m1.m00 * m2.m20 + m1.m10 * m2.m21 + m1.m20 * m2.m22;
|
|
2043
|
+
|
|
2044
|
+
tm10 = m1.m01 * m2.m00 + m1.m11 * m2.m01 + m1.m21 * m2.m02;
|
|
2045
|
+
tm11 = m1.m01 * m2.m10 + m1.m11 * m2.m11 + m1.m21 * m2.m12;
|
|
2046
|
+
tm12 = m1.m01 * m2.m20 + m1.m11 * m2.m21 + m1.m21 * m2.m22;
|
|
2047
|
+
|
|
2048
|
+
tm20 = m1.m02 * m2.m00 + m1.m12 * m2.m01 + m1.m22 * m2.m02;
|
|
2049
|
+
tm21 = m1.m02 * m2.m10 + m1.m12 * m2.m11 + m1.m22 * m2.m12;
|
|
2050
|
+
tm22 = m1.m02 * m2.m20 + m1.m12 * m2.m21 + m1.m22 * m2.m22;
|
|
2051
|
+
|
|
2052
|
+
this.m00 = tm00;
|
|
2053
|
+
this.m01 = tm01;
|
|
2054
|
+
this.m02 = tm02;
|
|
2055
|
+
this.m10 = tm10;
|
|
2056
|
+
this.m11 = tm11;
|
|
2057
|
+
this.m12 = tm12;
|
|
2058
|
+
this.m20 = tm20;
|
|
2059
|
+
this.m21 = tm21;
|
|
2060
|
+
this.m22 = tm22;
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
}
|
|
2064
|
+
|
|
2065
|
+
/**
|
|
2066
|
+
* Multiplies the transpose of matrix m1 times matrix m2, and places the
|
|
2067
|
+
* result into this.
|
|
2068
|
+
*
|
|
2069
|
+
* @param m1
|
|
2070
|
+
* the matrix on the left hand side of the multiplication
|
|
2071
|
+
* @param m2
|
|
2072
|
+
* the matrix on the right hand side of the multiplication
|
|
2073
|
+
*/
|
|
2074
|
+
public final void mulTransposeLeft(Matrix3d m1, Matrix3d m2) {
|
|
2075
|
+
if (this != m1 && this != m2) {
|
|
2076
|
+
this.m00 = m1.m00 * m2.m00 + m1.m10 * m2.m10 + m1.m20 * m2.m20;
|
|
2077
|
+
this.m01 = m1.m00 * m2.m01 + m1.m10 * m2.m11 + m1.m20 * m2.m21;
|
|
2078
|
+
this.m02 = m1.m00 * m2.m02 + m1.m10 * m2.m12 + m1.m20 * m2.m22;
|
|
2079
|
+
|
|
2080
|
+
this.m10 = m1.m01 * m2.m00 + m1.m11 * m2.m10 + m1.m21 * m2.m20;
|
|
2081
|
+
this.m11 = m1.m01 * m2.m01 + m1.m11 * m2.m11 + m1.m21 * m2.m21;
|
|
2082
|
+
this.m12 = m1.m01 * m2.m02 + m1.m11 * m2.m12 + m1.m21 * m2.m22;
|
|
2083
|
+
|
|
2084
|
+
this.m20 = m1.m02 * m2.m00 + m1.m12 * m2.m10 + m1.m22 * m2.m20;
|
|
2085
|
+
this.m21 = m1.m02 * m2.m01 + m1.m12 * m2.m11 + m1.m22 * m2.m21;
|
|
2086
|
+
this.m22 = m1.m02 * m2.m02 + m1.m12 * m2.m12 + m1.m22 * m2.m22;
|
|
2087
|
+
} else {
|
|
2088
|
+
double tm00, tm01, tm02, tm10, tm11, tm12, tm20, tm21, tm22; // vars for temp
|
|
2089
|
+
// result matrix
|
|
2090
|
+
|
|
2091
|
+
tm00 = m1.m00 * m2.m00 + m1.m10 * m2.m10 + m1.m20 * m2.m20;
|
|
2092
|
+
tm01 = m1.m00 * m2.m01 + m1.m10 * m2.m11 + m1.m20 * m2.m21;
|
|
2093
|
+
tm02 = m1.m00 * m2.m02 + m1.m10 * m2.m12 + m1.m20 * m2.m22;
|
|
2094
|
+
|
|
2095
|
+
tm10 = m1.m01 * m2.m00 + m1.m11 * m2.m10 + m1.m21 * m2.m20;
|
|
2096
|
+
tm11 = m1.m01 * m2.m01 + m1.m11 * m2.m11 + m1.m21 * m2.m21;
|
|
2097
|
+
tm12 = m1.m01 * m2.m02 + m1.m11 * m2.m12 + m1.m21 * m2.m22;
|
|
2098
|
+
|
|
2099
|
+
tm20 = m1.m02 * m2.m00 + m1.m12 * m2.m10 + m1.m22 * m2.m20;
|
|
2100
|
+
tm21 = m1.m02 * m2.m01 + m1.m12 * m2.m11 + m1.m22 * m2.m21;
|
|
2101
|
+
tm22 = m1.m02 * m2.m02 + m1.m12 * m2.m12 + m1.m22 * m2.m22;
|
|
2102
|
+
|
|
2103
|
+
this.m00 = tm00;
|
|
2104
|
+
this.m01 = tm01;
|
|
2105
|
+
this.m02 = tm02;
|
|
2106
|
+
this.m10 = tm10;
|
|
2107
|
+
this.m11 = tm11;
|
|
2108
|
+
this.m12 = tm12;
|
|
2109
|
+
this.m20 = tm20;
|
|
2110
|
+
this.m21 = tm21;
|
|
2111
|
+
this.m22 = tm22;
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
|
|
2115
|
+
/**
|
|
2116
|
+
* Multiplies matrix m1 times the transpose of matrix m2, and places the
|
|
2117
|
+
* result into this.
|
|
2118
|
+
*
|
|
2119
|
+
* @param m1
|
|
2120
|
+
* the matrix on the left hand side of the multiplication
|
|
2121
|
+
* @param m2
|
|
2122
|
+
* the matrix on the right hand side of the multiplication
|
|
2123
|
+
*/
|
|
2124
|
+
public final void mulTransposeRight(Matrix3d m1, Matrix3d m2) {
|
|
2125
|
+
if (this != m1 && this != m2) {
|
|
2126
|
+
this.m00 = m1.m00 * m2.m00 + m1.m01 * m2.m01 + m1.m02 * m2.m02;
|
|
2127
|
+
this.m01 = m1.m00 * m2.m10 + m1.m01 * m2.m11 + m1.m02 * m2.m12;
|
|
2128
|
+
this.m02 = m1.m00 * m2.m20 + m1.m01 * m2.m21 + m1.m02 * m2.m22;
|
|
2129
|
+
|
|
2130
|
+
this.m10 = m1.m10 * m2.m00 + m1.m11 * m2.m01 + m1.m12 * m2.m02;
|
|
2131
|
+
this.m11 = m1.m10 * m2.m10 + m1.m11 * m2.m11 + m1.m12 * m2.m12;
|
|
2132
|
+
this.m12 = m1.m10 * m2.m20 + m1.m11 * m2.m21 + m1.m12 * m2.m22;
|
|
2133
|
+
|
|
2134
|
+
this.m20 = m1.m20 * m2.m00 + m1.m21 * m2.m01 + m1.m22 * m2.m02;
|
|
2135
|
+
this.m21 = m1.m20 * m2.m10 + m1.m21 * m2.m11 + m1.m22 * m2.m12;
|
|
2136
|
+
this.m22 = m1.m20 * m2.m20 + m1.m21 * m2.m21 + m1.m22 * m2.m22;
|
|
2137
|
+
} else {
|
|
2138
|
+
double tm00, tm01, tm02, tm10, tm11, tm12, tm20, tm21, tm22; // vars for temp
|
|
2139
|
+
// result matrix
|
|
2140
|
+
|
|
2141
|
+
tm00 = m1.m00 * m2.m00 + m1.m01 * m2.m01 + m1.m02 * m2.m02;
|
|
2142
|
+
tm01 = m1.m00 * m2.m10 + m1.m01 * m2.m11 + m1.m02 * m2.m12;
|
|
2143
|
+
tm02 = m1.m00 * m2.m20 + m1.m01 * m2.m21 + m1.m02 * m2.m22;
|
|
2144
|
+
|
|
2145
|
+
tm10 = m1.m10 * m2.m00 + m1.m11 * m2.m01 + m1.m12 * m2.m02;
|
|
2146
|
+
tm11 = m1.m10 * m2.m10 + m1.m11 * m2.m11 + m1.m12 * m2.m12;
|
|
2147
|
+
tm12 = m1.m10 * m2.m20 + m1.m11 * m2.m21 + m1.m12 * m2.m22;
|
|
2148
|
+
|
|
2149
|
+
tm20 = m1.m20 * m2.m00 + m1.m21 * m2.m01 + m1.m22 * m2.m02;
|
|
2150
|
+
tm21 = m1.m20 * m2.m10 + m1.m21 * m2.m11 + m1.m22 * m2.m12;
|
|
2151
|
+
tm22 = m1.m20 * m2.m20 + m1.m21 * m2.m21 + m1.m22 * m2.m22;
|
|
2152
|
+
|
|
2153
|
+
this.m00 = tm00;
|
|
2154
|
+
this.m01 = tm01;
|
|
2155
|
+
this.m02 = tm02;
|
|
2156
|
+
this.m10 = tm10;
|
|
2157
|
+
this.m11 = tm11;
|
|
2158
|
+
this.m12 = tm12;
|
|
2159
|
+
this.m20 = tm20;
|
|
2160
|
+
this.m21 = tm21;
|
|
2161
|
+
this.m22 = tm22;
|
|
2162
|
+
}
|
|
2163
|
+
}
|
|
2164
|
+
|
|
2165
|
+
/**
|
|
2166
|
+
* Negates the value of this matrix: this = -this.
|
|
2167
|
+
*/
|
|
2168
|
+
public final void negate() {
|
|
2169
|
+
this.m00 = -this.m00;
|
|
2170
|
+
this.m01 = -this.m01;
|
|
2171
|
+
this.m02 = -this.m02;
|
|
2172
|
+
|
|
2173
|
+
this.m10 = -this.m10;
|
|
2174
|
+
this.m11 = -this.m11;
|
|
2175
|
+
this.m12 = -this.m12;
|
|
2176
|
+
|
|
2177
|
+
this.m20 = -this.m20;
|
|
2178
|
+
this.m21 = -this.m21;
|
|
2179
|
+
this.m22 = -this.m22;
|
|
2180
|
+
|
|
2181
|
+
}
|
|
2182
|
+
|
|
2183
|
+
/**
|
|
2184
|
+
* Sets the value of this matrix equal to the negation of of the Matrix3d
|
|
2185
|
+
* parameter.
|
|
2186
|
+
*
|
|
2187
|
+
* @param m1
|
|
2188
|
+
* the source matrix
|
|
2189
|
+
*/
|
|
2190
|
+
public final void negate(Matrix3d m1) {
|
|
2191
|
+
this.m00 = -m1.m00;
|
|
2192
|
+
this.m01 = -m1.m01;
|
|
2193
|
+
this.m02 = -m1.m02;
|
|
2194
|
+
|
|
2195
|
+
this.m10 = -m1.m10;
|
|
2196
|
+
this.m11 = -m1.m11;
|
|
2197
|
+
this.m12 = -m1.m12;
|
|
2198
|
+
|
|
2199
|
+
this.m20 = -m1.m20;
|
|
2200
|
+
this.m21 = -m1.m21;
|
|
2201
|
+
this.m22 = -m1.m22;
|
|
2202
|
+
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2205
|
+
/**
|
|
2206
|
+
* Performs singular value decomposition normalization of this matrix.
|
|
2207
|
+
*/
|
|
2208
|
+
public final void normalize() {
|
|
2209
|
+
double[] tmp_rot = new double[9]; // scratch matrix
|
|
2210
|
+
double[] tmp_scale = new double[3]; // scratch matrix
|
|
2211
|
+
|
|
2212
|
+
getScaleRotate(tmp_scale, tmp_rot);
|
|
2213
|
+
|
|
2214
|
+
this.m00 = tmp_rot[0];
|
|
2215
|
+
this.m01 = tmp_rot[1];
|
|
2216
|
+
this.m02 = tmp_rot[2];
|
|
2217
|
+
|
|
2218
|
+
this.m10 = tmp_rot[3];
|
|
2219
|
+
this.m11 = tmp_rot[4];
|
|
2220
|
+
this.m12 = tmp_rot[5];
|
|
2221
|
+
|
|
2222
|
+
this.m20 = tmp_rot[6];
|
|
2223
|
+
this.m21 = tmp_rot[7];
|
|
2224
|
+
this.m22 = tmp_rot[8];
|
|
2225
|
+
|
|
2226
|
+
}
|
|
2227
|
+
|
|
2228
|
+
/**
|
|
2229
|
+
* Perform singular value decomposition normalization of matrix m1 and place
|
|
2230
|
+
* the normalized values into this.
|
|
2231
|
+
*
|
|
2232
|
+
* @param m1
|
|
2233
|
+
* Provides the matrix values to be normalized
|
|
2234
|
+
*/
|
|
2235
|
+
public final void normalize(Matrix3d m1) {
|
|
2236
|
+
|
|
2237
|
+
double[] tmp = new double[9]; // scratch matrix
|
|
2238
|
+
double[] tmp_rot = new double[9]; // scratch matrix
|
|
2239
|
+
double[] tmp_scale = new double[3]; // scratch matrix
|
|
2240
|
+
|
|
2241
|
+
tmp[0] = m1.m00;
|
|
2242
|
+
tmp[1] = m1.m01;
|
|
2243
|
+
tmp[2] = m1.m02;
|
|
2244
|
+
|
|
2245
|
+
tmp[3] = m1.m10;
|
|
2246
|
+
tmp[4] = m1.m11;
|
|
2247
|
+
tmp[5] = m1.m12;
|
|
2248
|
+
|
|
2249
|
+
tmp[6] = m1.m20;
|
|
2250
|
+
tmp[7] = m1.m21;
|
|
2251
|
+
tmp[8] = m1.m22;
|
|
2252
|
+
|
|
2253
|
+
compute_svd(tmp, tmp_scale, tmp_rot);
|
|
2254
|
+
|
|
2255
|
+
this.m00 = tmp_rot[0];
|
|
2256
|
+
this.m01 = tmp_rot[1];
|
|
2257
|
+
this.m02 = tmp_rot[2];
|
|
2258
|
+
|
|
2259
|
+
this.m10 = tmp_rot[3];
|
|
2260
|
+
this.m11 = tmp_rot[4];
|
|
2261
|
+
this.m12 = tmp_rot[5];
|
|
2262
|
+
|
|
2263
|
+
this.m20 = tmp_rot[6];
|
|
2264
|
+
this.m21 = tmp_rot[7];
|
|
2265
|
+
this.m22 = tmp_rot[8];
|
|
2266
|
+
}
|
|
2267
|
+
|
|
2268
|
+
/**
|
|
2269
|
+
* Perform cross product normalization of this matrix.
|
|
2270
|
+
*/
|
|
2271
|
+
|
|
2272
|
+
public final void normalizeCP() {
|
|
2273
|
+
double mag = 1.0 / Math.sqrt(m00 * m00 + m10 * m10 + m20 * m20);
|
|
2274
|
+
m00 = m00 * mag;
|
|
2275
|
+
m10 = m10 * mag;
|
|
2276
|
+
m20 = m20 * mag;
|
|
2277
|
+
|
|
2278
|
+
mag = 1.0 / Math.sqrt(m01 * m01 + m11 * m11 + m21 * m21);
|
|
2279
|
+
m01 = m01 * mag;
|
|
2280
|
+
m11 = m11 * mag;
|
|
2281
|
+
m21 = m21 * mag;
|
|
2282
|
+
|
|
2283
|
+
m02 = m10 * m21 - m11 * m20;
|
|
2284
|
+
m12 = m01 * m20 - m00 * m21;
|
|
2285
|
+
m22 = m00 * m11 - m01 * m10;
|
|
2286
|
+
}
|
|
2287
|
+
|
|
2288
|
+
/**
|
|
2289
|
+
* Perform cross product normalization of matrix m1 and place the normalized
|
|
2290
|
+
* values into this.
|
|
2291
|
+
*
|
|
2292
|
+
* @param m1
|
|
2293
|
+
* Provides the matrix values to be normalized
|
|
2294
|
+
*/
|
|
2295
|
+
public final void normalizeCP(Matrix3d m1) {
|
|
2296
|
+
double mag = 1.0 / Math.sqrt(m1.m00 * m1.m00 + m1.m10 * m1.m10 + m1.m20
|
|
2297
|
+
* m1.m20);
|
|
2298
|
+
m00 = m1.m00 * mag;
|
|
2299
|
+
m10 = m1.m10 * mag;
|
|
2300
|
+
m20 = m1.m20 * mag;
|
|
2301
|
+
|
|
2302
|
+
mag = 1.0 / Math.sqrt(m1.m01 * m1.m01 + m1.m11 * m1.m11 + m1.m21
|
|
2303
|
+
* m1.m21);
|
|
2304
|
+
m01 = m1.m01 * mag;
|
|
2305
|
+
m11 = m1.m11 * mag;
|
|
2306
|
+
m21 = m1.m21 * mag;
|
|
2307
|
+
|
|
2308
|
+
m02 = m10 * m21 - m11 * m20;
|
|
2309
|
+
m12 = m01 * m20 - m00 * m21;
|
|
2310
|
+
m22 = m00 * m11 - m01 * m10;
|
|
2311
|
+
}
|
|
2312
|
+
|
|
2313
|
+
/**
|
|
2314
|
+
* Sets the value of this matrix to a counter clockwise rotation about the x
|
|
2315
|
+
* axis.
|
|
2316
|
+
*
|
|
2317
|
+
* @param angle
|
|
2318
|
+
* the angle to rotate about the X axis in radians
|
|
2319
|
+
*/
|
|
2320
|
+
public final void rotX(double angle) {
|
|
2321
|
+
double sinAngle, cosAngle;
|
|
2322
|
+
|
|
2323
|
+
sinAngle = Math.sin(angle);
|
|
2324
|
+
cosAngle = Math.cos(angle);
|
|
2325
|
+
|
|
2326
|
+
this.m00 = 1.0;
|
|
2327
|
+
this.m01 = 0.0;
|
|
2328
|
+
this.m02 = 0.0;
|
|
2329
|
+
|
|
2330
|
+
this.m10 = 0.0;
|
|
2331
|
+
this.m11 = cosAngle;
|
|
2332
|
+
this.m12 = -sinAngle;
|
|
2333
|
+
|
|
2334
|
+
this.m20 = 0.0;
|
|
2335
|
+
this.m21 = sinAngle;
|
|
2336
|
+
this.m22 = cosAngle;
|
|
2337
|
+
}
|
|
2338
|
+
|
|
2339
|
+
/**
|
|
2340
|
+
* Sets the value of this matrix to a counter clockwise rotation about the y
|
|
2341
|
+
* axis.
|
|
2342
|
+
*
|
|
2343
|
+
* @param angle
|
|
2344
|
+
* the angle to rotate about the Y axis in radians
|
|
2345
|
+
*/
|
|
2346
|
+
public final void rotY(double angle) {
|
|
2347
|
+
double sinAngle, cosAngle;
|
|
2348
|
+
|
|
2349
|
+
sinAngle = Math.sin(angle);
|
|
2350
|
+
cosAngle = Math.cos(angle);
|
|
2351
|
+
|
|
2352
|
+
this.m00 = cosAngle;
|
|
2353
|
+
this.m01 = 0.0;
|
|
2354
|
+
this.m02 = sinAngle;
|
|
2355
|
+
|
|
2356
|
+
this.m10 = 0.0;
|
|
2357
|
+
this.m11 = 1.0;
|
|
2358
|
+
this.m12 = 0.0;
|
|
2359
|
+
|
|
2360
|
+
this.m20 = -sinAngle;
|
|
2361
|
+
this.m21 = 0.0;
|
|
2362
|
+
this.m22 = cosAngle;
|
|
2363
|
+
}
|
|
2364
|
+
|
|
2365
|
+
/**
|
|
2366
|
+
* Sets the value of this matrix to a counter clockwise rotation about the z
|
|
2367
|
+
* axis.
|
|
2368
|
+
*
|
|
2369
|
+
* @param angle
|
|
2370
|
+
* the angle to rotate about the Z axis in radians
|
|
2371
|
+
*/
|
|
2372
|
+
public final void rotZ(double angle) {
|
|
2373
|
+
double sinAngle, cosAngle;
|
|
2374
|
+
|
|
2375
|
+
sinAngle = Math.sin(angle);
|
|
2376
|
+
cosAngle = Math.cos(angle);
|
|
2377
|
+
|
|
2378
|
+
this.m00 = cosAngle;
|
|
2379
|
+
this.m01 = -sinAngle;
|
|
2380
|
+
this.m02 = 0.0;
|
|
2381
|
+
|
|
2382
|
+
this.m10 = sinAngle;
|
|
2383
|
+
this.m11 = cosAngle;
|
|
2384
|
+
this.m12 = 0.0;
|
|
2385
|
+
|
|
2386
|
+
this.m20 = 0.0;
|
|
2387
|
+
this.m21 = 0.0;
|
|
2388
|
+
this.m22 = 1.0;
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2391
|
+
/**
|
|
2392
|
+
* Sets the value of this matrix to a scale matrix with the passed scale
|
|
2393
|
+
* amount.
|
|
2394
|
+
*
|
|
2395
|
+
* @param scale
|
|
2396
|
+
* the scale factor for the matrix
|
|
2397
|
+
*/
|
|
2398
|
+
public final void set(double scale) {
|
|
2399
|
+
this.m00 = scale;
|
|
2400
|
+
this.m01 = 0.0;
|
|
2401
|
+
this.m02 = 0.0;
|
|
2402
|
+
|
|
2403
|
+
this.m10 = 0.0;
|
|
2404
|
+
this.m11 = scale;
|
|
2405
|
+
this.m12 = 0.0;
|
|
2406
|
+
|
|
2407
|
+
this.m20 = 0.0;
|
|
2408
|
+
this.m21 = 0.0;
|
|
2409
|
+
this.m22 = scale;
|
|
2410
|
+
}
|
|
2411
|
+
|
|
2412
|
+
/**
|
|
2413
|
+
* Sets the values in this Matrix3d equal to the row-major array parameter
|
|
2414
|
+
* (ie, the first three elements of the array will be copied into the first
|
|
2415
|
+
* row of this matrix, etc.).
|
|
2416
|
+
*
|
|
2417
|
+
* @param m
|
|
2418
|
+
* the double precision array of length 9
|
|
2419
|
+
*/
|
|
2420
|
+
public final void set(double[] m) {
|
|
2421
|
+
m00 = m[0];
|
|
2422
|
+
m01 = m[1];
|
|
2423
|
+
m02 = m[2];
|
|
2424
|
+
|
|
2425
|
+
m10 = m[3];
|
|
2426
|
+
m11 = m[4];
|
|
2427
|
+
m12 = m[5];
|
|
2428
|
+
|
|
2429
|
+
m20 = m[6];
|
|
2430
|
+
m21 = m[7];
|
|
2431
|
+
m22 = m[8];
|
|
2432
|
+
|
|
2433
|
+
}
|
|
2434
|
+
|
|
2435
|
+
/**
|
|
2436
|
+
* Sets the value of this matrix to the value of the Matrix3d argument.
|
|
2437
|
+
*
|
|
2438
|
+
* @param m1
|
|
2439
|
+
* the source matrix3d
|
|
2440
|
+
*/
|
|
2441
|
+
public final void set(Matrix3d m1) {
|
|
2442
|
+
this.m00 = m1.m00;
|
|
2443
|
+
this.m01 = m1.m01;
|
|
2444
|
+
this.m02 = m1.m02;
|
|
2445
|
+
|
|
2446
|
+
this.m10 = m1.m10;
|
|
2447
|
+
this.m11 = m1.m11;
|
|
2448
|
+
this.m12 = m1.m12;
|
|
2449
|
+
|
|
2450
|
+
this.m20 = m1.m20;
|
|
2451
|
+
this.m21 = m1.m21;
|
|
2452
|
+
this.m22 = m1.m22;
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2455
|
+
/**
|
|
2456
|
+
* Sets the value of this matrix to the matrix conversion of the single
|
|
2457
|
+
* precision quaternion argument.
|
|
2458
|
+
*
|
|
2459
|
+
* @param q1
|
|
2460
|
+
* the quaternion to be converted
|
|
2461
|
+
*/
|
|
2462
|
+
public final void set(Quaternion q1) {
|
|
2463
|
+
this.m00 = (1.0 - 2.0 * q1.y * q1.y - 2.0 * q1.z * q1.z);
|
|
2464
|
+
this.m10 = (2.0 * (q1.x * q1.y + q1.w * q1.z));
|
|
2465
|
+
this.m20 = (2.0 * (q1.x * q1.z - q1.w * q1.y));
|
|
2466
|
+
|
|
2467
|
+
this.m01 = (2.0 * (q1.x * q1.y - q1.w * q1.z));
|
|
2468
|
+
this.m11 = (1.0 - 2.0 * q1.x * q1.x - 2.0 * q1.z * q1.z);
|
|
2469
|
+
this.m21 = (2.0 * (q1.y * q1.z + q1.w * q1.x));
|
|
2470
|
+
|
|
2471
|
+
this.m02 = (2.0 * (q1.x * q1.z + q1.w * q1.y));
|
|
2472
|
+
this.m12 = (2.0 * (q1.y * q1.z - q1.w * q1.x));
|
|
2473
|
+
this.m22 = (1.0 - 2.0 * q1.x * q1.x - 2.0 * q1.y * q1.y);
|
|
2474
|
+
}
|
|
2475
|
+
|
|
2476
|
+
/**
|
|
2477
|
+
* Sets the specified column of this matrix3d to the three values provided.
|
|
2478
|
+
*
|
|
2479
|
+
* @param column
|
|
2480
|
+
* the column number to be modified (zero indexed)
|
|
2481
|
+
* @param v
|
|
2482
|
+
* the replacement column
|
|
2483
|
+
*/
|
|
2484
|
+
public final void setColumn(int column, double v[]) {
|
|
2485
|
+
switch (column) {
|
|
2486
|
+
case 0:
|
|
2487
|
+
this.m00 = v[0];
|
|
2488
|
+
this.m10 = v[1];
|
|
2489
|
+
this.m20 = v[2];
|
|
2490
|
+
break;
|
|
2491
|
+
|
|
2492
|
+
case 1:
|
|
2493
|
+
this.m01 = v[0];
|
|
2494
|
+
this.m11 = v[1];
|
|
2495
|
+
this.m21 = v[2];
|
|
2496
|
+
break;
|
|
2497
|
+
|
|
2498
|
+
case 2:
|
|
2499
|
+
this.m02 = v[0];
|
|
2500
|
+
this.m12 = v[1];
|
|
2501
|
+
this.m22 = v[2];
|
|
2502
|
+
break;
|
|
2503
|
+
|
|
2504
|
+
default:
|
|
2505
|
+
throw new ArrayIndexOutOfBoundsException();
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
|
|
2509
|
+
/**
|
|
2510
|
+
* Sets the specified column of this matrix3d to the three values provided.
|
|
2511
|
+
*
|
|
2512
|
+
* @param column
|
|
2513
|
+
* the column number to be modified (zero indexed)
|
|
2514
|
+
* @param x
|
|
2515
|
+
* the first row element
|
|
2516
|
+
* @param y
|
|
2517
|
+
* the second row element
|
|
2518
|
+
* @param z
|
|
2519
|
+
* the third row element
|
|
2520
|
+
*/
|
|
2521
|
+
public final void setColumn(int column, double x, double y, double z) {
|
|
2522
|
+
switch (column) {
|
|
2523
|
+
case 0:
|
|
2524
|
+
this.m00 = x;
|
|
2525
|
+
this.m10 = y;
|
|
2526
|
+
this.m20 = z;
|
|
2527
|
+
break;
|
|
2528
|
+
|
|
2529
|
+
case 1:
|
|
2530
|
+
this.m01 = x;
|
|
2531
|
+
this.m11 = y;
|
|
2532
|
+
this.m21 = z;
|
|
2533
|
+
break;
|
|
2534
|
+
|
|
2535
|
+
case 2:
|
|
2536
|
+
this.m02 = x;
|
|
2537
|
+
this.m12 = y;
|
|
2538
|
+
this.m22 = z;
|
|
2539
|
+
break;
|
|
2540
|
+
|
|
2541
|
+
default:
|
|
2542
|
+
throw new ArrayIndexOutOfBoundsException();
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2546
|
+
/**
|
|
2547
|
+
* Sets the specified column of this matrix3d to the vector provided.
|
|
2548
|
+
*
|
|
2549
|
+
* @param column
|
|
2550
|
+
* the column number to be modified (zero indexed)
|
|
2551
|
+
* @param v
|
|
2552
|
+
* the replacement column
|
|
2553
|
+
*/
|
|
2554
|
+
public final void setColumn(int column, Vec3D v) {
|
|
2555
|
+
switch (column) {
|
|
2556
|
+
case 0:
|
|
2557
|
+
this.m00 = v.x;
|
|
2558
|
+
this.m10 = v.y;
|
|
2559
|
+
this.m20 = v.z;
|
|
2560
|
+
break;
|
|
2561
|
+
|
|
2562
|
+
case 1:
|
|
2563
|
+
this.m01 = v.x;
|
|
2564
|
+
this.m11 = v.y;
|
|
2565
|
+
this.m21 = v.z;
|
|
2566
|
+
break;
|
|
2567
|
+
|
|
2568
|
+
case 2:
|
|
2569
|
+
this.m02 = v.x;
|
|
2570
|
+
this.m12 = v.y;
|
|
2571
|
+
this.m22 = v.z;
|
|
2572
|
+
break;
|
|
2573
|
+
|
|
2574
|
+
default:
|
|
2575
|
+
throw new ArrayIndexOutOfBoundsException();
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
|
|
2579
|
+
/**
|
|
2580
|
+
* Sets the specified element of this matrix3f to the value provided.
|
|
2581
|
+
*
|
|
2582
|
+
* @param row
|
|
2583
|
+
* the row number to be modified (zero indexed)
|
|
2584
|
+
* @param column
|
|
2585
|
+
* the column number to be modified (zero indexed)
|
|
2586
|
+
* @param value
|
|
2587
|
+
* the new value
|
|
2588
|
+
*/
|
|
2589
|
+
public final void setElement(int row, int column, double value) {
|
|
2590
|
+
switch (row) {
|
|
2591
|
+
case 0:
|
|
2592
|
+
switch (column) {
|
|
2593
|
+
case 0:
|
|
2594
|
+
this.m00 = value;
|
|
2595
|
+
break;
|
|
2596
|
+
case 1:
|
|
2597
|
+
this.m01 = value;
|
|
2598
|
+
break;
|
|
2599
|
+
case 2:
|
|
2600
|
+
this.m02 = value;
|
|
2601
|
+
break;
|
|
2602
|
+
default:
|
|
2603
|
+
throw new ArrayIndexOutOfBoundsException();
|
|
2604
|
+
}
|
|
2605
|
+
break;
|
|
2606
|
+
|
|
2607
|
+
case 1:
|
|
2608
|
+
switch (column) {
|
|
2609
|
+
case 0:
|
|
2610
|
+
this.m10 = value;
|
|
2611
|
+
break;
|
|
2612
|
+
case 1:
|
|
2613
|
+
this.m11 = value;
|
|
2614
|
+
break;
|
|
2615
|
+
case 2:
|
|
2616
|
+
this.m12 = value;
|
|
2617
|
+
break;
|
|
2618
|
+
default:
|
|
2619
|
+
throw new ArrayIndexOutOfBoundsException();
|
|
2620
|
+
}
|
|
2621
|
+
break;
|
|
2622
|
+
|
|
2623
|
+
case 2:
|
|
2624
|
+
switch (column) {
|
|
2625
|
+
case 0:
|
|
2626
|
+
this.m20 = value;
|
|
2627
|
+
break;
|
|
2628
|
+
case 1:
|
|
2629
|
+
this.m21 = value;
|
|
2630
|
+
break;
|
|
2631
|
+
case 2:
|
|
2632
|
+
this.m22 = value;
|
|
2633
|
+
break;
|
|
2634
|
+
default:
|
|
2635
|
+
throw new ArrayIndexOutOfBoundsException();
|
|
2636
|
+
}
|
|
2637
|
+
break;
|
|
2638
|
+
|
|
2639
|
+
default:
|
|
2640
|
+
throw new ArrayIndexOutOfBoundsException();
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
|
|
2644
|
+
/**
|
|
2645
|
+
* Sets this Matrix3d to identity.
|
|
2646
|
+
*/
|
|
2647
|
+
public final void setIdentity() {
|
|
2648
|
+
this.m00 = 1.0;
|
|
2649
|
+
this.m01 = 0.0;
|
|
2650
|
+
this.m02 = 0.0;
|
|
2651
|
+
|
|
2652
|
+
this.m10 = 0.0;
|
|
2653
|
+
this.m11 = 1.0;
|
|
2654
|
+
this.m12 = 0.0;
|
|
2655
|
+
|
|
2656
|
+
this.m20 = 0.0;
|
|
2657
|
+
this.m21 = 0.0;
|
|
2658
|
+
this.m22 = 1.0;
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2661
|
+
/**
|
|
2662
|
+
* Set the first matrix element in the first row.
|
|
2663
|
+
*
|
|
2664
|
+
* @param m00
|
|
2665
|
+
* The m00 to set.
|
|
2666
|
+
*
|
|
2667
|
+
* @since vecmath 1.5
|
|
2668
|
+
*/
|
|
2669
|
+
public final void setM00(double m00) {
|
|
2670
|
+
this.m00 = m00;
|
|
2671
|
+
}
|
|
2672
|
+
|
|
2673
|
+
/**
|
|
2674
|
+
* Set the second matrix element in the first row.
|
|
2675
|
+
*
|
|
2676
|
+
* @param m01
|
|
2677
|
+
* The m01 to set.
|
|
2678
|
+
*
|
|
2679
|
+
* @since vecmath 1.5
|
|
2680
|
+
*/
|
|
2681
|
+
public final void setM01(double m01) {
|
|
2682
|
+
this.m01 = m01;
|
|
2683
|
+
}
|
|
2684
|
+
|
|
2685
|
+
/**
|
|
2686
|
+
* Set the third matrix element in the first row.
|
|
2687
|
+
*
|
|
2688
|
+
* @param m02
|
|
2689
|
+
* The m02 to set.
|
|
2690
|
+
*
|
|
2691
|
+
* @since vecmath 1.5
|
|
2692
|
+
*/
|
|
2693
|
+
public final void setM02(double m02) {
|
|
2694
|
+
this.m02 = m02;
|
|
2695
|
+
}
|
|
2696
|
+
|
|
2697
|
+
/**
|
|
2698
|
+
* Set first matrix element in the second row.
|
|
2699
|
+
*
|
|
2700
|
+
* @param m10
|
|
2701
|
+
* The m10 to set.
|
|
2702
|
+
*
|
|
2703
|
+
* @since vecmath 1.5
|
|
2704
|
+
*/
|
|
2705
|
+
public final void setM10(double m10) {
|
|
2706
|
+
this.m10 = m10;
|
|
2707
|
+
}
|
|
2708
|
+
|
|
2709
|
+
/**
|
|
2710
|
+
* Set the second matrix element in the second row.
|
|
2711
|
+
*
|
|
2712
|
+
* @param m11
|
|
2713
|
+
* The m11 to set.
|
|
2714
|
+
*
|
|
2715
|
+
* @since vecmath 1.5
|
|
2716
|
+
*/
|
|
2717
|
+
public final void setM11(double m11) {
|
|
2718
|
+
this.m11 = m11;
|
|
2719
|
+
}
|
|
2720
|
+
|
|
2721
|
+
/**
|
|
2722
|
+
* Set the third matrix element in the second row.
|
|
2723
|
+
*
|
|
2724
|
+
* @param m12
|
|
2725
|
+
* The m12 to set.
|
|
2726
|
+
*
|
|
2727
|
+
* @since vecmath 1.5
|
|
2728
|
+
*/
|
|
2729
|
+
public final void setM12(double m12) {
|
|
2730
|
+
this.m12 = m12;
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2733
|
+
/**
|
|
2734
|
+
* Set the first matrix element in the third row.
|
|
2735
|
+
*
|
|
2736
|
+
* @param m20
|
|
2737
|
+
* The m20 to set.
|
|
2738
|
+
*
|
|
2739
|
+
* @since vecmath 1.5
|
|
2740
|
+
*/
|
|
2741
|
+
public final void setM20(double m20) {
|
|
2742
|
+
this.m20 = m20;
|
|
2743
|
+
}
|
|
2744
|
+
|
|
2745
|
+
/**
|
|
2746
|
+
* Set the second matrix element in the third row.
|
|
2747
|
+
*
|
|
2748
|
+
* @param m21
|
|
2749
|
+
* The m21 to set.
|
|
2750
|
+
*
|
|
2751
|
+
* @since vecmath 1.5
|
|
2752
|
+
*/
|
|
2753
|
+
public final void setM21(double m21) {
|
|
2754
|
+
this.m21 = m21;
|
|
2755
|
+
}
|
|
2756
|
+
|
|
2757
|
+
/**
|
|
2758
|
+
* Set the third matrix element in the third row.
|
|
2759
|
+
*
|
|
2760
|
+
* @param m22
|
|
2761
|
+
* The m22 to set.
|
|
2762
|
+
*
|
|
2763
|
+
* @since vecmath 1.5
|
|
2764
|
+
*/
|
|
2765
|
+
public final void setM22(double m22) {
|
|
2766
|
+
this.m22 = m22;
|
|
2767
|
+
}
|
|
2768
|
+
|
|
2769
|
+
/**
|
|
2770
|
+
* Sets the specified row of this matrix3d to the three values provided.
|
|
2771
|
+
*
|
|
2772
|
+
* @param row
|
|
2773
|
+
* the row number to be modified (zero indexed)
|
|
2774
|
+
* @param v
|
|
2775
|
+
* the replacement row
|
|
2776
|
+
*/
|
|
2777
|
+
public final void setRow(int row, double v[]) {
|
|
2778
|
+
switch (row) {
|
|
2779
|
+
case 0:
|
|
2780
|
+
this.m00 = v[0];
|
|
2781
|
+
this.m01 = v[1];
|
|
2782
|
+
this.m02 = v[2];
|
|
2783
|
+
break;
|
|
2784
|
+
|
|
2785
|
+
case 1:
|
|
2786
|
+
this.m10 = v[0];
|
|
2787
|
+
this.m11 = v[1];
|
|
2788
|
+
this.m12 = v[2];
|
|
2789
|
+
break;
|
|
2790
|
+
|
|
2791
|
+
case 2:
|
|
2792
|
+
this.m20 = v[0];
|
|
2793
|
+
this.m21 = v[1];
|
|
2794
|
+
this.m22 = v[2];
|
|
2795
|
+
break;
|
|
2796
|
+
|
|
2797
|
+
default:
|
|
2798
|
+
throw new ArrayIndexOutOfBoundsException();
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2801
|
+
|
|
2802
|
+
/**
|
|
2803
|
+
* Sets the specified row of this matrix3d to the 4 values provided.
|
|
2804
|
+
*
|
|
2805
|
+
* @param row
|
|
2806
|
+
* the row number to be modified (zero indexed)
|
|
2807
|
+
* @param x
|
|
2808
|
+
* the first column element
|
|
2809
|
+
* @param y
|
|
2810
|
+
* the second column element
|
|
2811
|
+
* @param z
|
|
2812
|
+
* the third column element
|
|
2813
|
+
*/
|
|
2814
|
+
public final void setRow(int row, double x, double y, double z) {
|
|
2815
|
+
switch (row) {
|
|
2816
|
+
case 0:
|
|
2817
|
+
this.m00 = x;
|
|
2818
|
+
this.m01 = y;
|
|
2819
|
+
this.m02 = z;
|
|
2820
|
+
break;
|
|
2821
|
+
|
|
2822
|
+
case 1:
|
|
2823
|
+
this.m10 = x;
|
|
2824
|
+
this.m11 = y;
|
|
2825
|
+
this.m12 = z;
|
|
2826
|
+
break;
|
|
2827
|
+
|
|
2828
|
+
case 2:
|
|
2829
|
+
this.m20 = x;
|
|
2830
|
+
this.m21 = y;
|
|
2831
|
+
this.m22 = z;
|
|
2832
|
+
break;
|
|
2833
|
+
|
|
2834
|
+
default:
|
|
2835
|
+
throw new ArrayIndexOutOfBoundsException();
|
|
2836
|
+
}
|
|
2837
|
+
}
|
|
2838
|
+
|
|
2839
|
+
/**
|
|
2840
|
+
* Sets the specified row of this matrix3d to the Vector provided.
|
|
2841
|
+
*
|
|
2842
|
+
* @param row
|
|
2843
|
+
* the row number to be modified (zero indexed)
|
|
2844
|
+
* @param v
|
|
2845
|
+
* the replacement row
|
|
2846
|
+
*/
|
|
2847
|
+
public final void setRow(int row, Vec3D v) {
|
|
2848
|
+
switch (row) {
|
|
2849
|
+
case 0:
|
|
2850
|
+
this.m00 = v.x;
|
|
2851
|
+
this.m01 = v.y;
|
|
2852
|
+
this.m02 = v.z;
|
|
2853
|
+
break;
|
|
2854
|
+
|
|
2855
|
+
case 1:
|
|
2856
|
+
this.m10 = v.x;
|
|
2857
|
+
this.m11 = v.y;
|
|
2858
|
+
this.m12 = v.z;
|
|
2859
|
+
break;
|
|
2860
|
+
|
|
2861
|
+
case 2:
|
|
2862
|
+
this.m20 = v.x;
|
|
2863
|
+
this.m21 = v.y;
|
|
2864
|
+
this.m22 = v.z;
|
|
2865
|
+
break;
|
|
2866
|
+
|
|
2867
|
+
default:
|
|
2868
|
+
throw new ArrayIndexOutOfBoundsException();
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
|
|
2872
|
+
/**
|
|
2873
|
+
* Sets the scale component of the current matrix by factoring out the
|
|
2874
|
+
* current scale (by doing an SVD) and multiplying by the new scale.
|
|
2875
|
+
*
|
|
2876
|
+
* @param scale
|
|
2877
|
+
* the new scale amount
|
|
2878
|
+
*/
|
|
2879
|
+
public final void setScale(double scale) {
|
|
2880
|
+
|
|
2881
|
+
double[] tmp_rot = new double[9]; // scratch matrix
|
|
2882
|
+
double[] tmp_scale = new double[3]; // scratch matrix
|
|
2883
|
+
|
|
2884
|
+
getScaleRotate(tmp_scale, tmp_rot);
|
|
2885
|
+
|
|
2886
|
+
this.m00 = tmp_rot[0] * scale;
|
|
2887
|
+
this.m01 = tmp_rot[1] * scale;
|
|
2888
|
+
this.m02 = tmp_rot[2] * scale;
|
|
2889
|
+
|
|
2890
|
+
this.m10 = tmp_rot[3] * scale;
|
|
2891
|
+
this.m11 = tmp_rot[4] * scale;
|
|
2892
|
+
this.m12 = tmp_rot[5] * scale;
|
|
2893
|
+
|
|
2894
|
+
this.m20 = tmp_rot[6] * scale;
|
|
2895
|
+
this.m21 = tmp_rot[7] * scale;
|
|
2896
|
+
this.m22 = tmp_rot[8] * scale;
|
|
2897
|
+
}
|
|
2898
|
+
|
|
2899
|
+
/**
|
|
2900
|
+
* Sets this matrix to all zeros.
|
|
2901
|
+
*/
|
|
2902
|
+
public final void setZero() {
|
|
2903
|
+
m00 = 0.0;
|
|
2904
|
+
m01 = 0.0;
|
|
2905
|
+
m02 = 0.0;
|
|
2906
|
+
|
|
2907
|
+
m10 = 0.0;
|
|
2908
|
+
m11 = 0.0;
|
|
2909
|
+
m12 = 0.0;
|
|
2910
|
+
|
|
2911
|
+
m20 = 0.0;
|
|
2912
|
+
m21 = 0.0;
|
|
2913
|
+
m22 = 0.0;
|
|
2914
|
+
|
|
2915
|
+
}
|
|
2916
|
+
|
|
2917
|
+
/**
|
|
2918
|
+
* Sets the value of this matrix to the matrix difference of itself and
|
|
2919
|
+
* matrix m1 (this = this - m1).
|
|
2920
|
+
*
|
|
2921
|
+
* @param m1
|
|
2922
|
+
* the other matrix
|
|
2923
|
+
*/
|
|
2924
|
+
public final void sub(Matrix3d m1) {
|
|
2925
|
+
this.m00 -= m1.m00;
|
|
2926
|
+
this.m01 -= m1.m01;
|
|
2927
|
+
this.m02 -= m1.m02;
|
|
2928
|
+
|
|
2929
|
+
this.m10 -= m1.m10;
|
|
2930
|
+
this.m11 -= m1.m11;
|
|
2931
|
+
this.m12 -= m1.m12;
|
|
2932
|
+
|
|
2933
|
+
this.m20 -= m1.m20;
|
|
2934
|
+
this.m21 -= m1.m21;
|
|
2935
|
+
this.m22 -= m1.m22;
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2938
|
+
/**
|
|
2939
|
+
* Sets the value of this matrix to the matrix difference of matrices m1 and
|
|
2940
|
+
* m2.
|
|
2941
|
+
*
|
|
2942
|
+
* @param m1
|
|
2943
|
+
* the first matrix
|
|
2944
|
+
* @param m2
|
|
2945
|
+
* the second matrix
|
|
2946
|
+
*/
|
|
2947
|
+
public final void sub(Matrix3d m1, Matrix3d m2) {
|
|
2948
|
+
this.m00 = m1.m00 - m2.m00;
|
|
2949
|
+
this.m01 = m1.m01 - m2.m01;
|
|
2950
|
+
this.m02 = m1.m02 - m2.m02;
|
|
2951
|
+
|
|
2952
|
+
this.m10 = m1.m10 - m2.m10;
|
|
2953
|
+
this.m11 = m1.m11 - m2.m11;
|
|
2954
|
+
this.m12 = m1.m12 - m2.m12;
|
|
2955
|
+
|
|
2956
|
+
this.m20 = m1.m20 - m2.m20;
|
|
2957
|
+
this.m21 = m1.m21 - m2.m21;
|
|
2958
|
+
this.m22 = m1.m22 - m2.m22;
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2961
|
+
/**
|
|
2962
|
+
* Returns a string that contains the values of this Matrix3d.
|
|
2963
|
+
*
|
|
2964
|
+
* @return the String representation
|
|
2965
|
+
*/
|
|
2966
|
+
@Override
|
|
2967
|
+
public String toString() {
|
|
2968
|
+
return this.m00 + ", " + this.m01 + ", " + this.m02 + "\n" + this.m10
|
|
2969
|
+
+ ", " + this.m11 + ", " + this.m12 + "\n" + this.m20 + ", "
|
|
2970
|
+
+ this.m21 + ", " + this.m22 + "\n";
|
|
2971
|
+
}
|
|
2972
|
+
|
|
2973
|
+
/**
|
|
2974
|
+
* Multiply this matrix by the tuple t and place the result back into the
|
|
2975
|
+
* tuple (t = this*t).
|
|
2976
|
+
*
|
|
2977
|
+
* @param t
|
|
2978
|
+
* the tuple to be multiplied by this matrix and then replaced
|
|
2979
|
+
*/
|
|
2980
|
+
public final void transform(Vec3D t) {
|
|
2981
|
+
float x, y, z;
|
|
2982
|
+
x = (float) (m00 * t.x + m01 * t.y + m02 * t.z);
|
|
2983
|
+
y = (float) (m10 * t.x + m11 * t.y + m12 * t.z);
|
|
2984
|
+
z = (float) (m20 * t.x + m21 * t.y + m22 * t.z);
|
|
2985
|
+
t.set(x, y, z);
|
|
2986
|
+
}
|
|
2987
|
+
|
|
2988
|
+
/**
|
|
2989
|
+
* Multiply this matrix by the tuple t and and place the result into the
|
|
2990
|
+
* tuple "result" (result = this*t).
|
|
2991
|
+
*
|
|
2992
|
+
* @param t
|
|
2993
|
+
* the tuple to be multiplied by this matrix
|
|
2994
|
+
* @param result
|
|
2995
|
+
* the tuple into which the product is placed
|
|
2996
|
+
*/
|
|
2997
|
+
public final void transform(Vec3D t, Vec3D result) {
|
|
2998
|
+
float x, y, z;
|
|
2999
|
+
x = (float) (m00 * t.x + m01 * t.y + m02 * t.z);
|
|
3000
|
+
y = (float) (m10 * t.x + m11 * t.y + m12 * t.z);
|
|
3001
|
+
result.z = (float) (m20 * t.x + m21 * t.y + m22 * t.z);
|
|
3002
|
+
result.x = x;
|
|
3003
|
+
result.y = y;
|
|
3004
|
+
}
|
|
3005
|
+
|
|
3006
|
+
/**
|
|
3007
|
+
* Sets the value of this matrix to its transpose.
|
|
3008
|
+
*/
|
|
3009
|
+
public final void transpose() {
|
|
3010
|
+
double temp;
|
|
3011
|
+
|
|
3012
|
+
temp = this.m10;
|
|
3013
|
+
this.m10 = this.m01;
|
|
3014
|
+
this.m01 = temp;
|
|
3015
|
+
|
|
3016
|
+
temp = this.m20;
|
|
3017
|
+
this.m20 = this.m02;
|
|
3018
|
+
this.m02 = temp;
|
|
3019
|
+
|
|
3020
|
+
temp = this.m21;
|
|
3021
|
+
this.m21 = this.m12;
|
|
3022
|
+
this.m12 = temp;
|
|
3023
|
+
}
|
|
3024
|
+
|
|
3025
|
+
/**
|
|
3026
|
+
* Sets the value of this matrix to the transpose of the argument matrix.
|
|
3027
|
+
*
|
|
3028
|
+
* @param m1
|
|
3029
|
+
* the matrix to be transposed
|
|
3030
|
+
*/
|
|
3031
|
+
public final void transpose(Matrix3d m1) {
|
|
3032
|
+
if (this != m1) {
|
|
3033
|
+
this.m00 = m1.m00;
|
|
3034
|
+
this.m01 = m1.m10;
|
|
3035
|
+
this.m02 = m1.m20;
|
|
3036
|
+
|
|
3037
|
+
this.m10 = m1.m01;
|
|
3038
|
+
this.m11 = m1.m11;
|
|
3039
|
+
this.m12 = m1.m21;
|
|
3040
|
+
|
|
3041
|
+
this.m20 = m1.m02;
|
|
3042
|
+
this.m21 = m1.m12;
|
|
3043
|
+
this.m22 = m1.m22;
|
|
3044
|
+
} else {
|
|
3045
|
+
this.transpose();
|
|
3046
|
+
}
|
|
3047
|
+
}
|
|
3048
|
+
}
|