好玩的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纹理坐标,这里就不深究的,后面可以深入探讨写一篇博客。

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

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

时间: 2024-10-29 13:11:03

好玩的WPF第四弹:用Viewport2DVisual3D实现3D旋转效果的相关文章

好玩的WPF第三弹:颤抖吧,地球!消失吧,地球!

我承认这一篇比较标题党,不过下面这个GIF貌似也和适合这个标题嘛. (画质比较烂是因为CSDN的博客图片限制在2M,所以我设置的是20帧,时间也很短,大家可以自己把项目拷回去慢慢看) 这个最终设计出来的样式: 中间的小圆点是一个Button,外面是一个经过切割的Grid,Grid里面还有一个Image. 其中在加上Image(地球图片)之前,Button还是很大的,所以给他设计了渐变色. <Button Padding="20" Foreground="White&qu

好玩的WPF第二弹:电子表字体显示时间+多彩呼吸灯特效按钮

我们先来看看Quartz MS字体动态显示系统时间的效果,难度相较于上一篇也要简单许多. 首先是定义一个TextBlock如下. <Grid> <TextBlock Name="tBlockTime" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="68" Foreground="Green"/> &

深度学习零基础进阶第四弹!|干货分享

编者按:时隔一段时间,雷锋网独家奉送的深度学习零基础进阶第四弹又来了!经过前面三篇文章的研究和学习,相信大家在深度学习的方式与深度学习在不同领域的运用都有了一定的了解.而本次雷锋网(公众号:雷锋网)所推荐的论文,主要集中于自然语言处理层面,相对于此前比较枯燥的理论阶段,相信以下的内容会更能让初学者们有的放矢.原文首发于 GitHub,作者 songrotek,文章名为<Deep-Learning-Papers-Reading-Roadmap>,雷锋网对每篇论文都增加了补充介绍,未经许可不得转载

MaxCompute - ODPS重装上阵 第四弹 - CTE,VALUES,SEMIJOIN

MaxCompute(原ODPS)是阿里云自主研发的具有业界领先水平的分布式大数据处理平台, 尤其在集团内部得到广泛应用,支撑了多个BU的核心业务. MaxCompute除了持续优化性能外,也致力于提升SQL语言的用户体验和表达能力,提高广大ODPS开发者的生产力. MaxCompute基于ODPS2.0新一代的SQL引擎,显著提升了SQL语言编译过程的易用性与语言的表达能力.我们在此推出MaxCompute(ODPS2.0)重装上阵系列文章 第一弹 - 善用MaxCompute编译器的错误和警

好玩的WPF第一弹:窗口抖动+边框阴影效果+倒计时显示文字

大家一进到博客就应该看到这张GIF了吧--好吧,今天不是星期一-- 那么就来一起做做这个效果啦!看完记得点赞哦~ 新建一个WPF项目 如果新建WPF项目应该不用我说了吧,在C#下面找找就好了. MainWindow.xaml 在初始的Window下添加如下属性: x:Name="mainWindow" WindowStartupLocation="CenterScreen" WindowState="Normal" WindowStyle=&qu

8天入门wpf—— 第四天 模板

今天说下wpf中的模板,前面一篇中我们讲到了style,但是style所能做的仅仅是在现有控件的基础上进行修修补补,但是如果我们想 彻底颠覆控件样式,那么我们就必须使用这一篇所说的模板. 老外写书都喜欢在篇头搞一个类图,方便我们宏观认识,这里我也上一个. 一:控件模板 1:ControlTemplate 我们知道wpf的控件都是继承自Control,在Control类中有一个Template属性,类型就是ControlTemplate. 那么利用这个ControlTemplate就可以彻底的颠覆

HTML5,不只是看上去很美(第四弹:可交互地铁线路图)

前言 最近特别忙,承蒙大伙关照,3D机房的项目一个接着一个,领了一帮小弟,搞搞传帮带,乌飞兔走,转眼已经菊黄蟹肥--有个小弟很不错,勤奋好学,很快就把API都摸透了,国庆几天自己折腾着做了个HTML5的魔都的地铁线路图,能拖能拽的,还和电子地图做了交互.哥决定把小弟的成果纳入"HTML5,不只是看上去很美"系列,以示鼓励(P.S. 其实还挺有压力的,后浪推前浪,新人赶旧人.我们这些老鸟也得注意,免得让00后给抢了饭碗) 效果图对比 网上的地铁图还是很多的,小弟选了这张比较新的做参考.想

深度学习零基础进阶第四弹​|干货分享

雷锋网曾编译了<干货分享 | 深度学习零基础进阶大法!>系列,相信读者一定对深度学习的历史有了一个基本了解,其基本的模型架构(CNN/RNN/LSTM)与深度学习如何应用在图片和语音识别上肯定也不在话下了.今天这一部分,我们将通过新一批论文,让你对深度学习在不同领域的运用有个清晰的了解.由于第三部分的论文开始向细化方向延展,因此你可以根据自己的研究方向酌情进行选择.雷锋网对每篇论文都增加了补充介绍.这一弹主要从自然语言处理以及对象检测两方面的应用进行介绍. 本文编译于外媒 github,原文标

ActiveMQ第四弹:在HermesJMS中创建ActiveMQ Session

Hermes JMS是一个开源免费的跨平台的JMS消息监听工具.它可以很方便和各种JMS框架集成和交互,可以用来监听.发送.接收.修改.存储消息等.这篇文章将讲解HermesJMS如何集成ActiveMQ并与其交互. ActiveMQ在通过命令行运行时会自动启动一个Web终端,默认地址是http://localhost:8161/admin,默认用户名/密码为admin/admin.通过这个web终端可以监控和操作ActiveMQ.但是这个Web终端有两个缺陷,第一是功能较弱,有些需求不能满足: