Java 角度约束不';我不能从某些角度工作

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

我正在为我的2d物理引擎写一个角度接头。除“最大角度”为负值,“最小角度”为正值(当角度直接向左时)外,它可以工作

如您所见,所有其他球都在其公差角度内移动,但直接向左移动的球则不在公差角度内

公共类角关节延伸关节{
私人浮动米南格尔;
私有浮动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);
    }

}