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

基于R Grid包的圆周角度绘制方案技术求助

问题解决:用Grid包在圆周边缘正确绘制角度(地理坐标系)

你遇到的核心问题是地理坐标系角度与数学坐标系的转换不匹配,以及箭头绘制的逻辑错误。circular包的geographics模板采用正北为0度、顺时针递增的规则,但默认三角函数是数学坐标系(右为0度、逆时针递增),同时你用viewport旋转的方式绘制箭头也不符合需求。以下是修正方案:

错误点分析

  1. 角度坐标转换错误:地理坐标系的角度(正北0°,顺时针)不能直接代入数学三角函数计算,需要转换为对应的数学坐标系角度。
  2. 箭头绘制逻辑错误:通过旋转viewport绘制箭头会导致坐标偏移,应该直接计算箭头端点的笛卡尔坐标。
  3. 重复pushViewport:代码中多次重复推送同一位置的viewport,造成坐标混乱。

修正后的完整代码

library(grid)

# 数据准备
limits <- data.frame(lims = c(57, 75, 42))
angles <- read.table(text ='
degree Year
    120  2000
     30  2001
  160  2002
    35 2003
   150  2004    
   90  2005
    70  2006
      20  2007', header = TRUE)

# 适配地理坐标系的坐标转换函数
# 地理坐标系:正北为0°,顺时针递增
circ_coords_geo <- function(r, t_deg, h = 0.5, k = 0.5) {
  t_rad <- t_deg * pi / 180
  # 转换为数学坐标系计算:正北对应y轴正方向,顺时针转等价于角度取负
  x <- h + r * sin(t_rad)
  y <- k + r * cos(t_rad)
  return(c(X = x, Y = y))
}

# 绘制圆周点的函数
angles_custom <- function(angles_df, r = 0.5) {
  lapply(1:nrow(angles_df), function(i) {
    coord <- circ_coords_geo(r, angles_df$degree[i])
    grid.points(x = coord["X"], y = coord["Y"], gp = gpar(pch = 16, col = "black"))
  })
}

# 绘制角度箭头的函数(从中心指向圆周外)
limits_custom <- function(limits_df, r_inner = 0.5, r_outer = 0.6) {
  lapply(1:nrow(limits_df), function(i) {
    t <- limits_df$lims[i]
    # 箭头起点(圆周边缘)和终点(圆周外)
    start <- circ_coords_geo(r_inner, t)
    end <- circ_coords_geo(r_outer, t)
    # 绘制线段+箭头
    grid.segments(x0 = start["X"], y0 = start["Y"], 
                  x1 = end["X"], y1 = end["Y"],
                  gp = gpar(lty = 5, lwd = 2, col = c("red", "red", "blue")[i]))
    grid.arrows(x0 = start["X"], y0 = start["Y"], 
                x1 = end["X"], y1 = end["Y"],
                gp = gpar(col = c("red", "red", "blue")[i]), length = unit(0.05, "npc"))
  })
}

# 主绘图逻辑
grid.newpage()
# 创建主viewport(避免重复推送)
pushViewport(viewport(x = 0.5, y = 0.5, width = 1, height = 1))
# 绘制外圆
grid.circle(x = 0.5, y = 0.5, r = 0.5, gp = gpar(lwd = 3, col = "black"))
# 绘制十字参考线
grid.segments(x0 = 0.5, y0 = 0, x1 = 0.5, y1 = 1, gp = gpar(col = "grey"))
grid.segments(x0 = 0, y0 = 0.5, x1 = 1, y1 = 0.5, gp = gpar(col = "grey"))
# 绘制圆周点和角度箭头
angles_custom(angles)
limits_custom(limits)
popViewport()

关键修正说明

  • 坐标转换适配地理坐标系:将地理角度转换为数学坐标时,使用sin计算x值、cos计算y值,匹配正北为0°顺时针的规则。
  • 直接计算箭头坐标:不再通过旋转viewport,而是直接计算箭头起点(圆周边缘)和终点(圆周外)的坐标,确保箭头指向正确角度。
  • 简化viewport层级:只推送一次主viewport,避免坐标混乱。
  • 添加箭头样式:用grid.arrows直接绘制箭头,替代单纯的线段,更符合需求。

内容的提问来源于stack exchange,提问作者Lisa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 02:58:25