Пример #1
0
        //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&lt;ColourCell, PointyHexPoint, PointyHexNeighborIndex&gt;(
        ///             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&lt;ColourCell, PointyHexPoint, PointyHexNeighborIndex&gt;(
        ///         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);
        }
Пример #2
0
            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);
            }
Пример #3
0
 /// <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));
 }
Пример #4
0
        /// <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));
        }
Пример #5
0
        /// <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));
        }
Пример #6
0
            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);
            }
Пример #7
0
        /// <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);
        }
Пример #8
0
        /// <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);
                        }
                    }
                }
            }
        }
Пример #9
0
 public static IImplicitShape <TPoint> ReverseSelect <TPoint>(
     this IImplicitShape <TPoint> shape,
     Func <TPoint, TPoint> projection)
 {
     return(Func <TPoint>(p => shape.Contains(projection(p))));
 }
Пример #10
0
 public static IExplicitShape <int> ToExplicit(this IImplicitShape <int> shape, AbstractBounds <int> bounds)
 {
     return(new ExplicitShape1(shape, bounds));
 }
Пример #11
0
 /// <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));
 }
Пример #12
0
 public TranslationShape3(IImplicitShape <GridPoint3> baseShape, GridPoint3 offset)
 {
     this.offset    = offset;
     this.baseShape = baseShape;
 }
Пример #13
0
 /// <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)));
 }
Пример #14
0
 public ExplicitShape1(IImplicitShape <int> implicitShape, AbstractBounds <int> storageBounds)
 {
     this.implicitShape = implicitShape;
     this.storageBounds = storageBounds;
 }
Пример #15
0
 public static IExplicitShape <GridPoint3> ToExplicit(this IImplicitShape <GridPoint3> shape, AbstractBounds <GridPoint3> bounds)
 {
     return(new ExplicitShape3(shape, bounds));
 }
Пример #16
0
 /// <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)));
 }
Пример #17
0
 /// <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))));
 }
Пример #18
0
 /// <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));
 }
Пример #19
0
 /// <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)));
 }
Пример #20
0
 /// <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))));
 }
Пример #21
0
 public TranslationShape1(IImplicitShape <int> baseShape, int offset)
 {
     this.offset    = offset;
     this.baseShape = baseShape;
 }
Пример #22
0
 /// <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));
 }
Пример #23
0
            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);
            }
Пример #24
0
 public static IImplicitShape <GridPoint3> Layer(this IImplicitShape <GridPoint2> shape, int layerCount)
 {
     return(new SimpleLayerShape(shape, layerCount));
 }
Пример #25
0
 public SimpleLayerShape(IImplicitShape <GridPoint2> baseShape, int layerCount)
 {
     this.baseShape  = baseShape;
     this.layerCount = layerCount;
 }
Пример #26
0
 public static IImplicitShape <GridPoint3> SwapToZYX(this IImplicitShape <GridPoint3> shape)
 {
     return(new FunctionShape <GridPoint3>(p => shape.Contains(new GridPoint3(p.Z, p.Y, p.X))));
 }
Пример #27
0
 /// <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));
 }
Пример #28
0
 public ExplicitShape3(IImplicitShape <GridPoint3> implicitShape, AbstractBounds <GridPoint3> storageBounds)
 {
     this.implicitShape = implicitShape;
     this.storageBounds = storageBounds;
 }