ParametricGeometries.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*
  2. * @author zz85
  3. *
  4. * Experimenting of primitive geometry creation using Surface Parametric equations
  5. *
  6. */
  7. THREE.ParametricGeometries = {
  8. klein: function (v, u) {
  9. u *= Math.PI;
  10. v *= 2 * Math.PI;
  11. u = u * 2;
  12. var x, y, z;
  13. if (u < Math.PI) {
  14. x = 3 * Math.cos(u) * (1 + Math.sin(u)) + (2 * (1 - Math.cos(u) / 2)) * Math.cos(u) * Math.cos(v);
  15. z = -8 * Math.sin(u) - 2 * (1 - Math.cos(u) / 2) * Math.sin(u) * Math.cos(v);
  16. } else {
  17. x = 3 * Math.cos(u) * (1 + Math.sin(u)) + (2 * (1 - Math.cos(u) / 2)) * Math.cos(v + Math.PI);
  18. z = -8 * Math.sin(u);
  19. }
  20. y = -2 * (1 - Math.cos(u) / 2) * Math.sin(v);
  21. return new THREE.Vector3(x, y, z);
  22. },
  23. plane: function (width, height) {
  24. return function(u, v) {
  25. var x = u * width;
  26. var y = 0;
  27. var z = v * height;
  28. return new THREE.Vector3(x, y, z);
  29. };
  30. },
  31. mobius: function(u, t) {
  32. // flat mobius strip
  33. // http://www.wolframalpha.com/input/?i=M%C3%B6bius+strip+parametric+equations&lk=1&a=ClashPrefs_*Surface.MoebiusStrip.SurfaceProperty.ParametricEquations-
  34. u = u - 0.5;
  35. var v = 2 * Math.PI * t;
  36. var x, y, z;
  37. var a = 2;
  38. x = Math.cos(v) * (a + u * Math.cos(v/2));
  39. y = Math.sin(v) * (a + u * Math.cos(v/2));
  40. z = u * Math.sin(v/2);
  41. return new THREE.Vector3(x, y, z);
  42. },
  43. mobius3d: function(u, t) {
  44. // volumetric mobius strip
  45. u *= Math.PI;
  46. t *= 2 * Math.PI;
  47. u = u * 2;
  48. var phi = u / 2;
  49. var major = 2.25, a = 0.125, b = 0.65;
  50. var x, y, z;
  51. x = a * Math.cos(t) * Math.cos(phi) - b * Math.sin(t) * Math.sin(phi);
  52. z = a * Math.cos(t) * Math.sin(phi) + b * Math.sin(t) * Math.cos(phi);
  53. y = (major + x) * Math.sin(u);
  54. x = (major + x) * Math.cos(u);
  55. return new THREE.Vector3(x, y, z);
  56. }
  57. };
  58. /*********************************************
  59. *
  60. * Parametric Replacement for TubeGeometry
  61. *
  62. *********************************************/
  63. THREE.ParametricGeometries.TubeGeometry = function(path, segments, radius, segmentsRadius, closed, debug) {
  64. this.path = path;
  65. this.segments = segments || 64;
  66. this.radius = radius || 1;
  67. this.segmentsRadius = segmentsRadius || 8;
  68. this.closed = closed || false;
  69. if (debug) this.debug = new THREE.Object3D();
  70. var scope = this,
  71. tangent, normal, binormal,
  72. numpoints = this.segments + 1,
  73. x, y, z, tx, ty, tz, u, v,
  74. cx, cy, pos, pos2 = new THREE.Vector3(),
  75. i, j, ip, jp, a, b, c, d, uva, uvb, uvc, uvd;
  76. var frames = new THREE.TubeGeometry.FrenetFrames(path, segments, closed),
  77. tangents = frames.tangents,
  78. normals = frames.normals,
  79. binormals = frames.binormals;
  80. // proxy internals
  81. this.tangents = tangents;
  82. this.normals = normals;
  83. this.binormals = binormals;
  84. var ParametricTube = function(u, v) {
  85. v *= 2 * Math.PI;
  86. i = u * (numpoints - 1);
  87. i = Math.floor(i);
  88. pos = path.getPointAt(u);
  89. tangent = tangents[i];
  90. normal = normals[i];
  91. binormal = binormals[i];
  92. if (scope.debug) {
  93. scope.debug.add(new THREE.ArrowHelper(tangent, pos, radius, 0x0000ff));
  94. scope.debug.add(new THREE.ArrowHelper(normal, pos, radius, 0xff0000));
  95. scope.debug.add(new THREE.ArrowHelper(binormal, pos, radius, 0x00ff00));
  96. }
  97. cx = -scope.radius * Math.cos(v); // TODO: Hack: Negating it so it faces outside.
  98. cy = scope.radius * Math.sin(v);
  99. pos2.copy(pos);
  100. pos2.x += cx * normal.x + cy * binormal.x;
  101. pos2.y += cx * normal.y + cy * binormal.y;
  102. pos2.z += cx * normal.z + cy * binormal.z;
  103. return pos2.clone();
  104. };
  105. THREE.ParametricGeometry.call(this, ParametricTube, segments, segmentsRadius);
  106. };
  107. THREE.ParametricGeometries.TubeGeometry.prototype = Object.create( THREE.Geometry.prototype );
  108. /*********************************************
  109. *
  110. * Parametric Replacement for TorusKnotGeometry
  111. *
  112. *********************************************/
  113. THREE.ParametricGeometries.TorusKnotGeometry = function ( radius, tube, segmentsR, segmentsT, p, q, heightScale ) {
  114. var scope = this;
  115. this.radius = radius || 200;
  116. this.tube = tube || 40;
  117. this.segmentsR = segmentsR || 64;
  118. this.segmentsT = segmentsT || 8;
  119. this.p = p || 2;
  120. this.q = q || 3;
  121. this.heightScale = heightScale || 1;
  122. var TorusKnotCurve = THREE.Curve.create(
  123. function() {
  124. },
  125. function(t) {
  126. t *= Math.PI * 2;
  127. var r = 0.5;
  128. var tx = (1 + r * Math.cos(q * t)) * Math.cos(p * t),
  129. ty = (1 + r * Math.cos(q * t)) * Math.sin(p * t),
  130. tz = r * Math.sin(q * t);
  131. return new THREE.Vector3(tx, ty * heightScale, tz).multiplyScalar(radius);
  132. }
  133. );
  134. var segments = segmentsR;
  135. var radiusSegments = segmentsT;
  136. var extrudePath = new TorusKnotCurve();
  137. THREE.ParametricGeometries.TubeGeometry.call( this, extrudePath, segments, tube, radiusSegments, true, false );
  138. };
  139. THREE.ParametricGeometries.TorusKnotGeometry.prototype = Object.create( THREE.Geometry.prototype );
  140. /*********************************************
  141. *
  142. * Parametric Replacement for SphereGeometry
  143. *
  144. *********************************************/
  145. THREE.ParametricGeometries.SphereGeometry = function(size, u, v) {
  146. function sphere(u, v) {
  147. u *= Math.PI;
  148. v *= 2 * Math.PI;
  149. var x = size * Math.sin(u) * Math.cos(v);
  150. var y = size * Math.sin(u) * Math.sin(v);
  151. var z = size * Math.cos(u);
  152. return new THREE.Vector3(x, y, z);
  153. }
  154. THREE.ParametricGeometry.call(this, sphere, u, v, !true);
  155. };
  156. THREE.ParametricGeometries.SphereGeometry.prototype = Object.create( THREE.Geometry.prototype );
  157. /*********************************************
  158. *
  159. * Parametric Replacement for PlaneGeometry
  160. *
  161. *********************************************/
  162. THREE.ParametricGeometries.PlaneGeometry = function(width, depth, segmentsWidth, segmentsDepth) {
  163. function plane(u, v) {
  164. var x = u * width;
  165. var y = 0;
  166. var z = v * depth;
  167. return new THREE.Vector3(x, y, z);
  168. }
  169. THREE.ParametricGeometry.call(this, plane, segmentsWidth, segmentsDepth);
  170. };
  171. THREE.ParametricGeometries.PlaneGeometry.prototype = Object.create( THREE.Geometry.prototype );