public HitTestResult HitTest(Coordinates point, double tolerance, HitTestFilter filter)
        {
            // first check the selected object and it's hierarchy
            if (selectedObject != null)
            {
                object obj = selectedObject;
                while (obj != null)
                {
                    if (obj is IHittable)
                    {
                        // run the hit test on the object
                        HitTestResult hitResult = HitTest((IHittable)obj, point, tolerance, filter);
                        // if it's a hit, we're done
                        if (hitResult.Hit)
                        {
                            return(hitResult);
                        }
                    }

                    // move up the next step in the hierarchy
                    obj = ((IHittable)obj).Parent;
                }
            }

            // iterate backwards through the objects (last object is drawn on top)
            foreach (object obj in Services.DisplayObjectService.GetReverseVisibleEnumerator())
            {
                if (obj is IHittable)
                {
                    // run the hit test on the object
                    HitTestResult hitResult = HitTest((IHittable)obj, point, tolerance, filter);
                    // if it's a hit, we're done
                    if (hitResult.Hit)
                    {
                        return(hitResult);
                    }
                }
            }

            // return a no hit
            return(HitTestResult.NoHit);
        }
        private HitTestResult HitTest(IHittable obj, Coordinates point, double tolerance, HitTestFilter filter)
        {
            // check if we're in the bounding box
            RectangleF boundingBox = obj.GetBoundingBox();

            // inflate by the tolerance
            if (!boundingBox.IsEmpty)
            {
                boundingBox.Inflate((float)tolerance, (float)tolerance);
            }
            // check if the bounding box is empty or we're inside it
            if (boundingBox.IsEmpty || boundingBox.Contains(Utility.ToPointF(point)))
            {
                // run the hit test
                HitTestResult result = obj.HitTest(point, (float)tolerance);
                // apply the filter
                if (filter(result))
                {
                    return(result);
                }
            }

            // return a no-hit
            return(HitTestResult.NoHit);
        }
        private HitTestResult HitTest(IHittable obj, Coordinates point, double tolerance, HitTestFilter filter)
        {
            // check if we're in the bounding box
            RectangleF boundingBox = obj.GetBoundingBox();
            // inflate by the tolerance
            if (!boundingBox.IsEmpty) {
                boundingBox.Inflate((float)tolerance, (float)tolerance);
            }
            // check if the bounding box is empty or we're inside it
            if (boundingBox.IsEmpty || boundingBox.Contains(Utility.ToPointF(point))) {
                // run the hit test
                HitTestResult result = obj.HitTest(point, (float)tolerance);
                // apply the filter
                if (filter(result)) {
                    return result;
                }
            }

            // return a no-hit
            return HitTestResult.NoHit;
        }
        public HitTestResult HitTest(Coordinates point, double tolerance, HitTestFilter filter)
        {
            // first check the selected object and it's hierarchy
            if (selectedObject != null) {
                object obj = selectedObject;
                while (obj != null) {
                    if (obj is IHittable) {
                        // run the hit test on the object
                        HitTestResult hitResult = HitTest((IHittable)obj, point, tolerance, filter);
                        // if it's a hit, we're done
                        if (hitResult.Hit)
                            return hitResult;
                    }

                    // move up the next step in the hierarchy
                    obj = ((IHittable)obj).Parent;
                }
            }

            // iterate backwards through the objects (last object is drawn on top)
            foreach (object obj in Services.DisplayObjectService.GetReverseVisibleEnumerator()) {
                if (obj is IHittable) {
                    // run the hit test on the object
                    HitTestResult hitResult = HitTest((IHittable)obj, point, tolerance, filter);
                    // if it's a hit, we're done
                    if (hitResult.Hit)
                        return hitResult;
                }
            }

            // return a no hit
            return HitTestResult.NoHit;
        }