2017-06-30 5 views
0

avant de partager mon problème, je veux partager un peu de code qui pourrait être utile pour certaines personnes à l'extérieur. J'ai regardé assez de code temporel pour tracer dans les mesures d'antenne 3D mais je n'ai pas pu trouver le code qui fait cela. Le problème est que les mesures d'antenne ont des coordonnées polaires et que les fonctions de tracé 3D typiques utilisent des coordonnées cartésiennes. Donc, mon code ci-dessous fait juste cela (je ne suis pas un programmeur avancé donc je suis sûr que quelqu'un pourrait être en mesure de l'optimiser pour son utilisation). Le code peut être exécuté directement et j'ai ajouté des commentaires pour le rendre plus lisible.R égler le graphe d'échelle logarithmique en 3D et les tracés de motifs d'antennes

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) 

Le problème que j'ai maintenant que mon tracé idéalement, je voudrais être sur une échelle logarithmique que le paquet de RGL ne supporte pas! Si j'essaie d'utiliser le log sur mon X, Y, Z pour les compresser, j'obtiens une erreur que le log n'est pas défini pour les nombres négatifs (bien sûr c'est correct). Comment penseriez-vous résoudre ce problème en compressant les valeurs des axes lorsque le tracé de l'échelle logarithmique n'est pas supporté?

Je voudrais vous remercier pour votre réponse Cordialement Alex

Répondre

0

Il n'a pas de sens d'appliquer une échelle logarithmique à X, Y et Z. Il suffit d'appliquer à vos données originales, et transformer les valeurs enregistrées aux coordonnées polaires. Puisque vos valeurs de test enregistrées sont négatives, vous voudrez probablement appliquer un décalage; les coordonnées polaires avec des valeurs de rayon négatives sont assez difficiles à interpréter. Une fois que vous avez fait cela, vous pouvez utiliser la fonction axis3d() pour ajouter un axe avec des étiquettes arbitraires au graphique. Par exemple, si vous souhaitez que l'origine corresponde à -50 dBm, vous devez ignorer la transformation en coordonnées linéaires et ajouter simplement 50. Vous devez annuler cette opération lorsque vous calculez des étiquettes. Voici votre exemple, modifié:

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

Un mon système il produit cet affichage:

enter image description here

Vous pouvez ajouter des cercles pour montrer comment l'échelle continue autour de chaque plan. Ce code ferait:

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

je trouve l'intrigue trop occupé avec ceux ajoutés, mais vous pouvez l'essayer et de décider par vous-même.

+0

Tout d'abord je dois vous remercier (je suis malheureusement un nouvel utilisateur, donc je ne suis pas sûr que mon évaluation à vous enregistre dans le système). Bonne réponse, très très bien écrite et vous avez vraiment simplifié énormément ce problème, alors que j'étais coincé dans une forme de complexité inutile! A la fin j'ai utilisé le lines3d et j'ai aussi ajouté trois cercles comme point de référence SimpleCircleX <-turnPolarToX (Minimum, 1: 359) SimpleCircleY <-turnPolarToY (Minimum, 1: 359) lines3d (SimpleCircleX, SimpleCircleY, 0 , col = "rouge", ajouter = TRUE) lines3d (SimpleCircleX, 0, SimpleCircleY, col = "vert", ajouter = TRUE) lines3d (0, SimpleCircleX, ... –