java - 将 Vector3 缓动到新位置

标签 java android vector libgdx easing

不确定 libgdx 是否提供此功能,所以这可能是一个数学问题。我将各种 3D 相机坐标存储为 Vector3,并且我想将相机从一个移动到另一个。

Vector3 CAM_POSITION_DEFAULT = new Vector3(0f, 1f, -5f);
Vector3 CAM_POSITION_TOP = new Vector3(0f, 10f, -5f);

我可以将相机位置设置为新位置,但这太清晰了。一个很好的平滑过渡,带有一些缓和(慢速开始,快速中间,慢速结束)将是理想的。

这只是一个简单的矩阵操作,还是有一个简洁的方法来通过缓动来获得此功能?其次,如果缓动可用,是否可以使用不同形式的缓动(例如在 javascript 的 jQuery 库中)?

非常感谢。

最佳答案

您正在寻找的是两个位置之间的简单线性插值。

要实现此目的,您可以使用 libgdx 提供的 lerp(...) 方法。

如果您想计算 CAM_POSITION_DEFAULTCAM_POSITION_TOP 之间的位置,您只需在两个 vector 之间进行插值即可:

Vector3 inbetween = CAM_POSITION_DEFAULT.lerp(CAM_POSITION_TOP, alpha);

如果您提供的值 alpha=0,您将返回 CAM_POSITION_DEFAULT,如果您提供 alpha=1,您将获得 CAM_POSITION_TOP...因此 alpha=0.5f 将是两个位置正中间的点...

现在的技巧是如何选择 alpha 值以实现需要指定秒数的平滑过渡:

class CameraTransition {

    private final Vector3 startPos;
    private final Vector3 goalPos;
    private final float duration;

    private float stateTime = 0.0f;

    public CameraTransition(final Vector3 startPos, final Vector3 goalPos, float duration) {
        this.startPos = startPos;
        this.goalPos = goalPos;
        this.duration = duration;
    }

    public Vector3 act(float delta) {
        stateTime += delta;

        return startPos.lerp(goalPos, MathUtils.clamp(stateTime/duration, 0.0f,1.0f));
    }

}

所以你可以使用这段代码(未经测试,抱歉)...创建一个新的 CameraTransition 并设置持续时间。

然后在您的 render(float delta) 中,您只需调用 act() 方法并传递增量时间。 当然,您应该仅在希望运行转换时调用 act() 方法。

希望这有帮助......:)

更新:

看到您正在寻找缓慢开始和缓慢结束的平滑过渡后,我已将插值更改为使用更平滑的曲线而不是线性插值:

class CameraTransition {

        private final Vector3 startPos;
        private final Vector3 goalPos;
        private final float duration;

        private float stateTime = 0.0f;
        private float alpha;

        public CameraTransition(final Vector3 startPos, final Vector3 goalPos, float duration) {
            this.startPos = startPos;
            this.goalPos = goalPos;
            this.duration = duration;
        }

        public Vector3 act(float delta) {
            stateTime += delta;

            alpha = MathUtils.clamp(stateTime/duration, 0.0f,1.0f);


            return startPos.lerp(goalPos, -2 * alpha*alpha*alpha + 3 * alpha*alpha);
        }

    }

在此版本中,我更改线性插值以使用此曲线:

f(x) = -2*alpha^3 + 3*alpha^2

http://www.wolframalpha.com/input/?i=plot+f%28x%29+%3D+-2x%5E3+%2B3x%5E2+from+0+to+1

关于java - 将 Vector3 缓动到新位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22892251/

相关文章:

php - 无法解析主机名(即使添加 INTERNET 权限后)

c++ Vector push_back移动新元素

java - 控制台应用程序中基于选项卡的自动完成

java - Spring @Async 与可完成的 future 运行异步

java - 当我能够通过 FileZilla 连接时,我无法从 SFTP 文件源中提取文件

android - 使用 gradle 导入 ShowcaseView

java - libGDX 动画纹理区域

python - 3D矢量的旋转?

c++ - 错误 : expected primary-expression before 'float'

java - EMMA 代码覆盖率报告使用的颜色图例