Como você transforma um cubo em uma esfera?

31

Estou tentando criar uma esfera quadrada com base em um artigo , que mostra resultados como este:

corrigir

Eu posso gerar um cubo corretamente:

antes

Mas quando eu converter todos os pontos de acordo com esta fórmula (da página vinculada acima):

Fórmula

    x = x * sqrtf(1.0 - (y*y/2.0) - (z*z/2.0) + (y*y*z*z/3.0));
    y = y * sqrtf(1.0 - (z*z/2.0) - (x*x/2.0) + (z*z*x*x/3.0));
    z = z * sqrtf(1.0 - (x*x/2.0) - (y*y/2.0) + (x*x*y*y/3.0));

Minha esfera fica assim:

depois de

Como você pode ver, as bordas do cubo ainda se destacam demais. O cubo varia de -1a +1em todos os eixos, como diz o artigo.

Alguma ideia do que está errado?

Tom Dalling
fonte
1
A sua implementação também contém o problema "x = x ..." ou é apenas aqui?
snake5
8
Recursos visuais fantásticos. Obrigado por incluí-los.
Doppelgreener
2
Para responder à pergunta no título, você pode normalizar os vértices do cubo para torná-lo uma esfera. A distribuição dos vértices provavelmente será diferente do método vinculado.
msell

Respostas:

27

Você escreveu errado a fórmula.

x = x * sqrtf(1.0 - (y*y/2.0) - (z*z/2.0) + (y*y*z*z/3.0));
y = y * sqrtf(1.0 - (z*z/2.0) - (x*x/2.0) + (z*z*x*x/3.0));
z = z * sqrtf(1.0 - (x*x/2.0) - (y*y/2.0) + (x*x*y*y/3.0));

Você modifica o original xe o substitui. Então você modifica com ybase não no original, xmas no modificado x. Em seguida, você modifica com zbase na versão modificada de ambos .

Preserve os originais e calcule:

float dx = x * sqrtf(1.0 - (y*y/2.0) - (z*z/2.0) + (y*y*z*z/3.0));
float dy = y * sqrtf(1.0 - (z*z/2.0) - (x*x/2.0) + (z*z*x*x/3.0));
float dz = z * sqrtf(1.0 - (x*x/2.0) - (y*y/2.0) + (x*x*y*y/3.0));

Use dx, dy e dz a partir de então.

doppelgreener
fonte
Ops. Não estava pensando.
Tom Dalling
você tem alguma fonte de amostra para o programa acima?
Vamsi