Używam krzywych Beziera jako ścieżek do poruszania się statkami kosmicznymi, kiedy zbliżają się do stacji dokującej. Mam prosty algorytm do obliczania gdzie statek powinien być w czasie t wzdłuż krzywej sześciennej Beziera:Krzywa Beziera Krzywa: Maksymalne unikanie kolizji i kolizji?
public class BezierMovement{
public BezierMovement(){
// start docking straight away in this test version
initDocking();
}
private Vector3 p0;
private Vector3 p1;
private Vector3 p2;
private Vector3 p3;
private double tInc = 0.001d;
private double t = tInc;
protected void initDocking(){
// get current location
Vector3 location = getCurrentLocation();
// get docking point
Vector3 dockingPoint = getDockingPoint();
// ship's normalised direction vector
Vector3 direction = getDirection();
// docking point's normalised direction vector
Vector3 dockingDirection = getDockingDirection();
// scalars to multiply normalised vectors by
// The higher the number, the "curvier" the curve
float curveFactorShip = 10000.0f;
float curveFactorDock = 2000.0f;
p0 = new Vector3(location.x,location.y,location.z);
p1 = new Vector3(location.x + (direction.x * curveFactorShip),
location.y + (direction.y * curveFactorShip),
location.z + (direction.z * curveFactorShip));
p2 = new Vector3(dockingPoint.x + (dockingDirection.x * curveFactorDock),
dockingPoint.y + (dockingDirection.y * curveFactorDock),
dockingPoint.z + (dockingDirection.z * curveFactorDock));
p3 = new Vector3(dockingPoint.x, dockingPoint.y, dockingPoint.z);
}
public void incrementPosition() {
bezier(p0, p1, p2, p3, t, getCurrentLocation());
// make ship go back and forth along curve for testing
t += tInc;
if(t>=1){
tInc = 0-tInc;
} else if(t<0){
tInc = 0-tInc;
}
}
protected void bezier(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, double t, Vector3 outputVector){
double a = (1-t)*(1-t)*(1-t);
double b = 3*((1-t)*(1-t))*t;
double c = 3*(1-t)*(t*t);
double d = t*t*t;
outputVector.x = a*p0.x + b*p1.x + c*p2.x + d*p3.x;
outputVector.y = a*p0.y + b*p1.y + c*p2.y + d*p3.y;
outputVector.z = a*p0.z + b*p1.z + c*p2.z + d*p3.z;
}
}
Krzywa punkt startu jest lokalizacja statek kosmiczny, a punkt końcowy znajduje się wejście do hangaru (czerwone kropki na schemacie). Statek kosmiczny ma znormalizowany wektor dla jego kierunku, a wnęka dokująca ma inny znormalizowany wektor, który wskazuje kierunek, w którym statek musi się przemieszczać, tak aby był wyrównany bezpośrednio do dokującej stacji, gdy nadejdzie (żółte linie na schemacie)
Zielona linia to możliwa ścieżka statku kosmicznego i fioletowy okrąg, promień statku kosmicznego. W końcu czarna skrzynka to ramka ograniczająca dla stacji.
mam dwa problemy:
- kosmicznym ma tylko być w stanie obrócić w R radianach na sekundę
- statek kosmiczny nie może latać przez stację
Zakładam, że przekłada się to na:
a). Znalezienie "współczynników krzywej" (długości punktów kontrolnych), które dadzą ścieżkę, w której statek nie musi zbyt mocno skręcić
b). Znalezienie lokalizacji/kierunku statku kosmicznego, z którego nie może uniknąć kolizji ze stacją (i utworzenie ścieżki do wyprowadzenia go z tego stanu, aby można było przejść do części a))
Jednak w przypadku obu tych , Nie miałem szczęścia znaleźć rozwiązania. Mam już kod do wykrywania przecięć między wektorami, ramkami, punktami i sferami, ale jeszcze nie krzywymi Beziera. Mam również funkcje pozwalające mi znaleźć odległość między dwoma punktami.
Każda pomoc będzie najbardziej cenionych
Dzięki James
Dzięki! i przepraszam, że tak długo wracam do ciebie. Poprawiłem to pytanie, chociaż ostatecznie zdecydowałem się na inną metodę, w której używam "punktu bocznego", który statki idą do przodu, jeśli stacja jest na drodze, zanim przejdzie do punktu dokowania. –