坐标象限法判断矩形之间最短的距离
大家应该都知道坐标系分为四个象限(Quadrant)
其实这是一种很简单矩形距离算法,大概分为以下几个步骤:
1. 以其中一个矩形的的左下点为原点做一个2维坐标系,判断另外一个矩形的左下点在这个坐标系的哪个象限(其他点也可以,但是被比较的也得是相同的点);
2. 根据所在不同的象限分别在矩形上取不同的一个点作为比较;
3. 对取到的两个点做向量的减法运算;
4. 通过判断的相减后的向量来的到两个矩形的距离;
代码如下:
// 取两个矩形的距离 如果相交返回-1 否则返回两矩形距离 int Distance(Rect rect1,Rect rect2) { // 用于判断rect1在rect2的第三象限里 用于反转X轴用 bool isInversion; // 保存两个比较的点 Point point1; Point point2; // 判断 rect1 在rect2的上面还是下面 也就是说是在第一、二象限还是在三四象限 if(rect1.y<rect2.y) { // 判断rect1 在rect2的左边还是右边 也就是说是在 一象限还是二象限 isInversion= rect1.x<rect2.x; if(is1Quadrant ) { // 取rect1的右上点 point1 = new Point(rect1.x+rect1.width,rect1.y+rect1.height); // 取rect2的左下点 point2 = new Point(rect2.x,rect2.y); }else { // 取rect1的左上点 point1 = new Point(rect1.x,rect1.y+rect1.height); // 取rect2的右下点 point2 = new Point(rect2.x+rect2.width,rect2.y); } }else { // 判断rect1 在rect2的左边还是右边 也就是说是在 三象限还是四象限 isInversion = rect1.x>rect2.x; if(isInversion) { // 取rect2的右上点 point1 = new Point(rect2.x+rect2.width,rect2.y+rect2.height); // 取rect1的左下点 point2 = new Point(rect1.x,rect1.y); }else { // 取rect2的左上点 point1 = new Point(rect2.x,rect2.y+rect2.height); // 取rect1的右下点 point2 = new Point(rect1.x+rect1.width,rect1.y); } } // 做向量减法 Point dPoint = point2 -point1; // 如果反转x轴 dPoint.x = isInversion? dPoint.x:-dPoint; // 如果这个向量在第三象限里 那么这两个矩形相交 返回-1 if(dPoint.x<0&& dPoint.y<0) return -1; // 如果x<0 返回y if(dPoint.x<0) return dPoint.y; // 如果y小于0 返回x if(dPoint.y<0) return dPoint.x; // 返回这个向量的长度 return dPoint.magnitude; }
通过这样一个象限判断法能够很快判断出一个矩形是否相交 同时还能知道这两个之间的距离
算法过程
下图是两个个相交矩形的示图,先拿这两个矩形来验证下,然后在举一反三验证其他所有。
rect1在 rect2 的左下方 也就是在rect2的第三象限,我们取rect1右上点为p1,取rect2左下点为p2然后用p2减去p1我们得到一个第三象限的点 也就是x和y都为负数的点。
反之如果两个矩形不相交,那么我们得到的就是一个都为正数的点。
Talk is cheap. Show me the code