LibGDX路径(CatmullRomSpline)恒速 [英] LibGDX Path (CatmullRomSpline) Constant Speed

查看:137
本文介绍了LibGDX路径(CatmullRomSpline)恒速的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用LibGDX CatmullRomSpline在路径上实现恒定速度,并且我在使其工作时遇到问题。我已经尝试过很多关于这个主题的研究,包括阅读LibGDX维基,但他们对实现恒定速度的解释并没有真正意义,我无法让他们的方法发挥作用。 https://github.com/libgdx/libgdx/wiki/Path -interface-& -Splines
在我的情况下,导数值非常大(数百),所以当将0-1之间的数除以导数时,结果非常小并且运动非常缓慢但仍然不稳定。所以我不确定他们的例子是如何运作的。

I’m trying to achieve constant speed on a path using the LibGDX CatmullRomSpline and I’m having problems getting it to work. I’ve tried researching on this topic a lot including reading the LibGDX wiki, but their explanation for achieving constant speed doesn’t really make sense and I wasn’t able to get their method to work. https://github.com/libgdx/libgdx/wiki/Path-interface-&-Splines In my case, the derivative values are very large (in the hundreds) so when dividing a number between 0-1 by the derivative the result is very small and the movement is very slow and still not constant. So I’m not sure exactly how their example works.

在我的例子中,我有几个视觉辅助工具与球的速度相吻合,底部的条形图随着速度的增加,屏幕长度增加,随着速度的增加,颜色也会从白色变为红色。

In my example I have a couple visual aids coinciding with the speed of the ball, the bar at the bottom of the screen increases in length as the speed increases and the color also changes from white to red as the speed increases.

在MyPath.java的act()方法中我有从[1]和[2]开始,两节注释掉了。第一个是正常的,通过路径可变速度,第二个是我尝试使LibGDX wiki恒速工作失败。所以只需取消注释这些行就可以在两个版本之间切换。

In the act() method of MyPath.java I have two sections commented out starting with [1] and [2]. The first one is normal with the variable speed through the path and the second one is my failed attempt at getting the LibGDX wiki constant speed to work. So just un-comment these lines to switch between the two versions.

我对恒定速度的想法包括根据路径的总长度确定速度(使用对样条曲线进行近似(1000)方法,然后使用导数函数确定给定时刻的实际速度,并调整发送到样条曲线的百分比值以补偿速度变化,以使速度保持恒定。但是,我不太明白衍生函数实际上代表什么。我之前发布了关于衍生函数的问题,但根据我收到的评论,我认为可能更容易询问实现恒定速度。这是我之前关于衍生函数的问题:
LibGDX CatmullRomSpline衍生意义?

My idea for constant speed involves figuring out the speed based on the total length of the path (using the approxLength(1000) method on the spline), then using the derivative function to determine the actual speed at a given instant, and adjusting the percentage value sent into the spline to compensate for the speed changes in order to make the speed constant. However, I don’t quite understand what the derivative function actually represents. I posted a question about the derivative function earlier, but based a comment I received I figured it might be easier to ask about achieving constant speed instead. Here is my previous question on the derivative function: LibGDX CatmullRomSpline Derivative Meaning?

关于如何在我的示例中实现恒定速度的任何想法(或解释CatmullRomSpline的衍生函数实际上代表什么,以便我可以更好地理解如何使用它)将会非常赞。

Any ideas on how to achieve constant speed in my example (or explaining what the derivative function for the CatmullRomSpline actually represents so I could better understand how to use it) would be greatly appreciated.

对于任何想要运行程序的人来说,这里是我为我的例子创建的两个图像文件(将这些文件添加到assets文件夹的根目录) :
http://dropshots.com/Tekker/date/2015-09 -19

For anyone who'd like to run the program, here are the two image files I created for my example (add these to the root of the assets folder): http://dropshots.com/Tekker/date/2015-09-19

以下是我的示例代码:

DesktopLauncher.java:(将桌面窗口宽度和高度更改为1000)

DesktopLauncher.java: (changed desktop window width and height to 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);
        }
    }
}


推荐答案

由于导数是样条位置的变化率,它确实是速度,当样条曲线远离基础数据点时,它必须加速以使计算的样条曲线达到下一个数据时间点,你必须将这个速度分开来感知视觉恒定速度。

Since the derivative is the rate of change of the spline position it is indeed the 'speed', and when the spline is bending away from the underlying data points it has to 'speed up' to make the calculated spline reach the next data point in time, you must divide out this speed to perceive a visual constant speed.

你没有得到一个恒定的速度,因为你还在增加你的时间变量乘以delta而不是delta除以变化率(导数)。您应该在每个帧的百分比变量中添加一个可变量,而不是通过沿Catmull-Rom样条曲线的单个点的导数修改所有内容。

You aren't getting a constant speed because you are still incrementing your time variable by delta instead of delta divided by the rate of change (derivative). You should be adding a variable amount to the percent variable each frame, instead you were modifying everything by the derivative of a single point along the Catmull-Rom spline.

而不是:

catmull.derivativeAt(previousDerivative, percent);
time += delta;
percent = ((time / cycle) / previousDerivative.len() ) % 1;

你应该:

catmull.derivativeAt(previousDerivative, percent);
percent += derivativeAverage / cycle * delta / previousDerivative.len();
percent %= 1;

你现在应该使用平均导数除以周期,因为你不能单独使用周期作为百分比每秒变量。

you should use the average derivative divided by cycle now since you can't use cycle alone as a percent per second variable anymore.

迭代样条曲线以找到derivativeAverage的平均值:

Iterating over the spline to find the average value of the derivativeAverage:

 int samples = 100; //the higher the more accurate, however slower
 float derivativeAverage = 0;
 Vector2 out = new Vector2();
 for (float i=0;i<1;i+=1f/samples) {
     catmull.derivativeAt(out, i);
     derivativeAverage += out.len();
 }
 derivativeAverage /= samples;

这篇关于LibGDX路径(CatmullRomSpline)恒速的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆