【Threejs进阶教程-算法篇】1.常用坐标系介绍与2d/3d随机点位算法

2d/3d随机算法

  • 学习ThreeJS的捷径
  • 坐标系简介
    • 平面直角坐标系和极坐标系
    • 空间直角坐标系
    • 圆柱坐标系
    • 球坐标系
      • 球坐标系与直角坐标系的转换
  • 基于坐标系系统的随机点位算法
    • 平面直角坐标系随机
      • 平面直角坐标系随机的变形
    • 空间直角坐标系随机
    • 二维极坐标系随机
    • 圆柱坐标系随机
    • 基于Cylindercal(圆柱坐标系)的圆柱坐标系随机
    • 球坐标系随机
  • 随机算法的应用
    • 土星环(使用极坐标系)
    • 粒子球(使用球坐标系)

学习ThreeJS的捷径

本段内容会写在0篇以外所有的,本人所编写的Threejs教程中

对,学习ThreeJS有捷径
当你有哪个函数不懂的时候,第一时间去翻一翻文档
当你有哪个效果不会做的时候,第一时间去翻一翻所有的案例,也许就能找到你想要的效果
最重要的一点,就是,绝对不要怕问问题,越怕找找别人问题,你的问题就会被拖的越久

如果你确定要走WebGL/ThreeJS的开发者路线的话,以下行为可以让你更快的学习ThreeJS

  1. 没事就把所有的文档翻一遍,哪怕看不懂,也要留个印象,至少要知道Threejs有什么
  2. 没事多看看案例效果,当你记忆的案例效果足够多时,下次再遇到相似问题时,你就有可能第一时间来找对应的案例,能更快解决你自己的问题
  3. 上述案例不只是官网的案例,郭隆邦技术博客,跃焱邵隼,暮志未晚等站点均有不少优质案例,记得一并收藏
    http://www.yanhuangxueyuan.com/ 郭隆邦技术博客
    https://www.wellyyss.cn/ 跃焱邵隼
    http://www.wjceo.com/ 暮志未晚(暮老的站点暂时挂了,请查阅他之前的threejs相关文档)
    暮老的csdn首页
    这三个站点是我最常逛的站点,推荐各位有事没事逛一下,看看他们的案例和写法思路,绝对没坏处

坐标系简介

我们常见2D坐标系,一般有平面直角坐标系极坐标系
我们常见的3D坐标系,一般有空间直角坐标系圆柱坐标系球坐标系

平面直角坐标系和极坐标系

平面直角坐标系,一般以 (x,y) 两个数值来表示点位坐标
极坐标系,一般以(radius,theta),半径和旋转角度来表示点位坐标

极坐标系和平面直角坐标系可以互相转换:

	//平面直角坐标系转极坐标系let radius = Math.sqrt( x * x + y * y );let theta = Math.atan( y / x );//极坐标系转平面直角坐标系let x = radius * Math.cos(theta);let y = radius * Math.sin(theta);

空间直角坐标系

空间直角坐标系,一般使用(x,y,z)三个值来表示点位坐标,也就是我们在threejs中最常用的position

圆柱坐标系

圆柱坐标系,一般使用(radius,theta,height)来表示点位坐标,三个值可以根据实际使用情况做互换,圆柱坐标系,官方已经提供了相关API,我们可以查阅threejs的官方文档来更详细的了解圆柱坐标系
在这里插入图片描述
由于官方文档的内容就这些,所以这里就不贴文档源地址了,具体的圆柱坐标系到平面直角坐标系的转换算法,其实和上面极坐标算法相似,xz平面使用极坐标系来计算,y轴依然是用高度轴来计算,本质上圆柱坐标系就是极坐标系增加了高度轴的一种空间坐标系,转换公式参考极坐标系,这里不再赘述

球坐标系

球坐标系最常用的应用就是计算地球的经纬度,球坐标系一般用( radius,phi,theta)来表示点位坐标,phi可以视为纬度,theta可以视为经度,我们也可以参考threejs官方文档对球坐标系的解释
在这里插入图片描述

球坐标系与直角坐标系的转换

球坐标系到直角坐标系的互转,写法有点多,这里我贴出《3D数学基础》190页的内容,如果你的手边有这本书,书本内的183页到192页对球坐标系做了详细的介绍,这里请根据自身需求做了解即可
在这里插入图片描述
因为考虑到threejs使用右手坐标系,所以我们的公式以Threejs提供的为准

	//直角坐标系转球坐标系,这里我们以threejs官方开发包中//src/math/Spherical.js 中为准setFromCartesianCoords( x, y, z ) {this.radius = Math.sqrt( x * x + y * y + z * z );if ( this.radius === 0 ) {this.theta = 0;this.phi = 0;} else {this.theta = Math.atan2( x, z );this.phi = Math.acos( MathUtils.clamp( y / this.radius, - 1, 1 ) );}return this;}//球坐标系转换平面直角坐标系,这里我们以thrjeejs官方开发包中//src/math/Vector3.js 564行的算法为准setFromSphericalCoords( radius, phi, theta ) {const sinPhiRadius = Math.sin( phi ) * radius;this.x = sinPhiRadius * Math.sin( theta );this.y = Math.cos( phi ) * radius;this.z = sinPhiRadius * Math.cos( theta );return this;}

基于坐标系系统的随机点位算法

平面直角坐标系随机

默认的情况下,场景使用的是空间直角坐标系

	     for(let i = 0;i< 100;i++){let geometry = new THREE.BoxGeometry(1,1,1);let material = new THREE.MeshStandardMaterial({color:0xffffff * Math.random()});let mesh = new THREE.Mesh(geometry,material);mesh.position.x = Math.random() * 10 - 5;mesh.position.z = Math.random() * 10 - 5;scene.add(mesh);}

在这里插入图片描述
因为我们这里仅操作了x轴和z轴,高度轴均保持一致,这样的随机为平面直角坐标系的随机,当然,我们也可以选择随机x轴和y轴,随机y轴和z轴,根据你自身的需求来做即可

这样的以x轴和z轴为随机的方式,可以用于在某个地区生成随机数量的树木,我们在代码中,xz轴的随机范围均为 -5 ~ 5 ,所以我们实际上是在

Math.random()的取值范围为 0~1,Math.random() * 10的取值范围为0 ~ 10,Math.random() * 10 - 5的取值范围为 -5 ~ 5

平面直角坐标系随机的变形

变形其实非常简单,只需要控制position.x,position.y,position.z其中两个轴,就可以控制物体在哪个平面上随机

空间直角坐标系随机

基本上没啥说的,只是在上面的基础上,将三个轴都参与随机

二维极坐标系随机

	     for(let i = 0;i< 100;i++){let geometry = new THREE.BoxGeometry(1,1,1);let material = new THREE.MeshStandardMaterial({color:0xffffff * Math.random()});let mesh = new THREE.Mesh(geometry,material);let angle = Math.random() * Math.PI * 2;let radius = Math.random() * 10;let x = Math.cos(angle) * radius;let z = Math.sin(angle) * radius;mesh.position.x = x;mesh.position.z = z;scene.add(mesh);}

在这里插入图片描述
这样其实我们看的不太明显,我们可以选择随机的方块数量大幅增加,或者让半径不再随机
在这里插入图片描述

	替换随机的半径// let radius = Math.random() * 10;let radius = 10;

在这里插入图片描述
生成1000个盒子,只需要修改for循环的100为1000即可

圆柱坐标系随机

其实就是在极坐标系的基础上,增加对高度轴y轴的随机数即可
这里我们对半径不做随机,相对来说结果更显而易见,如果你需要在圆柱范围内随机,将固定的radius改为随机即可

	     for(let i = 0;i< 1000;i++){let geometry = new THREE.BoxGeometry(1,1,1);let material = new THREE.MeshStandardMaterial({color:0xffffff * Math.random()});let mesh = new THREE.Mesh(geometry,material);let angle = Math.random() * Math.PI * 2;let radius = 10;let x = Math.cos(angle) * radius;let z = Math.sin(angle) * radius;mesh.position.x = x;mesh.position.z = z;mesh.position.y = Math.random() * 10 - 5;scene.add(mesh);}

在这里插入图片描述

基于Cylindercal(圆柱坐标系)的圆柱坐标系随机

这里使用了上述的Cylindercal的概念,如果你实在绕不过来极坐标系,可以考虑使用这个

        let cylindrical = new THREE.Cylindrical();for(let i = 0;i< 1000;i++){let geometry = new THREE.BoxGeometry(1,1,1);let material = new THREE.MeshStandardMaterial({color:0xffffff * Math.random()});let mesh = new THREE.Mesh(geometry,material);cylindrical.radius = 10;cylindrical.theta = Math.random() * Math.PI * 2;cylindrical.y = Math.random() * 10 - 5;//文档在Vector3中mesh.position.setFromCylindrical(cylindrical);scene.add(mesh);}

效果与上面一致,这里不再截图

球坐标系随机

球坐标系随机,这里仅建议使用官方的Spherical来进行随机

        let spherical = new THREE.Spherical()for(let i = 0;i< 1000;i++){let geometry = new THREE.BoxGeometry(1,1,1);let material = new THREE.MeshStandardMaterial({color:0xffffff * Math.random()});let mesh = new THREE.Mesh(geometry,material);spherical.radius = 10;spherical.phi = Math.random() * Math.PI * 2;spherical.theta = Math.random() * Math.PI * 2;mesh.position.setFromSpherical(spherical);scene.add(mesh);}

在这里插入图片描述

随机算法的应用

土星环(使用极坐标系)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><style>*{margin: 0;padding: 0;border: 0;}body{width:100vw;height: 100vh;overflow: hidden;}</style>
</head>
<body><!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script><script type="importmap">{"imports": {"three": "../three/build/three.module.js","three/addons/": "../three/examples/jsm/"}}</script><script type="module">import * as THREE from "../three/build/three.module.js";import {OrbitControls} from "../three/examples/jsm/controls/OrbitControls.js";window.addEventListener('load',e=>{init();addMesh();render();})let scene,renderer,camera;let orbit;function init(){scene = new THREE.Scene();renderer = new THREE.WebGLRenderer({alpha:true,antialias:true});renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);camera = new THREE.PerspectiveCamera(50,window.innerWidth/window.innerHeight,0.1,2000);camera.add(new THREE.PointLight());camera.position.set(10,10,10);scene.add(camera);orbit = new OrbitControls(camera,renderer.domElement);orbit.enableDamping = true;scene.add(new THREE.GridHelper(10,10));}let groups = [];function addMesh() {//创建中心的球体let geometry = new THREE.SphereGeometry(10,32,32);let material = new THREE.MeshStandardMaterial({color:0xffffff * Math.random()});let mesh = new THREE.Mesh(geometry,material);scene.add(mesh);//创建5层土星环for(let i = 0;i< 5;i++){let group = new THREE.Group();let material2 = new THREE.MeshStandardMaterial({color:0xffffff * Math.random()})//每层土星环创造100个图块for(let j = 0;j < 100;j++){let geometry2 = new THREE.BoxGeometry();let mesh2 = new THREE.Mesh(geometry2,material2);group.add(mesh2);//在 15 ~ i*2的半径范围内,生成指定的星环let radius = Math.random() * i * 2 + 15;let theta = Math.random() * Math.PI * 2;mesh2.position.x = Math.cos(theta) * radius;mesh2.position.z = Math.sin(theta) * radius;//随机初始角度mesh2.rotation.set(Math.random() * Math.PI * 2,Math.random() * Math.PI * 2,Math.random() * Math.PI * 2,)//随机大小mesh2.scale.set(Math.random() * 2,Math.random() * 2,Math.random() * 2,)//注意,onBeforeRender,只有具有材质属性的物体,才生效,对group不生效mesh2.onBeforeRender = ()=>{mesh2.rotation.x += 0.01;mesh2.rotation.y += 0.01;}}scene.add(group);groups.push(group);}}function render() {renderer.render(scene,camera);orbit.update();requestAnimationFrame(render);//让每一层的星环转起来for(let i = 0;i< groups.length;i++){groups[i].rotation.y += 0.001 * (i+1);}}</script>
</body>
</html>

在这里插入图片描述
效果如上,我不是设计师,所以不用太纠结好看与不好看的问题

粒子球(使用球坐标系)

这里就不贴完整代码了

    function addMesh() {let spherical = new THREE.Spherical();let vectors = [];for(let i = 0;i< 1000;i++){spherical.radius = Math.random() * 100spherical.theta = Math.random() * Math.PI * 2;spherical.phi = Math.random() * Math.PI * 2;let vec = new THREE.Vector3().setFromSpherical(spherical);vectors.push(vec);}let geometry = new THREE.BufferGeometry().setFromPoints(vectors);let points = new THREE.Points(geometry,new THREE.PointsMaterial({sizeAttenuation:true,}));points.onBeforeRender = ()=>{points.rotation.x += 0.001;points.rotation.y += 0.001;}scene.add(points);}

在这里插入图片描述

有的人也许已经看出来了,粒子球可以用作创建星空(也不一定非要用球坐标系来创建也可以创建星空),粒子球也是烟花效果的基础

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

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

相关文章

QT学习----知识整理(入门篇)

一、初识QT 1、序章 1.1 下载地址 官网&#xff1a;Try Qt | Develop Applications and Embedded Systems | Qt 或者&#xff1a;Index of /archive/qt&#xff08;下载慢&#xff09; 或者&#xff1a;FFmpeg中文网站 中文教程 Android 安卓 -QT 下载 1.2 组件介绍 MSVC…

在面对各种问题时,我们应该如何进行数据分析

python数据分析汇总 前言一、对比分析概念特征类型案例Matplotlib的颜色字母对照表解决遇到未知函数 二、相关性分析概念类型案例一案例二 三、时间序列分析概念类型案例 四、回归分析概念类型案例一案例二案例三 五、决策树概念计算过程案例 六、主成分分析概念计算过程案例 七…

分析人工智能在智慧银行服务中的实际应用以及面临的挑战

一、引言 近年来,人工智能(AI)技术快速发展,其在金融领域,特别是智慧银行服务中的应用日益广泛。人工智能以其独特的数据处理能力、预测分析能力以及自动化决策能力,极大地提升了智慧银行的服务效率、降低了运营成本,并优化了客户体验。然而,人工智能在智慧银行服务中…

web安全学习笔记(16)

记一下第27-28课的内容。Token 验证 URL跳转漏洞的类型与三种跳转形式&#xff1b;URL跳转漏洞修复 短信轰炸漏洞绕过挖掘 一、token有关知识 什么是token&#xff1f;token是用来干嘛的&#xff1f;_token是什么意思-CSDN博客 二、URL跳转漏洞 我们在靶场中&#xff0c;…

计算机SCI期刊,中科院2区TOP,对国人相当友好,一周内出版!

一、期刊名称 ISA Transactions 二、期刊简介概况 期刊类型&#xff1a;SCI 学科领域&#xff1a;计算机科学 影响因子&#xff1a;7.3 中科院分区&#xff1a;2区TOP 出版方式&#xff1a;订阅模式/开放出版 版面费&#xff1a;选择开放出版需支付$3950 三、期刊征稿范…

抖音小店有订单后怎么发货?实操分享!发货全流程来了

哈喽~我是电商月月 做无货源抖音小店的店铺在出单后怎么发货&#xff1f;今天我就来给大家解答这个问题&#xff0c;其中的注意事项新手商家可以收藏一下&#xff0c;避免犯错 抖音小店的商品出单后&#xff0c;商家在“管理中心-订单管理”页面就能看见所有待处理的订单 一…

github新手用法

目录 1&#xff0c;github账号注册2&#xff0c;github登录3&#xff0c;新建一个仓库4&#xff0c;往仓库里面写入东西或者上传东西5&#xff0c; 下载Git软件并安装6 &#xff0c;获取ssh密钥7&#xff0c; 绑定ssh密钥8&#xff0c; 测试本地和github是否联通9&#xff0c;从…

618好物推荐大赏:2024年必囤好物一网打尽,购物攻略助你抢购无忧!

在618购物狂欢节来临之际&#xff0c;我为大家精心挑选了一系列好物&#xff0c;它们不仅品质卓越&#xff0c;更能在日常生活中为我们带来无限便利与乐趣。这里的每一款产品都经过我严格筛选&#xff0c;只为给你最优质的购物体验。让我们一起在这个618&#xff0c;发现生活中…

统计学第2天

参数估计 基本概念 估计量与估计值 估计量&#xff1a;用于估计总体参数的随机变量 如&#xff1a;样本均值&#xff0c;样本比例&#xff0c;样本方差等 例如&#xff1a;样本均值就是总体均值的一个估计量 估计值&#xff1a;估计参数时计算出来的统计量的具体值 如&…

后端之路第一站——Maven

前提&#xff1a;得会基础java 前言&#xff1a;不知道出于什么原因&#xff0c;可能是喜欢犯贱吧&#xff0c;本人从大一到大二都一直在专研前端开发&#xff0c;一点也没接触过后端&#xff0c;但是突然抽风想学后端了&#xff0c;想试着自己全栈搞一下项目&#xff0c;于是在…

武汉星起航深耕亚马逊跨境,助力合作伙伴实现全球业务增长

在数字化浪潮席卷全球的今天&#xff0c;跨境电商业务蓬勃发展&#xff0c;成为推动国际贸易增长的重要引擎。亚马逊&#xff0c;作为全球最大的电商平台之一&#xff0c;以其独特的平台特点和全球化布局&#xff0c;为卖家和买家提供了便捷、高效的交易环境&#xff0c;成为众…

音视频开发4-补充 FFmpeg 开发环境搭建 -- 配置环境 Ubuntu 22.04.2 LTS +FFmpeg 7.0

配置环境 Ubuntu 22.04.2 LTS FFmpeg 7.0 参开如下的博客内容&#xff0c;但是实际build 中使用 FFmpeg 6.0 会有build error&#xff0c;网上查资料&#xff0c;需要使用7.0中的代码切换6.0中的一部分&#xff0c;因为嫌麻烦&#xff0c;直接换成7.0 【调试经验】Ubuntu FFm…

【网站项目】SpringBoot379儿童疫苗接种管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

Python自学之路--004:Python使用注意点(原始字符串‘r’\字符转换\‘wb’与‘w区别’\‘\‘与‘\\’区别)

目录 1、原始字符串‘r’ 2、字符转换问题 3、open与write函数’wb’与’w’区分 4、Python里面\与\\的区别 1、原始字符串‘r’ 以前的脚本通过Python2.7写的&#xff0c;通过Python3.12去编译发现不通用了&#xff0c;其实也是从一个初学者的角度去看待这些问题。 其中的\…

解放双手,批量自动上传视频到微信视频号

文件夹里面有很多视频&#xff0c;一个个手工上传到视频号很麻烦&#xff0c;可以借助AI来自动化。 先把视频号上传流程熟悉一遍&#xff0c;把一些按钮截图&#xff0c;记录一些屏幕坐标。 然后&#xff0c;在deepseek的代码助手中输入提示词&#xff1a; 你是一个Python编程…

机器学习-SVM预测

本文使用机器学习SVM对数据进行预测。仅供参考 1、数据 1.1 训练数据集&#xff1a; medol.xlsx文件示例 otv3015-1.9153622093018-1.9634097763021-1.7620284083024-1.789477583 1.2 预测数据集 test.xlsx文件示例 ot35163519 2、模型训练 train.py import pandas as …

软件工程期末复习(8)需求的表达方法和状态转换图

需求的表达方法 系统模型 需求分析的任务就是借助于当前系统的逻辑模型导出目标系统的逻辑模型&#xff0c;解决目标系统 “做什么” 的问题 通常软件开发项目是要实现目标系统的物理模型。目标系统的具体物理模型是由它的逻辑模型经实例化&#xff0c;即具体到某个业务领域而…

韵搜坊 -- java爬虫抓取数据

文章目录 三种抓取方式数据抓取的流程获取文章具体操作 获取用户获取图片jsoup操作 三种抓取方式 直接调用请求接口(最方便&#xff0c;这里使用该方法) HttpClient,OKHttp,RestTemplate,Hutool等网页渲染出明文内容后&#xff0c;从前端页面的内容抓取有些网站可能是动态请求…

第三十二天 | 46.全排列 47.全排列||

终于进入排列&#xff01;&#xff08;之前都是组合&#xff09; 排列和组合的区别&#xff1a;在数学上的区别都懂&#xff0c;主要是看在代码实现上有什么区别 题目&#xff1a;46.全排列 树型结构比较简单 用used标记某一元素是否使用过。在组合问题中&#xff0c;其实是…

【制作100个unity游戏之26】unity2d横版卷轴动作类游戏7(附带项目源码)

最终效果 系列导航 文章目录 最终效果系列导航前言血条 能量条UI配置画布绘制血条 能量条UI 头像框 延迟虚血源码完结 前言 欢迎来到【制作100个Unity游戏】系列&#xff01;本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第26篇中&#xff0c;我们将探索如何…