| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package gecaoji; |
| | | |
| | | import java.awt.geom.Point2D; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * å²èæºè¾¹çæ£æ¥å·¥å
፱ȋ |
| | | * |
| | | * ç¨æ³å¥çº¦ï¼ |
| | | * - è¾å
¥çå°åè¾¹ç为éåçå¤è¾¹å½¢ç¹åºåï¼é¡ºåºä¸ºé¡ºæ¶éæéæ¶éåå¯ï¼ï¼æ¯ä¸ªç¹å
å« Xï¼ç±³ï¼ãYï¼ç±³ï¼åæ ã |
| | | * - è¥ç¹ä½äºå¤è¾¹å½¢å
鍿ä½äºè¾¹ç线ä¸ï¼è¿å trueï¼å¦åè¿å falseã |
| | | */ |
| | | public final class MowerBoundaryChecker { |
| | | |
| | | private MowerBoundaryChecker() { } |
| | | |
| | | /** |
| | | * 夿ç»å®ç¹æ¯å¦å¨è¾¹çå¤è¾¹å½¢å
é¨ï¼å«è¾¹çï¼ã |
| | | * |
| | | * @param polygonPoints è¾¹çç¹åè¡¨ï¼æ¯ä¸ªå
ç´ ä¸º double[2]ï¼ç´¢å¼0为xï¼ç´¢å¼1为yï¼è³å°éè¦3ä¸ªç¹ |
| | | * @param x å²èæºå®æ¶Xåæ ï¼ç±³ï¼ |
| | | * @param y å²èæºå®æ¶Yåæ ï¼ç±³ï¼ |
| | | * @return 妿ç¹å¨å¤è¾¹å½¢å
é¨æè¾¹çä¸åè¿å trueï¼å¦åè¿å false |
| | | */ |
| | | public static boolean isInsideBoundary(List<double[]> polygonPoints, double x, double y) { |
| | | if (polygonPoints == null || polygonPoints.size() < 3) { |
| | | return false; |
| | | } |
| | | int n = polygonPoints.size(); |
| | | boolean inside = false; |
| | | for (int i = 0, j = n - 1; i < n; j = i++) { |
| | | double xi = polygonPoints.get(i)[0]; |
| | | double yi = polygonPoints.get(i)[1]; |
| | | double xj = polygonPoints.get(j)[0]; |
| | | double yj = polygonPoints.get(j)[1]; |
| | | |
| | | // å¤æç¹æ¯å¦å¨å½åè¾¹ä¸ï¼èèæµ®ç¹å®¹å·®ï¼ |
| | | if (pointOnSegment(xj, yj, xi, yi, x, y)) { |
| | | return true; |
| | | } |
| | | |
| | | boolean intersect = ((yi > y) != (yj > y)) && |
| | | (x < (xj - xi) * (y - yi) / (yj - yi + 0.0) + xi); |
| | | if (intersect) { |
| | | inside = !inside; |
| | | } |
| | | } |
| | | return inside; |
| | | } |
| | | |
| | | /** |
| | | * éè½½ï¼æ¥å Point2D å表 |
| | | */ |
| | | public static boolean isInsideBoundaryPoints(List<Point2D.Double> polygonPoints, double x, double y) { |
| | | if (polygonPoints == null || polygonPoints.size() < 3) { |
| | | return false; |
| | | } |
| | | int n = polygonPoints.size(); |
| | | boolean inside = false; |
| | | for (int i = 0, j = n - 1; i < n; j = i++) { |
| | | double xi = polygonPoints.get(i).x; |
| | | double yi = polygonPoints.get(i).y; |
| | | double xj = polygonPoints.get(j).x; |
| | | double yj = polygonPoints.get(j).y; |
| | | |
| | | if (pointOnSegment(xj, yj, xi, yi, x, y)) { |
| | | return true; |
| | | } |
| | | |
| | | boolean intersect = ((yi > y) != (yj > y)) && |
| | | (x < (xj - xi) * (y - yi) / (yj - yi + 0.0) + xi); |
| | | if (intersect) { |
| | | inside = !inside; |
| | | } |
| | | } |
| | | return inside; |
| | | } |
| | | |
| | | /** |
| | | * éè½½ï¼æ¥åäºç»´æ°ç» double[][]ï¼æ¯è¡ [x,y] |
| | | */ |
| | | public static boolean isInsideBoundary(double[][] polygon, double x, double y) { |
| | | if (polygon == null || polygon.length < 3) { |
| | | return false; |
| | | } |
| | | int n = polygon.length; |
| | | boolean inside = false; |
| | | for (int i = 0, j = n - 1; i < n; j = i++) { |
| | | double xi = polygon[i][0]; |
| | | double yi = polygon[i][1]; |
| | | double xj = polygon[j][0]; |
| | | double yj = polygon[j][1]; |
| | | |
| | | if (pointOnSegment(xj, yj, xi, yi, x, y)) { |
| | | return true; |
| | | } |
| | | |
| | | boolean intersect = ((yi > y) != (yj > y)) && |
| | | (x < (xj - xi) * (y - yi) / (yj - yi + 0.0) + xi); |
| | | if (intersect) { |
| | | inside = !inside; |
| | | } |
| | | } |
| | | return inside; |
| | | } |
| | | |
| | | // å¤æç¹æ¯å¦å¨çº¿æ®µ (x1,y1)-(x2,y2) ä¸ï¼å
æ¬ç«¯ç¹ï¼ï¼å
许å°çæ°å¼è¯¯å·® |
| | | private static boolean pointOnSegment(double x1, double y1, double x2, double y2, double px, double py) { |
| | | double cross = (px - x1) * (y2 - y1) - (py - y1) * (x2 - x1); |
| | | double eps = 1e-8; |
| | | if (Math.abs(cross) > eps) { |
| | | return false; |
| | | } |
| | | double dot = (px - x1) * (px - x2) + (py - y1) * (py - y2); |
| | | return dot <= eps; |
| | | } |
| | | } |