Пересечение прямой / плоскости на основе точек - PullRequest
5 голосов
/ 08 февраля 2011

У меня есть две точки в пространстве, L1 и L2, которые определяют две точки на линии.

У меня есть три точки в пространстве, P1, P2 и P3, которые имеют 3 точки на плоскости.

Итак, учитывая эти входные данные, в какой точке линия пересекает плоскость?

Fx. уравнение плоскости A * x + B * y + C * z + D = 0 равно:

A = p1.Y * (p2.Z - p3.Z) + p2.Y * (p3.Z - p1.Z) + p3.Y * (p1.Z - p2.Z)
B = p1.Z * (p2.X - p3.X) + p2.Z * (p3.X - p1.X) + p3.Z * (p1.X - p2.X)
C = p1.X * (p2.Y - p3.Y) + p2.X * (p3.Y - p1.Y) + p3.X * (p1.Y - p2.Y)
D = -(p1.X * (p2.Y * p3.Z - p3.Y * p2.Z) + p2.X * (p3.Y * p1.Z - p1.Y * p3.Z) + p3.X * (p1.Y * p2.Z - p2.Y * p1.Z))

А как насчет остальных?

Ответы [ 2 ]

8 голосов
/ 09 февраля 2011

Самый простой (и очень обобщенный) способ решить эту проблему - сказать, что

L1 + x*(L2 - L1) = (P1 + y*(P2 - P1)) + (P1 + z*(P3 - P1))

, что дает вам 3 уравнения в 3 переменных.Решите для x, y и z, а затем подставьте обратно в любое из исходных уравнений, чтобы получить ответ.Это может быть обобщено, чтобы делать сложные вещи, такие как поиск точки, которая является пересечением двух плоскостей в 4 измерениях.вектор, который находится под прямым углом к ​​плоскости.Это означает, что плоскость может быть определена как набор точек P, так что скалярное произведение P и N является скалярным произведением P1 и N.Решение для x такое, что (L1 + x*(L2 - L1)) dot N является этой константой, дает вам одно уравнение в одной переменной, которое легко решить.Если вы собираетесь пересекать много линий с этой плоскостью, этот подход определенно стоит.

В явном виде это дает:

N = cross(P2-P1, P3 - P1)
Answer = L1 + (dot(N, P1 - L1) / dot(N, L2 - L1)) * (L2 - L1)

где

cross([x, y, z], [u, v, w]) = x*u + y*w + z*u - x*w - y*u - z*v
dot([x, y, z], [u, v, w]) = x*u + y*v + z*w

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

1 голос
/ 09 февраля 2011

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

var lv = L2-L1;
var ray = new Microsoft.Xna.Framework.Ray(L1,lv);
var plane = new Microsoft.Xna.Framework.Plane(P1, P2, P3);

var t = ray.Intersects(plane); //Distance along line from L1
///Result:
var x = L1.X + t * lv.X;
var y = L1.Y + t * lv.Y;
var z = L1.Z + t * lv.Z;

Конечно, я бы предпочел иметь только простые уравнения, которые имеют место под прикрытием XNA.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...