手寫動態 3D 蛛網圖 | THREE.js

2021-01-21 澎湃新聞

原創 服老思 P話 收錄於話題#3D1#可視化1#算法2#數據2

��雷達圖容易誤用,所以我一般不用。從數據可視化的最佳實踐來說,不推薦 3D,因為透視關係導致無法準確比較。同時,不推薦動態圖,人老了後看起來眼花,當然某些場景下引入時間維度後,可以增強信息密度,如��動態柱狀圖和��動態折線圖。

我們做人有原則,要麼嚴格遵守,要麼三條一起破壞。

所以,今天做一個 3D 的、動態的雷達圖。最後選擇用 THREE.js 實現主體,用 DOM 實現控制項和交互。

Hacking THREE

之前 ��解析《自然》 雜誌 150 年論文可視化作品 中,提到過這個庫。THREE.js 基於 WebGL,前身是廣泛用於 3D 遊戲的 OpenGL。隨著移動硬體性能的提升,OpenGL 這套標準接口,在 web 環境中,也普及開來。而 THREE 對 WebGL 進行了更友好的封裝,使得沒有計算機圖形學的開發者,也能夠很快地搭建自己的 3D 場景。

推薦網站:https://threejsfundamentals.org/

如果追求速度的話,看過 Fundamentals、Responsive Design、Primitives 這三章,就可以開始 hack 自己的項目了。如果趕時間的話, Responsive Design 一節可以後面來看。不過推薦放在前面,這樣可以讓自己的設計從一開始避免鋸齒、拉伸等問題,之後可以專注在圖形上。閱讀加練習大概 2-3 小時。

https://threejsfundamentals.org/threejs/lessons/threejs-fundamentals.html

基本概念:

•Renderer:渲染引擎,它的輸入是 scene 和 camera

•Object:一個基本單元

•Scene/ scene graph:類似文件夾,scene 和包含 object,scene 可以嵌套

•Geometry:幾何形狀,具體包括點(vector3)、面(face3)

•Material:材質,應用在面上

•Texture:紋理,應用在材質上

•Mesh:Geometry 和 Material 的組合;Geometry 決定了畫什麼、Material 決定了怎麼畫

•Light:光源

•Camera:鏡頭

THREE 的世界中,hello world 就是一個 「Hello Cube」,即畫一個方塊。跟教程的第一個 milestone 大概是上面這樣,有幾個 cube,不停翻轉。

https://threejsfundamentals.org/threejs/lessons/threejs-fundamentals.html

如果是初學,建議在這裡多花一點時間,調整各項參數,觀察結果,以掌握基本概念。否則,很容易花了大把功夫後,怎麼也調不出自己要的圖形。

我遇到的幾個常見問題有:

•相機方向問題,物件不在視野內

•視域的長度不夠(far)

•沒有加光源

•光源沒有對準物體

•座標系錯誤。注意右手法則。x 向右(拇指)、y 向上(食指)、z 從屏幕指向自己(中指)。

•角度錯誤。注意 THREE 裡面的旋轉(rotation)用弧度(radian),但相機的設置中,fov 用角度(degree)。

•面的方向(法向量)

有了 Hello Cube 後,可以進一步嘗試光照、相機、材質等不同設置。

接下來,就可以探索 THREE 裡面現成的形狀,把它們拼接起來就可以組成複雜的圖形。原網頁可以掃碼查看。

https://threejsfundamentals.org/threejs/lessons/threejs-primitives.html

可以看到,有許多現成的圖形。

比如,下面演示了如何畫一個 3D 的心形。這段代碼的功能其實更廣,它示範了如何通過一系列 2D 的點,通過貝塞爾曲線連接起來,再生成一個 3D 空間中的面。

https://threejsfundamentals.org/threejs/lessons/threejs-primitives.html

又比如,下面演示了如何通過矢量字體,生成三體空間中的形狀。

https://threejsfundamentals.org/threejs/lessons/threejs-primitives.html

我們的目標是蛛網圖,每一個數據點是一個多面柱,它們通過顏色和高度來彼此區分,多面柱的每個稜角,就是一個維度。所以,基本的單元是多面柱。我們在 THREE 的 primitive 裡面尋找,最接近的是下面這個形狀。

https://threejsfundamentals.org/threejs/lessons/threejs-primitives.html

可是它有一個問題:所有的稜都是一樣的長度。

我們的數據可視化中,需要根據數據值的不同,來設置稜的長度。

於是,這裡要做一點探索。首選的方案,是非侵入式的。即如果能通過 THREE 已經有的接口,從外部改變這個多面柱的特性,達到我們的可視化效果,則為上策。實在不行,可以選擇魔改一把 THREE,再硬嵌入到項目中。

這就回到補充基本概念的時候。

https://threejsfundamentals.org/threejs/lessons/threejs-primitives.html

在 THREE 中,模型是通過 Gemoetry 設定的。Geometry 的設定有兩部分:

•設置一系列的頂點。每個頂點由 (x, y, z) 這樣一個三元組聲明,代表空間中的座標。

•設置一系列的三角形。每個頂點由 (id1, id2, id3) 這樣的三元組聲明,代表點集中下標。

所以,如果要程序化地改變一個形狀,只需要改變頂點的位置,不用改變三角形的設置,與該頂點相連的線和面就會自動地改變。不過注意要把 verticesNeedUpdate 和 elementsNeedUpdate 兩個標記打上,這樣在下次渲染的時候,引擎會做相應的更新。

在 Hello Cube 的基礎上,做如下改變測試。

通過改變頂點,實現形狀變化

其中一個頂點,會以 8 秒為周期,伸長後又縮短。可以看到,鄰接的面都配合變化,非常平滑。

經過這個實驗,我們就有信心,一定能通過一些 primitive,以及修改頂點的方法,來實現可變尺寸的多面柱(VariableCylinder)。

不過,從外部實現的話,要修改的頂點比較多。其中涉及到極座標的公式,核心計算部分和普通多面柱(Cylinder)是重複的。另外,修改完頂點,還要重新計算 UV 和法向量,才能正確響應光照和紋理的設置。

考慮到這些,覺得先看一下源碼比較好,也許直接改庫更方便。

源碼:https://github.com/mrdoob/three.js/blob/master/src/geometries/CylinderGeometry.js

將這個 CylinderGeometry 拷貝一份,做成我們自己的 VariableCylinderGeometry。事實證明,只需要修改 7 行,就達到目的了……

當然,為了修改這 7 行,需要花點時間研究 THREE 這個項目的結構。另外,由於是可變的多面柱,數據接口發生了一些變化。之前只需要輸入稜的個數,而現在要輸入的是每個稜的相對長度。

想起了福特和斯坦門茨的那個廣為流傳的段子:畫一根線,只要一美元;知道在哪裡畫這根線,值 9999 美元。

比較好的方法,可能是從模組級別集成 THREE,然後自己派生出這個可變多面柱的類。由於對前端工程不熟悉,一看到近年的各種框架和 import 就頭大。於是選擇了魔改路線,直接侵入式地做了需要的修改,然後重新 build 一個 THREE 嵌在項目裡面。

導入魔改版的THREE,將 HelloCube 改一下,得到了多面柱:

可變多面柱

接下來比較重要的部分就是蛛網了。計算核心還是極座標變換。得到關鍵點後,放入一個 Geometry,再通過 THREE.Line 這個輔助工具,轉化成可渲染的圖形。注意 THREE.Line 的地位和 THREE.Mesh 是類似的。而 Geometry 中,有點和面,但是沒有線。

蛛網的大致效果如下。

大家可能發現,前面的模型,都是用黑色作為背景。以前我也覺得奇怪,是不是設計師喜歡黑色背景,看起來更高端?

其實更直接的原因是,在 3D 的世界中,一切本來就是黑的。因為有了光、有了物體,而光照到物體上,我們才看到不同的顏色。哪怕是背景,也是如此。如果用戶看到的不是黑色,說明有東西在那,它反光。

所以,我們需要在所有的物件下面(-y 的區域),加一個白色的面,作為襯底。

把以上物件組合在一起,就得到第一個原型了。

接著,在 canvas 的上面,加一個浮層,放入座標標籤和相對應的值。再給 legend 加上事件,當用戶選擇的時候,可以高亮相應的多面柱。最後,再調一下顏色。這部分和平時寫的前端沒什麼差別,就略過細節了。

一個 3D 動態蛛網圖,就做成了。

這個圖有什麼用呢?

它比較適合數據點在各個維度都單調遞增的場景。比如,用來描述一個同學的成績,每個軸代表一個學科,每個多面柱代表一個年份。隨著努力學習,他成績越來越好,就是這樣的感覺。如果不滿足這個單調遞增,則效果是很奇怪的,下層的柱子,可能有一部分 「陷入」 上層的柱子中。

覆盤

時間開銷:

•調研:10%

•入門 THREE:20%

•Hacking prototype:30%

•調整細節:40%

其中,調研階段考慮了 aframe 和 THREE 兩個庫。aframe 是基於 THREE 的一套 declarative 語言。通過 HTML 元素,來生成 3D 的物件。如果是簡單的圖形,用 aframe 確實很方便。經過幾年的發展,它有了一個強大的社區,其中有不少參考項目。另外,還內置一個所見即所得(WYSIWYG)的編輯器,對於調整細節非常方便。

Aframe 內置編輯器 (ctrl+alt+i)

對於稍微複雜的項目,可以通過建模軟體,如 Maya 建立模型,再導入 aframe,利用前端技術做交互。這樣開發者不需要有關於 3D 圖形的知識,只需要復用 DOM 交互的經驗即可,可以滿足快速開發的需求。

不過,當圖形是數據驅動生成的時候,發現 aframe 就有點差強人意了。程序化地修改,可以比較方便完成的是:

•平移

•縮放

•旋轉

•組合

如果要改變一個形狀本身,比如這次我們需要的可變多面體,aframe 就需要一個 custom model。而 custom model 是用 THREE 寫的…… 所以結果是,不如直接學習 THREE 好了。

這是前期調研走的一點彎路。該來的遲早會來,怎麼也擋不住。不過好在 THREE 的封裝已經極其方便,相比十年前學習OpenGL,已經快了很多。由於都是在前端,可以綜合使用 WebGL 和 DOM 兩種技術,利用浮層實現假 3D 的效果,也能省下不少時間。如果放在古時候,到這會可能才把 Hello Cube 搞定……

CREDIT

排版:Bee

數據科學 | 數字廣告 | 未來主義

原標題:《手寫動態 3D 蛛網圖 | THREE.js》

閱讀原文  

相關焦點

  • three.js為何如此奇妙
    WebGL是在瀏覽器中實現三維效果的一套規範,而最初使用WebGL原生的API來寫3D程序是一件非常痛苦的事情,在辛苦的付出下WebGL開源框架出現了,其中three.js就是非常優秀的一個,它掩蓋了很多麻煩的細節,那麼,就讓我們一起來看看,什麼是three.js吧!
  • threeJS——ASCII:實現代碼雨的科幻效果
    在這部影片中, 有一個非常經典的畫面效果對不起, 不是這張, 而是這張叫做代碼雨,大家可以通過百度看一下代碼雨的動態效果。而在電影中,所有的現實中的東西都是由一串串代碼組成的, 比如這樣。今天, 我就要帶領大家製作這樣的效果。這個效果叫做ASCII碼字化效果(文本畫),非常簡單。
  • ThreeJS-初體驗(1.0)
    應用場景遊戲3D模型VR數據可視化開始之前在開始threejs之前我們還需要了解一些相關知識。控制器(Control): 可通過鍵盤、滑鼠控制相機的移動結語了解到接下來業務可能會涉及到相關業務,就提前了解了一些相關three知識,通過了解根深的認識到這一塊相關知識面涉及得比較廣泛,通過簡單了解到three能做什麼,接下來也會通過完成小demo來根深一步的認知three,喜歡的小夥伴可以關注我,在近期會更新demo上線。
  • Threejs開發3D地圖實踐總結
    問題的解決思路是要保證在3d世界中的縮放尺寸,經過一系列變換投影到相機屏幕後仍然與canvas在屏幕上的大小保持一致。這需要我們計算出屏幕像素與3d世界中的長度單位的比值,然後將sprite縮放到合適的3d長度。
  • ThingJS:基於WebGL的3D技術在網頁中的運用
    因此,很多3D圖形引擎庫應運而生,直接使用Javascript腳本語言開發,將WebGL進行不同程度的封裝,例如「three js「、「scenceJS」、「Oak3d」和「simjs」等,這些引擎庫能夠讓用戶更加方便地進行3D圖形繪製和動畫的製作。
  • 基於WebGL的3D可視化告警系統關鍵技術解析 ThingJS
    為了解決開發效率低的問題,出現了基於 JavaScript語言的第三方庫-three.js,這是開源的技術,受到了廣大前端轉3D開發師的追捧。three.js是一個跨瀏覽器的腳本,它封裝了底層的圖形接口,對 WebGL有很好的支持,不需要掌握複雜的圖形學知識就能實現三維場景的渲染。
  • 基於webgl的三維室內空間邏輯建模 three.js ThingJS
    進出層級官方示例>>```javascriptvar app = new THING.App({url: 'https://www.thingjs.com/static/models/storehouse' // 場景地址
  • 20個使用WebGL和Three.js實現的網頁場景
    20個使用WebGL和Three.js實現的網頁場景 也許你們可能已經聽說過關於Three.js庫,Three.js是一個WebGL第三方庫,它能夠讓瀏覽器更加輕鬆的使用和實現3D效果,就打個
  • 藉助WebGL三維可視化技術檢索3D動態圖像
    瀏覽器對WebGL的越來越完善,,WebGL基於GPU渲染技術,支持海量數據的的動態渲染,在對海量的遙感,氣象等數據進行可視化渲染,分析時,我們選用了WebGL技術,滿足對柵格數據在操作。同時柵格數據這些格點數據,在數據統計時更是對數以百萬計的二維矩陣的運算分析,藉助WEBGL GPGPU通用GPU計算功能統計運算。
  • 3d全景是什麼意思?3d全景圖怎麼做的
    3d全景便是如此,它的出現給我們帶來很多以往圖文視頻所不能達到的體驗。3d全景是什麼呢意思?3d全景圖又被很多人稱為三維全景和vr全景,實際上是一種新的展現方式,不同以往的是能夠給人帶來很好的沉浸感,對所展現的空間有一種仿佛身臨其境般的體驗。實際上目前3d全景都是由相機實景拍攝而來的,雖然也有完全使用虛擬技術來搭建完成的,但成本以及效率都要低於前者。
  • 全棧AI工程師指南,DIY一個識別手寫數字的web應用
    ,下一篇文章將實現一個手寫字的輸入工具。drawingboard.js https://github.com/Leimi/drawingboard.js 這邊我選擇的是signature_pad。
  • 教你製作NASA樣本實驗室3D渲染圖!3D ThingJS
    本文就來解析一下,如何完成NASA樣本實驗室的3D渲染圖?-提供施工圖紙----------NASA找實驗室承建方繪製了該實驗室的平面草圖,然後使用 Leica DistoD3雷射測距儀和鋼尺進行了平面的測距,使用 AutoCAD繪製了樣本實驗室的施工平面圖。
  • 使用reveal.js製作精美的網頁版PPT
    接下來我們再看看reveal.js的優勢.reveal.js使介紹以及核心api作為一名前端工程師, 我們很容易把reveal.js集成到我們的vue或者react項目中, 但是作為演講類型的項目,我們直接用最原始的方式實現即可,首先我們需要引入相關的文件,具體可參考官網所說的步驟去做: revealjs.com/.
  • 從Rust到遠方:ASM.js星系
    這篇文章會解釋什麼是ASM.js,怎樣編譯博客解析器到ASM.js以及如何在瀏覽器中和Javascript一起使用ASM.js. 使用ASM.js的目標是當作WebAssembly不可用的備用方案。靜態和動態的組合校驗讓Javascript可以對有效 的asm.js代碼使用一種叫做ahead-of-time(AOT)的編譯時優化策略。因此ASM.js程序其實只是一個普通的Javascript程序。它不是一個新的語言而是Javascript的一個子集。它可以被任何Javascript虛擬機執行。
  • 2017.05:房地產市場價格影響因素的蛛網模型分析(翟帥等)
    翟 帥 殷宇飛   內容摘要:本文構建了包含銀行利率、匯率、人口因素等變量的動態蛛網模型   關鍵詞:動態蛛網模型;住房價格;房地產供求關係;房地產供給量;房地產需求量   中圖分類號:F293.3文獻標識碼:
  • 蜘蛛的殺手鐧:蛛網
    那種經露水浸潤後的蛛網粘性最強,把篾條製成的小圓圈對著蛛網旋轉幾下,也就製成了捕捉知了的殺手鐧。觀察蛛網的時刻到了。拉在薔薇上的迷宮,牢牢地固定在荊棘叢中,有一塊手帕那麼大。蛛網的周邊比較平坦,越往中部,蛛網就越是凹陷起來,形成火山口似的圓窪。蛛網的中間是一個圓錐形深坑,像個頸部漸漸變窄的漏鬥,大約有手的虎口深。迷宮蛛就在那陰暗危險的管口處,是灰色的。胸部,簡單地飾有兩條黑帶,腹部也有兩道橫槓。橫槓上,夾雜著白色和棕色的斑點。腹部末端有兩個小小的、會活動的附屬器官。
  • 蜘蛛的殺手鐧:蛛網
    那種經露水浸潤後的蛛網粘性最強,把篾條製成的小圓圈對著蛛網旋轉幾下,也就製成了捕捉知了的殺手鐧。耐心等待獵物的殺手蛛絲細得幾乎連肉眼都看不出來,但它居然還是由幾根更細的線纏合而成。更為讓人驚異的是,這種線還是空心的,濃性的粘液就在管道裡藏著。粘液能從線壁滲出來,使線的表面有粘性。它的粘性可大呢!你用小草的葉片去碰它,立刻就會被粘住。
  • 「黏菌算法」繪製「宇宙蛛網」
    星系內部是恆星、行星與塵埃;星系之間則由暗物質織成的「宇宙蛛網」互聯互通。暗物質是什麼?由於未能直接觀測,科學界始終捉摸不透這隻無形的大手。研究人員根據黏菌的行為特點和宇宙中3.7萬個星系的位置設計了一套蛛網算法。根據現代天文學的預測,宇宙中現存的物質集結成一個巨大的纖維結構網絡,俗稱「宇宙蛛網」。這張網由充斥星系的暗物質和氣體纖維組成,系內恆星即孕育於此。氣體纖維綿延數百萬光年,與超空洞一起填充了「宇宙蛛網」。可以說,氣體纖維狀網絡是宇宙中的最大結構,可能沒有之一。
  • 「黏菌算法」繪製「宇宙蛛網」
    科學家們從這張聯結不同位置的蛛網入手,用算法模擬黏菌的行為,進而繪製出三維的宇宙星河網絡。 項目負責人、美國加州大學聖克魯斯分校研究員約瑟夫·伯切特表示,從最簡單生命體的行為表現裡,竟然可以發現宇宙中最大結構的規律,簡直太神奇了!