思路:
就是坐标系上找4个点,然后判断这些点和点之间能组合出多少长度的线,然后根据勾股定理看看是否能组成直角
// 判断坐标系上的任意4个点是否可以组成一个矩形 // 1,2个点一组,穷举所有组合方式 // 2,计算每个组合方式2点之间的距离 // 3,对产生的所有距离长度去重,计算数量,数量为3是长方形(假设),数量是2是正方形(假设) // 4,判断剩余的距离能否组成一个直角,利用勾股定理判断,如果不能组成直角三角形,可能是菱形、梯形、不规则四边形
error_reporting(0); // 判断坐标系上的任意4个点是否可以组成一个矩形 // 1,2个点一组,穷举所有组合方式 // 2,计算每个组合方式2点之间的距离 // 3,对产生的所有距离长度去重,计算数量,数量为3是长方形(假设),数量是2是正方形(假设) // 4,判断剩余的距离能否组成一个直角,利用勾股定理判断,如果不能组成直角三角形,可能是菱形、梯形、不规则四边形 // 是否是矩形 function IsRectangle($point_1 = [0, 0], $point_2 = [0, 0], $point_3 = [0, 0], $point_4 = [0, 0]) { $point_list = [$point_1, $point_2, $point_3, $point_4]; // 判断是否有重复的点 if (count(array_unique($point_list, SORT_REGULAR)) < 4) { echo 2; return false; } // 通过穷举获得所有组合 $list_combi = combination($point_list, 2); $list_len = []; foreach ($list_combi as $k => $v) { // 注意,这里为了计算对角线,防止开方导致的数据精度问题,所有数据保持平方后的状态,不再开方 $list_len[] = pow($v[0][0] - $v[1][0], 2) + pow($v[0][1] - $v[1][1], 2); } // 对所有长度去重 $list_len = array_unique($list_len); $length = count($list_len); if ($length == 3) { $max_side = max($list_len); unset($list_len[array_search($max_side, $list_len)]); // 前面计算距离的时候已经平方过了,不再进行平方,直接对比 if (max($list_len) + min($list_len) == $max_side) { return '长方形矩形'; } else { return '不是正矩形'; } } elseif ($length == 2) { // 判断是否为正方形,最长边和两个相同短边满足勾股定理 if (max($list_len) == 2 * min($list_len)) { return '正方形矩形'; } else { return '不是正矩形'; } } else { return '不是矩形'; } } // 组合 function combination($array, $m) { $result_list = array(); $list_num = count($array); if ($m <= 0 || $m > $list_num) { return $result_list; } for ($i = 0; $i < $list_num; $i++) { $t = array($array[$i]); if ($m == 1) { $result_list[] = $t; } else { $b = array_slice($array, $i + 1); $c = combination($b, $m - 1); foreach ($c as $v) { $result_list[] = array_merge($t, $v); } } } return $result_list; } echo IsRectangle([0, 0], [0, 2], [2, 2], [2, 0]); echo '<hr/>'; echo IsRectangle([1, 3], [1, 0], [3, 3], [3, 0]); echo '<hr/>'; echo IsRectangle([0, 0], [1, 2], [3, 2], [3, 0]);
