|
|
@ -4,7 +4,11 @@ import lombok.AllArgsConstructor; |
|
|
|
import lombok.Builder; |
|
|
|
import lombok.Builder; |
|
|
|
import lombok.Data; |
|
|
|
import lombok.Data; |
|
|
|
import lombok.NoArgsConstructor; |
|
|
|
import lombok.NoArgsConstructor; |
|
|
|
|
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.List; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Slf4j |
|
|
|
public class CoordUtil { |
|
|
|
public class CoordUtil { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -15,8 +19,13 @@ public class CoordUtil { |
|
|
|
public static class Coordinates { |
|
|
|
public static class Coordinates { |
|
|
|
public double x; |
|
|
|
public double x; |
|
|
|
public double y; |
|
|
|
public double y; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public String toString() { |
|
|
|
|
|
|
|
return String.format("[x:: %s, y:: %s]", x, y); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 좌표 두 거리간의 거리
|
|
|
|
public static double calculateDistance(Coordinates c1, Coordinates c2) { |
|
|
|
public static double calculateDistance(Coordinates c1, Coordinates c2) { |
|
|
|
double earthRadius = 6371; // 지구의 반지름 (단위: km)
|
|
|
|
double earthRadius = 6371; // 지구의 반지름 (단위: km)
|
|
|
|
|
|
|
|
|
|
|
@ -36,4 +45,120 @@ public class CoordUtil { |
|
|
|
|
|
|
|
|
|
|
|
return distance; |
|
|
|
return distance; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 특정 좌표가 다각형의 내부에 포함 여부 확인
|
|
|
|
|
|
|
|
public static boolean isInsidePolygon(List<Coordinates> polygon, Coordinates point) { |
|
|
|
|
|
|
|
if (polygon.size() < 3) { |
|
|
|
|
|
|
|
log.warn("polygon size more then 3 point."); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
int intersectCount = 0; |
|
|
|
|
|
|
|
for (int i = 0; i < polygon.size(); i++) { |
|
|
|
|
|
|
|
Coordinates start = polygon.get(i); |
|
|
|
|
|
|
|
Coordinates end = polygon.get((i + 1) % polygon.size()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// [무시] 주어진 좌표로 부터 선분이 좌측에 있을 경우 제외한다.
|
|
|
|
|
|
|
|
if (point.x > Math.max(start.x, end.x)) { |
|
|
|
|
|
|
|
// log.info(">>> x pass -- px: {}, sx: {}, ex: {}", point.x, start.x, end.x);
|
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// [무시] 주어진 좌표로 부터 선분이 위에 있거나 아래 있을 경우 교차 되지 않으므로 제외한다.
|
|
|
|
|
|
|
|
if (point.y < Math.min(start.y, end.y) || point.y > Math.max(start.y, end.y)) { |
|
|
|
|
|
|
|
// log.info(">>> y pass -- py: {}, sy: {}, ey: {}", point.y, start.y, end.y);
|
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// [선분위] 수직 선분 위에 주어진 좌표가 존재할 경우
|
|
|
|
|
|
|
|
if (point.x == start.x && point.x == end.x) { |
|
|
|
|
|
|
|
// log.info("[선분위] 수직 선분 위에 주어진 좌표가 존재할 경우 {} - {} - {}", point, start, end);
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 수평 선분
|
|
|
|
|
|
|
|
if (start.y == end.y) { |
|
|
|
|
|
|
|
if (point.y == start.y && point.x >= Math.min(start.x, start.y) && point.x <= Math.max(start.x, end.x)) { |
|
|
|
|
|
|
|
// [선분위] 수평 선분 위에 주어진 좌표가 존재할 경우
|
|
|
|
|
|
|
|
// log.info("[선분위] 수평 선분 위에 주어진 좌표가 존재할 경우 {} - {} - {}", point, start, end);
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// [무시] 그외 수평 선분은 제외
|
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// [무시] 선분의 끝점이 주어진 좌표 y와 동일할 경우 아래에 있는 선분은 제외
|
|
|
|
|
|
|
|
if (point.y == Math.max(start.y, end.y)) { |
|
|
|
|
|
|
|
// log.info("[무시] 선분의 끝점이 주어진 좌표 y와 동일할 경우 아래에 있는 선분은 제외");
|
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double x = (point.y - start.y) * (end.x - start.x) / (end.y - start.y) + start.x; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// [선분위] 주어진 좌표가 선분 위에 존재할 경우
|
|
|
|
|
|
|
|
if (x == point.x) { |
|
|
|
|
|
|
|
// log.info("[선분위] 주어진 좌표가 선분 위에 존재할 경우 {} - {} - {}", point, start, end);
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (x > point.x) { |
|
|
|
|
|
|
|
intersectCount++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return intersectCount % 2 == 1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 직사각형 내부 포함 여부
|
|
|
|
|
|
|
|
public static boolean isInsideRectangle(List<Coordinates> polygon, Coordinates point) { |
|
|
|
|
|
|
|
if (polygon == null || polygon.size() != 4) { |
|
|
|
|
|
|
|
log.warn("polygon size only 4 point"); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double maxX = polygon.getFirst().getX(); |
|
|
|
|
|
|
|
double minX = polygon.getFirst().getX(); |
|
|
|
|
|
|
|
; |
|
|
|
|
|
|
|
double maxY = polygon.getFirst().getY(); |
|
|
|
|
|
|
|
; |
|
|
|
|
|
|
|
double minY = polygon.getFirst().getY(); |
|
|
|
|
|
|
|
; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 1; i < polygon.size(); i++) { |
|
|
|
|
|
|
|
if (polygon.get(i).getX() > maxX) { |
|
|
|
|
|
|
|
maxX = polygon.get(i).getX(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (polygon.get(i).getX() < minX) { |
|
|
|
|
|
|
|
minX = polygon.get(i).getX(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (polygon.get(i).getY() > maxY) { |
|
|
|
|
|
|
|
maxY = polygon.get(i).getY(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (polygon.get(i).getY() < minY) { |
|
|
|
|
|
|
|
minY = polygon.get(i).getY(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (point.getX() >= minX && point.getX() <= maxX && point.getY() >= minY && point.getY() <= maxY) { |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// public static void main(String[] args) {
|
|
|
|
|
|
|
|
// List<Coordinates> polygon = new ArrayList<>();
|
|
|
|
|
|
|
|
// polygon.add(Coordinates.builder().x(15.0).y(10.0).build());
|
|
|
|
|
|
|
|
// polygon.add(Coordinates.builder().x(10.0).y(15.0).build());
|
|
|
|
|
|
|
|
// polygon.add(Coordinates.builder().x(10.0).y(20.0).build());
|
|
|
|
|
|
|
|
// polygon.add(Coordinates.builder().x(15.0).y(20.0).build());
|
|
|
|
|
|
|
|
// polygon.add(Coordinates.builder().x(20.0).y(15.0).build());
|
|
|
|
|
|
|
|
// polygon.add(Coordinates.builder().x(15.0).y(15.0).build());
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// for (int i = 21; i >= 9; i--) {
|
|
|
|
|
|
|
|
// for (int j = 9; j <= 21; j++) {
|
|
|
|
|
|
|
|
// Coordinates p = Coordinates.builder().x(j).y(i).build();
|
|
|
|
|
|
|
|
// boolean flag = CoordUtil.isInsidePolygon(polygon, p);
|
|
|
|
|
|
|
|
// System.out.printf("%s ", flag ? "◼︎" : "◻︎");
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// System.out.println();
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
} |
|
|
|
} |
|
|
|