Java使用joml計算機圖學庫,將3D座標旋轉正交投影轉為2D座標

2023-07-01 18:00:11

最近遇到了一個困擾我許久的難題,現將解決方案分享出來

由於我們的專案側重點在前端繪圖,導致了前後端工作量不協調,我後端介面很快就能寫完,而前端一個圖要畫好久,領導見狀將前端的任務分到後端一部分用Java程式碼來實現,然後給前端提供介面

而我接到的任務就是將Echarts中繪製三維圖形的點旋轉後投影為2D座標,當我一個大專生在瞭解需求,並知道這涉及到線性代數和計算機圖學後,我的想法是這樣的:

我想了很多種方法,一開始在網上搜Java相關資料,但是網上好像沒有人處理過這種情況,找到的貼文都是做Java圖形化的,他們所謂的座標旋轉是直接用眼球看到的介面效果,跟我想要的計算完全不同

而後我又拜託ChatGPT幫我寫了幾版,不得不說的確幫我寫出來了,而且自己測試效果還可以,但是前端調介面後點數太多了,旋轉後的座標直接亂了,最終我在網上游蕩了很久找到了解決方案,目前效果還算不錯

功能實現

首先在pom.xml中新增joml的Maven座標,該庫是一個輕量級數學庫,專門用於處理3D圖形的數學計算

<!-- 計算機圖學計算庫 -->
<dependency>
    <groupId>org.joml</groupId>
    <artifactId>joml</artifactId>
    <version>1.10.5</version>
</dependency>

然後建立個主類編寫測試程式碼,方法很簡單直接呼叫就好啦

import org.joml.Matrix3d;
import org.joml.Vector3d;

public class Application {

    public static void main(String[] args) {
        // 構建一個X軸旋轉90°的旋轉物件
        Matrix3d matrix = new Matrix3d().rotateX(Math.toRadians(90));
        // 構建一個3D座標點
        Vector3d point = new Vector3d(10, 10, 10);
        // 執行旋轉
        Vector3d transform = matrix.transform(point);
        // 列印旋轉後的角度
        System.out.println(transform.x);
        System.out.println(transform.y);
        System.out.println(transform.z);
    }

}

很悲哀,這麼簡單的幾行程式碼困擾了我兩三天才把功能做出來,見識少就是不行啊

封裝為Springboot介面

這裡我就不寫封裝介面的過程了,我會把程式碼地址放到文章結尾,有需要請自行獲取,這裡展示一下介面的使用和效果

首先開啟Echarts的官網,分別開啟三維折線圖和二維折線圖,用我給的這組測試資料畫出一個三維折線圖,或者自己有測試資料也可以

var data = [[0, 0, 0], [8, 8, 6], [18, 12, 4], [13, 21, 7]];

然後呼叫寫好的rotateProj介面,將座標和軸旋轉角度傳入,檢視效果

不進行旋轉,直接看正面

Z軸旋轉90°

X軸旋轉90°

Z軸旋轉45°

有一點比較可惜,經過測試改程式碼僅支援單軸旋轉,如果同時旋轉兩個軸以上效果就會有問題,不過單軸旋轉已經可以滿足我專案的需求,就不再花費時間研究這個東西了,有興趣可自行鑽研joml這個框架,如果您解決了多軸旋轉的問題還請回來留個言,可以幫助到更多人

程式碼地址:https://gitee.com/zhang_hanzhe/example-java/tree/master/springboot-proj-coord