• 从清月高中物理动学课件制作工具说【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
    

      

  • 相关阅读:
    ActiveMQ-在Centos7下安装和安全配置
    Servlet基础知识点
    Filter的执行顺序
    Dubbo-使用Maven构建Dubbo服务的可执行jar包
    Dubbo-Centos7管控台安装
    Spring 小知识点
    Zookeeper+ActiveMQ集群搭建
    Zookeeper在Centos7上搭建单节点应用
    SpringMVC+AJAX+JSON
    RocketMQ-Filer
  • 原文地址:https://www.cnblogs.com/zcsor/p/5919075.html
Copyright © 2020-2023  润新知