2017-11-02 12 views
0

다항식 함수로 설명 된 특정 코스를 따라 차량을 시간 경과에 따라 움직이는 실시간 그래픽 엔진 (C++/OpenGL)을 구현하고 있습니다. 이 함수 자체는 프로그램 외부에서 프로그래밍 방식으로 생성되었으며 고차원 (25 점 이상)이므로 여기에 게시 할 수는 없습니다 (어쨌든 중요하지 않다고 생각합니다). 런타임 중에 함수는 변경되지 않으므로 첫 번째 및 두 번째 파생 상품을 한 번 계산하여 나중에 신속하게 사용할 수 있습니다.arc 길이에 대해 일정한 속도로 함수를 계산하십시오.

내 문제는 일정한 속도 (예 : 초당 10 단위)로 곡선을 따라 이동해야하므로 내 함수 매개 변수가 시간과 직접 같지 않기 때문에 두 지점 x1과 x2 사이의 호 길이가 다르기 때문에 함수 값에 따라 다릅니다. 예를 들어 f (a + 1) - f (a)의 차이는 함수가 점 a 및 b에서 보는 방법에 따라 f (b + 1) - f (b)보다 크게 또는 작을 수 있습니다.

움직임이 시각적이며 더 이상 처리되지 않으므로 모든 근사값도 정상이므로 100 % 정확한 솔루션이 필요하지 않습니다. 또한 모든 것을 런타임에 각 프레임 (60fps)에서 계산해야하므로 계산 시간에 따라 복잡한 수학으로 방정식을 풀면 문제가되지 않을 수도 있습니다.

나는 어디서부터 시작 해야할지 모르겠다. 그래서 어떤 생각의 기차라도 높이 평가할 것이다!

+1

미적분을 아십니까? 차량을 움직여야하는 각도가 다항식의 첫 번째 미분입니다. – Alnitak

+2

https://stackoverflow.com/questions/26226663/evenly-space-circles-along-sin-curve/26226795#26226795 – Alnitak

+0

감사합니다. 나는 그 접근법을 시도 할 것이다. 그러나 링크 된 math.stackexchange 페이지에있는 사람들이 sqrt의 정밀도와 소수점에 문제가있는 것처럼 보였으므로 아마도 약간 조정해야 할 것입니다. (여기에도 작은 숫자로 작업하고 있습니다.) – Markus

답변

0

기준에 정확한 해결책이있는 것이 아니기 때문에 시각적으로 매력적인 근사치가 있으므로 여러 가지 가능한 해결책이 있습니다.


접근 방식은 내가 작은 반복에 의해 통합 실제 arclength을 근사하는 구현 (코멘트에 알니 타크에 의해 제안 이후 coproc 응답). 이 버전은 대부분의 경우 실제로 잘 작동했지만 가파른 각도에서는 안정적이지 못했으며 편평한 각도에서 너무 많은 반복을 사용했습니다. coproc가 이미 답변에서 지적했듯이, 가능한 해결책은 dx를 2 차 미분을 기반으로하는 것입니다.

이 모든 조정은 이 될 수 있지만 일 수 있습니다. 그러나 런타임 친숙한 알고리즘이 필요합니다. 이걸로 반복의 수를 예측하기가 어렵습니다. 그래서 나는 그것에 만족하지 않았습니다.


(도 알니 타크 영감)을 방법은 (현재의 x 값의 유도체와 동일) 상기 계산 된 슬로프에 따라 "푸시"차량에 의해 1 차 도함수를 이용된다. 다음 x 값을 계산하는 기능은 정말 작고 빠릅니다. 시각적으로 명확한 부정확성은 없으며 결과는 항상 일치합니다.객체는 항상 직선과 함께 밀어되기 때문에

float current_x = ...; //stores current x 
float f(x) {...} 
float f_derv(x) {...} 

void calc_next_x(float units_per_second, float time_delta) { 
    float arc_length = units_per_second * time_delta; 
    float derv_squared = f_derv(current_x) * f_derv(current_x); 
    current_x += arc_length/sqrt(derv_squared + 1); 
} 

이 방법은, 그러나, 가능성 만 높은 프레임 시간의 경우 (광산은> 60 프레임) 충분히 정확 것이다 (내가 선택한 이유입니다) 상기 프레임 시간에 의존하는 길이.

0

프레임 사이의 일정한 속도와 시간이 주어지면 프레임 사이의 원하는 호 길이를 계산할 수 있습니다. 당신은 정확도가 바로 작동 할 수 적절한 dx 위의 함수를 선택하는 최고의 기준이 아니라고 때문에

#include <cmath> 
typedef double (*Function)(double); 

double moveOnArc(Function f, const double xStart, const double desiredArcLength, const double dx = 1e-2) 
{ 
    double arcLength = 0.; 
    double fPrev = f(xStart); 
    double x = xStart; 
    double dx2 = dx*dx; 
    while (arcLength < desiredArcLength) 
    { 
    x += dx; 
    double fx = f(x); 
    double dfx = fx - fPrev; 
    arcLength += sqrt(dx2 + dfx*dfx); 
    fPrev = fx; 
    } 
    return x; 
} 

: 그래서 다음 함수가 작업을 수행해야합니다. 물론, dx을 자동으로 (예 : 2 차 미분을 기반으로) 조정하거나 이진 검색으로 끝점을 좁히면 향상 될 수 있습니다.