Java 计算坐标点距离,平行线交点算法详解

1. 前言主要记录一些关于坐标和线段的计算方法 。因为经常会碰见,需要在平面上,计算坐标点 。
例如两个坐标点之间的距离,两个线段是否平行,两个不相交的线段的交点 。
由于程序中的坐标原点,都是左上角开始的 。所以很少涉及象限的问题 。以下的一些算法,不会强调象限问题 。
这里,主要介绍如何使用勾股定理计算坐标距离,斜率计算线段交点等 。
2. 根据两个坐标点,计算距离平面中,两点之间,直线最短 。而在已知两个坐标点的x轴和y轴的情况下 。我们可以通过勾股定理,来计算两个坐标点的距离 。
因为,两个坐标点之间x轴的距离和y轴的距离可以看做三角形的两条直角边 。斜边就是我们要计算的距离了 。
而勾股定理为:a^2^+b^2^=C^2^
让我们带入到代码中来实现:
public double getPointDistance(Point point1, Point point2) {int a = point2.y - point1.y;int b = point2.x - point1.x;return Math.sqrt(a * a + b * b);} 两个坐标point1,point2 其实顺序无所谓 。
两个x轴坐标相减,得到的是在x轴上的距离 。这个值可能为正,也可能为负 。但无所谓,因为进行平方之后 。只会是正数 。
同理,Y轴也是一样的 。所以我们计算时不用管哪个坐标点是前还是后 。
Math.sqrt()是 JAVA 提供的开平方工具 。
我们得到的X轴的距离和Y轴的距离,都是相对于x轴和y轴垂直的 。所以这两个距离组合的就是直角三角形的两条直角边 。
两点的距离就是直角三角形的斜边了 。也就是上面公式中的勾股定义直接计算即可 。
有些小伙伴可能就会问了,如果这两个点的Y轴或者X轴的值是相同的 。那么还可以这么计算么?
结论当然是可以了 。
用上面的代码举例子,如果两个坐标点的Y轴相同 。那么它们的距离实际上就是X轴的距离 。
int a = point2.y - point1.y; //两个值相同,那么a的结果就是0int b = point2.x - point1.x; // 那么距离就是 b的值 。// 带入进去0的平方也是0.那么就是b的平方进行开方运算 。结果也就是b 。(来源:zinyan.com)Math.sqrt(0+b*b);所以,如果两个坐标点的Y轴相同,或者X轴相同 。那么最后计算的结果仍然是正确的 。
但,我们可以添加一个判断,来减少这种情况下的多余的平方,开方计算 。
所以,完整版代码如下所示:
public double getPointDistance(Point point1, Point point2) {int a = point2.y - point1.y;int b = point2.x - point1.x;if (a == 0)return b;if (b == 0)return a;return Math.sqrt(a * a + b * b);} 但是,如果我们的x轴和y轴的坐标值是 double? 或者 float。就不能这么判断了 。
因为浮点运算,本身就不精确 。我们判断的时候,需要考虑到这个浮动范围 。
我们也可以不用考虑这方面的优化 。因为多一个平方开方,也耗费不了多少内存和时间 。
3. 计算两个线段的交点计算:在平面直角坐标系中点A和点B组成了线段A,点C和点D组成了线段B 。如果他们有交点 。那么交点坐标是多少 。
而在平面直角坐标系中,同一平面内两条直线只有相交和平行两种情况 。这个定义是一个数学定理 。
所以我们计算交点的时候,可以先处理一下两个线段是否平行的问题 。
3.1 判断线段是否平行那么,该如何判断两个线段是否平行呢?很简单比较两个线段的斜率是否相同即可 。
斜率,计算的是一条直线相对横坐标轴的倾斜角度 。所以它也叫做角系数 。
例如,这两个线段,都相较于X轴倾斜了30°,那么不就是证明了这两个线段是平行线了么 。
而直线的斜率公式为:k=(y2-y1)/(x2-x1) 。其中K值就是斜率结果了 。
那么线段是否平行就可以写为:
public boolean getParallel(Point pointA, Point pointB, Point pointC, Point pointD) {int line1K = (pointB.y - pointA.y) / (pointB.x - pointA.x);int line2K = (pointD.y - pointC.y) / (pointD.x - pointC.x);returnline1K==line2K}但是如果碰见了线段的x轴是相同的怎么办?也就是说线段垂直于X轴上 。那么上面的方法就有问题了 。
因为pointB.x - pointA.x =0了 。
所以,我们需要进行变种:
//实际比较模式:(pointB.y - pointA.y) / (pointB.x - pointA.x)==(pointD.y - pointC.y) / (pointD.x - pointC.x)//改除法为乘法:(pointB.y - pointA.y) * (pointD.x - pointC.x) == (pointD.y - pointC.y)* (pointB.x - pointA.x)这两个等式是相同的 。
这样我们就可以判断两个线条是否平行了 。完整代码如下:
public boolean getParallel(Point pointA, Point pointB, Point pointC, Point pointD) {return (pointB.y - pointA.y) * (pointD.x - pointC.x) == (pointD.y - pointC.y)* (pointB.x - pointA.x)}


推荐阅读