如何依次沿x,y和z轴旋转ModelVisual3D对象的中心

时间:2017-05-09 13:04:04

标签: c# wpf xaml 3d

我有200张照片,我想逐个构建一个有200张照片的立方体。现在我已经建立了立方体,我想完成功能是立方体的中心依次沿x y z轴旋转,现在我已经构建了立方体,并设置了Viewport3D.Camera。我想只旋转立方体,并保持立方体在摄像机视野中,使用C#中的代码来完成功能。 现在我将在xaml和C#中复制我的代码,以帮助您理解我的代码。

我在xaml中的代码:

Window x:Class="ThreeDemensionsCube.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">
<Grid Background="Black" >


    <Viewport3D x:Name="viewport" Margin="0"  Height="319" VerticalAlignment="Top" >
        <ModelVisual3D>
            <ModelVisual3D.Content>
                <Model3DGroup x:Name="group">
                    <!--Ligthts-->
                    <AmbientLight Color="Gray" />
                    <DirectionalLight Color="gray" Direction="1,-1,-1" />
                    <DirectionalLight Color="Gray" Direction="-1,1,1" />
                </Model3DGroup>

            </ModelVisual3D.Content>
        </ModelVisual3D>

        <Viewport3D.Camera>

            <PerspectiveCamera x:Name="camera"
                      Position = "30, 30, 90"
                      LookDirection = "-30, -30, -90"
                      UpDirection = "0, 1, 0"
                      FieldOfView = "60">


                <PerspectiveCamera.Transform>
                    <Transform3DGroup>
                        <RotateTransform3D>
                            <RotateTransform3D.Rotation>
                                <AxisAngleRotation3D
                                          Axis="0 1 0" 
                                          Angle="{Binding ElementName=hscroll, Path=Value}" />
                            </RotateTransform3D.Rotation>
                        </RotateTransform3D>
                        <RotateTransform3D>
                            <RotateTransform3D.Rotation>
                                <AxisAngleRotation3D
                                          Axis="0 0 1" 
                                          Angle="{Binding ElementName=vscroll, Path=Value}" />
                            </RotateTransform3D.Rotation>
                        </RotateTransform3D>
                    </Transform3DGroup>
                </PerspectiveCamera.Transform>


            </PerspectiveCamera>
        </Viewport3D.Camera>
    </Viewport3D>
    <Border VerticalAlignment="Top" HorizontalAlignment="Right"  Background="White" BorderBrush="Bisque" BorderThickness="3,5,3,5">
        <StackPanel>
             <Button Content="processImage" HorizontalAlignment="Left"  VerticalAlignment="Top" Width="75"  Margin="5" Click="processImage"/>
             <Button Content="loadImage" HorizontalAlignment="Left"  VerticalAlignment="Top" Width="75" Margin="5" Click="loadProcessedImage"/>

        </StackPanel>


    </Border>
     <DockPanel>
        <ProgressBar x:Name="pBar" DockPanel.Dock="Bottom" VerticalAlignment="Bottom" Height="9"></ProgressBar>

    </DockPanel>

</Grid>

我在C#中的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;


using System.IO;
using System.Runtime.InteropServices;
using Emgu.CV;
using Emgu.CV.Structure;

using System.Windows.Media.Media3D;

namespace ThreeDemensionsCube
{
    /// <summary>
    /// MainWindow.xaml Interactive logic
    /// </summary>
    public partial class MainWindow : Window
    {
        string appPath = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase+"Images";
        string newAppPath = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "ProcessedImages";

        double a = 0;
        public MainWindow()
        {
            InitializeComponent();

        }
        private void imageProc()
        {
            //define  a DirectoryInfo object
            DirectoryInfo dir = new DirectoryInfo(appPath);
            DirectoryInfo[] listDir = dir.GetDirectories();
            FileInfo[] listFile = dir.GetFiles("*.jpg");
            int picNum = listFile.Length;
            if (picNum > 0)
            {
                //create new file
                string newFileName = appPath.Replace("Images", "ProcessedImages");
                DirectoryInfo newDir = new DirectoryInfo(newFileName);
                newDir.Create();
                for (int i = 0; i < picNum; i++)
                {
                    Image<Bgra, byte> image = new Image<Bgra, byte>(listFile[i].FullName.ToString());
                    Image<Bgra, byte> dst = setAlphaImage(image);

                    string fullFileName = listFile[i].FullName.ToString().Replace("jpg", "png").Replace("Images", "ProcessedImages");

                    dst.ToBitmap().Save(fullFileName);
                    double value = i * 100.0 / picNum;
                    pBar.Dispatcher.Invoke(new Action<System.Windows.DependencyProperty, object>(pBar.SetValue), System.Windows.Threading.DispatcherPriority.Background, ProgressBar.ValueProperty, value);


                }

            }
            else
            {
                MessageBox.Show("please select a valid file")

            }
        }
        private void cubeShow()
        {
            //define a DirectoryInfo object 
            DirectoryInfo dir = new DirectoryInfo(newAppPath);
            DirectoryInfo[] listDir = dir.GetDirectories();
            FileInfo[] listFile = dir.GetFiles("*.png");
            int picNum = listFile.Length;
            if (picNum > 0)
            {
                for(int i=0;i<picNum;i++)
                {
                    a += 0.1;

                    MeshGeometry3D mesh = new MeshGeometry3D();

                    mesh.Positions.Add(new Point3D(a, -10, 10));
                    mesh.Positions.Add(new Point3D(a, -10, -10));
                    mesh.Positions.Add(new Point3D(a, 10, -10));
                    mesh.Positions.Add(new Point3D(a, 10, 10));

                    mesh.TriangleIndices.Add(0);
                    mesh.TriangleIndices.Add(3);
                    mesh.TriangleIndices.Add(2);
                    mesh.TriangleIndices.Add(2);
                    mesh.TriangleIndices.Add(1);
                    mesh.TriangleIndices.Add(0);
                    mesh.TextureCoordinates.Add(new Point(0, 1));
                    mesh.TextureCoordinates.Add(new Point(1, 1));
                    mesh.TextureCoordinates.Add(new Point(1, 0));
                    mesh.TextureCoordinates.Add(new Point(0, 0));

                    mesh.TriangleIndices.Add(0);
                    mesh.TriangleIndices.Add(1);
                    mesh.TriangleIndices.Add(2);
                    mesh.TriangleIndices.Add(2);
                    mesh.TriangleIndices.Add(3);
                    mesh.TriangleIndices.Add(0);
                    mesh.TextureCoordinates.Add(new Point(0, 1));
                    mesh.TextureCoordinates.Add(new Point(1, 1));
                    mesh.TextureCoordinates.Add(new Point(1, 0));
                    mesh.TextureCoordinates.Add(new Point(0, 0));

                    BitmapImage bitmapimage = new BitmapImage(new Uri(listFile[i].FullName.ToString()));
                    Brush brush = new ImageBrush(bitmapimage);
                    GeometryModel3D mGeometry = new GeometryModel3D(mesh, new DiffuseMaterial(brush));
                    mGeometry.Transform = new Transform3DGroup();
                    group.Children.Add(mGeometry);
                    double value = i * 100.0 / picNum;
                    pBar.Dispatcher.Invoke(new Action<System.Windows.DependencyProperty, object>(pBar.SetValue), System.Windows.Threading.DispatcherPriority.Background, ProgressBar.ValueProperty, value);

                }
            }
            else
            {
                MessageBox.Show("please select a valid file");
            }

        }

        private Image<Bgra, byte> setAlphaImage(Image<Bgra, byte> src)
        {

            Image<Bgra, byte> dst = src.Copy();
            int rows = src.Rows;
            int cols = src.Cols;
            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < cols; j++)
                {
                    int blue = src.Data[i, j, 0];
                    int green = src.Data[i, j, 1];
                    int red = src.Data[i, j, 2];
                    //
                    if (Math.Abs(blue - green) < 20 && Math.Abs(blue - red) < 20 && Math.Abs(green - red) < 10)
                    {
                        dst.Data[i, j, 3] = 0;
                    }
                    //
                    else
                    {
                        dst.Data[i, j, 0] = 255;
                        dst.Data[i, j, 1] = 0;
                        dst.Data[i, j, 2] = 0;
                        dst.Data[i, j, 3] = src.Data[i, j, 0];

                    }
                }
            }
            return dst;

        }
        private void processImage(object sender, RoutedEventArgs e)
        {
            imageProc();
        }
        private void loadProcessedImage(object sender,RoutedEventArgs e)
        {
            cubeShow();
        }

    }
}

1 个答案:

答案 0 :(得分:0)

现在,我将发布我的代码,代码的目标是旋转3D立方体对象。

xaml中的代码:

 <PerspectiveCamera.Transform>
                    <Transform3DGroup>
                        <RotateTransform3D>
                            <RotateTransform3D.Rotation>
                                <AxisAngleRotation3D x:Name="rotate3D" 
                                Axis="1,0,0" />
                            </RotateTransform3D.Rotation>
                        </RotateTransform3D>

                    </Transform3DGroup>
                </PerspectiveCamera.Transform>

c#中的代码:

DoubleAnimation rotate = new DoubleAnimation();
        rotate.From = 0;
        rotate.To = 360;
        rotate.Duration = TimeSpan.FromSeconds(6);
       // rotate.RepeatBehavior=new RepeatBehavior(2.5);
        rotate.RepeatBehavior = RepeatBehavior.Forever;
        rotate3D.Axis = new Vector3D(0,1,1);
        rotate3D.Angle = 60;
        rotate3D.BeginAnimation(AxisAngleRotation3D.AngleProperty, rotate);
xaml中的

代码是为了使用PerspectiveCamera.Transform并对其进行配置。 c#中的代码是创建一个doubleAnimation来控制相机。

以上内容仅为个人意见,如有疑问请指正。 现在我将展示我的结果和一些问题。 good result picture

bad result picture

从结果我们可以知道有一些问题,有阴影一方面在糟糕的结果图片中,我该如何删除阴影?