当前位置: 首页 > news >正文

使用 Three.js 创建一个 3D 人形机器人仿真系统

引言

在这篇文章中,我们将探讨如何使用 Three.js 创建一个简单但有趣的 3D 人形机器人仿真系统。这个机器人可以通过键盘控制进行行走和转向,并具有基本的动画效果。

在这里插入图片描述

技术栈

  • HTML5
  • Three.js
  • JavaScript

实现步骤

1. 基础设置

首先,我们需要创建基本的 HTML 结构并引入 Three.js 库:

<!DOCTYPE html>
<html>
<head><title>3D Robot Simulation</title><style>body { margin: 0; overflow: hidden;}canvas { display: block; }#info {position: absolute;top: 10px;left: 10px;color: white;font-family: Arial;font-size: 14px;background: rgba(0,0,0,0.5);padding: 10px;}</style>
</head>
<body><div id="info">使用方向键控制机器人:<br>↑ - 向前移动<br>← → - 左右转向</div><script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
</body>
</html>

2. 场景初始化

接下来,我们需要初始化 Three.js 的基本组件:

const scene = new THREE.Scene();
scene.background = new THREE.Color(0x87CEEB); // 天空蓝色背景const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);

3. 创建机器人类

创建一个 Robot 类来管理机器人的所有组件和动作:

class Robot {constructor() {this.body = new THREE.Group();// 创建躯干const torsoGeometry = new THREE.BoxGeometry(2, 3, 1);const torsoMaterial = new THREE.MeshPhongMaterial({color: 0x999999});this.torso = new THREE.Mesh(torsoGeometry, torsoMaterial);this.torso.castShadow = true;// 创建头部const headGeometry = new THREE.SphereGeometry(0.5);const headMaterial = new THREE.MeshPhongMaterial({color: 0xcccccc});this.head = new THREE.Mesh(headGeometry, headMaterial);this.head.position.y = 2;this.head.castShadow = true;// ... 其他部件的创建代码 ...}// 创建四肢createLimb(width, height) {const geometry = new THREE.BoxGeometry(width, height, width);const material = new THREE.MeshPhongMaterial({color: 0x999999});const limb = new THREE.Mesh(geometry, material);limb.castShadow = true;return limb;}// 行走动画walk() {const legRotation = Math.sin(Date.now() * 0.005) * 0.5;this.leftLeg.rotation.x = legRotation;this.rightLeg.rotation.x = -legRotation;const armRotation = Math.sin(Date.now() * 0.005) * 0.25;this.leftArm.rotation.x = -armRotation;this.rightArm.rotation.x = armRotation;}// 转向和移动方法turn(angle) {this.body.rotation.y += angle;}moveForward(speed) {this.body.position.x += Math.sin(this.body.rotation.y) * speed;this.body.position.z += Math.cos(this.body.rotation.y) * speed;}
}

4. 添加环境元素

创建地面和光照系统:

// 创建地面
const groundGeometry = new THREE.PlaneGeometry(100, 100);
const groundMaterial = new THREE.MeshPhongMaterial({ color: 0x808080,side: THREE.DoubleSide
});
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = -Math.PI / 2;
ground.position.y = -2.5;
ground.receiveShadow = true;
scene.add(ground);// 添加光源
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 10, 5);
directionalLight.castShadow = true;
scene.add(directionalLight);const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);

5. 实现控制系统

添加键盘控制和动画循环:

const keyStates = {};document.addEventListener('keydown', (e) => {keyStates[e.key] = true;
});document.addEventListener('keyup', (e) => {keyStates[e.key] = false;
});function animate() {requestAnimationFrame(animate);if(keyStates['ArrowUp']) {robot.walk();robot.moveForward(0.1);}if(keyStates['ArrowLeft']) {robot.turn(0.05);}if(keyStates['ArrowRight']) {robot.turn(-0.05);}camera.position.x = robot.body.position.x;camera.position.z = robot.body.position.z + 10;camera.lookAt(robot.body.position);renderer.render(scene, camera);
}animate();

主要特性

  1. 3D 人形机器人模型
  2. 基本的行走动画
  3. 键盘控制系统
  4. 相机跟随
  5. 阴影效果
  6. 响应式设计

控制方法

  • ↑ 向前移动
  • ← 向左转
  • → 向右转

可能的改进方向

  1. 添加更多动作(如后退、跳跃)
  2. 改进机器人模型细节
  3. 添加碰撞检测
  4. 添加物理引擎
  5. 实现更复杂的动画效果
  6. 添加声音效果
  7. 增加更多交互控制选项
  8. 优化性能

结论

通过这个项目,我们展示了如何使用 Three.js 创建一个基本的 3D 人形机器人仿真系统。虽然这是一个相对简单的实现,但它为更复杂的 3D 网页应用提供了良好的起点。

完整代码

<!DOCTYPE html>
<html>
<head><title>3D Robot Simulation</title><style>body { margin: 0; overflow: hidden;}canvas { display: block; }#info {position: absolute;top: 10px;left: 10px;color: white;font-family: Arial;font-size: 14px;background: rgba(0,0,0,0.5);padding: 10px;}</style>
</head>
<body><div id="info">使用方向键控制机器人:<br>- 向前移动<br>← → - 左右转向</div><script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script><script>// 初始化场景、相机和渲染器const scene = new THREE.Scene();scene.background = new THREE.Color(0x87CEEB); // 天空蓝色背景const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);const renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setSize(window.innerWidth, window.innerHeight);renderer.shadowMap.enabled = true;document.body.appendChild(renderer.domElement);// 创建机器人类class Robot {constructor() {// 机器人主体this.body = new THREE.Group();// 躯干const torsoGeometry = new THREE.BoxGeometry(2, 3, 1);const torsoMaterial = new THREE.MeshPhongMaterial({color: 0x999999});this.torso = new THREE.Mesh(torsoGeometry, torsoMaterial);this.torso.castShadow = true;// 头部const headGeometry = new THREE.SphereGeometry(0.5);const headMaterial = new THREE.MeshPhongMaterial({color: 0xcccccc});this.head = new THREE.Mesh(headGeometry, headMaterial);this.head.position.y = 2;this.head.castShadow = true;// 眼睛const eyeGeometry = new THREE.SphereGeometry(0.1);const eyeMaterial = new THREE.MeshPhongMaterial({color: 0x000000});this.leftEye = new THREE.Mesh(eyeGeometry, eyeMaterial);this.rightEye = new THREE.Mesh(eyeGeometry, eyeMaterial);this.leftEye.position.set(-0.2, 2, 0.4);this.rightEye.position.set(0.2, 2, 0.4);// 手臂this.leftArm = this.createLimb(0.3, 2);this.leftArm.position.set(-1.2, 1, 0);this.rightArm = this.createLimb(0.3, 2);this.rightArm.position.set(1.2, 1, 0);// 腿部this.leftLeg = this.createLimb(0.4, 2);this.leftLeg.position.set(-0.6, -1.5, 0);this.rightLeg = this.createLimb(0.4, 2);this.rightLeg.position.set(0.6, -1.5, 0);// 组装机器人this.body.add(this.torso);this.body.add(this.head);this.body.add(this.leftEye);this.body.add(this.rightEye);this.body.add(this.leftArm);this.body.add(this.rightArm);this.body.add(this.leftLeg);this.body.add(this.rightLeg);}createLimb(width, height) {const geometry = new THREE.BoxGeometry(width, height, width);const material = new THREE.MeshPhongMaterial({color: 0x999999});const limb = new THREE.Mesh(geometry, material);limb.castShadow = true;return limb;}walk() {// 腿部摆动const legRotation = Math.sin(Date.now() * 0.005) * 0.5;this.leftLeg.rotation.x = legRotation;this.rightLeg.rotation.x = -legRotation;// 手臂摆动const armRotation = Math.sin(Date.now() * 0.005) * 0.25;this.leftArm.rotation.x = -armRotation;this.rightArm.rotation.x = armRotation;}turn(angle) {this.body.rotation.y += angle;}moveForward(speed) {this.body.position.x += Math.sin(this.body.rotation.y) * speed;this.body.position.z += Math.cos(this.body.rotation.y) * speed;}}// 创建地面const groundGeometry = new THREE.PlaneGeometry(100, 100);const groundMaterial = new THREE.MeshPhongMaterial({ color: 0x808080,side: THREE.DoubleSide});const ground = new THREE.Mesh(groundGeometry, groundMaterial);ground.rotation.x = -Math.PI / 2;ground.position.y = -2.5;ground.receiveShadow = true;scene.add(ground);// 创建机器人实例const robot = new Robot();scene.add(robot.body);// 添加光源const directionalLight = new THREE.DirectionalLight(0xffffff, 1);directionalLight.position.set(5, 10, 5);directionalLight.castShadow = true;directionalLight.shadow.camera.near = 0.1;directionalLight.shadow.camera.far = 100;directionalLight.shadow.camera.left = -50;directionalLight.shadow.camera.right = 50;directionalLight.shadow.camera.top = 50;directionalLight.shadow.camera.bottom = -50;scene.add(directionalLight);const ambientLight = new THREE.AmbientLight(0x404040);scene.add(ambientLight);// 设置相机位置camera.position.set(0, 5, 10);camera.lookAt(robot.body.position);// 键盘状态const keyStates = {};// 键盘事件监听document.addEventListener('keydown', (e) => {keyStates[e.key] = true;});document.addEventListener('keyup', (e) => {keyStates[e.key] = false;});// 窗口大小调整window.addEventListener('resize', onWindowResize, false);function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);}// 动画循环function animate() {requestAnimationFrame(animate);// 更新机器人动作if(keyStates['ArrowUp']) {robot.walk();robot.moveForward(0.1);}if(keyStates['ArrowLeft']) {robot.turn(0.05);}if(keyStates['ArrowRight']) {robot.turn(-0.05);}// 相机跟随camera.position.x = robot.body.position.x;camera.position.z = robot.body.position.z + 10;camera.lookAt(robot.body.position);renderer.render(scene, camera);}animate();</script>
</body>
</html>

相关文章:

使用 Three.js 创建一个 3D 人形机器人仿真系统

引言 在这篇文章中&#xff0c;我们将探讨如何使用 Three.js 创建一个简单但有趣的 3D 人形机器人仿真系统。这个机器人可以通过键盘控制进行行走和转向&#xff0c;并具有基本的动画效果。 技术栈 HTML5Three.jsJavaScript 实现步骤 1. 基础设置 首先&#xff0c;我们需要…...

图像修复和编辑大一统 | 腾讯北大等联合提出BrushEdit:BrushNet进阶版来了

文章链接&#xff1a;https://arxiv.org/pdf/2412.10316 项目链接&#xff1a;https://liyaowei-stu.github.io/project/BrushEdit 亮点直击 提出了BrushEdit&#xff0c;这是先前BrushNet模型的高级迭代版本。BrushEdit通过开创基于修复&#xff08;inpainting&#xff09;的图…...

【hackmyvm】Adroit靶机wp

tags: HMVjava反编译SQL注入 1. 基本信息^toc 文章目录 1. 基本信息^toc2. 信息收集3. java反编译4. sql注入5. 解密密码6. 提权 靶机链接 https://hackmyvm.eu/machines/machine.php?vmAdroit 作者 alienum 难度 ⭐️⭐️⭐️⭐️️ 2. 信息收集 ┌──(root㉿kali)-[~] └…...

【Python运维】自动化备份与恢复系统的实现:Python脚本实战

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 随着信息化进程的加速,数据的重要性日益增加,数据丢失的风险也随之增加。为了保证数据安全,定期备份和及时恢复数据是必不可少的操作。本…...

Goland 安装与使用

GoLand安装 官方网址&#xff1a; JetBrains GoLand&#xff1a;不只是 Go IDE 1. 进入官网&#xff0c;点击下载&#xff1a; ​ 2. 如下图一步步安装 ​ ​ ​ ​ ​ 3. 如下图一步步安装...

vue2 升级为 vite 打包

VUE2 中使用 Webpack 打包、开发&#xff0c;每次打包时间太久&#xff0c;尤其是在开发的过程中&#xff0c;本文记录一下 VUE2 升级Vite 步骤。 安装 Vue2 Vite 依赖 dev 依赖 vitejs/plugin-vue2": "^2.3.3 vitejs/plugin-vue2-jsx": "^1.1.1 vite&…...

FreeSwitch中启用WebRTC

在FreeSwitch中启用WebRTC需要进行一系列配置。以下是详细的步骤&#xff1a; 1. 安装必要的依赖&#xff1a; 确保安装了支持WebRTC的依赖库&#xff0c;如libsrtp。 2. 配置SIP Profile&#xff1a; 编辑 conf/sip_profiles/internal.xml 文件&#xff0c;添加或修改以下内…...

R语言的数据类型

标题&#xff1a;《探索R语言数据类型的奥秘》 引言&#xff1a; 在统计学和数据分析的世界里&#xff0c;R语言无疑是一颗璀璨的明星。它以其强大的数据处理能力和丰富的图形展示功能而受到广泛欢迎。然而&#xff0c;要熟练掌握并高效使用R语言&#xff0c;深入了解其数据类…...

基于UNET的图像分类

网络架构 UNet网络是一种革命性的图像分割架构,在图像分类任务中同样展现出卓越的性能。其独特的设计巧妙地平衡了全局信息捕捉和精细细节保留的需求,特别适合处理需要高度精确定位的任务。 UNet的核心设计理念体现在其 对称的编码器-解码器结构 中。这种结构不仅实现了高效…...

css文字折行以及双端对齐实现方式

使用flex布局后&#xff0c;文字超出容器部分不会自动折行了。实现代码如下&#xff1a; <el-row><el-col :span"24"><span class"label">姓名</span><span class"content">{{name}}</span></el-col>…...

华为云语音交互SIS的使用案例(文字转语音-详细教程)

文章目录 题记一 、语音交互服务&#xff08;Speech Interaction Service&#xff0c;简称SIS&#xff09;二、功能介绍1、实时语音识别2、一句话识别3、录音文件识别4、语音合成 三、约束与限制四、使用1、API2、SDK 五、项目集成1、引入pom依赖2、初始化 Client1&#xff09;…...

设计一个监控摄像头物联网IOT(webRTC、音视频、文件存储)

前言&#xff1a; 设计一个完整的 监控摄像头物联网 IoT 平台 涉及 视频直播和点播、WebRTC 和 文件存储模块&#xff0c;可以分为以下几个主要部分&#xff1a;摄像头设备、服务端处理、Web 前端、视频流存储和回放。以下是结合这些技术的一个具体完整流程设计&#xff0c;涵盖…...

学习笔记(prism--视频【WPF-prism核心教程】)--待更新

《一》框架介绍 prism是一个用于WPF…和winUI中构建的松散耦合&#xff0c;可维护和可测试的应用程序框架。帮助WPF开发人员以简化编写&#xff0c;维护和扩展来设计应用程序。 优点&#xff1a;遵循特定的约定&#xff0c;可自动将view/ViewModel建立DataContext的关系&#…...

Kafka无锁设计

前言 在分布式消息队列系统中,Kafka 的无锁设计是其高吞吐量和高并发的核心优势之一。通过避免锁的竞争,Kafka 能够在高并发和大规模的生产环境中保持高效的性能。为了更好地理解 Kafka 的无锁设计,我们首先对比传统的队列模型,然后探讨 Kafka 如何通过无锁机制优化生产者…...

【GO基础学习】gin框架路由详解

文章目录 gin框架路由详解&#xff08;1&#xff09;go mod tidy&#xff08;2&#xff09;r : gin.Default()&#xff08;3&#xff09;r.GET()路由注册 &#xff08;4&#xff09;r.Run()路由匹配 总结 gin框架路由详解 先创建一个项目&#xff0c;编写一个简单的demo&#…...

GPIO+TIM(无PWM)实现呼吸灯功能

程序特点&#xff1a; 1、模块化&#xff0c;可快速移植&#xff0c;5分钟便可完成移植。 2、通过GPIO普通定时器&#xff0c;实现呼吸灯功能。 3、PWM周期为5ms&#xff0c;占空比调节时间为20ms&#xff0c;占空比为100等份&#xff0c;即呼吸灯从暗到亮需要20ms*1002s。 …...

贪心算法.

贪心算法是指只从当前角度出发,做出当前情景下最好的选择,在某种意义上来说是局部最优解,并不从全局的角度做决策.如果贪心策略选择不恰当,可能无法得到全局最优解. 贪心算法的基本流程如下: 1.分析问题,确定优化目标,对变量进行初始化 2.制定贪心策略:在制定贪心策略时需要…...

Linux系统和makefile详解

### Linux系统详解 Linux是一个开源且功能强大的操作系统内核&#xff0c;自1991年由林纳斯托瓦兹首次发布以来&#xff0c;它已经成为全球最流行的操作系统之一。Linux的核心特性包括开源、多用户多任务、高稳定性与安全性&#xff0c;以及良好的跨平台能力。 1. **开源**&a…...

GitLab 将停止为中国区用户提供服务,60天迁移期如何应对? | LeetTalk Daily

“LeetTalk Daily”&#xff0c;每日科技前沿&#xff0c;由LeetTools AI精心筛选&#xff0c;为您带来最新鲜、最具洞察力的科技新闻。 GitLab作为一个广受欢迎的开源代码托管平台&#xff0c;近期宣布将停止服务中国大陆、澳门和香港地区的用户提供服务。根据官方通知&#x…...

【杂谈】-AI搜索引擎如何改变传统SEO及其在内容营销中的作用

AI搜索引擎如何改变传统SEO及其在内容营销中的作用 文章目录 AI搜索引擎如何改变传统SEO及其在内容营销中的作用1、什么是AI搜索引擎2、AI搜索引擎对SEO策略的影响3、AI搜索引擎在内容营销转型中的作用4、AI搜索引擎在营销领域的挑战、道德问题和未来5、总结 在当今的数字营销世…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...