检查C#对象的碰撞:3D(X Y Z) [英] Check collision of objects c# : 3D (X Y Z)

查看:159
本文介绍了检查C#对象的碰撞:3D(X Y Z)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个函数来检查碰撞对象,以避免这种

此功能需要检查是否相交的对象,其他对象:

 静态布尔CheckCollision(的Int32 X,的Int32 Y,的Int32 Z,的Int32 SIZEX,的Int32 SIZEY,的Int32 SizeZ)
    {
        布尔RET = FALSE;


        的for(int i = 0; I< ObjList.Count;我++)
        {

            如果(Z> ObjList [I] .Z + ObjList [I] .SizeZ || Z + SizeZ< ObjList [I] .Z)
                Console.WriteLine(Z +  - );
            否则,如果(Y + SIZEY< ObjList [I] .Y || Y'GT; ObjList [I] .Y + ObjList [I] .SizeY)
                Console.WriteLine(Y +  - );
            否则,如果(X + SIZEX< ObjList [I] .X || X  -  GT; ObjList [I] .X + ObjList [I] .SizeX)
                Console.WriteLine(X +  - );
            其他
            {
                Console.WriteLine(||);
                RET = TRUE;
                打破;
            }


        }


     // Console.Write(\ N+ RET +\ N);


            返回RET;
    }
 

ObjList - 对象数据的列表:

 私人结构S_ObjList
{
    公众的Int32 X;
    公众的Int32ÿ;
    公众的Int32 Z者除外;
    公众的Int32 SIZEX;
    公众的Int32 SIZEY;
    公众的Int32 SizeZ;
}

静态列表< S_ObjList> ObjList =新的名单,其中,S_ObjList>();
 

http://pastebin.com/abDZLk9N - 所有code

CheckCollision 不能正常工作。

此功能也不起作用(总是返回true)

 静态布尔CheckCollision(的Int32 X,的Int32 Y,的Int32 Z,的Int32 SIZEX,的Int32 SIZEY,的Int32 SizeZ)
    {
        的foreach(S_ObjList为MyObject在ObjList)
        {

            如果((z + SizeZ> MyObject.Z || z,其中; MyObject.Z + MyObject.SizeZ)及及(X + SIZEX> MyObject.X || X  - 其中; MyObject.X + MyObject.SizeX) &安培;及(Y + SIZEY> MyObject.Y || Y'其中; MyObject.Y + MyObject.SizeY))
            {

                返回true;

            }

        }
        返回false;

    }
 

解决方案

您可以将您的 X,Y,Z 坐标转换为 Vector3类型

  [StructLayout(LayoutKind.Sequential,包= 1,大小= 12)]
公共结构Vector3类型:IFormattable
{
    ///<总结>
    ///的X坐标。
    ///< /总结>
    公众持股量X;

    ///<总结>
    /// Y坐标。
    ///< /总结>
    公众持股量ÿ;

    ///<总结>
    /// Z坐标。
    ///< /总结>
    公众持股量Z者除外;

    ///<总结>
    ///初始化一个全新<见CREF =Vector3类型/>实例。
    ///< /总结>
    ///&所述; PARAM NAME =×>将X坐标与所述; /参数>
    ///< PARAM NAME =Y>将Y坐标和LT; /参数>
    ///< PARAM NAME =Z>在Z坐标< /参数>
    公共Vector3类型(浮点X,浮动Y,浮Z)
    {
        X = X;
        Y = Y;
        Z = Z者除外;
    }
}
 

然后创建一个所谓的的BoundingBox (或基本上它周围的一圈)为您的每一个对象,其中包含对象的中心为向量和半径为浮动

  ///<总结>
///
///< /总结>
公共类SphericalObstacle
{
    私人只读浮动_radius;
    私人只读Vector3类型_center;
    私人只读ULONG _vehicleId;

    ///<总结>
    ///初始化的新实例的<看到CREF =SphericalObstacle/>类。
    ///< /总结>
    ///< PARAM NAME =中心>该中心< /参数>
    ///< PARAM NAME =半径>的半径LT; /参数>
    ///< PARAM NAME =parentVehicleId>母公司车辆ID< /参数>
    公共SphericalObstacle(Vector3类型中心,浮半径,ULONG parentVehicleId)
    {
        _radius =半径;
        _center =中心;
        _vehicleId = parentVehicleId;
    }

    ///<总结>获取车辆ID< /总结>
    公共ULONG VehicleId {{返回_vehicleId; }}

    ///<总结>获取半径LT; /总结>
    公众持股量半径{{返回_radius; }}

    ///<总结>获取中心< /总结>
    公共Vector3类型中心{{返回_center; }}

    ///<总结>
    ///检查的球体碰撞。
    ///< /总结>
    ///< PARAM NAME =障碍>的障碍< /参数>
    ///< PARAM NAME =宽容与GT;的耐受性LT; /参数>
    ///<返回>
    ///&其中c取代;真&所述; / c取代;如果发生碰撞,c为C>假< / c取代;除此以外。
    ///< /回报>
    公共BOOL CollidesWith(SphericalObstacle障碍,双容差= 0.0D)
    {
        Vector3类型差异=中心 -  obstacle.Center;
        双距离=
            System.Math.Sqrt(System.Math.Pow(difference.X,2)+ System.Math.Pow(difference.Y,2)+ System.Math.Pow(difference.Z,2));

        双sumRadius =半径+ obstacle.Radius;
        返回距离< (sumRadius +容);
    }

    公共重写字符串的ToString()
    {
        返回的String.Format(半径:{0},中心:{1},_radius,_center);
    }
}
 

如果你去这个对所有你检查碰撞的,你基本上只是检查你画他们周围的圈子是否互相碰撞的对象。

从你的照片,我不能完全确定是否需要球或包围盒,但如果你需要的边界框,你可以pretty的,同样也适用相同的概念略有不同的数学。 GameDev.net是一个很好的来源,这样的东西,由途径。

I'm trying to write a function to check the collision objects to avoid this

This function needs to check intersect whether an object other objects:

 static bool CheckCollision(Int32 X, Int32 Y, Int32 Z, Int32 SizeX, Int32 SizeY, Int32 SizeZ)
    {
        bool ret = false;


        for (int i = 0; i < ObjList.Count ; i++ )
        {

            if (Z > ObjList[i].Z + ObjList[i].SizeZ || Z + SizeZ < ObjList[i].Z)
                Console.WriteLine("Z +-");
            else if (Y + SizeY < ObjList[i].Y || Y > ObjList[i].Y + ObjList[i].SizeY)
                Console.WriteLine("Y +-");
            else if (X + SizeX < ObjList[i].X || X > ObjList[i].X + ObjList[i].SizeX)
                Console.WriteLine("X +-");
            else
            {
                Console.WriteLine("||");
                ret = true;
                break;
            }


        }


     //   Console.Write("\n" + ret+"\n");


            return ret;
    }

ObjList - a list of objects data:

    private struct S_ObjList
{
    public Int32 X;
    public Int32 Y;
    public Int32 Z;
    public Int32 SizeX;
    public Int32 SizeY;
    public Int32 SizeZ;
}

static List<S_ObjList> ObjList = new List<S_ObjList>();

http://pastebin.com/abDZLk9N - all code.

CheckCollision not working correctly.

This function too does not work (always returns true)

        static bool CheckCollision(Int32 X, Int32 Y, Int32 Z, Int32 SizeX, Int32 SizeY, Int32 SizeZ)
    {
        foreach (S_ObjList MyObject in ObjList)
        {

            if ((Z + SizeZ > MyObject.Z || Z < MyObject.Z + MyObject.SizeZ) && (X + SizeX > MyObject.X || X < MyObject.X + MyObject.SizeX) && (Y + SizeY > MyObject.Y || Y < MyObject.Y + MyObject.SizeY))
            {

                return true;

            }

        }
        return false;

    }

解决方案

You could convert your X, Y, Z coordinates into a Vector3:

[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 12)]
public struct Vector3 : IFormattable
{
    /// <summary>
    /// The X coordinate.
    /// </summary>
    public float X;

    /// <summary>
    /// The Y coordinate.
    /// </summary>
    public float Y;

    /// <summary>
    /// The Z coordinate.
    /// </summary>
    public float Z;

    /// <summary>
    /// Initializes a new <see cref="Vector3"/> instance.
    /// </summary>
    /// <param name="x">The X coordinate.</param>
    /// <param name="y">The Y coordinate.</param>
    /// <param name="z">The Z coordinate.</param>
    public Vector3(float x, float y, float z)
    {
        X = x;
        Y = y;
        Z = z;
    }
}

And then create a so-called BoundingBox (or basically a circle around it) for each of your objects, which contains the center of the object as a Vector and a radius as a float:

/// <summary>
/// 
/// </summary>
public class SphericalObstacle
{
    private readonly float _radius;
    private readonly Vector3 _center;
    private readonly ulong _vehicleId;

    /// <summary>
    /// Initializes a new instance of the <see cref="SphericalObstacle"/> class.
    /// </summary>
    /// <param name="center">The center.</param>
    /// <param name="radius">The radius.</param>
    /// <param name="parentVehicleId">The parent vehicle id.</param>
    public SphericalObstacle(Vector3 center, float radius, ulong parentVehicleId)
    {
        _radius = radius;
        _center = center;
        _vehicleId = parentVehicleId;
    }

    /// <summary>Gets the vehicle id.</summary>
    public ulong VehicleId { get { return _vehicleId; } }

    /// <summary>Gets the radius.</summary>
    public float Radius { get { return _radius; } }

    /// <summary>Gets the center.</summary>
    public Vector3 Center { get { return _center; } }

    /// <summary>
    /// Checks for sphere collision.
    /// </summary>
    /// <param name="obstacle">The obstacle.</param>
    /// <param name="tolerance">The tolerance.</param>
    /// <returns>
    ///   <c>true</c> if it collides, <c>false</c> otherwise.
    /// </returns>
    public bool CollidesWith(SphericalObstacle obstacle, double tolerance = 0.0d)
    {
        Vector3 difference = Center - obstacle.Center;
        double distance =
            System.Math.Sqrt(System.Math.Pow(difference.X, 2) + System.Math.Pow(difference.Y, 2) + System.Math.Pow(difference.Z, 2));

        double sumRadius = Radius + obstacle.Radius;
        return distance < (sumRadius + tolerance);
    }

    public override string ToString()
    {
        return string.Format("Radius: {0}, Center: {1}", _radius, _center);
    }
}

If you go about this for all of the objects you're checking collision for, you're essentially just checking whether the circles you draw around them collide with each other.

From your pictures I couldn't quite determine whether you needed spheres or bounding boxes, but if you need bounding boxes you can pretty much apply the same concept with slightly different math. GameDev.net is a good source for stuff like this, by the way.

这篇关于检查C#对象的碰撞:3D(X Y Z)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆