2009-08-13 3 views
2

В flash10 I can легко поворачивайте изображение вокруг своего центра в трехмерном пространстве.Как я могу сделать 3D-преобразование в WPF?

Flash10 пример у меня есть на http://jsc.sourceforge.net/examples/web/MatrixStuffExample/Application.htm alt text http://jsc.sourceforge.net/examples/web/MatrixStuffExample/assets/MatrixStuffExample/Preview.png

Я хочу перенести этот пример WPF.

Есть ли пример, как сделать такое 3D-преобразование в WPF внутри C# без XAML?

В silverlight 3 вы будете использовать Matrix3DProjection. Как бы вы реализовали WPF?

ответ

6

Я установил базовый тонкий куб и повернул его вокруг, чтобы вы могли видеть, как преобразование работает через C#.

Настройте Viewport в XAML

<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <StackPanel> 

     <Viewport3D Name="mainViewport" ClipToBounds="True" HorizontalAlignment="Stretch" Height="300"> 
      <Viewport3D.Camera> 
       <PerspectiveCamera 
         LookDirection="0,0,-20" 
         UpDirection="0,1,0" 
         Position="0,0,50" 
         /> 
      </Viewport3D.Camera> 
      <ModelVisual3D> 
       <ModelVisual3D.Content> 
        <Model3DGroup x:Name="group3d"> 

         <SpotLight Position="10,10,10" x:Name="mySpotLight" Color="Yellow" InnerConeAngle="15" OuterConeAngle="100" Range="100" /> 
        </Model3DGroup> 
       </ModelVisual3D.Content> 

      </ModelVisual3D> 
     </Viewport3D> 

    </StackPanel> 
</Window> 

И ЭРВО код позади, преобразование является последним методом ... надеюсь, что это помогает ... дайте мне окрик, если вы хотите получить больше информации!

public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent(); 
     Init(); 
    } 


    private Timer _timer; 
    private ModelVisual3D _model = new ModelVisual3D(); 
    private double _angle = 0; 

    public void Init() 
    { 
     _model = GetCube(GetSurfaceMaterial(Colors.Red), new Point3D(10, 10, 1), new Point3D(-10,-10,-1)); 
     mainViewport.Children.Add(_model);  
     _timer = new Timer(10); 
     _timer.Elapsed += TimerElapsed; 
     _timer.Enabled = true; 
    } 

    void TimerElapsed(object sender, ElapsedEventArgs e) 
    { 
     Dispatcher.Invoke(DispatcherPriority.Normal, new Action<double>(Transform), 0.5d); 
    } 

    public MaterialGroup GetSurfaceMaterial(Color colour) 
    { 
     var materialGroup = new MaterialGroup(); 
     var emmMat = new EmissiveMaterial(new SolidColorBrush(colour)); 
     materialGroup.Children.Add(emmMat); 
     materialGroup.Children.Add(new DiffuseMaterial(new SolidColorBrush(colour))); 
     var specMat = new SpecularMaterial(new SolidColorBrush(Colors.White), 30); 
     materialGroup.Children.Add(specMat); 
     return materialGroup; 
    } 

    public ModelVisual3D GetCube(MaterialGroup materialGroup, Point3D nearPoint, Point3D farPoint) 
    { 
     var cube = new Model3DGroup(); 
     var p0 = new Point3D(farPoint.X, farPoint.Y, farPoint.Z); 
     var p1 = new Point3D(nearPoint.X, farPoint.Y, farPoint.Z); 
     var p2 = new Point3D(nearPoint.X, farPoint.Y, nearPoint.Z); 
     var p3 = new Point3D(farPoint.X, farPoint.Y, nearPoint.Z); 
     var p4 = new Point3D(farPoint.X, nearPoint.Y, farPoint.Z); 
     var p5 = new Point3D(nearPoint.X, nearPoint.Y, farPoint.Z); 
     var p6 = new Point3D(nearPoint.X, nearPoint.Y, nearPoint.Z); 
     var p7 = new Point3D(farPoint.X, nearPoint.Y, nearPoint.Z); 
     //front side triangles 
     cube.Children.Add(CreateTriangleModel(materialGroup, p3, p2, p6)); 
     cube.Children.Add(CreateTriangleModel(materialGroup, p3, p6, p7)); 
     //right side triangles 
     cube.Children.Add(CreateTriangleModel(materialGroup, p2, p1, p5)); 
     cube.Children.Add(CreateTriangleModel(materialGroup, p2, p5, p6)); 
     //back side triangles 
     cube.Children.Add(CreateTriangleModel(materialGroup, p1, p0, p4)); 
     cube.Children.Add(CreateTriangleModel(materialGroup, p1, p4, p5)); 
     //left side triangles 
     cube.Children.Add(CreateTriangleModel(materialGroup, p0, p3, p7)); 
     cube.Children.Add(CreateTriangleModel(materialGroup, p0, p7, p4)); 
     //top side triangles 
     cube.Children.Add(CreateTriangleModel(materialGroup, p7, p6, p5)); 
     cube.Children.Add(CreateTriangleModel(materialGroup, p7, p5, p4)); 
     //bottom side triangles 
     cube.Children.Add(CreateTriangleModel(materialGroup, p2, p3, p0)); 
     cube.Children.Add(CreateTriangleModel(materialGroup, p2, p0, p1)); 
     var model = new ModelVisual3D(); 
     model.Content = cube; 
     return model; 
    } 

    private Model3DGroup CreateTriangleModel(Material material, Point3D p0, Point3D p1, Point3D p2) 
    { 
     var mesh = new MeshGeometry3D(); 
     mesh.Positions.Add(p0); 
     mesh.Positions.Add(p1); 
     mesh.Positions.Add(p2); 
     mesh.TriangleIndices.Add(0); 
     mesh.TriangleIndices.Add(1); 
     mesh.TriangleIndices.Add(2); 
     var normal = CalculateNormal(p0, p1, p2); 
     mesh.Normals.Add(normal); 
     mesh.Normals.Add(normal); 
     mesh.Normals.Add(normal); 

     var model = new GeometryModel3D(mesh, material); 

     var group = new Model3DGroup(); 
     group.Children.Add(model); 
     return group; 
    } 

    private Vector3D CalculateNormal(Point3D p0, Point3D p1, Point3D p2) 
    { 
     var v0 = new Vector3D(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z); 
     var v1 = new Vector3D(p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z); 
     return Vector3D.CrossProduct(v0, v1); 
    } 

    void Transform(double adjustBy) 
    { 
     _angle += adjustBy; 


     var rotateTransform3D = new RotateTransform3D {CenterX = 0, CenterZ = 0}; 
     var axisAngleRotation3D = new AxisAngleRotation3D {Axis = new Vector3D(0, 1, 0), Angle = _angle}; 
     rotateTransform3D.Rotation = axisAngleRotation3D; 
     var myTransform3DGroup = new Transform3DGroup(); 
     myTransform3DGroup.Children.Add(rotateTransform3D); 
     _model.Transform = myTransform3DGroup; 

    } 


} 
+0

Похоже, что у Silverlight 3 есть функция, которой я пользуюсь, но она недоступна в WPF. документ: http://msdn.microsoft.com/en-us/library/system.windows.media.planeprojection%28VS.96%29.aspx пример: http://www.gleblanc.eu /Blog/post/PlaneTransform.aspx – zproxy

+0

Слишком плохо, что Matrix3DProjection не является частью WPF ... http://msdn.microsoft.com/en-us/library/system.windows.media.matrix3dprojection%28VS.95 % 29.aspx Оператор MSFT: WPF действительно не предоставляет неаффинные преобразования http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/b2d3ba94-82f6-4356-ab78- 9c70cc8b26fd :( – zproxy

+0

Я не могу заставить это работать. Кто-нибудь имеет projec t, что я могу загрузить образец? – amok

Смежные вопросы