three.js + suncalc 在vue中模拟太阳运行轨迹以及光照效果

近期项目需要实现一个在three中出现 一个光照的效果,遂开始学习three.js,中间遇到了一些坑这边记录一下。
一开始想的比较简单,觉得只要熟悉three.js 的api后,就直接模拟了一个光照环形运转的效果出来。可惜等我做出来直接就被否定了,实际的太阳运行阶段要按当地经纬度来计算太阳位置。遂查询资料,发现有库suncalc可以计算太阳的角度。废话不多说直接贴代码吧:

<template><canvas id="canvas"></canvas>
</template>
<script>// 引入three
import * as THREE from 'three';// 引入轨道控制器扩展库OrbitControls.js  // 网上的方案是这种 but 
// import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
//   "suncalc": "^1.9.0",引入方式
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';let scene, camera, rendererexport default {data() {return {}},onLoad() {},onReady() {// 默认经纬度const latitude = 116.40400, longitude = 39.92800;const currentTime = new Date();// 凌晨时分currentTime.setHours(0, 0, 0, 0);let timeInterval = 120000; // 2分钟的时间间隔(毫秒)// 太阳高度const distance = 10;let sunX = 200;  // 初始x坐标let sunY = 200;  // 初始y坐标// 更新太阳位置和高度function updateSunPosition() {const sunPosition = SunCalc.getPosition(currentTime, latitude, longitude);const sunAltitude = sunPosition.altitude * (180 / Math.PI);const sunAzimuth = sunPosition.azimuth * (180 / Math.PI);const theta = (90 - sunAltitude) * (Math.PI / 180);const phi = (-sunAzimuth + 180) * (Math.PI / 180); // 考虑太阳在地平线以下的情况const x = 10 * Math.sin(theta) * Math.cos(phi);const y = 10 * Math.cos(theta);const z = 10 * Math.sin(theta) * Math.sin(phi);// 时间推移currentTime.setTime(currentTime.getTime() + timeInterval);// 因为太阳是从底部出来,所以数据去反就好了;directionalLight.position.set(-x, -y, -z);}// 创建场景scene = new THREE.Scene();// 创建相机camera = new THREE.PerspectiveCamera(45,// 视角window.innerWidth / window.innerHeight, //宽高比0.1, //近平面1000 // 远平面)// 创建渲染器renderer = new THREE.WebGLRenderer({ antialias: true })renderer.setSize(window.innerWidth, window.innerHeight)renderer.shadowMap.enabled = true;// 可以产生阴影// 将渲染器绑定到dom节点上const myCanvas = document.getElementById("canvas")myCanvas.appendChild(renderer.domElement)// 创建几何体const geometry = new THREE.BoxGeometry(1, 1, 5);// 创建材质const material = new THREE.MeshStandardMaterial(); // 基础材质// 父元素const cube = new THREE.Mesh(geometry, material);// 设置物体投射阴影cube.castShadow = true;// 设置立方体和平面接收阴影cube.receiveShadow = true;cube.position.set(0, 0, 0.5);scene.add(cube)// 创建平面const planeGeometry = new THREE.PlaneGeometry(10, 10);const plane = new THREE.Mesh(planeGeometry, material);plane.position.set(0, -1, 0);plane.receiveShadow = true;// plane.setRotationFromMatrix(-Math.PI / 2);scene.add(plane);// 设置相机位置camera.position.z = 10;camera.position.y = -14;camera.position.x = 0;camera.lookAt(0, 0, 0)// 添加世界坐标辅助器// const axesHelper = new THREE.AxesHelper(5);// scene.add(axesHelper);// 灯光// 环境光const light = new THREE.AmbientLight(0xffffff, 0.5);scene.add(light);// 直线光源const directionalLight = new THREE.DirectionalLight(0xffffff, 10);directionalLight.position.set(sunX, sunY, distance);// 开启光照投射阴影directionalLight.castShadow = true;scene.add(directionalLight);// 添加轨道控制器const controls = new OrbitControls(camera, renderer.domElement);// 设置带阻尼惯性controls.enableDamping = true;// 设置带阻尼系数controls.dampingFactor = 0.01;// 设置自动旋转// controls.autoRotate = true;// 渲染函数function animate() {controls.update();updateSunPosition();// // 调用getSunXY函数来计算太阳的位置// const [sunX, sunY, sunZ] = getSunXYZ();// // console.log("sunY",sunY)// directionalLight.position.set(sunX, sunY, sunZ);// 旋转// cube.rotation.x += 0.01;// cube.rotation.y += 0.01;// 渲染renderer.render(scene, camera);requestAnimationFrame(animate);}animate();// 页面监听窗口大小变化window.addEventListener('resize', () => {// 重置渲染器宽高比renderer.setSize(window.innerWidth, window.innerHeight);// 重置相机宽高比camera.aspect = window.innerWidth / window.innerHeight;// 更新相机投影矩阵camera.updateProjectionMatrix();})},methods: {}
}
</script>
<style></style>

思考,这里可以做一个优化就是把每个频率的xyz记录到一个Array中,等一天跑完了,这边就可以直接使用array中的值。不用再复杂的去计算了。

以上就是全部内容。

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

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

相关文章

linux开发工具的介绍

目录 1. Linux 软件包管理器 yum 2.Linux编辑器-vim使用 3.Linux编译器-gcc/g使用 预处理(进行宏替换) 编译(生成汇编) 汇编&#xff08;生成机器可识别代码&#xff09; 链接&#xff08;生成可执行文件或库文件&#xff09; 3.1在链接过程中我们需要用到函数库 函数…

Error running ‘Tomcat 8.5.29‘ Address localhost:1099 is already in use

一、Error running ‘Tomcat 8.5.29’ Address localhost:1099 is already in use 原因&#xff1a;端口1099被占用了。 二、解决 2.1 解决方法一-结束该端口1099占用 //1-查看端口占用&#xff0c;根据端口号1099&#xff0c;获取PID(进程ID) netstat -ano | findstr "…

stackoverflow问题

Stack Overflow requires external JavaScript from another domain, which is blocked or failed to load. stackoverflow引用了谷歌中被屏ajax.googleapis.com的jquery.min.js文件。“https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js” 方案1.打开网站…

字节一面:你能讲一下跨域吗

前言 最近博主在字节面试中遇到这样一个面试题&#xff0c;这个问题也是前端面试的高频问题&#xff0c;作为一名前端开发工程师&#xff0c;我们日常开发中与后端联调时一定会遇到跨域的问题&#xff0c;只有处理好了跨域才能够与后端交互完成需求&#xff0c;所以深入学习跨域…

docker 04.更加重要的命令

之前的都是基础命令&#xff0c; 前台交互进程和后台守护进程&#xff1a; 重新进入容器&#xff1a; docker中的导入导出&#xff1a; docker中的拷贝到&#xff1a;

ubuntu学习(五)----读取文件以及光标的移动

1、读取文件函数原型介绍 ssize_t read(int fd,void*buf,size_t count) 参数说明&#xff1a; fd: 是文件描述符 buf:为读出数据的缓冲区&#xff1b; count: 为每次读取的字节数&#xff08;是请求读取的字节数&#xff0c;读上来的数据保存在缓冲区buf中&#xff0c;同时文…

ubuntu学习(四)----文件写入操作编程

1、write函数的详解 ssize_t write(int fd,const void*buf,size_t count); 参数说明&#xff1a; fd:是文件描述符&#xff08;write所对应的是写&#xff0c;即就是1&#xff09; buf:通常是一个字符串&#xff0c;需要写入的字符串 count&#xff1a;是每次写入的字节数…

Vue3 全局路由的使用

一. App.vue <template><router-view/> </template><script> export default {name: App,components: {} } </script> 二. main.js import { createApp } from vue import App from ./App.vue import router from ./router/indexcreateApp(Ap…

小程序input的placeholder不垂直居中的问题解决

input的placeholder不垂直居中&#xff0c;input设置高度后&#xff0c;使用line-height只能使输入的文字垂直居中&#xff0c;但是placeholder不会居中&#xff0c;反而会偏上。 首先placeholder样式自定义 有两种方法&#xff0c;第一种行内样式&#xff1a; <input ty…

sql server 备份到网络共享

场景&#xff1a;sql server服务器A将数据库备份文件备份到服务器B 1&#xff09;服务器B创建共享目录 这里我将 D:\ProDbBak 共享&#xff0c;并且Everyone完全控制 2&#xff09;sql server服务器A能够访问服务器B共享目录&#xff0c;并且能完全控制 3&#xff09;修改服务…

c语言每日一练(12)

前言&#xff1a;每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。每日一练系列会持续更新&#xff0c;暑假时三天之内必有一更&#xff0c;到了开学之后&#xff0c;将看学业情…

基于Axios完成前后端分离项目数据交互

一、安装Axios npm i axios -S 封装一个请求工具&#xff1a;request.js import axios from axios// 创建可一个新的axios对象 const request axios.create({baseURL: http://localhost:9090, // 后端的接口地址 ip:porttimeout: 30000 })// request 拦截器 // 可以自请求…

Git分布式版本控制系统与github

第四阶段提升 时 间&#xff1a;2023年8月29日 参加人&#xff1a;全班人员 内 容&#xff1a; Git分布式版本控制系统与github 目录 一、案例概述 二、版本控制系统 &#xff08;一&#xff09; 本地版本控制 &#xff08;二&#xff09;集中化的版本控制系统 &…

系统架构:软件工程

文章目录 资源知识点自顶向下与自底向上形式化方法结构化方法敏捷方法净室软件工程面向服务的方法面向对象的方法快速应用开发螺旋模型软件过程和活动开放式源码开发方法功用驱动开发方法统一过程模型RUP基于构件的软件开发UML 资源 信息系统开发方法 知识点 自顶向下与自底…

基于 Debian 12 的 Devuan GNU+Linux 5 为软件自由爱好者而生

导读Devuan 开发人员宣布发布 Devuan GNULinux 5.0 “代达罗斯 “发行版&#xff0c;它是 Debian GNU/Linux 操作系统的 100% 衍生版本&#xff0c;不包含 systemd 和相关组件。 Devuan GNULinux 5 基于最新的 Debian GNU/Linux 12 “书虫 “操作系统系列&#xff0c;采用长期支…

Ubuntu系统环境搭建(八)——Ubuntu开机自动执行命令

ubuntu环境搭建专栏&#x1f517;点击跳转 Ubuntu系统环境搭建&#xff08;八&#xff09;——Ubuntu开机自动执行命令 修改文件 vim /etc/rc.local以自启动mysql为例&#xff0c;在文件末尾添加 /usr/local/mysql8/bin/mysqld_safe --defaults-file/usr/local/etc/my.cnf …

时序预测 | MATLAB实现基于QPSO-BiLSTM、PSO-BiLSTM和BiLSTM时间序列预测

时序预测 | MATLAB实现基于QPSO-BiLSTM、PSO-BiLSTM和BiLSTM时间序列预测 目录 时序预测 | MATLAB实现基于QPSO-BiLSTM、PSO-BiLSTM和BiLSTM时间序列预测效果一览基本描述程序设计参考资料 效果一览 基本描述 1.Matlab实现QPSO-BiLSTM、PSO-BiLSTM和BiLSTM神经网络时间序列预测…

ESDA in PySal (1) 利用 A-DBSCAN 聚类点并探索边界模糊性

ESDA in PySAL (1) 利用 A-DBSCAN 聚类点并探索边界模糊性 在本例中,我们将以柏林的 AirBnb 房源样本为例,说明如何使用 A-DBSCAN (Arribas-Bel et al., 2019)。A-DBSCAN 可以让我们做两件事: 识别高密度 AirBnb 房源集群并划定其边界探索这些边界的稳定性%matplotlib inli…

TCP/IP网络编程(一) 理解网络编程和套接字

文章目录 理解网络编程和套接字网络编程和套接字概要构建套接字编写 Hello World 服务器端构建请求连接套接字在Linux平台下运行 基于Linux的文件操作打开文件关闭文件将数据写入文件读取文件中的数据 理解网络编程和套接字 网络编程和套接字概要 网络编程就是编写程序使两台…