Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

Задачки любителям 3Д

23.06.21 16:06
Re: Задачки любителям 3Д
 
NightWatch коренной житель
NightWatch
в ответ AlexNek 22.06.21 11:50, Последний раз изменено 23.06.21 20:16 (NightWatch)
Нужен видимо еще какой то вектор указывающий направление, потому как можно целый цилиндр параллельных прямых сделать возле центральной.

Именно. Или соглашение, как расположить басис.

В примере я совмещаю ось х с направлющим вектором заданной линии.


using System.Numerics;

float distance = (float)Math.Sqrt(2);
Vector3 pnt1 = new Vector3(1, 0, 0);
Vector3 pnt2 = new Vector3(4, 3, 0);
Vector3 ray = pnt2 - pnt1;

Matrix4x4 rotate1 = Matrix4x4.CreateRotationX(0.0f); // В результате поворачивает полученную линию вокруг заданной (опционально).
Matrix4x4 rotate2 = getRotateMatrix(Vector3.UnitX, Vector3.Normalize(ray)); // Совмещает ось х с направляющим вектором линии
Matrix4x4 rotate = Matrix4x4.Multiply(rotate1, rotate2); // Комбинация

Vector3 axis = Vector3.Transform(Vector3.UnitY, rotate); // Получаем вектор, вдоль которого будем перемещать линию
Matrix4x4 translate = Matrix4x4.CreateTranslation(distance * axis); // Собственно перемещение
pnt1 = Vector3.Transform(pnt1, translate);
pnt2 = Vector3.Transform(pnt2, translate);

// Матрица поворота одного нормализованного вектора к другому. Стырено отсюда https://gist.github.com/kevinmoran/b45980723e53edeb8a5a43c49f134724
private static Matrix4x4 getRotateMatrix(Vector3 v1, Vector3 v2)
{
    Vector3 axis = Vector3.Normalize(Vector3.Cross(v1, v2));
    float dotProduct = Vector3.Dot(v1, v2);
    dotProduct = Math.Max(
        -1.0f,
        Math.Min(1.0f, dotProduct)
    );
    float angleRadians = (float)Math.Acos(dotProduct);
    return Matrix4x4.CreateFromAxisAngle(axis, angleRadians);
}
 

Перейти на