/// <summary>
        /// Checks wheter the hyperbox is colliding with the given hyperbox
        /// using AAABBtechnique
        /// </summary>
        /// <param name="bx">An hyperbox to check for collision with</param>
        /// <returns>The possible separation planes (if there's any)</returns>
        public List <PPlane> Collide(Hyperbox bx)
        {
            var planes = new List <PPlane>();

            for (var axis = 0; axis < Axis.Count; axis++)
            {
                var reachCurrent = Axis[axis].Reach;
                var reachCompare = bx.Axis[axis].Reach;

                var distance = Math.Abs(Axis[axis].Middle - bx.Axis[axis].Middle);
                if (reachCurrent == 0.0)
                {
                    var l = Axis[axis].Middle;
                    if (l >= bx.Axis[axis].Min && l <= bx.Axis[axis].Max)
                    {
                        continue;
                    }
                }
                else if (reachCompare == 0.0)
                {
                    var l = bx.Axis[axis].Middle;
                    if (l >= Axis[axis].Min && l <= Axis[axis].Max)
                    {
                        continue;
                    }
                }
                else if (reachCurrent + reachCompare >= distance)
                {
                    continue;                                               //collision!  >= : doesn't allow the boxes to touch each other;  >: allows the touching
                }
                double min, max;
                var    axisA = Axis[axis];
                var    axisB = bx.Axis[axis];
                if (axisA.Average < axisB.Average)
                {
                    min = axisB.Min;
                    max = axisA.Max;
                }
                else
                {
                    min = axisA.Min;
                    max = axisB.Max;
                }
                var value = (min + max) / 2;

                planes.Add(new PPlane(axis, value));
                return(planes);//do not keep looking for separation planes if one is found
            }

            return(planes);
        }
        /// <summary>
        /// Informs the [previously calculated] separation parallel plane between two given objects
        /// </summary>
        /// <param name="a">An object A</param>
        /// <param name="b">An object B</param>
        /// <returns>The separation parallel plane (PPlane object)</returns>
        private PPlane GetSeparationPlane(Hyperbox a, Hyperbox b)
        {
            var idxA = GetObjectIdx(a);
            var idxB = GetObjectIdx(b);

            if (_separationPlanes == null || _separationPlanes[idxA] == null || _separationPlanes[idxB] == null || _separationPlanes[idxA][idxB] == null)
            {
                return(null);
            }
            else
            {
                return(_separationPlanes[idxB][idxA]);
            }
        }
        /// <summary>
        /// Informs the object index from the objects list of the system
        /// NOT THE OBJECT'S ID!!
        /// </summary>
        /// <param name="o">An object to be found</param>
        /// <returns>The object's index</returns>
        private int GetObjectIdx(Hyperbox o)
        {
            var idx = 0;

            foreach (var obj in Objects)
            {
                if (o.ID == obj.ID)
                {
                    return(idx);
                }
                idx++;
            }
            return(-1);
        }
        private IEnumerable <Range> FindRanges(Hyperbox box)
        {
            var boxRanges = new List <Range>();

            foreach (var range in Ranges)
            {
                var axis = range.Axis;
                var min  = box.Axis[axis].Min;
                var max  = box.Axis[axis].Max;

                if (range.Check(min) || range.Check(max))
                {
                    boxRanges.Add(range);
                }
            }

            return(boxRanges);
        }