[C#] Not happy with the following method, is there a better alternative?

Started by
7 comments, last by Spa8nky 14 years, 2 months ago
I would like to do a test between any two classes that inherit from the same shape class. I can only think of the following method to differentiate between each shape type automatically, but I'm not entirely happy with it. What methods would you guys recommend?


    public enum Shape_Type : int
    {
        AABB = 0, 
        CIRCLE = 1,
        OBB = 2,
        POLYGON = 3,        
        Count = 4                               // Total number of shape types
    }

        static CollisionFunction2D[] function = new CollisionFunction2D[]
        {
            TestAABBAABB,
            TestCircleCircle,
            TestOBBOBB,
            TestPolygonPolygon,
            TestSweptAABBAABB,
            TestSweptCircleCircle,
            TestSweptOBBOBB,
            TestSweptPolygonPolygon,
        };

        public static bool TestShapeShape(Shape s1, Shape s2, ref Contact2D contact)
        {
            // Cast enum type to int so the type can be used in calculations
            int a_Value = (int)s1.Type;
            int b_Value = (int)s2.Type;

            // All tests are covered in ascending numberical order
            // There is no need to test (a vs b) if we have (b vs a) implemented
            if (a_Value > b_Value)
            {
                // [Swap a and b]
                // • This method should return a boolean
                // • Otherwise the original DetectCollision method will still be performed with the objects the wrong way around     
                return TestShapeShape(s2, s1, ref contact);
            }

            // Find the correct collision test function based on both bodies' shape type (set to 3 for time being)
            int index = 3;      
            CollisionFunction2D function_Current = function[index];

            return function_Current(s1, s2, ref contact);
        }

Thank you.
Advertisement
I usually use run-time type checking since C# offers it. What you are doing is what I would usually do in C++.

If you have a BaseClass and ChildClass1 and ChildClass2, you can for example do the following tests:

BaseClass var1 = new ChildClass1();
BaseClass var2 = new ChildClass2();

if (var1 is ChildClass2)... // FALSE!
if (var2 is ChildClass2)... // TRUE!
if (var1 is BaseClass && var2 is BaseClass)... // TRUE!
Fate fell short this time your smile fades in the summer.
I thought about the "is" keyword but what if I add another shape type? In this case it won't automatically assign a new function based on the shape type unless I code it in.

I was thinking of something more automated, or perhaps a formula for the index that can adapt to the number of shape types and delegate accordingly?
Method overloading?

class Collision{  public static bool Test(Circle, Circle)  {    }    public static bool Test(Circle, Polygon)  {    }    public static bool Test(Circle, Box)  {    }}

You'll have to add new collision methods for every new shape you introduce (but you'd have to do that anyway I imagine), but at least you won't have to maintain a list and explicitly tie the collision functions to the various types of shapes.
That method doesn't work:

        private static bool Test(CD_Rectangle a, CD_Rectangle b, ref Contact2D contact)        {            Console.WriteLine("AABBAABB");            return false;        }        private static bool Test(CD_Circle a, CD_Circle b, ref Contact2D contact)        {            Console.WriteLine("CircleCircle");            return false;        }        public static bool TestShapeShape(Shape s1, Shape s2, ref Contact2D contact)        {            Test(s1, s2, ref contact);        }


The best overloaded method match for 'Cthonian.Detection2D.Test(Cthonian.CD_Rectangle, Cthonian.CD_Rectangle, ref Cthonian.Contact2D)' has some invalid arguments

Argument '1': cannot convert from 'Cthonian.Shape' to 'Cthonian.CD_Rectangle'
Argument '2': cannot convert from 'Cthonian.Shape' to 'Cthonian.CD_Rectangle'
Oops, my bad. I hadn't realized how you would use it.
You may be able to implement a solution in terms of the visitor pattern though.
For a relatively small, closed set of types, especially being used in a typically performance sensitive area like collision, your original method would be pretty good I think.

You could have a complete table for testing each type against each other (so you would have a 4x4 array). You can then calculate the index with:
"a_Value * COUNT + b_Value".
Are you going to call this method frequently (as in a physics engine)?
In that case you might want to test the overload versus delegate invokation for performance.
Quote:Original post by rip-off
For a relatively small, closed set of types, especially being used in a typically performance sensitive area like collision, your original method would be pretty good I think.

You could have a complete table for testing each type against each other (so you would have a 4x4 array). You can then calculate the index with:
"a_Value * COUNT + b_Value".


This is what I initially thought, but then what of swept collisions? How could I factor them into that array?

Also, wouldn't that equation mean that I would have to have dummy functions in the function array, just so the index is correct?

This topic is closed to new replies.

Advertisement