c++判断矩形和线段是否相交或包含

依据数学理论:

如果矩形 rec1 和 rec2 的水平边投影到 x 轴上的线段分别为 (rec1[0], rec1[2]) 和 (rec2[0], rec2[2])。根据数学知识我们可以知道,当 min(rec1[2], rec2[2]) > max(rec1[0], rec2[0]) 时,这两条线段有交集。对于矩形 rec1 和 rec2 的竖直边投影到 y 轴上的线段,同理可以得到,当 min(rec1[3], rec2[3]) > max(rec1[1], rec2[1]) 时,这两条线段有交集,

简单点说,如图

不相交的情况一定符合下面的公式

std::max(A.x, a.x()) <= std::min(B.x, b.x()) && std::max(A.y, a.y()) <= std::min(B.y, b.y())


 

可以使用以下方法判断线段矩形包围盒是否相交: 1. 首先确定矩形的四个顶点坐标,可以根据矩形的中心点坐标和半长、半宽计算出。 2. 对于线段的两个端点,分别计算其在矩形的左、右、上、下四条边上的投影点。 3. 判断线段的两个端点是否都在矩形内部,如果是,则直接返回相交;如果不是,则继续判断线段是否矩形的四条边相交。 4. 判断线段矩形的四条边是否相交,可以使用线段是否跨越矩形边界的方法进行判断。 下面是示例代码实现: ```cpp struct Point { double x, y; }; bool intersect(Point p1, Point p2, Point rect[]) { double xmin = rect[0].x, xmax = rect[2].x; double ymin = rect[0].y, ymax = rect[2].y; // 计算线段两端点在矩形四条边上的投影点 Point proj1 = {clamp(p1.x, xmin, xmax), clamp(p1.y, ymin, ymax)}; Point proj2 = {clamp(p2.x, xmin, xmax), clamp(p2.y, ymin, ymax)}; // 判断线段两端点是否都在矩形内部 if (proj1.x == p1.x && proj1.y == p1.y && proj2.x == p2.x && proj2.y == p2.y) { return true; } // 判断线段是否矩形的四条边相交 double dy = p2.y - p1.y; double dx = p2.x - p1.x; double k = dy / dx; double b = p1.y - k * p1.x; bool intersects = false; if (proj1.x == xmin && proj2.x == xmin) { // 线段矩形左边相交 double y = k * xmin + b; if (y >= ymin && y <= ymax) { intersects = true; } } else if (proj1.x == xmax && proj2.x == xmax) { // 线段矩形右边相交 double y = k * xmax + b; if (y >= ymin && y <= ymax) { intersects = true; } } else if (proj1.y == ymin && proj2.y == ymin) { // 线段矩形下边相交 double x = (ymin - b) / k; if (x >= xmin && x <= xmax) { intersects = true; } } else if (proj1.y == ymax && proj2.y == ymax) { // 线段矩形上边相交 double x = (ymax - b) / k; if (x >= xmin && x <= xmax) { intersects = true; } } return intersects; } double clamp(double x, double a, double b) { return std::max(a, std::min(b, x)); } ``` 其中,`Point` 结构体表示一个二维点,`intersect` 函数用于判断线段矩形是否相交,`clamp` 函数用于将一个数限制在一个区间内。在判断线段矩形相交时,首先确定矩形的四个顶点坐标,然后计算出线段两端点在矩形的左、右、上、下四条边上的投影点,再判断线段两端点是否都在矩形内部,最后判断线段是否矩形的四条边相交即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值