Сделать кольцо векторов «плоским» относительно мирового пространства - PullRequest
0 голосов
/ 15 января 2020

Я пытаюсь смоделировать соответствие жидкости в контейнере. Контейнер представляет собой цилиндр Unity и жидкость. Я отслеживаю текущий объем и максимальный объем и использую их для определения координат центра того места, где должна быть поверхность. Когда контейнер наклонен, каждая вершина в верхнем кольце цилиндра должна сохранять свои текущие локальные значения x и z, но иметь новое локальное значение y, равное высоте в глобальном пространстве с центром поверхности.

В моей ближайшей попытке поверхность является плоской относительно мирового пространства, но жидкость не касается стенок контейнера.

Vector3 v = verts[i];

Vector3 newV = new Vector3(v.x, globalSurfaceCenter.y, v.z);
verts[i] = transform.InverseTransformPoint(newV);

(я понимаю, что инвертирование точки после использования vx и vz меняет их , но если я изменю их после того факта, что поверхность больше не будет плоской ...)

Я перепробовал много разных подходов, и я всегда оказываюсь в одной и той же точке или более странном.

Кроме того, я не ищу какой-либо принципиально иной подход к проблеме. Важно, чтобы я изменил вершины цилиндра.

РЕДАКТИРОВАТЬ

Спасибо всем за ваши отзывы. Это помогло мне добиться прогресса в решении этой проблемы, но я достиг другого контрольно-пропускного пункта. Я сделал свой код более презентабельным и сделал несколько снимков экрана с некоторыми результатами, а также графическую модель, чтобы помочь вам визуализировать происходящее и дать имена переменных для ссылки.

На следующих изображениях цветные кубики создаются и получают координаты некоторых векторов, которые я использую для получения результатов.

F (красный) A (зеленый) B (синий)

H (зеленый) E (синий)

Графическая модель

ПРИМЕЧАНИЕ: когда я ссылаюсь на заглавные буквы A и B, я имею в виду Vector3 в моем код.

Цилиндры на изображениях имеют следующие повороты (слева направо): (0,0,45) (45,45,0) (45,0,20)

Как видно из рисунка 1, F является правильным, когда применяется только одно измерение вращения. Когда применяются два или более, поверхность является плоской, но не ориентированной правильно.

Если я отрегулирую вращение цилиндра после получения этих результатов, я могу получить ориентацию поверхности, чтобы иметь смысл, но число не соответствует ожидаемому.

Например: для цилиндра 3 (с правой стороны), отрегулированного так, чтобы поверхность была плоской относительно мирового пространства, потребуется вращение примерно на (42,2, 0, 27,8) .

Не уверен, что это полезно, но это вызывает у меня путаницу.

Мой код: (см. Модель переменных для имен переменных)

Vector3 v = verts[iter];

Vector3 D = globalSurfaceCenter;
Vector3 E = transform.TransformPoint(new Vector3(v.x, surfaceHeight, v.z));
Vector3 H = new Vector3(gsc.x, E.y, gsc.z);

float a = Vector3.Distance(H, D);
float b = Vector3.Distance(H, E);
float i = (a / b) * a;

Vector3 A = H - D;
Vector3 B = H - E;
Vector3 F = ((A + B)) + ((A + B) * i);

Instantiate(greenPrefab, transform).transform.position = H;
Instantiate(bluePrefab, transform).transform.position = E;

//Instantiate(redPrefab, transform).transform.position = transform.TransformPoint(F);
//Instantiate(greenPrefab, transform).transform.position = transform.TransformPoint(A);
//Instantiate(bluePrefab, transform).transform.position = transform.TransformPoint(B);

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

Имейте в виду, что я менее чем разбираюсь в геометрии и математике в генеральный. Пожалуйста, используйте условия Laymans. Спасибо!

И еще раз спасибо, что нашли время помочь мне.

1 Ответ

0 голосов
/ 15 января 2020

В качестве первого шага мы можем вычислить нормаль верхней поверхности цилиндра в локальной системе координат цилиндра. Учитывая мировое преобразование вашего цилиндра transform, это просто:

localNormal = inverse(transform) * (0, 1, 0, 0)

Используя эту нормаль и высоту цилиндра h, мы можем определить плоскость верхнего цилиндра в нормальной форме как

dot(localNormal, (x, y, z) - (0, h / 2, 0)) = 0

Я предполагаю, что ваш цилиндр центрирован вокруг начала координат.

Используя это, мы можем вычислить y -координату для любой пары x/z как

y = h / 2 - (localNormal.x * x + localNormal.z * z) / localNormal.y
...