Функция, которая определяет, пересекает ли луч объект

У меня есть функция, которая определяет, пересекает ли луч объект, но он работает с радиусом вокруг центра объекта, я хочу, чтобы он работал с ограничивающей рамкой, я хочу дать ему 2 Vector3D от ограничительной рамки, и один вектор происхождения луча и один из направления луча, и он будет рассчитывать, если есть пересечение, кто-нибудь может мне помочь с этим? какая математическая формула для этого?

intersectRay (источник:Vector3D, каталог:Vector3D):

1 ответ

Нашел решение. 1. Я использую ограничивающую рамку из 8 точек, каждая для каждого угла. 2. Я использовал эту функцию, чтобы назначить каждой точке положение x и y на 2D-плоскости, таким образом я превратил 3D-задачу в 2D-задачу, где x и y - это горизонтальный угол точки относительно положения камеры и вертикальный угол относительно точки положения камеры:

    public function AngleBetween2vectors(v1:Vector3D,v2:Vector3D):Point
    {
        var angleX:Number = Math.atan2(v1.x-v2.x,v1.z-v2.z);
        angleX = angleX*180/Math.PI;

        var angleY:Number = Math.atan2(v1.y-v2.y,v1.z-v2.z);
        angleY = angleY*180/Math.PI;

        return new Point(angleX,angleY);

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

  2. Затем я использую этот алгоритм, чтобы определить, находится ли точка щелчка мыши внутри этого многоугольника или за его пределами:

        private function pnpoly( A:Array,p:Point ):Boolean
    {
        var i:int;
        var j:int;
        var c:Boolean = false;
        for( i = 0, j = A.length-1; i < A.length; j = i++ ) {
            if( ( ( A[i].y > p.y ) != ( A[j].y > p.y ) ) &&
                ( p.x < ( A[j].x - A[i].x ) * ( p.y - A[i].y ) / ( A[j].y - A[i].y ) + A[i].x ) )
            {
                c = !c;
            }
        }
        return c;
    }
    
  3. Затем я измеряю расстояние до объекта и выбираю ближайший к положению камеры, используя эту функцию:

        public function DistanceBetween2Vectors(v1:Vector3D,v2:Vector3D):Number
    {
        var a:Number = Math.sqrt(Math.pow((v1.x-v2.x),2)+Math.pow((v1.y-v2.y),2));
        var b:Number = Math.sqrt(Math.pow((v1.z-v2.z),2)+Math.pow((v1.y-v2.y),2));
        return Math.sqrt(Math.pow(a,2)+Math.pow(b,2));
    }
    

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

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