gpt4 book ai didi

java - 基于速度的平滑运动和可预测的持续时间

转载 作者:行者123 更新时间:2023-12-01 11:46:38 39 4
gpt4 key购买 nike

有人有一个好的算法,可以用任何语言从 2D 点 a -> b 获得平滑但可预测的运动吗?

我需要一个函数来设置每一帧的速度:

function GetVel(current_pos : Vector2, dest_pos : Vector2, current_vel : Vector2)
{
var new_vel : Vector2d;
.......
return new_vel;
}

以及相应的:

function GetDestTime(current_pos : Vector2, dest_pos : Vector2, current_vel : Vector2 )
{
var duration : float;
.......
return duration;
}

仅使用加速度会导致大量滑动,因此我需要一些可以预测确切目标时间的良好 smoothDamp 算法。

有什么想法吗?

最佳答案

假设 v(0) = 0 且 v(T) = 0,并且 v(t) 是一个二次函数,其最大值在 t = T/2 处。

因此,我们可以采用以下形式,

由于该点在 T 秒内移动 L,因此将 v(t) 从 0 到 T 积分必须得到 L。因此,我们可以得到另一个方程,

求解这些方程可得出,

使用 a 和 b,您可以计算当前速度。

它相当长,但我做了一个Java玩具来实现这一点。请检查一下!

import java.awt.*;
import javax.swing.*;

public class MovePoint extends Canvas implements Runnable {
public static void main(String... args) {
Thread thread = new Thread(new MovePoint());
thread.start();
}

private static final int WIDTH = 500;
private static final int HEIGHT = 500;

public MovePoint() {
super();
this.setBackground(Color.WHITE);
this.setForeground(Color.BLACK);
this.setSize(WIDTH, HEIGHT);

JFrame f = new JFrame("Move Point");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setVisible(true);
}

private Point V;
private Point S = new Point(50, 50);
private Point E = new Point(450, 450);
private double duration = 5.0;
private double dt = 0.03;
private Image buffer;
private Graphics gBuf;

public void run() {
double t = 0.0;
V = S.copy();
while (t < duration) {
V = Point.add(V, calcVelocity(V, S, E, t, duration).scale(dt));
t += dt;
repaint();
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.exit(0);
}

public void paint(Graphics g) {
if (gBuf == null) {
buffer = createImage(WIDTH, HEIGHT);
gBuf = buffer.getGraphics();
}
gBuf.setColor(Color.WHITE);
gBuf.fillRect(0, 0, WIDTH, HEIGHT);
gBuf.setColor(Color.BLACK);
gBuf.fillOval((int)(V.x - 5), (int)(V.y - 5), 11, 11);
g.drawImage(buffer, 0, 0, this);
}

public void update(Graphics g) {
paint(g);
}

public Point calcVelocity(Point current, Point start, Point goal, double t, double T) {
double L = Point.distance(start, goal);
double a = -6.0 / (T * T * T);
double b = 3.0 / (2.0 * T);

double s = (t - 0.5 * T);
double v = a * s * s + b;
return Point.subtract(goal, start).scale(v);
}
}

class Point {
public double x;
public double y;

public Point(double x, double y) {
this.x = x;
this.y = y;
}

public Point copy() {
return new Point(x, y);
}

public static double distance(Point p, Point q) {
double dx = p.x - q.x;
double dy = p.y - q.y;
return Math.sqrt(dx * dx + dy * dy);
}

public static Point add(Point p, Point q) {
return new Point(p.x + q.x, p.y + q.y);
}

public static Point subtract(Point p, Point q) {
return new Point(p.x - q.x, p.y - q.y);
}

public Point scale(double s) {
return new Point(x * s, y * s);
}
}

关于java - 基于速度的平滑运动和可预测的持续时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29089551/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com