Как рассчитать вращение для коробки на основе набора из четырех точек?

Я немного новичок в работе с трехмерным пространством и вращением. У меня есть список из четырех точек Vector3, представляющих углы прямоугольника. Что я хочу сделать, так это использовать эти точки для создания блочной сетки, которая поворачивается так, чтобы точно соответствовать углу поворота точек.

Вот демонстрация детской площадки babylonjs, показывающая, что я имею в виду. На нем вы можете видеть, что я нарисовал простую линейную сетку между точками. Это здорово, и нарисованный прямоугольник находится под ожидаемым углом с учетом данных. Я также создал блочную сетку и настроил ее размеры так, чтобы они совпадали, и поместил ее центральную точку в правильный центр точек. Пока все хорошо, однако я не могу понять, как повернуть коробку так, чтобы ее верхняя грань была параллельна грани прямоугольника.

https://playground.babylonjs.com/#SN5K8L#2

var createScene = function () {
    // This creates a basic Babylon Scene object (non-mesh)
    var scene = new BABYLON.Scene(engine);
    // This creates and positions a free camera (non-mesh)
    var target = new BABYLON.Vector3(1.5, 4, 0)
    var camera = new BABYLON.ArcRotateCamera("camera1", Math.PI / 2 + Math.PI, Math.PI / 4, 10, target, scene)
    // This attaches the camera to the canvas
    camera.attachControl(canvas, true);
    // This creates a light, aiming 0,1,0 - to the sky (non-mesh)
    var light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
    // Default intensity is 1. Let's dim the light a small amount
    light.intensity = 0.7;

    const axes = new BABYLON.AxesViewer(scene)

    const points = [
        new BABYLON.Vector3(1, 5, 1),
        new BABYLON.Vector3(2, 5, 1),
        new BABYLON.Vector3(2, 3, -1),
        new BABYLON.Vector3(1, 3, -1)
    ]

    const lines = BABYLON.MeshBuilder.CreateLines("lines", {
        points: [...points, points[0]] // add a duplicate of first point to close polygon
    }, scene)

    const centerPoint = new BABYLON.Vector3(
        (points[0].x + points[1].x + points[2].x + points[3].x) / 4,
        (points[0].y + points[1].y + points[2].y + points[3].y) / 4,
        (points[0].z + points[1].z + points[2].z + points[3].z) / 4
    )

    const width = Math.sqrt(
      Math.pow(points[1].x - points[0].x, 2) +
      Math.pow(points[1].y - points[0].y, 2) +
      Math.pow(points[1].z - points[0].z, 2)
    )

    const depth = Math.sqrt(
      Math.pow(points[2].x - points[1].x, 2) +
      Math.pow(points[2].y - points[1].y, 2) +
      Math.pow(points[2].z - points[1].z, 2)
    )

    const height = 0.15

    const box = BABYLON.CreateBox("box", { width, height, depth}, scene)
    box.position = centerPoint
    //box.rotation = ???

    return scene;
};
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать Vector3.RotationFromAxis для вычисления требуемого поворота в углах Эйлера:

const rotationAxisX = points[1].subtract(points[0])
const rotationAxisZ = points[1].subtract(points[2])
const rotationAxisY = rotationAxisZ.cross(rotationAxisX)

// RotationFromAxis has the side effect of normalising the input vectors
// so retrieve the box dimensions here
const width = rotationAxisX.length()
const depth = rotationAxisZ.length()
const height = 0.15

const rotationEuler = BABYLON.Vector3.RotationFromAxis(
    rotationAxisX, 
    rotationAxisY, 
    rotationAxisZ
)

const box = BABYLON.CreateBox("box", { width, height, depth}, scene)
box.position = centerPoint
box.rotation = rotationEuler

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