Кубическая кривая Безье :Максимальный градиент и предотвращение столкновений?

Я использую кривые Безье в качестве путей, по которым мои космические корабли должны двигаться, когда они входят в док на станции. У меня есть простой алгоритм для вычисления того, где должен находиться корабль в момент времени t по кубической кривой Безье:

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;

    }
}

Начальная точка кривой — это местонахождение космического корабля, а конечная точка — вход в стыковочный отсек (красные точки на диаграмме ). У космического корабля есть нормализованный вектор направления, а у стыковочного отсека есть еще один нормализованный вектор, указывающий направление, в котором должен двигаться корабль, чтобы он был выровнен прямо по стыковочному отсеку, когда он прибудет (желтые линии на диаграмма)

Зеленая линия — это возможный путь космического корабля, а фиолетовый кружок — радиус космического корабля. Наконец, черный ящик является ограничивающим прямоугольником для станции.

enter image description here

У меня две проблемы:

  1. Предполагается, что космический корабль может вращаться только со скоростью r радиан в секунду
  2. . Космический корабль не может пролететь через станцию ​​

Я предполагаю, что это переводится как:

а ). Нахождение «коэффициентов кривой» (длин контрольных точек ), которые дадут путь, по которому кораблю не придется поворачивать слишком круто

б ). Определение местоположения/направления космического корабля, с которого он не может избежать столкновения со станцией (, и создание пути, который выведет его из этого состояния, чтобы он мог приступить к части а))

Однако с обоими из них мне не очень повезло найти решение. У меня уже есть код для обнаружения пересечений между векторами, прямоугольниками, точками и сферами, но пока нет кривых Безье. У меня также есть функции, позволяющие мне найти расстояние между двумя точками.

Будем признательны за любую помощь

Спасибо, Джеймс

6
задан vainolo 12 July 2012 в 15:12
поделиться