Java中如何计算两点之间的距离
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26576000/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to calculate distance between two points in Java
提问by oscar toco
Hi I am really new to Java. I really don't have an idea on what I can do to make this code work at all.
嗨,我对 Java 真的很陌生。我真的不知道我可以做些什么来使这段代码正常工作。
public class Distance
{ private int xOne,yOne,xTwo,yTwo;
private double distance;
public Distance()
{
}
public Distance(int x1, int y1, int x2, int y2)
{ x1=xOne;
x2=xTwo;
y1=yOne;
y2=yTwo;
}
public void setCoordinates(int x1, int y1, int x2, int y2)
{
xOne=4;
yOne=3;
xTwo=6;
yTwo=56;
}
public void calcDistance()
{
Math.sqrt((xTwo-xOne)*(xTwo-xOne)+(yTwo-yOne)*(yTwo-yOne));
}
public void print( )
{
out.println("x1:");
out.println("y1:");
out.println("x2:");
out.println("y2:");
out.println(distance);
}
}
采纳答案by Boann
The entire Distance
class could be reduced to a single method. But I guess this is a learning exercise so I'll try and help you step-by-step with everything I can:
整个Distance
类可以简化为一个方法。但我想这是一个学习练习,所以我会尽力帮助你一步一步地做我能做的:
All of your
int
variables for the points would be more useful if they weredouble
s. Then you can use fractional positions and a greater range of distances.These variables:
private int xOne,yOne,xTwo,yTwo;
would be better namedx1, y1, x2, y2
.Your
setCoordinates
method is currently ignoring the arguments and assigning hard-coded values, for testing I suppose. Anyway, assuming you fix that and you change the field names as I suggested, you'll need to distinguish between the local variable and the field of the same name, which you can do by qualifying access to the field with the prefixthis.
, so you get:public void setCoordinates(double x1, double y1, double x2, double y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; }
This constructor isn't doing anything since the assignments are backwards:
public Distance(int x1, int y1, int x2, int y2) { x1=xOne; x2=xTwo; y1=yOne; y2=yTwo; }
Should be:
xOne=x1;
and so on.
However, you already have a
setCoordinates
method to do the same thing, so it makes sense to call that instead of repeating yourself:public Distance(double x1, double y1, double x2, double y2) { setCoordinates(x1, y1, x2, y2); }
The
calcDistance
method doesn't currently work because after calculating the answer, it doesn't assign it to thedistance
variable, or do anything else with it. The assignment should be:public void calcDistance() { distance = Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); }
A dedicated function,
Math.hypot
exists, which calculates√(x2 + y2)
. Using that simplifies things:public void calcDistance() { distance = Math.hypot(x2 - x1, y2 - y1); }
Next, consider when you would actually call the
calcDistance
method... It would always be after setting the coordinates, right? So why not subsume the math intosetCoordinates
, and remove thecalcDistance
method entirely, to simplify use of the class:public void setCoordinates(double x1, double y1, double x2, double y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; this.distance = Math.hypot(x2 - x1, y2 - y1); }
Examining your
print
method, the statements to print the coordinates don't actually do so:out.println("x1:");
should be:
out.println("x1:" + x1);
Using
out.println(...);
is legal, assuming that at the top of the file you've a declarationimport static java.lang.System.out;
, but it is non-standard. Consider changing that toSystem.out.println(...);
.Finally, reconsider the entire
Distance
class. It's supposed to calculate distances between points but most of the methods are devoted to getting the coordinates into it and getting the result out of it. You've provided two different ways of getting the coordinates into it: either using the the no-args constructor followed bysetCoordinates
, or using the 4-args constructor.You've provided one way of getting the result out, the
print
method, but it's usefulness is limited. It's not very generalbecause it allows output only to the console (useless in a GUI app) and only in a fixed format. You could add agetDistance
method (or make thedistance
fieldpublic
) to increase its usefulness, but let's see what that would look like.Imagine that typical use of the class always looks like this:
/* ... get x1,y1,x2,y2 ... */ Distance distance = new Distance(); distance.setCoordinates(x1, y1, x2, y2); double result = distance.getDistance(); /* ... do something with the result ... */
It turns out that
Distance
is just a glorified function. So let's turn it into a real function that returns the result directly:static double calcDistance(double x1, double y1, double x2, double y2) { return Math.hypot(x2 - x1, y2 - y1); }
(It's
static
because it no longer requires an instance of a class to be created.) This method is now so small and portable it could be placed in any class, and doesn't need the dedicatedDistance
class. You could place it in a class calledMathUtils
, for example, along with other useful bits and pieces. Anyway, using it is now simpler:/* ... get x1,y1,x2,y2 ... */ double distance = MathUtils.calcDistance(x1, y1, x2, y2); /* ... do something with the result ... */
What about printing the output? Well, printing, in that particular format, was not part of the generalusefulness of the function. If you only need to do it once, that's something that can be done in the caller. If you need to calc and print distances in that format from several places in the code, that's a candidate for a method, but not the same method, because it's better to keep
calcDistance
itself general. Something like this would do:static void printDistance(double x1, double y1, double x2, double y2) { System.out.println("x1:" + x1); System.out.println("y1:" + y1); System.out.println("x2:" + x2); System.out.println("y2:" + y2); System.out.println("distance:" + calcDistance(x1, y1, x2, y2)); }
int
如果这些点的所有变量都是double
s,它们会更有用。然后您可以使用分数位置和更大范围的距离。这些变量:
private int xOne,yOne,xTwo,yTwo;
最好命名为x1, y1, x2, y2
.您的
setCoordinates
方法目前正在忽略参数并分配硬编码值,以进行测试。无论如何,假设您修复了该问题并按照我的建议更改了字段名称,您需要区分局部变量和同名字段,您可以通过使用前缀限定对字段的访问来做到这一点this.
,因此您得到:public void setCoordinates(double x1, double y1, double x2, double y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; }
这个构造函数没有做任何事情,因为赋值是向后的:
public Distance(int x1, int y1, int x2, int y2) { x1=xOne; x2=xTwo; y1=yOne; y2=yTwo; }
应该:
xOne=x1;
等等。
但是,您已经有一个
setCoordinates
方法可以做同样的事情,所以调用它而不是重复自己是有意义的:public Distance(double x1, double y1, double x2, double y2) { setCoordinates(x1, y1, x2, y2); }
该
calcDistance
方法当前不起作用,因为在计算答案后,它不会将其分配给distance
变量,也不会对其执行任何其他操作。任务应该是:public void calcDistance() { distance = Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); }
Math.hypot
存在一个专用函数,用于计算√(x2 + y2)
。使用它可以简化事情:public void calcDistance() { distance = Math.hypot(x2 - x1, y2 - y1); }
接下来,考虑何时实际调用该
calcDistance
方法......它总是在设置坐标之后,对吧?那么为什么不将数学归入setCoordinates
,并calcDistance
完全删除该方法,以简化该类的使用:public void setCoordinates(double x1, double y1, double x2, double y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; this.distance = Math.hypot(x2 - x1, y2 - y1); }
检查您的
print
方法,打印坐标的语句实际上并没有这样做:out.println("x1:");
应该:
out.println("x1:" + x1);
Using
out.println(...);
是合法的,假设在文件的顶部你有一个 declarationimport static java.lang.System.out;
,但它是非标准的。考虑将其更改为System.out.println(...);
.最后,重新考虑整个
Distance
班级。它应该计算点之间的距离,但大多数方法都致力于将坐标输入其中并从中获取结果。您提供了两种不同的获取坐标的方法:使用后跟 的无参数构造函数setCoordinates
,或使用 4-args 构造函数。您提供了一种获取结果的
print
方法,即方法,但它的用处是有限的。它不是很通用,因为它只允许输出到控制台(在 GUI 应用程序中无用)并且只允许以固定格式输出。您可以添加一个getDistance
方法(或创建distance
fieldpublic
)以增加其实用性,但让我们看看它会是什么样子。想象一下,类的典型用法总是如下所示:
/* ... get x1,y1,x2,y2 ... */ Distance distance = new Distance(); distance.setCoordinates(x1, y1, x2, y2); double result = distance.getDistance(); /* ... do something with the result ... */
事实证明,这
Distance
只是一个美化的功能。所以我们把它变成一个真正的函数,直接返回结果:static double calcDistance(double x1, double y1, double x2, double y2) { return Math.hypot(x2 - x1, y2 - y1); }
(这是
static
因为它不再需要创建类的实例。)此方法现在非常小且可移植,可以放置在任何类中,并且不需要专用Distance
类。MathUtils
例如,您可以将它与其他有用的零碎部分放在一个名为 的类中。无论如何,现在使用它更简单:/* ... get x1,y1,x2,y2 ... */ double distance = MathUtils.calcDistance(x1, y1, x2, y2); /* ... do something with the result ... */
打印输出怎么样?好吧,以这种特定格式进行打印并不是该功能的一般用途的一部分。如果你只需要做一次,那可以在调用者中完成。如果您需要从代码中的多个位置以该格式计算和打印距离,这是一种方法的候选者,但不是相同的方法,因为最好保持
calcDistance
其通用性。像这样的事情会做:static void printDistance(double x1, double y1, double x2, double y2) { System.out.println("x1:" + x1); System.out.println("y1:" + y1); System.out.println("x2:" + x2); System.out.println("y2:" + y2); System.out.println("distance:" + calcDistance(x1, y1, x2, y2)); }
Anyway, I hope this solves your problem. Feel free to use any/all parts of this answer, as you see fit.
无论如何,我希望这可以解决您的问题。随意使用此答案的任何/所有部分,只要您认为合适。
回答by Mark Jeronimus
You forgot to set the distance variable with the result
你忘了用结果设置距离变量
distance = Math.sqrt((xTwo-xOne)*(xTwo-xOne)+(yTwo-yOne)*(yTwo-yOne));
回答by Visruth
You should change Math.sqrt((xTwo-xOne)*(xTwo-xOne)+(yTwo-yOne)*(yTwo-yOne));
with distance = Math.sqrt( (x1-x2)^2 + (y1-y2)^2 );
.
And,
你应该Math.sqrt((xTwo-xOne)*(xTwo-xOne)+(yTwo-yOne)*(yTwo-yOne));
用distance = Math.sqrt( (x1-x2)^2 + (y1-y2)^2 );
. 和,
out.println("x1:");
out.println("y1:");
out.println("x2:");
out.println("y2:");
out.println(distance);
with
和
System.out.println("x1 : " + x1);
System.out.println("y1 : " + y1);
System.out.println("x2 : " + x2);
System.out.println("y2 : " + y2);
System.out.println("distance : " + distance);
You may refer this websiteto learn java basics.
你可以参考这个网站来学习java基础知识。
回答by DanSchneiderNA
There are a couple of things wrong, to be honest.
老实说,有几件事是错误的。
- You are not assigning the global variables to the local ones properly in
Distance
constructor. - Your
setCoordinates
method is useless since you are not using the parameters at all. - You are not assigning
Math.sqrt()
to a value - You need to put
System.out.println()
rather than justprintln()
- 您没有在
Distance
构造函数中正确地将全局变量分配给本地变量。 - 您的
setCoordinates
方法毫无用处,因为您根本没有使用参数。 - 您没有分配
Math.sqrt()
给一个值 - 你需要把
System.out.println()
而不仅仅是println()