Ejemplo n.º 1
0
 private static Dir4 GetNormal(Loc invEntry, Loc invExit, Multiplier entryX, Multiplier entryY)
 {
     if (entryX > entryY)
     {
         return((invEntry.X < 0) || (invEntry.X == 0 && invExit.X < 0) ? Dir4.Right : Dir4.Left);
     }
     else if (entryX < entryY)
     {
         return((invEntry.Y < 0 || (invEntry.Y == 0 && invExit.Y < 0)) ? Dir4.Down : Dir4.Up);
     }
     else
     {
         return(Dir4.None);
     }
 }
Ejemplo n.º 2
0
        private static Hit ResolveNarrow(Loc origin1, Loc origin2, Loc destination, Rect other)
        {
            var velocity = (destination - origin1);

            Loc        invEntry, invExit;
            Multiplier entryX, entryY, exitX, exitY;

            if (velocity.X > 0)
            {
                invEntry.X = other.Left - origin2.X;
                invExit.X  = other.Right - origin1.X;
            }
            else
            {
                invEntry.X = other.Right - origin1.X;
                invExit.X  = other.Left - origin2.X;
            }

            if (velocity.Y > 0)
            {
                invEntry.Y = other.Top - origin2.Y;
                invExit.Y  = other.Bottom - origin1.Y;
            }
            else
            {
                invEntry.Y = other.Bottom - origin1.Y;
                invExit.Y  = other.Top - origin2.Y;
            }

            if (velocity.X == 0)
            {
                entryX = Multiplier.MinValue;
                exitX  = Multiplier.MaxValue;
            }
            else
            {
                entryX = new Multiplier(invEntry.X, velocity.X);
                exitX  = new Multiplier(invExit.X, velocity.X);

                if (entryX > new Multiplier(1, 1))
                {
                    entryX = Multiplier.MaxValue;
                }
            }

            if (velocity.Y == 0)
            {
                entryY = Multiplier.MinValue;
                exitY  = Multiplier.MaxValue;
            }
            else
            {
                entryY = new Multiplier(invEntry.Y, velocity.Y);
                exitY  = new Multiplier(invExit.Y, velocity.Y);

                if (entryY > new Multiplier(1, 1))
                {
                    entryY = Multiplier.MinValue;
                }
            }

            var entryTime = Multiplier.Max(entryX, entryY);
            var exitTime  = Multiplier.Min(exitX, exitY);

            if ((entryTime > exitTime || entryX == Multiplier.MinValue && entryY == Multiplier.MinValue) ||
                (entryX == Multiplier.MinValue && (origin2.X < other.Left || origin1.X > other.Right)) ||
                entryY == Multiplier.MinValue && (origin2.Y < other.Top || origin1.Y > other.Bottom))
            {
                return(null);
            }


            var result = new Hit()
            {
                Amount   = entryTime,
                Position = origin1 + velocity * entryTime.Numerator / entryTime.Denominator,
                Normal   = GetNormal(invEntry, invExit, entryX, entryY),
            };

            return(result);
        }