Страницы

Поиск по вопросам

воскресенье, 26 января 2020 г.

Построить 4 нормальные прямые в пространстве от центра фигуры

#c_sharp #unity3d #вычислительная_геометрия


Здравствуйте!
Собственно, реализую редактор поверхностей, основная проблема встала с расчётом "габаритов"
кисточки, а точнее, поверхности в пространстве, попадающей под эту самую кисточку.



Привожу максимально урезанный рабочий код сего действа:

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

namespace EngineEditor.Terrain {

    /// 
    /// Режим редактирования
    /// 
    public enum EEditorMode : int {
        ModeAdd    = 0x00, // режим добавления
        ModeDelete = 0x01, // режим удаления
        ModePick   = 0x02  // режим захвата
    };

    public class Test : EditorWindow {

        private static Color designAddColor = new Color(0.15f, 1.0f, 0.15f);
        private static Color textColor      = new Color(0.9f, 0.9f, 0.9f);
        private static float brushSize      = 1.1f;

        private EEditorMode  currentMode    = EEditorMode.ModeAdd;

        private bool selectModeOn = false;

        [MenuItem("Test/Editor")]
        public static void ShowWindow() {
            EditorWindow window = EditorWindow.GetWindow(typeof(Test));
            window.titleContent = new GUIContent("...");
        }

        void OnGUI() {

        }

        void OnFocus() {
            SceneView.onSceneGUIDelegate -= this.OnSceneGUI;
            SceneView.onSceneGUIDelegate += this.OnSceneGUI;
        }

        void OnDestroy() {
            SceneView.onSceneGUIDelegate -= this.OnSceneGUI;
        }

        /// 
        /// Метод обрабатывающий задобренный объект
        /// 
        /// 
        /// Объект, до которого дотронулись лучи добра
        private void OnRaycast(SceneView sceneView, RaycastHit hitInfo) {

            Collider collider   = hitInfo.collider;
            Vector3 cameraPoint = sceneView.camera.transform.position + sceneView.camera.transform.forward
+ sceneView.camera.transform.right;
            Quaternion startRot = Quaternion.LookRotation(hitInfo.normal);


            switch (currentMode) {
                case EEditorMode.ModeAdd:
                    Handles.color = designAddColor;
                    break;
            }

            Handles.DrawLine(hitInfo.point, cameraPoint);

                // рисуем кисточку
            Handles.CircleCap(0, hitInfo.point, startRot, brushSize);

            Handles.color = textColor;

            Handles.Label(collider.transform.position, new GUIContent(Utils.ToString(collider.transform.position)),
EditorStyles.boldLabel);
            Handles.Label(hitInfo.point, new GUIContent("\n"+Utils.ToString(hitInfo.normal)+"\n"+Utils.ToString(hitInfo.barycentricCoordinate)));
            Handles.Label(hitInfo.point, Utils.ToString(startRot));

            sceneView.Repaint();
        }

        /// 
        /// Отрисовка в окне сцены
        /// 
        /// 
        public void OnSceneGUI(SceneView sceneView) {

            Selection.activeObject = null;

            Vector3 mousePosition = new Vector3(Event.current.mousePosition.x, sceneView.camera.pixelHeight
- Event.current.mousePosition.y, 0);
            RaycastHit hitInfo = new RaycastHit();
            Ray ray = sceneView.camera.ScreenPointToRay(mousePosition); // генерируем
луч добра

            if (Physics.Raycast(ray, out hitInfo)) // одобряем всё и вся нашим лучом
                OnRaycast(sceneView, hitInfo);

        }


    }

}


Покажу схематично саму кисточку:


Собственно, что я знаю:


Известна середина фигуры point{x,y,z}
Известны углы этой фигуры rect{x,y,z} и вращение quaternion{x,y,z,w}
Известен размер кисти (в данном случае - сторона квадрата)


Сам вопрос:


Каким образом я могу вычислить координаты v1,v2,v3,v4, чтобы провести линии


от point до v1,
от point до v2,
от point до v3,
от point до v4?



Если получится их вычислить, решиться проблема с обнаружением поверхности под кисточкой
(обычными вычитаниями).

Возможно ли, что я не правильно подхожу к задаче, и данные точки можно не вычислять,
а каким то чудесным образом получить единичные вектора direction из центра к каждой
из этих точек?
    


Ответы

Ответ 1



VladD Хм. А почему не так: вектор MV1 = quaternion * (-d/2, 0, 0), отсюда V1 = M + MV1 (M — центр, d — сторона). – VladD 4 мин. назад Дал самое простое и понятное решение! Огромное спасибо, я просто не знал что в unity перегружены операции кватернионов с векторами (facepalm), пинать меня за это надо. Ещё раз Спасибо!

Комментариев нет:

Отправить комментарий