Existe-t-il un moyen de tracer une surface comme un ellipsoïde avec une tracée 3D?

Actuellement, seules les surfaces de la forme z = f (x, y) sont discutées dans les documents. Il existe également des Mesh 3D, mais je n'ai trouvé aucun exemple. Il semble possible de faire une triangulation de l'ellipsoïde manuellement puis d'utiliser le maillage pour obtenir l'ellipsoïde, mais cela me semble un peu difficile. Y a-t-il une meilleure façon de le faire?

2
Ilya V. Schurov 6 mars 2016 à 03:20

3 réponses

Meilleure réponse

D'accord, c'est plus facile que je ne le pensais. Il existe une option alphahull qui demande de manière parcellaire de calculer automatiquement la triangulation correspondante.

from plotly.offline import iplot, init_notebook_mode
from plotly.graph_objs import Mesh3d
from numpy import sin, cos, pi

# some math: generate points on the surface of ellipsoid

phi = np.linspace(0, 2*pi)
theta = np.linspace(-pi/2, pi/2)
phi, theta=np.meshgrid(phi, theta)

x = cos(theta) * sin(phi) * 3
y = cos(theta) * cos(phi) * 2
z = sin(theta)

# to use with Jupyter notebook

init_notebook_mode()

iplot([Mesh3d({
                'x': x.flatten(), 
                'y': y.flatten(), 
                'z': z.flatten(), 
                'alphahull': 0
})])

Ellipsoid

Et ceci est la version R:

library(pracma)
theta <- seq(-pi/2, pi/2, by=0.1)
phi <- seq(0, 2*pi, by=0.1)
mgrd <- meshgrid(phi, theta)
phi <- mgrd$X
theta <-  mgrd$Y
x <- cos(theta) * cos(phi) * 3
dim(x) <- NULL
y <- cos(theta) * sin(phi) * 2
dim(y) <- NULL
z <- sin(theta) * scale
dim(z) <- NULL

ell <- cbind(x, y, z)

ell <- setNames(ell, c('x', 'y', 'z'))

library(plotly)
p <- plot_ly(as.data.frame(ell), x=x, y=y, z=z, type='mesh3d', alphahull = 0)

p %>% layout(scene = list(aspectmode = 'data'))

EDIT: il est également possible d'utiliser type='surface' pour produire des tracés paramétriques: dans ce cas, il faut fournir des x et y bidimensionnels.

library(plotly)
library(pracma)
mgrd <- meshgrid(seq(-pi, pi, length.out = 100), seq(-pi/2, pi/2, length.out = 100))
U <- mgrd$X
V <- mgrd$Y
frame <- list(x=cos(V)*cos(U)*3, y=cos(V)*sin(U)*2, z=sin(V))
plot_ly(frame, type='surface', x=x, y=y, z=z, showlegend=F, showscale=F,
        colorscale=list(list(0, 'blue'), list(1, 'blue')))
6
Ilya V. Schurov 6 mars 2016 à 21:00

Pourquoi ne pas résoudre z dans cette équation extraite de l'élément mathématique sur les ellipsoïdes:

enter image description here

require(plotly)
a=5; b=7; c=9
x=rep(seq(-10,10,by=1), each=21)
y=rep( seq(-10,10,by=1), times=21)
z <- c^2*sqrt(1-x^2/a^2-y^2/b^2)
#Warning message:
#In sqrt(1 - x^2/a^2 - y^2/b^2) : NaNs produced

 plot_ly(z = matrix(z,21,21), type = "surface")

enter image description here

1
42- 6 mars 2016 à 00:52

En supposant que l'ellipsoïde est donné par l'équation (X-c)'A(X-c) = r.

library(Rvcg)
sphr <- vcgSphere()
library(rgl)
ell <- scale3d(transform3d(sphr, chol(A)), r, r, r)
vs <- ell$vb[1:3,] + c
idx <- ell$it - 1
library(plotly)
p <- plot_ly(type="mesh3d",
  x = vs[1,], y = vs[2,], z = vs[3,],
  i = idx[1,], j = idx[2,], k = idx[3,],
  opacity = 0.3) 
2
Stéphane Laurent 18 août 2018 à 08:18