1

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: enter image description here

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. enter image description here enter image description here enter image description here

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();
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Tintinabulator Zea
  • 2,617
  • 5
  • 18
  • 32

1 Answers1

2

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://cdn.jsdelivr.net/npm/three@0.124.0/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.124.0/examples/js/controls/OrbitControls.js"></script>
prisoner849
  • 16,894
  • 4
  • 34
  • 68
  • when i apply this to my object i can't get the same effect as the vase in codepen. My object uses z height and x and y for widths. this is what it looks like when i use Z for the radiall wave section https://imgur.com/a/ayQouUX and this is what it looks like when i use Y https://imgur.com/a/HEBrWr3 do i have to adjust the spherical to match the Z height of cylinder? – Tintinabulator Zea Jan 02 '19 at 21:20
  • @TintinabulatorZea you can rotate your geometry to align it along the Y-axis, apply all the operations, provided in the answer, then rotate the geometry back to the initial state. – prisoner849 Jan 02 '19 at 21:38
  • ok cool thank you! also, what do you think of this question https://stackoverflow.com/questions/54029401/how-to-bend-a-cylinder-in-three-js ? do you think this is possible? @prisoner849 – Tintinabulator Zea Jan 03 '19 at 20:32
  • @TintinabulatorZea You can find me on the forum: https://discourse.threejs.org. The same nickname :) Just ping me there somehow with a private message. – prisoner849 Jan 03 '19 at 23:36
  • @TintinabulatorZea I hope I've found a right person there with that skype nickname :D – prisoner849 Jan 04 '19 at 00:17