一份小白前端可視化學習指南——附思維導圖
前言
因為群里粉絲一直要求我寫一篇「可視化入門指南」,今天他來了,其實說起前端可視化,大家所能想到的就是各種圖表,大屏,這種看著賊炫酷,而筆者呢作業也一直從事3D前端開發作業,慢慢對圖形產生了興趣,但是呢一直做的是三維的東西,沒搞過二維的,大概是2月前開始學習2D的一些東西,然后并寫了一些文章,效果還不錯,所以我就寫一些經驗之談,大佬勿噴, 我大概從4個方面去講我是怎么學習的
-
「可視化不得不掌握的數學基礎」
-
「svg」方面的學習
-
「canvas」方面的學習
-
「可視化中」不得不掌握的「圖形演算法」
讀完本篇文章,你可以大概知道我該怎么去學,需要學什么?以及我推薦的一些學習資料和學習資源!
數學篇
提起數學很多程式員頭疼哇,我寫代碼還要學可惡的數學,但是我很明確的告訴你——「很重要」,如果你想學可可視化的話,數學很重要,背后的幾何意義更重要,讀者一開始理解不深,導致很多東西理解不了,吃了很多虧哇!
向量
在二維空間或者三維空間中, 是不是都有點的概念,只不過一個是二維的一個是三維的, 假設,現在這個平面直角坐標系上有一個向量 v,向量 v 有兩個含義:一是可以表示該坐標系下位于 (x, y) 處的一個點;二是可以表示從原點 (0,0) 到坐標 (x,y) 的一根線段,
我在寫canvas的同時就喜歡用一個Point2d 類就是這個原理, canvas本身就是坐標系,畫布上的點都可以用向量表示, 原點在左上方,
向量加減法
一個向量可以用其他兩個向量去表示,也可以用兩個向量去做減法,我說個實際作業中經常用到的例子: 如何讓一個點在某一個方向延展多少長度呢?
這里其實就是用到了向量的加法, 「首先這個方向肯定是是個單位向量」 , 為什么是單位向量呢?? 因為向量是有「大小」和方向的, 而「單位向量 只有方向, 長度 為1」 ,然后我們只要開始點 加上 這個方向向量 ?? 長度,就可以得到了, 背后不就是向量加法的運用, 我還是畫圖給大家展示下吧,
如圖:我要從A-B點 方向是od 然后你可以乘以任何長度 得到 OD 然后相加, 是不是就可以得到B點了, 一圖勝千言!,減法大家可以自己去思考,同樣的道理的
向量的叉乘和點乘
其實很多種實踐,這里我就舉一個例子哈,帶你了解點乘,其實還有投影
向量點乘可以用來判斷 連個向量是否同一方向, 我還是畫圖給大家講解, 不說太多理論,都是實戰中經常用到的,
A向量和B向量之間的夾角是銳角 所以是同向 , B向量和C量之間的夾角是鈍角所以是反向 ,因為點乘的數學公式就是兩個向量的模長 × cosθ ,
叉乘
叉乘的幾何意義也是非常重要的,可以算多邊形的面積, 計算出另一個向量 垂直于這兩個向量, 還是開始畫圖:
X向量 和 Y向量去做叉乘 得到的 向量Z 是 xy 平面的「normal」,
算面積:
叉乘的數學意義: A向量的模長 × B向量的模長 × sinθ 不就是平行四邊形的高 H 所以可以用來算面積,
叉乘還可以用來判斷三個點的方向
Corss 的幾何叉積得到的是一個數值, 只要判斷當前數值是大于0 小于 0就好了, 就知道這個三個點的方式是逆時針 還是順時針就好了,
圖中可以看到 OAB 和OA1B 的方向是不同,OA向量?? OB向量 的值 和 OA1 ??OB向量 算出的來的值 是相反的,公式我給大家列舉下:
?a.x * b.y - a.y * b.x
?
其實向量的點乘 和叉乘非常的重要,大家一定要要好理解,后面的圖形演算法,很多也是基于這個去實作的,
矩陣
空間中圖形的大部分變化都是可以通過矩陣去表示的,大概有下面幾種型別:
-
平移矩陣 -
旋轉矩陣 -
縮放矩陣 -
鏡像矩陣 -
錯切矩陣 -
投影矩陣
這里我給大家推薦的學習資源是B站的:
https://www.bilibili.com/video/BV1ib411t7YR?from=search&seid=15308763710996235630
線性代數的本質,看完你就能夠明白了,包括上面的向量之間的變化,
鏡像矩陣我推薦你看我這篇文章, 我是求導了三維空間中任意平面的鏡像矩陣的了,
求空間任意平面的鏡像矩陣
我這里給大家簡單的講解下最簡單的變化—— 「平移矩陣」
還是看下圖吧:
在這樣的三維坐標系中從A點平移到B點 x變化了 2 y變化了0 z 變化了 2 對應矩陣的寫法是什么呢:
其實矩陣中每一行都有對應的矩陣, 平移矩陣一般改變的第四列的前三個數字
曲線
無論是2d還是3d都需要曲線的表達,最簡單的圓弧、橢圓弧、然后連續曲線可以用貝塞爾曲線去表達,還有B樣條曲線,nurbs曲線,掌握曲線最終的還是數學哇,
圓的方程: x ^2 + y ^ 2 = r ^ 2
橢圓的方程: x ^ 2 / a ^ 2 + y ^ 2 / b ^ 2 = 1
n階貝塞爾曲線的方程: 𝐵(𝑡)=∑𝑖=0𝑛𝑃𝑖(1?𝑡)𝑛?𝑖𝑡𝑖,𝑡𝜖[0,1]
b樣條曲線和nurbs曲線我還沒接觸過,但是我們組的小伙伴正在做自由曲面,可能涉及到了,這里我只是簡單表示了直線方程,有了方程你可以你去進行高度模擬,比如我在做3D文字的時候,我們底層演算法庫還沒有支持貝塞爾, 不過沒關系我們不是有方程嘛, 可以通過方程將貝塞爾曲線離散成多個點,然后用直線去表達,因為我們人眼去看螢屏上的東西,離散的很多的話,肉眼是完全看不出來的, 我這里給大家看一張圖吧:
圗這個部分的弧線我就是用我貝塞爾曲線 離散成直線去表達的, 還有國中的點其實也是貝塞爾曲線離散成直線去做的,從視覺上來看是能夠近似模擬的,3D文字中的 更多技術,我后面會專門寫一篇文章去詳細介紹, 順便自己去梳理下,如果你感興趣,那你可得關注我,不然就找不到我了,
坐標系的轉換
為什么要有這個東西呢,canvas和svg的坐標系都是左上方是原點,這一點你不覺得有點反人類? 好不舒服,我在畫折線圖的時候就發現了,從原點向上,坐標軸是遞減的,其實這個問題怎么解決呢,其實很簡單就是我們進行坐標系的轉換,我將原先畫布的原點, 通過變化到左下角, 這樣我們在計算點的坐標的時候,就沒有心智負擔了,該怎樣就是怎樣, 說完2d我再和你聊聊3D, 就拿Three.js 舉例子吧有個區域坐標系,觀察坐標系(相機)、 世界坐標系、裁剪坐標系、螢屏坐標系,
這是空間中某個物體到最終螢屏所做的一系列操作,
-
首先物體的自身有個坐標系我們叫做區域坐標系,他也有個原點,但是他在世界坐標系下也有對應的位置,所以他們之間有一個矩陣變化——「模型矩陣」
-
世界坐標系——到觀察坐標系也有矩陣變化, 這叫「視圖矩陣」
-
觀察空間——裁剪空間 叫做 「投影矩陣」因為3維空間的東西我們是用相機去模擬人眼,在視椎體內的東西才能被看到,所有就有了投影矩陣, 有透視投影和正交投影, 一個近大遠小,一個遠近都是一樣的
-
標準設備坐標-螢屏坐標, 這里就涉及到坐標系的原點的問題,
坐標系
歸一化的坐標是相對于畫布中心的, 但是canvas默認的坐標系是左上角的, 我們分析下坐標系的變化,首先Y軸是相反的所以 第一個變化就是 X不變,然后Y都?? -1這下方向對了,差的就是偏移量, x軸和Y軸差的偏移量都是畫布的一半寬度和高度, 這樣就實作了,到螢屏坐標的轉換了,
svg和canvas
SVG和canvas的學習我還是推薦Mdn, 大家去認真從頭擼一遍,然后再談進階,再去如何優化, 你連基本的api都不熟悉和談進階對吧,
-
svg教程 https://developer.mozilla.org/zh-CN/docs/Web/SVG/Tutorial
-
canvas教程 https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial
跟著后面學一遍,手敲一遍,自然就明白其中的奧秘, 下面👇是我用了這么久的小經驗,和小tips
-
svg中的path 中大寫字母和小寫字母的 區別主要是相對定位和絕對定位的關系,
-
svg的defs標簽 不會出現在畫布上,是為了下面的組合使用的
-
svg的g 和 symbols 都可以實作組合 ,但是symbols 有viewbox 也就是視口的概念
-
use 復用標簽 對應上文定義的id
-
canvas 「clearRect()」 清除畫布 由于canvas 每一幀都要進行重繪
-
「restore() save()」 保存當前canvas 的狀態 確保不影響 其他繪圖元素
-
「isPointinPath()」 可以用來點是不是在最后一個繪制的path 中(有坑) , 判斷點是不是在圖形內部最后用演算法去解決,
-
beginPath() 和 closePath() 的使用
-
像素級別的處理 imageData 的使用
當你熟悉了這些可以進階了, 推薦學習
「進階學習」
深入理解canvas
https://joshondesign.com/p/books/canvasdeepdive/title.html
Canvas 最佳實踐(性能優化)
https://www.cnblogs.com/mopagunda/p/5622911.html
canvas 離屏渲染
https://devnook.github.io/OffscreenCanvasDemo/keep-ui-responsive.html
canvas視頻學習
https://www.bilibili.com/video/av26151775/
「推薦書籍」
《HTML5 Canvas核心技術:圖形、影片與游戲開發》
《HTML5 2D游戲編程核心技術》
webgl
1.學習圖形學基礎
一定一定一定要看閆令琪老師的GAMES101現代計算機圖形學,建議1.5倍速,大概一個月內可以掌握,跟著課程,把光柵渲染器和光線追蹤的作業都做掉,學了這門課,差不多圖形學基礎就打牢了,對圖形學、游戲、3D引擎、OpenGL、Unity、UE差不多也有了基本的認識,我自己還沒有看完,還在學習中,
https://www.bilibili.com/video/BV1X7411F744?from=search&seid=7915905348717479996
2.webgl 網站學習,這是我覺得質量非常不錯同時又有點深度的學習網站
https://webglfundamentals.org/webgl/lessons/zh_cn/webgl-fundamentals.html
-
「著色器和glsl」 -
光照和顏色 -
如何加載外部模型 -
點線面如何三角化 -
貼圖
書籍推薦:
webgl 編程指南
3D游戲與計算機圖形學中的數學方法
Fundamentals of Computer Graphics (4th Edition)
「directx 9.0 3d游戲開發編程基礎」 這本書強力推薦 雖然是用c++寫的 ,但是他把整個渲染流程講解的很清楚,我反正看了識訓很大,這也是我們老大推薦的一本書,
框架層面
three.js
Three.js 是最知名的 WebGL 專案,Contributions 人數高達 1313,和 React 是一個量級的,盡管它自身的定位只是渲染引擎,但社區硬是把不少游戲引擎的功能都加上了,比如物理引擎、貼花、影片等,在原始碼中有大量例子,很適合學習,但不少重要功能,比如 gltf 加載器,都是放在 examples 目錄里,讓人感覺很不正式,
由于知名度最高,Three.js 最大的優勢就是社區強大,搜索問題能找到很多答案,也有非常多開源和商業專案使用
但 Three.js 在版本管理方面很不專業,到現在都還沒采用 semver 版本命名規范,每次發布都是一個叫 rXXX 的版本,我見過不少基于 Three.js 的專案都是固定在某個版本不敢升級了
babylonjs
最后壓軸的是 Babylon,它也是 Sugar 最終采用的 WebGL 引擎,不僅功能強大,代碼質量也很高,TypeScript 型別完善,幾乎每個函式都有注釋,
Babylon 在材質方面功能豐富,除了基礎的 PBR,還提供了用于皮膚的次表面渲染 SubSurface、用于車漆的 ClearCoat、用于布料的 Sheen,以及用于光碟之類的各向異性材質 Anisotropy 等等,
Babylon 最后一個亮點是正在開發 WebGPU 版本,而其他引擎都沒開始做,所以等 WebGPU 發布后,Babylon 應該是首批支持的,將得到更多關注,
AntV
在AntV中,有好幾個不同的可視化引擎,事實上,它們是相互隔絕的,彼此獨立的,學習的時候需要單獨的去學習,ChartCube圖表魔方支持在線的生成圖表,地圖則使用L7地理空間資料可視化,
echarts
ECharts最初是"Enterprise Charts"(企業圖表)的簡稱,來自百度EFE資料可視化團隊,是用JavaScript實作的開源可視化庫,ECharts的功能非常強大,對移動端進行了細致的優化,適配微信小程式,支持多種渲染方式和千萬資料的前端展現,甚至實作了無障礙訪問,底層是用的z-render 這個庫去進行封裝的,還是很值的學習對的,有點類似于組件的概念,進行可配置的去展示圖表,
d3
D3是指資料驅動檔案(Data-Driven Documents),D3.js是一個JavaScript庫,它可以通過資料來操作檔案,D3可以通過使用HTML、SVG和CSS把資料鮮活形象地展現出來,D3嚴格遵循Web標準,因而可以讓你的程式輕松兼容現代主流瀏覽器并避免對特定框架的依賴,同時,它提供了強大的可視化組件,可以讓使用者以資料驅動的方式去操作DOM,被稱為可視化版的jquery,
圖形演算法
最后講一下不得不掌握的圖形演算法, 比如很簡答的例子, 判斷點是不是在任意多邊形內部對吧這就是 涉及到演算法,
我大概列舉下
-
判斷點是不是在任意閉合polygon中 「用射線檢測法, 有內部的點,像任意方向發出一天射線計算出交點的個數, 奇數就是內部 偶數就是外部」 -
判斷連續多邊形的方向 是順時針還是逆時針 **求面積的正負 ** 「求平面的noraml (慎用) 對于凹多邊形是不準的」 -
二維圖形下, 任意圖形的相交 推薦兩個庫 「clipper 和turf 洞和外輪廓的概念,自己可以百度了解」 -
判斷一個點 在某個向量的哪一面 「上面的三點求方向逆時針還是順時針」 -
線段求線段求相交 「直線方程求焦點」 -
求任意兩個區域的包含關系 內部 外部 相交 -
碰撞檢測 「boundingbox 求交集」
這里我大概列了一下我作業中用到的一些演算法,
推薦一些文章:
「談"求線段交點"的幾種演算法(js實作,完整版)」
https://www.cnblogs.com/i-gps/archive/2012/06/19/2554992.html
「計算幾何與圖形學有關的幾種常用演算法」
https://blog.csdn.net/wilson1068/article/details/44133303
點在多邊形內演算法——判斷一個點是否在一個復雜多邊形的內部
https://blog.csdn.net/hjh2005/article/details/9246967
「實作多邊形的交并差還有偏移」
http://turfjs.org/
「Clipper庫中文檔案詳解」
https://www.cnblogs.com/zhigu/p/11943118.html
總結
本篇文章大概就是我的個人理解哈,水平有限,能表達的就這么多,如果有更好的歡迎補充學習和交流,文章有錯誤的歡迎指正,最后送給大家一張思維導圖,對照學習哈,我是熱愛圖形的Fly,我們下次再見👋啦,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/293008.html
標籤:其他
上一篇:2021-08-08
