LibGDX Path (CatmullRomSpline) Постоянная скорость

Я пытаюсь достичь постоянной скорости на пути, используя LibGDX CatmullRomSpline, и у меня возникают проблемы с его работой. Я много пытался исследовать эту тему, включая чтение вики LibGDX, но их объяснение достижения постоянной скорости не имеет смысла, и я не смог заставить их метод работать.https://github.com/libgdx/libgdx/wiki/Path-interface-&-Splines В моем случае значения производной очень велики (в сотнях), поэтому при делении числа между 0-1 и производной результат очень мал, а движение очень медленное и все еще не постоянное. Так что я не уверен, как именно работает их пример.

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

В методе act () MyPath.java я закомментировал два раздела, начиная с [1] и [2]. Первый нормальный с переменной скоростью на пути, а второй - моя неудачная попытка заставить постоянную скорость вики LibGDX работать. Так что просто откомментируйте эти строки для переключения между двумя версиями.

Моя идея постоянной скорости заключается в определении скорости на основе общей длины пути (с использованием метода приблизительной длины (1000) на сплайне), затем с использованием производной функции для определения фактической скорости в данный момент и корректировки процента значение, отправляемое в сплайн для компенсации изменений скорости с целью обеспечения постоянной скорости. Тем не менее, я не совсем понимаю, что на самом деле представляет производная функция. Я ранее опубликовал вопрос о производной функции, но, основываясь на полученном мной комментарии, я подумал, что вместо этого проще задать вопрос о достижении постоянной скорости. Вот мой предыдущий вопрос о производной функции:Производная LibGDX CatmullRomSpline Значение?

Будем весьма благодарны за любые идеи о том, как добиться постоянной скорости в моем примере (или объяснения того, что на самом деле представляет производная функция для CatmullRomSpline, чтобы я мог лучше понять, как ее использовать).

Для тех, кто хотел бы запустить программу, вот два файла изображений, которые я создал для моего примера (добавьте их в корень папки assets):http://dropshots.com/Tekker/date/2015-09-19

Вот мой пример кода:

DesktopLauncher.java: (изменена ширина и высота окна рабочего стола до 1000)

public class DesktopLauncher {
    public static void main (String[] arg) {
        LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
        config.width = 1000;
        config.height = 1000;
        new LwjglApplication(new TEST(), config);
    }
}

TEST.java:

public class TEST extends Game {
    Stage stage;    
    MyPath path;

    @Override
    public void create () {
        stage = new Stage();
        stage.setViewport(new ScreenViewport(stage.getViewport().getCamera()));
        Gdx.input.setInputProcessor(stage);
        path = new MyPath(1000, 1000);
        stage.addActor(path);
    }

    @Override
    public void render () {
        Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        stage.act(Gdx.graphics.getDeltaTime());
        stage.draw();
    }

    @Override
    public void dispose(){
        stage.dispose();
        super.dispose();
    }
}

MyPath.java:

public class MyPath extends WidgetGroup {
    Image start, end, path, bar1, horizontal;
    float time, percent, dVal, pathLength, dMax=1000, cycle=6, maxPercent, deltaCycle;

    CatmullRomSpline<Vector2> catmull;
    Vector2 result = new Vector2();
    Vector2 previousResult = new Vector2(50,150);
    Vector2 derivative = new Vector2();
    Vector2 previousDerivative = new Vector2();
    Vector2[] points = {
        new Vector2(50,150), new Vector2(50,150),
        new Vector2(400,800), new Vector2(600,150), new Vector2(700,400),
        new Vector2(860,150), new Vector2(860,150)
    };

    boolean print = true;

    public MyPath(int width, int height){
        this.setSize(width, height);
        catmull = new CatmullRomSpline<Vector2>(points, false);

        createPath();
        createBar();

        pathLength = catmull.approxLength(1000);
    }

    @Override
    public void act(float delta){
        // [1] VARIABLE SPEED
        //time += delta;
        //percent = (time / cycle) % 1;

        // [2] CONSTANT SPEED FAIL!
        //catmull.derivativeAt(previousDerivative, percent);
        //time += delta;
        //percent = ((time / cycle) / previousDerivative.len() ) % 1;

        catmull.valueAt(result, percent);
        path.setPosition(result.x, this.getHeight() - result.y);

        updateSpeedVisuals();
        debugPrint();

        previousResult.set(result);
    }

    private void createPath(){
        start = new Image(new Texture("dot.png"));
        start.setColor(Color.GRAY);
        start.setPosition(50, this.getHeight() - 150);
        this.addActor(start);

        end = new Image(new Texture("dot.png"));
        end.setColor(Color.GRAY);
        end.setPosition(860, this.getHeight() - 150);
        this.addActor(end);

        path = new Image(new Texture("dot.png"));
        path.setColor(Color.WHITE);
        this.addActor(path);
    }

    private void createBar(){
        Texture texture = new Texture("ninepatch.png");
        int crop = (int)(texture.getWidth()/2)-1;
        NinePatch patch9 = new NinePatch(texture, crop, crop, crop, crop);
        bar1 = new Image(patch9);
        bar1.setColor(Color.GRAY);
        bar1.setPosition(5, this.getHeight()-900);
        this.addActor(bar1);
    }

    private void updateSpeedVisuals(){
        catmull.derivativeAt(derivative, percent);
        dVal = derivative.len() / dMax;
        path.setColor(1f, 1f-dVal, 1f-dVal, 1f);
        bar1.setWidth(derivative.len());
        bar1.setColor(1f, 1f-dVal, 1f-dVal, 1f);
    }

    private void debugPrint(){
        maxPercent = (percent > maxPercent) ? percent : maxPercent;
        if (maxPercent > percent){
            print = false;
        }
        if (print){
            String debugPrint = "";
            debugPrint = debugPrint + "pathLength=" + pathLength + "\t";
            debugPrint = debugPrint + "derivative=" + derivative.len() + "\t";
            System.out.println(debugPrint);
        }
    }
}

Ответы на вопрос(1)

Ваш ответ на вопрос