三維空間中的物體旋轉和透視投影是電腦圖形學的基礎概念。理解旋轉矩陣的組合以及透視投影的數學原理對於構建逼真的三維場景至關重要。本文提供的程式碼示例可以幫助讀者更好地理解這些概念,並將其應用於實際的圖形學開發中。常見的旋轉操作包括繞x、y、z軸的旋轉,這些操作可以透過矩陣相乘組合成更複雜的旋轉。透視投影則模擬了人眼觀察世界的方式,將三維物體投射到二維平面上,產生近大遠小的視覺效果。在程式碼實作中,我們使用了NumPy和Matplotlib等Python函式庫來進行矩陣運算和圖形繪製,並透過互動式輸入讓使用者可以動態調整旋轉角度和觀察不同軸向的旋轉效果。

矩陣串接與3D旋轉的應用

在3D圖形學中,物體的旋轉是一個重要的操作。旋轉的順序會對最終結果產生重大影響。本篇文章將深入探討矩陣串接的概念,並透過例項程式碼展示如何在Python中實作3D旋轉。

3D旋轉的基本原理

在3D空間中,物體的旋轉可以透過矩陣乘法來實作。對於繞x、y、z軸的旋轉,分別對應不同的旋轉矩陣:

  1. 繞x軸旋轉:
Rx = [[1, 0, 0],
      [0, cos(θ), -sin(θ)],
      [0, sin(θ), cos(θ)]]
  1. 繞y軸旋轉:
Ry = [[cos(θ), 0, sin(θ)],
      [0, 1, 0],
      [-sin(θ), 0, cos(θ)]]
  1. 繞z軸旋轉:
Rz = [[cos(θ), -sin(θ), 0],
      [sin(θ), cos(θ), 0],
      [0, 0, 1]]

這些旋轉矩陣可以透過串接來實作複雜的旋轉操作。

矩陣串接的重要性

矩陣串接的順序會直接影響最終的旋轉結果。例如,RxRyRz和RyRxRz會產生不同的結果。這是因為矩陣乘法不滿足交換律,即AB ≠ BA。

圖表翻譯:

此圖示展示了3D旋轉的順序對最終位置的影響。從原始位置開始,依次進行繞X軸、Y軸和Z軸的旋轉,每一步旋轉都會改變物體的狀態,最終達到預期的位置。

實作範例:使用Python進行3D旋轉

以下是一個使用Python和matplotlib實作3D旋轉的範例程式碼:

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

def plot_circle(xc, yc, zc, R, axis):
    theta = np.linspace(0, 2*np.pi, 100)
    if axis == 'x':
        x = xc + R * np.cos(theta)
        y = yc + R * np.sin(theta)
        z = zc * np.ones_like(theta)
    elif axis == 'y':
        x = xc + R * np.cos(theta)
        y = yc * np.ones_like(theta)
        z = zc + R * np.sin(theta)
    elif axis == 'z':
        x = xc + R * np.cos(theta)
        y = yc + R * np.sin(theta)
        z = zc * np.ones_like(theta)
    return x, y, z

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# 原始圓形
xc, yc, zc = 0, 0, 0
R = 1
x, y, z = plot_circle(xc, yc, zc, R, 'z')
ax.plot(x, y, z)

# 繞X軸旋轉45度
theta = np.radians(45)
x_rotated = x
y_rotated = y * np.cos(theta) - z * np.sin(theta)
z_rotated = y * np.sin(theta) + z * np.cos(theta)
ax.plot(x_rotated, y_rotated, z_rotated)

plt.show()

內容解密:

此程式碼展示瞭如何使用Python的matplotlib函式庫繪製3D圓形並進行旋轉操作。首先定義了一個繪製圓形的函式plot_circle,然後在3D坐標系中繪製原始圓形和繞X軸旋轉45度後的圓形。透過矩陣運算實作了3D旋轉。

透過鍵盤輸入實作動態旋轉

為了提高程式的靈活性,可以透過鍵盤輸入來控制旋轉的順序和角度。這需要使用函式式程式設計結構,將不同的旋轉操作封裝成獨立的函式。

def rotate_x(x, y, z, theta):
    y_rotated = y * np.cos(theta) - z * np.sin(theta)
    z_rotated = y * np.sin(theta) + z * np.cos(theta)
    return x, y_rotated, z_rotated

def rotate_y(x, y, z, theta):
    x_rotated = x * np.cos(theta) + z * np.sin(theta)
    z_rotated = -x * np.sin(theta) + z * np.cos(theta)
    return x_rotated, y, z_rotated

def rotate_z(x, y, z, theta):
    x_rotated = x * np.cos(theta) - y * np.sin(theta)
    y_rotated = x * np.sin(theta) + y * np.cos(theta)
    return x_rotated, y_rotated, z

# 使用者輸入旋轉順序和角度
axis = input("輸入旋轉軸 (x/y/z): ")
theta = np.radians(float(input("輸入旋轉角度: ")))

# 根據使用者輸入進行旋轉
if axis == 'x':
    x_rotated, y_rotated, z_rotated = rotate_x(x, y, z, theta)
elif axis == 'y':
    x_rotated, y_rotated, z_rotated = rotate_y(x, y, z, theta)
elif axis == 'z':
    x_rotated, y_rotated, z_rotated = rotate_z(x, y, z, theta)

ax.plot(x_rotated, y_rotated, z_rotated)
plt.show()

內容解密:

此程式碼透過定義不同的旋轉函式(如rotate_xrotate_yrotate_z)來實作繞不同軸的旋轉。使用者可以透過鍵盤輸入選擇旋轉軸和角度,程式根據輸入進行相應的旋轉操作並顯示結果。

三維空間中的圓形旋轉與互動式控制實作

在三維圖形學中,圓形的旋轉與呈現是一個基礎且重要的課題。本文將深入探討如何透過Python實作三維圓形的旋轉,並結合互動式控制達到動態展示的效果。我們將詳細解析相關程式碼的實作細節和技術原理。

技術背景與實作目標

本實作旨在達成以下目標:

  1. 在三維空間中建立圓形並實作繞不同軸旋轉
  2. 提供互動式控制介面以動態調整旋轉引數
  3. 展示不同旋轉操作下的圓形變化過程

程式架構與核心功能實作

1. 座標初始化與資料結構建立

首先,我們需要建立圓形在三維空間中的初始座標。這部分由以下程式碼實作:

import numpy as np

# 定義初始引數
radius = 15  # 圓形半徑
phi1 = np.radians(0)  # 起始角度
phi2 = np.radians(360)  # 終止角度
dphi = np.radians(5)  # 角度間隔

# 建立圓形周邊點的座標
x, y, z = [], [], []
for phi in np.arange(phi1, phi2 + dphi, dphi):
    x.append(radius * np.cos(phi))
    y.append(radius * np.sin(phi))
    z.append(0)

圖表翻譯:

此段程式碼展示瞭如何使用NumPy建立圓形在三維空間中的初始座標。透過等間隔取樣圓週上的點,構建了圓形的基礎幾何結構。

2. 旋轉函式的實作

為了實作圓形的旋轉,我們定義了三個旋轉函式,分別對應繞x、y、z軸的旋轉操作:

def rotx(xc, yc, zc, xp, yp, zp, Rx):
    """繞x軸旋轉"""
    a = [xp, yp, zp]
    b = [1, 0, 0]
    xpp = np.inner(a, b)
    b = [0, np.cos(Rx), -np.sin(Rx)]
    ypp = np.inner(a, b)
    b = [0, np.sin(Rx), np.cos(Rx)]
    zpp = np.inner(a, b)
    return [xpp + xc, ypp + yc, zpp + zc]

def roty(xc, yc, zc, xp, yp, zp, Ry):
    """繞y軸旋轉"""
    a = [xp, yp, zp]
    b = [np.cos(Ry), 0, np.sin(Ry)]
    xpp = np.inner(a, b)
    b = [0, 1, 0]
    ypp = np.inner(a, b)
    b = [-np.sin(Ry), 0, np.cos(Ry)]
    zpp = np.inner(a, b)
    return [xpp + xc, ypp + yc, zpp + zc]

def rotz(xc, yc, zc, xp, yp, zp, Rz):
    """繞z軸旋轉"""
    a = [xp, yp, zp]
    b = [np.cos(Rz), -np.sin(Rz), 0]
    xpp = np.inner(a, b)
    b = [np.sin(Rz), np.cos(Rz), 0]
    ypp = np.inner(a, b)
    b = [0, 0, 1]
    zpp = np.inner(a, b)
    return [xpp + xc, ypp + yc, zpp + zc]

圖表翻譯:

以上三個函式展示了三維空間中繞不同座標軸的旋轉變換實作。每個函式透過矩陣運算實作對應的旋轉變換,並將結果轉換回世界座標系。

3. 圖形繪製與互動控制實作

繪製圓形及實作互動控制的核心程式碼如下:

import matplotlib.pyplot as plt

def plotcircle(xg, yg, zg):
    """繪製圓形"""
    lastxg, lastyg = xg[0], yg[0]
    for i in range(len(xg)):
        color = 'g' if i < len(xg)/2 else 'r'
        plt.plot([lastxg, xg[i]], [lastyg, yg[i]], 
                linewidth=1, color=color)
        lastxg, lastyg = xg[i], yg[i]
    plt.scatter(xc, yc, s=5, color='k')
    plt.axis([0, 150, 100, 0])
    plt.axis('on')
    plt.grid(True)
    plt.show()

while True:
    axis = input('選擇旋轉軸 (x, y, z): ')
    if axis == 'x':
        Rx = np.radians(float(input('輸入旋轉角度: ')))
        # 執行繞x軸旋轉並繪圖
    # 其他軸的處理邏輯類別似

圖表翻譯:

此互動式控制流程圖展示了程式的執行邏輯。使用者可以透過命令列介面選擇旋轉軸並輸入旋轉角度,程式會根據輸入引數進行對應的旋轉操作並即時顯示結果。

圖表翻譯:

此流程圖清晰地展示了程式的互動邏輯和執行流程,從使用者輸入到最終的圖形繪製,完整地呈現了整個操作過程。

技術特點與優勢分析

  1. 互動式控制:程式提供了靈活的互動式控制機制,使用者可以即時調整旋轉引數並觀察結果。
  2. 三維視覺化:透過Matplotlib實作了高品質的三維圖形展示,有效地呈現了旋轉效果。
  3. 模組化設計:程式採用了模組化的函式設計,各功能模組之間耦合度低,便於維護和擴充套件。

透視投影技術詳解

在前一章中,我們學習瞭如何構建三維座標軸和三維形狀,以及如何圍繞三個座標方向進行旋轉和平移。本章將深入探討透視投影技術,這是一種能夠自動生成透視檢視的變換技術。它的運作原理類別似於相機,將物體上的各個點投射到一個平面上,可以視為相機的底片平面。

透視投影的幾何原理

如圖4-1所示,物體是一個位於x,y,z空間的三維盒子。x,y平面代表了相機的底片平面,而焦點則位於x,y平面的前方。從盒子的角點到焦點繪製出虛擬的光線,這些光線與x,y平面相交,從而構建出盒子的透視檢視。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 三維圖形旋轉與透視投影技術實作

package "圖論網路分析" {
    package "節點層" {
        component [節點 A] as nodeA
        component [節點 B] as nodeB
        component [節點 C] as nodeC
        component [節點 D] as nodeD
    }

    package "中心性指標" {
        component [度中心性
Degree Centrality] as degree
        component [特徵向量中心性
Eigenvector Centrality] as eigen
        component [介數中心性
Betweenness Centrality] as between
        component [接近中心性
Closeness Centrality] as close
    }
}

nodeA -- nodeB
nodeA -- nodeC
nodeB -- nodeD
nodeC -- nodeD

nodeA --> degree : 計算連接數
nodeA --> eigen : 計算影響力
nodeB --> between : 計算橋接度
nodeC --> close : 計算距離

note right of degree
  直接連接數量
  衡量局部影響力
end note

note right of eigen
  考慮鄰居重要性
  衡量全局影響力
end note

@enduml

圖表翻譯:

此圖示展示了透視投影的幾何原理。物體上的點透過虛擬光線與焦點連線,這些光線在x,y平面上形成投射點,從而構建出透視檢視。

針孔相機與電腦投影幾何

針孔相機是透視投影的一個經典例子。如圖4-2所示,從物體發出的光線透過針孔,在相機的底片上形成透視影像。電腦中的透視投影技術與針孔相機的工作原理類別似,但它是在電腦螢幕上呈現影像。

# 透視投影計算示例
def perspective_projection(x, y, z, xfp, yfp, zfp):
    """
    計算透視投影後的座標
    :param x: 物體x座標
    :param y: 物體y座標
    :param z: 物體z座標
    :param xfp: 焦點x座標
    :param yfp: 焦點y座標
    :param zfp: 焦點z座標
    :return: 投影後的x, y座標
    """
    a = x - xfp
    b = y - yfp
    c = z + abs(zfp)  # 使用絕對值確保正確的距離計算
    Q = (a**2 + b**2 + c**2)**0.5
    ux, uy, uz = a/Q, b/Q, c/Q  # 計算單位向量
    Qh = abs(zfp) / (abs(zfp) + z) * Q
    xh = ux * Qh + xfp
    yh = uy * Qh + yfp
    return xh, yh

# 示例用法
x, y, z = 1, 2, 3  # 物體座標
xfp, yfp, zfp = 0, 0, -5  # 焦點座標
xh, yh = perspective_projection(x, y, z, xfp, yfp, zfp)
print(f"投影後的座標:({xh}, {yh})")

內容解密:

此程式碼實作了透視投影的計算過程。首先,計算物體點與焦點之間的向量分量a, b, c,然後計算向量長度Q和單位向量。接著,根據透視投影公式計算投影點的座標(xh, yh)。這個過程模擬了光線從物體投射到焦點,再到投影平面的過程。

透視投影的數學推導

透視投影的數學推導涉及以下步驟:

  1. 計算物體點到焦點的向量。
  2. 計算該向量的單位向量。
  3. 根據單位向量和焦點到物體點的距離,計算投影點的座標。

相關公式如下:

  • $a = x - x_{fp}$
  • $b = y - y_{fp}$
  • $c = z + |z_{fp}|$
  • $Q = \sqrt{a^2 + b^2 + c^2}$
  • $u_x = a / Q$, $u_y = b / Q$, $u_z = c / Q$
  • $Q_h = \frac{|z_{fp}|}{|z_{fp}| + z}Q$
  • $x_h = u_xQ_h + x_{fp}$
  • $y_h = u_yQ_h + y_{fp}$

這些公式描述瞭如何從物體的三維座標計算出其在二維投影平面上的座標。

透視投影的應用與歷史

透視投影技術早在17世紀就被藝術家使用,例如荷蘭畫家維米爾可能使用了針孔相機來輔助他的繪畫。現代電腦圖形學中,透視投影被廣泛應用於遊戲、動畫和視覺特效等領域。