Jak zamieniasz sześcian w kulę?

31

Próbuję stworzyć quad-kulę na podstawie artykułu , który pokazuje takie wyniki:

poprawny

Mogę poprawnie wygenerować kostkę:

przed

Ale kiedy przekonwertuję wszystkie punkty zgodnie z tym wzorem (ze strony, do której prowadzi link powyżej):

formuła

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

Moja kula wygląda następująco:

po

Jak widać, krawędzie sześcianu wciąż wystają zbyt daleko. Sześcian rozciąga się od -1do +1we wszystkich osiach, jak mówi artykuł.

Jakieś pomysły, co jest nie tak?

Tom Dalling
źródło
1
Czy Twoja implementacja zawiera również problem „x = x ...”, czy właśnie tutaj?
snake5
8
Fantastyczne pomoce wizualne. Dziękuję za uwzględnienie tych.
doppelgreener
2
Aby odpowiedzieć na pytanie w tytule, możesz po prostu znormalizować wierzchołki sześcianu, aby stał się kulą. Jednak rozkład wierzchołków będzie prawdopodobnie różny od metody połączonej.
sprzedać

Odpowiedzi:

27

Źle napisałeś formułę.

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

Zmieniasz oryginał xi zastępujesz go. Następnie modyfikujesz ynie w oparciu o oryginał, xale zmodyfikowany x. Następnie modyfikujesz zna podstawie zmodyfikowanej wersji obu tych elementów.

Zachowaj oryginały i oblicz to:

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

Od tego momentu używaj dx, dy i dz.

doppelgreener
źródło
Ups Nie myślałem.
Tom Dalling
czy masz jakieś przykładowe źródło dla powyższego programu?
Vamsi,