Проецирование объекта в сцену только на основе мировых координат - PullRequest
2 голосов
/ 01 июня 2010

Я хочу поместить трехмерное изображение в основу сцены по мировым / глобальным координатам. У меня есть изображение сцены. Изображение было снято по некоторой глобальной координате (x1, y1, z1). Мне дан объект, который нужно поместить в эту сцену на основе ее глобальной координаты (x2, y2, y3). Этот объект необходимо проецировать на сцену точно так же, как в перспективе.

Пример может помочь прояснить это. Представьте, что есть автостоянка с некоторым набором глобальных координат. Снимок части парковки. Координаты от места, где было снято изображение, записывается. Цель состоит в том, чтобы разместить виртуальное транспортное средство на этом изображении, используя глобальные координаты для этого транспортного средства. Поскольку глобальные координаты транспортного средства могут не совпадать с глобальными координатами изображения, я предполагаю, что мне понадобятся координаты изображения, угол и, возможно, поле обзора.

3D-графика - это не моя область, поэтому я смотрю на http://en.wikipedia.org/wiki/Perspective_projection#Perspective_projection. Я также смотрю на Matrix3DProjection, которое, возможно, является тем, что я ищу, но оно работает только в Silverlight, и я пытаюсь сделать это в WPF. В моем представлении мне кажется, что мне нужно определить координаты (X, Y, Z), которые находятся в поле зрения изображения, определить преобразование мировой координаты в пиксели, а затем точно спроецировать транспортное средство на изображение, придав ему правильную перспективу, так что выглядит 3D, т.е. чем меньше, тем дальше больше, ближе

Есть ли в WPF функция, которая может помочь с этим, или мне нужно заново изучать матрицы и делать это вручную?

1 Ответ

3 голосов
/ 05 июня 2010

Я не уверен, что понимаю, почему это сложно. Если я вас правильно понимаю, все, что вам нужно сделать, это установить преобразования для ваших объектов Model3D. Я предполагаю, что у вас уже есть объекты Model3D для вашей модели автомобиля (Model3DGroup или GeometryModel3D). Вот как вы можете комбинировать это с изображением сцены:

  1. Используйте любые удобные координаты в Model3D, представляющие модель вашего автомобиля, затем добавьте Transform3DGroup, состоящую из ScaleTransform3D, RotateTransform3D и TranslateTransform3D, чтобы определить размер и расположить модель вашего автомобиля в глобальных координатах

  2. Создайте GeometryModel3D для сцены, используя ImageBrush для материала, простую прямоугольную Geometry3D и Transform3DGroup, состоящую из ScaleTransform3D, TranslateTransform3D, RotateTransform3D и TranslateTransform3D для определения размера и расположения сцены (см. Код комментарии ниже для деталей)

  3. Создание Viewport3DVisual, используя PerspectiveCamera и содержащее Model3DVisual, содержащее Model3DGroup, содержащую AmbientLight плюс модели, созданные на шагах 1 и 2

Так что XAML будет выглядеть примерно так:

...
<Viewport3DVisual>

  <!-- the camera -->
  <Viewport3DVisual.Camera>
    <PerspectiveCamera ... camera parameters ... />
  </Viewport3DVisual.Camera>

  <ModelVisual3D>
    <ModelVisual3D.Content>
      <Model3DGroup>

        <!-- the light -->
        <AmbientLight ... light parameters ... />

        <!-- the car model -->
        <Model3DGroup>
          <Model3DGroup.Transform>
            <Transform3DGroup>
              <ScaleTransform3D    ... scale car to proper size ... />
              <RotateTransform3D   ... face car in proper direction ... />
              <TranslateTranform3D ... move car to proper global coordinates ... />
            </Transform3DGroup>
          </Model3DGroup.Transform>

          ... GeometryModel3D or Model3DGroup for the car model goes here ...

        </Model3DGroup>

        <!-- the scene image -->
        <GeometryModel3D>

          <GeometryModel3D.Material>
            <ImageBrush ImageSource=... scene image ... />
          </GeometryModel3D.Material>

          <GeometryModel3D.Geometry>
            <MeshGeometry3D Positions="0,0,0 1,0,0 1,1,0 0,1,0" Indices="0,1,2 2,3,0" />
          </GeometryModel3D.Geometry>

          <GeometryModel3D.Transform>
            <Transform3DGroup>
              <ScaleTransform3D     ... scale scene to apparent size ... />
              <TranslateTransform3D ... translate scene along Z axis to apparent distance from camera ... />
              <RotateTransform3D    ... rotate distanced scene to original camera orientation ... />
              <TranslateTransform3D ... move to global coordinates of original camera location ... />
            </Transform3DGroup>
          </GeometryModel3D.Transform>

        </GeometryModel3D>

      </Model3DGroup>
    </ModelVisual3D.Content>
  </ModelVisual3D>
</Viewport3DVisual>

Обратите внимание, что изображение сцены устанавливается с использованием видимого размера и расстояния, а не поля зрения. Выберите большое видимое расстояние для изображения сцены, чтобы оно всегда было позади модели автомобиля. Вычислите видимый размер следующим образом:

var verticalFieldOfView = 60.0;    // Degrees
var horizontalFieldOfView = 60.0;  // Degrees
SceneApparentDistance = 1000.0;    // In global coordinate units

SceneApparentHeight = image.Height * SceneApparentDistance * Math.Tan(verticalFieldOfView * Math.Pi/180));
SceneApparentWidth = image.Width * SceneApparentDistance * Math.Tan(horizontalFieldOfView * Math.Pi/180));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...