Я отвечаю на это, потому что он впервые появился в Google, когда его спросили о c ++ примере пересечения лучей:)
Код всегда возвращает false, потому что вы вводите здесь if:
if (Dot(normal, ray)) {
return false; // avoid divide by zero
}
И скалярное произведение равно нулю только в том случае, если векторы перпендикулярны, и это тот случай, которого вы хотите избежать (без пересечений), и ненулевые числа истинны в C.Таким образом, решение состоит в том, чтобы отрицать (!) Или сделать Dot (...) == 0.Во всех остальных случаях будет пересечение.
На вычислении пересечения: Все точки X плоскости следуют уравнению
Точка (N, X) = d
Где N - нормаль, а d можно найти, поместив известную точку плоскости в уравнение.
float d = Dot(normal, coord);
На луче все точки s линии могут быть выражены в виде точки p и вектора, задающего направление D :
s = p + x * D
Так что если мы ищем, какой xs находится в плоскости, мы имеем
Точка (N, s) = d Точка (N, p + x * D) = d
Точечное произведение ab равно transpose (a) * b ,Пусть транспонировать (N) будет Nt .
Nt * (p + x * D) = d Nt * p + Nt * D * x = d (x скаляр) x = (d - Nt * p) / (Nt * D) x = (d - точка (N, p)) / точка (N, D)
Что дает нам:
<code>float x = (d - Dot(normal, rayOrigin)) / Dot(normal, ray);
Теперь мы можем получить пересечениеукажите в уравнении строки
x s = p + x * D
<code>Vector intersection = rayOrigin + x*ray;
Вышеуказанный код обновлен:
<code>bool linePlaneIntersection(Vector& contact, Vector ray, Vector rayOrigin,
Vector normal, Vector coord) {
// get d value
float d = Dot(normal, coord);<br/>
if (Dot(normal, ray) == 0) {
return false; // No intersection, the line is parallel to the plane
}<br/>
// Compute the X value for the directed line ray intersecting the plane
float x = (d - Dot(normal, rayOrigin)) / Dot(normal, ray);<br/>
// output contact point
*contact = rayOrigin + normalize(ray)*x; //Make sure your ray vector is normalized
return true;
}
В сторону 1: Что означает значение d ? Для двух векторов
a и
b точечное произведение фактически возвращает длину ортогональной проекции одного вектора на другой, умноженный на этот другой вектор.Но если
a нормализовано (длина = 1),
Dot (a, b) - это длина проекции
b на
a .В случае нашей плоскости
d дает нам направленное расстояние всех точек плоскости в нормальном направлении к началу координат (
a - нормаль).Затем мы можем определить, находится ли точка на этой плоскости, сравнивая длину проекции с нормалью (произведение точек).
В сторону 2: Как проверить, пересекает ли луч треугольник?(Используется для трассировки лучей) Чтобы проверить, входит ли луч в треугольник, заданный 3-мя вершинами, сначала нужно сделать то, что показано здесь, получить пересечение с плоскостью, образованной треугольником.Следующий шаг - посмотреть, лежит ли эта точка в треугольнике.Этого можно достичь, используя барицентрические координаты, которые выражают точку на плоскости как комбинацию трех точек на ней.См.
Барицентрические координаты и преобразование из декартовых координат .