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