Threejs之相机基础

参考资料

  • 正投影相机
  • 相机控件MapControls

知识点

注:基于Three.jsv0.155.0

  • 正投影相机
  • 正投影相机-Canvas尺寸变化
  • 包围盒Box3
  • 地图案例(包围盒、正投影)
  • 相机动画(.position和.lookAt())
  • 不同方向的投影视图
  • 旋转渲染结果(.up相机上方向)
  • 管道漫游案例
  • OrbitControls旋转缩放限制
  • 相机控件MapControls

代码实现

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Three.js</title>
</head><body></body><!-- 具体路径配置,你根据自己文件目录设置,我的是课件中源码形式 --><script type="importmap">{"imports": {"three": "./js/three.module.js","three/addons/": "../three.js/examples/jsm/"}}</script><script type="module">import * as THREE from 'three';import { OrbitControls } from 'three/addons/controls/OrbitControls.js';import { MapControls } from 'three/addons/controls/MapControls.js';const width = window.innerWidthconst height = window.innerHeight// 场景const scene = new THREE.Scene();const data = [[110.3906, 34.585],[110.8301, 34.6289],[111.1816, 34.8047],[111.5332, 34.8486],[111.7969, 35.0684],[112.0605, 35.0684],[112.0605, 35.2881],[112.7637, 35.2002],[113.1152, 35.332],[113.6426, 35.6836],[113.7305, 36.3428],[114.873, 36.123],[114.9609, 36.0791],[115.1367, 36.2109],[115.3125, 36.0791],[115.4883, 36.167],[115.3125, 35.8154],[116.1035, 36.0791],[115.4883, 35.7275],[115.2246, 35.4199],[115.0488, 35.376],[114.7852, 35.0684],[115.4004, 34.8486],[115.5762, 34.585],[116.1914, 34.585],[116.1914, 34.4092],[116.543, 34.2773],[116.6309, 33.9258],[116.1914, 33.7061],[116.0156, 33.9697],[115.6641, 34.0576],[115.5762, 33.9258],[115.5762, 33.6621],[115.4004, 33.5303],[115.3125, 33.1787],[114.873, 33.1348],[114.873, 33.0029],[115.1367, 32.8711],[115.2246, 32.6074],[115.5762, 32.4316],[115.8398, 32.5195],[115.9277, 31.7725],[115.4883, 31.6846],[115.4004, 31.4209],[115.2246, 31.4209],[115.1367, 31.5967],[114.7852, 31.4648],[114.6094, 31.5527],[114.5215, 31.7725],[114.1699, 31.8604],[113.9941, 31.7725],[113.8184, 31.8604],[113.7305, 32.4316],[113.4668, 32.2998],[113.2031, 32.4316],[112.3242, 32.3438],[111.5332, 32.6074],[111.0059, 33.2666],[111.0059, 33.5303],[110.6543, 33.8379],[110.6543, 34.1455],[110.4785, 34.2334],[110.3906, 34.585]]const pointsArr = [];// 一组二维向量表示一个多边形轮廓坐标data.forEach(function(e){// data坐标数据转化为Vector2构成的顶点数组const v2 = new THREE.Vector2(e[0],e[1])pointsArr.push(v2);})// Shape表示一个平面多边形轮廓,参数是二维向量构成的数组pointsArrconst shape = new THREE.Shape(pointsArr);// 多边形shape轮廓作为ShapeGeometry参数,生成一个多边形平面几何体const geometry = new THREE.ShapeGeometry(shape);// 生成一个平面网格模型const mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({color: '#0000ff',side: THREE.DoubleSide}))// 设置模型位置mesh.position.set(0, 0, 0);// 添加模型到场景scene.add(mesh);// 点光源const pointLight = new THREE.PointLight( 0xffffff, 1.0, 0, 0);pointLight.position.set(200, 200, 200 );scene.add( pointLight );// 环境光const ambientLight = new THREE.AmbientLight( 0xffffff, 1);scene.add( ambientLight );// 坐标系const axes = new THREE.AxesHelper(200);scene.add(axes);// 相机const s = 2.5;//控制left, right, top, bottom范围大小const k = width / height; //canvas画布宽高比const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 8000);// const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 3000);// camera.position.set(300, 300, 300); // camera.lookAt(0, 0, 0); //指向坐标原点// 包围盒计算模型对象的大小和位置const box3 = new THREE.Box3();box3.expandByObject(mesh); // 计算模型包围盒const size = new THREE.Vector3();box3.getSize(size); // 计算包围盒尺寸console.log('模型包围盒尺寸',size);const center = new THREE.Vector3();box3.getCenter(center); // 计算包围盒中心坐标console.log('模型中心坐标1',center);const x = 113.51,y = 33.88;camera.position.set(x, y, 300);// 你可以看到模型相比原来上下颠倒  y坐标轴朝下camera.up.set(0,-1,0)camera.lookAt(x, y, 0);// 渲染器const renderer = new THREE.WebGLRenderer();renderer.setSize(width, height);renderer.render(scene, camera);document.body.appendChild(renderer.domElement);renderer.outputColorSpace = THREE.SRGBColorSpace;//设置为SRGB颜色空间// const controls = new OrbitControls(camera, renderer.domElement);// controls.target.set(x, y, 0); //与lookAt参数保持一致// controls.update();//update()函数内会执行camera.lookAt(controls.target)// // 左右旋转范围// controls.minAzimuthAngle = -Math.PI/2;// controls.maxAzimuthAngle = Math.PI/2;// // Vector3 {x: -49.803731395661714, y: 146.90160246353028, z: 35.47368304973255}// // Vector3 {x: -11.970638355445846, y: -51.0801205834488, z: 0.7429414745816755}// // 渲染循环// let angle = 0; //用于圆周运动计算的角度值// const R = 100; //相机圆周运动的半径// function render() {//     angle += 0.01;//     // 相机y坐标不变,在XOZ平面上做圆周运动//     camera.position.x = R * Math.cos(angle);//     camera.position.z = R * Math.sin(angle);//     renderer.render(scene, camera);//     camera.lookAt(0,0,0);//     // console.log('🚀 ~ file: 6.加载外部三维模型.html:70 ~ render ~ camera:', camera.position) // 鼠标左键改变相机位置//     // console.log('🚀 ~ file: 6.加载外部三维模型.html:66 ~ controls:', controls.target) // 鼠标右键改变相机观察点//     requestAnimationFrame(render);// }// // render();// 控制器// controls.addEventListener('change', () => {//   // 因为动画渲染了,所以这里可以省略//   renderer.render(scene, camera);// });const controls = new MapControls(camera, renderer.domElement);controls.addEventListener('change', function () {// 鼠标右键旋转时候,查看.position变化// 鼠标左键拖动的时候,查看.position、.target的位置会变化console.log('camera.position',camera.position);console.log('controls.target',controls.target);});</script>
</html>

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

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

相关文章

字节流生成的map进行remove报错分析

使用stream流生成的map进行remove操作会报错 当对stream生成的map进行remove操作时&#xff0c;代码报错&#xff0c;复现代码如下&#xff1a; package com.test.testdemo01.service;import com.test.testdemo01.entity.dto.DemoData; import org.junit.Test;import java.ut…

【数据结构】栈和队列超详解!(Stack Queue)

文章目录 前言一、栈1、栈的基本概念2、栈的实现&#xff08;数组实现&#xff09;3、栈的基本操作3.1 栈的结构设计3.2 栈常见的基本函数接口 4、栈的实现4.1 初始化栈4.2 栈的销毁4.3 入栈4.4 出栈4.5 判空4.6 长度4.7 获取栈顶元素 完整代码Stack.hStack.cTest.c 二、队列1、…

SQLAlchemy 第一篇

安装SQLAlchemy pip install SQLAlchemy查看当前版本 # 查看当前版本import sqlalchemyprint(sqlalchemy.__version__)2.0.23创建数据库连接 此处我们以pymysql为mysql的数据库驱动 安装pymysql pip install pymysqlfrom sqlalchemy import create_engine engine create_…

Next.js 的设计理念

Next.js 的设计理念&#xff1a;简洁、强大与高效 Next.js 是一个流行的 React 框架&#xff0c;由 Vercel 公司开发。它的设计理念是简洁、强大和高效&#xff0c;这种理念贯穿于 Next.js 的所有功能中。下面我们将深入探讨这三个设计理念。 简洁 Next.js 的一个核心设计理…

阿里云国际设置DDoS基础防护和原生防护攻击事件报警

通过事件报警您能够获知业务遭受的DDoS攻击事件&#xff0c;及时发现并修复问题&#xff0c;缩短故障处理时间&#xff0c;以便尽快恢复业务。本文介绍如何设置DDoS基础防护和原生防护攻击事件的报警通知。 报警方式说明 阿里云DDoS原生防护提供消息中心报警、云监控报警和日…

HTTP 500错误:服务器内部错误,原因及解决方案

大家好&#xff0c;今天我们来聊聊一个常见的问题——HTTP 500错误&#xff0c;也就是服务器内部错误。这个错误就像是一个神秘的魔法&#xff0c;时不时地出现在你的网页上&#xff0c;让你的用户和你在一片懵逼中互相猜疑。 首先&#xff0c;我们来了解一下这个错误。HTTP 5…

大力说企微入门系列第四课:规则设计

当公司的企业微信体系建立起来以后&#xff0c;相应的人员、角色、权限已经配置&#xff0c;接下来是否就可以开始进入运营阶段那。 理论上来说是可以的&#xff0c;但是可能会引起混乱。所谓没有规矩不成方圆&#xff0c;要想运营顺利&#xff0c;还需要一些规则的设计。 01…

查找两个总和为特定值的索引(蓝桥杯)

#include <stdio.h> int main(){int n;scanf("%d",&n);int s[n];for(int i 0 ; i < n ; i)scanf("%d",&s[i]);int k;scanf("%d",&k);int sum 0;int t0,h;int st[101]; for(int i 0 ; i < n ; i)st[i] 0; //标记数…

Python员工信息管理系统V2(python系列21)

前言&#xff1a;在python系列19&#xff0c;我们使用MVC架构初步完成员工信息管理系统&#xff0c;今天我们使用封装&#xff0c;继承&#xff0c;多态让我们的程序有隐藏的魅力&#xff0c;更加灵活&#xff0c;有扩展性。 实现的功能和python系列19一模一样&#xff0c;所以…

Springboot+Libreoffice集成开发

简介 LibreOffice 是一款功能强大的办公软件&#xff0c;默认使用开放文档格式 (OpenDocument Format , ODF), 并支持 *.docx, *.xlsx, *.pptx 等其他格式。 它包含了 Writer, Calc, Impress, Draw, Base 以及 Math 等组件&#xff0c;可用于处理文本文档、电子表格、演示文稿、…

垃圾回收 (GC) 在 .NET Core 中是如何工作的?

提起GC大家肯定不陌生&#xff0c;但是让大家是说一下GC是怎么运行的&#xff0c;可能大多数人都不太清楚&#xff0c;这也很正常&#xff0c;因为GC这东西在.NET基本不用开发者关注&#xff0c;它是依靠程序自动判断来释放托管堆的&#xff0c;我们基本不需要主动调用Collect(…

【论文阅读】O’Reach: Even Faster Reachability in Large Graphs

Hanauer K, Schulz C, Trummer J. O’reach: Even faster reachability in large graphs[J]. ACM Journal of Experimental Algorithmics, 2022, 27: 1-27. Abstract 计算机科学中最基本的问题之一是可达性问题&#xff1a;给定一个有向图和两个顶点s和t&#xff0c;s可以通过…

C++进阶学习:map和set的实现

我们知道set和map的底层其实是红黑树&#xff0c;在学习完红黑树这个数据结构之后&#xff0c;我们开始简单模拟实现一下这两个STL容器 目录 1.set和map的泛型编程思想 2.红黑树的结构 2.1.迭代器的实现 2.2.迭代器的 operator 2.3.迭代器的代码 2.4.set和map迭…

资产管理系统部署及库存告警

1.需求&#xff1a;对电脑&#xff0c;办公设备&#xff0c;耗材等做资产盘点和整理&#xff0c;并对库存预警。 2.选型&#xff1a;snipeit 3.部署 #!/bin/bash docker run -d -p 80:80 --name"snipeit" --env-filesnipeit.env --mount sourcesnipe-vol,dst/var/l…

鸿蒙OS应用开发之文本输入组件

前面学习了按钮组件的输入方式,它只能响应触摸输入,或者点击输入,而不能实现文本的输入,虽然它是主流的操作方式,但是很多时候还是需要文本的输入。比如登录邮箱需要输入用户帐号和密码,网上购物需要输入地址和电话号码等等。应用对这样的需求,就需要使用文本输入组件,…

【算法系列篇】递归、搜索和回溯(三)

文章目录 前言什么是二叉树剪枝1. 二叉树剪枝1.1 题目要求1.2 做题思路1.3 代码实现 2. 验证二叉搜索树2.1 题目要求2.2 做题思路2.3 代码实现 3. 二叉搜索树中第k小的元素3.1 题目要求3.2 做题思路3.3 代码实现 4. 二叉树的所有路径4.1 题目要求4.2 做题思路4.3 代码实现 前言…

(八)数组和函数实践:扫雷游戏

目录 1. 扫雷游戏分析和设计 1.1 扫雷游戏的功能说明 1.2 游戏的分析和设计 1.2.1 数据结构的分析 1.2.2 文件结构设计 2. 扫雷游戏的代码实现 3. 如何生成用户版本 4. 完整的排雷程序 1. 扫雷游戏分析和设计 1.1 扫雷游戏的功能说明 1&#xff09;使用控制台实现经典…

数据结构和算法-栈

数据结构和算法-栈 文章目录 数据结构和算法-栈1. 栈的介绍2. 栈的应用场景3. 栈的快速入门3.1 用数组模拟栈3.2 课堂作业-用链表模拟栈 4. 栈实现综合计算器4.1 课堂作业-加入小括号5. 栈的三种表达式-**前缀、中缀、后缀表达式(逆波兰表达式)**5.1 前缀表达式(波兰表达式)5.1…

中低压MOS 适用于电子烟等产品—— 较小的开关损耗 过流能力好

工作原理&#xff1a; 当用户在吸嘴处抽吸时&#xff0c;气流经过进气孔&#xff0c;穿 过电路板上方的咪头&#xff0c;咪头即产生电信号&#xff0c;驱 动芯片板&#xff0c;让电池供电给雾化芯&#xff0c;雾化芯中的 发热丝将电能转化成热能&#xff0c;当温度达到雾化液…

LeetCode-2487. 从链表中移除节点【栈 递归 链表 单调栈】

LeetCode-2487. 从链表中移除节点【栈 递归 链表 单调栈】 题目描述&#xff1a;解题思路一&#xff1a;可以将链表转为数组&#xff0c;然后从后往前遍历&#xff0c;遇到大于等于当前元素的就入栈&#xff0c;最终栈里面的元素即是最终的答案。解题思路二&#xff1a;递归&am…