Как вы превращаете куб в сферу?

31

Я пытаюсь сделать четырехугольную сферу на основе статьи , которая показывает результаты, подобные этим:

правильный

Я могу сгенерировать куб правильно:

до

Но когда я конвертирую все точки по этой формуле (со страницы, указанной выше):

формула

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

Моя сфера выглядит так:

после

Как вы можете видеть, края куба все еще высовываются слишком далеко. Куб варьируется от -1до +1по всем осям, как говорится в статье.

Есть идеи, что не так?

Том Даллинг
источник
1
Ваша реализация также содержит проблему "x = x ..." или это только здесь?
snake5
8
Фантастические наглядные пособия. Спасибо за включение тех.
Doppelgreener
2
Чтобы ответить на вопрос в заголовке, вы можете просто нормализовать вершины куба, чтобы сделать его сферой. Распределение вершин, вероятно, будет отличаться от связанного метода.
msell
Связанные: gamedev.stackexchange.com/questions/7189/…
MichaelHouse

Ответы:

27

Вы неправильно написали формулу.

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

Вы модифицируете оригинал xи перезаписываете его. Затем вы модифицируете, yосновываясь не на оригинале, xа на модифицированном x. Затем вы модифицируете zна основе измененной версии обоих .

Сохраните оригиналы и рассчитайте это:

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

Используйте dx, dy и dz с тех пор.

doppelgreener
источник
Упс. Не думал.
Том Даллинг
У вас есть пример источника для вышеуказанной программы?
Вамси