Java 角度约束不';我不能从某些角度工作
我正在为我的2d物理引擎写一个角度接头。除“最大角度”为负值,“最小角度”为正值(当角度直接向左时)外,它可以工作 如您所见,所有其他球都在其公差角度内移动,但直接向左移动的球则不在公差角度内Java 角度约束不';我不能从某些角度工作,java,math,2d,physics,game-physics,Java,Math,2d,Physics,Game Physics,我正在为我的2d物理引擎写一个角度接头。除“最大角度”为负值,“最小角度”为正值(当角度直接向左时)外,它可以工作 如您所见,所有其他球都在其公差角度内移动,但直接向左移动的球则不在公差角度内 公共类角关节延伸关节{ 私人浮动米南格尔; 私有浮动maxAngle; 公共角接头( 最终游戏实体a, 最终游戏实体b, 最终浮动中间角, 最终浮动公差 ) { 超级(a,b); 断言容差>=0; minAngle=midAngle-公差; 最大角度=中间角度+公差; while(minAngle>Ma
公共类角关节延伸关节{
私人浮动米南格尔;
私有浮动maxAngle;
公共角接头(
最终游戏实体a,
最终游戏实体b,
最终浮动中间角,
最终浮动公差
) {
超级(a,b);
断言容差>=0;
minAngle=midAngle-公差;
最大角度=中间角度+公差;
while(minAngle>Math.PI){
minAngle-=2*Math.PI;
}
while(minAngle<-Math.PI){
minAngle+=2*Math.PI;
}
while(maxangel>Math.PI){
maxAngle-=2*Math.PI;
}
while(maxangel<-Math.PI){
maxAngle+=2*Math.PI;
}
System.out.println(minAngle+,“+maxangel);
}
@凌驾
公共无效更新(){
断言getA()!=null&&getB()!=null;
最终CManifold m=新CManifold();
m、 a=getA();
m、 b=getB();
final Vec2D aToB=getB().center().减号(getA().center());
//从A到B的角度
最终浮动角度=aToB.getTheta();
如果(角度>=minAngle&&angle这部分代码:
if (angle >= minAngle && angle <= maxAngle) {
// we don't need to do anything
return;
}
if(angle>=minAngle&&angle我通过首先执行一个建议的检查来解决这个问题,但也改变了一点数学。这是完成的关节类
public class AngleJoint extends Joint {
// angles stored between -Pi and Pi
private final float minAngle;
private final float maxAngle;
/**
*
* @param a
* @param b
* @param midAngle
* the angle in the range of -Pi to Pi.
* @param tolerance
* the angle tolerance in both directions. 0 <= tolerance < Pi
*/
public AngleJoint(final GameEntity a, final GameEntity b, final float midAngle, final float tolerance) {
super(a, b);
if (tolerance < 0 || tolerance >= AngleUtils.PI) {
throw new IllegalArgumentException("Tolerance must be >= 0 and < Pi");
}
minAngle = AngleUtils.normalize(midAngle - tolerance);
maxAngle = AngleUtils.normalize(midAngle + tolerance);
}
@Override
public void update() {
assert getA() != null && getB() != null;
final CManifold m = new CManifold();
m.a = getA();
m.b = getB();
final Vec2D aToB = getB().center().minus(getA().center());
// angle from A to B
final float angle = aToB.getTheta();
if (angle >= minAngle && angle <= maxAngle) {
// we don't need to do anything
return;
}
// if we are in that dumb spot where maxAngle < min Angle (directly to the left) we need extra checks
if (maxAngle < minAngle && (angle <= maxAngle && angle >= -AngleUtils.PI || angle >= minAngle && angle <= AngleUtils.PI)) {
return;
}
final float distBtoA = aToB.length();
final float closestAngleBound = AngleUtils.angleDifference(angle, maxAngle) < AngleUtils.angleDifference(angle, minAngle) ? maxAngle
: minAngle;
// where we should be
final Vec2D solvedLocation = getA().center().plus(
new Vec2D((float) (Math.cos(closestAngleBound) * distBtoA), (float) (Math.sin(closestAngleBound) * distBtoA)));
final Vec2D correction = solvedLocation.minus(getB().center());
final float d = correction.length();
m.setNormal(correction.divide(d));
m.setPenetration(d);
Collisions.fixCollision(m, false);
}
}
公共类角关节延伸关节{
//存储在-Pi和Pi之间的角度
私人最终浮动米南格尔;
私人最终浮动最大角度;
/**
*
*@param a
*@param b
*@param midAngle
*在-Pi到Pi范围内的角度。
*@param公差
*两个方向上的角度公差(0=AngleUtils.PI){
抛出新的IllegalArgumentException(“公差必须大于等于0且小于Pi”);
}
minAngle=角度规格化(midAngle-公差);
maxAngle=AngleUtils.normalize(中间角+公差);
}
@凌驾
公共无效更新(){
断言getA()!=null&&getB()!=null;
最终CManifold m=新CManifold();
m、 a=getA();
m、 b=getB();
final Vec2D aToB=getB().center().减号(getA().center());
//从A到B的角度
最终浮动角度=aToB.getTheta();
如果(angle>=minAngle&&angle@durron597是的,我刚刚提交了。我已经放弃了尝试解决这个问题。很难弄清楚发生了什么事情;您的类耦合太紧密,方法太长。我建议阅读并学习如何使用JUnit和Mockito。我感谢您的回复,我确实需要像您一样实现一个检查暗示
if (angle >= minAngle && angle <= maxAngle) {
// we don't need to do anything
return;
}
public class AngleJoint extends Joint {
// angles stored between -Pi and Pi
private final float minAngle;
private final float maxAngle;
/**
*
* @param a
* @param b
* @param midAngle
* the angle in the range of -Pi to Pi.
* @param tolerance
* the angle tolerance in both directions. 0 <= tolerance < Pi
*/
public AngleJoint(final GameEntity a, final GameEntity b, final float midAngle, final float tolerance) {
super(a, b);
if (tolerance < 0 || tolerance >= AngleUtils.PI) {
throw new IllegalArgumentException("Tolerance must be >= 0 and < Pi");
}
minAngle = AngleUtils.normalize(midAngle - tolerance);
maxAngle = AngleUtils.normalize(midAngle + tolerance);
}
@Override
public void update() {
assert getA() != null && getB() != null;
final CManifold m = new CManifold();
m.a = getA();
m.b = getB();
final Vec2D aToB = getB().center().minus(getA().center());
// angle from A to B
final float angle = aToB.getTheta();
if (angle >= minAngle && angle <= maxAngle) {
// we don't need to do anything
return;
}
// if we are in that dumb spot where maxAngle < min Angle (directly to the left) we need extra checks
if (maxAngle < minAngle && (angle <= maxAngle && angle >= -AngleUtils.PI || angle >= minAngle && angle <= AngleUtils.PI)) {
return;
}
final float distBtoA = aToB.length();
final float closestAngleBound = AngleUtils.angleDifference(angle, maxAngle) < AngleUtils.angleDifference(angle, minAngle) ? maxAngle
: minAngle;
// where we should be
final Vec2D solvedLocation = getA().center().plus(
new Vec2D((float) (Math.cos(closestAngleBound) * distBtoA), (float) (Math.sin(closestAngleBound) * distBtoA)));
final Vec2D correction = solvedLocation.minus(getB().center());
final float d = correction.length();
m.setNormal(correction.divide(d));
m.setPenetration(d);
Collisions.fixCollision(m, false);
}
}