WPF 3D: проверьте, может ли куб полностью содержать другой куб

Я работаю над Drop & Drop в 3D. Я создал трехмерные пространства (комнаты) со стенами (кубиками), которые выполняют роль заполнителей для отбрасываемых объектов (например, кубиков меньшего размера).

Как мне разобраться:

если пользователь уронит объект по краям комнаты, то может ли комната полностью содержать этот объект?

То есть я не хочу, чтобы объекты были частично в комнате, а частично снаружи. В идеале я бы отменил операцию перетаскивания / переместил бы ее в точку, чтобы комната безопасно содержала этот объект.

У меня есть границы комнаты и объекта (ModelVisual3D.Content.Bounds) и точки, в которой объект был отброшен.

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

идеи / мысли / указатель оценен.

3 ответа

1. Точка А. (точка может быть углом внутреннего куба CubeIn)

Выберите одну точку из одного куба. (Я предполагаю, что мы должны проверить один куб полностью внутри другого. Значит, пересечения нет).

2. Проверьте A внутри CubeOut (Внешний куб)

3. если A внутри CubeOut, чем CubeIn полностью внутри CubeOut

если точка находится внутри второго куба, это означает, что первый куб находится внутри второго (почему? потому что, если куб находится внутри другого куба. Таким образом, каждая точка на внутреннем кубе будет внутри внешнего куба)

4. Иначе CubeIn не внутри CubeOut

Это будет работать со всеми видами твердого тела (сфера, конус...).

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

Учитывая следующее Box учебный класс:

class Box 
{
  Vector3 minEdge;
  Vector3 maxEdge;
}

Вы можете легко иметь метод внутри Box что тесты на включение:

bool IsInside(Box other)
{
  return maxEdge.X <= other.maxEdge.X &&
         maxEdge.Y <= other.maxEdge.Y &&
         maxEdge.Z <= other.maxEdge.Z &&
         minEdge.X >= other.minEdge.X &&
         minEdge.Y >= other.minEdge.Y &&
         minEdge.Z >= other.minEdge.Z;
}

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

Чтобы упростить перетаскивание в 3D, вы можете внедрить (опционально) систему привязки.

Чтобы проверить, содержит ли ящик другой ящик, просто отметьте все углы ящика. Проверьте каждый угол, чтобы увидеть, находится ли он "внутри" (или снаружи) граней другого блока. Если все углы внутри, коробка внутри.

Это будет работать для всех блоков, а не только для выровненных по оси блоков.

Другие вопросы по тегам