WPF3D立方体图形展开动画

效果图:

规定:

立方体中心为(000),棱长为2,则(111)(-1-1-1)等1,-1三维组合的八个点为其顶点

坐标系:

补充:

WPF 3D 分为中心对称旋转RotateTransform3D),平移旋转TranslateTransform3D)和比例缩减ScaleTransform3D),立体图形展开目前只用到对称和平移变换

1 按轴旋转的面

如图所示,则其是按照由(-1-1-1)到(1-1-1)的轴运动

换算成中心对称,也就是这条边的中点,则对称点为(0,-1,-1)

此动画可描述为,对点(0,-1,-1)做中心对称变换,沿X轴旋转90度。

Code:

			//设置对称中心
face0RotateTransform3D.CenterX = 0;
face0RotateTransform3D.CenterY = -1;
face0RotateTransform3D.CenterZ = -1;
//设置旋转角度
(face0RotateTransform3D.Rotation as AxisAngleRotation3D).Axis = new Vector3D(1, 0, 0);
DoubleAnimation face0AxisAngleRotation3DAnimation = new DoubleAnimation();
face0AxisAngleRotation3DAnimation.From = 0;
face0AxisAngleRotation3DAnimation.To = -90;
face0AxisAngleRotation3DAnimation.Duration = new Duration(TimeSpan.FromSeconds(keyFrameAnimationTotalTimeM));

同理可得另一个面:对点(1,-1,-1)做中心对称变换,沿Z轴旋转90度。

Code:

 	    face3RotateTransform3D.CenterX = 1;
face3RotateTransform3D.CenterY = -1;
face3RotateTransform3D.CenterZ = -1;
(face3RotateTransform3D.Rotation as AxisAngleRotation3D).Axis = new Vector3D(0, 0, 1);
DoubleAnimation DoubleAnimation = new DoubleAnimation();
DoubleAnimation.From = 0;
DoubleAnimation.To = -90;

2 连接按轴旋转的面的面

即二级旋转面

此时,我们可以把它理解为两个旋转的结合,一个轴对称旋转+一个平移旋转

1 轴对称旋转:

描述为,对点(11-1)进行旋转,沿Z轴旋转180度。

Code:

            face4RotateTransform3D.CenterX = 1;
face4RotateTransform3D.CenterY = 1;
face4RotateTransform3D.CenterZ = -1;
(face4RotateTransform3D.Rotation as AxisAngleRotation3D).Axis = new Vector3D(0, 0, 1);
DoubleAnimation DoubleAnimation = new DoubleAnimation();
DoubleAnimation.From = 0;
DoubleAnimation.To = -180;
2 平移旋转:

从侧面看的平移轨迹:

此平移按X和Y轴方向分解示意图:

其中X方向可以描述为:

在t时间内,L为边长

x方向值为:x=L*Sin(a)

y方向值为:y=L*Cos(a)

其中角度a可描述为:(PI/2)*currentTime/totalAnimationDuration

如果我们将动画描述成帧动画,综上:

X方向平移动画帧

 LinearDoubleKeyFrame GetFace4OffsetXKeyFrame(double time)
{
return new LinearDoubleKeyFrame(borderLength * Math.Sin(time * (Math.PI / 2) / keyFrameAnimationTotalTimeM), KeyTime.FromTimeSpan(TimeSpan.FromSeconds(time)));
}

Y方向平移动画帧

  LinearDoubleKeyFrame GetFace4OffsetYKeyFrame(double time)
{
return new LinearDoubleKeyFrame(-(borderLength - borderLength * Math.Cos(time * (Math.PI / 2) / keyFrameAnimationTotalTimeM)), KeyTime.FromTimeSpan(TimeSpan.FromSeconds(time)));
}

3 三级旋转面

同理,我们可以把它理解为两个旋转的结合,一个轴对称旋转+一个平移旋转

轴对称旋转:

描述为,对点(-110)进行旋转,沿Z轴旋转270度。

Code:

            face1RotateTransform3D.CenterX = -1;
face1RotateTransform3D.CenterY = 1;
face1RotateTransform3D.CenterZ = 0;
(face1RotateTransform3D.Rotation as AxisAngleRotation3D).Axis = new Vector3D(0, 0, 1);
DoubleAnimation DoubleAnimation = new DoubleAnimation();
DoubleAnimation.From = 0;
DoubleAnimation.To = -270;
DoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(keyFrameAnimationTotalTimeM));
平移旋转:

平移旋转的量需要通过分解轴旋转来得出。

通过观察我们可以将其分为两个轴旋转,第一个旋转是该面沿着A轴的轴对称旋转(自身旋转),第二个是二级面的沿着B轴的轴对称旋转(相对面旋转)

A棱边沿着A·轨迹旋转,B棱边沿着B·轨迹旋转

则沿着B轴的旋转,与二级面分解一样:

A轴旋转分解:

对于y,y=Sin(a2)

对于x,分为两种情况

当a2处于0-PI/2时,x=Cos(a2),

当a2处于PI/2-PI时,y=L-Cos(a2)

把上述两个分解加一起就得到了X=xa+xb,y=ya+yb,

Code:

X

 LinearDoubleKeyFrame GetFace1OffsetXKeyFrame(double time)
{
//自身边的定位坐标
double angle = time / keyFrameAnimationTotalTimeM;
double xa, xb;
double xTotal;
if (angle <= 1 / 2)
{
//0-1/2PI
xa = borderLength * Math.Cos(Math.PI * time / keyFrameAnimationTotalTimeM);
}
else
{
//1/2PI-PI
xa = borderLength - borderLength * Math.Cos(Math.PI * time / keyFrameAnimationTotalTimeM);
}
//前轴定位坐标
xb = borderLength * Math.Sin((Math.PI / 2) * time / keyFrameAnimationTotalTimeM);
xTotal = xa + xb;
return new LinearDoubleKeyFrame(xTotal, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(time)));
}

Y

 Timeline Face1ExpandedAnimation_MoveOffsetY_UsingKeyFrames()
{
DoubleAnimationUsingKeyFrames DoubleAnimation = new DoubleAnimationUsingKeyFrames();
DoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(keyFrameAnimationTotalTimeM));
DoubleAnimation.Completed += ((sender, e) =>
{
faceStoryboard.Remove(tileButton);
});
Storyboard.SetTargetName(DoubleAnimation, "face1TranslateTransform3D");
Storyboard.SetTargetProperty(DoubleAnimation,
new PropertyPath(TranslateTransform3D.OffsetYProperty)); for (double i = 0; i <= keyFrameAnimationTotalTimeM + keyFrameAnimationIntervalM; i += keyFrameAnimationIntervalM)
{
DoubleAnimation.KeyFrames.Add(GetFace1OffsetYKeyFrame(i));
}
return DoubleAnimation;
}C

4 双重轴对称旋转+平移旋转面

如图所示,左边这个橙色的面,在黑色的三级旋转面之上又增加一个沿着Z轴的旋转。

此时可以简单地分解为三级旋转面的旋转+沿着Z轴的旋转

三级旋转面的旋转:

见上文

Z轴旋转

可描述为:对点(-1-11)进行旋转,沿Z轴旋转90度。

            face5RotateTransform3D.CenterX = -1;
face5RotateTransform3D.CenterY = -1;
face5RotateTransform3D.CenterZ = 1;
(face5RotateTransform3D.Rotation as AxisAngleRotation3D).Axis = new Vector3D(0, 1, 0);
DoubleAnimation DoubleAnimation = new DoubleAnimation();
DoubleAnimation.From = 0;
DoubleAnimation.To = -90;
DoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(keyFrameAnimationTotalTimeM));

WPF3D立方体图形展开动画思路的更多相关文章

  1. WPF(C#) 矩阵拖动、矩阵动画、边缘展开动画处理。

    最近在研发新的项目,遇到了一个桌面模式下的难点--展开动画.之前动画这方面没做过,也许很多人开始做的时候也会遇到相关问题,因此我把几个重点及实际效果图总结展示出来: 我的开发环境是在VS2017下进行 ...

  2. Html5游戏开发-图形与动画(一)

    最近研究了一下出来了很久的HTML5,总结了一下,准备来个系列,文中也许有很多问题,欢迎大家指正. Canvas介绍 canvas用于在网页中绘制图形的一个元素,具体内容请查看 -> HTML5 ...

  3. jQuery鼠标悬停3d菜单展开动画

    效果体验:http://hovertree.com/texiao/jquery/93/ 竖直的主菜单贴着页面左侧,当光标移入菜单项时,以3D动画的方式弹出对应的二级菜单.采用jQuery和CSS3实现 ...

  4. 【Android】第21章 2D图形和动画

    分类:C#.Android.VS2015: 创建日期:2016-03-19 一.简介 Android系统定义了一系列独立的图形处理类,其中,2D图形处理类分别位于以下命名空间: Android.Gra ...

  5. HTML5 Canvas核心技术:图形、动画与游戏开发 PDF扫描版​

    HTML5 Canvas核心技术:图形.动画与游戏开发 内容简介: <HTML5 Canvas核心技术:图形.动画与游戏开发>中,畅销书作家David Geary(基瑞)先生以实用的范例程 ...

  6. 解惑:如何使用html+css+js实现旋转相册,立方体相册等动画效果

    解惑:如何使用html+css+js实现旋转相册,立方体相册等动画效果 一.前言 最初还是在抖音上看到可以使用简单地代码实现炫酷的网页效果的,但是想要找到可以运行的代码还是比较困难的,最近突然想起就在 ...

  7. HTML5 Canvas核心技术—图形、动画与游戏开发.pdf8

    第6章 精灵 精灵(sprite),它是一种可以集成入动画之中的图像对象,赋予它们各种行为,精灵并非Canvas API的一部分,,但都是从它衍生而来 本章将会实现三种设计模式:策略模式(精灵与绘制器 ...

  8. HTML5 Canvas核心技术—图形、动画与游戏开发.pdf2

    事件处理: HTML5应用程序是以事件来驱动的,可以在canvas中增加一个事件监听器,当事件发生时,浏览器就会调用这个监听器 //方法一canvas.onmousedown=function(e){ ...

  9. iOS 图形图像动画 Core Animation

    //Core Animation #define WeakSelf __weak __typeof(self) weakSelf = self #define StrongSelf __strong ...

随机推荐

  1. Linux 如何查看一个文件夹下面有多少个文件

    Linux 如何查看一个文件夹下面有多少个文件 $ tree $ find ./ -type f | wc -l $ ls -l | grep "^-" | wc -l refs ...

  2. codepen iframe theme id

    codepen iframe theme id iframe css theme demos See the Pen css margin collapsing (1. 相邻兄弟元素) by xgqf ...

  3. Kotlin & Android & Swift & Flutter & React Native

    Kotlin & Android https://www.runoob.com/kotlin/kotlin-tutorial.html Swift 5 & iOS 12 https:/ ...

  4. Web SQL& IndexedDB

    Web SQL& IndexedDB https://developer.mozilla.org/en/docs/Web/API/IndexedDB_API https://mdn.githu ...

  5. array auto slice

    array auto slice https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Ar ...

  6. TypeScript——02——TS基本数据类型介绍和使用

    一,TS的数据类型 ES6的数据类型: 6种基本数据类型 Boolean Number String Symbol undefined null 3种引用类型 Array Function Objec ...

  7. 在gradle中构建java项目

    目录 简介 构建java项目的两大插件 管理依赖 编译代码 管理resource 打包和发布 生成javadoc 简介 之前的文章我们讲到了gradle的基本使用,使用gradle的最终目的就是为了构 ...

  8. 微信附近的人,用redis也能实现?(GEO)

    相信微信附近的人的功能大家都应该用过 我可以很随意的通过我自己的定位能看到我附近的人,并且能看到那个人距离我的距离,大家有没有思考过这个是怎么实现的? 作为一个程序猿任何问题应该都有一个思考的过程,而 ...

  9. C++算法代码——标题统计

    题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=2327 题目描述 凯凯刚写了一篇美妙的作文,请问这篇作文的标题中有多少个字符? 注意: ...

  10. InnoDB 的记录结构和页结构

    本文转载自InnoDB 的记录结构和页结构 概述 InnoDB将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位,中页的大小一般为16KB.也就是在一般情况下,一次最少从磁盘中读取16KB的内 ...