public static HashSet <Location> GenerateAreaMask(int firstSize, AreaMaskShapeType areaMaskShapeType) { HashSet <Location> areaMask = new HashSet <Location>(); switch (areaMaskShapeType) { case AreaMaskShapeType.Vertical: firstSize.For(i => areaMask.Add(new Location(0, i))); break; case AreaMaskShapeType.Horizontal: firstSize.For(i => areaMask.Add(new Location(i, 0))); break; case AreaMaskShapeType.Cross: (-firstSize, firstSize).ForIncludeEnd(i => areaMask.Add(new Location(0, i))); (-firstSize, firstSize).ForIncludeEnd(i => areaMask.Add(new Location(i, 0))); break; case AreaMaskShapeType.Rectangle: (-firstSize, firstSize).ForIncludeEnd(x => (-firstSize, firstSize).ForIncludeEnd(y => { areaMask.Add(new Location(x, y)); })); break; case AreaMaskShapeType.Square: (-firstSize, firstSize).ForIncludeEnd(x => (-firstSize, firstSize).ForIncludeEnd(y => { areaMask.Add(new Location(x, y)); })); break; case AreaMaskShapeType.Rhombus: (-firstSize, firstSize).ForIncludeEnd(x => (-(firstSize - Mathf.Abs(x)), (firstSize - Mathf.Abs(x))).ForIncludeEnd(y => { areaMask.Add(new Location(x, y)); })); break; } return(areaMask); }
public static HashSet <Location> GenerateAreaMask(float firstSize, float secondSize, AreaMaskShapeType areaMaskShapeType, ApproximationType approximationType, float roundThreshold = 0.5f) { HashSet <Location> areaMask = new HashSet <Location>(); switch (areaMaskShapeType) { case AreaMaskShapeType.Vertical: (firstSize, secondSize - 1).For(i => areaMask.Add(new Location(0, i))); break; case AreaMaskShapeType.Horizontal: (firstSize, secondSize - 1).For(i => areaMask.Add(new Location(i, 0))); break; case AreaMaskShapeType.Cross: (-firstSize, firstSize).For(i => areaMask.Add(new Location(0, i))); (-secondSize, secondSize).For(i => areaMask.Add(new Location(i, 0))); break; case AreaMaskShapeType.Rectangle: (-firstSize, firstSize) .For(x => secondSize .For(y => { areaMask.Add(new Location(x, y)); })); break; case AreaMaskShapeType.Square: (-firstSize, firstSize).For(x => (-secondSize, secondSize).For(y => { areaMask.Add(new Location(x, y)); })); break; case AreaMaskShapeType.Rhombus: switch (approximationType) { case ApproximationType.Round: (-firstSize, firstSize) .For(x => (-(secondSize * (1f - Mathf.Abs(x) / firstSize)).Round(roundThreshold), (secondSize * (1f - (Mathf.Abs(x) / firstSize))).Round(roundThreshold)) .For(y => { areaMask.Add(new Location(x, y)); })); (-secondSize, secondSize) .For(y => (-(firstSize * (1f - Mathf.Abs(y) / secondSize)).Round(roundThreshold), (firstSize * (1f - (Mathf.Abs(y) / secondSize))).Round(roundThreshold)) .For(x => { areaMask.Add(new Location(x, y)); })); break; case ApproximationType.Convex: (-firstSize, firstSize) .For(x => (-(secondSize * (1f - Mathf.Abs(x) / firstSize)).Ceil(), (secondSize * (1f - (Mathf.Abs(x) / firstSize))).Ceil()) .For(y => { areaMask.Add(new Location(x, y)); })); (-secondSize, secondSize) .For(y => (-(firstSize * (1f - Mathf.Abs(y) / secondSize)).Ceil(), (firstSize * (1f - (Mathf.Abs(y) / secondSize))).Ceil()) .For(x => { areaMask.Add(new Location(x, y)); })); break; case ApproximationType.Concave: (-firstSize, firstSize) .For(x => (-(secondSize * (1f - Mathf.Abs(x) / firstSize)).Floor(), (secondSize * (1f - (Mathf.Abs(x) / firstSize))).Floor()) .For(y => { areaMask.Add(new Location(x, y)); })); (-secondSize, secondSize) .For(y => (-(firstSize * (1f - Mathf.Abs(y) / secondSize)).Floor(), (firstSize * (1f - (Mathf.Abs(y) / secondSize))).Floor()) .For(x => { areaMask.Add(new Location(x, y)); })); break; } break; case AreaMaskShapeType.Circle: switch (approximationType) { case ApproximationType.Round: (-firstSize, firstSize) .For(x => (-(secondSize * (1f - (x / firstSize).Square()).Sqrt()).Round(roundThreshold), (secondSize * (1f - (x / firstSize).Square()).Sqrt()).Round(roundThreshold)) .For(y => { areaMask.Add(new Location(x, y)); })); (-secondSize, secondSize) .For(y => (-(firstSize * (1f - (y / secondSize).Square()).Sqrt()).Round(roundThreshold), (firstSize * (1f - (y / secondSize).Square()).Sqrt()).Round(roundThreshold)) .For(x => { areaMask.Add(new Location(x, y)); })); break; case ApproximationType.Convex: (-firstSize, firstSize) .For(x => (-(secondSize * (1f - (x / firstSize).Square()).Sqrt()).Ceil(), (secondSize * (1f - (x / firstSize).Square()).Sqrt()).Ceil()) .For(y => { areaMask.Add(new Location(x, y)); })); (-secondSize, secondSize) .For(y => (-(firstSize * (1f - (y / secondSize).Square()).Sqrt()).Ceil(), (firstSize * (1f - (y / secondSize).Square()).Sqrt()).Ceil()) .For(x => { areaMask.Add(new Location(x, y)); })); break; case ApproximationType.Concave: (-firstSize, firstSize) .For(x => (-(secondSize * (1f - (x / firstSize).Square()).Sqrt()).Floor(), (secondSize * (1f - (x / firstSize).Square()).Sqrt()).Floor()) .For(y => { areaMask.Add(new Location(x, y)); })); (-secondSize, secondSize) .For(y => (-(firstSize * (1f - (y / secondSize).Square()).Sqrt()).Floor(), (firstSize * (1f - (y / secondSize).Square()).Sqrt()).Floor()) .For(x => { areaMask.Add(new Location(x, y)); })); break; } break; case AreaMaskShapeType.Arc: switch (approximationType) { case ApproximationType.Round: (-firstSize, firstSize) .For(x => (((secondSize.Square() - firstSize.Square()).Sqrt() / firstSize * x.Abs()).Round(1f - roundThreshold), (secondSize.Square() - x.Square()).Sqrt().Round(roundThreshold)) .For(y => { areaMask.Add(new Location(x, y)); })); (secondSize.Square() - firstSize.Square()).Sqrt() .For(y => (-(firstSize / secondSize * y).Round(roundThreshold), (firstSize / secondSize * y).Round(roundThreshold)) .For(x => { areaMask.Add(new Location(x, y)); })); ((secondSize.Square() - firstSize.Square()).Sqrt(), secondSize) .For(y => (-(secondSize.Square() - y.Square()).Sqrt().Round(roundThreshold), (secondSize.Square() - y.Square()).Sqrt().Round(roundThreshold)) .For(x => { areaMask.Add(new Location(x, y)); })); break; case ApproximationType.Convex: (-firstSize, firstSize) .For(x => (((secondSize.Square() - firstSize.Square()).Sqrt() / firstSize * x.Abs()).Floor(), (secondSize.Square() - x.Square()).Sqrt().Ceil()) .For(y => { areaMask.Add(new Location(x, y)); })); (secondSize.Square() - firstSize.Square()).Sqrt() .For(y => (-(firstSize / secondSize * y).Ceil(), (firstSize / secondSize * y).Ceil()) .For(x => { areaMask.Add(new Location(x, y)); })); ((secondSize.Square() - firstSize.Square()).Sqrt(), secondSize) .For(y => (-(secondSize.Square() - y.Square()).Sqrt().Ceil(), (secondSize.Square() - y.Square()).Sqrt().Ceil()) .For(x => { areaMask.Add(new Location(x, y)); })); break; case ApproximationType.Concave: (-firstSize, firstSize) .For(x => (((secondSize.Square() - firstSize.Square()).Sqrt() / firstSize * x.Abs()).Ceil(), (secondSize.Square() - x.Square()).Sqrt().Floor()) .For(y => { areaMask.Add(new Location(x, y)); })); (secondSize.Square() - firstSize.Square()).Sqrt() .For(y => (-(firstSize / secondSize * y).Floor(), (firstSize / secondSize * y).Floor()) .For(x => { areaMask.Add(new Location(x, y)); })); ((secondSize.Square() - firstSize.Square()).Sqrt(), secondSize) .For(y => (-(secondSize.Square() - y.Square()).Sqrt().Floor(), (secondSize.Square() - y.Square()).Sqrt().Floor()) .For(x => { areaMask.Add(new Location(x, y)); })); break; } break; case AreaMaskShapeType.Cone: switch (approximationType) { case ApproximationType.Round: (-firstSize, firstSize) .For(x => ((secondSize / firstSize * x.Abs()).Round(roundThreshold), secondSize - 1) .For(y => { areaMask.Add(new Location(x, y)); })); secondSize .For(y => (-(firstSize / secondSize * y).Round(roundThreshold), (firstSize / secondSize * y).Round(roundThreshold)) .For(x => { areaMask.Add(new Location(x, y)); })); break; case ApproximationType.Convex: (-firstSize, firstSize) .For(x => ((secondSize / firstSize * x.Abs()).Floor(), secondSize - 1) .For(y => { areaMask.Add(new Location(x, y)); })); secondSize .For(y => (-(firstSize / secondSize * y).Ceil(), (firstSize / secondSize * y).Ceil()) .For(x => { areaMask.Add(new Location(x, y)); })); break; case ApproximationType.Concave: (-firstSize, firstSize) .For(x => ((secondSize / firstSize * x.Abs()).Ceil(), secondSize - 1) .For(y => { areaMask.Add(new Location(x, y)); })); secondSize .For(y => (-(firstSize / secondSize * y).Floor(), (firstSize / secondSize * y).Floor()) .For(x => { areaMask.Add(new Location(x, y)); })); break; } break; } return(areaMask); }