three.js 箭头ArrowHelper的实践应用

效果:

代码:

html 复制代码
<template>
  <div>
    <el-container>
      <el-main>
        <div class="box-card-left">
          <div id="threejs" style="border: 1px solid red"></div>
        </div>
      </el-main>
    </el-container>
  </div>
</template>
<script>
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
export default {
  data() {
    return {
      sphereGeometry: null,
      group: null,
      camera: null,
      mesh: null,
      renderer: null,
      requestAnimationFrame_time: null,
      B: null,
      lengthVal: 0,
      normalizeVal: null,
      css3DRenderer: null,
    };
  },
  mounted() {
    this.name = this.$route.query.name;
    this.init();
  },
  methods: {
    goBack() {
      this.$router.go(-1);
    },
    init() {
      // 创建场景对象
      this.scene = new this.$three.Scene();
      // 调用方法创建点模型 A
      this.createPoint([0,40,0]);
      // 调用方法创建点模型 B
      this.createPoint([50,0,0]);
      this.createBox();
      // 创建环境光对象
      const ambientLight = new this.$three.AmbientLight(0xffffff,0.8);
      this.scene.add(ambientLight);
      // 创建箭头对象
      /**
       * ArrowHelper(dir : Vector3, origin : Vector3, length : Number, hex : Number, headLength : Number, headWidth : Number )
          dir -- 基于箭头原点的方向. 必须为单位向量.
          origin -- 箭头的原点.
          length -- 箭头的长度. 默认为 1.
          hex -- 定义的16进制颜色值. 默认为 0xffff00.
          headLength -- 箭头头部(锥体)的长度. 默认为箭头长度的0.2倍(0.2 * length).
          headWidth -- The width of the head of the arrow. Default is 0.2 * headLength.
       */
      /**
       * 计算箭头需要的参数;箭头是从A指向B
       */
      const A = new this.$three.Vector3(0,40,0);
      const B = new this.$three.Vector3(50,0,0);
      // 箭头方向的单位向量
      const dir = B.clone().sub(A).normalize();
      // 箭头原点 是 A
      const origin = A;
      // 箭头长度---就是 A 点到 B  点的距离;使用 length()方法可以计算得到
      const length = B.clone().sub(A).length();
      const hex = 0xffddaa;
      const arrowHelper = new this.$three.ArrowHelper(dir, origin, length, hex);
      this.scene.add(arrowHelper);
      // 创建坐标轴辅助对象
      const axesHelper = new this.$three.AxesHelper(200);
      this.scene.add(axesHelper);
      // 创建相机对象
      this.camera = new this.$three.PerspectiveCamera();
      this.camera.position.set(150,150,150);
      this.camera.lookAt(0,0,0);
      // 创建渲染器对象
      this.renderer = new this.$three.WebGLRenderer();
      this.renderer.setSize(1000,800);
      this.renderer.render(this.scene, this.camera);
      window.document.getElementById("threejs").appendChild(this.renderer.domElement);
      
      const controls = new OrbitControls(this.camera, this.renderer.domElement);
      controls.addEventListener("change", e => {
        this.renderer.render(this.scene, this.camera);
      })
    },
    /**
     * 创建点模型的方法,
     * point_position: 数组类型,数组里有且只有三个元素,
     *  */
    createPoint(point_position) {
      // 创建缓存几何体对象
      const bufferGeometry = new this.$three.BufferGeometry();
      // 创建类型化数组来存放顶点数据
      const vectors = new Float32Array(point_position);
      // 创建缓存属性来格式化顶点数据
      const bufferAttribute = new this.$three.BufferAttribute(vectors,3);
      // 设置缓存几何体的位置属性
      bufferGeometry.setAttribute("position", bufferAttribute);
      // 创建点材质对象
      const material = new this.$three.PointsMaterial({
        color: 0x99dd,
        size: 10
      });
      // 创建点模型对象
      const point = new this.$three.Points(bufferGeometry, material);
      this.scene.add(point);
    },
    createBox() {
      const geometry = new this.$three.BoxGeometry(50, 50, 50);
      const material = new this.$three.MeshLambertMaterial({
        color: 0x00ffff,
      });
      const mesh = new this.$three.Mesh(geometry, material);
      const p = mesh.geometry.attributes.position; // 顶点坐标集合
      const n = mesh.geometry.attributes.normal; // 顶点法线数据集合
      // 顶点数量
      const count = p.count;
      for(let i = 0; i < count; i ++) {
        // 该向量是单位向量了
        const dir = new this.$three.Vector3(n.getX(i), n.getY(i), n.getZ(i));
        // 箭头起点
        const origin = new this.$three.Vector3(p.getX(i), p.getY(i), p.getZ(i));
        const arrowHelper = new this.$three.ArrowHelper(dir, origin, 20);
        mesh.add(arrowHelper);
      }
      // mesh模型沿着 z 轴正向移动 50
      mesh.translateZ(50);
      this.scene.add(mesh);
    }
  },
};
</script>
<style lang="less" scoped>
.box-card-left {
  display: flex;
  align-items: flex-start;
  flex-direction: row;

  width: 100%;

  .box-right {
    img {
      width: 500px;
      user-select: none;
    }
  }
}
</style>
相关推荐
uppp»11 分钟前
深入理解 Java 反射机制:获取类信息与动态操作
java·开发语言
玩电脑的辣条哥2 小时前
Python如何播放本地音乐并在web页面播放
开发语言·前端·python
ew452182 小时前
ElementUI表格表头自定义添加checkbox,点击选中样式不生效
前端·javascript·elementui
画月的亮2 小时前
element-ui 使用过程中遇到的一些问题及解决方法
javascript·vue.js·ui
m0_526119402 小时前
点击el-dialog弹框跳到其他页面浏览器的滚动条消失了多了 el-popup-parent--hidden
javascript·vue.js·elementui
ll7788115 小时前
LeetCode每日精进:20.有效的括号
c语言·开发语言·算法·leetcode·职场和发展
工业甲酰苯胺5 小时前
Vue3 基础概念与环境搭建
前端·javascript·vue.js
lyj1689975 小时前
el-tree选中数据重组成树
javascript·vue.js·elementui
Jackson@ML6 小时前
Python数据可视化简介
开发语言·python·数据可视化
赵琳琅7 小时前
Java语言的云计算
开发语言·后端·golang