Я пытаюсь найти лучший способ определить, находится ли точка внутри усеченного конуса. У меня есть кое-что работающее, но я не уверен, слишком ли это громоздко, и, возможно, есть более элегантный / эффективный способ, которым я должен это делать.
Предположим, я хочу выяснить, находится ли точка «х» внутри трещины:
После того, как у меня есть местоположения 8 точек усеченного тела (4 ближних точки, четыре дальних точки), я вычисляю нормали для каждой плоскости усеченного конуса на основе треугольника, составленного из трех точек. Например (как на диаграмме выше), для правой стороны я делаю два вектора из трех точек:
Vector U = FBR - NBR
Vector V = FTR - NBR
Затем я делаю перекрестное произведение между этими двумя векторами, гарантируя, что порядок намотки правильный для нормали, указывающей внутри усеченного конуса, в этом случае V x U
даст правильную нормаль.
Right_normal = V x U
Когда у меня есть нормаль для каждой плоскости, я проверяю, находится ли точка x перед или позади плоскости, рисуя вектор из x в одну из точек плоскости:
Vector xNBR = x - NBR
Затем я делаю скалярное произведение между этим вектором и нормалью и проверяю, является ли ответ положительным, подтверждая, является ли точка x правильной стороной этой плоскости усеченного элемента:
if ( xNBR . Right_normal < 0 )
{
return false;
}
else continue testing x against other planes...
Если x положительно для всех плоскостей, то оно находится внутри усеченного конуса.
Так что это похоже на работу, но мне просто интересно, делаю ли я это глупо. До вчерашнего дня я даже не знал, что означает «перекрестный продукт», так что для меня все это довольно ново, и я могу делать что-то довольно глупое.
Чтобы адаптировать выбранный вами подход, а не менять его полностью, вы можете использовать тот факт, что две пары плоскостей параллельны. Создайте только одну нормаль для этой пары самолетов. У вас уже есть тест для точки, находящейся «перед» одной из плоскостей, но предполагая, что вы знаете глубину усеченного конуса, вы можете использовать то же расстояние, чтобы проверить точку относительно другой параллельной грани.
double distancePastFrontPlane = xNBR . Right_normal;
if (distancePastFrontPlane < 0 )
{
// point is in front of front plane
return false;
if(distancePastFrontPlane > depthFaceRtoFaceL)
{
// point is behind back plane
return false;
}
}
Если у вас есть несколько точек для тестирования на одном и том же усечении, вы можете выиграть, потому что вы рассчитываете глубину усеченного коня только один раз (для пары параллельных плоскостей).
Других решений пока нет …