Beispiel #1
0
        /// <summary> Intersect the <see cref="AxisAlignedBox"/> by a <paramref name="ray"/>.
        /// Using Amy Williams's "An Efficient and Robust Ray–Box Intersection" Algorithm </summary>
        /// <param name="ray">The <see cref="Ray"/> to intersect the <see cref="IAxisAlignedBox"/> with</param>
        /// <returns>Whether and when the <see cref="Ray"/> intersects the <see cref="IAxisAlignedBox"/></returns>
        public IEnumerable <Position1> IntersectDistances(IRay ray)
        {
            Position1 tmin = (Bounds[ray.Sign.X].X - ray.Origin.X) * ray.InvDirection.X;
            Position1 tmax = (Bounds[1 - ray.Sign.X].X - ray.Origin.X) * ray.InvDirection.X;

            Position1 tymin = (Bounds[ray.Sign.Y].Y - ray.Origin.Y) * ray.InvDirection.Y;
            Position1 tymax = (Bounds[1 - ray.Sign.Y].Y - ray.Origin.Y) * ray.InvDirection.Y;

            if ((tmin > tymax) || (tmax < tymin))
            {
                yield break;
            }
            tmin = Position1.Max(tmin, tymin);
            tmax = Position1.Min(tmax, tymax);

            Position1 tzmin = (Bounds[ray.Sign.Z].Z - ray.Origin.Z) * ray.InvDirection.Z;
            Position1 tzmax = (Bounds[1 - ray.Sign.Z].Z - ray.Origin.Z) * ray.InvDirection.Z;

            if ((tmin > tzmax) || (tmax < tzmin))
            {
                yield break;
            }
            yield return(Position1.Max(tmin, tzmin));

            yield return(Position1.Min(tmax, tzmax));
        }
Beispiel #2
0
        /// <summary> Clip the <see cref="AxisAlignedBox"/> by a <paramref name="plane"/> </summary>
        /// <param name="plane">The <see cref="AxisAlignedPlane"/> to clip the <see cref="AxisAlignedBox"/> with</param>
        /// <returns>A new clipped <see cref="AxisAlignedBox"/> if it's not clipped entirely</returns>
        public IEnumerable <AxisAlignedBox> Clip(AxisAlignedPlane plane)
        {
            Position3 minCorner = MinCorner;
            Position3 maxCorner = MaxCorner;

            if (plane.Normal == Normal3.UnitX)
            {
                minCorner = new(Position1.Max(MinCorner.X, plane.Position.X), MinCorner.Y, MinCorner.Z);
            }
            else if (plane.Normal == -Normal3.UnitX)
            {
                maxCorner = new(Position1.Min(MinCorner.X, plane.Position.X), MaxCorner.Y, MaxCorner.Z);
            }
            else if (plane.Normal == Normal3.UnitY)
            {
                minCorner = new(MinCorner.X, Position1.Max(MinCorner.Y, plane.Position.Y), MinCorner.Z);
            }
            else if (plane.Normal == -Normal3.UnitY)
            {
                maxCorner = new(MaxCorner.X, Position1.Min(MaxCorner.Y, plane.Position.Y), MaxCorner.Z);
            }
            else if (plane.Normal == Normal3.UnitZ)
            {
                minCorner = new(MinCorner.X, MinCorner.Y, Position1.Max(MinCorner.Z, plane.Position.Z));
            }
            else if (plane.Normal == -Normal3.UnitZ)
            {
                maxCorner = new(MaxCorner.X, MaxCorner.Y, Position1.Min(MaxCorner.Z, plane.Position.Z));
            }
            if (minCorner == MinCorner && maxCorner == MaxCorner)
            {
                yield return(this);
            }
            else if (minCorner.X < maxCorner.X && minCorner.Y < maxCorner.Y && minCorner.Z < maxCorner.Z)
            {
                yield return(new AxisAlignedBox(minCorner, maxCorner));
            }
        }