É possível renderizar Graphics3D em um projeção isométrica ? Eu sei que a opção ViewPoint pode ser usada para projeção ortogonal especificando, por exemplo, ViewPoint -> {0, Infinity, 0}. No entanto, isso não leva vários infinitos, então não posso fazer ViewPoint -> {Infinity, -Infinity, Infinity}, por exemplo.

Percebo que poderia conseguir isso girando a cena inteira cerca de dois eixos e usando uma projeção ortogonal:

Graphics3D[ Rotate[ Rotate[ Cuboid[{-.5, -.5, -.5}], Pi/4, {0, 0, 1} ], ArcTan[1/Sqrt[2]], {0, 1, 0} ], ViewPoint -> {-Infinity, 0, 0} ] 

No entanto, isso é bastante complicado e “é mais difícil descobrir as rotações corretas para o ponto de vista I” estou interessado. Prefiro apenas especificar o octante a partir do qual visualizar a cena isometricamente. Existe realmente uma maneira “adequada” de fazer isso?

Comentários

  • Fiz uma projeção isométrica aqui: mathematica.stackexchange.com/questions/28000/isometric-3d-plot/… .
  • @ MichaelE2 Ah, tudo bem, eu apenas li o corpo da pergunta e não ' não vi o que isso tinha a ver com plotagem isométrica (deveria li os comentários também). Mas acho que sua abordagem é semelhante à minha, exceto que usar dois vetores para a rotação é óbvio muito mais simples do que usar dois ângulos.

Resposta

A partir da V11.2, podemos usar uma combinação de ViewProjection e ViewPoint :

Graphics3D[Cuboid[], ViewProjection -> "Orthographic", ViewPoint -> {1, 1, 1}] 

Várias vantagens:

v = Tuples[{Tuples[{-1, 1}, 3], IdentityMatrix[3]}]; Graphics3D[Cuboid[{-.5, -.5, -.5}, {1., 2., 4}], ViewProjection -> "Orthographic", ViewPoint -> #1, ViewVertical -> #2] & @@@ v 

insira a descrição da imagem aqui

Resposta

[Editar aviso: Atualizado para permitir a configuração da direção vertical do gráfico e para corrigir um erro .]

Aqui está uma ligeira generalização da minha resposta para Gráfico 3D isométrico . Para obter uma visão isométrica, precisamos construir um ViewMatrix que irá girar um vetor da forma {±1, ±1, ±1} para {0, 0, 1} e projete ortogonalmente nas duas primeiras coordenadas.

ClearAll[isometricView]; isometricView[ g_Graphics3D, (* needed only for PlotRange *) v_ /; Equal @@ Abs[N@v] && 1. + v[[1]] != 1., (* view point {±1, ±1, ±1} *) vert_: {0, 0, 1}] := (* like ViewVertical; default: z-axis *) {TransformationMatrix[ RescalingTransform[ EuclideanDistance @@ Transpose[Charting`get3DPlotRange@ g] {{-1/2, 1/2}, {-1/2, 1/2}, {-1/2, 1/2}}]. RotationTransform[{-v, {0, 0, 1}}]. RotationTransform[{vert - Projection[vert, v], {0, 0, 1} - Projection[{0, 0, 1}, v]}]. RotationTransform[Mod[ArcTan @@ Most[v], Pi], v]. TranslationTransform[-Mean /@ (Charting`get3DPlotRange@ g)]], {{0, 1, 0, 0}, {1, 0, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}}; foo = Graphics3D[Cuboid[{-.5, -.5, -.5}, {1., 2., 4}]]; Show[foo, ViewMatrix -> isometricView[foo, {1, 1, 1}, {0, 0, 1}], ImagePadding -> 20, Axes -> True, AxesLabel -> {x, y, z}] Show[foo, ViewMatrix -> isometricView[foo, {-1, 1, 1}, {1, 1, 0}], ImagePadding -> 20, Axes -> True, AxesLabel -> {x, y, z}] 

Gráficos do Mathematica Gráficos do Mathematica

Todas as combinações de pontos de vista e eixos verticais:

Gráficos do Mathematica

Notes:

Obter um intervalo preciso do gráfico que inclua o preenchimento é importante para a computação a matriz de visualização correta. Existem alternativas para a função interna não documentada Charting`get3DPlotRange. Alexey Popkov tem um método aqui: Como obter o PlotRange real usando AbsoluteOptions? Usei PlotRange /. AbsolutOptions[g, PlotRange] e multipliquei por 1.02 (Não me lembro por que não algo como 1.04) para aproximar o preenchimento em minha resposta a Gráfico em 3D isométrico .

Meu recurso básico para entender ViewMatrix foi especialmente a resposta de Heike para Extraia valores para ViewMatrix de um Graphics3D .

Esta atualização é uma resposta a Yves “ comentário. Trabalhar com os eixos me fez perceber que o sistema de coordenadas é invertido (de “destro” para “canhoto). Portanto, mudei a projeção de IdentityMatrix[4] para uma que inverte as coordenadas x & y.

Pode ser um boa ideia Deploy os gráficos para evitar a rotação do mouse. Quando os gráficos são girados, o front end redefine o ViewMatrix de uma forma bastante feia.

Comentários

  • Muito bom – é possível alinhar o eixo z verticalmente?
  • @YvesKlett Isso foi um pouco mais difícil do que eu pensei que seria, principalmente porque eu havia entendido algo errado.
  • Incrível! Isso será útil!

Resposta

Você pode usar a seguinte postagem função de processo para aplicar uma projeção paralela geral:

parallelProjection[g_Graphics3D, axes_, pad_: 0.15] := Module[{pr3, pr2, ar, t}, pr3 = {-pad, pad} (#2 - #) & @@@ # + # &@Charting`get3DPlotRange@g; pr2 = MinMax /@ Transpose[[email protected]]; ar = Divide @@ Subtract @@@ pr2; t = AffineTransform@Append[Transpose@axes, {0, 0, -1}]; t = RescalingTransform@Append[pr2, pr3[[3]]].t; Show[g, AspectRatio -> 1/ar, ViewMatrix -> {TransformationMatrix[t], IdentityMatrix[4]}]]; 

Aqui axes define a projeção de x, y, eixos z para o plano 2d e pad abre espaço para exibir os rótulos dos eixos.

Projeção isométrica:

g = Graphics3D[Cuboid[], Axes -> True, AxesLabel -> {X, Y, Z}]; parallelProjection[g, {{-Sqrt[3]/2, -1/2}, {Sqrt[3]/2, -1/2}, {0, 1}}] 

insira a descrição da imagem aqui

Projeção do gabinete:

α = π/4; parallelProjection[g, {{1, 0}, {0, 1}, -{Cos[α]/2, Sin[α]/2}}] 

insira a descrição da imagem aqui

Resposta

Apenas no caso de você não estar procurando uma solução completamente correta, mas sim apenas uma solução alternativa barata.

Eu estava procurando um ViewPoint->{Infinity,Infinity, Infinity} tipo de solução. Substituindo o Infinity por um número grande o suficiente (no meu caso, 500), poderia obter os resultados que estava procurando.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *