简体   繁体   中英

Check collision of objects c# : 3D (X Y Z)

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.

http://pastebin.com/abDZLk9N-工作代码:)仅更改了几行代码

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM