График R rgl в 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, чтобы сжать их, я получаю сообщение об ошибке, что журнал не определен для отрицательных чисел (конечно, это правильно). Как бы вы решили решить эту проблему со сжатием значений осей, когда построение в логарифмическом масштабе не поддерживается?

Я хотел бы поблагодарить вас за ваш ответ С уважением, Алекс


person Alex P    schedule 30.06.2017    source источник


Ответы (1)


Нет смысла применять логарифмическую шкалу к X, Y и Z. Просто примените ее к исходным данным и преобразуйте зарегистрированные значения в полярные координаты.

Поскольку ваши зарегистрированные тестовые значения отрицательны, вы, вероятно, захотите применить смещение; полярные координаты с отрицательными значениями радиуса довольно сложно интерпретировать.

Как только вы это сделаете, вы можете использовать функцию axis3d(), чтобы добавить ось с произвольными метками на график. Например, если вы хотите, чтобы исходная точка соответствовала -50 дБм, вы должны пропустить преобразование в линейные координаты и просто добавить 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) )

Одна моя система выдает такой дисплей:

введите здесь описание изображения

Вы можете добавить круги, чтобы показать, как масштаб продолжается в каждой плоскости. Этот код сделает это:

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)
}

Я нахожу сюжет слишком загруженным добавленными, но вы можете попробовать и решить для себя.

person user2554330    schedule 30.06.2017
comment
Прежде всего, я должен поблагодарить вас (к сожалению, я новый пользователь, поэтому я не уверен, что моя оценка вам зарегистрируется в системе). Отличный ответ, очень хорошо написанный, и вы действительно здорово упростили эту проблему, в то время как я застрял в ненужной форме сложности! В конце я использовал линии 3d, а также добавил три круга в качестве точки отсчета. red,add=TRUE) lines3d(SimpleCircleX,0,SimpleCircleY,col=green,add=TRUE) lines3d(0,SimpleCircleX,... - person Alex P; 03.07.2017