从清月高中物理动学课件制作工具说【FarseerPhysics引擎之WheelJoint】及【PropetryGrid之动态下拉列表】
最近在写一个简单的小工具,可以用来制作一些简单的运动学课件,这个工具主要是把物理引擎的设置可视化,主要包括利用纹理图片直接创建并设置物体、关节等方面。之前开发时主要使用BOX2D引擎和BOX2D.XNA。这次选择FarseerPhysics 3.5,主要是因为其创建复合多边形和编码反面有一些优势。WheelJoint是一个比较简单的关节,其实相对于创建物体要简单很多。但很多资料上对这WheelJoint描述并不清晰,包括范例也没有详细说明。
首先观察一下代码:
_WheelJoint = New WheelJoint(Car.GetBody, Wheel.GetBody, Wheel.GetBody.Position, ConvertUnits.ToSimUnits(Axis), True)
_WheelJoint.MotorSpeed = _MotorSpeed ' 0.0F
_WheelJoint.MaxMotorTorque = _MaxMotorTorque ' 20.0F
_WheelJoint.MotorEnabled = _MotorEnabled ' True
_WheelJoint.Frequency = _Frequency ' 4.0F
_WheelJoint.DampingRatio = _DampingRatio ' 0.7F
WorldManager.WorldEdit.World.AddJoint(_WheelJoint)
关节的创建有5个参数:
1、作为车的物体
2、作为轮的物体
3、轮上的锚点
4、固定轴:轮相对车的运动方向和位置
5、轮的锚点是否是世界坐标
关于固定轴的理解:实际上它就是轮关节本身:想象一辆汽车,轮关节就是连接前轴或后轴与汽车车体的部分,并且包含了减震系统。那么方向和弹性就很好理解了。
接下来是其他的一些设置,唯一需要注意的是如果对从动轮启用发动机,则导致该轮不转动。
在编写这个工具时,使用了PropertyGrid来设置属性,这个控件很好用,但有时也会有一点麻烦。在上述代码中,car和wheel设置时是根据现有的物体形成下拉列表进行选择的。这里有两个问题需要解决:
1、得到下拉列表
2、对象和string之间的转换
为了解决这些问题,我们需要给属性指定类型转换器:
Private _Wheel As BodyEdit
<CategoryAttribute("初始"), DescriptionAttribute("设置作为滚轮的物体。"), TypeConverter(GetType(BodyNameConverter))>
Public Property Wheel As BodyEdit
Get
Return _Wheel
End Get
Set(value As BodyEdit)
If value IsNot Nothing AndAlso value.Equals(_Car) Then
#If DEBUG Then
Debug.Print("滚轮关节不能连接在同一物体上。")
#Else
Throw New Exception("滚轮关节不能连接在同一物体上。")
#End If
Return
End If
_Wheel = value
End Set
End Property
注意代码中关于类型转换器的指定。另外,很多时候属性是不能任意设置的,可能值超出范围,也可能无法转换。所以,我们需要弹出一个对话框来进行提示,PropertyGrid已经做好了这方面的工作,所以我们只需要在set块中检测并对不合适的值引发错误。就像上述代码中的一样,但是这里有几个小技巧:return避免了错误值被写入实际数据;#IF避免了调试模式下弹出错误对话框,而在发布模式下则会弹出“不正确的属性值”对话框,就像你在VS的IDE中使用属性窗口一样。
接下来我们看一下如何在PropertyGrid中显示属性的下拉列表以及如何把对象和文字相互转换:
Imports System.ComponentModel
Imports System.Globalization Public Class BodyNameConverter : Inherits TypeConverter Public Overrides Function CanConvertFrom(context As ITypeDescriptorContext, sourceType As Type) As Boolean
If sourceType Is GetType(String) Then
Return True
End If
Return MyBase.CanConvertFrom(context, sourceType)
End Function Public Overrides Function CanConvertTo(context As ITypeDescriptorContext, destinationType As Type) As Boolean
If destinationType Is GetType(BodyEdit) Then
Return True
End If
Return MyBase.CanConvertTo(context, destinationType)
End Function Public Overrides Function ConvertFrom(context As ITypeDescriptorContext, culture As CultureInfo, value As Object) As Object
If value.GetType Is GetType(String) Then
For Each be As BodyEdit In WorldManager.BodyEdits
If be.Name = value.ToString Then
Return be
End If
Next
Return Nothing
End If
Return MyBase.ConvertFrom(context, culture, value)
End Function Public Overrides Function ConvertTo(context As ITypeDescriptorContext, culture As CultureInfo, value As Object, destinationType As Type) As Object
If destinationType Is GetType(String) Then
If value Is Nothing Then
Return String.Empty
Else
For Each be As BodyEdit In WorldManager.BodyEdits
If be.Name = value.ToString Then
Return be.Name
End If
Next
End If
End If
Return MyBase.ConvertTo(context, culture, value, destinationType)
End Function Public Overrides Function GetStandardValues(context As ITypeDescriptorContext) As StandardValuesCollection
Dim result As New List(Of String)
For Each be As BodyEdit In WorldManager.BodyEdits
result.Add(be.Name)
Next
Return New StandardValuesCollection(result.ToArray)
End Function Public Overrides Function GetStandardValuesSupported(context As ITypeDescriptorContext) As Boolean
Return True
End Function End Class
1、观察最下面两个重载,它们用于收集列表和告诉PropertyGrid列表是可以正确获取的。
2、观察上面两个重载,它们用于确认对象和文字之间可以相互转换。
3、中间两个重载,它们完成对象和文字之间转换的工作。
PS:重载BodyEdit类的ToString方法:Return Name.Tostring。
当然,这需要保持BodyEdit的Name属性不重复,你可以在该属性的Set块来解决这个问题,它看起来就像这样:
Private _Name As String
<CategoryAttribute("初始"), DescriptionAttribute("设置对象名称。")>
Public Property Name As String
Get
Return _Name
End Get
Set(value As String)
If value = String.Empty Then
#If DEBUG Then
Debug.Print("无效的属性值,不允许使用空名称。")
#Else
Throw New Exception("无效的属性值,不允许使用空名称。")
#End If
Else
For Each obj As BodyEdit In WorldManager.BodyEdits
If obj.Name = value Then
#If DEBUG Then
Debug.Print("无效的属性值,物体名称冲突。")
#Else
Throw New Exception("无效的属性值,物体名称冲突。")
#End If
Return
End If
Next
_Name = value
End If
End Set
End Property
从清月高中物理动学课件制作工具说【FarseerPhysics引擎之WheelJoint】及【PropetryGrid之动态下拉列表】的更多相关文章
- 五子棋AI清月连珠开源
经过差不多两年的业余时间学习和编写,最近把清月连珠的无禁手部分完善得差不多了.这中间进行了很多思考,也有很多错误认识,到现在有一些东西还没有全面掌握,所以想通过开源于大家共同交流. 最近一直发表一些五 ...
- Gift动图分解小工具
gif 动图分解小工具 Overview 因为自己有时候需要将一些gif图片分解,但是没有在网上找到合适的工具,所有就自己写了一个,在这里与大家分享,其实实现很简单,是通过C#实现的.文章下方有下载链 ...
- 学汇编的时候可以拿IDA之类的反汇编工具辅助学习,再用gdb或者IDA动态调试,跟踪每条指令的 执行结果。都不难
作者:潘安仁链接:https://www.zhihu.com/question/40720890/answer/87926792来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
- [Android开发学iOS系列] 工具篇: Xcode使用和快捷键
[Android开发学iOS系列] 工具篇: Xcode使用和快捷键 工欲善其事必先利其器. 编辑 Cmd + N: 新建文件 Option + Cmd + N: 新建文件夹 Cmd + / : 注释 ...
- 2014年11月17~11月18日,杨学明老师《企业IT需求收集和实施》内训在湖南长沙某酒店成功举办!
2014年11月17至18日,受湖南某软件企业的邀请,杨学明老师<企业IT需求收集和实施>内训在某长沙某五星级酒店成功举办!来自全国各地的IT高管和企业负责人参加了此次培训.杨学明老师分别 ...
- 浙大PAT CCCC L3-013 非常弹的球 ( 高中物理题 )
题目链接 题意 : 刚上高一的森森为了学好物理,买了一个“非常弹”的球.虽然说是非常弹的球,其实也就是一般的弹力球而已.森森玩了一会儿弹力球后突然想到,假如他在地上用力弹球,球最远能弹到多远去呢?他不 ...
- HDU 4445 Crazy Tank 高中物理知识忘得差不多了
题意不难理解,仔细看题吧,就不说题意了 #include <iostream> #include <cstdio> #include <cstring> #incl ...
- gcc使用及动静态库制作
一. GCC的使用 1. GCC的编译过程 (1)预处理(cpp)gcc -E(输出问价通常以 .i 结尾),将头文件展开,宏替换等操作: (2)编译器(gcc)gcc -S(输出问价以 .s 结尾) ...
- 菜鸟学SSH(十四)——Spring容器AOP的实现原理——动态代理
之前写了一篇关于IOC的博客——<Spring容器IOC解析及简单实现>,今天再来聊聊AOP.大家都知道Spring的两大特性是IOC和AOP,换句话说,容器的两大特性就是IOC和AOP. ...
随机推荐
- EF框架step by step(3)—Code-First
CodeFirst是EF框架的第三种方式,也是最为复杂一种方式,本文将以EF4.1版本为基础,简要讲解一下用法,同时,也介绍DbContext的用法. 本文采用的示例仍然是前两篇采用的博客用户的示例. ...
- .net平台下垃圾回收机制
引言:使用c++进行编程,内存的处理绝对是让每个程序设计者最头疼的一块了.但是对于.net平台下使用c#语言开发系统,内存管理可以说已经不算是问题了.在.net平台下CLR负责管理内存,CLR中的垃圾 ...
- Lc.exe已退出,代码为-1
编译项目,出现提示"Lc.exe已退出,代码为-1" . 解决办法: 意思就是把licenses.licx这个文件里的内容删除,但是文件还在(此时是个空文件),发生这个问题的原 ...
- BZOJ4635 : 数论小测验
第一问: 设$a[i]$表示使用$[1,i]$的数字$n$次形成的数组里有多少个$\gcd=1$. 考虑容斥,则$a[i]=i^n-\sum_{j=2}^i a[\lfloor\frac{i}{j}\ ...
- .htaccess 的写法
RewriteCond RewriteRule 记录下现在我会的: RewriteEngine On#RewriteRule ^(.*)/(.*)/$ index.php?m=index&c= ...
- struts.properties配置详解
Struts 2框架有两个核心配置文件,其中struts.xml文件主要负责管理应用中的Action映射,以及该Action包含的Result定义等.除此之外,Struts 2框架还包含 st ...
- android 第三方 图表
1.XCL-Charts 直接利用Canvas api画出图形,各有好处. XCL-Chart尽量把图的绘制逻辑封装在类中,而把绘制相关的各 个元素开放出来,目的是在保证开发效率的同时,给程序员足够多 ...
- ACM: 敌兵布阵 解题报告 -线段树
敌兵布阵 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Description Li ...
- BZOJ 1015 题解
1015: [JSOI2008]星球大战starwar Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝 ...
- 【noiOJ】p8210
10:河中跳房子 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 每年奶牛们都要举办各种特殊版本的跳房子比赛,包括在河里从一个岩石跳到另一个岩石.这项激动人心 ...