参考:光线投射器(Raycaster)、ThreeJS中的点击与交互——Raycaster的用法

该类用来处理光线投射。光线投射主要用于物体选择、碰撞检测以及图像成像等方面。

坐标系概念

我们的手机屏幕是二维的,但是我们展示物体的世界是三维的,当我们在构建一个物体的时候我们是以一个三维世界既是世界坐标来构建,而转化为屏幕坐标展示在我们眼前,则需要经历多道矩阵变化,中间webGL替我们操作了许多事情。

世界坐标系:在webGL中,世界坐标系是以屏幕中心为原点(0, 0, 0),且是始终不变的。你面对屏幕,你的右边是x正轴,上面是y正轴,屏幕指向你的为z正轴。长度单位这样来定:窗口范围按此单位恰好是(-1,-1)到(1,1),即屏幕左下角坐标为(-1,-1),右上角坐标为(1,1)。

屏幕坐标系:
webGL的重要功能之一就是将三维的世界坐标经过变换、投影等计算,最终算出它在显示设备上对应的位置,这个位置就称为设备坐标。在屏幕、打印机等设备上的坐标是二维坐标。

视点坐标系:
是以视点(照相机)为原点,以视线的方向为Z+轴正方向的坐标系中的方向。webGL会将世界坐标先变换到视点坐标,然后进行裁剪,只有在视线范围(视见体)之内的场景才会进入下一阶段的计算。

鼠标在屏幕上点击的时候,得到二维坐标p(x, y),再加上深度坐标的范围(0, 1), 就可以形成两个三位坐标A(x1, y1, 0), B(x2, y, 1), 由于它们的Z轴坐标是0和1,则转变到投影坐标系的话,一定分别是前剪切平面上的点和后剪切平面上的点,也就是说,在投影坐标系中,A点一定在能看见的所有模型的最前面,B点一定在能看见的所有的模型的最后边,将AB点连成线,AB线穿过的物体就是被点击的物体。而 Three.js提供一个射线类Raycasting来拾取场景里面的物体。更方便的使用鼠标来操作3D场景。(不过在实际代码中我们组成射线的两个点是摄像机所在视点与屏幕上点击的点连接而成的射线)

完整代码:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Raycaster射线投射器</title><style>.body {margin: 0;overflow: hidden;}</style><script src="js/three.js"></script><!-- orbitcontrol.js用于鼠标自由变化 --><script src="js/OrbitControls.js"></script>
</head><body></body>
<script>/*场景*/var scene = new THREE.Scene();/*相机*/var width = window.innerWidth;var height = window.innerHeight;var k = width / height;var camera = new THREE.PerspectiveCamera(45, k, 1, 1000);camera.position.set(300, 400, 300);camera.lookAt(scene.position);/*添加光源*/var pointlight = new THREE.PointLight(0xFFFFE0);pointlight.position.set(100, 200, 100);scene.add(pointlight);/*添加geometry(几何体)*/var boxgeomrtry = new THREE.BoxGeometry(100, 100, 100);var material = new THREE.MeshBasicMaterial({color: 0xff0000});var mesh = new THREE.Mesh(boxgeomrtry, material);scene.add(mesh);/*渲染*/var renderer = new THREE.WebGLRenderer();renderer.setSize(width, height);renderer.setClearColor(0xC0C0C0, 1);//下面一句话很重要不要忘掉document.body.appendChild(renderer.domElement);render();/*射线投射器*/var raycaster = new THREE.Raycaster();var mouse = new THREE.Vector2();function render() {renderer.render(scene, camera);}function onMouseDown(event) {mouse.x = (event.clientX / width) * 2 - 1;mouse.y = -(event.clientY / height) * 2 + 1;//将平面坐标系转为世界坐标系raycaster.setFromCamera(mouse, camera);//得到点击的几何体var raycasters = raycaster.intersectObjects(scene.children);if (raycasters.length > 0) {raycasters[0].object.material.color.set(0x00ff00);}render()}//监视鼠标左键按下事件window.addEventListener("mousedown", onMouseDown, false);//用于鼠标自由变化var control = new THREE.OrbitControls(camera);control.addEventListener("change", render);
</script></html>

效果:

点击几何体前

点击后

代码解释

由鼠标点击转为世界坐标的过程

//得到mouse.x = (e.clientX / window.innerWidth) * 2 - 1;mouse.y = -(e.clientY / window.innerHeight) * 2 + 1;推导过程:设A点为点击点(x1,y1),x1=e.clintX, y1=e.clientY设A点在世界坐标中的坐标值为B(x2,y2);由于A点的坐标值的原点是以屏幕左上角为(0,0);我们可以计算可得以屏幕中心为原点的B'值x2' = x1 - innerWidth/2y2' = innerHeight/2 - y1又由于在世界坐标的范围是[-1,1],要得到正确的B值我们必须要将坐标标准化x2 = (x1 -innerWidth/2)/(innerwidth/2) = (x1/innerWidth)*2-1同理得 y2 = -(y1/innerHeight)*2 +1

three.js(6):屏幕点击与鼠标的交互(Raycaster的用法)相关推荐

  1. android 模拟点击 不发出声音,【Android】代码实现模拟屏幕点击和键盘按键事件...

    最近参加某比赛写了一个Android手机控制Android电视的程序,其中需要控制电视端模拟"鼠标"点击,和模拟按键盘的事件. 下面直接贴上程序: // 模拟屏幕点击事件 publ ...

  2. Android代码模拟物理、屏幕点击事件

    一.应用中模拟物理和屏幕点击事件 例如,模拟对某个view的点击事件 private void simulateClick(View view, float x, float y) {long dow ...

  3. Unity3D 屏幕点击特效

    前言 屏幕点击特效目前用到两种,场景中特效和UI特效,其实就是坐标和层级之间的区别.无论特效用的帧动画.粒子特效亦或是贴图都可以使用,根据项目稍微调整下就好了.如果想优化的话可以写个对象池,这里就不赘 ...

  4. JS 实战: Drag 点击拖曳效果

    JS 实战: Drag 点击拖曳效果 文章目录 JS 实战: Drag 点击拖曳效果 简介 参考 正文 项目结构 & 静态模版 添加元素 添加 position 主要逻辑片段 事件响应结构 移 ...

  5. 计算机桌面点击无反应,电脑屏幕点击没反应是怎么回事

    大家好,我是时间财富网智能客服时间君,上述问题将由我为大家进行解答. 电脑屏幕点击没反应的原因是: 1.检查显示器连接线是否松动,线路完好仍没有反应则准备拆机. 2.断电源,拧掉底壳的所有螺丝,将内存 ...

  6. vue判断是否双击_vue双击事件2.0事件监听(点击-双击-鼠标事件)和事件修饰符操作...

    Vue 事件处理方法 可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码. v-on:click 单击事件 + + - - v-on:dblclick 双击事件 ...

  7. vue 点击获取鼠标坐标(鼠标位置)

    <button @click="getMouseXY($event)">点击获取鼠标坐标</button> getMouseXY(e){this.x = e ...

  8. js实现按钮点击变色,其他的按钮恢复默认颜色

    JavaScript实现按钮点击变色,其他的按钮恢复默认颜色,则需通过循环实现,当有按钮点击的时候,先将所有的按钮的颜色,更改为空,然后在针对,鼠标点击的相应的按钮,进行更改按钮颜色: onclick ...

  9. 从根源上看屏幕点击事件是如何传递到View中的(上)-事件获取

    浅谈 曾经在开发的很长一段时间内,笔者对点击事件的认知只存在于自定义View中的onTouchEvent等方法的处理. 后来慢慢的接触到Android的事件分发机制,但也只是在Activity-> ...

最新文章

  1. 清华大学 唐杰 计算机学院 怎么样,我国首位原创虚拟学生,后期希望“她”能够像人一样进行创新...
  2. mac mysql 链接_mac上搭建mysql环境配置和Navicat连接mysql
  3. springMVC处理跨域问题
  4. Android Fragment切换动画效果
  5. 关于jesd204B调试总结
  6. 2018 CISSP考试一路走来
  7. c语言2的n次方编程利用数组,1.6编程基础之一维数组_12计算2的N次方
  8. c语言中sprint的用法
  9. 机器学习与控制:ADMM的ODE模型与基于Lyapunov的收敛分析
  10. Ansible9:变量之Fact
  11. 设置Hi提醒实现机器人盯盘|自动监测股票价格达到条件推送消息通知
  12. godot着色器shader效果收集
  13. win7升级win10后出现VisualSVN Server提供程序无法执行所尝试的操作 0x80041024
  14. 【实战分享2】:如何基于OpenXR@ unity + 华为VR Glass 6dof Quest 开发跨平台VR游戏/应用
  15. 趣题:奇怪的自然数集划分
  16. 天赋是积累出来的——转载自周鸿祎博客
  17. 我的U盘是金士顿4G的打不开,windows无法格式化
  18. 【备忘】无限互联IOS全套视频教程下载
  19. vxe-table踩坑,表格操作列按钮不出现问题
  20. 惠普暗影精灵2 win10+linux双系统开机直接进win10,无法进系统选择界面的解决办法

热门文章

  1. HaaS600物联网开发板学习笔记(三)---使用amp工具远程更新js代码
  2. Centos6.5 LAMP环境源码包安装与配置,附安装包百度网盘地址
  3. 科技爱好者周刊(第 202 期):三个有启发的学习方法
  4. C#编程学习:正则表达式的使用
  5. 万字长文带你玩转2020全国大学生计算机技能应用大赛—C语言模考整理解析
  6. 深入剖析Tomcat第一章ERR_INVALID_HTTP_RESPONSE
  7. App推送推了10万打开100?3招提高消息推送(Push)到达率
  8. FTDI 2232H GPIO设置 NAND Read
  9. 目标跟踪:在视频序列中跟踪特定对象的位置和状态
  10. 解决Word2019使用卡顿问题