原文:WPF弹性模拟动画

我们此次将要制作模拟物理中的弹性现象的交互动画,我们让一个小球向鼠标点击位置移动,这个移动的轨迹不是简单的位移,而是根据胡克定律计算得出的。

胡克定律:F=-kd



F代表弹性力的大小

d是拉伸的位移

k为弹性系数

在我们的动画中还将加入摩擦力,否则物体就如在真空中运动,永远不会停止。

需声明的是,以上知识并不属于我,也不是来自课本,要知道我的初中物理及格次数并不多,这些是来自于奇才Robert Penner的著作,而以下示例也是其书中Flash示例的翻版。

下面开始我们的示例:

首先我在Expression Design中设计了一个球的外观以及一个渐变的背景:

然后将它们导出为WPF资源字典,在Visual Studio中新建一个项目,引用上述资源做Ellipse元素和Window元素的背景,创建如下的界面:

需注意的是,要将两个Slider的Maximum属性设为1、LargeChange属性设为0.1,因为我们的两个属性取值范围都是在0-1之间。

在后台代码中将窗体的DataContext属性设为其自身,即“this”。

然后实现INotifyPropertyChanged接口,并设置4个用于前台绑定的4个属性:X、Y、弹性系数、流体摩擦力

之后将Ellipse的Canvas.Top及Canvas.Left属性分别绑定到Y和X,两个Slider的Value属性分别绑定到弹性系数和流体摩擦力。

之后为Window增加ContentRendered事件处理,在此将初始化一个计时器,以此来控制动画的每个帧:

DispatcherTimer 帧计时器;

private void Window_ContentRendered(object sender, EventArgs e)

{

帧计时器 = new DispatcherTimer();

帧计时器.Tick += new EventHandler(帧计时器_Tick);

帧计时器.Interval );

帧计时器.Start();

}

double x ;

double y ;

void 帧计时器_Tick(object sender, EventArgs e)

{

var X轴弹力 = (X - 目标位置.X) * -弹性系数;

x += X轴弹力;

x -流体摩擦力;

X += x;

var Y轴弹力 = (Y - 目标位置.Y) * -弹性系数;

y += Y轴弹力;

y - 流体摩擦力;

Y += y;

}

计时器每次触发时,都将进行位置计算,并调整X、Y的值。

其中的目标位置是在鼠标单击时指定的,为此还要为Window增加PreviewMouseLeftButtonDown事件处理:

private void Window_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

var p = e.GetPosition(this);

目标位置 = , p);

}

在此事件处理中,将目标位置设为鼠标当前坐标减去Ellipse元素的实际尺寸的一半,这样在移动完成后,球的中心点就位于鼠标的点击处了。

PS:将PreviewMouseLeftButtonDown事件改为MouseLeftButtonDown也是可行的,但是窗体内的控件如果截获并处理了点击事件,那么将不会引发球体移动。

现在编译和运行后,显示的程序界面效果如下:

通过点击可以使球移动,调整两个参数可以看到不同的移动效果。

你可以通过下面这个视频大略了解此示例的效果,但它与实际的流畅度有些差距,程序中的帧频应当是每秒100帧的,而视频只有每秒25帧。

源视频下载(清晰度高一些):http://www.box.net/shared/fjv5kucgns

本文章的PDF文档下载:http://www.box.net/shared/rlqoqf5lkp

源代码下载

WPF弹性模拟动画的更多相关文章

  1. WPF利用动画实现圆形进度条

    原文:WPF利用动画实现圆形进度条 这是我的第一篇随笔,最近因为工作需要,开始学习WPF相关技术,自己想实现以下圆形进度条的效果,逛了园子发现基本都是很久以前的文章,实现方式一般都是GDI实现的,想到 ...

  2. WPF控制动画开始、停止、暂停和恢复

    1.闲言 好久也没更新一博客了,自己有点发懒,同时确实这几个月来也有点忙.风机监测软件,项目中,有这样一个小需求:正常风机在旋转的时候,上位机软要做一个风机的图片,让它不停地旋转,一但检测到下面风机停 ...

  3. Wpf(Storyboard)动画简单实例

    原文:Wpf(Storyboard)动画简单实例 动画的三种变换方式 RotateTransform:旋转变换变化值:CenterX围绕转的圆心横坐标 CenterY纵坐标 Angle旋转角度(角度正 ...

  4. WPF实现动画的几种方式及其小案例

    WPF实现动画的方式: 基于计时器的动画 建立一个定时器,然后根据其频率循环调用函数或者一个事件处理函数,在这个函数中可以手工更新目标属性,直到达到最终值,这时可以停止计时器. 案例: 效果图: XA ...

  5. WPF之动画

    原文:WPF之动画 线性关键帧.不连续关键帧动画: <Window.Triggers> <EventTrigger RoutedEvent="Window.Loaded&q ...

  6. WPF后台动画DoubleAnimation讲解

    WPF后台动画,使用DoubleAnimation做的. 1.移动动画 需要参数(目标点离最上边的位置,目标点离最左边的位置,元素名称) Image mImage = new Image(); Flo ...

  7. C# WPF 时钟动画(2/2)

    模拟实现时钟效果,学习WPF动画好例子,本文承接上文 C# WPF 时钟动画(1/2). 微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. C# ...

  8. C# WPF 时钟动画(1/2)

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. C# WPF 时钟动画(1/2) 内容目录 实现效果 业务场景 编码实现 本文参考 源码下载 ...

  9. WPF路径动画(动态逆向动画)

    WPF 中的Path.Data 不再多介绍,M开始坐标点 C弧度坐标点 L 直线坐标点 <Path x:Name="path0" Data="M 10,100 C ...

随机推荐

  1. Android自学绝佳资料

    本文转自stormzhang老师的博客:http://stormzhang.com/android/2014/07/07/learn-android-from-rookie 首先感谢stromzhan ...

  2. ABAP 负号前置方法汇总

    ABAP 负号前置方法汇总 开发过程中有这样的一个需求,要求指定数字栏位负号前置: 方法一: PERFORM FRM_MOVE_DATA_MINUS CHANGING L_CHAR20. ” 负号前置 ...

  3. C#实现栈

    概述 先用C#实现一个栈的类,如下: public class MyStack<T> : IEnumerable<T>, IDisposable { ; ; private T ...

  4. 贴一个CMemDC 代码,这东西真不错噢,短小精悍,可谓极品

    罗索客 发布于 2006-11-28 21:53 点击:3941次  来自: 原文: http://yuantao82.spaces.live.com/Blog/cns!8FC0A772D812A22 ...

  5. MFC消息映射的原理:笔记

    多态的实现机制有两种,一是通过查找绝对位置表,二是查找名称表:两者各有优缺点,那么为什么mfc的消息映射采用了第二种方法,而不是c++使用的第一种呢?因为在mfc的gui类库是一个庞大的继承体系,而里 ...

  6. DirectX SDK版本与Visual Studio版本

    对于刚刚接触 DirectShow 的人来说,安装配置是一个令人头疼的问题,经常出现的情况是最基本的 baseclass 就无法编译.一开始我也为此费了很大的功夫,比如说修改代码.修改编译选项使其编译 ...

  7. Eclipse 修改maven 仓储Repository位置

    简述: 使用两个Nexus, 需要配置两份不同的Maven仓库 步骤: 1. 下载新的Maven运行包 2. 进入conf/ 修改setting.xml项 <localRepository> ...

  8. Java Web Services (0) - Overview

    前言第1章 Web服务快速入门 1.1 Web服务杂项 1.2 Web服务有什么好处 1.3 Web服务和面向服务的架构 1.4 Web服务简史 1.4.1 从DCE/RPC到XML-RPC 1.4. ...

  9. 网络知识汇总(2) - Linux下如何修改ip地址

    在Linux的系统下如何才能修改IP信息   以前总是用ifconfig修改,重启后总是得重做.如果修改配置文件,就不用那么麻烦了-   A.修改ip地址   即时生效:   # ifconfig e ...

  10. LAN路由

    一.实验的目的:   实现不同子网之前的信息交流      二.如果 1.虚拟子网 VMnet8:192.168.233.0/24 VMnet1:172.16.1.0/24 2.虚拟机vm1 ip:1 ...