Three.js如何计算3DObject的2D包围框?

news2024/11/15 14:19:14

在这里插入图片描述

推荐:用 NSDT编辑器 快速搭建可编程3D场景

在Three.js应用开发中,有时你可能需要为3D场景中的网格绘制2D的包围框,应该怎么做?

朴素的想法是把网格的3D包围框投影到屏幕空间,例如,下图中的绿色框 3D包围框, 当将其投影为 2D 时,得到的红色2D包围框,显然比想要的蓝色框大很多:
在这里插入图片描述

正确的做法是先将3D网格投影到屏幕空间,再计算2D包围框。

1、计算单个网格的2D包围框

只需将所有顶点转换为屏幕空间并从中创建一个 2d 边界框:

function computescreenspaceboundingbox(mesh, camera) {
  var vertices = mesh.geometry.vertices;
  var vertex = new three.vector3();
  var min = new three.vector3(1, 1, 1);
  var max = new three.vector3(-1, -1, -1);

  for (var i = 0; i < vertices.length; i++) {
    var vertexworldcoord = vertex.copy(vertices[i]).applymatrix4(mesh.matrixworld);
    var vertexscreenspace = vertexworldcoord.project(camera);
    min.min(vertexscreenspace);
    max.max(vertexscreenspace);
  }

  return new three.box2(min, max);
}

生成的 box2 位于标准化屏幕坐标 [-1, 1] 中, 可以通过乘以渲染器高度和宽度的一半来获得像素:

function normalizedtopixels(coord, renderwidthpixels, renderheightpixels) {
  var halfscreen = new three.vector2(renderwidthpixels/2, renderheightpixels/2)
  return coord.clone().multiply(halfscreen);
}

2、计算3DObject的2D包围框

更完善的实现需要考虑组、子节点等各种3DObject,其中可能包含多个网格,这需要一个递归实现,代码如下:

function computescreenspaceboundingbox(obj, camera) {
    var min;
    var max;

    // is this an array of objects?
    if(array.isarray(obj)) {
        for(var i = 0; i < obj.length; ++i) {
            let box2 = computescreenspaceboundingbox(obj[i], camera);
            if(min === undefined) {
                min = box2.min.clone();
                max = box2.max.clone();
            } else {
                min.min(box2.min);
                max.max(box2.max);
            }
        }
    }

    // does this object have geometry?
    if(obj.geometry !== undefined) {
        var vertices = obj.geometry.vertices;
        if(vertices === undefined
            && obj.geometry.attributes !== undefined
            && 'position' in obj.geometry.attributes) {
            // buffered geometry
            var vertex = new three.vector3();       
            var pos = obj.geometry.attributes.position;
            for(var i = 0; i < pos.count * pos.itemsize; i += pos.itemsize)
            {
                vertex.set(pos.array[i], pos.array[i + 1], pos.array[1 + 2]);
                var vertexworldcoord = vertex.applymatrix4(obj.matrixworld);
                var vertexscreenspace = vertexworldcoord.project(camera);
                if(min === undefined) {
                    min = vertexscreenspace.clone();
                    max = vertexscreenspace.clone();
                }
                min.min(vertexscreenspace);
                max.max(vertexscreenspace);
            }
        } else {
            // regular geometry
            var vertex = new three.vector3();       
            for(var i = 0; i < vertices.length; ++i) {
                var vertexworldcoord = vertex.copy(vertices[i]).applymatrix4(obj.matrixworld);
                var vertexscreenspace = vertexworldcoord.project(camera);
                if(min === undefined) {
                    min = vertexscreenspace.clone();
                    max = vertexscreenspace.clone();
                }
                min.min(vertexscreenspace);
                max.max(vertexscreenspace);
            }
        }
    }
    
    // does this object have children?
    if(obj.children !== undefined) {
        for(var i = 0; i < obj.children.length; ++i) {
            let box2 = computescreenspaceboundingbox(obj.children[i], camera);
            if(min === undefined) {
                min = box2.min.clone();
                max = box2.max.clone();
            } else {
                min.min(box2.min);
                max.max(box2.max);
            }
        }
    }
    
    return new three.box2(min, max);
}

原文链接:计算3D对象的2D包围框 — BimAnt

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

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

相关文章

Linux 部署1Panel 现代化运维管理面板进行公网远程访问

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《速学数据结构》 《C语言进阶篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透2.1 使用一键脚本安装命令 2.2向系统添加服务2.3 启动cpolar服务…

【名城优企游学】国轩高科,用数字化带来强劲发展动力

成立于2006 年5月&#xff0c;系中国动力电池产业最早进入资本市场的民族企业&#xff1b;2015年5月上市&#xff0c;股票代码SZ.002074&#xff0c;拥有新能源汽车动力锂电池、储能、输配电设备等业务板块&#xff0c;建有独立成熟的研发、采购、生产、销售体系。 它就是新能…

五分钟了解一下什么是「贪心算法 」‼️‼️‼️

五分钟了解一下什么是「贪心算法 」‼️‼️‼️ 1 概念 贪心的意思在于在作出选择时&#xff0c;每次都要选择对自身最为有利的结果&#xff0c;保证自身利益的最大化。贪心算法就是利用这种贪心思想而得出一种算法。 贪心算法作为五大算法之一&#xff0c;在数据结构中的应…

如何进行lidar和imu的外参标定

我们使用的lidar_align这个算法来进行标定。 1.下载源码 在ros工作空间下的src文件夹下运行这个命令。 git clone https://github.com/ethz-asl/lidar_align.gitsudo apt-get install libnlopt-devcd ..catkin_make 这里编译的时候会爆一些错误。我遇到的是&#xff1a; 这…

渗透测试成功的8个关键

渗透测试 (penetration test)并没有一个标准的定义&#xff0c;国外一些安全组织达成共识的通用说法是&#xff1a;渗透测试是通过模拟恶意黑客的攻击方法&#xff0c;来评估计算机网络系统安全的一种评估方法。这个过程包括对系统的任何弱点、技术缺陷或漏洞的主动分析&#x…

考试中心|学习资料|学习情况|纯净无广|在线组卷刷题

土著刷题Plus专业版v1.2版本已全面对其个人版功能&#xff0c;完全满足学员培训/刷题考察全套流程&#xff0c;提供完整的服务流程。接下来将主要介绍一下这一版的新功能 考试中心 满足培训机构/刷题组织者考察刷题用户的管理需求&#xff0c;【围绕考试展开】&#xff0c;提供…

SQLite数据库使用时碰到的问题

背景 1、最近使用sqlite数据库&#xff0c;因为轻量&#xff0c;所以&#xff0c;不需要特别的部署服务器环境。 开发的平台使用的是Qt 碰到的问题 1、我在向数据库中插入字段的时候&#xff0c;少写了一个字段的内容&#xff0c;报这个错误 QSqlError("", "…

火焰原子吸收光谱法、容量法和电感耦合等离子体发射光谱法

声明 本文是学习GB-T 1871.5-2022 磷矿石和磷精矿中氧化镁含量的测定 火焰原子吸收光谱法、容量法和电感耦合等离子体发射光谱法. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件描述了在磷矿石和磷精矿中测定氧化镁含量的火焰原子吸收…

史上最全 结构型模式之 代理 适配器 装饰者 模式

创建型设计模式 原型模式 建造者模式 创建者模式对比_软工菜鸡的博客-CSDN博客 5&#xff0c;结构型模式 day03 结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式&#xff0c;前者采用继承机制来组织接口和类&#xff0c;后者釆用组…

大模型部署手记(8)LLaMa2+Windows+llama.cpp+英文文本补齐

1.简介&#xff1a; 组织机构&#xff1a;Meta&#xff08;Facebook&#xff09; 代码仓&#xff1a;https://github.com/facebookresearch/llama 模型&#xff1a;llama-2-7b 下载&#xff1a;使用download.sh下载 硬件环境&#xff1a;暗影精灵7Plus Windows版本&#…

制药企业纯化水设备的应用及维护:设备健康管理软件的关键作用

纯化水设备在制药企业中扮演着重要角色&#xff0c;为生产高纯度水提供支持。然而&#xff0c;为了确保设备的可靠性和稳定性&#xff0c;有效的维护和管理至关重要。设备健康管理软件PreMaint成为实现这一目标的关键工具。本文将介绍PreMaint软件如何优化纯化水设备的维护&…

Qt_C++读写FM1208 CPU卡源码、支持windows、Linux系统

本示例使用的发卡器&#xff1a; Android Linux RFID读写器NFC发卡器WEB可编程NDEF文本/智能海报/-淘宝网 (taobao.com) #include "mainwindow.h" #include "./ui_mainwindow.h" #include <QDebug> #include "QLibrary" #include "Q…

政府部门搭建的数字化工具平台有哪些?

政府部门搭建的数字化工具平台多样且广泛&#xff0c;旨在提高行政效能、优化公共服务和促进政务创新。以下是一些常见的数字化工具平台及其功能的详细介绍。 一、电子政务平台 1. 政务门户网站&#xff1a;作为政府对外的窗口&#xff0c;提供政府机构、政策信息、在线办事、…

Redis 的过期键 | Navicat 技术干货

Redis 是一种高性能的内存数据存储&#xff0c;以其速度和多功能性而闻名。其中一个有用的特性是为键设置过期时间的功能。在 Redis 中&#xff0c;为键设置过期时间对于管理数据和确保过时或临时数据自动从数据库中删除是至关重要的。在本文中&#xff0c;我们将探讨在 redis-…

SpringBoot整合DataWay配置前端查询

Dataway介绍 Dataway 是基于 DataQL 服务聚合能力&#xff0c;为应用提供的一个接口配置工具。使得使用者无需开发任何代码就配置一个满足需求的接口。整个接口配置、测试、冒烟、发布。一站式都通过 Dataway 提供的 UI 界面完成。UI 会以 Jar 包方式提供并集成到应用中并和应…

Springboot学习笔记——3

Springboot学习笔记——3 一、热部署1.1、手动启动热部署1.2、自动启动热部署1.3、热部署范围配置1.4、关闭热部署 二、配置高级2.1、第三方bean属性绑定2.2、松散绑定2.3、常用计量单位应用2.4、bean属性校验2.5、进制数据转换规则 三、测试3.1、加载测试专用属性3.2、加载测试…

mysql面试题32:MySQL数据库服务器性能分析的方法命令有哪些?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:MySQL数据库服务器性能分析的方法命令有哪些? MySQL数据库服务器性能分析的方法和命令有以下几种: EXPLAIN命令:用于分析查询语句的执行计划,…

基于springboot实现在线动漫信息交流分享平台项目【项目源码+论文说明】计算机毕业设计

基于springboot实现在线动漫信息交流分享平台演示 摘要 随着社会互联网技术的快速发展&#xff0c;每个行业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于在线动漫信息平台当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#x…

结婚请帖邀请函制作全攻略,一分钟学会

结婚是人生的重要时刻之一&#xff0c;而一份精美的结婚请帖邀请函则是新人向亲友们发出完美邀请的必备品。为了让你轻松制作出令人惊艳的结婚请帖邀请函&#xff0c;我们为你推荐一个简单易用的在线制作平台——乔拓云微传单平台。只需一分钟&#xff0c;你就能轻松学会&#…

城市项目招商创业园区供需特产公益小程序开源版开发

城市项目招商创业园区供需特产公益小程序开源版开发 城市项目招商创业园区供需特产公益小程序的功能主要包括以下几个方面&#xff1a; 项目招商&#xff1a;提供城市项目招商信息&#xff0c;包括项目介绍、投资额、回报率等详细信息&#xff0c;方便投资者了解项目情况&#…