【问题标题】:Ball Rolling in DirectX with C#使用 C# 在 DirectX 中滚球
【发布时间】:2011-06-08 19:39:04
【问题描述】:

我试图用球的形状创建一个跷跷板,根据形状角度,球滚动。

这是它的截图。

因此,跷跷板的形状根据轨迹条值生成的角度移动。

这里是声明的变量:

private const float ONE_DEGREE = 0.0174532924f;
        private ID3DMesh tab;        
        private ID3DMesh ball;

'tab' 变量是形状。

此方法设置形状的角度:

public void setShapeAngle(float degree)
{            
    tabTargetAngle = Util.DegreeToRadian(degree);
}

这是更新它的方法:

public void Update(int elapsedTime)
        {

            if (tab.Pitch != tabTargetAngle)
            {
                if (tabTargetAngle > tab.Pitch)
                {
                    if (tab.Pitch >= (tabTargetAngle - ONE_DEGREE))
                    {
                        tab.Pitch = tabTargetAngle;

                    }
                    else
                    {
                        tab.Pitch += tabuaSpeed * elapsedTime;                        
                    }
                }
                else if (tabTargetAngle < tab.Pitch)
                {
                    if (tab.Pitch <= (tabTargetAngle + ONE_DEGREE))
                    {
                        tab.Pitch = tabTargetAngle;

                    }
                    else
                    {
                        tab.Pitch -= tabuaSpeed * elapsedTime;                        

                    }

                }

            }                                                 
        }

所有的对象,都是 ID3DMesh 对象。这是ID3DMesh类的代码。

 public interface ID3DMesh : IDisposable
    {
        Color Ambient { get; set; }
        CollisionTestMethod CollisionDetectionMethod { get; set; }
        Mesh D3DXMesh { get; }
        Color Diffuse { get; set; }
        Color Emissive { get; set; }
        Material[] Materials { get; set; }
        ID3DMesh Parent { get; set; }
        float Pitch { get; set; }
        Vector3 PivotOffset { get; set; }
        float PivotOffsetX { get; set; }
        float PivotOffsetY { get; set; }
        float PivotOffsetZ { get; set; }
        Vector3 Position { get; set; }
        RenderOptions RenderSettings { get; set; }
        float Roll { get; set; }
        Vector3 Scale { get; set; }
        float ScaleX { get; set; }
        float ScaleY { get; set; }
        float ScaleZ { get; set; }
        Color Specular { get; set; }
        float SpecularSharpness { get; set; }
        Texture[] Textures { get; set; }
        Color WireColor { get; set; }
        float X { get; set; }
        float Y { get; set; }
        float Yaw { get; set; }
        float Z { get; set; }

        MeshBoundingBox GetBoundingBox();
        MeshBoundingSphere GetBoundingSphere();
        float GetDepth();
        float GetHeight();
        float GetWidth();
        Matrix GetWorldMatrix();
        bool Intersects(ID3DMesh mesh);
        void Link(ID3DMesh parentMesh, Vector3 linkPosition);
        void Move(float xAmount, float yAmount, float zAmount);
        void Render();
        void RenderPlanarShadow(Plane groundPlane, Light light, bool allowDoubleBlending);
        void SetDepth(float depth);
        void SetDepth(float depth, bool uniformScale);
        void SetHeight(float height);
        void SetHeight(float height, bool uniformScale);
        void SetPlanarShadowOpacity(float shadowOpacity);
        void SetScale(float amount);
        void SetScale(float xAmount, float yAmount, float zAmount);
        void SetSize(float width, float height, float depth);
        void SetWidth(float width);
        void SetWidth(float width, bool uniformScale);
    }

我尝试使用 Move(float, float, float) 方法。但它没有按应有的方式移动。如果你能帮我解决这个问题。

谢谢。

【问题讨论】:

    标签: c# directx 3d direct3d


    【解决方案1】:

    (注意:下面我将忽略第三个维度,因为球将始终沿同一平面移动)

    如果我们以跷跷板为参考系,我认为球的运动将类似于harmonic oscillator 的运动。也就是说,球在给定时刻s(t)沿跷跷板的位置将由以下公式给出:

    s(t) = L cos(2π t / T + φ)

    其中 L 是跷跷板的长度(谐波的幅度),T 是球从跷跷板的一端移动到另一端并返回起点所需的时间(谐波的周期) . φ,谐波的初始相位,可以调整公式,因此 s(0) 可以为您提供起始位置。如果你想让它从中心开始,你需要使 s(0) = 0,这意味着你需要余弦为 0。所以你必须使 φ 为 π/2(90 度),因为 cos(π /2) = 0。

    有了这个,你可以通过改变世界变换把球放在适当的位置。如果将它旋转到跷跷板的当前角度(我们称之为 θ(t)),您可以将球沿 xx 轴平移 s(t) 的值。

    这相当于将 (s(t),θ(t)) 视为球在极坐标中的位置。然后,您可以使用以下公式获得给定时间 (x(t),y(t)) 的笛卡尔坐标:

    x(t) = s(t) cos(θ)

    y(t) = s(t) sin(θ)

    【讨论】:

      【解决方案2】:

      (假设上向量为 (0, 1, 0) 且制表符与 X 轴对齐)

      您可以想象,小球必须沿 X 轴“滚动”到标签下方,并且您必须计算 Y 位置以使其粘在标签上。

      您可以对 X 位置使用 Move() 方法,因为球的速度会以相对方式影响其 X 位置。

      通过设置Y 属性,可以更轻松地为每个 X 位置计算 Y 位置(只要球保留在选项卡上)。

      如果我是你,我会首先创建一个计算 Y 位置的方法,以使球在任何 X 位置都“粘在标签上”。

      如果这没有为您指明正确的方向,请详细说明“它没有按应有的方式移动”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-16
        • 1970-01-01
        • 2013-06-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多