three.js 向量方向(归一化.normalize)

news2024/11/16 7:26:19

效果:

<template>
  <div>
    <el-container>
      <el-main>
        <div class="box-card-left">
          <div id="threejs" style="border: 1px solid red"></div>
          <div>
            <p>
              <el-button type="primary" @click="move()">沿着AB方向移动100</el-button>
              <el-button type="primary" @click="reset">重置</el-button>
            </p>
              <pre style="text-align: left;line-height: 20px;">
              已知直线AB上两个坐标,A点(-50,0,-50)、B点(100,0,100)。
              物体默认在A点,希望从A点开始沿着直线AB移动距离100,
              单位向量每个分量乘以100,得到的向量长度就是100,
              相当于得到一个沿着AB方向移动100的向量,
              这就是单位向量的意义,单位向量长度位1,
              乘以任何一个值S,就可以得到一个长度为S的向量。</pre>
          </div>
        </div>
      </el-main>
    </el-container>
  </div>
</template>
<script>
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { CSS3DObject, CSS3DSprite, CSS3DRenderer } from "three/examples/jsm/renderers/CSS3DRenderer.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,
      A: [-50,0,-50],
      B: [100,0,100]
    };
  },
  created() {},
  mounted() {
    this.name = this.$route.query.name;
    this.init();
  },
  methods: {
    goBack() {
      this.$router.go(-1);
    },
    init() {
      this.scene = new this.$three.Scene();
      const boxGeometry = new this.$three.BoxGeometry(30,40,50);
      const material = new this.$three.MeshBasicMaterial({color: 0x89aadd});
      this.mesh = new this.$three.Mesh(boxGeometry, material);
      this.scene.add(this.mesh);
      const axesHelper = new this.$three.AxesHelper(100);
      this.scene.add(axesHelper);

      this.createPoints(this.A, "A点");
      this.createPoints(this.B, "B点");
      this.createLine3();
      this.camera = new this.$three.PerspectiveCamera();
      this.camera.position.set(200,200,200);
      this.camera.lookAt(0,0,0);
      let v = new this.$three.Vector3();
      this.camera.getWorldDirection(v); // 获得相机视线方向的单位向量,并赋值给 v
      console.log(v);
      console.log(v.length());
      // 创建渲染器对象
      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);
      
      // 创建CSS3DRenderer 对象
      this.css3DRenderer = new CSS3DRenderer();
      this.css3DRenderer.setSize(1000,800);
      this.css3DRenderer.render(this.scene, this.camera);
      this.css3DRenderer.domElement.style.position = 'absolute';
      this.css3DRenderer.domElement.style.top = 0;
      this.css3DRenderer.domElement.style.pointerEvents = 'none';

      window.document.getElementById("threejs").appendChild(this.css3DRenderer.domElement);


      const controls = new OrbitControls(this.camera, this.renderer.domElement);
      controls.addEventListener("change", e => {
        this.renderer.render(this.scene, this.camera);
      })
      this.loopFun();
    },
    loopFun() {
      this.css3DRenderer.render(this.scene, this.camera);
      requestAnimationFrame(this.loopFun);
    },
    normalize_fn() {
      const A = new this.$three.Vector3(10,20,30);
      this.normalizeVal = A.normalize();
    },
    // 已知直线AB上两个坐标,A点(-50,0,-50)、B点(100,0,100)。物体默认在A点,希望从A点开始沿着直线AB移动距离100。
    createPoints(pointsArr, name) {
      // 创建缓存几何体对象
      const bufferGeometry = new this.$three.BufferGeometry();
      // 创建类型化数组来保存顶点数据
      // const vertices = new Float32Array([-50,0,-50]);
      const vertices = new Float32Array(pointsArr);
      // 通过创建  缓存属性对象  来表示顶点数据
      const attribute = new this.$three.BufferAttribute(vertices, 3);
      // 缓存几何体设置属性 position
      bufferGeometry.setAttribute("position", attribute);
      // 创建点材质对象
      const pointMaterial = new this.$three.PointsMaterial({
        color: 0xffaadd, // 点颜色
        size: 10, // 点大小
      });
      // 创建点对象
      const points = new this.$three.Points(bufferGeometry, pointMaterial);
      points.name = name;
      const dom = this.createDom(name);
      const sprite = new CSS3DSprite(dom);
      let x = pointsArr[0];
      let y = pointsArr[1] + 10;
      let z = pointsArr[2];
      sprite.position.set(x,y,z);
      // sprite.scale.set(0.5,0.5,0.5);
      points.add(sprite);
      this.scene.add(points);
    },
    createDom(text) {
      const dom = document.createElement("div");
      dom.style.border = '1px solid blue';
      dom.style.borderRadius = '5px';
      dom.style.fontSize = '14px';
      dom.style.padding = '1px 10px';
      dom.innerText = text;
      return dom;
    },
    move() {
      let A = new this.$three.Vector3(-50,0,-50);
      let B = new this.$three.Vector3(100,0,100);
      let AB = B.clone().sub(A);
      AB.normalize();
      const T = AB.clone().multiplyScalar(100);
      this.mesh.position.add(T);
      this.renderer.render(this.scene, this.camera);
    },
    reset() {
      this.mesh.position.set(0,0,0);
      this.renderer.render(this.scene, this.camera);
    },
    // 创建直线
    createLine3() {
      // 创建缓存几何体对象
      const bufferGeometry = new this.$three.BufferGeometry();
      let A = new this.$three.Vector3(-50,0,-50);
      let B = new this.$three.Vector3(100,0,100);
      let line3 = new this.$three.LineCurve3(A, B);
      let pointes = line3.getPoints(200);
      bufferGeometry.setFromPoints(pointes);
      const material = new this.$three.LineBasicMaterial({color: 0xffffff});
      const line = new this.$three.Line(bufferGeometry, material);
      this.scene.add(line);
    }
  },
};
</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>

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1436033.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Springboot启动出现Waiting for changelog lock...问题

今天在开发的时候&#xff0c;Springboot启动的时候出现Waiting for changelog lock…问题. 问题原因&#xff1a;该问题就是发生了数据库的死锁问题&#xff0c;可能是由于一个杀死的liquibase进程没有释放它对DATABASECHANGELOGLOCK表的锁定&#xff0c;导致服务启动失败&…

Blender_查看版本

Blender_查看版本 烦人的烦恼&#xff0c;没找见哪儿可以查看版本&#xff1f; 算是个隐蔽的角落&#xff01;

Rust-获取随机数练习案例

文章目录 前言一、取官网示例猜数字游戏玩一玩cargo checkTOML文件 二、完整代码总结 前言 Rust学习系列-获取随机数练习案例&#xff0c;基于cargo 进行案例练习&#xff0c;过程中会使用cargo check&#xff1b; cargo run&#xff1b;等命名&#xff0c;同时了解基础的let …

【Java EE】----Bean的作用域和生命周期

1.Bean的作用域 定义&#xff1a;Bean 的作⽤域是指 Bean 在 Spring 整个框架中的某种⾏为模式&#xff0c;⽐如 singleton 单例作⽤域&#xff0c;就 表示 Bean 在整个 Spring 中只有⼀份 &#xff08;产生的原因&#xff0c;Bean 默认情况下是单例状态&#xff08;singleton&…

2024数据分析管理、数字经济与教育国际学术会议(ICDAMDEE2024)

会议简介 2024年数据分析管理、数字经济和教育国际学术会议&#xff08;ICDAMDEE 2024&#xff09;将在武汉举行。会议不仅展示了来自世界各地的研究专家围绕数据分析管理、数字经济和教育的最新科研成果&#xff0c;还为来自不同地区的代表们提供了面对面的交流意见和实验经验…

编程实例分享,宠物诊所电子处方怎么开,兽医电子处方模板电子版操作教程

编程实例分享&#xff0c;宠物诊所电子处方怎么开&#xff0c;兽医电子处方模板电子版操作教程 一、前言 以下操作教程以 佳易王兽医电子处方软件V16.0为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 1、在系统 设置里可以设置打印参数&#x…

【Docker】了解Docker Desktop桌面应用程序,TA是如何管理和运行Docker容器(2)

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是《Docker容器》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对…

【Spring】Spring事务和事务传播机制

文章目录 什么是事务事务的操作Spring 中事务的实现Spring编程式事务Spring 声明式事务 TransactionalTransactional作用Transactional 详解rollbackFor事务隔离级别Spring 事务隔离级别Spring 事务传播机制 什么是事务 事务&#xff08;Transaction&#xff09;是一个程序中一…

最新的 Ivanti SSRF 零日漏洞正在被大规模利用

Bleeping Computer 网站消息&#xff0c;安全研究员发现 Ivanti Connect Secure 和 Ivanti Policy Secure 服务器端请求伪造 (SSRF) 漏洞&#xff08;CVE-2024-21893 &#xff09;正在被多个威胁攻击者大规模利用。 2024 年 1 月 31 日&#xff0c;Ivanti 首次就网关 SAML 组件…

Vivado-IP核

Vivado-IP核 主程序 timescale 1ns / 1ps ////module ip_clk_wiz(input sys_clk,input sys_rst_n,output clk_out1,output clk_out2,output clk_out3,output clk_out4,output locked);clk_wiz_0 instance_name(// Clock out ports.clk_out1(clk_out1), // output clk_out…

java设计模式- 建造者模式

一 需求以及实现方式 1.1 需求描述 我们要创建一个表示汽车的复杂对象&#xff0c;汽车包含发动机、轮胎和座椅等部分。用传统方式创建&#xff0c;代码如下 1.2 传统实现方式 1.抽象类 public abstract class BuildCarAbstaract {//引擎public abstract void buildEng…

OpenGL 入门(十)— 光照系统

光照系统 前言平行光点光源衰减衰减的实现 聚光平滑/软化边缘 多光源 前言 介绍三种光源类型&#xff1a;平行光&#xff08;Directional Light&#xff09;、点光源&#xff08;Point Light&#xff09;、聚光灯(Spot Light)。 平行光(Directional Light)&#xff1a;只有一…

【力扣】整数反转,判断是否溢出的数学解法

整数反转原题地址 方法一&#xff1a;数学 反转整数 如何反转一个整数呢&#xff1f;考虑整数操作的3个技巧&#xff1a; xmod10可以取出x的最低位&#xff0c;如x123&#xff0c;xmod103。x/10可以去掉x的最低位&#xff0c;如x123&#xff0c;x/10&#xff0c;x12。xx*10…

C# CAD交互界面-自定义面板集(四)

运行环境 vs2022 c# cad2016 调试成功 一、程序说明 创建自定义面板集&#xff08;PaletteSet&#xff09;的C#命令方法实现。该方法名为CreatePalette&#xff0c;当在AutoCAD环境中调用此命令时&#xff0c;会执行以下操作&#xff1a; 获取AutoCAD主应用对象&#xff1…

docer compose部署simple-docker

简介 一个看似简陋但是功能足够用的docker管理工具 安装 创建目录 mkdir -p /opt/simple-docker cd /opt/simple-docker 创建并启动容器 编写docker-compose.yml文件,内容如下 version: 3 services: redis: image: redis:latest restart: always web: image: registry.cn-…

APP攻防-资产收集篇FridaHOOKXposed证书提取单向双向检验抓包mobsf

知识点 1、单向校验-XP框架&Frida&HOOK 2、双向校验-Frida&HOOK&导入证书 一、演示案例-APP-综合分析-Mobexler&MobSF识别 mobsf 移动安全框架 (MobSF) 是一种自动化的一体化移动应用程序 (Android/iOS/Windows) 渗透测试、恶意软件分析和安全评估框架…

Elasticsearch:BM25 及 使用 Elasticsearch 和 LangChain 的自查询检索器

本工作簿演示了 Elasticsearch 的自查询检索器将非结构化查询转换为结构化查询的示例&#xff0c;我们将其用于 BM25 示例。 在这个例子中&#xff1a; 我们将摄取 LangChain 之外的电影样本数据集自定义 ElasticsearchStore 中的检索策略以仅使用 BM25使用自查询检索将问题转…

Fate-Serving推理服务源码解读

https://fate-serving.readthedocs.io/en/develop/?queryguest 什么是Fate-Serving fate-serving是FATE的在线部分&#xff0c;在使用FATE进行联邦建模完成之后&#xff0c;可以使用fate-serving进行包括单笔预测、多笔预测以及多host预测在内的在线联合预测。 模型的初始化流…

用友U8 Cloud ReportDetailDataQuery SQL注入漏洞复现(QVD-2023-47860)

0x01 产品简介 用友U8 Cloud 提供企业级云ERP整体解决方案,全面支持多组织业务协同,实现企业互联网资源连接。 U8 Cloud 亦是亚太地区成长型企业最广泛采用的云解决方案。 0x02 漏洞概述 用友U8 cloud ReportDetailDataQuery 接口处存在SQL注入漏洞,攻击者未经授权可以访…

adb push 将电脑中的文件传输到安卓开发板

1. adb remount 重新挂载设备的文件系统&#xff0c;以便可以对设备进行读写操作&#xff0c;通常情况下&#xff0c;安卓开发板在连接到计算机后&#xff0c;设备的文件系统会被挂载为只读文件系统&#xff0c;重新挂载后变成可读可写权限 C:\Users\Administrator>adb re…