代码之家  ›  专栏  ›  技术社区  ›  Karsten W.

底部R中的旋转箭头

  •  0
  • Karsten W.  · 技术社区  · 6 年前

    在底部R(和 sp ),我希望创建具有预定义形状但以提供的坐标为中心灵活旋转的箭头。我想出了以下函数:

    my_arrow <- function(x,y, rotate=0, col=par("fg"), cex=1) {
        xbase <- c(1.2,0.2,0.2,-1.2, -1.2, 0.2, 0.2)
        ybase <- c(0,1,0.5,0.5,-0.5,-0.5,-1)
        rotM <- matrix(c(cos(rotate*pi/180), sin(rotate*pi/180), -sin(rotate*pi/180), cos(rotate*pi/180)), nrow=2)
        transf <- function(x1,y1) cex * rotM %*% c(x1,y1) + c(x,y)
        ans <- t(mapply(transf, xbase, ybase))
        polygon(x=ans[,1], y=ans[,2], col=col)
    }
    

    这将生成我想要的箭头,如果 rotation=0 ,但当我旋转时,它会扭曲。例如,

    plot(1:2, type="p", col="white", xlim=c(-5,5), ylim=c(-10,10))
    my_arrow(0,0, rotate=45)
    

    生成下面的图表。

    我想我需要应用一些特殊类型的坐标,但我被卡住了。有什么想法吗?

    (The arrows 这个函数对我不起作用,因为我脑子里有另一个形状。使用 gridBase 一些旋转的视口对我来说听起来太夸张了。)

    enter image description here

    1 回复  |  直到 6 年前
        1
  •  0
  •   Karsten W.    6 年前

    检查功能后 shapes::rotatexy ,我自己找到了解决方案:我需要解决纵横比问题。最后,我想出了以下对我来说很有用的函数:

    my_arrow <- function(x,y, rotate=0, col=par("fg"), border=par("fg"), cex=1) {
        scale_base <- strwidth("O")/2.4
        xbase <- c(1.2,0.2,0.2,-1.2, -1.2, 0.2, 0.2) * scale_base
        ybase <- c(0,1,0.5,0.5,-0.5,-0.5,-1) * scale_base
        rotM <- matrix(c(cos(rotate*pi/180), sin(rotate*pi/180), -sin(rotate*pi/180), cos(rotate*pi/180)), nrow=2)
        transf <- function(x1,y1) cex * rotM %*% c(x1,y1) + c(x,y)
        ans <- t(mapply(transf, xbase, ybase))
    
        # this is deliberately taken from shapes::rotatexy
        user <- par("usr")
        pin <- par("pin")
        sy <- user[4] - user[3]
        sx <- user[2] - user[1]
        ans[,2] <- y + (ans[,2]-y) * sy/sx * pin[1]/pin[2]
    
        polygon(x=ans[,1], y=ans[,2], col=col, border=border)
    }
    

    所以,当我打电话时:

    plot(1:2, type="p", col="white", xlim=c(-5,5), ylim=c(-10,10))
    my_arrow(0,0, rotate=45, cex=5)
    

    我得到了我想要的:

    enter image description here