public FlatHexShapeInfo <TCell> Hexagon(int side) { var storageSize = 2 * side - 1; var storageBottomLeft = new FlatHexPoint(1 - side, 1 - side); return(Shape(storageSize, storageSize, x => IsInsideHex(x, side), storageBottomLeft)); }
/// <summary> /// Gives a new point that represents the /// first point divided by the second point /// component-wise. The division is integer /// division. /// /// Since version 1.6 (Rect) /// Since version 1.7 (other) /// </summary> public FlatHexPoint Div(FlatHexPoint otherPoint) { var x = GLMathf.FloorDiv(X, otherPoint.X); var y = GLMathf.FloorDiv(Y, otherPoint.Y); return(new FlatHexPoint(x, y)); }
/// <summary> /// Gives a new point that represents the /// first point multiplied by the second point /// component-wise. /// /// Since version 1.6 (Rect) /// Since version 1.7 (other) /// </summary> public FlatHexPoint Mul(FlatHexPoint otherPoint) { var x = X * otherPoint.X; var y = Y * otherPoint.Y; return(new FlatHexPoint(x, y)); }
public IEnumerable <FlatHexPoint> GetSpiralIterator(FlatHexPoint origin, int ringCount) { var hexPoint = origin; yield return(hexPoint); for (var k = 1; k < ringCount; k++) { hexPoint = new FlatHexPoint(0, 0); hexPoint = hexPoint + SpiralIteratorDirections[4] * (k); for (var i = 0; i < 6; i++) { for (var j = 0; j < k; j++) { if (Contains(hexPoint)) { yield return(hexPoint); } hexPoint = hexPoint + SpiralIteratorDirections[i]; } } } }
/** * @since 1.7 */ public IEnumerable <FlatHexPoint> GetSpiralIterator(int N) { var hexPoint = new FlatHexPoint(0, 0); yield return(hexPoint); for (var k = 0; k < N; k++) { hexPoint = new FlatHexPoint(0, 0); hexPoint = hexPoint + HexDirections[4] * (k); for (var i = 0; i < 6; i++) { for (var j = 0; j < k; j++) { if (Contains(hexPoint)) { yield return(hexPoint); } hexPoint = hexPoint + HexDirections[i]; } } } }
public FlatHexShapeInfo <TCell> ThinRectangle(int width, int height) { var storageWidth = width; var storageHeight = height + GLMathf.FloorDiv(width - 1, 2); var storageBottomLeft = new FlatHexPoint(0, -GLMathf.FloorDiv(width - 1, 2)); return(Shape(storageWidth, storageHeight, x => IsInsideThinRectangle(x, width, height), storageBottomLeft)); }
private static bool IsInsideXYParallelogram(FlatHexPoint point, int width, int height) { return (point.X >= 0 && point.X < width && point.Y >= 0 && point.Y < height); }
public static bool DefaultContains(FlatHexPoint point, int width, int height) { ArrayPoint storagePoint = ArrayPointFromGridPoint(point); return (storagePoint.X >= 0 && storagePoint.X < width && storagePoint.Y >= 0 && storagePoint.Y < height); }
/** * Rotates a shape 180 degrees around the edge shared by the two given points. * * The two points must be neighbors. */ public static IEnumerable <FlatHexPoint> Rotate180About( IEnumerable <FlatHexPoint> shape, FlatHexPoint p1, FlatHexPoint p2) { var translation = p1.Translate(p2); var correction = translation.Subtract(translation.Rotate180()).ScaleDown(2); return(TransformShape <FlatHexPoint>(shape, point => point.Rotate180().Translate(correction)).ToList()); }
private static bool IsInsideFatRectangle(FlatHexPoint point, int width, int height) { int startY = -(GLMathf.FloorDiv(point.X, 2)); return (point.Y >= startY - GLMathf.FloorMod(point.X, 2) && point.Y < startY + height && point.X >= 0 && point.X < width); }
private bool IsInsideThinRectangle(FlatHexPoint point, int width, int height) { int startY = -(GLMathf.FloorDiv(point.X, 2)); return (point.Y >= startY && point.Y + GLMathf.FloorMod(point.X, 2) < startY + height && point.X >= 0 && point.X < width); }
/** * Makes an edge grid for this grid. */ public IGrid <TNewCell, FlatRhombPoint> MakeEdgeGrid <TNewCell>() { var edgeOffset = GridOrigin; var edges = this.SelectMany(x => x.GetEdges()); var storage = FlatRhombGrid <TNewCell> .CalculateStorage(edges); var offset = new FlatHexPoint(-2, 0); return(new FlatRhombGrid <TNewCell>(storage.dimensions.X + 4, storage.dimensions.Y + 4, x => IsInsideEdgeGrid(x + offset), edgeOffset.GetEdgeAnchor().BasePoint + offset)); }
/// <summary> /// Makes an edge grid for this grid. /// </summary> public IGrid <TNewCell, FlatRhombPoint> MakeEdgeGrid <TNewCell>() { var edges = this.SelectMany(x => x.GetEdges()); var storage = FlatRhombGrid <TNewCell> .CalculateStorage(edges); var offset = FlatRhombGrid <TNewCell> .GridPointFromArrayPoint(storage.offset); var oddPoint = new FlatHexPoint( GLMathf.FloorMod(offset.X, 2), GLMathf.FloorMod(offset.Y, 2)); var evenPoint = offset.Subtract(oddPoint); return(new FlatRhombGrid <TNewCell>(storage.dimensions.X + 2, storage.dimensions.Y + 2, IsInsideEdgeGrid, evenPoint)); }
/** * Rotates a shape 120 degrees around the vertice shared by the three given points. * * The three points must form a close triangle (they must share a vertex). */ public static IEnumerable <FlatHexPoint> Rotate120About( IEnumerable <FlatHexPoint> shape, FlatHexPoint p1, FlatHexPoint p2, FlatHexPoint p3) { /* * If t = (p1 + p2 + p3)/3, then the result is p => (p - t).Rotate120() + t. * * This can be rewritten p => p.Rotate120() - t.Rotate120() + t * = p.Rotate120() (T - T.Rotate120())/3, * where T = p1 + p2 + p3. * * This is what this method calculates. This is done so that all coordinates in * intermediatary calculations stay integers. */ var translation = p1.Translate(p2.Translate(p3)); var correction = translation.Subtract(translation.Rotate120()).ScaleDown(3); return(TransformShape(shape, point => point.Rotate120().Translate(correction)).ToList()); }
/// <summary> /// Gives a coloring of the grid such that /// if a point p has color k, then all points /// p + m[ux, 0] + n[vx, vy] have the same color /// for any integers a and b. /// /// More information anout grid colorings: /// http://gamelogic.co.za/2013/12/18/what-are-grid-colorings/ /// /// Since version 1.7 /// </summary> public int __GetColor__ReferenceImplementation(int ux, int vx, int vy) { var u = new FlatHexPoint(ux, 0); var v = new FlatHexPoint(vx, vy); int colorCount = u.PerpDot(v); float a = PerpDot(v) / (float)colorCount; float b = -PerpDot(u) / (float)colorCount; int m = Mathf.FloorToInt(a); int n = Mathf.FloorToInt(b); int baseVectorX = m * u.X + n * v.X; int baseVectorY = n * u.Y + n * v.Y; int offsetX = GLMathf.FloorMod(X - baseVectorX, ux); int offsetY = Y - baseVectorY; int colorIndex = Mathf.FloorToInt(offsetX + offsetY * ux); return(colorIndex); }
/** * Construct a new grid whose cells are determined by the given test function. * * The function should only return true for points within the bounds of the rectangle when * the given transforms are applied to them. * * Normally, the static factory methods or shape building methods should be used to create grids. * These constructors are provided for advanced usage. * * @link_constructing_grids */ public FlatHexGrid(int width, int height, Func <FlatHexPoint, bool> isInside, FlatHexPoint offset) : this(width, height, isInside, x => x.MoveBy(offset), x => x.MoveBackBy(offset), FlatHexPoint.MainDirections) { }
protected override PointyTriGrid <TCell> MakeShape(int x, int y, Func <PointyTriPoint, bool> isInside, FlatHexPoint offset) { return(new PointyTriGrid <TCell>(x, y, isInside, offset)); }
public PointyTriShapeInfo<TCell> ParallelogramXZ(int width, int height) { var storageBottomLeft = new FlatHexPoint(0, 1-width -height); return Shape(width, width + height, x => IsInsideParallelogramXZ(x, width, height), storageBottomLeft); }
public InspectableVectorPoint(FlatHexPoint point) { x = point.X; y = point.Y; }
public PointyTriGrid(int width, int height, Func <PointyTriPoint, bool> isInside, FlatHexPoint offset) : this(width, height, isInside, x => x.Translate(offset), x => x.Translate(offset.Negate())) { }
private static bool IsInsideHex(FlatHexPoint point, int side) { return(point.Magnitude() < side); }
public static ArrayPoint ArrayPointFromGridPoint(FlatHexPoint point) { return(FlatHexGrid <TCell> .ArrayPointFromGridPoint(point)); }
protected override FlatRhombPoint MakePoint(FlatHexPoint basePoint, int index) { return(new FlatRhombPoint(basePoint.X, basePoint.Y, index)); }
private static bool IsInsideLeftTriangle(FlatHexPoint point, int side) { return((point.Y <= side - 1) && (point.X <= 0) && (point.Y + point.X >= 0)); }
/** * Use this function to create shapes to ensure they fit into memory. * * The test function can test shapes anywhere in space. If you specify the bottom corner * (in terms of the storage rectangle), the shape is automatically translated in memory * to fit, assuming memory width and height is big enough. * * Strategy for implementing new shapes: * - First, determine the test function. * - Next, draw a storage rectangle that contains the shape. * - Determine the storgae rectangle width and height. * - Finally, determine the grid-space coordinate of the left bottom corner of the storage rectangle. * * Then define your function as follows: * * \code{cs} * public FlatRhombShapeInfo<TCell> MyShape() * { * Shape(stargeRectangleWidth, storageRectangleHeight, isInsideMyShape, storageRectangleBottomleft); * } * \endcode * * \param width The widh of the storage rectangle * \param height The height of the storage rectangle * \param isInside A function that returns true if a passed point lies inside the shape being defined * \param bottomLeftCorner The grid-space coordinate of the bottom left corner of the storage rect. * */ public FlatRhombShapeInfo <TCell> Shape(int width, int height, Func <FlatRhombPoint, bool> isInside, FlatHexPoint bottomLeftCorner) { var shapeInfo = MakeShapeStorageInfo <FlatRhombPoint>(width, height, x => isInside(x + bottomLeftCorner)); return(new FlatRhombShapeInfo <TCell>(shapeInfo).Translate(bottomLeftCorner)); }
protected override ArrayPoint ArrayPointFromGridPoint(FlatHexPoint point) { return(FlatRhombGrid <TCell> .ArrayPointFromGridPoint(point)); }
protected override FlatRhombGrid <TCell> MakeShape(int x, int y, Func <FlatRhombPoint, bool> isInside, FlatHexPoint offset) { return(new FlatRhombGrid <TCell>(x, y, isInside, offset)); }
public FlatHexShapeInfo <TCell> Hexagon(FlatHexPoint centre, int side) { return(Hexagon(side).Translate(centre)); }
/** * Whether this point is in the hexagon with the given radius * and given center. * * A single point is considered a hexagon with zero radius. * * @sa http://devmag.org.za/2013/08/31/geometry-with-hex-coordinates/ * * @since 1.3 */ public bool IsInsideHexagon(FlatHexPoint center, int radius) { return((this - center).Magnitude() <= radius); }
public FlatHexShapeInfo <TCell> LeftTriangle(int side) { var storageBottomLeft = new FlatHexPoint(1 - side, 0); return(Shape(side, side, x => IsInsideLeftTriangle(x, side), storageBottomLeft)); }