toxiclibs 0.2-java → 0.5.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (383) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +16 -0
  3. data/CHANGELOG.md +4 -0
  4. data/LICENSE +675 -0
  5. data/README.md +12 -5
  6. data/Rakefile +25 -82
  7. data/examples/attract_repel/attract_repel.rb +30 -0
  8. data/examples/attract_repel/attractor.rb +23 -0
  9. data/examples/attract_repel/particle.rb +27 -0
  10. data/examples/data/ti_yong.png +0 -0
  11. data/examples/force_directed/cluster.rb +76 -0
  12. data/examples/force_directed/force_directed_graph.rb +92 -0
  13. data/examples/force_directed/node.rb +26 -0
  14. data/examples/gray_scott_image.rb +75 -0
  15. data/examples/gray_scott_tone_map.rb +77 -0
  16. data/examples/implicit.rb +139 -0
  17. data/examples/inflate_mesh.rb +89 -0
  18. data/examples/model_align.rb +44 -0
  19. data/examples/povmesh/ftest.rb +46 -0
  20. data/examples/povmesh/tentacle.rb +73 -0
  21. data/examples/simple_cluster/cluster.rb +47 -0
  22. data/examples/simple_cluster/node.rb +27 -0
  23. data/examples/simple_cluster/simple_cluster.rb +60 -0
  24. data/examples/soft_body/blanket.rb +45 -0
  25. data/examples/soft_body/connection.rb +16 -0
  26. data/examples/soft_body/particle.rb +22 -0
  27. data/examples/soft_body/soft_body_square_adapted.rb +55 -0
  28. data/lib/toxiclibs.jar +0 -0
  29. data/lib/toxiclibs.rb +91 -32
  30. data/lib/toxiclibs/version.rb +1 -1
  31. data/pom.xml +122 -0
  32. data/src/com/toxi/net/ClientListener.java +41 -0
  33. data/src/com/toxi/net/ServerListener.java +70 -0
  34. data/src/com/toxi/net/ServerListenerAdapter.java +47 -0
  35. data/src/com/toxi/net/ServerState.java +18 -0
  36. data/src/com/toxi/net/UDPConnection.java +66 -0
  37. data/src/com/toxi/net/UDPSyncClient.java +81 -0
  38. data/src/com/toxi/net/UDPSyncServer.java +450 -0
  39. data/src/com/toxi/nio/UDPClient.java +121 -0
  40. data/src/com/toxi/nio/UDPClientState.java +32 -0
  41. data/src/com/toxi/nio/UDPServer.java +129 -0
  42. data/src/toxi/color/AccessCriteria.java +114 -0
  43. data/src/toxi/color/AlphaAccessor.java +67 -0
  44. data/src/toxi/color/CMYKAccessor.java +122 -0
  45. data/src/toxi/color/CMYKDistanceProxy.java +40 -0
  46. data/src/toxi/color/ColorGradient.java +260 -0
  47. data/src/toxi/color/ColorList.java +699 -0
  48. data/src/toxi/color/ColorRange.java +671 -0
  49. data/src/toxi/color/ColorTheme.java +163 -0
  50. data/src/toxi/color/DistanceProxy.java +44 -0
  51. data/src/toxi/color/HSVAccessor.java +113 -0
  52. data/src/toxi/color/HSVDistanceProxy.java +40 -0
  53. data/src/toxi/color/HistEntry.java +85 -0
  54. data/src/toxi/color/Histogram.java +185 -0
  55. data/src/toxi/color/Hue.java +249 -0
  56. data/src/toxi/color/LuminanceAccessor.java +78 -0
  57. data/src/toxi/color/NamedColor.java +935 -0
  58. data/src/toxi/color/ProximityComparator.java +70 -0
  59. data/src/toxi/color/RGBAccessor.java +113 -0
  60. data/src/toxi/color/RGBDistanceProxy.java +41 -0
  61. data/src/toxi/color/ReadonlyTColor.java +296 -0
  62. data/src/toxi/color/TColor.java +1677 -0
  63. data/src/toxi/color/TColorAdapter.java +68 -0
  64. data/src/toxi/color/ToneMap.java +218 -0
  65. data/src/toxi/color/theory/AnalogousStrategy.java +140 -0
  66. data/src/toxi/color/theory/ColorTheoryRegistry.java +139 -0
  67. data/src/toxi/color/theory/ColorTheoryStrategy.java +56 -0
  68. data/src/toxi/color/theory/ComplementaryStrategy.java +111 -0
  69. data/src/toxi/color/theory/CompoundTheoryStrategy.java +143 -0
  70. data/src/toxi/color/theory/LeftSplitComplementaryStrategy.java +82 -0
  71. data/src/toxi/color/theory/MonochromeTheoryStrategy.java +103 -0
  72. data/src/toxi/color/theory/RightSplitComplementaryStrategy.java +82 -0
  73. data/src/toxi/color/theory/SingleComplementStrategy.java +76 -0
  74. data/src/toxi/color/theory/SplitComplementaryStrategy.java +77 -0
  75. data/src/toxi/color/theory/TetradTheoryStrategy.java +114 -0
  76. data/src/toxi/color/theory/TriadTheoryStrategy.java +77 -0
  77. data/src/toxi/data/csv/CSVAdapter.java +74 -0
  78. data/src/toxi/data/csv/CSVFieldMapper.java +212 -0
  79. data/src/toxi/data/csv/CSVListener.java +61 -0
  80. data/src/toxi/data/csv/CSVParser.java +202 -0
  81. data/src/toxi/data/feeds/AtomAuthor.java +49 -0
  82. data/src/toxi/data/feeds/AtomContent.java +50 -0
  83. data/src/toxi/data/feeds/AtomEntry.java +111 -0
  84. data/src/toxi/data/feeds/AtomFeed.java +129 -0
  85. data/src/toxi/data/feeds/AtomLink.java +62 -0
  86. data/src/toxi/data/feeds/RSSChannel.java +88 -0
  87. data/src/toxi/data/feeds/RSSEnclosure.java +60 -0
  88. data/src/toxi/data/feeds/RSSFeed.java +99 -0
  89. data/src/toxi/data/feeds/RSSItem.java +104 -0
  90. data/src/toxi/data/feeds/util/EntityStripper.java +2480 -0
  91. data/src/toxi/data/feeds/util/Iso8601DateAdapter.java +101 -0
  92. data/src/toxi/data/feeds/util/Rfc822DateAdapter.java +93 -0
  93. data/src/toxi/geom/AABB.java +658 -0
  94. data/src/toxi/geom/Axis3D.java +116 -0
  95. data/src/toxi/geom/AxisAlignedCylinder.java +163 -0
  96. data/src/toxi/geom/BernsteinPolynomial.java +94 -0
  97. data/src/toxi/geom/BezierCurve2D.java +159 -0
  98. data/src/toxi/geom/BezierCurve3D.java +148 -0
  99. data/src/toxi/geom/BooleanShapeBuilder.java +185 -0
  100. data/src/toxi/geom/BoxIntersector.java +52 -0
  101. data/src/toxi/geom/Circle.java +230 -0
  102. data/src/toxi/geom/CircleIntersector.java +85 -0
  103. data/src/toxi/geom/Cone.java +150 -0
  104. data/src/toxi/geom/ConvexPolygonClipper.java +136 -0
  105. data/src/toxi/geom/CoordinateExtractor.java +16 -0
  106. data/src/toxi/geom/Ellipse.java +250 -0
  107. data/src/toxi/geom/GMatrix.java +2599 -0
  108. data/src/toxi/geom/GVector.java +833 -0
  109. data/src/toxi/geom/GlobalGridTesselator.java +54 -0
  110. data/src/toxi/geom/GridTesselator.java +108 -0
  111. data/src/toxi/geom/Intersector2D.java +49 -0
  112. data/src/toxi/geom/Intersector3D.java +51 -0
  113. data/src/toxi/geom/IsectData2D.java +103 -0
  114. data/src/toxi/geom/IsectData3D.java +103 -0
  115. data/src/toxi/geom/Line2D.java +534 -0
  116. data/src/toxi/geom/Line3D.java +471 -0
  117. data/src/toxi/geom/LineStrip2D.java +430 -0
  118. data/src/toxi/geom/LineStrip3D.java +230 -0
  119. data/src/toxi/geom/LocalGridTesselator.java +57 -0
  120. data/src/toxi/geom/Matrix3d.java +3048 -0
  121. data/src/toxi/geom/Matrix4f.java +3446 -0
  122. data/src/toxi/geom/Matrix4x4.java +1076 -0
  123. data/src/toxi/geom/MatrixSizeException.java +58 -0
  124. data/src/toxi/geom/OctreeVisitor.java +44 -0
  125. data/src/toxi/geom/Origin3D.java +148 -0
  126. data/src/toxi/geom/Plane.java +293 -0
  127. data/src/toxi/geom/PlaneIntersector.java +57 -0
  128. data/src/toxi/geom/PointCloud3D.java +253 -0
  129. data/src/toxi/geom/PointOctree.java +502 -0
  130. data/src/toxi/geom/PointQuadtree.java +375 -0
  131. data/src/toxi/geom/Polygon2D.java +1038 -0
  132. data/src/toxi/geom/PolygonClipper2D.java +45 -0
  133. data/src/toxi/geom/PolygonTesselator.java +20 -0
  134. data/src/toxi/geom/QuadtreeVisitor.java +44 -0
  135. data/src/toxi/geom/Quaternion.java +641 -0
  136. data/src/toxi/geom/Ray2D.java +146 -0
  137. data/src/toxi/geom/Ray3D.java +150 -0
  138. data/src/toxi/geom/Ray3DIntersector.java +75 -0
  139. data/src/toxi/geom/ReadonlyVec2D.java +575 -0
  140. data/src/toxi/geom/ReadonlyVec3D.java +628 -0
  141. data/src/toxi/geom/ReadonlyVec4D.java +431 -0
  142. data/src/toxi/geom/Rect.java +720 -0
  143. data/src/toxi/geom/Reflector3D.java +58 -0
  144. data/src/toxi/geom/Shape2D.java +94 -0
  145. data/src/toxi/geom/Shape3D.java +42 -0
  146. data/src/toxi/geom/SingularMatrixException.java +57 -0
  147. data/src/toxi/geom/SpatialBins.java +182 -0
  148. data/src/toxi/geom/SpatialIndex.java +61 -0
  149. data/src/toxi/geom/Sphere.java +224 -0
  150. data/src/toxi/geom/SphereIntersectorReflector.java +196 -0
  151. data/src/toxi/geom/Spline2D.java +349 -0
  152. data/src/toxi/geom/Spline3D.java +351 -0
  153. data/src/toxi/geom/SutherlandHodgemanClipper.java +151 -0
  154. data/src/toxi/geom/Triangle2D.java +422 -0
  155. data/src/toxi/geom/Triangle3D.java +456 -0
  156. data/src/toxi/geom/TriangleIntersector.java +105 -0
  157. data/src/toxi/geom/Vec2D.java +1328 -0
  158. data/src/toxi/geom/Vec3D.java +1832 -0
  159. data/src/toxi/geom/Vec4D.java +985 -0
  160. data/src/toxi/geom/VecMathUtil.java +100 -0
  161. data/src/toxi/geom/XAxisCylinder.java +64 -0
  162. data/src/toxi/geom/YAxisCylinder.java +65 -0
  163. data/src/toxi/geom/ZAxisCylinder.java +64 -0
  164. data/src/toxi/geom/mesh/BezierPatch.java +200 -0
  165. data/src/toxi/geom/mesh/BoxSelector.java +62 -0
  166. data/src/toxi/geom/mesh/DefaultSTLColorModel.java +67 -0
  167. data/src/toxi/geom/mesh/DefaultSelector.java +50 -0
  168. data/src/toxi/geom/mesh/Face.java +176 -0
  169. data/src/toxi/geom/mesh/LaplacianSmooth.java +80 -0
  170. data/src/toxi/geom/mesh/MaterialiseSTLColorModel.java +150 -0
  171. data/src/toxi/geom/mesh/Mesh3D.java +224 -0
  172. data/src/toxi/geom/mesh/MeshIntersector.java +91 -0
  173. data/src/toxi/geom/mesh/OBJWriter.java +194 -0
  174. data/src/toxi/geom/mesh/PLYWriter.java +167 -0
  175. data/src/toxi/geom/mesh/PlaneSelector.java +90 -0
  176. data/src/toxi/geom/mesh/STLColorModel.java +54 -0
  177. data/src/toxi/geom/mesh/STLReader.java +185 -0
  178. data/src/toxi/geom/mesh/STLWriter.java +323 -0
  179. data/src/toxi/geom/mesh/SphereFunction.java +156 -0
  180. data/src/toxi/geom/mesh/SphericalHarmonics.java +110 -0
  181. data/src/toxi/geom/mesh/SuperEllipsoid.java +110 -0
  182. data/src/toxi/geom/mesh/SurfaceFunction.java +75 -0
  183. data/src/toxi/geom/mesh/SurfaceMeshBuilder.java +149 -0
  184. data/src/toxi/geom/mesh/Terrain.java +451 -0
  185. data/src/toxi/geom/mesh/TriangleMesh.java +1201 -0
  186. data/src/toxi/geom/mesh/Vertex.java +78 -0
  187. data/src/toxi/geom/mesh/VertexSelector.java +193 -0
  188. data/src/toxi/geom/mesh/WEFace.java +100 -0
  189. data/src/toxi/geom/mesh/WEMeshFilterStrategy.java +51 -0
  190. data/src/toxi/geom/mesh/WETriangleMesh.java +761 -0
  191. data/src/toxi/geom/mesh/WEVertex.java +134 -0
  192. data/src/toxi/geom/mesh/WingedEdge.java +115 -0
  193. data/src/toxi/geom/mesh/subdiv/CentroidSubdiv.java +37 -0
  194. data/src/toxi/geom/mesh/subdiv/DisplacementSubdivision.java +85 -0
  195. data/src/toxi/geom/mesh/subdiv/DualDisplacementSubdivision.java +94 -0
  196. data/src/toxi/geom/mesh/subdiv/DualSubdivision.java +49 -0
  197. data/src/toxi/geom/mesh/subdiv/EdgeLengthComparator.java +50 -0
  198. data/src/toxi/geom/mesh/subdiv/FaceCountComparator.java +51 -0
  199. data/src/toxi/geom/mesh/subdiv/MidpointDisplacementSubdivision.java +80 -0
  200. data/src/toxi/geom/mesh/subdiv/MidpointSubdiv.java +42 -0
  201. data/src/toxi/geom/mesh/subdiv/MidpointSubdivision.java +48 -0
  202. data/src/toxi/geom/mesh/subdiv/NewSubdivStrategy.java +23 -0
  203. data/src/toxi/geom/mesh/subdiv/NormalDisplacementSubdivision.java +74 -0
  204. data/src/toxi/geom/mesh/subdiv/SubdivisionStrategy.java +83 -0
  205. data/src/toxi/geom/mesh/subdiv/TriSubdivision.java +51 -0
  206. data/src/toxi/geom/mesh2d/DelaunayTriangle.java +222 -0
  207. data/src/toxi/geom/mesh2d/DelaunayTriangulation.java +327 -0
  208. data/src/toxi/geom/mesh2d/DelaunayVertex.java +560 -0
  209. data/src/toxi/geom/mesh2d/Voronoi.java +149 -0
  210. data/src/toxi/geom/nurbs/BasicNurbsCurve.java +210 -0
  211. data/src/toxi/geom/nurbs/BasicNurbsSurface.java +233 -0
  212. data/src/toxi/geom/nurbs/ControlNet.java +148 -0
  213. data/src/toxi/geom/nurbs/CurveCreator.java +112 -0
  214. data/src/toxi/geom/nurbs/CurveUtils.java +259 -0
  215. data/src/toxi/geom/nurbs/InterpolationException.java +65 -0
  216. data/src/toxi/geom/nurbs/KnotVector.java +333 -0
  217. data/src/toxi/geom/nurbs/NurbsCreator.java +815 -0
  218. data/src/toxi/geom/nurbs/NurbsCurve.java +120 -0
  219. data/src/toxi/geom/nurbs/NurbsMeshCreator.java +145 -0
  220. data/src/toxi/geom/nurbs/NurbsSurface.java +147 -0
  221. data/src/toxi/image/util/Filter8bit.java +331 -0
  222. data/src/toxi/image/util/TiledFrameExporter.java +162 -0
  223. data/src/toxi/math/BezierInterpolation.java +102 -0
  224. data/src/toxi/math/CircularInterpolation.java +88 -0
  225. data/src/toxi/math/CosineInterpolation.java +51 -0
  226. data/src/toxi/math/DecimatedInterpolation.java +77 -0
  227. data/src/toxi/math/ExponentialInterpolation.java +68 -0
  228. data/src/toxi/math/InterpolateStrategy.java +60 -0
  229. data/src/toxi/math/Interpolation2D.java +93 -0
  230. data/src/toxi/math/LinearInterpolation.java +46 -0
  231. data/src/toxi/math/MathUtils.java +990 -0
  232. data/src/toxi/math/NonLinearScaleMap.java +101 -0
  233. data/src/toxi/math/ScaleMap.java +183 -0
  234. data/src/toxi/math/SigmoidInterpolation.java +78 -0
  235. data/src/toxi/math/SinCosLUT.java +141 -0
  236. data/src/toxi/math/ThresholdInterpolation.java +58 -0
  237. data/src/toxi/math/ZoomLensInterpolation.java +126 -0
  238. data/src/toxi/math/conversion/UnitTranslator.java +161 -0
  239. data/src/toxi/math/noise/PerlinNoise.java +281 -0
  240. data/src/toxi/math/noise/SimplexNoise.java +542 -0
  241. data/src/toxi/math/waves/AMFMSineWave.java +143 -0
  242. data/src/toxi/math/waves/AbstractWave.java +248 -0
  243. data/src/toxi/math/waves/ConstantWave.java +48 -0
  244. data/src/toxi/math/waves/FMHarmonicSquareWave.java +155 -0
  245. data/src/toxi/math/waves/FMSawtoothWave.java +144 -0
  246. data/src/toxi/math/waves/FMSineWave.java +142 -0
  247. data/src/toxi/math/waves/FMSquareWave.java +143 -0
  248. data/src/toxi/math/waves/FMTriangleWave.java +126 -0
  249. data/src/toxi/math/waves/SineWave.java +81 -0
  250. data/src/toxi/math/waves/Wave2D.java +68 -0
  251. data/src/toxi/math/waves/WaveState.java +69 -0
  252. data/src/toxi/music/scale/AbstractScale.java +117 -0
  253. data/src/toxi/music/scale/GenericScale.java +66 -0
  254. data/src/toxi/music/scale/MajorScale.java +41 -0
  255. data/src/toxi/newmesh/AttributedEdge.java +106 -0
  256. data/src/toxi/newmesh/AttributedFace.java +63 -0
  257. data/src/toxi/newmesh/IndexedTriangleMesh.java +809 -0
  258. data/src/toxi/newmesh/MeshAttributeCompiler.java +45 -0
  259. data/src/toxi/newmesh/MeshFaceNormalCompiler.java +52 -0
  260. data/src/toxi/newmesh/MeshUVCompiler.java +52 -0
  261. data/src/toxi/newmesh/MeshVertexColorCompiler.java +49 -0
  262. data/src/toxi/newmesh/MeshVertexCompiler.java +54 -0
  263. data/src/toxi/newmesh/MeshVertexNormalCompiler.java +55 -0
  264. data/src/toxi/newmesh/SpatialIndex.java +78 -0
  265. data/src/toxi/physics2d/ParticlePath2D.java +100 -0
  266. data/src/toxi/physics2d/ParticleString2D.java +184 -0
  267. data/src/toxi/physics2d/PullBackSpring2D.java +51 -0
  268. data/src/toxi/physics2d/VerletConstrainedSpring2D.java +89 -0
  269. data/src/toxi/physics2d/VerletMinDistanceSpring2D.java +57 -0
  270. data/src/toxi/physics2d/VerletParticle2D.java +457 -0
  271. data/src/toxi/physics2d/VerletPhysics2D.java +448 -0
  272. data/src/toxi/physics2d/VerletSpring2D.java +181 -0
  273. data/src/toxi/physics2d/behaviors/AttractionBehavior2D.java +212 -0
  274. data/src/toxi/physics2d/behaviors/ConstantForceBehavior2D.java +112 -0
  275. data/src/toxi/physics2d/behaviors/GravityBehavior2D.java +61 -0
  276. data/src/toxi/physics2d/behaviors/ParticleBehavior2D.java +66 -0
  277. data/src/toxi/physics2d/constraints/AngularConstraint.java +83 -0
  278. data/src/toxi/physics2d/constraints/AxisConstraint.java +71 -0
  279. data/src/toxi/physics2d/constraints/CircularConstraint.java +69 -0
  280. data/src/toxi/physics2d/constraints/MaxConstraint.java +66 -0
  281. data/src/toxi/physics2d/constraints/MinConstraint.java +66 -0
  282. data/src/toxi/physics2d/constraints/ParticleConstraint2D.java +47 -0
  283. data/src/toxi/physics2d/constraints/PolygonConstraint.java +93 -0
  284. data/src/toxi/physics2d/constraints/RectConstraint.java +114 -0
  285. data/src/toxi/physics3d/ParticlePath3D.java +100 -0
  286. data/src/toxi/physics3d/ParticleString3D.java +184 -0
  287. data/src/toxi/physics3d/PullBackSpring3D.java +50 -0
  288. data/src/toxi/physics3d/VerletConstrainedSpring3D.java +88 -0
  289. data/src/toxi/physics3d/VerletMinDistanceSpring3D.java +56 -0
  290. data/src/toxi/physics3d/VerletParticle3D.java +385 -0
  291. data/src/toxi/physics3d/VerletPhysics3D.java +417 -0
  292. data/src/toxi/physics3d/VerletSpring3D.java +180 -0
  293. data/src/toxi/physics3d/behaviors/AttractionBehavior3D.java +182 -0
  294. data/src/toxi/physics3d/behaviors/ConstantForceBehavior3D.java +92 -0
  295. data/src/toxi/physics3d/behaviors/GravityBehavior3D.java +61 -0
  296. data/src/toxi/physics3d/behaviors/ParticleBehavior3D.java +52 -0
  297. data/src/toxi/physics3d/constraints/AxisConstraint.java +68 -0
  298. data/src/toxi/physics3d/constraints/BoxConstraint.java +121 -0
  299. data/src/toxi/physics3d/constraints/CylinderConstraint.java +87 -0
  300. data/src/toxi/physics3d/constraints/MaxConstraint.java +65 -0
  301. data/src/toxi/physics3d/constraints/MinConstraint.java +65 -0
  302. data/src/toxi/physics3d/constraints/ParticleConstraint3D.java +49 -0
  303. data/src/toxi/physics3d/constraints/PlaneConstraint.java +78 -0
  304. data/src/toxi/physics3d/constraints/SoftBoxConstraint.java +87 -0
  305. data/src/toxi/physics3d/constraints/SphereConstraint.java +108 -0
  306. data/src/toxi/processing/ArrowModifier.java +116 -0
  307. data/src/toxi/processing/DashedLineModifier.java +48 -0
  308. data/src/toxi/processing/DeltaOrientationMapper.java +57 -0
  309. data/src/toxi/processing/Line2DRenderModifier.java +18 -0
  310. data/src/toxi/processing/MeshToVBO.java +94 -0
  311. data/src/toxi/processing/NormalMapper.java +18 -0
  312. data/src/toxi/processing/POVInterface.java +121 -0
  313. data/src/toxi/processing/POVMesh.java +219 -0
  314. data/src/toxi/processing/POVWriter.java +460 -0
  315. data/src/toxi/processing/RCOpaque.java +77 -0
  316. data/src/toxi/processing/RCTransp.java +78 -0
  317. data/src/toxi/processing/TextureBuilder.java +232 -0
  318. data/src/toxi/processing/Textures.java +110 -0
  319. data/src/toxi/processing/ToxiclibsSupport.java +1239 -0
  320. data/src/toxi/processing/Tracing.java +25 -0
  321. data/src/toxi/processing/XYZNormalMapper.java +30 -0
  322. data/src/toxi/sim/automata/CAMatrix.java +297 -0
  323. data/src/toxi/sim/automata/CARule.java +76 -0
  324. data/src/toxi/sim/automata/CARule2D.java +354 -0
  325. data/src/toxi/sim/automata/CAWolfram1D.java +309 -0
  326. data/src/toxi/sim/automata/EvolvableMatrix.java +61 -0
  327. data/src/toxi/sim/automata/MatrixEvolver.java +42 -0
  328. data/src/toxi/sim/dla/BottomUpOrder.java +76 -0
  329. data/src/toxi/sim/dla/DLA.java +497 -0
  330. data/src/toxi/sim/dla/DLAConfiguration.java +364 -0
  331. data/src/toxi/sim/dla/DLAEventAdapter.java +64 -0
  332. data/src/toxi/sim/dla/DLAEventListener.java +57 -0
  333. data/src/toxi/sim/dla/DLAGuideLines.java +219 -0
  334. data/src/toxi/sim/dla/DLAParticle.java +102 -0
  335. data/src/toxi/sim/dla/DLASegment.java +88 -0
  336. data/src/toxi/sim/dla/PipelineOrder.java +50 -0
  337. data/src/toxi/sim/dla/RadialDistanceOrder.java +92 -0
  338. data/src/toxi/sim/erosion/ErosionFunction.java +122 -0
  339. data/src/toxi/sim/erosion/TalusAngleErosion.java +145 -0
  340. data/src/toxi/sim/erosion/ThermalErosion.java +75 -0
  341. data/src/toxi/sim/fluids/FluidSolver2D.java +762 -0
  342. data/src/toxi/sim/fluids/FluidSolver3D.java +326 -0
  343. data/src/toxi/sim/grayscott/GrayScott.java +469 -0
  344. data/src/toxi/util/DateUtils.java +141 -0
  345. data/src/toxi/util/FileSequenceDescriptor.java +181 -0
  346. data/src/toxi/util/FileUtils.java +467 -0
  347. data/src/toxi/util/datatypes/ArraySet.java +128 -0
  348. data/src/toxi/util/datatypes/ArrayUtil.java +404 -0
  349. data/src/toxi/util/datatypes/BiasedDoubleRange.java +141 -0
  350. data/src/toxi/util/datatypes/BiasedFloatRange.java +141 -0
  351. data/src/toxi/util/datatypes/BiasedIntegerRange.java +141 -0
  352. data/src/toxi/util/datatypes/DoubleRange.java +251 -0
  353. data/src/toxi/util/datatypes/FloatRange.java +251 -0
  354. data/src/toxi/util/datatypes/GenericSet.java +215 -0
  355. data/src/toxi/util/datatypes/IntegerRange.java +247 -0
  356. data/src/toxi/util/datatypes/IntegerSet.java +149 -0
  357. data/src/toxi/util/datatypes/ItemIndex.java +72 -0
  358. data/src/toxi/util/datatypes/SingletonRegistry.java +91 -0
  359. data/src/toxi/util/datatypes/TypedProperties.java +291 -0
  360. data/src/toxi/util/datatypes/UndirectedGraph.java +134 -0
  361. data/src/toxi/util/datatypes/UniqueItemIndex.java +223 -0
  362. data/src/toxi/util/datatypes/WeightedRandomEntry.java +76 -0
  363. data/src/toxi/util/datatypes/WeightedRandomSet.java +125 -0
  364. data/src/toxi/util/events/EventDispatcher.java +86 -0
  365. data/src/toxi/volume/AdditiveBrush.java +19 -0
  366. data/src/toxi/volume/ArrayIsoSurface.java +297 -0
  367. data/src/toxi/volume/BoxBrush.java +100 -0
  368. data/src/toxi/volume/BrushMode.java +16 -0
  369. data/src/toxi/volume/HashIsoSurface.java +354 -0
  370. data/src/toxi/volume/IsoSurface.java +59 -0
  371. data/src/toxi/volume/MarchingCubesIndex.java +312 -0
  372. data/src/toxi/volume/MeshLatticeBuilder.java +358 -0
  373. data/src/toxi/volume/MeshVoxelizer.java +216 -0
  374. data/src/toxi/volume/MultiplyBrush.java +20 -0
  375. data/src/toxi/volume/PeakBrush.java +21 -0
  376. data/src/toxi/volume/ReplaceBrush.java +19 -0
  377. data/src/toxi/volume/RoundBrush.java +113 -0
  378. data/src/toxi/volume/VolumetricBrush.java +160 -0
  379. data/src/toxi/volume/VolumetricHashMap.java +179 -0
  380. data/src/toxi/volume/VolumetricSpace.java +195 -0
  381. data/src/toxi/volume/VolumetricSpaceArray.java +214 -0
  382. data/toxiclibs.gemspec +34 -0
  383. metadata +424 -27
@@ -0,0 +1,65 @@
1
+ /*
2
+ * jgeom: Geometry Library fo Java
3
+ *
4
+ * Copyright (C) 2005 Samuel Gerber
5
+ *
6
+ * This program is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU General Public License
8
+ * as published by the Free Software Foundation; either version 2
9
+ * of the License, or (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
+ */
20
+ package toxi.geom.nurbs;
21
+
22
+ /**
23
+ * An InterpolationException is thrown if Nurbs could not be interpolated from
24
+ * the given points.
25
+ *
26
+ * @author sg
27
+ * @version 1.0
28
+ */
29
+ public class InterpolationException extends Exception {
30
+
31
+ private static final long serialVersionUID = 1L;
32
+
33
+ /**
34
+ *
35
+ */
36
+ public InterpolationException() {
37
+ super();
38
+ }
39
+
40
+ /**
41
+ *
42
+ * @param arg0
43
+ */
44
+ public InterpolationException(String arg0) {
45
+ super(arg0);
46
+ }
47
+
48
+ /**
49
+ *
50
+ * @param arg0
51
+ * @param arg1
52
+ */
53
+ public InterpolationException(String arg0, Throwable arg1) {
54
+ super(arg0, arg1);
55
+ }
56
+
57
+ /**
58
+ *
59
+ * @param arg0
60
+ */
61
+ public InterpolationException(Throwable arg0) {
62
+ super(arg0);
63
+ }
64
+
65
+ }
@@ -0,0 +1,333 @@
1
+ /*
2
+ * jgeom: Geometry Library fo Java
3
+ *
4
+ * Copyright (C) 2005 Samuel Gerber
5
+ *
6
+ * This program is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU General Public License
8
+ * as published by the Free Software Foundation; either version 2
9
+ * of the License, or (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
+ */
20
+ package toxi.geom.nurbs;
21
+
22
+ /**
23
+ * KnotVector, assembles the knots values of a NURBS and its degree.
24
+ *
25
+ * @author sg
26
+ * @version 1.0
27
+ */
28
+ public class KnotVector {
29
+
30
+ private boolean isOpen;
31
+ private final float knots[];
32
+ private final int degree;
33
+ private final int n;
34
+
35
+ /**
36
+ * Create a Knotvector from the given knot values of the desired degree.
37
+ *
38
+ * @param knots
39
+ * knot values
40
+ * @param degree
41
+ * degree of Nurbs
42
+ */
43
+ public KnotVector(float knots[], int degree)
44
+ throws IllegalArgumentException {
45
+ this.knots = knots;
46
+ this.degree = degree;
47
+ n = knots.length - degree - 2;
48
+ for (int i = 1; i < knots.length; i++) {
49
+ if (knots[i - 1] > knots[i]) {
50
+ throw new IllegalArgumentException("Knots not valid knot["
51
+ + (i - 1) + "] > knot[" + i + "]: knot[" + (i - 1)
52
+ + "]=" + knots[i - 1] + " > knot[" + i + "]="
53
+ + knots[i]);
54
+ }
55
+ }
56
+
57
+ int m = knots.length - 1;
58
+
59
+ // Check if it is an open knot vector
60
+ isOpen = true;
61
+ for (int k = 0; k < degree && isOpen; k++) {
62
+ if (knots[k] != knots[k + 1]) {
63
+ isOpen = false;
64
+ }
65
+ }
66
+ for (int k = m; k > m - degree && isOpen; k--) {
67
+ if (knots[k] != knots[k - 1]) {
68
+ isOpen = false;
69
+ }
70
+ }
71
+
72
+ }
73
+
74
+ /**
75
+ * Gets the basis function values for the given u value. This function
76
+ * calculates firstly the span which is needed in order to calculate the
77
+ * basis functions values.
78
+ *
79
+ * @param u
80
+ * Value to calculate basis functions for.
81
+ * @return basis function values
82
+ */
83
+ public double[] basisFunctions(float u) {
84
+ return basisFunctions(findSpan(u), u);
85
+ }
86
+
87
+ /**
88
+ * Calculates the basis function values for the given u value, when it's
89
+ * already known in which span u lies.
90
+ *
91
+ * @param span
92
+ * The span u lies in
93
+ * @param u
94
+ * Value to calculate basis functions for.
95
+ * @return basis function values
96
+ */
97
+ public double[] basisFunctions(int span, float u) {
98
+ final int d1 = degree + 1;
99
+ double res[] = new double[d1];
100
+ double left[] = new double[d1];
101
+ double right[] = new double[d1];
102
+ res[0] = 1;
103
+ for (int j = 1; j < d1; j++) {
104
+ left[j] = u - knots[span + 1 - j];
105
+ right[j] = knots[span + j] - u;
106
+ double saved = 0;
107
+ for (int r = 0; r < j; r++) {
108
+ double tmp = res[r] / (right[r + 1] + left[j - r]);
109
+ res[r] = saved + right[r + 1] * tmp;
110
+ saved = left[j - r] * tmp;
111
+ }
112
+ res[j] = saved;
113
+ }
114
+ return res;
115
+ }
116
+
117
+ /**
118
+ * Calculates the basis functions and its derivatives up to the given grade.
119
+ *
120
+ * @param u
121
+ * Value to calculate basis functions and derivatives for.
122
+ * @param grade
123
+ * grade to calculate derivations for.
124
+ * @return an array of basis function values or derivated basis functions
125
+ * values. The first array is the degree of dderivation in the
126
+ * second array rhe values are stored. <br>
127
+ * Example: <br>
128
+ * <code>
129
+ * float[]][] f=dersBasisFuns(0.1f, 3);
130
+ * float value=f[0][1]; //In value is know the second value of the basis function derived 0 times stored.
131
+ * </code>
132
+ *
133
+ */
134
+ public float[][] derivBasisFunctions(float u, int grade) {
135
+ int span = findSpan(u);
136
+ return derivBasisFunctions(span, u, grade);
137
+ }
138
+
139
+ /**
140
+ * Calculates the basis functions and its derivatives up to the given grade.
141
+ *
142
+ * @param span
143
+ * Span the given value lies in.
144
+ * @param u
145
+ * Value to calculate basis functions and derivatives for.
146
+ * @param grade
147
+ * grade to calculate derivations for.
148
+ * @return an array of basis function values or derivated basis functions
149
+ * values
150
+ * @see KnotVector#derivBasisFunctions(float, int)
151
+ */
152
+ public float[][] derivBasisFunctions(int span, float u, int grade) {
153
+ float[][] ders = new float[grade + 1][degree + 1];
154
+ float[][] ndu = new float[degree + 1][degree + 1];
155
+ ndu[0][0] = 1.0f;
156
+ float[] left = new float[degree + 1];
157
+ float[] right = new float[degree + 1];
158
+ int j1, j2;
159
+ for (int j = 1; j <= degree; j++) {
160
+ left[j] = u - knots[span + 1 - j];
161
+ right[j] = knots[span + j] - u;
162
+ float saved = 0.0f;
163
+ for (int r = 0; r < j; r++) {
164
+ ndu[j][r] = right[r + 1] + left[j - r];
165
+ float temp = ndu[r][j - 1] / ndu[j][r];
166
+ ndu[r][j] = saved + right[r + 1] * temp;
167
+ saved = left[j - r] * temp;
168
+ }
169
+ ndu[j][j] = saved;
170
+ }
171
+ for (int j = 0; j <= degree; j++) {
172
+ ders[0][j] = ndu[j][degree];
173
+ }
174
+ for (int r = 0; r <= degree; r++) {
175
+ int s1 = 0;
176
+ int s2 = 1;
177
+ float[][] a = new float[2][degree + 1];
178
+ a[0][0] = 1.0f;
179
+ for (int k = 1; k <= grade; k++) {
180
+ float d = 0.0f;
181
+ final int rk = r - k;
182
+ final int pk = degree - k;
183
+ final float[] as1 = a[s1];
184
+ final float[] as2 = a[s2];
185
+ if (r >= k) {
186
+ as2[0] = d = as1[0] / ndu[pk + 1][rk];
187
+ d *= ndu[rk][pk];
188
+ }
189
+ if (rk >= -1) {
190
+ j1 = 1;
191
+ } else {
192
+ j1 = -rk;
193
+ }
194
+ if (r - 1 <= pk) {
195
+ j2 = k - 1;
196
+ } else {
197
+ j2 = degree - r;
198
+ }
199
+ for (int j = j1; j <= j2; j++) {
200
+ as2[j] = (as1[j] - as1[j - 1]) / ndu[pk + 1][rk + j];
201
+ d += as2[j] * ndu[rk + j][pk];
202
+ }
203
+ if (r <= pk) {
204
+ as2[k] = -as1[k - 1] / ndu[pk + 1][r];
205
+ d += as2[k] * ndu[r][pk];
206
+ }
207
+ ders[k][r] = d;
208
+ int j = s1;
209
+ s1 = s2;
210
+ s2 = j;
211
+ }
212
+ }
213
+ int r = degree;
214
+ for (int k = 1; k <= grade; k++) {
215
+ for (int j = 0; j <= degree; j++) {
216
+ ders[k][j] *= r;
217
+ }
218
+ r *= (degree - k);
219
+ }
220
+ return ders;
221
+ }
222
+
223
+ /**
224
+ * Finds the span (Position of corresponding knot values in knot vector) a
225
+ * given value belongs to.
226
+ *
227
+ * @param u
228
+ * value to find span for
229
+ * @return Position of span.
230
+ */
231
+ public int findSpan(float u) {
232
+ if (u >= knots[n + 1]) {
233
+ return n;
234
+ }
235
+ int low = degree;
236
+ int high = n + 1;
237
+ int mid = (low + high) / 2;
238
+ while ((u < knots[mid] || u >= knots[mid + 1]) && low < high) {
239
+ if (u < knots[mid]) {
240
+ high = mid;
241
+ } else {
242
+ low = mid;
243
+ }
244
+ mid = (low + high) / 2;
245
+ }
246
+ return mid;
247
+ }
248
+
249
+ /**
250
+ * Get the knot value at a specific index.
251
+ *
252
+ * @param i
253
+ * Index to get knot value for
254
+ * @return the knot value
255
+ */
256
+ public float get(int i) {
257
+ return knots[i];
258
+ }
259
+
260
+ /**
261
+ * get the knot values as float array
262
+ *
263
+ * @return the knot values
264
+ */
265
+ public float[] getArray() {
266
+ return knots;
267
+ }
268
+
269
+ /**
270
+ * Get the degree of the KnotVector
271
+ *
272
+ * @return Degree of the Knotvector
273
+ */
274
+ public int getDegree() {
275
+ return degree;
276
+ }
277
+
278
+ /**
279
+ * Return the nu
280
+ *
281
+ * @return Length of the KnotVector
282
+ */
283
+ public int getN() {
284
+ return n;
285
+ }
286
+
287
+ /**
288
+ *
289
+ * @return
290
+ */
291
+ public int getNumberOfSegments() {
292
+ int seg = 0;
293
+ float u = knots[0];
294
+ for (int i = 1; i < knots.length; i++) {
295
+ if (u != knots[i]) {
296
+ seg++;
297
+ u = knots[i];
298
+ }
299
+ }
300
+ return seg;
301
+ }
302
+
303
+ /**
304
+ *
305
+ * @return
306
+ */
307
+ public synchronized boolean isOpen() {
308
+ return isOpen;
309
+ }
310
+
311
+ /**
312
+ *
313
+ * @return
314
+ */
315
+ public int length() {
316
+ return knots.length;
317
+ }
318
+
319
+ /**
320
+ * Set the knot value at a specific index. After this operation a call to
321
+ * isValid may be needed if one is not sure if the KnotVector with the
322
+ * changed value is valid for a Nurbs.
323
+ *
324
+ * @param i
325
+ * Index to set knot value
326
+ * @param val
327
+ * value to set the knot too
328
+ */
329
+ public void set(int i, float val) {
330
+ knots[i] = val;
331
+ }
332
+
333
+ }
@@ -0,0 +1,815 @@
1
+ /*
2
+ * jgeom: Geometry Library fo Java
3
+ *
4
+ * Copyright (C) 2005 Samuel Gerber
5
+ *
6
+ * This program is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU General Public License
8
+ * as published by the Free Software Foundation; either version 2
9
+ * of the License, or (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
+ */
20
+ package toxi.geom.nurbs;
21
+
22
+ import toxi.geom.Axis3D;
23
+ import toxi.geom.GMatrix;
24
+ import toxi.geom.GVector;
25
+ import toxi.geom.Origin3D;
26
+ import toxi.geom.ReadonlyVec3D;
27
+ import toxi.geom.SingularMatrixException;
28
+ import toxi.geom.Vec3D;
29
+ import toxi.geom.Vec4D;
30
+ import toxi.math.MathUtils;
31
+
32
+ /**
33
+ * This class offers some static methods to create NurbsSurfaces and NurbsCurves
34
+ * from diffrent inputs.
35
+ *
36
+ * @author sg
37
+ * @version 1.0
38
+ */
39
+ public final class NurbsCreator {
40
+
41
+ private static KnotVector averaging(final float[] uk, final int p) {
42
+ int m = uk.length + p;
43
+ int n = uk.length - 1;
44
+ float ip = 1f / p;
45
+ float[] u = new float[m + 1];
46
+ for (int i = 0; i <= p; i++) {
47
+ u[m - i] = 1;
48
+ }
49
+ for (int j = 1; j <= n - p; j++) {
50
+ float sum = 0;
51
+ for (int i = j; i <= j + p - 1; i++) {
52
+ sum += uk[i];
53
+ }
54
+ u[j + p] = sum * ip;
55
+ }
56
+ return new KnotVector(u, p);
57
+ }
58
+
59
+ private static float[] centripetal(Vec3D[] points) {
60
+ int n = points.length - 1;
61
+ float d = 0;
62
+ float[] uk = new float[n + 1];
63
+ uk[n] = 1;
64
+ double[] tmp = new double[n];
65
+ for (int k = 1; k <= n; k++) {
66
+ tmp[k - 1] = Math.sqrt(points[k].distanceTo(points[k - 1]));
67
+ d += tmp[k - 1];
68
+ }
69
+ d = 1f / d;
70
+ for (int i = 1; i < n; i++) {
71
+ uk[i] = uk[i - 1] + (float) (tmp[i - 1] * d);
72
+ }
73
+ return uk;
74
+ }
75
+
76
+ /**
77
+ * Create an Arc.
78
+ *
79
+ * @param o
80
+ * Origin to creat arc around
81
+ * @param r
82
+ * Radius of the arc.
83
+ * @param thetaStart
84
+ * Start angle of the arc in radians
85
+ * @param thetaEnd
86
+ * End angle of the arc in radians. If end angle is smaller than
87
+ * start angle, the end angle is increased by 2*PI.
88
+ * @return A NurbsCurve for the Arc.
89
+ */
90
+ public static NurbsCurve createArc(Origin3D o, float r, float thetaStart,
91
+ float thetaEnd) {
92
+ Vec3D tmp = new Vec3D();
93
+
94
+ if (thetaEnd < thetaStart) {
95
+ thetaEnd += MathUtils.TWO_PI;
96
+ }
97
+ double theta = thetaEnd - thetaStart;
98
+
99
+ int narcs = 4;
100
+ if (theta <= MathUtils.HALF_PI) {
101
+ narcs = 1;
102
+ } else if (theta <= MathUtils.PI) {
103
+ narcs = 2;
104
+ } else if (theta <= MathUtils.THREE_HALVES_PI) {
105
+ narcs = 3;
106
+ }
107
+ double dtheta = theta / narcs;
108
+ int n = 2 * narcs;
109
+ double w1 = Math.cos(dtheta / 2);
110
+
111
+ final float sinStart = (float) Math.sin(thetaStart);
112
+ final float cosStart = (float) Math.cos(thetaStart);
113
+ tmp.set(o.xAxis).scaleSelf(r * cosStart);
114
+ Vec3D p0 = new Vec3D(o.origin).addSelf(tmp);
115
+ tmp.set(o.yAxis).scaleSelf(r * sinStart);
116
+ p0.addSelf(tmp);
117
+
118
+ tmp.set(o.yAxis).scaleSelf(cosStart);
119
+ Vec3D t0 = new Vec3D(o.xAxis).scaleSelf(-sinStart).addSelf(tmp);
120
+
121
+ Vec4D[] cps = new Vec4D[n + 1];
122
+ cps[0] = new Vec4D(p0, 1);
123
+ int index = 0;
124
+ double angle = thetaStart;
125
+
126
+ Vec3D p1 = new Vec3D();
127
+ Vec3D p2 = new Vec3D();
128
+ Vec3D t2 = new Vec3D();
129
+ for (int i = 1; i <= narcs; i++) {
130
+ angle += dtheta;
131
+ final double sin = Math.sin(angle);
132
+ final double cos = Math.cos(angle);
133
+
134
+ tmp.set(o.xAxis).scaleSelf((float) (r * cos));
135
+ p2.set(o.origin).addSelf(tmp);
136
+ tmp.set(o.yAxis).scaleSelf((float) (r * sin));
137
+ p2.addSelf(tmp);
138
+
139
+ cps[index + 2] = new Vec4D(p2, 1);
140
+
141
+ t2.set(o.xAxis).scaleSelf((float) -sin);
142
+ tmp.set(o.yAxis).scaleSelf((float) cos);
143
+ t2.addSelf(tmp);
144
+
145
+ lineIntersect3D(p0, t0, p2, t2, p1, p1);
146
+
147
+ cps[index + 1] = new Vec4D(p1, (float) w1);
148
+ index += 2;
149
+ if (i < narcs) {
150
+ p0.set(p2);
151
+ t0.set(t2);
152
+ }
153
+ }
154
+ int j = n + 1;
155
+ float[] uKnot = new float[j + 3];
156
+ for (int i = 0; i < 3; i++) {
157
+ uKnot[i + j] = 1;
158
+ }
159
+ switch (narcs) {
160
+ case 2:
161
+ uKnot[3] = 0.5f;
162
+ uKnot[4] = 0.5f;
163
+ break;
164
+ case 3:
165
+ uKnot[3] = uKnot[4] = MathUtils.THIRD;
166
+ uKnot[5] = uKnot[6] = 2 * MathUtils.THIRD;
167
+ break;
168
+ case 4:
169
+ uKnot[3] = 0.25f;
170
+ uKnot[4] = 0.25f;
171
+ uKnot[5] = 0.5f;
172
+ uKnot[6] = 0.5f;
173
+ uKnot[7] = 0.75f;
174
+ uKnot[8] = 0.75f;
175
+ break;
176
+ }
177
+
178
+ return new BasicNurbsCurve(cps, uKnot, 2);
179
+ }
180
+
181
+ /**
182
+ * Create a full-circle NurbsCurve around the given Origin with radius r.
183
+ * The NurbsCurve has controlpolygon which has 7 controlpoints and the shape
184
+ * of quadrat.
185
+ *
186
+ * @param o
187
+ * Origin to create the full-circle around
188
+ * @param r
189
+ * Radius of the full-circle
190
+ * @return A NurbsCurve for a full-circle
191
+ */
192
+ public static NurbsCurve createFullCircleQuad7(Origin3D o, float r) {
193
+
194
+ Vec4D[] cp = new Vec4D[7];
195
+ cp[0] = new Vec4D(o.xAxis.scale(r), 1);
196
+ cp[3] = cp[0].getInvertedXYZ();
197
+ cp[6] = cp[0].copy();
198
+
199
+ cp[1] = new Vec4D(o.yAxis.add(o.xAxis).scaleSelf(r), 0.5f);
200
+ cp[4] = cp[1].getInvertedXYZ();
201
+
202
+ cp[2] = new Vec4D(o.xAxis.getInverted().addSelf(o.yAxis).scaleSelf(r),
203
+ 0.5f);
204
+ cp[5] = cp[2].getInvertedXYZ();
205
+
206
+ for (int i = 0; i < 7; i++) {
207
+ cp[i].addXYZSelf(o.origin);
208
+ }
209
+ float[] u = {
210
+ 0, 0, 0, 0.25f, 0.5f, 0.5f, 0.75f, 1, 1, 1
211
+ };
212
+ return new BasicNurbsCurve(cp, u, 2);
213
+ }
214
+
215
+ /**
216
+ * Create a full-circle NurbsCurve around the given Origin with radius r.
217
+ * The NurbsCurve has controlpolygon which has 9 controlpoints and the shape
218
+ * of quadrat.
219
+ *
220
+ * @param o
221
+ * Origin to create the full-circle around
222
+ * @param r
223
+ * Radius of the full-circle
224
+ * @return A NurbsCurve for a full-circle
225
+ */
226
+ public static NurbsCurve createFullCircleQuad9(Origin3D o, float r) {
227
+ final float w = MathUtils.SQRT2 / 2;
228
+
229
+ Vec4D[] cp = new Vec4D[9];
230
+ cp[0] = new Vec4D(o.xAxis.scale(r), 1);
231
+ cp[4] = cp[0].getInvertedXYZ();
232
+ cp[8] = cp[0].copy();
233
+
234
+ cp[1] = new Vec4D(o.xAxis.add(o.yAxis).scaleSelf(r), w);
235
+ cp[5] = cp[1].getInvertedXYZ();
236
+
237
+ cp[2] = new Vec4D(o.yAxis.scale(r), 1);
238
+ cp[6] = cp[2].getInvertedXYZ();
239
+
240
+ cp[3] = new Vec4D(o.xAxis.getInverted().addSelf(o.yAxis).scaleSelf(r),
241
+ w);
242
+ cp[7] = cp[3].getInvertedXYZ();
243
+
244
+ for (int i = 0; i < 9; i++) {
245
+ cp[i].addXYZSelf(o.origin);
246
+ }
247
+ float[] u = {
248
+ 0, 0, 0, 0.25f, 0.25f, 0.5f, 0.5f, 0.75f, 0.75f, 1, 1, 1
249
+ };
250
+ return new BasicNurbsCurve(cp, u, 2);
251
+ }
252
+
253
+ /**
254
+ * Create a revolved NurbsSurface from the given NurbsCurve around the given
255
+ * axis whith the angle theta.
256
+ *
257
+ * @param a
258
+ * Axis to revolve around.
259
+ * @param curve
260
+ * NurbsCurve to revolve
261
+ * @param theta
262
+ * Angle to revolve
263
+ * @return The revolved NurbsSurface
264
+ */
265
+ // TODO:call createRevolvedSurface(Axis3D a, NurbsCurve curve, double
266
+ // thetaStart, double thetaEnd) as as it is tested
267
+ public static NurbsSurface createRevolvedSurface(Axis3D a,
268
+ NurbsCurve curve, double theta) {
269
+ int narcs = 4;
270
+ if (theta <= MathUtils.HALF_PI) {
271
+ narcs = 1;
272
+ } else if (theta <= MathUtils.PI) {
273
+ narcs = 2;
274
+ } else if (theta <= MathUtils.THREE_HALVES_PI) {
275
+ narcs = 3;
276
+ }
277
+
278
+ int j = 3 + 2 * (narcs - 1);
279
+ final double dtheta = theta / narcs;
280
+ final float[] uKnot = new float[j + 3];
281
+ for (int i = 0; i < 3; i++) {
282
+ uKnot[j + i] = 1;
283
+ }
284
+ switch (narcs) {
285
+ case 2:
286
+ uKnot[3] = 0.5f;
287
+ uKnot[4] = 0.5f;
288
+ break;
289
+ case 3:
290
+ uKnot[3] = uKnot[4] = MathUtils.THIRD;
291
+ uKnot[5] = uKnot[6] = 2 * MathUtils.THIRD;
292
+ break;
293
+ case 4:
294
+ uKnot[3] = 0.25f;
295
+ uKnot[4] = 0.25f;
296
+ uKnot[5] = 0.5f;
297
+ uKnot[6] = 0.5f;
298
+ uKnot[7] = 0.75f;
299
+ uKnot[8] = 0.75f;
300
+ break;
301
+ }
302
+
303
+ double angle = 0;
304
+ final double[] cos = new double[narcs + 1];
305
+ final double[] sin = new double[narcs + 1];
306
+ for (int i = 0; i <= narcs; i++) {
307
+ cos[i] = Math.cos(angle);
308
+ sin[i] = Math.sin(angle);
309
+ angle += dtheta;
310
+ }
311
+
312
+ Vec4D[] pj = curve.getControlPoints();
313
+ Vec3D P0 = new Vec3D();
314
+ final Vec3D P2 = new Vec3D();
315
+ final Vec3D O = new Vec3D();
316
+ final Vec3D T2 = new Vec3D();
317
+ final Vec3D T0 = new Vec3D();
318
+ final Vec3D tmp = new Vec3D();
319
+ final Vec3D X = new Vec3D();
320
+ final Vec3D Y = new Vec3D();
321
+ final Vec4D[][] pij = new Vec4D[2 * narcs + 1][pj.length];
322
+ final double wm = Math.cos(dtheta / 2);
323
+ for (j = 0; j < pj.length; j++) {
324
+ pointToLine3D(a.origin, a.dir, pj[j].to3D(), O);
325
+ X.set(pj[j].to3D().subSelf(O));
326
+ final double r = X.magnitude();
327
+ if (r == 0) {
328
+ X.set(O);
329
+ }
330
+ X.normalize();
331
+ a.dir.crossInto(X, Y);
332
+ pij[0][j] = new Vec4D(pj[j]);
333
+ P0 = pj[j].to3D();
334
+ T0.set(Y);
335
+ int index = 0;
336
+ for (int i = 1; i <= narcs; i++) {
337
+ tmp.set(X).scaleSelf((float) (r * cos[i]));
338
+ P2.set(O).addSelf(tmp);
339
+ tmp.set(Y).scaleSelf((float) (r * sin[i]));
340
+ P2.addSelf(tmp);
341
+
342
+ pij[index + 2][j] = new Vec4D(P2, pj[j].w);
343
+
344
+ tmp.set(Y).scaleSelf((float) cos[i]);
345
+ T2.set(X).scaleSelf((float) -sin[i]).addSelf(tmp);
346
+
347
+ lineIntersect3D(P0, T0, P2, T2, tmp, tmp);
348
+ pij[index + 1][j] = new Vec4D(tmp, (float) (wm * pj[j].w));
349
+
350
+ index += 2;
351
+ if (i < narcs) {
352
+ P0.set(P2);
353
+ T0.set(T2);
354
+ }
355
+
356
+ }
357
+ }
358
+ ControlNet cnet = new ControlNet(pij);
359
+ return new BasicNurbsSurface(cnet, uKnot, curve.getKnots(), 2,
360
+ curve.getDegree());
361
+ }
362
+
363
+ /**
364
+ * Create a revolved NurbsSurface from the given NurbsCurve around the given
365
+ * axis whith the angle theta.
366
+ *
367
+ * @param a
368
+ * Axis to revolve around.
369
+ * @param curve
370
+ * NurbsCurve to revolve
371
+ * @param thetaStart
372
+ * Angle to start revolution
373
+ * @param thetaEnd
374
+ * Angle to end revolution
375
+ * @return The revolved NurbsSurface
376
+ */
377
+ public static NurbsSurface createRevolvedSurface(Axis3D a,
378
+ NurbsCurve curve, double thetaStart, double thetaEnd) {
379
+ int narcs = 4;
380
+ if (thetaStart > thetaEnd) {
381
+ double tmp = thetaEnd;
382
+ thetaEnd = thetaStart;
383
+ thetaStart = tmp;
384
+ }
385
+ double theta = thetaEnd - thetaStart;
386
+ if (theta <= MathUtils.HALF_PI) {
387
+ narcs = 1;
388
+ } else if (theta <= MathUtils.PI) {
389
+ narcs = 2;
390
+ } else if (theta <= MathUtils.THREE_HALVES_PI) {
391
+ narcs = 3;
392
+ }
393
+
394
+ int j = 3 + 2 * (narcs - 1);
395
+ final double dtheta = theta / narcs;
396
+ final float[] uKnot = new float[j + 3];
397
+ for (int i = 0; i < 3; i++) {
398
+ uKnot[i] = 0;
399
+ uKnot[j + i] = 1;
400
+ }
401
+ switch (narcs) {
402
+ case 2:
403
+ uKnot[3] = 0.5f;
404
+ uKnot[4] = 0.5f;
405
+ break;
406
+ case 3:
407
+ uKnot[3] = uKnot[4] = MathUtils.THIRD;
408
+ uKnot[5] = uKnot[6] = 2 * MathUtils.THIRD;
409
+ break;
410
+ case 4:
411
+ uKnot[3] = 0.25f;
412
+ uKnot[4] = 0.25f;
413
+ uKnot[5] = 0.5f;
414
+ uKnot[6] = 0.5f;
415
+ uKnot[7] = 0.75f;
416
+ uKnot[8] = 0.75f;
417
+ break;
418
+ }
419
+
420
+ double angle = thetaStart;
421
+ final double[] cos = new double[narcs + 1];
422
+ final double[] sin = new double[narcs + 1];
423
+ for (int i = 0; i <= narcs; i++) {
424
+ cos[i] = Math.cos(angle);
425
+ sin[i] = Math.sin(angle);
426
+ angle += dtheta;
427
+ }
428
+
429
+ final Vec4D[] pj = curve.getControlPoints();
430
+ Vec3D P0 = new Vec3D();
431
+ final Vec3D O = new Vec3D();
432
+ final Vec3D P2 = new Vec3D();
433
+ final Vec3D T2 = new Vec3D();
434
+ final Vec3D T0 = new Vec3D();
435
+ final Vec3D tmp = new Vec3D();
436
+ final Vec3D X = new Vec3D();
437
+ final Vec3D Y = new Vec3D();
438
+ final Vec4D[][] pij = new Vec4D[2 * narcs + 1][pj.length];
439
+ final double wm = Math.cos(dtheta / 2);
440
+ for (j = 0; j < pj.length; j++) {
441
+ pointToLine3D(a.origin, a.dir, pj[j].to3D(), O);
442
+ X.set(pj[j].to3D().subSelf(O));
443
+ final double r = X.magnitude();
444
+ if (r == 0) {
445
+ X.set(O);
446
+ }
447
+ X.normalize();
448
+ a.dir.crossInto(X, Y);
449
+ pij[0][j] = new Vec4D(pj[j]);
450
+ P0 = pj[j].to3D();
451
+ T0.set(Y);
452
+ int index = 0;
453
+ for (int i = 1; i <= narcs; i++) {
454
+ tmp.set(X).scaleSelf((float) (r * cos[i]));
455
+ P2.set(O).addSelf(tmp);
456
+ tmp.set(Y).scaleSelf((float) (r * sin[i]));
457
+ P2.addSelf(tmp);
458
+
459
+ pij[index + 2][j] = new Vec4D(P2, pj[j].w);
460
+
461
+ tmp.set(Y).scaleSelf((float) cos[i]);
462
+ T2.set(X).scaleSelf((float) -sin[i]).addSelf(tmp);
463
+
464
+ lineIntersect3D(P0, T0, P2, T2, tmp, tmp);
465
+ pij[index + 1][j] = new Vec4D(tmp, (float) (wm * pj[j].w));
466
+
467
+ index += 2;
468
+ if (i < narcs) {
469
+ P0.set(P2);
470
+ T0.set(T2);
471
+ }
472
+ }
473
+ }
474
+ ControlNet cnet = new ControlNet(pij);
475
+ return new BasicNurbsSurface(cnet, uKnot, curve.getKnots(), 2,
476
+ curve.getDegree());
477
+ }
478
+
479
+ /**
480
+ * Create a semi-circle NurbsCurve around the given Origin with radius r.
481
+ *
482
+ * @param o
483
+ * Origin to create semi-circle around.
484
+ * @param r
485
+ * Radius of the semi-circle
486
+ * @return A NurbsCurve for a semi-circle
487
+ */
488
+ public static NurbsCurve createSemiCircle(Origin3D o, float r) {
489
+ Vec4D[] cp = new Vec4D[4];
490
+ cp[0] = new Vec4D(o.xAxis.scale(r), 1);
491
+ cp[3] = cp[0].getInvertedXYZ();
492
+ cp[0].addXYZSelf(o.origin);
493
+ cp[3].addXYZSelf(o.origin);
494
+ cp[1] = new Vec4D(o.xAxis.add(o.yAxis).scaleSelf(r).addSelf(o.origin),
495
+ 0.5f);
496
+ cp[2] = new Vec4D(o.xAxis.getInverted().addSelf(o.yAxis).scaleSelf(r)
497
+ .addSelf(o.origin), 0.5f);
498
+
499
+ float[] u = {
500
+ 0, 0, 0, 0.5f, 1, 1, 1
501
+ };
502
+ return new BasicNurbsCurve(cp, u, 2);
503
+ }
504
+
505
+ /**
506
+ * Creates a {@link NurbsSurface} by swinging a profile {@link NurbsCurve}
507
+ * in the XZ plane around a trajectory curve in the XY plane. Both curves
508
+ * MUST be offset from the major axes (i.e. their control points should have
509
+ * non-zero coordinates for the Y coordinates of the profile curve and the Z
510
+ * coordinates of the trajectory).
511
+ *
512
+ * @param proj
513
+ * profile curve in XZ
514
+ * @param traj
515
+ * trajectory curve in XY
516
+ * @param alpha
517
+ * scale factor
518
+ * @return 3D NURBS surface
519
+ */
520
+ public static NurbsSurface createSwungSurface(NurbsCurve proj,
521
+ NurbsCurve traj, float alpha) {
522
+ Vec4D[] cpProj = proj.getControlPoints();
523
+ Vec4D[] cpTraj = traj.getControlPoints();
524
+
525
+ // The NURBS Book, Piegl, p.455,456
526
+ // http://books.google.co.uk/books?id=7dqY5dyAwWkC&pg=PA455&lpg=PA455
527
+ // fixed Z handling (was wrong in original jgeom version)
528
+ Vec4D[][] cps = new Vec4D[cpProj.length][cpTraj.length];
529
+ for (int i = 0; i < cpProj.length; i++) {
530
+ for (int j = 0; j < cpTraj.length; j++) {
531
+ Vec4D cp = new Vec4D();
532
+ cp.x = cpProj[i].x * cpTraj[j].x * alpha;
533
+ cp.y = cpProj[i].y * cpTraj[j].y * alpha;
534
+ cp.z = (cpProj[i].z + cpTraj[j].z) * alpha;
535
+ cp.w = cpProj[i].w * cpTraj[j].w;
536
+ cps[i][j] = cp;
537
+ }
538
+ }
539
+ return new BasicNurbsSurface(new ControlNet(cps), proj.getKnots(),
540
+ traj.getKnots(), proj.getDegree(), traj.getDegree());
541
+
542
+ }
543
+
544
+ /**
545
+ * Perform a linear extrusion of the given {@link NurbsCurve} along the
546
+ * supplied vector to produce a new {@link NurbsSurface}. The extrusion
547
+ * length is the length of the vector given.
548
+ *
549
+ * @param curve
550
+ * NURBS curve instance
551
+ * @param extrude
552
+ * a extrusion vector
553
+ * @return a NurbsSurface.
554
+ */
555
+ public static NurbsSurface extrudeCurve(NurbsCurve curve, Vec3D extrude) {
556
+
557
+ // Curve and Surface Construction using Rational B-splines
558
+ // Piegl and Tiller CAD Vol 19 #9 November 1987 pp 485-498
559
+ KnotVector vKnot = new KnotVector(new float[] {
560
+ 0f, 0f, 1f, 1f
561
+ }, 1);
562
+
563
+ Vec4D[][] cpoints = new Vec4D[curve.getControlPoints().length][2];
564
+ Vec4D[] curvePoints = curve.getControlPoints();
565
+ for (int i = 0; i < cpoints.length; i++) {
566
+ for (int j = 0; j < 2; j++) {
567
+ /*
568
+ * Change added 11/02/90 Steve Larkin : Have multiplied the term
569
+ * wcoord to the extrusion vector before adding to the curve
570
+ * coordinates. Not really sure this is the correct fix, but it
571
+ * works !
572
+ */
573
+ Vec4D cp = new Vec4D();
574
+ cp.x = curvePoints[i].x + j * extrude.x;
575
+ cp.y = curvePoints[i].y + j * extrude.y;
576
+ cp.z = curvePoints[i].z + j * extrude.z;
577
+ cp.w = curvePoints[i].w;
578
+ cpoints[i][j] = cp;
579
+ }
580
+ }
581
+ ControlNet cnet = new ControlNet(cpoints);
582
+ return new BasicNurbsSurface(cnet, curve.getKnots(), vKnot.getArray(),
583
+ curve.getDegree(), vKnot.getDegree());
584
+ }
585
+
586
+ /**
587
+ * Interpolates a NurbCurve form the given Points using a global
588
+ * interpolation technique.
589
+ *
590
+ * @param points
591
+ * Points to interpolate
592
+ * @param degree
593
+ * degree of the interpolated NurbsCurve
594
+ * @return A NurbsCurve interpolating the given Points
595
+ * @throws InterpolationException
596
+ * thrown if interpolation failed or is not possible.
597
+ */
598
+ public static NurbsCurve globalCurveInterpolation(Vec3D[] points, int degree)
599
+ throws InterpolationException {
600
+ try {
601
+ final int n = points.length;
602
+ final double[] A = new double[n * n];
603
+
604
+ final float[] uk = centripetal(points);
605
+ KnotVector uKnots = averaging(uk, degree);
606
+ for (int i = 0; i < n; i++) {
607
+ int span = uKnots.findSpan(uk[i]);
608
+ double[] tmp = uKnots.basisFunctions(span, uk[i]);
609
+ System.arraycopy(tmp, 0, A, i * n + span - degree, tmp.length);
610
+ }
611
+ final GMatrix a = new GMatrix(n, n, A);
612
+ final GVector perm = new GVector(n);
613
+ final GMatrix lu = new GMatrix(n, n);
614
+ a.computeLUD(lu, perm);
615
+
616
+ final Vec4D[] cps = new Vec4D[n];
617
+ for (int i = 0; i < cps.length; i++) {
618
+ cps[i] = new Vec4D(0, 0, 0, 1);
619
+ }
620
+
621
+ // x-ccordinate
622
+ final GVector b = new GVector(n);
623
+ for (int j = 0; j < n; j++) {
624
+ b.setElement(j, points[j].x);
625
+ }
626
+ final GVector sol = new GVector(n);
627
+ sol.backSolveLUD(lu, b, perm);
628
+ for (int j = 0; j < n; j++) {
629
+ cps[j].x = (float) sol.get(j);
630
+ }
631
+
632
+ // y-ccordinate
633
+ for (int j = 0; j < n; j++) {
634
+ b.setElement(j, points[j].y);
635
+ }
636
+ sol.zero();
637
+ sol.backSolveLUD(lu, b, perm);
638
+ for (int j = 0; j < n; j++) {
639
+ cps[j].y = (float) sol.get(j);
640
+ }
641
+
642
+ // z-ccordinate
643
+ for (int j = 0; j < n; j++) {
644
+ b.setElement(j, points[j].z);
645
+ }
646
+ sol.zero();
647
+ sol.backSolveLUD(lu, b, perm);
648
+ for (int j = 0; j < n; j++) {
649
+ cps[j].z = (float) sol.get(j);
650
+ }
651
+ return new BasicNurbsCurve(cps, uKnots);
652
+ } catch (SingularMatrixException ex) {
653
+ throw new InterpolationException(ex);
654
+ }
655
+
656
+ }
657
+
658
+ /**
659
+ * Interpolates a NurbsSurface from the given points using a gloabl
660
+ * interpolation technique.
661
+ *
662
+ * @param points
663
+ * Points arranged in a net (matrix) to interpolate
664
+ * @param uDegrees
665
+ * degree in u direction
666
+ * @param vDegrees
667
+ * degree in v direction
668
+ * @return A NurbsSurface interpolating the given points.
669
+ * @throws InterpolationException
670
+ * thrown if interpolation failed or is not possible.
671
+ */
672
+ public static NurbsSurface globalSurfaceInterpolation(Vec3D[][] points,
673
+ int uDegrees, int vDegrees) throws InterpolationException {
674
+ final int n = points.length;
675
+ final int m = points[0].length;
676
+ float[][] uv = surfaceMeshParameters(points, n - 1, m - 1);
677
+ KnotVector u = averaging(uv[0], uDegrees);
678
+ KnotVector v = averaging(uv[1], vDegrees);
679
+
680
+ Vec4D[][] r = new Vec4D[m][n];
681
+ Vec3D[] tmp = new Vec3D[n];
682
+ for (int l = 0; l < m; l++) {
683
+ for (int i = 0; i < n; i++) {
684
+ tmp[i] = points[i][l];
685
+ }
686
+ try {
687
+ NurbsCurve curve = globalCurveInterpolation(tmp, uDegrees);
688
+ r[l] = curve.getControlPoints();
689
+ } catch (InterpolationException ex) {
690
+ for (int i = 0; i < tmp.length; i++) {
691
+ r[l][i] = new Vec4D(tmp[i], 1);
692
+ }
693
+ }
694
+
695
+ }
696
+
697
+ Vec4D[][] cp = new Vec4D[n][m];
698
+ tmp = new Vec3D[m];
699
+ for (int i = 0; i < n; i++) {
700
+ for (int j = 0; j < m; j++) {
701
+ tmp[j] = r[j][i].to3D();
702
+ }
703
+ try {
704
+ NurbsCurve curve = globalCurveInterpolation(tmp, vDegrees);
705
+ cp[i] = curve.getControlPoints();
706
+ } catch (InterpolationException ex) {
707
+ for (int j = 0; j < tmp.length; j++) {
708
+ cp[i][j] = new Vec4D(tmp[j], 1);
709
+ }
710
+ }
711
+ }
712
+
713
+ return new BasicNurbsSurface(new ControlNet(cp), u, v);
714
+ }
715
+
716
+ private static void lineIntersect3D(Vec3D p0, Vec3D t0, Vec3D p2, Vec3D t2,
717
+ Vec3D out0, Vec3D out2) {
718
+ Vec3D v02 = p0.sub(p2);
719
+
720
+ double a = t0.dot(t0);
721
+ double b = t0.dot(t2);
722
+ double c = t2.dot(t2);
723
+ double d = t0.dot(v02);
724
+ double e = t2.dot(v02);
725
+ double denom = a * c - b * b;
726
+
727
+ double mu0, mu2;
728
+
729
+ if (denom < MathUtils.EPS) {
730
+ mu0 = 0;
731
+ mu2 = b > c ? d / b : e / c;
732
+ } else {
733
+ mu0 = (b * e - c * d) / denom;
734
+ mu2 = (a * e - b * d) / denom;
735
+ }
736
+
737
+ out0.set(t0.scale((float) mu0).addSelf(p0));
738
+ out2.set(t2.scale((float) mu2).addSelf(p2));
739
+ }
740
+
741
+ private static void pointToLine3D(ReadonlyVec3D p, ReadonlyVec3D t,
742
+ Vec3D top, Vec3D out) {
743
+ Vec3D dir = top.sub(p);
744
+ float hyp = dir.magnitude();
745
+ out.set(p.add(t.scale(t.dot(dir.normalize()) * hyp)));
746
+ }
747
+
748
+ private static float[][] surfaceMeshParameters(Vec3D points[][], int n,
749
+ int m) {
750
+ final float[][] res = new float[2][];
751
+ int num = m + 1;
752
+ final float[] cds = new float[(n + 1) * (m + 1)];
753
+ final float[] uk = new float[n + 1];
754
+ uk[n] = 1;
755
+ for (int l = 0; l <= m; l++) {
756
+ float total = 0;
757
+ for (int k = 1; k <= n; k++) {
758
+ cds[k] = points[k][l].distanceTo(points[k - 1][l]);
759
+ total += cds[k];
760
+ }
761
+ if (total == 0) {
762
+ num = num - 1;
763
+ } else {
764
+ float d = 0;
765
+ total = 1f / total;
766
+ for (int k = 1; k <= n; k++) {
767
+ d += cds[k];
768
+ uk[k] += d * total;
769
+ }
770
+ }
771
+ }
772
+ if (num == 0) {
773
+ return null;
774
+ }
775
+ float inum = 1f / num;
776
+ for (int k = 1; k < n; k++) {
777
+ uk[k] *= inum;
778
+ }
779
+
780
+ num = n + 1;
781
+ final float[] vk = new float[m + 1];
782
+ vk[m] = 1;
783
+ for (int l = 0; l <= n; l++) {
784
+ float total = 0;
785
+ Vec3D[] pl = points[l];
786
+ for (int k = 1; k <= m; k++) {
787
+ cds[k] = pl[k].distanceTo(pl[k - 1]);
788
+ total += cds[k];
789
+ }
790
+ if (total == 0) {
791
+ num = num - 1;
792
+ } else {
793
+ float d = 0;
794
+ total = 1f / total;
795
+ for (int k = 1; k <= m; k++) {
796
+ d += cds[k];
797
+ vk[k] += d * total;
798
+ }
799
+ }
800
+ }
801
+ if (num == 0) {
802
+ return null;
803
+ }
804
+ inum = 1f / num;
805
+ for (int k = 1; k < m; k++) {
806
+ vk[k] *= inum;
807
+ }
808
+ res[0] = uk;
809
+ res[1] = vk;
810
+ return res;
811
+ }
812
+
813
+ private NurbsCreator() {
814
+ }
815
+ }