Biểu diễn điểm trong không gian dùng lớp Geom::Point3d
, vector thì dùng lớp Geom::Vector3d
, cũng có thể biểu diễn chúng đơn giản bằng cách dùng mảng Array ở bài trước.
Lớp Geom::Point3d
Lớp Geom::Point3d
biểu diễn điểm trong không gian với ba tọa độ x,y,z. Khởi tạo một đối tượng này có mấy cách như:
# Khởi tạo không tham số, điểm có tọa độ [0,0,0] pt1 = Geom::Point3d.new # Tạo điểm có tọa độ x = 100, y = 200, z = 300 pt2 = Geom::Point3d.new(100,200,300) # Cũng có thể tạo điểm bằng cách sử dụng mảng pt3 = [100,200,300]
linear_combination |
linear_combination(weight1, point1, weight2, point2)
Tạo một điểm mới bằng cách nội suy giữa hai điểm, điểm nội suy nằm trên đường giữa hai điểm point1 và point2 với trọng số giữa hai điểm tương ứng. Giống như tìm trọng tâm với hai điểm có khối lượng, công thức để nội suy là:
point = weight1 * point1 + weight2 * point2 point1 = Geom::Point3d.new(10,10,0) point2 = [20,20,0] point = Geom::Point3d.linear_combination(0.2, point1, 0.8, point2) # Point3d(18, 18, 0) |
+ -
|
Cộng/trừ tọa độ cho một vector
point1 = Geom::Point3d.new(1, 2, 3) vector = Geom::Vector3d.new(4, 5, 6) point2 = point1 + vector # Point3d(5, 7, 9) |
< |
Kiểm tra xem điểm nào gần gốc tọa độ hơn
pt1 = Geom::Point3d.new(0,0,10) pt2 = Geom::Point3d.new(0,0,20) result = pt1 < pt2 # true - pt1 gần gốc tọa độ hơn |
== |
Kiểm tra xem hai điểm có tọa độ trùng nhau không |
[] |
Toán tử lấy tọa độ điểm theo chỉ số, 0 là x [0] , 1 là y [1] |
.clone |
Khởi tạo điểm mới giống tọa độ điểm ban đầu |
distance |
Xác định khoảng cách hai điểm, giống ở phần mảng Array |
distance_to_line |
Khoảng cách điểm đến đường, xem phần mảng Array |
distance_to_plane |
Khoảng cách điểm đến mặt, xem phần mảng Array |
inspect |
Lấy chuỗi thông tin đối tượng |
offset |
offset(vector, length = vector.length) dịch chuyển điểm một đoạn theo hướng một vector point1 = Geom::Point3d.new(10,10,10) vector = Geom::Vector3d.new(0, 0, 1) point2 = point1.offset(vector) # Point3d(10, 10, 11) |
offset! |
Giống offset , nhưng biến đối chính đối tượng ban đầu |
on_line?(line) |
Kiểm tra điểm có thuộc một đường, xem phần Array |
on_plane?(plane) |
Kiểm tra điểm thuộc mặt, xem phần Array |
project_to_line(line) |
Chiếu điểm xuống đường, xem Array |
project_to_plane(plane) |
Chiếu điểm xuống mặt, xem Array |
set! |
Thiết lập giá trị các thành phần tọa độ |
to_a |
Chuyển Point3d về mảng Array |
to_s |
Lấy chuỗi biểu diễn điểm |
transform(transform) |
Biến đổi điểm theo một Transform
tr = Geom::Transformation.translation([1,1,1]) # dịch chuyển một đoạn bằng vector [1,1,1] point1 = Geom::Point3d.new(1,1,1) point2 = point1.transform(tr) |
transform!(transform) |
Giống transform(transform) nhưng biến đổi đối tượng gốc |
vector_to |
Tạo vector tới điểm thứ 2 |
x , y , z |
Lấy các thành phần tọa độ |
x= , y= , z= |
Gán các thành phần tọa độ |
Lớp Geom::Vector3d
Lớp Geom::Vector3d
biểu diễn vector trong không gian, có các phương thức tham khảo ở phần Array và Point3d, trong đó lưu ý:
% |
Tích vô hướng hai vector |
cross |
Tích có hướng hai vector |
+ , - |
Cộng, trừ hai vector |
< |
Kiểm tra các thành phần x,y hoặc z nhỏ hơn vector so sánh |
== |
Kiểm tra hai vector bằng nhau không |
[] []= |
Đọc / gán thành phần tọa độ của vector |
angle_between |
Tính góc giữa hai vector (Radian)
vector1 = Geom::Vector3d.new(1,1,0) vector2 = Geom::Vector3d.new(0,1,0) angle = vector1.angle_between vector2 angle.radians |
axes |
Lấy mảng chứa 3 vector biểu diễn ba trục tọa độ, trong đó trục z trùng với vector đã cho |
clone |
Sinh vector mới từ vector ban đầu |
cross giống * |
Tích hai vector |
dot |
Tích vô hướng |
length lengthu= |
Đọc, gán Chiều dài vector |
normalize |
Đưa về chiều dài đơn vị |
normalize! |
Giống normalize nhưng biến đổi đối tượng gốc |
parallel? |
Kiểm tra hai vector song song (cùng phương) |
perpendicular?(vector2) |
Kiểm tra hai vector vuông góc nhau |
reverse |
Tạo vector ngược chiều |
reverse! |
Biến đổi thành vector ngược chiều |
samedirection? |
Kiểm tra hai vector cùng phương, cùng hướng |
unitvector? |
Kiểm tra có phải vector đơn vị |
valid? |
Kiểm tra vector hợp lệ (dài khác 0) |
Phương thức trong Module Geom
Các phương thức trong module Geom có tham số là các đường và các mặt, nhưng không có một lớp cụ thể nào biểu diễn đường và mặt. Một đường có thể biểu diễn bằng một mảng gồm một điểm và một vector, hoặc một mảng hai điểm. Ví dụ như:
line1 = [Geom::Point3d.new(0, 0, 0), Geom::Vector3d.new(0, 0, 1)] line2 = [Geom::Point3d.new(0, 0, 0), Geom::Point3d.new(0, 0, 100)]
Một mặt có thể biểu diễn bởi một mảng gồm 1 điểm và một vector (là pháp tuyến).
plane1 = [Geom::Point3d.new(0, 0, 0), Geom::Vector3d.new(0, 0, 1)]
Mặt còn biểu diễn bởi mảng là các tham số của phương trình đại số biểu diễn mặt
Ax + By + Cz + D = 0
plane2 = [0, 0, 1, 0] # A= 0, B = 0, C = 1, D = 0
Các phương thức lớp
closest_points |
.closest_points(line1, line2) ⇒ Array(Geom::Point3d, Geom::Point3d)
Điềm điểm gần nhất trên hai đường, điểm thứ nhất nằm trên đường 1 và điểm thứ 2 nằm trên đường 2
|
fit_plane_to_points |
Tính toán trả về mặt biểu diễn bởi mảng gồm điểm và vector pháp tuyến
Array(Geom::Point3d, Geom::Vector3d)
Tìm mặt bởi các điểm, nếu trả về mảng 4 phần tử thì nó là tham số của phương trình mặt phẳng |
intersect_line_line |
Giao của hai đường intersect_line_line(line1, line2) ⇒ Geom::Point3d? |
intersect_line_plane |
Giao giữa đường và mặt
intersect_line_plane(line, plane) ⇒ Geom::Point3d?
|
intersect_plane_plane |
Tìm giao của hai mặt intersect_plane_plane(plane1, plane2) ⇒ Array(Geom::Point3d, Geom::Vector3d) |
linear_combination |
Nội suy điểm hoặc vector |
point_in_polygon_2D |
Kiểm tra điểm thuộc đa giác polygon, các điểm có z = 0
point_in_polygon_2D(point, polygon, check_border)
point = Geom::Point3d.new(5, 0, 10) triangle = [] triangle << Geom::Point3d.new(0, 0, 0) triangle << Geom::Point3d.new(10, 0, 0) triangle << Geom::Point3d.new(0, 10, 0) hits_on_border_count = true status = Geom.point_in_polygon_2D(point, triangle, hits_on_border_count) |
Ví dụ sau vẽ đường tròn qua ba điểm
# 30.circle3point.rb # load "/Users/xuanthulab/Desktop/learn-ruby/sketchup/30.circle3point.rb" require 'sketchup.rb' require 'extensions.rb' class Circle3Point # Phương thức vẽ đường tròn từ ba điểm (khác nhau, không thẳng hàng) # @param [Geom::Point3d] a # @param [Geom::Point3d] b # @param [Geom::Point3d] c def circle_3point(a, b, c) ents = Sketchup.active_model.entities lineab = [a,b] linebc = [b,c] projecta_bc = a.project_to_line linebc projectc_ab = c.project_to_line lineab normal_bc = (projecta_bc.vector_to a).normalize normal_ab = (projectc_ab.vector_to c).normalize mab = Geom::Point3d.linear_combination 0.5, a, 0.5, b mbc = Geom::Point3d.linear_combination 0.5, b, 0.5, c ab_center = [mab, normal_ab] bc_center = [mbc, normal_bc] center = Geom.intersect_line_line ab_center, bc_center radius = center.distance a normal = (a.vector_to b) * (b.vector_to c).normalize ents.add_circle center, normal, radius, 900 end # Gọi khi kích hoạt công cụ def activate puts 'Kích hoạt Tool' # InputPoint để nhấn chuột chọn các Entity @input = Sketchup::InputPoint.new @point1 = nil @point2 = nil @point3 = nil @pointmove = nil # Hiện thông báo VCB Sketchup.set_status_text "Nhập điểm 1", SB_VCB_LABEL end # Gọi khi hủy chọn công cụ def deactivate(view) puts "Bất hoạt tool: #{view}" end def onCancel(reason, view) puts "Hủy chọn tool ##{reason} trong view: #{view}" end # @param [Sketchup::View] view def draw(view) options = { :font => "Arial", :size => 20, :bold => true, :align => TextAlignRight } point = Geom::Point3d.new(200, 200, 0) view.draw_text(point, "Vẽ hình tròn có 3 điểm", options) view.drawing_color = Sketchup::Color.new(255, 0, 0, 64) if !@pointmove.nil? # Vẽ điểm tại chuột status = view.draw_points @pointmove, 10, 2, "red" end view.draw_points(@point1,10,2, "red") if !@point1.nil? view.draw_points(@point2,10,2, "red") if !@point2.nil? view.draw_points(@point3,10,2, "red") if !@point3.nil? end # Bắt sự kiện di chuyển chuột def onMouseMove(flags, x, y, view) # Hiện thị tọa độ trong VCB @input.pick view, x, y @pointmove = @input.position # Hiện thị tooltip điểm view.tooltip = @input.tooltip view.invalidate end # Bắt sự kiện nhấn chuột trái def onLButtonDown flags, x, y, view @input.pick view, x, y if @point1.nil? @point1 = @input.position Sketchup.set_status_text "Nhập điểm 2", SB_VCB_LABEL elsif @point2.nil? tempoint = @input.position if !(tempoint == @point1) @point2 = tempoint Sketchup.set_status_text "Nhập điểm 3", SB_VCB_LABEL else puts "Hai điểm trùng nhau" end elsif @point3.nil? tempoint = @input.position if !((tempoint == @point1) || (tempoint == @point2)) @point3 = tempoint if !tempoint.on_line? [@point1, @point2] if (@point3.nil?) UI.messagebox("Ba điểm không được thẳng hàng") else circle_3point(@point1, @point2, @point3) Sketchup.active_model.select_tool nil end else puts "Hai điểm trùng nhau" end end end end if( not file_loaded? "30.circle3point.rb" ) # Tạo menu chọn công cụ simple_cmd = UI::Command.new("Circle 3 Point") { # Chọn công cụ Sketchup.active_model.select_tool Circle3Point.new } tool_menu = UI.menu "Tools" tool_menu.add_separator tool_menu.add_item simple_cmd file_loaded "30.circle3point.rb" end