Перемещение точек в 3D пространстве

96
24 марта 2021, 02:40

Хочу попрактиковаться за это лето и попробовать написать что-нибудь в 3D с помощью библиотеки System.Windows.Media.Media3D. Даны две точки (не совсем точки, а Vector3D) в 3d пространстве (положение камеры и направление обзора камеры), как можно подвинуть камеру влево и вправо относительно текущего положения. Как я понимаю, нужно найти вектор, который будет параллелен плоскости OZ и перпендикулярен отрезку заключенному между тех двух точек, можете помочь или хотя бы намекнуть на то, как его найти? На парах алгебры мы очень мало проходили векторов, а в интернете не могу найти ничего из того что мне нужно. P.S. у самой камеры в свойствах есть только LookDirection и UpDirection

Правка Нашёл как можно повернуть вектор относительно точки, но не знаю получится ли так:

double X = myPCamera.Position.X + (myPCamera.LookDirection.X - myPCamera.Position.X) * Math.Cos(Math.PI / 2) - (lr.Y - myPCamera.Position.Y) * Math.Sin(Math.PI / 2);
double Y = myPCamera.Position.Y + (myPCamera.LookDirection.Y - myPCamera.Position.Y) * Math.Cos(Math.PI / 2) + (lr.X - myPCamera.Position.X) * Math.Sin(Math.PI / 2);
Answer 1

у самой камеры в свойствах есть только LookDirection и UpDirection

Это по сути все, что нужно для решения задачи. Искомый вектор ортогонален обоим этим векторам, а значит является их векторным произведением - результат нужно лишь умножить на значение, зависящее от направления и величины желаемого перемещения (отрицательное для перемещения влево). Вот демонстрация перемещения влево и вправо по нажатию клавиш-стрелок:

XAML:

<Window x:Class="Wpf3d.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
         WindowState="Maximized" KeyDown="Window_KeyDown" >
    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
          >
        <Viewport3D Name="myViewport" HorizontalAlignment="Stretch"
                    VerticalAlignment="Stretch">
            <!-- Add a camera. -->
            <Viewport3D.Camera>
                <PerspectiveCamera 
                        FarPlaneDistance="20" 
                        LookDirection="0,0,1" 
                        UpDirection="0,1,0" 
                        NearPlaneDistance="1" 
                        Position="0,0,-6" 
                        FieldOfView="45" />
            </Viewport3D.Camera>
            <!-- Add models. -->
            <Viewport3D.Children>
                <ModelVisual3D>
                    <ModelVisual3D.Content>
                        <Model3DGroup >
                            <Model3DGroup.Children>
                                <!-- Lights, MeshGeometry3D and DiffuseMaterial objects are added to the ModelVisual3D. -->
                                <DirectionalLight Color="#FFFFFFFF" Direction="3,-4,5" />
                                <!-- Define a red cone. -->
                                <GeometryModel3D>
                                    <GeometryModel3D.Geometry>

                                        <MeshGeometry3D 
    Positions="0.293893 -0.5 0.404509  0.475528 -0.5 0.154509  0 0.5 0  0.475528 -0.5 0.154509  0 0.5 0  0 0.5 0  0.475528 -0.5 0.154509  0.475528 -0.5 -0.154509  0 0.5 0  0.475528 -0.5 -0.154509  0 0.5 0  0 0.5 0  0.475528 -0.5 -0.154509  0.293893 -0.5 -0.404509  0 0.5 0  0.293893 -0.5 -0.404509  0 0.5 0  0 0.5 0  0.293893 -0.5 -0.404509  0 -0.5 -0.5  0 0.5 0  0 -0.5 -0.5  0 0.5 0  0 0.5 0  0 -0.5 -0.5  -0.293893 -0.5 -0.404509  0 0.5 0  -0.293893 -0.5 -0.404509  0 0.5 0  0 0.5 0  -0.293893 -0.5 -0.404509  -0.475528 -0.5 -0.154509  0 0.5 0  -0.475528 -0.5 -0.154509  0 0.5 0  0 0.5 0  -0.475528 -0.5 -0.154509  -0.475528 -0.5 0.154509  0 0.5 0  -0.475528 -0.5 0.154509  0 0.5 0  0 0.5 0  -0.475528 -0.5 0.154509  -0.293892 -0.5 0.404509  0 0.5 0  -0.293892 -0.5 0.404509  0 0.5 0  0 0.5 0  -0.293892 -0.5 0.404509  0 -0.5 0.5  0 0.5 0  0 -0.5 0.5  0 0.5 0  0 0.5 0  0 -0.5 0.5  0.293893 -0.5 0.404509  0 0.5 0  0.293893 -0.5 0.404509  0 0.5 0  0 0.5 0  " 
    Normals="0.7236065,0.4472139,0.5257313  0.2763934,0.4472138,0.8506507  0.5308242,0.4294462,0.7306172  0.2763934,0.4472138,0.8506507  0,0.4294458,0.9030925  0.5308242,0.4294462,0.7306172  0.2763934,0.4472138,0.8506507  -0.2763934,0.4472138,0.8506507  0,0.4294458,0.9030925  -0.2763934,0.4472138,0.8506507  -0.5308242,0.4294462,0.7306172  0,0.4294458,0.9030925  -0.2763934,0.4472138,0.8506507  -0.7236065,0.4472139,0.5257313  -0.5308242,0.4294462,0.7306172  -0.7236065,0.4472139,0.5257313  -0.858892,0.429446,0.279071  -0.5308242,0.4294462,0.7306172  -0.7236065,0.4472139,0.5257313  -0.8944269,0.4472139,0  -0.858892,0.429446,0.279071  -0.8944269,0.4472139,0  -0.858892,0.429446,-0.279071  -0.858892,0.429446,0.279071  -0.8944269,0.4472139,0  -0.7236065,0.4472139,-0.5257313  -0.858892,0.429446,-0.279071  -0.7236065,0.4472139,-0.5257313  -0.5308242,0.4294462,-0.7306172  -0.858892,0.429446,-0.279071  -0.7236065,0.4472139,-0.5257313  -0.2763934,0.4472138,-0.8506507  -0.5308242,0.4294462,-0.7306172  -0.2763934,0.4472138,-0.8506507  0,0.4294458,-0.9030925  -0.5308242,0.4294462,-0.7306172  -0.2763934,0.4472138,-0.8506507  0.2763934,0.4472138,-0.8506507  0,0.4294458,-0.9030925  0.2763934,0.4472138,-0.8506507  0.5308249,0.4294459,-0.7306169  0,0.4294458,-0.9030925  0.2763934,0.4472138,-0.8506507  0.7236068,0.4472141,-0.5257306  0.5308249,0.4294459,-0.7306169  0.7236068,0.4472141,-0.5257306  0.8588922,0.4294461,-0.27907  0.5308249,0.4294459,-0.7306169  0.7236068,0.4472141,-0.5257306  0.8944269,0.4472139,0  0.8588922,0.4294461,-0.27907  0.8944269,0.4472139,0  0.858892,0.429446,0.279071  0.8588922,0.4294461,-0.27907  0.8944269,0.4472139,0  0.7236065,0.4472139,0.5257313  0.858892,0.429446,0.279071  0.7236065,0.4472139,0.5257313  0.5308242,0.4294462,0.7306172  0.858892,0.429446,0.279071  "                   TriangleIndices="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 " />
                                    </GeometryModel3D.Geometry>
                                    <GeometryModel3D.Material>
                                        <DiffuseMaterial>
                                            <DiffuseMaterial.Brush>
                                                <SolidColorBrush 
                            Color="Red" 
                            Opacity="1.0"/>
                                            </DiffuseMaterial.Brush>
                                        </DiffuseMaterial>
                                    </GeometryModel3D.Material>
                                </GeometryModel3D>
                            </Model3DGroup.Children>
                        </Model3DGroup>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
            </Viewport3D.Children>
        </Viewport3D>
    </Grid>
</Window>

C#:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Media3D;
namespace Wpf3d
{
    public partial class MainWindow : Window
    {
        PerspectiveCamera cam;
        public MainWindow()
        {
            InitializeComponent();
            cam = myViewport.Camera as PerspectiveCamera;
        }  
        private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            double factor = 0.0;
            if (e.Key == Key.Left) factor = -1.0;
            else if (e.Key == Key.Right) factor = 1.0;
            else return;
            Point3D p0 = cam.Position;
            Vector3D L = cam.LookDirection;
            Vector3D U = cam.UpDirection;
            Vector3D normal = Vector3D.CrossProduct(L, U);
            normal.Normalize();
            normal = Vector3D.Multiply(factor, normal);            
            Point3D p = p0 + normal;            
            cam.Position = p;
        }
    }
}
READ ALSO
Вернуть значение из таблицы

Вернуть значение из таблицы

Есть таблица(Table) с полями (Name, age) 1Нужно проверить существование записи в таблице по имени

110
Ползунок диапазона цены jQuery

Ползунок диапазона цены jQuery

Здравствуйте, есть ползунок диапазона ценыВыглядит вот так

111
Wordpress Адаптивный thumbnail

Wordpress Адаптивный thumbnail

Данный код создает thumbnail 150x100 изображения к примеру с размером 500х1000 он берет центр и режет на 150 высотуКак создать thumbnail с адаптивным высотой...

85
Каким образом можно связать python и php через stdin?

Каким образом можно связать python и php через stdin?

У меня есть некий скрипт на python, который служит лаунчером для запуска фриды (https://fridare/docs/functions/)

93