我正在尝试编写一个C++程序,它从用户那里获取以下输入来构造矩形(2到5之间):高度,宽度,x-pos,y-pos.所有这些矩形将平行于x轴和y轴存在,即它们的所有边都将具有0或无穷大的斜率.
我试图实现这个问题中提到的但我没有太多运气.
我目前的实现如下:
// Gets all the vertices for Rectangle 1 and stores them in an array -> arrRect1 // point 1 x: arrRect1[0], point 1 y: arrRect1[1] and so on... // Gets all the vertices for Rectangle 2 and stores them in an array -> arrRect2 // rotated edge of point a, rect 1 int rot_x, rot_y; rot_x = -arrRect1[3]; rot_y = arrRect1[2]; // point on rotated edge int pnt_x, pnt_y; pnt_x = arrRect1[2]; pnt_y = arrRect1[3]; // test point, a from rect 2 int tst_x, tst_y; tst_x = arrRect2[0]; tst_y = arrRect2[1]; int value; value = (rot_x * (tst_x - pnt_x)) + (rot_y * (tst_y - pnt_y)); cout << "Value: " << value;
但是我不太确定(a)我是否实现了我正确链接的算法,或者我是否确实如何解释这个?
有什么建议?
if (RectA.Left < RectB.Right && RectA.Right > RectB.Left && RectA.Top > RectB.Bottom && RectA.Bottom < RectB.Top )
或者,使用笛卡尔坐标
(X1为左坐标,X2为右坐标,从左到右增加,Y1为顶部坐标,Y2为底部坐标,从下到上增加)......
if (RectA.X1 < RectB.X2 && RectA.X2 > RectB.X1 && RectA.Y1 > RectB.Y2 && RectA.Y2 < RectB.Y1)
注意:对于所有具有编辑权限的用户.请停止使用此信息.
假设您有Rect A和Rect B.证明是矛盾的.四个条件中的任何一个都保证不存在重叠:
COND1.如果A的左边缘位于B的右边缘的右边,那么A就完全在B的右边
COND2.如果A的右边缘位于B左边缘的左边,那么A则完全在B的左边
COND3.如果A的上边缘低于B的下边缘,则A完全低于B
COND4.如果A的下边缘高于B的上边缘,那么A完全高于B
所以非重叠的条件是
Cond1 Or Cond2 Or Cond3 Or Cond4
因此,重叠的充分条件恰恰相反.
Not (Cond1 Or Cond2 Or Cond3 Or Cond4)
De Morgan的法律说
Not (A or B or C or D)
与Not A And Not B And Not C And Not D
使用De Morgan一样,我们有
Not Cond1 And Not Cond2 And Not Cond3 And Not Cond4
这相当于:
A的左边缘位于B的右边缘,[ RectA.Left < RectB.Right
]和
A的右边缘到B的左边缘,[ RectA.Right > RectB.Left
]和
A高于B的底部,[ RectA.Top > RectB.Bottom
]和
A的底部位于B的顶部[ RectA.Bottom < RectB.Top
]
注1:很明显,同样的原则可以扩展到任意数量的维度.
注2:计算一个像素的重叠,将该边界<
和/或>
边界更改为a <=
或a 也应该是相当明显的>=
.
注3:当使用笛卡尔坐标(X,Y)时,这个答案基于标准代数笛卡尔坐标(x从左到右增加,Y从下到上增加).显然,在计算机系统可能以不同方式机械化屏幕坐标的情况下(例如,从上到下增加Y,或从右到左增加X),语法将需要相应地调整/
struct rect { int x; int y; int width; int height; }; bool valueInRange(int value, int min, int max) { return (value >= min) && (value <= max); } bool rectOverlap(rect A, rect B) { bool xOverlap = valueInRange(A.x, B.x, B.x + B.width) || valueInRange(B.x, A.x, A.x + A.width); bool yOverlap = valueInRange(A.y, B.y, B.y + B.height) || valueInRange(B.y, A.y, A.y + A.height); return xOverlap && yOverlap; }
struct Rect { Rect(int x1, int x2, int y1, int y2) : x1(x1), x2(x2), y1(y1), y2(y2) { assert(x1 < x2); assert(y1 < y2); } int x1, x2, y1, y2; }; bool overlap(const Rect &r1, const Rect &r2) { // The rectangles don't overlap if // one rectangle's minimum in some dimension // is greater than the other's maximum in // that dimension. bool noOverlap = r1.x1 > r2.x2 || r2.x1 > r1.x2 || r1.y1 > r2.y2 || r2.y1 > r1.y2; return !noOverlap; }
更容易检查一个矩形是否完全在另一个之外,所以如果它是
在左边...
(r1.x + r1.width < r2.x)
或在右边......
(r1.x > r2.x + r2.width)
或在顶部......
(r1.y + r1.height < r2.y)
或在底部......
(r1.y > r2.y + r2.height)
第二个矩形,它不可能与它碰撞.因此,要有一个返回布尔说明天气与矩形冲突的函数,我们只需通过逻辑OR组合条件并否定结果:
function checkOverlap(r1, r2) : Boolean { return !(r1.x + r1.width < r2.x || r1.y + r1.height < r2.y || r1.x > r2.x + r2.width || r1.y > r2.y + r2.height); }
仅在触摸时已经收到肯定结果,我们可以通过"<="和"> ="更改"<"和">".
问自己相反的问题:我怎样才能确定两个矩形是否完全不相交?显然,矩形B左侧的矩形A不相交.如果A完全在右边.并且类似地,如果A完全在B之上或完全在B之下.在任何其他情况下A和B相交.
以下内容可能存在错误,但我对该算法非常有信心:
struct Rectangle { int x; int y; int width; int height; }; bool is_left_of(Rectangle const & a, Rectangle const & b) { if (a.x + a.width <= b.x) return true; return false; } bool is_right_of(Rectangle const & a, Rectangle const & b) { return is_left_of(b, a); } bool not_intersect( Rectangle const & a, Rectangle const & b) { if (is_left_of(a, b)) return true; if (is_right_of(a, b)) return true; // Do the same for top/bottom... } bool intersect(Rectangle const & a, Rectangle const & b) { return !not_intersect(a, b); }
假设您已经定义了矩形的位置和大小,如下所示:
我的C++实现是这样的:
class Vector2D { public: Vector2D(int x, int y) : x(x), y(y) {} ~Vector2D(){} int x, y; }; bool DoRectanglesOverlap( const Vector2D & Pos1, const Vector2D & Size1, const Vector2D & Pos2, const Vector2D & Size2) { if ((Pos1.x < Pos2.x + Size2.x) && (Pos1.y < Pos2.y + Size2.y) && (Pos2.x < Pos1.x + Size1.x) && (Pos2.y < Pos1.y + Size1.y)) { return true; } return false; }
根据上图给出的示例函数调用:
DoRectanglesOverlap(Vector2D(3, 7), Vector2D(8, 5), Vector2D(6, 4), Vector2D(9, 4));
if
块内的比较如下所示:
if ((Pos1.x < Pos2.x + Size2.x) && (Pos1.y < Pos2.y + Size2.y) && (Pos2.x < Pos1.x + Size1.x) && (Pos2.y < Pos1.y + Size1.y)) ? if (( 3 < 6 + 9 ) && ( 7 < 4 + 4 ) && ( 6 < 3 + 8 ) && ( 4 < 7 + 5 ))