我正在使用Java编写植绒算法,但我陷入某种困境(使用Ardor3D库,在2D平面上)。
基本上,我需要找到要添加到当前旋转的角度差。如果你只能得到它应该用极坐标指向的方式,北方的0度而不是差异,不用担心 - 我有一种方法,它返回角度差,同时考虑角度和负角度的环绕。
目前,我有以下代码,由于算法没有引用初始轮换,因此显然无效:
long tpf = currUpdateTimeMS - lastUpdateTimeMS;
Vector2 pos = new Vector2();
rt.getPosition(pos);
double rot = pos.angleBetween(app.getAvgBoidPos(new Vector2()).normalizeLocal());
rt.setRotation(rot);
pos.addLocal(
Math.cos((rot - MathUtils.HALF_PI)) * (tpf / 10f),
Math.sin((rot - MathUtils.HALF_PI)) * (tpf / 10f)
);
rt.setPosition(pos);
super.updateLogic();
更新了代码(从第一个回答开始不起作用):
long tpf = currUpdateTimeMS - lastUpdateTimeMS;
//rt.setRotation(rt.getRotation() + ((tpf / (ROT_SPEED / 2f)) % 360));
Vector2 avgpos = app.getAvgBoidPos(new Vector2());
Vector2 pos = rt.getPosition(new Vector2());
avgpos.subtractLocal(pos);
double angleRads = rt.getRotation() * FastMath.DEG_TO_RAD;
double rot = MathUtils.acos((
(avgpos.getX() * MathUtils.sin(angleRads)
) +
(avgpos.getY() * MathUtils.cos(angleRads)
)) / ((Math.pow(avgpos.getX(), 2) + Math.pow(avgpos.getY(), 2)) * 0.5));
double adegdiff = rot * FastMath.RAD_TO_DEG;
rt.setRotation(rt.getRotation() - adegdiff);
double newrot = rt.getRotation();
pos.addLocal(
Math.cos((newrot - MathUtils.HALF_PI)) * (tpf / 10f),
Math.sin((newrot - MathUtils.HALF_PI)) * (tpf / 10f)
);
rt.setPosition(pos);
super.updateLogic();
基于另一个答案的另一个修改:
long tpf = currUpdateTimeMS - lastUpdateTimeMS;
//rt.setRotation(rt.getRotation() + ((tpf / (ROT_SPEED / 2f)) % 360));
Vector2 avgpos = app.getAvgBoidPos(new Vector2());
Vector2 pos = rt.getPosition(new Vector2());
avgpos.subtractLocal(pos);
double rot = pos.angleBetween(
app.getAvgBoidPos(new Vector2()).normalizeLocal()
) - (rt.getRotation() * MathUtils.DEG_TO_RAD);
rt.setRotation(rt.getRotation() - (rot * MathUtils.RAD_TO_DEG));
double newrot = rt.getRotation();
pos.addLocal(
Math.cos((newrot - MathUtils.HALF_PI)) * (tpf / 10f),
Math.sin((newrot - MathUtils.HALF_PI)) * (tpf / 10f)
);
rt.setPosition(pos);
super.updateLogic();
我不太擅长数学问题,所以代码会有用而不是公式:)
输入
输出
如果您能提供帮助,请提前致谢:)
克里斯
答案 0 :(得分:2)
您可以使用点积来确定当前方向与您想要面对的点之间的角度余弦(以弧度表示)。假设进行观察的代理位于原点并且定向成面向由相对于Y轴的角度θ给出的某个方向(即0度是“向上”或“向北”)。您想要找到该方向与面向点(x,y)之间的角度差θ'。这是由:
θ' = cos-1[(x*sin(θ) + y*cos(θ)) / sqrt(x2 + y2)]
从θ减去θ'将使药剂朝向目标。
如果代理人不在原点,只需从要查看的对象中减去代理商的位置,即可将其带入上述表格。
答案 1 :(得分:1)
稍微偏离主题,但你可能会发现我们的效果包(ardor3d-effects)中的粒子群和漫游代码也很有趣。
它们可以在ardor svn中找到,或者在这里:
答案 2 :(得分:0)
以下是关于如何在具有共同原点的两个向量之间找到角度的实现。根据那里描述的算法,这已被黑客攻击: http://www.wikihow.com/Find-the-Angle-Between-Two-Vectors
public class DeltaDoodle {
private double delta(ColumnVector v1,ColumnVector v2) throws Exception{
double sp=scalarProduct(v1,v2);
double magV1=magnitude(v1);
double magV2=magnitude(v2);
return Math.acos(sp/(magV1*magV2)) * (180/Math.PI);
}
private double scalarProduct(ColumnVector a, ColumnVector b) {
return (a.x*b.x) + (a.y*b.y);
}
private double magnitude(ColumnVector a){
return Math.sqrt((a.x*a.x) + (a.y*a.y));
}
public static void main(String[] args) {
DeltaDoodle v=new DeltaDoodle();
try {
System.out.println("angle: " + v.delta(new ColumnVector(5, 5), new ColumnVector(1,1)));
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class ColumnVector {
public final double x, y;
public ColumnVector(double x1, double x2) {
this.x = x1;
this.y = x2;
}
}
希望有所帮助...
答案 3 :(得分:0)
如果我正确理解这些功能,这可能会起作用:
Vector2 pos = new Vector2();
rt.getPosition(pos);
double rot = pos.angleBetween(app.getAvgBoidPos(new Vector2()).normalizeLocal()) - rt.getRotation();
P.S。忘记提及:这个rot
旨在成为角度差异。通过这么多旋转实体,它应该指向目标。
修改:
谢谢,代码确实有帮助(我误解了angleBetween
)。让我再试一次:
这是从实体到点的向量(请原谅我,如果我的语法错误,我不知道java):
Vector2 pos = new Vector2();
rt.getPosition(pos);
Vector2 direction = app.getAvgBoidPos(new Vector2());
direction.subtractLocal(pos);
现在我们将其标准化以获得指向该点的单位向量,并采用角度差:
double rot = rt.getRotation().angleBetween(direction.normalizeLocal())