代码之家  ›  专栏  ›  技术社区  ›  Alex P

R rgl 3d对数比例图和天线方向图

  •  0
  • Alex P  · 技术社区  · 7 年前

    首先,在分享我的问题之前,我想分享一些代码,这些代码可能对外面的一些人有所帮助。我一直在寻找一些时间代码来绘制3d天线测量,但我找不到这样的代码。问题是天线测量具有极坐标,典型的3d绘图函数使用笛卡尔坐标。所以我下面的代码就是这么做的(我不是一个高级程序员,所以我相信有人能够优化它的使用)。代码可以直接运行,我添加了注释以使其更易于阅读。

    require("rgl")
    require("fields")
    degreeToRadian<-function(degree){
      return   (0.01745329252*degree)
    }
    
    turnPolarToX<-function(Amplitude,Coordinate){
      return (Amplitude*cos(degreeToRadian(Coordinate)))
    }
    
    turnPolarToY<-function(Amplitude,Coordinate){
      return (Amplitude*sin(degreeToRadian(Coordinate)))
    }
    
    
    #  inputs for the code
    test<-runif(359,min=-50,max=-20) # the 359 elements correspond to the polar coordinates of 1 to 359
    test2<-runif(359,min=-50,max=-20)  # the 359 elements correspond to the polar coordinates of 1 to 359
    test3<-runif(359,min=-50,max=-20)  # the 359 elements correspond to the polar coordinates of 1 to 359
    
    # My three input vectors above are considered to be dBm values, typically unit for antenna or propagation measurements
    # I want to plot those on three different 3d planes the XY, the YZ and the ZX. Since the rgl does not support
    # polar coordinates I need to cast my polar coordinates to cartesian ones, using the three functions
    # defined at the beginning. I also need to change my dBm values to their linear relative ones that are the mW
    
    
    # Convert my dBm to linear ones
    test<-10^(test/10)
    test2<-10^(test2/10)
    test3<-10^(test3/10) 
    
    # Start preparing the data to be plotted in cartesian domain
    X1<-turnPolarToX(test,1:359)
    Y1<-turnPolarToY(test,1:359)
    Z1<-rep(0,359)
    
    
    X2<-turnPolarToX(test2,1:359)
    Y2<-rep(0,359)
    Z2<-turnPolarToY(test2,1:359) 
    
    X3<-rep(0,359)
    Y3<-turnPolarToX(test3,1:359)
    Z3<-turnPolarToY(test3,1:359)
    
    
    # Time for the plotting now
    
    Min<-min(test,test2,test3)
    Max<-max(test,test2,test3)
    
    bgplot3d( suppressWarnings ( 
        image.plot( legend.only=TRUE, legend.args=list(text='dBm/100kHz'), zlim=c(Min,Max),col=plotrix::color.scale(seq(Min,Max,length.out=21),c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)))
        ) # zlim is the colorbar numbers
    ) 
    
    # for below alternatively you can also use the lines3d to get values
    points3d(X1,Y1,Z1,col=plotrix::color.scale(test,c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)),add=TRUE)
    points3d(X2,Y2,Z2,col=plotrix::color.scale(test2,c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)),add=TRUE)
    points3d(X3,Y3,Z3,col=plotrix::color.scale(test3,c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)),add=TRUE)
    

    我现在的问题是,我的绘图理想情况下,我希望在rgl数据包不支持的对数尺度上!如果我尝试在X,Y,Z上使用log来压缩它们,我会得到一个错误,即log没有定义为负数(当然这是正确的)。当不支持对数比例打印时,您认为如何解决压缩轴值的问题?

    谢谢你的回复 亚历克斯

    1 回复  |  直到 7 年前
        1
  •  0
  •   user2554330    7 年前

    将对数比例应用于X、Y和Z没有意义。只需将其应用于原始数据,并将记录的值转换为极坐标。

    完成后,可以使用axis3d()函数将带有任意标签的轴添加到绘图中。例如,如果您希望原点对应于-50 dBm,您可以跳过到线性坐标的转换,只需添加50。在计算标签时,您需要撤消此操作。以下是您的示例,已修改:

    require("rgl")
    require("fields")
    degreeToRadian<-function(degree){
      return   (0.01745329252*degree)
    }
    
    turnPolarToX<-function(Amplitude,Coordinate){
      return (Amplitude*cos(degreeToRadian(Coordinate)))
    }
    
    turnPolarToY<-function(Amplitude,Coordinate){
      return (Amplitude*sin(degreeToRadian(Coordinate)))
    }
    
    
    #  inputs for the code
    test<-runif(359,min=-50,max=-20) # the 359 elements correspond to the polar coordinates of 1 to 359
    test2<-runif(359,min=-50,max=-20)  # the 359 elements correspond to the polar coordinates of 1 to 359
    test3<-runif(359,min=-50,max=-20)  # the 359 elements correspond to the polar coordinates of 1 to 359
    
    # Add an offset of 50 to the values.
    
    test <- test + 50
    test2 <- test2 + 50
    test3 <- test3 + 50
    
    # Start preparing the data to be plotted in cartesian domain
    X1<-turnPolarToX(test,1:359)
    Y1<-turnPolarToY(test,1:359)
    Z1<-rep(0,359)
    
    
    X2<-turnPolarToX(test2,1:359)
    Y2<-rep(0,359)
    Z2<-turnPolarToY(test2,1:359) 
    
    X3<-rep(0,359)
    Y3<-turnPolarToX(test3,1:359)
    Z3<-turnPolarToY(test3,1:359)
    
    
    # Time for the plotting now
    
    Min<-min(test,test2,test3)
    Max<-max(test,test2,test3)
    
    bgplot3d( suppressWarnings ( 
        image.plot( legend.only=TRUE, legend.args=list(text='dBm/100kHz'), zlim=c(Min,Max)-50,col=plotrix::color.scale(seq(Min-50,Max-50,length.out=21),c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)-50))
        ) # zlim is the colorbar numbers
    ) 
    
    # for below alternatively you can also use the lines3d to get values
    points3d(X1,Y1,Z1,col=plotrix::color.scale(test,c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)),add=TRUE)
    points3d(X2,Y2,Z2,col=plotrix::color.scale(test2,c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)),add=TRUE)
    points3d(X3,Y3,Z3,col=plotrix::color.scale(test3,c(0,1,1),c(0,1,0),0,xrange=c(Min,Max)),add=TRUE)
    
    # Add axes
    
    labels <- pretty(c(-50, -20))
    axis3d("x", at = labels + 50, labels = labels, pos = c(NA, 0, 0) )
    axis3d("y", at = labels + 50, labels = labels, pos = c(0, NA, 0) )
    axis3d("z", at = labels + 50, labels = labels, pos = c(0, 0, NA) )
    

    在我的系统中,它产生了这样的显示:

    enter image description here

    您可能需要添加圆,以显示比例如何在每个平面上继续。这段代码可以做到:

    theta <- seq(0, 2*pi, len = 100)
    for (i in seq_along(labels)) {
      x <- (labels[i] + 50)*cos(theta)
      y <- (labels[i] + 50)*sin(theta)
      lines3d(x, y, 0)
      lines3d(x, 0, y)
      lines3d(0, x, y)
    }