Point3d, Vector3d (Bài trước)

Các ma trận biến đổi

Trong các phân trước khi cần thực hiện việc di chuyển, quay, thay đổi tỷ lệ các Entity đã áp dụng đối tượng lớp Transformation, về bản chất nó là các phép toán dựa trên ma trận, mỗi Transformation chứa một ma trận 4 hàng 4 cột (16 phần tử), để lấy mảng biểu diễn ma trận này dùng phương thức to_a của nó.

Để in ra console ở dạng dễ đọc của ma trận 4x4 của đối tượng lớp Transformation này có thể xây dựng phương thức như sau:

require 'sketchup.rb'
require 'extensions.rb'

# @param [Geom::Transformation]
def puts_matrix t
  a = t.to_a
  printf "%8.03f %8.03f %8.03f %8.03f\n", a[0], a[4], a[8], a[12]
  printf "%8.03f %8.03f %8.03f %8.03f\n", a[1], a[5], a[9], a[13]
  printf "%8.03f %8.03f %8.03f %8.03f\n", a[2], a[6], a[10],a[14]
  printf "%8.03f %8.03f %8.03f %8.03f\n", a[3], a[7], a[11],a[15]
end

# Kiểm tra, tạo một đối tượng Transformation và in
t = Geom::Transformation.new
puts_matrix t

Kết quả in ra ma trận biến đổi là:

   1.000    0.000    0.000    0.000
   0.000    1.000    0.000    0.000
   0.000    0.000    1.000    0.000
   0.000    0.000    0.000    1.000

Ma trận Identity - Ma trận đơn vị

Ma trận khởi tạo ở phần trên thấy có các phần tử trên đường chéo của ma trận có giá trị bằng 1, còn các phần tử khác bằng không - thì đó là ma trận Identity - ma trận đơn vị. Khi ma trận biến đổi trong Geom::Transformation là man trận đơn vị thì khi áp dụng nó hình không có biến đổi gì - không thay đổi tỷ lệ, không dịch chuyển, không xoay

Transformation thu phóng - tỷ lệ và Ma trận của nó

Khi tạo Transformation có chức năng thu phóng, nếu khi áp dụng - tâm của hình tại gốc thì hình thay đổi về kích thước, nếu tâm hình không trùng gốc nó thay đổi về kích thước đồng thời là vị trí. Xem ma trận có chứ năng thu - phóng hình:

# Tạo Transformation có chức năng phóng to gấp đôi
t = Geom::Transformation.scaling 2
puts_matrix t

# Ma trận:
# 2.000    0.000    0.000    0.000
# 0.000    2.000    0.000    0.000
# 0.000    0.000    2.000    0.000
# 0.000    0.000    0.000    1.000

# Transformation thu nhỏ một nửa
t = Geom::Transformation.scaling 1.0/2
puts_matrix t
  #  0.500    0.000    0.000    0.000
  #  0.000    0.500    0.000    0.000
  #  0.000    0.000    0.500    0.000
  #  0.000    0.000    0.000    1.000

# Transformation thu phóng theo chiều x là 2, y là 3, z là 4
t = Geom::Transformation.scaling 2, 3, 4
puts_matrix t
  #  2.000    0.000    0.000    0.000
  #  0.000    3.000    0.000    0.000
  #  0.000    0.000    4.000    0.000
  #  0.000    0.000    0.000    1.000

Như vậy ba phần tử đầu tiên trên đường chéo chính cho biết tỷ lệ thu phóng tương ứng theo các trục. phần tử [1,1] là tỷ lệ theo x, phần tử [2,2] là tỷ lệ trục y và [3,3] là tỷ lệ cho trục z

Tịnh tiến và Ma trận của nó

Tạo một Transformation có chức năng tịnh tiến

# Transformation dịch chuyển theo x đoạn bằng 0,5, y 1,5 và z là 3
t = Geom::Transformation.translation [0.5, 1.5, 3]
puts_matrix t
# 1.000    0.000    0.000    0.500
# 0.000    1.000    0.000    1.500
# 0.000    0.000    1.000    3.000
# 0.000    0.000    0.000    1.000

Nhận thấy 3 phần tử đầu của cột 4 cho biết khoảng cần dịch chuyển, phần tử [1,4] là khoảng dịch theo x, [2,4] là theo y

Đối với Transformation xoay vật thể thì giá trị các phần tử khá phức tạp, tính toán theo sin, cos góc xoay

# Xoay quanh trục z góc 45 độ
t = Geom::Transformation.rotation [1,1,1], [0,0,1], 45.degrees
puts_matrix t
# 0.707   -0.707    0.000    1.000
# 0.707    0.707    0.000   -0.414
# 0.000    0.000    1.000    0.000
# 0.000    0.000    0.000    1.000

Kết hợp các Transformation

Khi có hai Transformation có thể kết hợp chúng thành 1 bằng phép toán tích *

tyle = Geom::Transformation.scaling 2
tinhtien = Geom::Transformation.translation [0.5, 1.5, 3]
puts_matrix tyle
puts '-----'
puts_matrix tinhtien
puts '-----'
thuphong_tinhtien = tyle * tinhtien
puts_matrix thuphong_tinhtien
tinhtien_thuphong = tinhtien * tyle
puts '-----'
puts_matrix tinhtien_thuphong

# 2.000    0.000    0.000    0.000
# 0.000    2.000    0.000    0.000
# 0.000    0.000    2.000    0.000
# 0.000    0.000    0.000    1.000
# -----
# 1.000    0.000    0.000    0.500
# 0.000    1.000    0.000    1.500
# 0.000    0.000    1.000    3.000
# 0.000    0.000    0.000    1.000
# -----
# 2.000    0.000    0.000    1.000
# 0.000    2.000    0.000    3.000
# 0.000    0.000    2.000    6.000
# 0.000    0.000    0.000    1.000
# -----
# 2.000    0.000    0.000    0.500
# 0.000    2.000    0.000    1.500
# 0.000    0.000    2.000    3.000
# 0.000    0.000    0.000    1.000

Đăng ký nhận bài viết mới
Point3d, Vector3d (Bài trước)