Как сделать круговой рисунок вокруг цилиндра? - PullRequest
0 голосов
/ 02 января 2019

Здравствуйте, я пытаюсь создать волновую картину на поверхности цилиндра.Волны должны вращаться с вращением поверхности.и таким образом, период синуса движется по кругу, а амплитуды представляют собой длинные насыпи на поверхности.Вот несколько фотографий, чтобы лучше объяснить, что я имею в виду.

Это то, что я пытаюсь получить вид цилиндра сверху вниз, чтобы он выглядел примерно так: enter image description here

это вид сверху моего цилиндра.Я бы хотел, чтобы волна меняла направление при вращении круга, чтобы она выглядела одинаково со всех сторон.enter image description here enter image description here enter image description here

Я чувствую, что я очень близок, я просто не уверен, что кватернионили угол для умножения на вектор:

    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 Ответ

0 голосов
/ 02 января 2019

Вы можете использовать абсолютное значение функции sin угла, которому принадлежит вершина.

В этом случае вы можете использовать THREE.Spherical() объект, который позволяет получить сферические координаты вектора:

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://cdnjs.cloudflare.com/ajax/libs/three.js/100/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
...