2010-07-29 31 views
12

Tôi đang cố viết một phương thức nội suy từ 0 đến x (vị trí của một đối tượng trong một chiều) theo thời gian bằng cách tăng tốc ở đầu và giảm tốc ở cuối (dễ dàng ra/dễ dàng) với các ràng buộc duy nhất mà tổng thời gian được cung cấp, cũng như thời gian tăng tốc và giảm tốc . chuyển động nên tái tạo hiệu ứng quán tính và tôi đang xem xét một số Hermite curve cho các phần không tuyến tính.Toán học: Dễ Trong, dễ dàng Chuyển vị trí bằng đường cong Hermite với giới hạn thời gian

double Interpolate(
    double timeToAccel, double timeCruising, double timeToDecel, 
    double finalPosition, 
    double currentTime) 
{ 
    //... 
} 

Ai đó có thể chỉ cho tôi một phần mã không? Tôi không biết làm thế nào để tích hợp đường cong Hermite, do đó không biết tôi sẽ di chuyển bao nhiêu trong phần tăng tốc hoặc trong phần giảm tốc, và đến lượt tôi không thể biết được tốc độ tuyến tính là bao nhiêu phần.

Cảm ơn.

Some reference để minh họa câu hỏi của tôi.

Sửa:

  • bắt đầu và kết thúc tốc độ là null, và thời điểm hiện tại cũng là một phần của các tham số trong phương pháp này, tôi đã cập nhật chữ ký.
  • về cơ bản ý tưởng là tưởng tượng di chuyển với tốc độ không đổi trên khoảng cách d, điều này cho tổng thời lượng. Sau đó, chúng ta thêm các pha tăng tốc và giảm tốc, trong khi duy trì cùng một khoảng thời gian, do đó chúng ta có một tốc độ hành trình mới chưa xác định để xác định (vì chúng ta di chuyển ít hơn trong các pha Hermite hơn trong các pha tuyến tính mà chúng đã thay thế). Có lẽ số lượng di chuyển bị mất trong các giai đoạn Hermite, so với một động thái tuyến tính của cùng một thời gian là tỷ lệ giữa khu vực trên và dưới trong các đường cong, chỉ là một ý tưởng từ một chuyên gia không.

Chỉnh sửa: Roman và Bob10 đã cung cấp giải pháp làm việc đầy đủ. Tôi đã triển khai mã từ Roman. Cảm ơn cả hai, các bạn! Tôi đánh giá cao sự hỗ trợ hoàn hảo của bạn và các giải pháp chi tiết của bạn, bạn đã lưu cho tôi các tìm kiếm và thử nghiệm dài.

+0

Are vận tốc thiết bị đầu cuối bằng không? –

+1

Có Victor, đúng vậy. – 742

Trả lời

22

Đầu tiên, chúng ta hãy làm một hàm Hermite spline khối:

/* 
    t - in interval <0..1> 
    p0 - Start position 
    p1 - End position 
    m0 - Start tangent 
    m1 - End tangent 
*/ 
double CubicHermite(double t, double p0, double p1, double m0, double m1) { 
    t2 = t*t; 
    t3 = t2*t; 
    return (2*t3 - 3*t2 + 1)*p0 + (t3-2*t2+t)*m0 + (-2*t3+3*t2)*p1 + (t3-t2)*m1; 
} 

Bây giờ nhiệm vụ của bạn là để tính toán p0, p1, M0 và m1 cho cả hai dễ dàng-in và dễ dàng-out phần. Hãy để chúng tôi thêm một vài biến để làm cho toán học dễ dàng hơn một chút để viết:

double Interpolate(
    double timeToAccel, double timeCruising, double timeToDecel, 
    double finalPosition, 
    double currentTime) { 

    double t1 = timeToAccel; 
    double t2 = timeCruising; 
    double t3 = timeToDecel; 
    double x = finalPosition; 
    double t = currentTime; 

Chúng tôi cần xác định đối tượng nên ở đâu khi nó ngừng tăng tốc và bắt đầu giảm tốc. Tuy nhiên, bạn có thể chỉ định những thứ này mà bạn vui lòng và vẫn tạo ra một chuyển động trơn tru, tuy nhiên, chúng tôi muốn có một giải pháp "tự nhiên".

Giả sử tốc độ bay là v. Trong quá trình crusing, đối tượng di chuyển khoảng cách x2 = v * t2. Bây giờ, khi đối tượng tăng tốc từ 0 đến tốc độ v, nó di chuyển khoảng cách x1 = v * t1/2. Tương tự cho giảm tốc x3 = v * t3/2.Đặt tất cả lại với nhau:

x1 + x2 + x3 = x

v * t1/2 + v * t2 + v * t3/2 = x

Từ đó chúng ta có thể tính toán tốc độ của chúng tôi và khoảng cách :

double v = x/(t1/2 + t2 + t3/2); 
    double x1 = v * t1/2; 
    double x2 = v * t2; 
    double x3 = v * t3/2; 

Và bây giờ chúng ta biết tất cả mọi thứ, chúng ta chỉ cần ăn nó vào Hermite khối spline xen vào của chúng tôi

if(t <= t1) { 
     // Acceleration 
     return CubicHermite(t/t1, 0, x1, 0, v*t1); 
    } else if(t <= t1+t2) { 
     // Cruising 
     return x1 + x2 * (t-t1)/t2; 
    } else { 
     // Deceleration 
     return CubicHermite((t-t1-t2)/t3, x1+x2, x, v*t3, 0); 
    } 
} 

Tôi đã thử nghiệm điều này trong Excel, đây là mã VBA tương đương để chơi với. Có một số bộ phận bằng 0 cho các điều kiện biên, tôi để lại bản sửa lỗi cho điều này như là một bài tập cho người đọc


Public Function CubicHermite(t As Double, p0 As Double, p1 As Double, _ 
m0 As Double, m1 As Double) As Double 
    t2 = t * t 
    t3 = t2 * t 
    CubicHermite = (2 * t3 - 3 * t2 + 1) * p0 + _ 
(t3 - 2 * t2 + t) * m0 + (-2 * t3 + 3 * t2) * p1 + (t3 - t2) * m1 
End Function 

Public Function Interpolate(t1 As Double, t2 As Double, t3 As Double, _ 
x As Double, t As Double) As Double 
    Dim x1 As Double, x2 As Double, x3 As Double 

    v = x/(t1/2 + t2 + t3/2) 
    x1 = v * t1/2 
    x2 = v * t2 
    x3 = v * t3/2 

    If (t <= t1) Then 
     Interpolate = CubicHermite(t/t1, 0, x1, 0, v*t1) 
    ElseIf t <= t1 + t2 Then 
     Interpolate = x1 + x2 * (t - t1)/t2 
    Else 
     Interpolate = CubicHermite((t-t1-t2)/t3, x1+x2, x, v*t3, 0) 
    End If 
End Function 
+0

Roman, cảm ơn. Đúng, vấn đề là làm thế nào để xác định số lượng di chuyển trong phần tuyến tính, để có được tốc độ hành trình, và đến lượt chúng ta quay lại pha tăng tốc và tốc độ cuối cùng của nó (nghịch đảo cho pha giảm tốc). Tất cả dường như được lồng vào nhau. Tôi đoán là chúng ta cần tích hợp các đường cong và sau đó giải phương trình mà kết quả là toàn bộ thời gian di chuyển. Nhưng tôi không phải là một nhà toán học, vì vậy tôi có thể sai. Tôi đã tìm kiếm rất nhiều trên mạng, nhưng cho đến nay vẫn không có sự theo đuổi nào. – 742

+0

@Roman, tôi nghĩ bạn có thể gặp lỗi ở đây. Bạn đã sử dụng x = v * t/2, nhưng điều này thường được sử dụng để tăng tốc liên tục và bạn đang sử dụng phương trình khối không khớp với tiêu chí này. Tôi sẽ quan tâm để xem liệu kết quả của chương trình này có phù hợp với các giả định đầu vào hay không. – tom10

+0

Cảm ơn bạn rất nhiều lần nữa. Tôi không hiểu làm thế nào để xác định tangents cho đường cong trong chức năng Nội suy. Tôi đọc một phần khó hiểu (đối với tôi) lý thuyết mà tôi có thể thấy m0 = c và m1 = 3a + 2b + c, nhưng không thể tìm ra giải thích trực quan về các tham số tangents là gì. Đó có phải là độ dốc tại điểm bắt đầu và điểm kết thúc không? Tôi đã mong cả hai sườn bằng 0 (ngang). Hay họ là chân trời, và giá trị là chiều dài của vectơ? Tôi cần điều này để quản lý các giá trị tiếp tuyến trong trường hợp một hoặc hai pha (tăng tốc, hành trình, giảm tốc) không được sử dụng (duration = 0). Thks. – 742

8

Điều này là đơn giản bằng cách sử dụng gia tốc không đổi bình thường. Sau đó, câu hỏi sẽ trở thành vận tốc (v) nào bạn cần tăng tốc để hoàn thành chuyến đi trong khoảng thời gian phù hợp và điều này sẽ cho bạn biết khả năng tăng tốc bạn cần để đạt được vận tốc đó.

Nếu tổng thời gian là T_T và thời gian tăng tốc là t_a, sau đó bạn có các khoảng cách di chuyển như hai tăng tốc và giảm tốc phần, và phần vận tốc không đổi:

x = 2*(a*t_a*t_a/2) + v*(t_t-2*t_a) 

Điều này có thể được giải quyết cho gia tốc bằng thể thay thế trong v = a * t_a, để tìm

a = x/(t_a*(t_t - t_a)) 

Dưới đây là một số mã Python sử dụng và âm mưu kết quả của những phương trình, cho thấy cả hai cách sử dụng các phương trình và kết quả ra sao trông giống như:

from pylab import * 

t_a, t_t, D = 3., 10., 1. # input values 

a = D/(t_a*(t_t - t_a)) 
segments = (t_a, a), (t_t-2*t_a, 0.), (t_a, -a) # durations and accelerations for each segment 

t0, x0, v0 = 0.0, 0.0, 0.0 #initial values for the segment 
tdata, xdata = [], [] 
for t_segment, a in segments: # loop over the three segments 
    times = arange(0, t_segment, .01) 
    x = x0 + v0*times + .5*a*times*times 
    xdata.append(x) 
    tdata.append(times+t0) 
    x0 = x[-1] # the last x calculated in the segment above 
    v0 += a*t_segment 
    t0 += t_segment 

plot(tdata[0], xdata[0], 'r', tdata[1], xdata[1], 'r', tdata[2], xdata[2], 'r') 
xlabel("time") 
ylabel("position") 
show() 

alt text http://i26.tinypic.com/34sqzpi.png

+0

Xin chào Tom, cảm ơn rất nhiều. Nếu tôi có ý tưởng chính xác thì gia tốc của các đường tăng tốc và giảm tốc được giả thiết là hằng số, và bởi vì đây là hằng số, tất cả sẽ được giải quyết bằng cách xác định nó (và v) v) Tuy nhiên tôi không chắc Hermite đường cong là một phần của tập hợp các đường cong với đạo hàm bậc hai không đổi. Dường như với tôi điều này sẽ là ok chỉ cho một parabola (một lần nữa: tôi đã rất hạn chế kỹ năng). Nếu tôi sai, và Hermite thực sự là một phần của các đường cong như vậy, thì bạn có thể vui lòng cho tôi biết làm thế nào để chuyển đổi gia tốc tính toán ở trên vào các tham số Hermite? Cảm ơn. – 742

+1

Đúng, điều này là dễ dàng, dễ dàng, nhưng không phải là một đường cong Hermite. Nói chung với các giải pháp đa thức, tốt nhất là chọn đường cong bậc thấp nhất để giải quyết vấn đề. Tôi có thể tưởng tượng một lý do có thể muốn các đường cong khác, nhưng vấn đề của bạn không được xác định cho một đường cong Hermite, vì vậy tôi cho rằng bạn không thực sự muốn một. – tom10

+0

Tôi nghĩ rằng chuyển động có thể mượt mà hơn nếu bạn sử dụng các đa thức bậc cao. Những gì bạn đề xuất sẽ dẫn đến một đường cong với đạo hàm bậc hai không liên tục. –

Các vấn đề liên quan