Java赋值 - 从我的计算中得到一些奇怪的值

时间:2015-04-19 04:26:23

标签: java methods return coordinates trigonometry

我现在正在学习Java,我的一项任务让我非常难过。我被要求创建一个类,它在笛卡尔平面的第一象限中指定一个坐标,并且只使用两个值:从所述点到原点的距离(0,0)以及矢量绘制到的那个角度。 X轴。到目前为止,该程序看起来像这样:

public class Point2 {
    private double _radius;
    private double _alpha;

    public Point2 (int x, int y) {
        this._radius = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
        this._alpha = Math.toDegrees(Math.atan2(y, x));
    }

    public Point2 (Point2 other) {
        this._radius = other._radius;
        this._alpha = other._alpha;
    }

    public int getX() {
        return (int)(this._radius * Math.cos(Math.toRadians(this._alpha)));
    }

    public int getY() {
        return (int)(this._radius * Math.sin(Math.toRadians(this._alpha)));
    }

    public void setX(int x) {
        if(x > 0) {
            this._radius = Math.sqrt(Math.pow(x, 2) + Math.pow(this.getY(), 2));
            this._alpha = Math.toDegrees(Math.atan2(this.getY(), x));
        }
    }

    public void setY(int y) {
        if(y > 0) {
            this._radius = Math.sqrt(Math.pow(this.getX(), 2) + Math.pow(y, 2));
            this._alpha = Math.toDegrees(Math.atan2(y, this.getX()));
        }
    }

    public boolean equals(Point2 other) {
        if(this._radius == other._radius && this._alpha == this._radius) {
            return true;
        } else {
            return false;
        }
    }

    public boolean isAbove(Point2 other) {
        if(this.getY() > other.getY()) {
            return true;
        } else {
            return false;
        }
    }

    public boolean isUnder(Point2 other) {
        if(this.getY() < other.getY()) {
            return true;
        } else {
            return false;
        }
    }

    public boolean isLeft(Point2 other) {
        if(this.getX() < other.getX()) {
            return true;
        } else {
            return false;
        }
    }

    public boolean isRight(Point2 other) {
        if(this.getX() > other.getX()) {
            return true;
        } else {
            return false;
        }
    }

    double distance(Point2 other) {
        double dist = Math.sqrt(Math.pow(this.getX() - other.getX(), 2) + Math.pow(this.getY() - other.getY(), 2));

        return dist;
    }

    public void move(int dX, int dY) {
        if(this.getX() + dX > 0 && this.getY() + dY > 0) {
            this._radius = Math.sqrt(Math.pow(this.getX() + dX, 2) + Math.pow(this.getY() + dY, 2));
            this._alpha = Math.toDegrees(Math.atan2(this.getY() + dY, this.getX() + dX));
        }
    }

    public String toString() {
        return "(" + _radius + "," + _alpha + ")";
    }
}

无论如何,当我创建这个类的实例时会发生什么,给定x和y坐标,这确实没问题 - 计算正确,一切都很好。问题是当我尝试使用任何改变X或Y坐标的方法时。

例如,我将运行setX(10),当我运行getX()时,我会获得9,但是当我再次运行setX(10)然后重新运行get(X)时我会得到10.同样适用于move() - 调用方法一次会为getX()getY()返回一个不准确的结果,但调用具有相同参数的方法一次或两次将会纠正结果。

这很奇怪 - 几乎就像这里的计算不正确或者存在舍入问题。任何人都有线索?

1 个答案:

答案 0 :(得分:1)

你肯定遇到了舍入错误。解决这个问题的第一种方法是直接存储x和y。通常存储计算数据是个坏主意。但是,我认为这是不可能的。

你遇到两个问题。

在此代码中:

this._radius = Math.sqrt(Math.pow(x, 2) + Math.pow(this.getY(), 2));
this._alpha = Math.toDegrees(Math.atan2(this.getY(), x));

请注意,this.getY()取决于radius和alpha。在第一次调用中更改半径时,从getY获得的值在第二次调用中会有所不同!您想要缓存从getY返回的值:

int y = this.getY();
this._radius = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
this._alpha = Math.toDegrees(Math.atan2(y, x));

在setY中发现同样的问题,getX改变了中间功能。

你得到的另一个问题是由于在getX / getY中将double转换为整数。 Java通过截断来实现此目的:(int) 4.99999999将成为4。使用(int) Math.round(...)可能会获得更好的结果(如果你传递一个double,Math.round()会返回一个long)。

总结

  • 如果可能,请将代码更改为直接存储x和y,您可以根据这些值计算角度和半径。
  • 考虑x和y可能是非整数。你为什么要把它们限制为整数?
  • 请注意,在您修改对象时,对象的状态可能不一致,例如:当您仅根据新的x值修改半径时,getY不安全。