threejs創建自定義多段柱

最近在研究自定義建模,有一個多斷柱模型比較有意思,分享下,就是利用幾組點串,比如上中下,然后每組點又不一樣多,點續還不一樣,(比如第一個環的第一個點在左邊,第二個環在右邊),然后進行插值,連接三角網

主函數:

export function createMultiRingPrismMesh(rings: Vector3[][],material?: Material,
) {if (!material) {const texture = new TextureLoader().load(green)material = new MeshStandardMaterial({map:texture,color: 0x3399ff,side: DoubleSide,wireframe: false,})}if (rings.length < 2) {throw new Error('至少需要兩個環來構建幾何體')}// 將所有環插值為統一點數const targetCount = Math.max(...rings.map((r) => r.length))const processedRings = rings.map((ring) => {const center = computeCenter(ring)const angles = computeAngles(ring, center)const { ring: sortedRing, angles: sortedAngles } = sortRingByAngle(ring,angles,)return interpolateRingByAngles(sortedRing, sortedAngles, targetCount)})const vertices = []const uvs = []const indices = []const ringCount = processedRings.lengthconst count = targetCount// 頂點和UVprocessedRings.forEach((ring, ringIndex) => {ring.forEach((p, i) => {vertices.push(p.x, p.y, p.z)// UV 映射:U 是角度,V 是高度歸一化// const angle = (i / count) * Math.PI * 2uvs.push(i / count, ringIndex / (ringCount - 1)) // U: 角度比例, V: 層級比例})})// 側面三角形索引for (let i = 0; i < ringCount - 1; i++) {const offset = i * countfor (let j = 0; j < count; j++) {const curr = offset + jconst next = offset + ((j + 1) % count)const currTop = curr + countconst nextTop = next + countindices.push(curr, next, currTop)indices.push(next, nextTop, currTop)}}// 封底(第一個環)const bottomCenter = computeCenter(processedRings[0])const bottomCenterIndex = vertices.length / 3vertices.push(bottomCenter.x, bottomCenter.y, bottomCenter.z)uvs.push(0.5, 0.5)for (let i = 0; i < count; i++) {const next = (i + 1) % countindices.push(bottomCenterIndex, next, i)}// 封頂(最后一個環)const topCenter = computeCenter(processedRings[ringCount - 1])const topCenterIndex = vertices.length / 3const topOffset = (ringCount - 1) * countvertices.push(topCenter.x, topCenter.y, topCenter.z)uvs.push(0.5, 0.5)for (let i = 0; i < count; i++) {const next = (i + 1) % countindices.push(topCenterIndex, topOffset + i, topOffset + next)}const geometry = new BufferGeometry()geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3))geometry.setAttribute('uv', new Float32BufferAttribute(uvs, 2))geometry.setIndex(indices)geometry.computeVertexNormals()return new Mesh(geometry, material)
}

?輔助函數

/*** 計算環中心點(平均點)* @param {Vector3[]} ring* @returns {Vector3}*/
function computeCenter(ring: Vector3[]) {const center = new Vector3(0, 0, 0)ring.forEach((p) => center.add(p))center.multiplyScalar(1 / ring.length)return center
}
/*** 計算環中每點相對于中心的角度(0~2π)* 這里按 XZ 平面計算角度* @param {Vector3[]} ring* @param {Vector3} center* @returns {number[]} 角度數組,與ring點一一對應*/
function computeAngles(ring: Vector3[], center: Vector3) {return ring.map((p) => {const dx = p.x - center.xconst dz = p.z - center.zlet angle = Math.atan2(dz, dx)if (angle < 0) angle += Math.PI * 2return angle})
}function interpolateRingByAngles(ring: Vector3[],angles: number[],targetCount: number,
) {const result = []const len = ring.length// 角度歸一化到 [0, 2PI)const TWO_PI = Math.PI * 2for (let i = 0; i < targetCount; i++) {const t = (i / targetCount) * TWO_PI// 找到 t 在 angles 中所在區間 [angles[j], angles[j+1]]// 注意最后一個區間是 [angles[len-1], angles[0] + 2PI]let j = 0for (; j < len; j++) {const a0 = angles[j]const a1 = angles[(j + 1) % len] + (j === len - 1 ? TWO_PI : 0)if (t >= a0 && t <= a1) {// 找到區間const p0 = ring[j]const p1 = ring[(j + 1) % len]const localT = (t - a0) / (a1 - a0)const interpolated = new Vector3().lerpVectors(p0, p1, localT)result.push(interpolated)break}}// 保險 fallback,如果沒找到區間,返回第一個點if (j === len) {result.push(ring[0].clone())}}return result
}// 對角度和點排序(保證升序)
function sortRingByAngle(ring: Vector3[], angles: number[]) {const pairs = ring.map((p, i) => ({ p, angle: angles[i] }))pairs.sort((a, b) => a.angle - b.angle)return {ring: pairs.map((pair) => pair.p),angles: pairs.map((pair) => pair.angle),}
}

使用

createMultiRingPrismMesh([points,points2,points3])

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/917039.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917039.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917039.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Language Models are Few-Shot Learners: 開箱即用的GPT-3(四)

Result續 Winograd-Style Tasks Winograd-Style Tasks 是自然語言處理中的一類經典任務。它源于 Winograd Schema Challenge(WSC),主要涉及確定代詞指的是哪個單詞,旨在評估模型的常識推理和自然語言理解能力。 這個任務中的具體通常包含高度歧義的代詞,但從語義角度看…

BGP高級特性之認證

一、概述BGP使用TCP作為傳輸協議&#xff0c;只要TCP數據包的源地址、目的地址、源端口、目的端 口和TCP序號是正確的&#xff0c;BGP就會認為這個數據包有效&#xff0c;但數據包的大部分參數對于攻擊 者來說是不難獲得的。為了保證BGP免受攻擊&#xff0c;可以在BGP鄰居之間使…

商旅平臺怎么選?如何規避商旅流程中的違規風險?

在中大型企業的商旅管理中&#xff0c;一個典型的管理“黑洞”——流程漏洞與超標正持續吞噬企業成本與管理效能&#xff1a;差標混亂、審批脫節讓超規訂單頻頻闖關&#xff0c;不僅讓企業商旅成本超支&#xff0c;還可能引發稅務稽查風險。隱性的合規風險&#xff0c;比如虛假…

Anaconda的常用命令

Anaconda 是一個用于科學計算、數據分析和機器學習的 Python 發行版&#xff0c;包含了大量的預安裝包。它配有 conda 命令行工具&#xff0c;方便用戶管理包和環境。以下是一些常用的 conda 命令和 Anaconda 的常見操作命令&#xff0c;幫助你高效管理環境和包。1. 環境管理創…

JVM之【Java虛擬機概述】

目錄 對JVM的理解 JVM的架構組成 類加載系統 執行引擎 運行時數據區 垃圾收集系統 本地方法庫 對JVM的理解 JVM保證了Java程序的執行&#xff0c;同時也是Java語言具有跨平臺性的根本原因&#xff1b;Java源代碼通過javac等前端編譯器生成的字節碼計算機并不能識別&…

RabbitMQ+內網穿透遠程訪問教程:實現異地AMQP通信+Web管理

RabbitMQ是一個開源的消息隊列中間件&#xff0c;基于Erlang開發&#xff0c;遵循AMQP&#xff08;Advanced Message Queuing Protocol&#xff0c;高級消息隊列協議&#xff09;標準&#xff0c;主要用于實現異步通信、消息解耦和系統間數據傳輸。它的核心作用是在分布式系統中…

go 語言 timer 與 ticker理論和實例大全

目錄 1. 時間之門的鑰匙:Timer與Ticker的本質 2. Timer:精準的單次計時 2.1 Timer的基礎用法 2.2 停止與重置Timer 2.3 Timer的高級技巧:優雅處理并發 3. Ticker:時間的節拍器 3.1 Ticker的基本用法 3.2 Ticker的高級應用:動態調整周期 4. Timer與Ticker的結合:打…

MySQL 45講 16-17

全字段排序 explain 中的 using fiesort ,掃描 數據,取出符合判斷條件的 數據,到sort buffer中,然后對排序字段采用快速排序進行 排序后直接將 所需字段進行返回 如果 字段長度所占內存大于所分配 的sort buffer ,需要借助 臨時文件 進行 數據的存放排序,此時會采用 歸并排序,將…

QT項目 -仿QQ音樂的音樂播放器(第四節)

一、RecBox中btUp和btDown按鈕clicked處理 選中左右鍵&#xff08;btUp和btDown按鈕&#xff09;然后右擊轉到槽->click() void RecBox::on_btUp_clicked() {}void RecBox::on_btDown_clicked() {} 二、imageList中圖片分組 // recbox.h 中新增 int currentIndex; // 標記…

DeepSeek SEO關鍵詞優化提升流量增長

內容概要DeepSeek SEO關鍵詞優化致力于通過科學的方法&#xff0c;顯著提升網站在搜索引擎中的可見度與自然流量。其核心在于深入理解并精準匹配用戶的真實搜索意圖&#xff0c;而非僅僅堆砌詞匯。具體來說&#xff0c;該策略運用深度意圖導向策略&#xff0c;確保內容與用戶需…

# Ubuntu 系統設置 USB PnP 音頻設備為默認設備的完整教程

Ubuntu 系統設置 USB PnP 音頻設備為默認設備的完整教程 在使用 Ubuntu 系統時&#xff0c;尤其是在嵌入式設備如 NVIDIA Jetson 系列上&#xff0c;我們經常需要將 USB PnP 音頻設備設置為默認設備。本文將詳細介紹如何通過命令行配置&#xff0c;使 USB PnP 音頻設備在系統重…

Hadoop JMX 配置的完整文檔

一、JMX 基礎概念與 Hadoop 支持 1、JMX 作用。 Java Management Extensions&#xff08;JMX&#xff09;提供標準 API 監控 JVM 應用運行時狀態&#xff08;內存、線程、GC&#xff09;及 Hadoop 組件指標&#xff08;HDFS 容量、RPC 性能、節點狀態&#xff09; 2、Hadoop 組…

arm架構系統打包qt程序--麒麟操作系統為例

檢查系統架構 uname -a如果顯示是aarch644或arm64&#xff0c;說明你使用的是ARM架構&#xff0c;&#xff0c;需要下載ARM版本。 下載對應架構的linuxdeployqt 編寫腳本 vim deploy.sh#!/bin/bash APP_NAME"sunny450_silc"# 確保deploy目錄存在 mkdir -p deploy# 復…

Kong API Gateway深度解析:插件系統與微服務架構的技術基石

在微服務&#xff08;microservices&#xff09;架構主導的今天&#xff0c;API網關&#xff08;API Gateway&#xff09;作為服務入口的“交通樞紐”&#xff0c;承擔著流量調度、安全防護、可觀測性&#xff08;observability&#xff09;等核心職責。Kong作為開源API網關領域…

Linux應用開發基礎知識——Makefile初級教程(九)

目錄 一、Makefile是啥&#xff1f; 1.1、了解幾種文件&#xff08;.o 文件和.c文件 &#xff09; 1.2、關于Makefile的寫法 1.3、簡單使用Makefile基本指令 1.4、引入偽目標 1.5、Makefile的優點 1.6、Makefile的使用 二、Makefile創建和使用變量 2.1、創建變量的目的…

面試問題收集——卷積神經網絡

博主會經常分享自己在人工智能階段的學習筆記&#xff0c;歡迎大家訪問我滴個人博客&#xff01;&#xff08;養成系Blog&#xff01;&#xff09; 小牛壯士滴Blog~ - 低頭趕路 敬事如儀https://kukudelin.top/ 01-卷積基礎知識 問&#xff1a;簡述卷積基本操作&#xff0c;…

Kubernetes 全面解析:從基礎設施變革到核心架構詳解

引言在容器化技術席卷全球的今天&#xff0c;Kubernetes&#xff08;簡稱 K8s&#xff09;已成為容器編排領域的事實標準。無論是互聯網企業還是傳統行業&#xff0c;都在通過 Kubernetes 實現應用的高效部署、彈性擴展和自動化運維。但對于初學者而言&#xff0c;Kubernetes 的…

哈希相關的模擬實現

哈希相關的模擬實現哈希表的模擬實現閉散列除留取余法查找、插入和刪除閉散列參考程序開散列除留取余法&#xff08;數組鏈表&#xff09;迭代器查找和刪除插入開散列參考程序unordered_map和unordered_set的模擬實現unordered_mapunordered_set建議先看 哈希的概念及其應用-CS…

Vue3+Vite項目如何簡單使用tsx

安裝必要的依賴npm install vitejs/plugin-vue-jsx -D在 vite.config.ts 中添加以下內容import vueJsx from vitejs/plugin-vue-jsx export default {plugins: [vueJsx()] }在Vue頁面使用<script lang"ts"> import { defineComponent } from vue export defaul…

05百融云策略引擎項目交付-laravel實戰完整交付定義常量分文件配置-獨立建立lib類處理-成功導出pdf-優雅草卓伊凡

05百融云策略引擎項目交付-laravel實戰完整交付定義常量分文件配置-獨立建立lib類處理-成功導出pdf-優雅草卓伊凡引言此前只是把關于如何把查詢內容導出pdf庫的代碼實現了&#xff0c;但是我們并沒有完成整個項目&#xff0c;這最后一個步驟就是安裝composer再安裝tcpdf庫&…