You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R语言中获取不规则细长多边形的两个端点?

解决不规则闭合多边形端点识别与环路径长度计算问题

首先,我完全理解你遇到的困扰:你手头有个闭合的细长多边形(顶点按顺序排列),想找到视觉上的两个端点,还要算出这两个点沿环的两条路径长度,同时需要O(n)复杂度的高效方案。

问题分析

你之前的思路是找沿环距离为周长一半的点对,但这种方法针对的是“半周长匹配点”,而非视觉上的端点——后者本质是多边形中欧氏距离最远的点对,所以才会得到不符合预期的结果。我们需要调整方向,先定位到最远点对(也就是你说的24和74),再计算对应的环路径长度。

O(n)解决方案步骤

1. 预处理:计算累积路径距离数组

首先快速计算每个顶点到起点的沿环累积距离,这一步是严格O(n)复杂度:

# 计算相邻顶点间的线段距离
n <- nrow(x)
seg_dist <- sqrt((x[-1,1] - x[-n,1])^2 + (x[-1,2] - x[-n,2])^2)
# 补上最后一个顶点到第一个顶点的闭合距离
seg_dist <- c(seg_dist, sqrt((x[1,1]-x[n,1])^2 + (x[1,2]-x[n,2])^2))

# 预分配累积距离数组,cum_dist[i]表示从点1到点i的沿环距离(点1到自身为0)
cum_dist <- numeric(n+1)
cum_dist[1] <- 0
for (i in 2:(n+1)) {
  cum_dist[i] <- cum_dist[i-1] + seg_dist[i-1]
}
perimeter <- cum_dist[n+1]  # 多边形总周长

这里用预分配数组代替你原代码里的rbind,避免了重复复制数据的开销,效率更高。

2. O(n)寻找最远点对(欧氏距离)

对于简单闭合多边形(你的数据看起来属于这类),旋转卡壳算法可以在O(n)时间内找到欧氏距离最远的点对,也就是你要的视觉端点:

# 旋转卡壳实现(要求顶点按顺时针/逆时针顺序排列)
max_dist <- 0
best_p1 <- 1
best_p2 <- 2

# 复制顶点数组处理闭合边界
x_ext <- rbind(x, x[1,])

for (i in 1:n) {
  # 移动指针p2,直到下一个点的距离不再增大
  while (sqrt((x_ext[i+1,1]-x_ext[best_p2+1,1])^2 + (x_ext[i+1,2]-x_ext[best_p2+1,2])^2) > 
         sqrt((x_ext[i+1,1]-x_ext[best_p2,1])^2 + (x_ext[i+1,2]-x_ext[best_p2,2])^2)) {
    best_p2 <- best_p2 %% n + 1
  }
  # 计算当前点对的欧氏距离,更新最远点对
  current_dist <- sqrt((x[i,1]-x[best_p2,1])^2 + (x[i,2]-x[best_p2,2])^2)
  if (current_dist > max_dist) {
    max_dist <- current_dist
    final_p1 <- i
    final_p2 <- best_p2
  }
}

cat("找到的端点索引:", final_p1, final_p2, "\n")
cat("端点间欧氏距离:", max_dist, "\n")

这个算法通过双指针遍历,每个指针最多移动n次,总时间复杂度为O(n),针对你的数据应该能精准定位到24和74。

3. 计算两点在环上的两条路径长度

有了累积距离数组,计算两条路径长度就是O(1)的操作:

# 确保索引小的在前,方便计算
if (final_p1 > final_p2) {
  temp <- final_p1
  final_p1 <- final_p2
  final_p2 <- temp
}

# 路径1:从final_p1到final_p2的沿环正向距离
path_length1 <- cum_dist[final_p2] - cum_dist[final_p1]
# 路径2:反向环路径距离,即总周长减去正向距离
path_length2 <- perimeter - path_length1

cat("环上两条路径长度:", path_length1, path_length2, "\n")

为什么你的原代码会出错?

你原代码的思路是寻找“沿环距离为半周长”的点对,但这种点对的欧氏距离不一定是最大的——尤其是当多边形不是正圆形或凸多边形时,半周长对应的点对和视觉上的端点(最远点对)可能完全不重合。而视觉上的端点本质是整个多边形中欧氏距离最远的两个点,所以用旋转卡壳找最远点对才是正确的方向。

内容的提问来源于stack exchange,提问作者Peter.k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:23:06