zoukankan      html  css  js  c++  java
  • 好玩的WPF第四弹:用Viewport2DVisual3D实现3D旋转效果

    这里写图片描述

    效果呢就是这么个效果,但是大家要发挥想象力,比如做成一个可以旋转的按钮等等。

    定义一个这样的资源就好。

    <Window.Resources>
            <DiffuseMaterial x:Key="DiffuseMaterialStyle" Viewport2DVisual3D.IsVisualHostMaterial="True" 
                             Brush="White"/>
    </Window.Resources>

    关键是在Grid里放这么一个东西:

     <Viewport3D x:Name="view" ClipToBounds="True" RenderOptions.EdgeMode="Aliased">                
         <Viewport3D.Camera>
              <PerspectiveCamera x:Name="perspectiveCam" FieldOfView="59" Position="0.5,0.5,2" LookDirection="0,0,-1">
                  <PerspectiveCamera.Transform>
                       <RotateTransform3D x:Name="rot" CenterY="0.5" CenterX="0.5" CenterZ="-0.5">
                            <RotateTransform3D.Rotation>
                                    <AxisAngleRotation3D x:Name="AxisAngleRot" Axis="0,1,0" Angle="0"/>
                            </RotateTransform3D.Rotation>
                       </RotateTransform3D>
                   </PerspectiveCamera.Transform>
               </PerspectiveCamera>
          </Viewport3D.Camera>                      
          <ModelVisual3D>
              <ModelVisual3D.Content>
                   <AmbientLight Color="White" />
              </ModelVisual3D.Content>
          </ModelVisual3D>
    </Viewport3D>

    正面:

    <Viewport2DVisual3D Material="{StaticResource  DiffuseMaterialStyle }">
        <Viewport2DVisual3D.Geometry>
             <MeshGeometry3D Positions="0,1,0    0,0,0     1,0,0    1,1,0"
                  TextureCoordinates="0,0   0,1     1,1     1,0"
                  TriangleIndices="0 1 2  0 2 3"/>
        </Viewport2DVisual3D.Geometry>
        <Border BorderThickness="10" x:Name="FrontSide" BorderBrush="Blue" CornerRadius="1"  
            PreviewMouseDown="FrontSide_PreviewMouseDown" >
            <TextBlock Text="欢迎访问我的博客" Foreground="Green" />
       </Border>
    </Viewport2DVisual3D>

    右侧:

    <Viewport2DVisual3D Material="{StaticResource DiffuseMaterialStyle}">
          <Viewport2DVisual3D.Geometry>
                <MeshGeometry3D Positions="1,1,0     1,0,0     1,0,-1     1,1,-1"
                    TextureCoordinates="0,0 0,1 1,1 1,0"
                    TriangleIndices="0 1 2  0 2 3"/>
           </Viewport2DVisual3D.Geometry>
           <Border BorderThickness="1" x:Name="RightSide" BorderBrush="Lime" CornerRadius="4"
               PreviewMouseDown="RightSide_PreviewMouseDown"  >
               <Border.Background>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="White" />
                    </LinearGradientBrush>
                </Border.Background>
                <TextBlock Text="感谢您的支持" FontSize="20"/>
           </Border>
    </Viewport2DVisual3D>

    大家对比上面这两个就知道正面的镂空是怎么来的了……

    左侧:

    <Viewport2DVisual3D Material="{StaticResource DiffuseMaterialStyle}">
          <Viewport2DVisual3D.Geometry>
                <MeshGeometry3D Positions="0,1,-1    0,0,-1   0,0,0    0,1,0"   
                TextureCoordinates="0,0 0,1 1,1 1,0"
                TriangleIndices="0 1 3  0 2 3"/>
               </Viewport2DVisual3D.Geometry>
               <Border BorderThickness="40" x:Name="LeftSide" BorderBrush="White" CornerRadius="1" 
                      PreviewMouseDown="LeftSide_PreviewMouseDown" >
                  <Border.Background>
                      <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                          <GradientStop Color="Black" />
                       </LinearGradientBrush>
                   </Border.Background>
              <TextBlock Text="有问题直接评论就好" Foreground="Lime"/>
         </Border>
    </Viewport2DVisual3D>

    后方:

    <Viewport2DVisual3D Material="{StaticResource DiffuseMaterialStyle}">
        <Viewport2DVisual3D.Geometry>
            <MeshGeometry3D Positions="1,1,-1    1,0,-1     0,0,-1     0,1,-1   0,0.5,-1"
               TextureCoordinates="0,0    0,1    1,1    1,0"
               TriangleIndices="0 1 2  0 2 4"/>
        </Viewport2DVisual3D.Geometry>
        <Border BorderThickness="1" x:Name="BackSide" BorderBrush="White" CornerRadius="4" 
             PreviewMouseDown="BackSide_PreviewMouseDown" >
            <Border.Background>
               <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                   <GradientStop Color="White" />
               </LinearGradientBrush>
            </Border.Background>
            <TextBlock Text="常来哦……" FontSize="20"/>
       </Border>
    </Viewport2DVisual3D>

    大家先不管MeshGeometry3D这些东西是做什么的,后面我尽量简单快速的讲解它们。

    所以先来看看程序的内部。

        public partial class MainWindow : Window
        {
            DispatcherTimer dispatTime = null;
            double AxAngle = 90;
    
            public MainWindow()
            {
                InitializeComponent();
    
                if (dispatTime == null)
                    dispatTime = new DispatcherTimer();
                dispatTime.Tick += new EventHandler(DT_Tick);
                dispatTime.Interval = new TimeSpan(0, 0, 0, 0, 2);
            }                       
    
    
            private void DT_Tick(object sender, EventArgs e)
            {
                AxisAngleRot.Angle += 1;
                if (AxisAngleRot.Angle >= AxAngle)
                    dispatTime.Stop();
            }
    
            private void FrontSide_PreviewMouseDown(object sender, MouseButtonEventArgs e)
            {
                AxisAngleRot.Angle = 0;
                AxAngle = 90;
                dispatTime.Start();
            }
    
            private void LeftSide_PreviewMouseDown(object sender, MouseButtonEventArgs e)
            {
                AxAngle = 360;
                dispatTime.Start();
            }
    
            private void BackSide_PreviewMouseDown(object sender, MouseButtonEventArgs e)
            {
                AxAngle = 270;
                dispatTime.Start();
            }
    
    
            private void RightSide_PreviewMouseDown(object sender, MouseButtonEventArgs e)
            {
                AxAngle = 180;
                dispatTime.Start();
            }
        }

    像这种程序肯定会涉及到计时器的,就是DT_Tick方法。我将它设置为每次都转动1度,而下面这一行则是间隔的时间。

    dispatTime.Interval = new TimeSpan(0, 0, 0, 0, 2);

    其余的每个方法都用于调节角度,可以看到在正面时会将角度重置一次。

    所以接下来看看Positions是什么意思。

    这里写图片描述

    原谅我把正方体画歪了,图中另外用箭头指出了“正面”、“右侧”等。

    大家看看Positions中都是3个数字一组对吧,这就是一个点,我在图中已经标识出来了。而TriangleIndices中也是3个数字一组,这3个数字指示了Positions中的组合索引(从0开始索引),然后3个数字组成三角形,如图中箭头所指向的。

    而TextureCoordinates是WPF的3D纹理坐标,这里就不深究的,后面可以深入探讨写一篇博客。

    大家也可以拿源码回去慢慢弄着玩嘛……

    所以这篇博客就到此为止咯。掰掰……

    版权声明:本文为 NoMasp柯于旺 原创文章,如需转载请联系本人。

  • 相关阅读:
    转:算法的空间复杂度
    转:算法的最坏情况与平均情况 复杂度就要看最坏情况
    转:一些字符串函数的实现
    转:C语言字符串操作函数
    搜狐在线笔试 时间复杂度O(n)实现数组A[n]中所有元素循环左移k个位置
    搜狐笔试 最大连续递增子段和 关键词连续递增
    转:最小区间:k个有序的数组,找到最小区间使k个数组中每个数组至少有一个数在区间中
    转:strcpy实现的考察要点
    转:strcat与strcpy与strcmp与strlen
    转:多篇文章中的设计模式-------策略模式
  • 原文地址:https://www.cnblogs.com/NoMasp/p/4785995.html
Copyright © 2011-2022 走看看