//TODO: @herman, check at the examples. /// <summary> /// Returns a list containing lines connected to the given points. A line is a list of points. /// Only returns correct results for square or hex grids. /// </summary> /// <example> /// <code> /// private bool IsSameColour(point1, point2) /// { /// return grid[point1].Color == grid[point2].Color; /// } /// /// private SomeMethod() /// { /// ... /// var rays = GetConnectedRays<ColourCell, PointyHexPoint, PointyHexNeighborIndex>( /// grid, point, IsSameColour); /// ... /// } /// </code> /// You can of course also use a lambda expression, like this: /// <code> /// //The following code returns all lines that radiate from the given point /// GetConnectedRays<ColourCell, PointyHexPoint, PointyHexNeighborIndex>( /// grid, point, (x, y) => grid[x].Color == grid[y].Color); /// </code> /// </example> /// <typeparam name="TPoint">The type of point of the grid that this algorithm takes.</typeparam> /// <param name="grid">Grid in which the calculations are made.</param> /// <param name="point">Point where the calculations start.</param> /// <param name="rayGenerators"></param> //TODO: Remove this argument? Make that as part of the rayGenerator? /// <param name="isNeighborsConnected"> /// A functions that returns true or false, depending on whether /// two points can be considered connected when they are neighbors.For example, if you want /// rays of points that refer to cells of the same color, you can pass in a functions that /// compares the DefaultColors of cells. /// </param> public static IEnumerable <IEnumerable <TPoint> > GetConnectedRays <TPoint>( IImplicitShape <TPoint> grid, TPoint point, IEnumerable <IForwardMap <TPoint, TPoint> > rayGenerators, Func <TPoint, TPoint, bool> isNeighborsConnected) { var lines = new List <IEnumerable <TPoint> >(); foreach (var rayGenertor in rayGenerators) { var line = new StructList <TPoint>(); var rayEnd = point; while (grid.Contains(rayEnd) && isNeighborsConnected(point, rayEnd)) { line.Add(rayEnd); rayEnd = rayGenertor.Forward(rayEnd); } if (line.Count > 1) { lines.Add(line); } } return(lines); }
public ProductShape2(IExplicitShape <GridPoint2> shape1, IImplicitShape <GridPoint2> shape2, GridPoint2 scaleFactor) { var translationShapes = shape1.Points .Select(point => shape2.Translate(point.Mul(scaleFactor))); unionShape = new UnionShape <GridPoint2>(translationShapes); }
/// <summary> /// Creates a shape that is the product of this shape with another shape. /// </summary> /// <remarks> /// Takes the first shape, and for each point, scale that point by /// the given amount, and create a copy of the second shape at that point. /// The combined shape is the product of the two shapes. /// </remarks> public static IImplicitShape <GridPoint3> Product( this IExplicitShape <GridPoint3> shape1, IImplicitShape <GridPoint3> shape2, GridPoint3 scale) { return(new ProductShape3(shape1, shape2, scale)); }
/// <summary> /// Get the longest line of points connected to the given point /// </summary> /// <typeparam name="TPoint">The type of point of the grid that this algorithm takes.</typeparam> /// <param name="grid">Grid in which the calculations are made.</param> /// <param name="point">Point where the calculations start.</param> /// <param name="lineGenerators">List of line generators.</param> //TODO is Generator the right word? /// <param name="isNeighborsConnected"> /// A functions that returns true or false, depending on whether /// two points can be considered connected when they are neighbors.For example, if you want /// rays of points that refer to cells of the same color, you can pass in a functions that /// compares the DefaultColors of cells. /// </param> public static IEnumerable <TPoint> GetLongestConnectedLine <TPoint>( IImplicitShape <TPoint> grid, TPoint point, IEnumerable <IMap <TPoint, TPoint> > lineGenerators, Func <TPoint, TPoint, bool> isNeighborsConnected) { var lines = GetConnectedLines(grid, point, lineGenerators, isNeighborsConnected); return(GetBiggestShape(lines)); }
/// <summary> /// Gets the longest of the rays connected to this cell. /// <see cref="GetConnectedRays{TPoint}"/> /// </summary> /// <typeparam name="TPoint">The type of point of the grid that this algorithm takes.</typeparam> /// <param name="grid">Grid in which the calculations are made.</param> /// <param name="point">Point where the calculations start.</param> /// <param name="rayGenerators">List of ray generators.</param> //TODO is Generator the right word? /// <param name="isNeighborsConnected"> /// A functions that returns true or false, depending on whether /// two points can be considered connected when they are neighbors.For example, if you want /// rays of points that refer to cells of the same color, you can pass in a functions that /// compares the DefaultColors of cells. /// </param> public static IEnumerable <TPoint> GetLongestConnectedRay <TPoint>( IImplicitShape <TPoint> grid, TPoint point, IEnumerable <IForwardMap <TPoint, TPoint> > rayGenerators, Func <TPoint, TPoint, bool> isNeighborsConnected) { var rays = GetConnectedRays(grid, point, rayGenerators, isNeighborsConnected); return(GetBiggestShape(rays)); }
public ConvexPolygonShape2(IEnumerable <GridPoint2> vertices) { var vertexList = vertices.ToList(); var halfPlanes = new List <IImplicitShape <GridPoint2> >(); for (int i = 0; i < vertexList.Count; i++) { int nextI = i + 1; if (nextI == vertexList.Count) { nextI = 0; } var halfPlane = new Halfplane(vertexList[i], vertexList[nextI]); halfPlanes.Add(halfPlane); } shape = Intersection(halfPlanes); }
/// <summary> /// Gets the longest line of connected points that contains this point. /// <see cref="GetConnectedRays{TPoint}"/> /// </summary> /// <typeparam name="TPoint">The type of point of the grid that this algorithm takes.</typeparam> /// <param name="grid">Grid in which the calculations are made.</param> /// <param name="point">Point where the calculations start.</param> /// <param name="lineGenerators">List of line generators.</param> //TODO is Generator the right word? /// <param name="isNeighborsConnected"> /// A functions that returns true or false, depending on whether /// two points can be considered connected when they are neighbors.For example, if you want /// rays of points that refer to cells of the same color, you can pass in a functions that /// compares the DefaultColors of cells. /// </param> public static IEnumerable <IEnumerable <TPoint> > GetConnectedLines <TPoint>( IImplicitShape <TPoint> grid, TPoint point, IEnumerable <IMap <TPoint, TPoint> > lineGenerators, Func <TPoint, TPoint, bool> isNeighborsConnected) { var lines = new List <IEnumerable <TPoint> >(); foreach (var lineGenerator in lineGenerators) { var line = new StructList <TPoint>(); var edge = point; //go forwards while (grid.Contains(edge) && isNeighborsConnected(point, edge)) { edge = lineGenerator.Forward(edge); } //TPoint oppositeNeighbor = point.MoveBy(direction.Negate()); edge = lineGenerator.Reverse(edge); //go backwards while (grid.Contains(edge) && isNeighborsConnected(point, edge)) { line.Add(edge); edge = lineGenerator.Reverse(edge); } if (line.Count > 1) { lines.Add(line); } } return(lines); }
/// <summary> /// Get's an enumerable of shape points in a spiral outwards from a given point, assuming the points are coordinates of /// a hex grid. /// </summary> /// <param name="shape">The shape to return points from.</param> /// <param name="origin">Where the spiral should start.</param> /// <param name="ringCount">How many rings there should be in the spiral. The origin is the first ring, so when ringCount is /// 1, only the origin will be returned.</param> /// <remarks> /// <note type="note"> /// Remember that <see cref="IExplicitShape{TPoint}"/>, <see cref="IGrid{TPoint, TCell}"/> /// and <see cref="Grid2{TCell}"/> all are also of type <see cref="IImplicitShape{TPoint}"/>, /// so this method can be used with explicit shapes and grids too. /// </note> /// <note type="tip">You can transform the grid shape to get transformed spirals, such /// as spirals going in the opposite direction, using <see cref="ImplicitShape.ReverseSelect{TPoint}(IImplicitShape{TPoint}, Func{TPoint, TPoint})"/>. For example: /// <code> /// <![CDATA[ /// var reverseSpiral = PointyHexPoint /// .GetSpiralIterator( /// grid.ReverseSelect(p => PointyHexPoint.ReflectAboutX(p)), /// center, /// radius); /// ]]> /// </code> /// </note> /// </remarks> //TODO: make sure this example works as expected!g public static IEnumerable <GridPoint2> GetSpiralIterator(IImplicitShape <GridPoint2> shape, GridPoint2 origin, int ringCount) { var point = origin; yield return(point); for (var k = 1; k < ringCount; k++) { point += NorthWest; for (var i = 0; i < 6; i++) { for (var j = 0; j < k; j++) { point += SpiralIteratorDirections[i]; if (shape.Contains(point)) { yield return(point); } } } } }
public static IImplicitShape <TPoint> ReverseSelect <TPoint>( this IImplicitShape <TPoint> shape, Func <TPoint, TPoint> projection) { return(Func <TPoint>(p => shape.Contains(projection(p)))); }
public static IExplicitShape <int> ToExplicit(this IImplicitShape <int> shape, AbstractBounds <int> bounds) { return(new ExplicitShape1(shape, bounds)); }
/// <summary> /// Creates a 1D Translation Shape with a given offset. /// </summary> /// <param name="shape">Base shape used to make the translation.</param> /// <param name="offset">Offset to perform in the shape.</param> public static IImplicitShape <int> Translate(this IImplicitShape <int> shape, int offset) { return(new TranslationShape1(shape, offset)); }
public TranslationShape3(IImplicitShape <GridPoint3> baseShape, GridPoint3 offset) { this.offset = offset; this.baseShape = baseShape; }
/// <summary> /// Create a generic Function Shape that works as a Generic Inverse. /// </summary> /// <typeparam name="TPoint">Type of the point.</typeparam> /// <param name="shape">Shape to apply the inverse operation.</param> public static IImplicitShape <TPoint> Inverse <TPoint>(IImplicitShape <TPoint> shape) { return(new FunctionShape <TPoint>(p => !shape.Contains(p))); }
public ExplicitShape1(IImplicitShape <int> implicitShape, AbstractBounds <int> storageBounds) { this.implicitShape = implicitShape; this.storageBounds = storageBounds; }
public static IExplicitShape <GridPoint3> ToExplicit(this IImplicitShape <GridPoint3> shape, AbstractBounds <GridPoint3> bounds) { return(new ExplicitShape3(shape, bounds)); }
/// <summary> /// Creates a generic Function Shape that works as a Generic Intersection. /// </summary> /// <typeparam name="TPoint">The type of the point.</typeparam> /// <param name="shape1">First Shape.</param> /// <param name="shape2">Second Shape.</param> public static IImplicitShape <TPoint> Intersection <TPoint>(IImplicitShape <TPoint> shape1, IImplicitShape <TPoint> shape2) { return(new FunctionShape <TPoint>(p => shape1.Contains(p) && shape2.Contains(p))); }
/// <summary> /// Creates a generic Function Shape that works as a Generic Transform. /// </summary> /// <typeparam name="TPoint">The type of the point.</typeparam> /// <param name="shape">Shape to transform.</param> /// <param name="transform">Reverse map to apply into the shape.</param> /// <returns></returns> public static IImplicitShape <TPoint> Transform <TPoint>( IImplicitShape <TPoint> shape, IReverseMap <TPoint, TPoint> transform) { return(new FunctionShape <TPoint>(p => shape.Contains(transform.Reverse(p)))); }
/// <summary> /// Selects all the points in the list also in the given shape. /// </summary> /// <typeparam name="TPoint">The point type.</typeparam> /// <param name="points">The points.</param> /// <param name="shape">The shape.</param> /// <remarks> /// <note type="note"> /// You can also pass an explicit shape or grid for the shape parameter. /// </note> /// </remarks> public static IEnumerable <TPoint> In <TPoint>( this IEnumerable <TPoint> points, IImplicitShape <TPoint> shape) { return(points.Where(shape.Contains)); }
/// <summary> /// Creates a generic Function Shape that works as a Generic Where. /// </summary> /// <typeparam name="TPoint">Type of the point.</typeparam> /// <param name="shape">Shape to apply the Where operation.</param> /// <param name="predicate">Predicate that indicate the where condition.</param> public static IImplicitShape <TPoint> Where <TPoint>(IImplicitShape <TPoint> shape, Func <TPoint, bool> predicate) { return(new FunctionShape <TPoint>(p => shape.Contains(p) && predicate(p))); }
/// <summary> /// Creates a new shape with the same points as the given shape with X and Y swapped. /// </summary> /// <preliminary/> public static IImplicitShape <GridPoint2> SwapXY(this IImplicitShape <GridPoint2> shape) { return(new FunctionShape <GridPoint2>(p => shape.Contains(new GridPoint2(p.Y, p.X)))); }
public TranslationShape1(IImplicitShape <int> baseShape, int offset) { this.offset = offset; this.baseShape = baseShape; }
/// <summary> /// Creates a 3D Translate Shape. /// </summary> /// <param name="shape">Base shape to translate.</param> /// <param name="offset">Offset of the movement of the shape.</param> public static IImplicitShape <GridPoint3> Translate( this IImplicitShape <GridPoint3> shape, GridPoint3 offset) { return(new TranslationShape3(shape, offset)); }
public ProductShape1(IExplicitShape <int> shape1, IImplicitShape <int> shape2, int scaleFactor) { var translationShapes = shape1.Points.Select(point => shape2.Translate(point * scaleFactor)); unionShape = new UnionShape <int>(translationShapes); }
public static IImplicitShape <GridPoint3> Layer(this IImplicitShape <GridPoint2> shape, int layerCount) { return(new SimpleLayerShape(shape, layerCount)); }
public SimpleLayerShape(IImplicitShape <GridPoint2> baseShape, int layerCount) { this.baseShape = baseShape; this.layerCount = layerCount; }
public static IImplicitShape <GridPoint3> SwapToZYX(this IImplicitShape <GridPoint3> shape) { return(new FunctionShape <GridPoint3>(p => shape.Contains(new GridPoint3(p.Z, p.Y, p.X)))); }
/// <summary> /// Creates a 1D Product Shape using another shape and a scale factor. /// </summary> /// <param name="shape1">Base shape to be process.</param> /// <param name="shape2">Shape used to process the shape1.</param> /// <param name="scale">Scale factor apply to the shape2 before making the product operation.</param> /// <returns></returns> public static IImplicitShape <int> Product(this IExplicitShape <int> shape1, IImplicitShape <int> shape2, int scale) { return(new ProductShape1(shape1, shape2, scale)); }
public ExplicitShape3(IImplicitShape <GridPoint3> implicitShape, AbstractBounds <GridPoint3> storageBounds) { this.implicitShape = implicitShape; this.storageBounds = storageBounds; }