/// <summary> /// Returns a random long between min and max. Both bounds are included by default /// </summary> public static long RandLong(long min, long max, InclusionOptions option = InclusionOptions.Both) { if (min < max) { //Handle long overflow if (max == long.MaxValue) { if (option == InclusionOptions.Upper) { option = InclusionOptions.None; } else if (option == InclusionOptions.Both) { option = InclusionOptions.Lower; } } if (min == long.MinValue) { if (option == InclusionOptions.Lower) { option = InclusionOptions.None; } else if (option == InclusionOptions.Both) { option = InclusionOptions.Upper; } } switch (option) { case InclusionOptions.Both: return(RandLongInRange(min, max + 1)); case InclusionOptions.Lower: return(RandLongInRange(min, max)); case InclusionOptions.Upper: return(RandLongInRange(min + 1, max + 1)); case InclusionOptions.None: return(RandLongInRange(min + 1, max)); default: throw new ArgumentException("Invalid InclusionOption"); } } else if (min == max) { return(min); } else { return(RandLong(max, min, option)); } }
private bool OtherAxisCheck(Rectangle other, Direction side, InclusionOptions coordinateInclusion) { other.ThrowIfNull(nameof(other)); switch (side) { case Direction.Up: case Direction.Down: switch (coordinateInclusion) { case InclusionOptions.BothInclusive: return(X >= other.X && Right <= other.Right); case InclusionOptions.OnlyLeftInclusive: return(X >= other.X && Right < other.Right); case InclusionOptions.OnlyRightInclusive: return(X > other.X && Right <= other.Right); case InclusionOptions.BothExclusive: return(X > other.X && Right < other.Right); default: throw new UnknownEnumValueException(); } case Direction.Left: case Direction.Right: switch (coordinateInclusion) { case InclusionOptions.BothInclusive: return(Y >= other.Y && Bottom <= other.Bottom); case InclusionOptions.OnlyLeftInclusive: return(Y >= other.Y && Bottom < other.Bottom); case InclusionOptions.OnlyRightInclusive: return(Y > other.Y && Bottom <= other.Bottom); case InclusionOptions.BothExclusive: return(Y > other.Y && Bottom < other.Bottom); default: throw new UnknownEnumValueException(); } default: throw new UnknownEnumValueException(); } }
/// <summary> /// Determines if a number is in the interval /// </summary> /// <param name="number">Number to test</param> /// <param name="left">Left side of the interval</param> /// <param name="right">Right side of the interval</param> /// <param name="options">Interval inclusion option</param> /// <exception cref="UnknownEnumValueException"/> public static bool Between(this double number, double left, double right, InclusionOptions options = InclusionOptions.BothInclusive) { switch (options) { case InclusionOptions.BothInclusive: return(number >= left && number <= right); case InclusionOptions.OnlyLeftInclusive: return(number >= left && number < right); case InclusionOptions.OnlyRightInclusive: return(number > left && number <= right); case InclusionOptions.BothExclusive: return(number > left && number < right); default: throw new UnknownEnumValueException(); } }
/// <summary> /// Checks which sides of the other rectangle are inside the current one /// </summary> /// <param name="other">Other rectangle</param> /// <param name="fullSideInsideCheck">Should the side be qualified as "inside" /// if it is fully in or if it partially in</param> /// <param name="coordinateInclusion">How should the check be performed</param> /// <exception cref="ArgumentNullException"/> public Direction Inside(Rectangle other, bool fullSideInsideCheck, InclusionOptions coordinateInclusion) { other.ThrowIfNull(nameof(other)); var direction = Direction.None; bool leftSideIn = SideIn(other, Direction.Left, coordinateInclusion); bool rightSideIn = SideIn(other, Direction.Right, coordinateInclusion); bool topSideIn = SideIn(other, Direction.Up, coordinateInclusion); bool bottomSideIn = SideIn(other, Direction.Down, coordinateInclusion); bool topAndBottomIn = topSideIn && bottomSideIn; bool leftAndRightIn = leftSideIn && rightSideIn; if (!fullSideInsideCheck || topAndBottomIn) { if (leftSideIn) { direction |= Direction.Left; } if (rightSideIn) { direction |= Direction.Right; } } if (!fullSideInsideCheck || leftAndRightIn) { if (topSideIn) { direction |= Direction.Up; } if (bottomSideIn) { direction |= Direction.Down; } } return(direction); }
/// <summary> /// Checks if a side of the other rectangle is inside the current one /// </summary> /// <param name="other">Other rectangle</param> /// <param name="side">Side to check</param> /// <param name="coordinateInclusion">How should the check be performed</param> /// <exception cref="ArgumentNullException"/> /// <exception cref="UnknownEnumValueException"/> public bool SideIn(Rectangle other, Direction side, InclusionOptions coordinateInclusion) { other.ThrowIfNull(nameof(other)); switch (side) { case Direction.Up: if (!Y.Between(other.Y, other.Bottom, coordinateInclusion)) { return(false); } break; case Direction.Down: if (!Bottom.Between(other.Y, other.Bottom, coordinateInclusion)) { return(false); } break; case Direction.Left: if (!X.Between(other.X, other.Right, coordinateInclusion)) { return(false); } break; case Direction.Right: if (!Right.Between(other.X, other.Right, coordinateInclusion)) { return(false); } break; default: throw new UnknownEnumValueException(); } return(OtherAxisCheck(other, side, coordinateInclusion)); }
/// <summary> /// Returns a random long between 0 and max. Max is excluded by default /// </summary> /// <param name="max">The upper bound for the random value</param> /// <param name="option">Determines which bounds are included</param> public static long RandLong(long max, InclusionOptions option = InclusionOptions.Lower) { return(RandLong(0, max, option)); }
/// <summary> /// Returns a random integer between 0 and max. Max is excluded by default /// </summary> /// <param name="max">The upper bound for the random value</param> /// <param name="option">Determines which bounds are included</param> public static int RandInt(int max, InclusionOptions option = InclusionOptions.Lower) { return(RandInt(0, max, option)); }
/// <summary> /// Checks if other rectangle is fully inside the current one /// </summary> /// <param name="other">Other rectangle</param> /// <param name="coordinateInclusion">How should the check be performed</param> /// <exception cref="ArgumentNullException"/> public bool FullyInside(Rectangle other, InclusionOptions coordinateInclusion) => Inside(other, true, coordinateInclusion) == (Direction.Up | Direction.Down | Direction.Left | Direction.Right);
/// <summary> /// Determines if a number is in the interval /// </summary> /// <param name="number">Number to test</param> /// <param name="left">Left side of the interval</param> /// <param name="right">Right side of the interval</param> /// <param name="options">Interval inclusion option</param> /// <exception cref="UnknownEnumValueException"/> public static bool Between(this int number, double left, double right, InclusionOptions options = InclusionOptions.BothInclusive) => Between((double)number, left, right, options);