Можно использовать простой трассировочный трюк для проверки, если вы находитесь внутри или снаружи формы. Оказывается, что двумерные, трехмерные объекты или, возможно, даже более крупные размерные объекты имеют аккуратное свойство. То есть, если вы снимаете произвольный луч в любом направлении, находящемся внутри фигуры, если и только если вы нажмете границы своей фигуры и нечетное число раз. Не нужно знать нормальное направление или что-то еще. Просто знайте, сколько пересечений у вас есть. Это легко визуализировать в 2D, и поскольку 3D - это просто много 2D-фрагментов, то это относится и к 3D.
![enter image description here](https://i.stack.imgur.com/F6Sdk.png)
фигура 1: Стрельба луч из точки в произвольном направлении производит нечетное число ударов, если внутри и даже если снаружи, так O_1 внутри и O_2 нет. В качестве особого случая оглядывающие хиты должны быть проверены на кривые, потому что они делают два удара совпадающими в одном месте (O_3).
![enter image description here](https://i.stack.imgur.com/4E7cf.png)
фигура 2: Смыкались поверхности имеют лучшее граничное условие, как только вершина хитов поглядывая Однако большинство трассировки двигателей игнорируют поглядывая хиты полностью перпендикулярные хиты (O_4) будут проблематичны, так что они ведут себя правильно для целей этого теста. Трассировка майя не является исключением.
Обратите внимание, что этот метод не требует закрытой поверхности, он работает, тем не менее он просто закрывает зазор в направлении луча, а открытые поверхности могут сообщать о странных результатах. Но может быть приемлемым в некоторых случаях.
Понятно, что трассировка лучей довольно тяжелая операция без подпрограмм ускорения, однако она становится довольно быстрой, когда ускорение на месте. Maya API предоставляет метод для этого. Обратите внимание, что ускоритель построен сначала, а затем каждый последующий вызов намного дешевле. Вот быстро написано эшафот без ускорения см документации для MFnMesh для получения дополнительной информации о том, как ускорить:
import maya.cmds as cmd
import maya.OpenMaya as om
def test_if_inside_mesh(point=(0.0, 0.0, 0.0), dir=(0.0, 0.0, 1.0)):
sel = om.MSelectionList()
dag = om.MDagPath()
#replace torus with arbitrary shape name
sel.add("pTorusShape1")
sel.getDagPath(0,dag)
mesh = om.MFnMesh(dag)
point = om.MFloatPoint(*point)
dir = om.MFloatVector(*dir)
farray = om.MFloatPointArray()
mesh.allIntersections(
point, dir,
None, None,
False, om.MSpace.kWorld,
10000, False,
None, # replace none with a mesh look up accelerator if needed
False,
farray,
None, None,
None, None,
None
)
return farray.length()%2 == 1
#test
cmd.polyTorus()
print test_if_inside_mesh()
print test_if_inside_mesh((1,0,0))
В вашем конкретном случае это может быть излишним. Я предполагаю, что вы делаете какую-то отбраковку. Также возможно построить тело из призм и рандомизировать с помощью барицентрических подобных координат. Это имеет то преимущество, что никогда не тратишь впустую результаты. Но трассировочный код намного проще использовать.
Удивительный. Большое спасибо! – chribis