Java distance()方法是否按其应该的方式编写
关于下面的代码,我可以为Java distance()方法是否按其应该的方式编写,java,oop,Java,Oop,关于下面的代码,我可以为distance()方法做得更好吗? 感觉这种方法不完全是面向对象的。。如何更改代码以使其更好地用于此操作 谢谢 public class Line extends Shape { private Point lineP1; private Point lineP2; public Line(int x1, int x2, int y1, int y2, Color myColor) { super(x1, x2, y1, y
distance()
方法做得更好吗?
感觉这种方法不完全是面向对象的。。如何更改代码以使其更好地用于此操作
谢谢
public class Line extends Shape {
private Point lineP1;
private Point lineP2;
public Line(int x1, int x2, int y1, int y2, Color myColor) {
super(x1, x2, y1, y2, myColor);
lineP1 = new Point(this.getX1(),this.getY1());
lineP2 = new Point(this.getX2(),this.getY2());
}
@Override
public void draw(Graphics g) {
g.drawLine(this.getX1(), this.getY1(), this.getX2(), this.getY2());
g.setColor(Color.GREEN);
}
@Override
public boolean contains(Point p) {
if((this.distance(lineP1, p)+this.distance(lineP2, p)) == this.distance(lineP1, lineP2))
return true;
return false;
}
/**@return distance between two given points
* This method return the distance between two given points*/
private double distance(Point p1,Point p2 ){
return Math.sqrt(Math.pow((p1.getX()-p2.getX()), 2) + Math.pow((p1.getY()-p2.getY()), 2));
}
}//class Line
您的距离方法似乎还可以(但如果您保存变量之间的差异,并使用
*
运算符将这些值与自身相乘,而不是使用Math.pow
,则性能会更好)
然而,由于浮点计算往往返回不精确的结果,我不建议使用端点节点和要测试的点之间的距离之和作为标准
但是,还有另一种确定点是否靠近直线的好方法:使用。它的工作原理如下:
设P1
和P2
为对应于端点的向量*
表示标量乘法,而|
表示向量的长度:
D = (P2 - P1) / |P2 - P1|;
设N
为坐标互换后的向量D
,新的x坐标乘以-1
(即向量或与D正交)
然后,点H
到直线的距离可以这样确定
| N * H - N * P1 |
此外,如果H
介于P1
和P2
之间,也可以这样检查(假设不丧失一般性D*P1
):
这不清楚。“完全OOP”是什么意思?重命名为
OOP\u distance
应该做一个旁注:a*a
通常比Math.pow(a,2)
好。此外,由于不需要计算实际距离,因此可以删除Math.sqrt()
调用as wellTW:如果点在直线上,有一种更好的检查方法:计算距离足够简单;将二维矢量旋转90°意味着必须交换坐标,并将其中一个坐标乘以-1
。要点是:使用Hesse法线形式,您可以通过2次乘法和1次加法+1次减法(假设您准备了法线)轻松计算到直线的距离。(如果要确保点位于直线的端点之间,必须执行两次)。它还允许您以更好的方式允许小错误。(使用double
s可能无法获得精确值)
D * P1 <= D * H <= D * P2
// components of normal vector
private double normalX;
private double normalY;
// components of direction vector
private double directionX;
private double directionY;
// the value of (N * P) for all points P on the line
private double normalScalarProduct;
// the range allowed for (D * P) for points on the line
private double minDirectionScalarProduct;
private double maxDirectionScalarProduct;
// error ranges; adjust as appropriate
private static final double directionAllowedError = 0.1;
private static final double normalAllowedError = 0.1;
public Line(int x1, int x2, int y1, int y2, Color myColor) {
...
double dx = x2 - x1;
double dy = y2 - y1;
double length = distance(dx, dy);
if (length == 0) {
// choose arbitrary direction, if length == 0
length = 1;
dx = 1;
}
// normalize direction
dx /= length;
dy /= length;
// set D and N values
this.directionX = dx;
this.directionY = dy;
this.normalX = -dy;
this.normalY = dx;
double prod1 = scalarProduct(directionX, directionY, x1, y1);
double prod2 = scalarProduct(directionX, directionY, x2, y2);
if (prod1 < prod2) {
minDirectionScalarProduct = prod1 - directionAllowedError;
maxDirectionScalarProduct = prod2 + directionAllowedError;
} else {
minDirectionScalarProduct = prod2 - directionAllowedError;
maxDirectionScalarProduct = prod1 + directionAllowedError;
}
normalScalarProduct = scalarProduct(x1, y1, normalX, normalY);
}
private static double scalarProduct(double x1, double y1, double x2, double y2) {
return x1*x2 + y1*y2;
}
public boolean contains(Point p) {
if (Math.abs(scalarProduct(p.getX(), p.getX(), normalX, normalY) - normalScalarProduct) <= normalAllowedError) {
// close enough to the line -> check, if between end points
double d = scalarProduct(p.getX(), p.getX(), directionX, directionY);
return minDirectionScalarProduct <= d && d <= maxDirectionScalarProduct;
}
return false;
}
private double distance(double dx, double dy) {
return Math.sqrt(dx*dx + dy*dy);
}