Use vue to learn three.js geometry-three-dimensional cylinder CylinderGeometry

Introduction and use of CylinderGeometry geometry

1. Introduction to CylinderGeometry

CylinderGeometry can be used to create a three-dimensional cylinder, you can enter the following parameters when creating:

Attributes have to description
radiusTop no This property defines the radius of the circle at the top of the cylinder, the default value is 20
radiusBottom no This attribute defines the radius of the circle at the bottom of the cylinder, the default value is 20
height no This attribute defines the height of the cylinder, the default is 100
segmentsX no This attribute specifies how many segments are divided along the X axis. The more segments, the smoother the cylinder. The default value is 8.
segmentsY no This attribute specifies how many segments are divided along the Y axis. The more the number of segments, the more faces the cylinder is divided into in the vertical direction. The default value is 1.
openEnded no This attribute is used to specify whether the top and bottom of the cylinder are closed, the default is false

The way to create a three-dimensional cylinder is as follows:
const geom = new THREE.CylinderGeometry(radiusTop,radiusBottom,height, segmentX, segmentsY, openEnded)

Similarly, the parameters we need when creating a cylinder are all stored in a parameter attribute. If you want to get these parameter values, you can get it through this attribute.

2.demo description

Insert picture description here

As shown above, this example supports the following functions

  1. Adjust the radius of the top of the cylinder through the radiusTop property
  2. Adjust the radius of the bottom of the cylinder through the radiusBottom property
  3. Adjust the height of the cylinder through the height property
  4. Adjust the number of circle segments at the top and bottom of the cylinder through the segmentsX property
  5. Adjust the number of segments in the Y-axis direction of the cylinder through the segmentsY property
  6. Adjust whether the bottom and top of the cylinder are closed through the openEnded property

3.demo code

<template>
  <div>
    <div id="container"></div>
    <div class="controls-box">
      <section>
        <el-row>
          <div v-for="(item,key) in properties" :key="key">
            <div v-if="item&&item.name!=undefined">
              <el-col :span="8">
                <span class="vertice-span">{
    
    {
    
    item.name}}</span>
              </el-col>
              <el-col :span="13">
                <el-slider v-model="item.value" :min="item.min" :max="item.max" :step="item.step" :format-tooltip="formatTooltip"></el-slider>
              </el-col>
              <el-col :span="3">
                <span class="vertice-span">{
    
    {
    
    item.value}}</span>
              </el-col>
            </div>
          </div>
        </el-row>
        <el-row>
          <el-checkbox v-model="properties.openEnded">openEnded</el-checkbox>
        </el-row>
      </section>
    </div>
  </div>
</template>

<script>
import * as THREE from 'three'
import {
    
     OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import {
    
     SceneUtils } from 'three/examples/jsm/utils/SceneUtils.js'
export default {
    
    
  data() {
    
    
    return {
    
    
      properties: {
    
    
        radiusTop: {
    
    
          name: 'radiusTop',
          value: 20,
          min: -40,
          max: 40,
          step: 1
        },
        radiusBottom: {
    
    
          name: 'radiusBottom',
          value: 20,
          min: -40,
          max: 40,
          step: 1
        },
        height: {
    
    
          name: 'height',
          value: 20,
          min: 0,
          max: 40,
          step: 1
        },

        segmentsX: {
    
    
          name: 'segmentsX',
          value: 10,
          min: 0,
          max: 40,
          step: 1
        },
        segmentsY: {
    
    
          name: 'segmentsY',
          value: 10,
          min: 0,
          max: 40,
          step: 1
        },
        openEnded: false
      },
      mesh: null,
      camera: null,
      scene: null,
      renderer: null,
      controls: null
    }
  },
  mounted() {
    
    
    this.init()
  },
  methods: {
    
    
    formatTooltip(val) {
    
    
      return val
    },
    // 初始化
    init() {
    
    
      this.createScene() // 创建场景
      this.createMesh() // 创建网格模型
      this.createLight() // 创建光源
      this.createCamera() // 创建相机
      this.createRender() // 创建渲染器
      this.createControls() // 创建控件对象
      this.render() // 渲染
    },
    // 创建场景
    createScene() {
    
    
      this.scene = new THREE.Scene()
    },
    // 创建网格模型
    createMesh() {
    
    
      //创建圆柱
      const geom = new THREE.CylinderGeometry(
        this.properties.radiusTop.value,
        this.properties.radiusBottom.value,
        this.properties.height.value,
        this.properties.segmentsX.value,
        this.properties.segmentsY.value,
        this.properties.openEnded
      )
      // 创建材质
      const meshMaterial = new THREE.MeshNormalMaterial({
    
    
        side: THREE.DoubleSide
      })
      const wireFrameMat = new THREE.MeshBasicMaterial({
    
     wireframe: true })

      // 添加组合材质
      this.mesh = SceneUtils.createMultiMaterialObject(geom, [
        meshMaterial,
        wireFrameMat
      ])

      // 网格对象添加到场景中
      this.scene.add(this.mesh)
    },

    // 创建光源
    createLight() {
    
    
      // 环境光
      const ambientLight = new THREE.AmbientLight(0xffffff, 0.1) // 创建环境光
      this.scene.add(ambientLight) // 将环境光添加到场景

      const spotLight = new THREE.SpotLight(0xffffff) // 创建聚光灯
      spotLight.position.set(-40, 60, -10)
      spotLight.castShadow = true
      this.scene.add(spotLight)
    },
    // 创建相机
    createCamera() {
    
    
      const element = document.getElementById('container')
      const width = element.clientWidth // 窗口宽度
      const height = element.clientHeight // 窗口高度
      const k = width / height // 窗口宽高比
      // PerspectiveCamera( fov, aspect, near, far )
      this.camera = new THREE.PerspectiveCamera(35, k, 0.1, 1000)
      this.camera.position.set(-80, 60, 40) // 设置相机位置

      this.camera.lookAt(new THREE.Vector3(10, 0, 0)) // 设置相机方向
      this.scene.add(this.camera)
    },
    // 创建渲染器
    createRender() {
    
    
      const element = document.getElementById('container')
      this.renderer = new THREE.WebGLRenderer({
    
     antialias: true, alpha: true })
      this.renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸
      this.renderer.shadowMap.enabled = true // 显示阴影
      this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
      this.renderer.setClearColor(0x3f3f3f, 1) // 设置背景颜色
      element.appendChild(this.renderer.domElement)
    },

    // 更新属性
    updateFun() {
    
    
      const tempRotationY = this.mesh.rotation.y
      this.scene.remove(this.mesh)
      this.createMesh()
      this.mesh.rotation.y += tempRotationY + 0.01
    },
    render() {
    
    
      this.updateFun()
      this.renderer.render(this.scene, this.camera)
      requestAnimationFrame(this.render)
    },
    // 创建控件对象
    createControls() {
    
    
      this.controls = new OrbitControls(this.camera, this.renderer.domElement)
    }
  }
}
</script>
<style>
#container {
    
    
  position: absolute;
  width: 100%;
  height: 100%;
}
.controls-box {
    
    
  position: absolute;
  right: 5px;
  top: 5px;
  width: 300px;
  padding: 10px;
  background-color: #fff;
  border: 1px solid #c3c3c3;
}
.vertice-span {
    
    
  line-height: 38px;
  padding: 0 2px 0 10px;
}
</style>

Guess you like

Origin blog.csdn.net/qw8704149/article/details/109954872