在java中判断一个点是不是在一个有斜度的矩形内的 Rectangle的用法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在java中判断一个点是不是在一个有斜度的矩形内的 Rectangle的用法相关的知识,希望对你有一定的参考价值。
现在工作需要要写这样一个算法,如题;我看到java.awt.Rectangle提供了一个矩形对象可以判断一个点是否在这个矩形内,可是我看Rectangle的构造是确定左上角的一个点的坐标和宽度和高度,我想这样只能确定一个平行于X轴和Y轴的矩形;那如果现在给出的矩形有斜度即每条边都不平行于X轴和Y轴,应该就不能用Rectangle来定义了吧;
我的问题就是现在有一个有斜度的矩形已知四个顶点的坐标,怎么判断一个点在不在这个矩形内呢,Rectangle还有没有可以解决这个问题的拓展用法;
请老鸟们指点一下,先谢过~
BufferedImage 有getRGB(int x, int y) 下面方法可以获取r、g、b的值
public static int [] getRGB(BufferedImage image, int x, int y)
int [] rgb = null ;
if (image != null && x < image.getWidth() && y < image.getHeight())
rgb = new int [ 3 ];
int pixel = image.getRGB(x,y);
rgb[ 0 ] = (pixel & 0xff0000 ) >> 16 ;
rgb[ 1 ] = (pixel & 0xff00 ) >> 8 ;
rgb[ 2 ] = (pixel & 0xff );
return rgb;
追问
服务器用的 必须考虑效率问题,而且不能按UI方式做
追答终于看明白题目了,既然是矩形那么就有4条边,首先判断下点的高度是不是在矩形范围内
如果在矩形内,获取同一高度的矩形左右2点的坐标,然后判断x值是否在矩形内
如图中的样子,根据斜率计算斜边上的某个点是可以计算的
计算
终于看明白了,矩形的话应该能计算出斜率,根据这个计算和你要判断的点同样y值的两条边相对应的两个点的x值,然后判断这个点是否在2个值范围内
参考技术A 这个好像是个算法问题……要先根据每相邻两点得出一个斜率公式,计算该点坐标是否分别在两条平行线之间
变换坐标的做法似乎更麻烦一点 参考技术B Path2D用这个对象表示非正规的图形,moveTo lineTo可以表示一个这样的图形。他是shape接口的实现,可以直接使用contains(double x, double y)来判断点是不是在范围内。
Java检查两个矩形是不是在任何点重叠
【中文标题】Java检查两个矩形是不是在任何点重叠【英文标题】:Java check if two rectangles overlap at any pointJava检查两个矩形是否在任何点重叠 【发布时间】:2014-06-11 17:36:08 【问题描述】:我有多个矩形和一个特殊矩形:选择矩形。 我想检查每个矩形是否包含至少一个位于选择矩形内的点。 为了清楚起见,这是一张图片:
【问题讨论】:
Rectangle::intersects
对你有用。
javarevisited.blogspot.com/2016/10/…
【参考方案1】:
背景:
一个矩形只能由它的对角线之一定义。 假设第一个矩形的对角线是 (x1, y1) 到 (x2, y2) 而另一个矩形的对角线是 (x3, y3) 到 (x4, y4)
进行:
现在,如果这 4 个条件中的任何一个为真,我们可以断定矩形不重叠:
-
x3 > x2(或)
y3 > y2(或)
x1 > x4(或)
y1 > y4
否则,它们会重叠!
或者:
如果矩形重叠
(x1 < x4) && (x3 < x2) && (y1 < y4) && (y3 < y2)
Leetcode 上的示例解决方案: https://leetcode.com/problems/rectangle-overlap/discuss/468548/Java-check-if-two-rectangles-overlap-at-any-point
【讨论】:
这个肯定比公认的答案有更好的解释! 这可以通过一个代码示例来使其成为一个很好的答案【参考方案2】:这将确定矩形是否与另一个矩形重叠:
public boolean overlaps (Rectangle r)
return x < r.x + r.width && x + width > r.x && y < r.y + r.height && y + height > r.y;
【讨论】:
@ahitt6345 是的,确实如此。唯一的问题是如果您尝试旋转矩形,在这种情况下您将需要多边形重叠方法。 虽然解决方案是正确的 - 我推荐this answer down below 以获得更好的理解。【参考方案3】:我会创建Rectangle objects,然后使用Rectangle.intersects
和Rectangle.contains
方法来确定它们是否相交或一个是否包含另一个。
既然你有一个大矩形,那就是选择矩形,这比我想象的还要容易。运行 Rectangle.contains,对于所有不包含的矩形,运行 Rectangle.intersects,你就会得到你想要的。
【讨论】:
【参考方案4】:这是另一个更简单的解决方案:
// Left x
int leftX = Math.max(x1, x3);
// Right x
int rightX = Math.min(x2, x4);
// Bottom y
int botY = Math.max(y1, y3);
// TopY
int topY = Math.min(y2, y4);
if (rightX > leftX && topY > botY)
return true;
【讨论】:
【参考方案5】:如果第一个实现RectangularShape
,第二个是Rectangle2D
,你可以简单地使用RectangularShape.intersects
:
selectionRectangle.intersects(otherRectangle)
测试 Shape 的内部是否与指定的 Rectangle2D 的内部相交
来自the Oracle Java docs
【讨论】:
【参考方案6】:我对 gps 坐标系中的多边形有一个通用的实现,这对于矩形(简单的多边形)可能有点矫枉过正;但它会起作用。如果您出于某种原因不想使用 AWT,那么根据您的用例调整该方法应该相当简单。
https://github.com/jillesvangurp/geogeometry/blob/master/src/main/java/com/jillesvangurp/geo/GeoGeometry.java#L753(重叠法)
我所做的只是检查多边形是否有其他多边形包含的任何点。
对于点的多边形包含,我有一个简单的算法可以遍历多边形的边缘以检查该点是在 O(n) 内部还是外部。对于矩形,运行起来应该很便宜。
这种方法的好处是它适用于任何矩形以及旋转的矩形或更复杂的形状。
【讨论】:
【参考方案7】:如果以下条件之一为真,则两个矩形不重叠。 1) 一个矩形在另一个矩形的顶部边缘之上。 2) 一个矩形在另一个矩形的左边。
请注意,一个矩形可以用两个坐标表示,左上角和右下角。所以主要是给我们以下四个坐标。 l1:第一个矩形的左上角坐标。 r1:第一个矩形的右下坐标。 l2:第二个矩形的左上角坐标。 r2:第二个矩形的右下坐标。
class Point
int x, y;
;
// Returns true if two rectangles (l1, r1) and (l2, r2) overlap
bool doOverlap(Point l1, Point r1, Point l2, Point r2)
// If one rectangle is on left side of other
if (l1.x > r2.x || l2.x > r1.x)
return false;
// If one rectangle is above other
if (l1.y < r2.y || l2.y < r1.y)
return false;
return true;
【讨论】:
【参考方案8】:这个类假定顺序为left<=right
、top<=bottom
、x1<=x2
、y1<=y2
:
public class Rect
int left, right, bottom, top;
Rect(int left, int top, int right, int bottom)
this.left = left;
this.right = right;
this.top = top;
this.bottom = bottom;
boolean overlap(int x1, int y1, int x2, int y2)
// if one rectangle is to the left or right, then there can be no overlap
if(x2 < left || right < x1)
return false;
// the x values overlap, but the y values may still lie outside the rectangle
// if one rectangle is above or below, then there can be no overlap
if(y2 < top || bottom < y1)
return false;
// otherwise we must overlap !
return true;
【讨论】:
【参考方案9】:java.awt.Rectangle
有一个内置的 intersects
方法。
import java.awt.Rectangle;
// ...
Rectangle r1 = new Rectangle(
0 /* top left x */, 0 /* top left y */,
5 /* width */, 7 /* height */
);
Rectangle r2 = new Rectangle(4, 5, 3, 3);
System.out.println(r1.intersects(r2)); // true
【讨论】:
【参考方案10】:编辑 正如接受的答案中所述,AWT Rectangle 对象通过intersects
方法提供此功能。如果您不想使用 AWT 或出于其他原因,下面是一个变体解决方案。
如果您想重新发明***,那么这里有一些东西。 使用您的示例图像,这将测试黑色矩形与蓝色矩形重叠。此外,这假设触摸没有重叠。
每个矩形将由两个坐标对表示:topLeft 和 bottomRight。
这里假设0,0在左上角。
Function xOverlapCheck(black, blue)
// black left side overlaps.
if ((black.topLeft.x <= blue.bottomRight.x) &&
(black.topLeft.x >= blue.topLeft.x))
return true;
// black right side overlaps.
if ((black.bottomRight.x <= blue.bottomRight.x) &&
(black.bottomRight.x >= blue.topLeft.x))
return true;
// black fully contains blue.
if ((black.bottomRight.x >= blue.bottomRight.x) &&
(black.topLeft.x <= blue.topLeft.x))
return true;
Function yOverlapCheck(black, blue)
// black top side overlaps.
if ((black.topLeft.y >= blue.topLeft.y) &&
(black.topLeft.y <= blue.bottomRight.y))
return true;
// black bottom side overlaps.
if ((black.bottomRight.y >= blue.topLeft.y) &&
(black.bottomRight.y <= blue.bottomRight.y))
return true;
// black fully contains blue.
if ((black.bottomRight.y >= blue.bottomRight.y) &&
(black.topLeft.y <= blue.topLeft.y))
return true;
当两个函数都返回 true 时,黑色与蓝色重叠。
编辑:使用 = 进行重叠比较。
【讨论】:
伙计,你让我进行了数小时毫无意义的调试,你的方法有缺陷——由于某些原因,它不包括仅移动一个像素的矩形。对我来说Rect.intersection(new Rect(0, 5, 5, 0), new Rect(0, 6, 5, 1))
返回错误。但是,如果我增加矩形之间的距离,它就开始起作用了。以上是关于在java中判断一个点是不是在一个有斜度的矩形内的 Rectangle的用法的主要内容,如果未能解决你的问题,请参考以下文章
java知道四个点坐标,怎么判断一个点是否在这个矩形区域内(矩形可能是斜着放的,有一定的斜度)