NumPy 陣列有效簡化 3D 曲面資料的儲存與運算,每個元素代表資料點的 x、y、z 座標,方便索引與存取。搭配 Matplotlib 的 3D 繪圖功能,能高效繪製曲面。陰影處理則仰賴計算曲面面片的法向量,並根據光源方向調整著色強度,使 3D 曲面更具立體感和真實感。程式碼範例中示範瞭如何使用 NumPy 陣列儲存資料、計演算法向量及著色,並以 Matplotlib 繪製最終結果,提供讀者實作參考。

3D曲面繪製與陰影處理技術詳解

在前面的章節中,我們已經探討瞭如何使用Python進行3D資料的視覺化。本章節將重點介紹如何使用NumPy陣列來簡化3D曲面的繪製過程,並實作曲面的陰影效果。

使用NumPy陣列進行3D曲面繪製

為了簡化3D曲面的繪製,我們將採用NumPy陣列來儲存和處理資料。以下是一個範例陣列,用於定義3D曲面的資料點:

import numpy as np

# 定義3D曲面資料陣列
A = np.array([
    [0, 0, 50],
    [0, 10, 45],
    [0, 20, 35],
    [0, 30, 14],
    [10, 0, 40],
    [10, 10, 38],
    [10, 20, 30],
    [10, 30, 20],
    [20, 0, 30],
    [20, 10, 28],
    [20, 20, 25],
    [20, 30, 18],
    [30, 0, 14],
    [30, 10, 12],
    [30, 20, 10],
    [30, 30, 8]
])

資料存取與座標解析

在這個陣列中,每一行代表一個資料點的x、y、z座標。例如,要存取第四個資料點的z座標,可以使用以下程式碼:

# 存取第四個資料點的z座標
z_coordinate = A[3, 2]
print(z_coordinate)  # 輸出:14

圖表翻譯:

此範例展示瞭如何使用NumPy陣列儲存3D曲面的資料點,並透過索引存取特定的座標值。這種方法比之前的清單編號系統更為簡潔高效。

3D曲面陰影處理技術

為了實作3D曲面的陰影效果,我們需要對曲面上的每個面片進行著色處理。以下是著色函式的範例實作:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def shade_patch(p1, p2, p3, p4, light_source):
    # 計算面片的法向量
    normal_vector = np.cross(p2 - p1, p3 - p1)
    normal_vector = normal_vector / np.linalg.norm(normal_vector)
    
    # 計算著色強度
    intensity = np.dot(normal_vector, light_source)
    color = plt.cm.viridis(intensity)
    
    # 繪製著色面片
    patch = [[p1, p2, p3, p4]]
    collection = PolyCollection(patch, facecolors=color, edgecolors='k')
    ax.add_collection3d(collection, zs=p1[2])

# 設定光源方向
light_source = np.array([1, 1, 1])

# 繪製並著色曲面
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

for i in range(3):
    for j in range(3):
        p1 = A[i*4 + j]
        p2 = A[i*4 + j + 1]
        p3 = A[(i+1)*4 + j + 1]
        p4 = A[(i+1)*4 + j]
        shade_patch(p1, p2, p3, p4, light_source)

plt.show()

內容解密:

此程式碼實作了一個著色函式,用於計算3D曲面上每個面片的法向量,並根據光源方向確定著色強度。透過遍歷曲面上的所有面片並呼叫著色函式,實作了3D曲面的陰影效果。

Plantuml圖表展示曲面繪製流程

圖表翻譯:

此圖示展示了3D曲面繪製與陰影處理的主要流程。首先定義3D曲面的資料陣列,接著繪製曲面,然後對曲面上的面片進行著色處理,最後顯示最終的視覺化結果。這個流程清晰地展示了從資料定義到最終視覺呈現的完整過程。

實作要點與最佳實踐

  1. 資料組織:使用NumPy陣列儲存3D曲面資料,提高了資料存取和處理的效率。
  2. 著色技術:透過計算面片的法向量並結合光源方向,實作了真實的陰影效果。
  3. 視覺化:利用Matplotlib的3D繪圖功能,實作了高品質的3D曲面視覺化。

三維資料繪圖中的曲面陰影處理技術

在三維資料視覺化中,曲面陰影處理是一項重要的技術,能夠增強資料的立體感和真實感。本文將深入探討如何在Python中使用Matplotlib實作三維曲面的陰影效果。

曲面陰影原理

曲面陰影的實作依賴於光源與曲面法向量的計算。透過模擬光源照射曲面的效果,可以呈現出更真實的3D視覺效果。主要步驟包括:

  1. 計算曲面的法向量
  2. 設定光源方向
  3. 計算光照強度
  4. 根據光照強度進行著色

程式碼實作

以下是一個實作曲面陰影效果的完整程式碼範例:

import matplotlib.pyplot as plt
import numpy as np
from math import sqrt, radians, sin, cos

# 定義旋轉矩陣函式
def rotx(x, y, z, Rx):
    g = [0]*3
    g[0] = x
    g[1] = y*cos(Rx) - z*sin(Rx)
    g[2] = y*sin(Rx) + z*cos(Rx)
    return g

def roty(x, y, z, Ry):
    g = [0]*3
    g[0] = x*cos(Ry) + z*sin(Ry)
    g[1] = y
    g[2] = -x*sin(Ry) + z*cos(Ry)
    return g

def rotz(x, y, z, Rz):
    g = [0]*3
    g[0] = x*cos(Rz) - y*sin(Rz)
    g[1] = x*sin(Rz) + y*cos(Rz)
    g[2] = z
    return g

# 繪製點函式
def plotpoint(x, y, z, Rx, Ry, Rz, clr):
    g = rotx(x, y, z, Rx)
    g = roty(g[0], g[1], g[2], Ry)
    g = rotz(g[0], g[1], g[2], Rz)
    plt.scatter(g[0], g[1], s=10, color=clr)

# 繪製線段函式
def plotline(x1, y1, z1, x2, y2, z2, Rx, Ry, Rz, clr):
    g1 = rotx(x1, y1, z1, Rx)
    g1 = roty(g1[0], g1[1], g1[2], Ry)
    g1 = rotz(g1[0], g1[1], g1[2], Rz)
    
    g2 = rotx(x2, y2, z2, Rx)
    g2 = roty(g2[0], g2[1], g2[2], Ry)
    g2 = rotz(g2[0], g2[1], g2[2], Rz)
    
    plt.plot([g1[0], g2[0]], [g1[1], g2[1]], linewidth=0.7, color=clr)

# 曲面陰影函式
def shade(x0, y0, z0, x1, y1, z1, x2, y2, z2, x3, y3, z3, Rx, Ry, Rz, clr):
    # 計算單位向量
    ux = (x3 - x0) / np.sqrt((x3-x0)**2 + (y3-y0)**2 + (z3-z0)**2)
    uy = (y3 - y0) / np.sqrt((x3-x0)**2 + (y3-y0)**2 + (z3-z0)**2)
    uz = (z3 - z0) / np.sqrt((x3-x0)**2 + (y3-y0)**2 + (z3-z0)**2)
    
    # 計演算法向量
    nx = uy*vz - uz*vy
    ny = uz*vx - ux*vz
    nz = ux*vy - uy*vx
    
    # 計算光照強度
    ndotl = nx*lx + ny*ly + nz*lz
    I = IA + (IB - IA)*((1-ndotl)/2)**n
    
    # 繪製陰影線條
    for q in np.arange(0, q03+1, dq):
        xb = x0 + ux*q
        yb = y0 + uy*q
        zb = z0 + uz*q
        
        xe = x1 + wx*q*r
        ye = y1 + wy*q*r
        ze = z1 + wz*q*r
        
        plotline(xb, yb, zb, xe, ye, ze, Rx, Ry, Rz, clr)

# 主程式
plt.axis([0, 150, 0, 100])
plt.axis('on')
plt.grid(True)

# 定義資料點陣列
A = np.array([
    [0, 0, 50], [0, 10, 43], [0, 20, 30], [0, 30, 14],
    [20, 0, 25], [20, 10, 23], [20, 20, 19], [20, 30, 12],
    [40, 0, 14], [40, 10, 15], [40, 20, 13], [40, 30, 9],
    [60, 0, 7], [60, 10, 10], [60, 30, 9]
])

# 繪製資料點
for i in range(len(A)):
    plotpoint(A[i, 0], A[i, 1], A[i, 2], Rx, Ry, Rz, 'k')

# 繪製曲面陰影
for i in range(3):
    for j in range(3):
        # 計算四個角點座標
        x0, y0, z0 = A[i*4 + j, 0], A[i*4 + j, 1], A[i*4 + j, 2]
        x1, y1, z1 = A[i*4 + j + 1, 0], A[i*4 + j + 1, 1], A[i*4 + j + 1, 2]
        x2, y2, z2 = A[(i+1)*4 + j + 1, 0], A[(i+1)*4 + j + 1, 1], A[(i+1)*4 + j + 1, 2]
        x3, y3, z3 = A[(i+1)*4 + j, 0], A[(i+1)*4 + j, 1], A[(i+1)*4 + j, 2]
        
        shade(x0, y0, z0, x1, y1, z1, x2, y2, z2, x3, y3, z3, Rx, Ry, Rz, 'k')

plt.show()

圖表翻譯:

此圖示展示了一個三維曲面陰影的效果。透過計算曲面的法向量和光照強度,程式實作了對曲面的陰影著色。左側的程式碼片段展示瞭如何定義旋轉矩陣、繪製點和線段,以及如何計算曲面的陰影效果。右側的圖形展示了最終的渲染結果,可以看到曲面上的陰影效果增強了其立體感。

內容解密:

  1. 程式首先定義了三個旋轉矩陣函式rotxrotyrotz,用於對三維座標進行旋轉變換。
  2. plotpointplotline函式分別用於繪製點和線段,並在繪製前進行旋轉變換。
  3. shade函式是核心,用於計算曲面的法向量、光照強度,並根據光照強度進行著色。
  4. 主程式中定義了資料點陣列A,並透過巢狀迴圈對每個曲面區塊進行陰影處理。
  5. 最終使用Matplotlib顯示繪製的結果。

Plantuml流程圖

圖表翻譯:

此流程圖展示了三維曲面陰影處理的主要步驟。首先載入資料,接著進行旋轉變換。成功後計算曲面的法向量和光照強度,最後進行陰影著色並顯示結果。整個過程清晰地展示了從資料輸入到最終輸出的完整流程。

三維資料視覺化技術

在資料視覺化領域中,三維資料的呈現是一項重要的技術。本文將深入探討如何使用Python進行三維資料視覺化,涵蓋資料連線、表面建構以及著色技術。

三維資料連線技術

在進行三維資料視覺化時,首先需要將資料點進行連線。以下是一個典型的程式碼範例,展示瞭如何連線三維資料點:

import numpy as np
import matplotlib.pyplot as plt

# 定義資料點陣列A
A = np.array([...])  # 假設這裡有具體的資料

# 定義旋轉角度
Rx, Ry, Rz = 30, 45, 60  # 示例旋轉角度

# 定義繪線函式
def plotline(x1, y1, z1, x2, y2, z2, Rx, Ry, Rz, clr):
    # 進行座標轉換
    x1_rot, y1_rot, z1_rot = rotx(x1, y1, z1, Rx)
    x1_rot, y1_rot, z1_rot = roty(x1_rot, y1_rot, z1_rot, Ry)
    x1_rot, y1_rot, z1_rot = rotz(x1_rot, y1_rot, z1_rot, Rz)
    
    x2_rot, y2_rot, z2_rot = rotx(x2, y2, z2, Rx)
    x2_rot, y2_rot, z2_rot = roty(x2_rot, y2_rot, z2_rot, Ry)
    x2_rot, y2_rot, z2_rot = rotz(x2_rot, y2_rot, z2_rot, Rz)
    
    # 繪製線段
    plt.plot([x1_rot, x2_rot], [y1_rot, y2_rot], [z1_rot, z2_rot], color=clr)

# 連線資料點
for i in range(0, 3):
    plotline(A[i, 0], A[i, 1], A[i, 2], A[i+1, 0], A[i+1, 1], A[i+1, 2], Rx, Ry, Rz, 'b')

# 其他方向的連線
for i in range(4, 7):
    plotline(A[i, 0], A[i, 1], A[i, 2], A[i+1, 0], A[i+1, 1], A[i+1, 2], Rx, Ry, Rz, 'b')

# 顯示圖形
plt.show()

內容解密:

此程式碼片段展示瞭如何連線三維空間中的資料點。首先定義了一個plotline函式,用於在經過旋轉變換後繪製兩點之間的線段。接著透過迴圈遍歷資料點陣列A,使用plotline函式連線相鄰的資料點。程式中使用了三個主要的旋轉函式:rotxrotyrotz,分別對x、y、z軸進行旋轉變換。最終透過matplotlib函式庫將三維圖形顯示出來。

三維表面建構與著色

在完成資料點的連線後,進一步可以構建三維表面並進行著色處理。以下是一個範例程式碼:

# 定義著色函式
def shade(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, Rx, Ry, Rz, clr):
    # 進行座標轉換
    x1_rot, y1_rot, z1_rot = rotx(x1, y1, z1, Rx)
    # ... 其他點的轉換
    
    # 計演算法向量並著色
    normal_vector = np.cross([x2_rot-x1_rot, y2_rot-y1_rot, z2_rot-z1_rot], 
                             [x3_rot-x1_rot, y3_rot-y1_rot, z3_rot-z1_rot])
    intensity = np.dot(normal_vector, [0, 0, 1])  # 簡化的光照模型
    color = clr * intensity
    # 使用計算出的顏色進行著色
    # ... 著色實作細節

# 對資料點進行著色
for i in range(0, 3):
    shade(A[i, 0], A[i, 1], A[i, 2], A[i+1, 0], A[i+1, 1], A[i+1, 2],
          A[i+4, 0], A[i+4, 1], A[i+4, 2], A[i+5, 0], A[i+5, 1], A[i+5, 2],
          Rx, Ry, Rz, 'b')

內容解密:

此著色函式shade首先對輸入的四個頂點進行座標變換,接著計算由這四個點構成的平面的法向量。透過簡化的光照模型,計算出著色的強度,並根據這個強度決定最終的顏色。程式中使用了向量運算來計演算法向量和光照強度,展現了三維圖形著色的基本原理。

圖表視覺化

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Python三維曲面繪製與陰影處理技術

package "資料視覺化流程" {
    package "資料準備" {
        component [資料載入] as load
        component [資料清洗] as clean
        component [資料轉換] as transform
    }

    package "圖表類型" {
        component [折線圖 Line] as line
        component [長條圖 Bar] as bar
        component [散佈圖 Scatter] as scatter
        component [熱力圖 Heatmap] as heatmap
    }

    package "美化輸出" {
        component [樣式設定] as style
        component [標籤註解] as label
        component [匯出儲存] as export
    }
}

load --> clean --> transform
transform --> line
transform --> bar
transform --> scatter
transform --> heatmap
line --> style --> export
bar --> label --> export

note right of scatter
  探索變數關係
  發現異常值
end note

@enduml

圖表翻譯:

此圖示展示了一個基本的資料處理流程。流程始於「開始處理」階段,接著進行資料有效性檢查。若資料有效,系統會進入「處理資料」階段;若資料無效,則轉向「回報錯誤」階段。最後,無論資料處理成功與否,流程都會到達「完成處理」階段。此圖清晰地說明瞭程式中的條件分支邏輯以及不同處理路徑的銜接方式,幫助讀者理解整體處理邏輯。

土星環視覺化展示

在進行三維視覺化的過程中,我們可以進一步展示複雜的天體結構,如土星環。以下是一個簡化的程式碼範例:

# 土星環模型建立
def plot_saturn_rings(Rx, Ry, Rz):
    # 建立環的模型
    r1, r2 = 1, 2  # 環半徑範圍
內外半徑
    deltar = 0.1  # # 環厚度
    
    # 繪製環
    for r in np.arange(r1, r2, deltar):
        theta = np.linspace(0, 2*np.pi, 100)
        x = r * np.cos(theta)
        y = r * np.sin(theta)
        z = np.zeros_like(theta)
        
        # 進行座標旋轉
        x_rot, y_rot, z_rot = rotx(x, y, z, Rx)
        x_rot, y_rot, z_rot = roty(x_rot, y_rot, z_rot, Ry)
        x_rot, y_rot, z_rot = rotz(x_rot, y_rot, z_rot, Rz)
        
        # 繪製環線
        plt.plot(x_rot, y_rot, z_rot, color='gray')

# 顯示土星環
plot_saturn_rings(30, 45, 60)
plt.show()

內容解密:

此程式碼片段展示瞭如何建立土星環的三維模型。透過定義環的內外半徑和厚度,使用迴圈在不同半徑上建立環線。接著對這些環線進行三維旋轉變換,最後使用matplotlib將旋轉後的土星環顯示出來。這種視覺化方式能夠有效地呈現土星環的結構和立體感。