Visualisation de lignes 3D en rotation

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Visualisation de lignes 3D en rotation

Messagepar Christophe Genolini » 23 Mai 2008, 15:02

Bonjour a tous,

J ai fait un petit script pour visualiser des trajectoires (des lignes) en 3D.

Code : Tout sélectionner

### Directement executable
plot3Dlines <- function(x,angle=20,delais=100000,color,...){
    time <- 1:dim(x)[[2]]
    var1 <- seq(min(x[,,1],na.rm=TRUE),max(x[,,1],na.rm=TRUE),length.out=11)
    var2 <- matrix(NA,length(time),length(var1))#outer(x, y, NA)
    var2[1,1] <- min(x[,,2],na.rm=TRUE)
    var2[length(time),length(var1)] <- max(x[,,2],na.rm=TRUE)
    nbLines<-min(100,dim(x)[1])
    if(missing(color)){color<-2:(nbLines+1)}else{}
    repeat{
        res <- persp(x=time, y=var1, z=var2, theta = angle, phi = 10, expand = 0.5, col = "lightblue",
                 ltheta = 120, shade = 0.75, ticktype = "detailed",xlab = "time", ylab = "var1", zlab = "var2")
        angle <- angle+1
        for(i in 1:nbLines){
            yy=x[i,,1]
            zz=x[i,,2]
            lines (trans3d(time, yy, zz, pmat = res),col=color[i])
        }
        for(k in 1:delais){}
    }
}

### Tiny exemple
data <- array(c(13,14,13,15, 14,15,16,15, 16,17,16,18 , 45,46,85,59, 43,58,70,56, 45,75,65,65),
                dim=c(4,3,2),dimnames=c("id","temps","var"))
plot3Dlines(data)

### Exemple reel
maxId <- 120
maxTime <- 15
f <- function(id,t)((id-1)%%3-1)*t*1.5
g <- function(id,t)((id-1)%%2+1)*t^2/10
data2 <- array(cbind(outer(1:maxId,1:maxTime,f),outer(1:maxId,1:maxTime,g))+
rnorm(maxId*maxTime*2,0,2),dim=c(maxId,maxTime,2) )
plot3Dlines(data2,col=rep(2:7,floor(maxId/6)))



Je ne sais pas vous, moi je trouve ca plutot beau ;-)
Mais reste deux problèmes :

1) Pendant la rotation, la boite change de taille
2) Les lignes sont tracées les une apres les autres. La dernière ligne tracée sera donc au premier plan, même si elle est sensé être cachée. Cela est du au fait que je trace les ligne grâce a lines(trans3d(....)). Il serait bien mieux de faire quelque chose de global genre matplot(trans3d(....)) mais je n ai pas réussi...

Quelqu'un a-t-il une idée pour améliorer ?

Christophe

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Messagepar Logez Maxime » 23 Mai 2008, 16:27

Bonjour,

Peut-être faire la même chose mais avec la librairie rgl :

Code : Tout sélectionner

plot3Dlinesrgl <- function(x,angle=20,delais=100000,color,...){
  require(rgl)
  X <- array(NA,dim=dim(data2)+c(0,0,1))
  X[,,2:3] <- data2
  X[,,1] <- matrix(rep(1:dim(data2)[[2]],dim(X)[1]),byrow=TRUE,nrow=dim(X)[1])
  if (missing(color))
    color<- 1:dim(X)[1]
  open3d()
  for (i in 1:dim(X)[1]){
    lines3d(X[i,,][,c(1,3,2)],col=color[i])
    }
    box3d()
    max1 <- apply(X,3,max)
    max1 <- max(max1)/max1
    max1 <- max1/max(max1)
    aspect3d(max1)
    for (i in 1:delais){
      rgl.viewpoint(i,20)
      }
    }
plot3Dlinesrgl(data2)


Maxime

Renaud Lancelot
Messages : 2484
Enregistré le : 16 Déc 2004, 08:01
Contact :

Messagepar Renaud Lancelot » 23 Mai 2008, 17:47

Joli code (dans les deux cas). Je ne sais pas répondre aux questions de Christophe. J'ai édité le code de Maxime qui faisait référence à data2 (au lieu de x):

Code : Tout sélectionner

plot3Dlinesrgl <- function(x, angle = 20, delais = 100000, color, ...){
  require(rgl)
  X <- array(NA, dim = dim(x) + c(0, 0, 1))
  X[ , , 2:3] <- x
  X[ , , 1] <- matrix(rep(1:dim(x)[[2]], dim(X)[1]), byrow = TRUE, nrow = dim(X)[1])
  if (missing(color))
    color <- 1:dim(X)[1]
  open3d()
  for (i in 1:dim(X)[1]){
    lines3d(X[i, , ][ , c(1, 3, 2)], col = color[i])
    }
    box3d()
    max1 <- apply(X, 3, max)
    max1 <- max(max1)/max1
    max1 <- max1/max(max1)
    aspect3d(max1)
    for (i in 1:delais){
      rgl.viewpoint(i,20)
      }
    }


Christophe Genolini
Messages : 698
Enregistré le : 12 Juin 2006, 21:37
Contact :

Messagepar Christophe Genolini » 23 Mai 2008, 23:05

J'achete carrement !

Deux mini modifications :
- delais servait dans ma version a ralentir la rotation
- Je suppose que le calcul de max1 (que j'ai renomé dimBox) sert a calculer la taille de la boite. Personnellement, je la préfere a c(1,1,1).

Code : Tout sélectionner

plot3Dlinesrgl <- function(x, angle = 20, delais = 100000, color, dimBox,...){
  require(rgl)
  X <- array(NA, dim = dim(x) + c(0, 0, 1))
  X[ , , 2:3] <- x
  X[ , , 1] <- matrix(rep(1:dim(x)[[2]], dim(X)[1]), byrow = TRUE, nrow = dim(X)[1])
  if (missing(color)){color <- 1:dim(X)[1]}else{}
  open3d()
  for (i in 1:dim(X)[1]){
    lines3d(X[i, , ][ , c(1, 3, 2)], col = color[i])
  }
  box3d()
  if (missing(dimBox)){
    dimBox <- apply(X, 3, max)
    dimBox <- max(dimBox)/dimBox
    dimBox <- dimBox/max(dimBox)
  }else{}
  aspect3d(dimBox)
  angle <-0
  repeat{
    for (pause in 1:delais){}
    angle <- (angle+1)%%360
    rgl.viewpoint(angle,20)
  }
}
plot3Dlinesrgl(data2,dimBox=c(1,1,1),color=rep(1:6,20))


Excellent ! Merci beaucoup.

Christophe


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité