说矩形相交算法之前,先看下如何判断两条线段是否相交
如果有两条线段 [a, b],[c, d](a, b, c, d 为 X 轴坐标点),有下面两种不相交的情况:
1)b < c 时,线段 [a, b] 在 [c, d] 的左边不相交
2)d < a 时,线段 [a, b] 在 [c, d] 的右边不相交
把上面两种情况取反就是相交的情况。
相交的线段则可以表示为[min(a, c), min(b, d)](注意:min(b, d) 应大于 min(a, c),否则就是不相交了),即两条线段中起点大的和终点小的。
写成程序如果下所示(程序中用的结构体表示是起点和长度):
#define max(x, y) ((x) > (y) ? (x) : (y)) #define min(x, y) ((x) < (y) ? (x) : (y)) struct section { int start; int length; }; /* determine if the two input section intersect with each other */ static int section_intersect(struct section sec1, struct section sec2) { /*return !(sec1.start > sec2.start + sec2.length || sec2.start > sec1.start + sec1.length);*/ return sec1.start < sec2.start + sec2.length && sec2.start < sec1.start + sec1.length; } static void section_intersect_test() { struct section sec1 = {5, 5}; struct section sec2 = {7, 8}; struct section sec3 = {18, 3}; printf("sec1 ^ sec2 : %d\n", section_intersect(sec1, sec2)); printf("sec1 ^ sec3 : %d\n", section_intersect(sec1, sec3)); printf("sec2 ^ sec3 : %d\n", section_intersect(sec2, sec3)); } /* return the intersection of the two input, if not intersect, return a emtpy section */ static struct section section_intersection(struct section sec1, struct section sec2) { struct section sec = {0, 0}; int start = max(sec1.start, sec2.start); int end = min(sec1.start + sec1.length, sec2.start + sec2.length); if (end >= start) { sec.start = start; sec.length = end - start; } return sec; } static void print_section(const char *pcstr, struct section sec) { printf("%s {%d, %d}\n", pcstr, sec.start, sec.length); } static void section_intersection_test() { struct section sec1 = {5, 5}; struct section sec2 = {7, 8}; struct section sec3 = {18, 3}; print_section("sec1 ^ sec2 :", section_intersection(sec1, sec2)); print_section("sec1 ^ sec3 :", section_intersection(sec1, sec3)); print_section("sec2 ^ sec3 :", section_intersection(sec2, sec3)); } static void test_driver() { section_intersect_test(); section_intersection_test(); }
说明:
section_intersect 判断两条线段是否相交,如果不相交返回 0。它里面的注释部分和没有注释的部分的意思等同。
section_intersect_test 是对 section_intersect 的简单测试。
section_intersection 返回两条线段相交的部分,如果不相交,返回一个空线段(起点为 0,长度为 0)。
section_intersection_test 是对 section_intersection 的简单测试。
判断矩形是否相交与之类似,因为矩形是由相互垂直的两条线段确定的。
代码如下:
struct rectangle { int x; int y; int width; int height; }; static int rectangle_intersect(struct rectangle rec1, struct rectangle rec2) { return rec1.x < rec2.x + rec2.width && rec2.x < rec1.x + rec1.width && rec1.y < rec2.y + rec2.height && rec2.y < rec1.y + rec1.height; } static struct rectangle rectangle_intersection(struct rectangle rec1, struct rectangle rec2) { struct rectangle rec = {0, 0, 0, 0}; int x1 = max(rec1.x, rec2.x); int x2 = min(rec1.x + rec1.width, rec2.x + rec2.width); int y1 = max(rec1.y, rec2.y); int y2 = min(rec1.y + rec1.height, rec2.y + rec2.height); if (x2 >= x1 && y2 >= y1) { rec.x = x1; rec.y = y1; rec.width = x2 - x1; rec.height = y2 - y1; } return rec; }
说明,以上的代码都没有经过严格的测试,只为了说明线段矩阵相交算法。
时间: 2024-12-28 21:08:18