public bool GetNearestCollision(out RRayCollision col)
        {
            if (!collisions.Any())
            {
                col = new RRayCollision();
                return(false);
            }
            var min = collisions.Min(y => y.distance);

            col = collisions.Where(x => x.distance == min).First();
            return(true);
        }
        public bool GetFarthestCollision(out RRayCollision col)
        {
            if (!collisions.Any())
            {
                col = new RRayCollision();
                return(false);
            }
            var max = collisions.Max(y => y.distance);

            col = collisions.Where(x => x.distance == max).First();
            return(true);
        }
        /// <summary>
        /// Cast a ray in a direction and return all collisions
        /// </summary>
        public static RRay Cast(ModelInfo info, View3D view, List <BuiltInCategory> find_cats, XYZ origin_pt, XYZ ray_dir, double max_distance = -1, List <ElementId> ids_to_ignore = null)
        {
            RRay ray = new RRay
            {
                direction   = ray_dir,
                start_point = origin_pt
            };

            bool prune_lengths = max_distance >= 0;

            ReferenceIntersector ref_intersect = new ReferenceIntersector(
                new ElementMulticategoryFilter(find_cats), FindReferenceTarget.Element, view)
            {
                FindReferencesInRevitLinks = true
            };

            List <ReferenceWithContext> rwcs = new List <ReferenceWithContext>();

            rwcs = ref_intersect.Find(ray.start_point, ray.direction).ToList();

            if (prune_lengths)
            {
                foreach (var rwc in rwcs.ToArray())
                {
                    if (rwc.Proximity > max_distance)
                    {
                        rwcs.Remove(rwc);
                    }
                }
            }

            List <RRayCollision> temp_collisions_storage = new List <RRayCollision>();

            if (ids_to_ignore == null)
            {
                ids_to_ignore = new List <ElementId>();
            }

            foreach (var rwc in rwcs)
            {
                Reference r = rwc.GetReference();
                if (ids_to_ignore.Any(x => x.IntegerValue == r.ElementId.IntegerValue))
                {
                    continue;
                }

                Element collided_element = info.DOC.GetElement(r.ElementId);
                if (collided_element == null)
                {
                    continue;
                }

                RRayCollision ray_collision = new RRayCollision();
                if (max_distance == -1)
                {
                    ray_collision.distance = rwc.Proximity;
                    ray_collision.other_id = collided_element.Id;
                    ray_collision.point    = r.GlobalPoint;
                    temp_collisions_storage.Add(ray_collision);
                }
                else
                {
                    if (rwc.Proximity <= max_distance)
                    {
                        ray_collision.distance = rwc.Proximity;
                        ray_collision.other_id = collided_element.Id;
                        ray_collision.point    = r.GlobalPoint;
                        temp_collisions_storage.Add(ray_collision);
                    }
                }
            }

            ray.collisions = temp_collisions_storage.ToArray();
            return(ray);
        }