| | |
| | | if (!optimized.get(0).equals(optimized.get(optimized.size() - 1))) { |
| | | Coordinate first = optimized.get(0); |
| | | Coordinate last = optimized.get(optimized.size() - 1); |
| | | double closingDistance = calculateDistance(first, last); |
| | | |
| | | double closingDistance = calculateDistance(last, first); |
| | | |
| | | if (closingDistance > params.interval) { |
| | | // 如果首尾距离较远,添加中间点 |
| | | List<Coordinate> interpolated = interpolateBoundary( |
| | | List.of(last, first), params.interval |
| | | ); |
| | | optimized.addAll(interpolated.subList(1, interpolated.size() - 1)); |
| | | int segments = (int) Math.ceil(closingDistance / params.interval); |
| | | for (int i = 1; i < segments; i++) { |
| | | double ratio = (double) i / segments; |
| | | Coordinate interpolatedPoint = interpolate(last, first, ratio); |
| | | if (!interpolatedPoint.equals(last)) { |
| | | optimized.add(interpolatedPoint); |
| | | } |
| | | } |
| | | } |
| | | optimized.add(first); |
| | | } |
| | | |
| | | return optimized; |
| | | |
| | | return removeConsecutiveDuplicates(optimized); |
| | | } |
| | | |
| | | // 道格拉斯-普克算法 |
| | |
| | | return interpolated; |
| | | } |
| | | |
| | | private List<Coordinate> removeConsecutiveDuplicates(List<Coordinate> points) { |
| | | if (points == null || points.isEmpty()) { |
| | | return points; |
| | | } |
| | | |
| | | List<Coordinate> cleaned = new ArrayList<>(); |
| | | Coordinate previous = null; |
| | | for (Coordinate point : points) { |
| | | if (previous == null || !point.equals(previous)) { |
| | | cleaned.add(point); |
| | | previous = point; |
| | | } |
| | | } |
| | | |
| | | if (!cleaned.isEmpty() && !cleaned.get(0).equals(cleaned.get(cleaned.size() - 1))) { |
| | | cleaned.add(cleaned.get(0)); |
| | | } |
| | | return cleaned; |
| | | } |
| | | |
| | | // 线性插值 |
| | | private Coordinate interpolate(Coordinate p1, Coordinate p2, double ratio) { |
| | | double x = p1.x + (p2.x - p1.x) * ratio; |