Я пытался @ Билл ответить , и это на самом деле не работает каждый раз, что я могу объяснить. На основании ссылки в его коде. Давайте, например, эти два отрезка AB и CD .
A = (2,1,5), B = (1,2,5) и C = (2,1,3) и D = (2,1,2)
когда вы пытаетесь получить перекресток, он может сказать вам, что это точка А (неверная) или пересечения нет (правильная). В зависимости от порядка размещения этих сегментов.
x = A + (B-A) s
х = С + (Д-С) т
Билл решен за с , но никогда не решен t . А поскольку вы хотите, чтобы эта точка пересечения находилась на обоих отрезках, оба значения s и t должны быть из интервала <0,1> . Что на самом деле происходит в моем примере, так это то, что только s , если из этого интервала и t равно -2. A лежит на линии, определяемой C и D , но не на отрезке CD .
var s = Vector3.Dot(Vector3.Cross(dc, db), Vector3.Cross(da, db)) / Norm2(Vector3.Cross(da, db));
var t = Vector3.Dot(Vector3.Cross(dc, da), Vector3.Cross(da, db)) / Norm2(Vector3.Cross(da, db));
где da - это B-A, db - это D-C, а dc - это C-A, я просто сохранил имена, предоставленные Биллом.
Тогда, как я уже сказал, вы должны проверить, являются ли оба s и t от <0,1> , и вы можете вычислить результат. На основе формулы выше.
if ((s >= 0 && s <= 1) && (k >= 0 && k <= 1))
{
Vector3 res = new Vector3(this.A.x + da.x * s, this.A.y + da.y * s, this.A.z + da.z * s);
}
Еще одна проблема с ответом Билла - это когда две линии коллинеарны и имеется более одной точки пересечения. Там будет деление на ноль. Вы хотите этого избежать.