WEB 3D技术 three.js通过光线投射 完成几何体与外界的事件交互

本文 我们来说 光线投射
在这里插入图片描述
光线投射技术是用于3维空间场景中的交互事件

我们先编写代码如下

import './style.css'
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";const scene = new THREE.Scene();
const sphere1 =new THREE .Mesh(new THREE.SphereGeometry(1, 32, 32),new THREE.MeshBasicMaterial({color: 0x00FF00})
)
sphere1.position.x = -2;
scene.add(sphere1);const sphere2 = new THREE .Mesh(new THREE.SphereGeometry(1, 32, 32),new THREE.MeshBasicMaterial({color: 0x0000FF})
)
scene.add(sphere2);const sphere3 = new THREE .Mesh(new THREE.SphereGeometry(1, 32, 32),new THREE.MeshBasicMaterial({color:  0xFFE0FF})
)
sphere3.position.x = 2;
scene.add(sphere3);//创建相机
const camera = new THREE.PerspectiveCamera(45, //视角 视角越大  能看到的范围就越大window.innerWidth / window.innerHeight,//相机的宽高比  一般和画布一样大最好0.1,  //近平面  相机能看到最近的距离1000  //远平面  相机能看到最远的距离
);//c创建一个canvas容器  并追加到 body上
const renderer = new THREE.WebGLRenderer(0);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);//设置相机位置   这里 我们设置Z轴  大家可以试试  S Y 和 Z  都是可以的
camera.position.z = 5;
//设置相机默认看向哪里   三个 0  代表 默认看向原点
camera.lookAt(0, 0, 0);
//将内容渲染到元素上
renderer.render(scene, camera);
const controls = new OrbitControls(camera, renderer.domElement);function animate() {controls.update();requestAnimationFrame(animate);/*cube.rotation.x += 0.01;cube.rotation.y += 0.01;*/renderer.render(scene, camera);
}
animate();

这里 我们声明了三个圆形
运行结果如下
在这里插入图片描述
首先 我们加入 这样的代码

const raycaster = new THREE.Raycaster();
//创建鼠标向量 获取当前鼠标点击位置
const mouse = new THREE.Vector2();
window.addEventListener("click",(event) =>{})

首先 我们定义出 一个射线Raycaster
然后 用Vector2 鼠标点击位置
然后 用window 监听窗口的点击事件

其实 click 的 event 就能拿到点击位置

window.addEventListener("click",(event) =>{console.log(event.clientX,event.clientY);
})

获取 x y轴位置
此时 我们点击
控制台就会输出事件触发的坐标
在这里插入图片描述
然后 我们编写代码如下

import './style.css'
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";//创建相机
const camera = new THREE.PerspectiveCamera(45, //视角 视角越大  能看到的范围就越大window.innerWidth / window.innerHeight,//相机的宽高比  一般和画布一样大最好0.1,  //近平面  相机能看到最近的距离1000  //远平面  相机能看到最远的距离
);
const scene = new THREE.Scene();
const sphere1 =new THREE .Mesh(new THREE.SphereGeometry(1, 32, 32),new THREE.MeshBasicMaterial({color: 0x00FF00})
)
sphere1.position.x = -2;
scene.add(sphere1);const sphere2 = new THREE .Mesh(new THREE.SphereGeometry(1, 32, 32),new THREE.MeshBasicMaterial({color: 0x0000FF})
)
scene.add(sphere2);const sphere3 = new THREE .Mesh(new THREE.SphereGeometry(1, 32, 32),new THREE.MeshBasicMaterial({color:  0xFFE0FF})
)
sphere3.position.x = 2;
scene.add(sphere3);
//创建射线
const raycaster = new THREE.Raycaster();
//创建鼠标向量 获取当前鼠标点击位置
const mouse = new THREE.Vector2();
window.addEventListener("click",(event) =>{console.log(event.clientX,event.clientY);mouse.x = (event.clientX / window.innerWidth) * 2 - 1;mouse.y = -((event.clientY / window.innerHeight) * 2 - 1);raycaster.setFromCamera(mouse, camera);const intersects = raycaster.intersectObjects([sphere1, sphere2, sphere3]);console.log(intersects);
})//c创建一个canvas容器  并追加到 body上
const renderer = new THREE.WebGLRenderer(0);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);//设置相机位置   这里 我们设置Z轴  大家可以试试  S Y 和 Z  都是可以的
camera.position.z = 5;
//设置相机默认看向哪里   三个 0  代表 默认看向原点
camera.lookAt(0, 0, 0);
//将内容渲染到元素上
renderer.render(scene, camera);
const controls = new OrbitControls(camera, renderer.domElement);function animate() {controls.update();requestAnimationFrame(animate);/*cube.rotation.x += 0.01;cube.rotation.y += 0.01;*/renderer.render(scene, camera);
}
animate();

主要是 我们点击事件
先算出 鼠标当前相对坐标
然后 调用射线对象的 setFromCamera 他需要两个参数
第一个 Vector2 对象 x y轴用来确认触发事件的位置
第二个 是我们全局创建的相机对象 我们这里叫 camera
然后 raycaster.intersectObjects 绑定元素 帮助我们获取到被接触的几何体 这里 如果鼠标点击的位置 包括 我们传进去的三个几何体 就会被收集起来

我们运行代码 然后没有物体的位置
收集的数组就是个空的
在这里插入图片描述
我们点击其中一个几何体
控制台就输出了它收集到的内容
在这里插入图片描述
我们将点击事件的代码改成这样

window.addEventListener("click",(event) =>{console.log(event.clientX,event.clientY);mouse.x = (event.clientX / window.innerWidth) * 2 - 1;mouse.y = -((event.clientY / window.innerHeight) * 2 - 1);raycaster.setFromCamera(mouse, camera);const intersects = raycaster.intersectObjects([sphere1, sphere2, sphere3]);if (intersects.length > 0) {intersects[0].object.material.color.set(0xff0000);}
})

这里 我们看他收集的 intersects 如果长多超过 0 说明是拿到东西了的
我们将被收集的 0下标物体 材质对象中的 color 颜色字段 set成0xff0000 红色

运行代码 我们点击圆形 即可变为红色了
在这里插入图片描述

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

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

相关文章

添加 Android App Links

添加 Android App Links功能 介绍一个简单的效果Android配置Add Url intent filtersAdd logic to handle the intentAssociate website 搭建网页支持AppLinks 介绍 Android App Links 是指将用户直接转到 Android 应用内特定内容的 HTTP 网址。Android App Links 可为您的应用带…

机械过滤器(石英砂过滤器)和多介质过滤器的区别 工作原理动画

​ 1:机械过滤器多介质石英砂过滤器介绍 机械过滤器:预处理水质的关键设备 机械过滤器,也被称为压力式过滤器,是纯水制备过程中不可或缺的预处理设备。它在水处理系统中扮演着重要的角色,能够有效地去除水中的悬浮物…

《Python机器学习原理与算法实现》学习笔记

以下为《Python机器学习原理与算法实现》(杨维忠 张甜 著 2023年2月新书 清华大学出版社)的学习笔记。 根据输入数据是否具有“响应变量”信息,机器学习被分为“监督式学习”和“非监督式学习”。 “监督式学习”即输入数据中即有X变量&…

Linux服务器搭建笔记-006:拓展/home目录容量

一、问题说明 Ubuntu服务器在使用过程中创建的新用户,每位用户会在/home目录下生成一个属于其个人的主文件夹。如果不限制各个用户的使用空间,所有的用户都会共用/home所挂载的硬盘。在这种多用户情况下,会很快的填满/home目录,导…

uniapp 添加自定义图标

1. 下载自定义图标 在阿里图标库,选择喜欢的图标库 https://www.iconfont.cn/collections/index 建议按收藏数排序进行,能更快找到合适的图标 点开喜欢的图标库(如 Ant Design 官方图标库),将喜欢的图标添加到图标收集…

仿网易云音乐网站PHP源码,可运营的原创音乐分享平台源码,在线音乐库系统

源码介绍 使用PHP和MYSQL开发的原创音乐分享平台源码,仿网易云音乐网站。用户可以在网站上注册并上传自己的音乐作品,系统内置广告系统,为网站创造收入来源。 安装教程 1.导入sql.sql 2.修改 includes\config.php 数据库信息和网址都改成…

B2005 字符三角形(python)

a input() print( a) print( a a a) print(a a a a a)python中默认输入的是字符型,第一句就是输入了一个字符赋给a python中单引号内的也是字符串,用print输出需要连接的字符串时用加号加在后面即可

数据结构:基于数组的环形队列(循环队列)实现

1 前言 队列是一种先进先出的线性表,简称为FIFO。它只允许在队尾插入成员,在队头删除成员,就像现实生活中排队上车一样。 队列的实现可以通过链表或数组完成,一般来说都推荐使用链表来实现队列,使用数组实现队列时每次…

Casper Network 推出 “DevRewards” 计划:允许所有开发者赚取激励

Casper Association 是一个致力于推动区块链大规模采用的非营利组织,该组织在 Casper Network 系统中推出了一个被称为 “DevRewards ” 的奖励计划,旨在邀请开发者提交能够解决现有问题的创新技术方案,以帮助 Casper Network 系统进一步完善…

idea部署javaSE项目(awt+swing项目)_idea导入eclipse的javaSE项目

一.idea打开项目 选择需要部署的项目 二、设置JDK 三、引入数据库驱动包 四、执行sql脚本 四、修改项目的数据库连接 找到数据库连接文件 五.其他系统实现 JavaSwing实现学生选课管理系统 JavaSwing实现学校教务管理系统 JavaSwingsqlserver学生成绩管理系统 JavaSwing用…

c语言:用指针输入两个数组|练习题

一、题目 利用指针&#xff0c;输入两个数组 如图&#xff1a; 二、代码截图【带注释】 三、源代码【带注释】 #include <stdio.h> int main() { int a[50]; int b[50]; int *paa,*pbb; //输入第一组数组 printf("请输入第一组5个数字&#xff1a;…

计算机网络课程设计-企业网三层架构

&#xff08;单人版&#xff09; 摘 要 本篇报告主要解决了为一家名为西宫的公司网络搭建问题&#xff0c;该网络采用企业网三层架构对完了过进行设计。首先使用以太网中继&#xff0c;主要使用VLAN划分的技术来划定不同部门。使用MSTP对每个组配置生成树&#xff0c;防止交换机…

fastApi 项目部署

方式一&#xff0c;Uvicorn部署 Run a Server Manually - Uvicorn - FastAPI 1&#xff0c;linux服务器安装 python>3.8 2&#xff0c;安装 uvicorn : pip install "uvicorn[standard]" 3&#xff0c;上传项目到服务器 main.py from typing imp…

Leetcode每日一题周汇总 (12.24-12.30)

Leetcode每日一题周汇总 (12.24-12.30) 1.Sunday (12.24) 题目链接&#xff1a;1954. 收集足够苹果的最小花园周长 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你一个用无限二维网格表示的花园&#xff0c;每一个 整数坐标处都有一棵苹果树。整数坐标…

设计模式设计原则——依赖倒置原则(DIP)

DIP&#xff1a;Dependence Inversion Principle 原始定义&#xff1a;High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions。 官…

Stable Diffusion API入门:简明教程

Stable Diffusion 是一个先进的深度学习模型&#xff0c;用于创造和修改图像。这个模型能够基于文本描述来生成图像&#xff0c;让机器理解和实现用户的创意。使用这项技术的关键在于掌握其 API&#xff0c;通过编程来操控图像生成的过程。 在探索 Stable Diffusion API 的世界…

ROS TF坐标变换 - TF树

目录 一、TF树介绍二、TF2与TF三、构建TF树四、rviz查看TF坐标关系 一、TF树介绍 在机器人系统中&#xff0c;存在运动学模型和动力学模型。对于刚体机器人&#xff0c;动力学模型基于刚体动力学&#xff0c;代表机器人系统在运动过程中力/力矩与其运动状态的变化关系。而运动…

【索引的数据结构】第1章节:B+Tree存储结构

目录结构 之前整篇文章太长&#xff0c;阅读体验不好&#xff0c;将其拆分为几个子篇章。 本篇章讲解 BTree 存储结构。 什么是索引 可以简单理解为索引好比一本书的目录&#xff0c;通过目录我们可以快速定位到我们要查看的章节。 MySQL 中的数据同样也是根据索引分类&…

Vue中目录以及文件内容简单分析

src文件下目录分析&#xff1a; App.vue文件中内容&#xff1a; vue文件中基本的三个结构&#xff0c;template&#xff08;结构&#xff09;、script&#xff08;行为&#xff09; 、style&#xff08;样式&#xff09;。 <template><!-- html结构 --><div cl…

linux释放交换空间-Swap

确保剩余内存比swap内存空间大&#xff0c;再执行以下操作&#xff0c;否则会宕机&#xff01; 查看swap分区 swapon -s 会查看到你的swap分区位置 停止swap分区 停止swap分区是将swap内存释放到实际内存中 swapoff /dev/dm-1开启swap分区 swap分区内存成功释放到实际内…