How to make a wave pattern circularly around a cylinder?

回眸只為那壹抹淺笑 提交于 2019-12-11 04:12:35

问题


Hello i'm trying to make a wave pattern on the surface of a cylinder. The waves should rotate with the rotation of the surface. and in a way the sine period is moving in circles, and the amplitudes are long mounds on the surface. Here's some pictures to better explain what i mean.

This is what i'm trying to get the top down view of the cylinder to look similar to:

this is the top view of my cylinder. I'd like the wave to change direction with the rotation of the circle, so it looks the same from all directions.

I feel like i'm very close, i'm just not sure what quaternion or angle to multiply against the vector:

    var geometry = this.threeDHandler.threeD_meshes[0].geometry;
    var vec3 = new THREE.Vector3(); // temp vector

    for (let i = 0; i < geometry.vertices.length; i++) {
      vec3.copy(geometry.vertices[i]); // copy current vertex to the temp vector
      vec3.setX(0); 
      vec3.normalize(); // normalize


      //part i'm confsude about
      const quaternion = new THREE.Quaternion();
      const xPos = geometry.vertices[i].x;

      //trying to twist the sine around the circle
      const twistAmount = 100;
      const upVec = new THREE.Vector3(0, 0, 1);
      quaternion.setFromAxisAngle(
          upVec, 
          (Math.PI / 180) * (xPos / twistAmount)
        );


      vec3.multiplyScalar(Math.sin((geometry.vertices[i].x* Math.PI) * period) * amplitude) // multiply with sin function
      geometry.vertices[i].add(vec3); // add the temp vector to the current vertex

      geometry.vertices[i].applyQuaternion(quaternion);

    }
    geometry.verticesNeedUpdate = true;
    geometry.computeVertexNormals();

回答1:


You can use absolute value of the sin function of the angle, that a vertex belongs to.

In this case you can use THREE.Spherical() object that allows to get spherical coordinates of a vector:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 6);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var cylinderGeom = new THREE.CylinderGeometry(1, 1, 4, 128, 40, true);

var vec3 = new THREE.Vector3(); // temp vector
var vec3_2 = new THREE.Vector3(); // temp vector 2
var spherical = new THREE.Spherical();
cylinderGeom.vertices.forEach(v => {
  vec3.copy(v); // copy current vertex to the temp vector
  vec3.setY(0); // leave x and z (thus the vector is parallel to XZ plane)
  vec3.normalize(); // normalize
  vec3.multiplyScalar(Math.sin(v.y * Math.PI) * 0.25) // multiply with sin function

  // radial wave
  vec3_2.copy(v).setY(0).normalize();
  spherical.setFromVector3(vec3_2);
  vec3_2.setLength(Math.abs(Math.sin((spherical.theta * 4) + v.y * 2) * 0.25));

  v.add(vec3).add(vec3_2); // add the temp vectors to the current vertex
})


cylinderGeom.computeVertexNormals();

var cylinder = new THREE.Mesh(cylinderGeom, new THREE.MeshNormalMaterial({
  side: THREE.DoubleSide,
  wireframe: false
}));
scene.add(cylinder);

renderer.setAnimationLoop(() => {
  renderer.render(scene, camera);
})
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>


来源:https://stackoverflow.com/questions/54003693/how-to-make-a-wave-pattern-circularly-around-a-cylinder

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!