12 Bây giờ véc-tơ mới thật là véc-tơ
12.4 Tạo hình chuyển động
trong không gian được mô tả bởi véc-tơ P1, và một hành tinh khối lượngm2 tại điểmP2. Độ lớn của lực hấp dẫn‡giữa chúng là
fg =Gm1m2 r2
trong đó r là khoảng cách giữa chúng, còn Glà hằng số hấp dẫn, bằng khoảng 6,67 ×10−11 N m2 / kg2. Nhớ rằng đây là giá trị của G chỉ trong trường hợp ta tính khối lượng theo ki-lô-gam, khoảng cách theo mét, và lực theo newton.
Hướng của lực lên ngôi sao tạiP1 là chỉ về phíaP2. Ta có thể tính hướng tương đối giữa chúng bằng cách trừ véc-tơ; nếu ta tínhR = P2 - P1, thì hướng củaR bây giờ sẽ chỉ từP1đếnP2.
Khoảng cách giữa hành tinh và ngôi sao là chiều dài củaR: r = norm(R)
Hướng của lực tác dụng lên ngôi sao làRˆ: rhat = R / r
Exercise 12.1 Hãy viết một dãy lệnh Octave để tínhF12là véc-tơ biểu diễn lực mà hành tinh tác dụng lên ngôi sao, vàF21, là lực do ngôi sao tác dụng lên hành tinh.
Exercise 12.2 Hãy gói các câu lệnh sau vào một hàm có tên
gravity_force_func nhận vào các biến P1, m1, P2, và m2 rồi trả lại
F12.
Exercise 12.3 Hãy viết một chương trình mô phỏng quỹ đạo của Sao Mộc quanh Mặt Trời. Khối lượng của Mặt Trời vào khoảng 2,0×1030kg. Bạn có thể lấy số liệu khối lượng của Sao Mộc cũng như khoảng cách đến Mặt Trời và vận tốc của Sao
Mộc trên quỹ đạo từ tranghttp://en.wikipedia.org/wiki/Jupiter.
Chạy chương trình để đảm bảo rằng Sao Mộc quay trọn 1 vòng quỹ đạo quanh Mặt Trời hết khoảng 4332 ngày.
12.4 Tạo hình chuyển động
Hình động là một công cụ hữu ích để kiểm tra kết quả tính toán từ một mô hình vật lý. Nếu có gì trục trặc xảy ra, mọi sự sẽ rõ ràng trên hình động. Có hai cách
làm hình động trong Octave. Một cách là dùnggetframeđể chụp một loạt các ảnh vàmovieđể phát lại chúng. Một cách làm khác, không chính thức, là vẽ một loạt các hình đồ thị. Sau đây là một ví dụ tôi viết cho Bài tập 12.3:
function animate_func(T,M)
% animate the positions of the planets, assuming that the % columns of M are x1, y1, x2, y2.
X1 = M(:,1); Y1 = M(:,2); X2 = M(:,3); Y2 = M(:,4);
minmax = [min([X1;X2]), max([X1;X2]), min([Y1;Y2]), max([Y1;Y2])]; for i=1:length(T)
clf;
axis(minmax); hold on;
draw_func(X1(i), Y1(i), X2(i), Y2(i)); drawnow;
end end
Các biến đầu vào là kết quả đầu ra từode45, một véc-tơTvà một ma trậnM. Các cột của Mchứa các vị trí và vận tốc của Mặt Trời và Sao Mộc, vì vậyX1vàY1 nhận các tọa độ của Mặt Trời; cònX2vàY2nhận các tọa độ của Sao Mộc.
minmaxlà một véc-tơ gồm 4 phần tử được dùng bên trong vòng lặp để thiết lập các trục trên biểu đồ. Thông tin này cần thiết bởi vì nếu không, Octave sẽ tự co dãn hình mỗi lần qua một lượt lặp, và các trục sẽ luôn thay đổi, dẫn đến khó theo dõi hình động.
Qua mỗi lượt lặp,animate_func dùngclf để xóa hình và axis để đặt lại các trục.hold ongiúp ta có thể vẽ được nhiều đường đồ thị lên cùng một hệ trúc (nếu không Octave sẽ tự xóa hình mỗi lần bạn gọi câu lệnhplotmới).
Cũng qua mỗi lượt lặp, ta phải gọidrawnow để Octave thực sự hiển thị từng hình vẽ. Còn nếu không, nó sẽ đợi đến tận khi bạn vẽ xong hết các hìnhrồi mới
cập nhật quá trình hiển thị.
draw_funclà hàm số đảm nhiệm việc vẽ đồ thị: function draw_func(x1, y1, x2, y2)
12.4 Tạo hình chuyển động 155
plot(x1, y1, 'r.', 'MarkerSize', 50); plot(x2, y2, 'b.', 'MarkerSize', 20); end
Các biến đầu vào là vị trí của Mặt Trời và Sao Mộc.draw_funcdùngplotđể vẽ Mặt Trời như một dấu đỏ lớn và Sao Mộc như một dấu xanh lam nhỏ hơn.
Exercise 12.4 Để chắc rằng bạn hiểu được cách hoạt động của
animate_func, hãy thử chú thích để loại ra một số dòng lệnh xem điều gì xảy ra.
Một hạn chế của kiểu hình động này là tốc độ của hình động phụ thuộc vào máy của bạn thực hiện việc vẽ hình lúc nào. Vì kết quả từode45thường không xuất ra đều theo thời gian nên hình động có thể sẽ chậm lại khiode45nhận bước thời gian ngắn và nhanh lên khi bước thời gian dài hơn.
Có hai cách sửa vấn đề này:
1. Khi gọiode45bạn có thể chỉ định một véc-tơ chứa các thời điểm cần phải tính kết quả. Sau đây là một ví dụ:
end_time = 1000; step = end_time/200;
[T, M] = ode45(@rate_func, [0:step:end_time], W);
Đối số thứ hai là một véc-tơ khoảng số chạy từ 0 đến 1000 với bước chạy quy định bởistep. Vìstepbằngend_time/200, nên sẽ có khoảng 200 hàng trongTvàM(chính xác là 201).
Tùy chọn này sẽ không ảnh hưởng đến độ chính xác của kết quả; ode45 vẫn dùng biến thời gian để thực hiện ước tính, nhưng rồi nó sẽ nội suy các giá trị trước khi trả lại kết quả.
2. Bạn có thể dùng pauseđể chạy hình động theo đúng thời gian thật. Sau khi vẽ từng hình và gọi nó drawnow, bạn có thể tính thời gian từ đó đến hình kế tiếp và dùngpauseđể đợi:
dt = T(i+1) - T(i); pause(dt);
Một hạn chế của phương pháp này là nó bỏ qua thời gian cần để vẽ hình, vì vậy nó có xu hướng chạy chậm, đặc biệt nếu hình vẽ phức tạp hoặc bước thời gian quá ngắn.
Exercise 12.5 Hãy dùnganimate_func và draw_funcđể hiển thị kết quả mô phỏng Sao Mộc. Sửa các hàm này để sao cho thời gian một ngày mô phỏng tương đương với 0,001 giây đồng hồ—mỗi vòng quay sẽ mất khoảng 4,3 giây.