/// <summary> /// Sets internal fields and creates board /// </summary> /// <param name="width">Board width</param> /// <param name="height">Board height</param> /// <param name="side">Hexagon side length</param> /// <param name="orientation">Orientation of the hexagons</param> /// <param name="xOffset">X coordinate offset</param> /// <param name="yOffset">Y coordinate offset</param> private void Initialize(int width, int height, int side, HexOrientation orientation, int xOffset, int yOffset) { this.width = width; this.height = height; this.xOffset = xOffset; this.yOffset = yOffset; this.side = side; this.orientation = orientation; hexes = new Hex[height, width]; //opposite of what we'd expect this.mapState = new HexagonalMapState(width, height); float h = CalcUtil.CalculateH(side); // short side float r = CalcUtil.CalculateR(side); // long side // // Calculate pixel info..remove? // because of staggering, need to add an extra r/h float hexWidth = 0; float hexHeight = 0; switch (orientation) { case HexOrientation.Flat: hexWidth = side + h; hexHeight = r + r; this.pixelWidth = (width * hexWidth) + h; this.pixelHeight = (height * hexHeight) + r; break; case HexOrientation.Pointy: hexWidth = r + r; hexHeight = side + h; this.pixelWidth = (width * hexWidth) + r; this.pixelHeight = (height * hexHeight) + h; break; default: break; } bool inTopRow = false; bool inBottomRow = false; bool inLeftColumn = false; bool inRightColumn = false; bool isTopLeft = false; bool isTopRight = false; bool isBotomLeft = false; bool isBottomRight = false; // i = y coordinate (rows), j = x coordinate (columns) of the hex tiles 2D plane for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { // Set position booleans #region Position Booleans if (i == 0) { inTopRow = true; } else { inTopRow = false; } if (i == height - 1) { inBottomRow = true; } else { inBottomRow = false; } if (j == 0) { inLeftColumn = true; } else { inLeftColumn = false; } if (j == width - 1) { inRightColumn = true; } else { inRightColumn = false; } if (inTopRow && inLeftColumn) { isTopLeft = true; } else { isTopLeft = false; } if (inTopRow && inRightColumn) { isTopRight = true; } else { isTopRight = false; } if (inBottomRow && inLeftColumn) { isBotomLeft = true; } else { isBotomLeft = false; } if (inBottomRow && inRightColumn) { isBottomRight = true; } else { isBottomRight = false; } #endregion // // Calculate Hex positions // if (isTopLeft) { //First hex switch (orientation) { case HexOrientation.Flat: hexes[0, 0] = new Hex(0 + h + xOffset, 0 + yOffset, side, orientation); break; case HexOrientation.Pointy: hexes[0, 0] = new Hex(0 + r + xOffset, 0 + yOffset, side, orientation); break; default: break; } } else { switch (orientation) { case HexOrientation.Flat: if (inLeftColumn) { // Calculate from hex above hexes[i, j] = new Hex(hexes[i - 1, j].Points[(int)FlatVertice.BottomLeft], side, orientation); } else { // Calculate from Hex to the left and need to stagger the columns if (j % 2 == 0) { // Calculate from Hex to left's Upper Right Vertice plus h and R offset float x = hexes[i, j - 1].Points[(int)FlatVertice.UpperRight].X; float y = hexes[i, j - 1].Points[(int)FlatVertice.UpperRight].Y; x += h; y -= r; hexes[i, j] = new Hex(x, y, side, orientation); } else { // Calculate from Hex to left's Middle Right Vertice hexes[i, j] = new Hex(hexes[i, j - 1].Points[(int)FlatVertice.MiddleRight], side, orientation); } } break; case HexOrientation.Pointy: if (inLeftColumn) { // Calculate from hex above and need to stagger the rows if (i % 2 == 0) { hexes[i, j] = new Hex(hexes[i - 1, j].Points[(int)PointyVertice.BottomLeft], side, orientation); } else { hexes[i, j] = new Hex(hexes[i - 1, j].Points[(int)PointyVertice.BottomRight], side, orientation); } } else { // Calculate from Hex to the left float x = hexes[i, j - 1].Points[(int)PointyVertice.UpperRight].X; float y = hexes[i, j - 1].Points[(int)PointyVertice.UpperRight].Y; x += r; y -= h; hexes[i, j] = new Hex(x, y, side, orientation); } break; default: break; } } } } mapStateMgr = new MapStateManager(this); }
/// <summary> /// Calculates the vertices of the hex based on orientation. Assumes that points[0] contains a value. /// </summary> private void CalculateVertices() { // // h = short length (outside) // r = long length (outside) // side = length of a side of the hexagon, all 6 are equal length // // h = sin (30 degrees) x side // r = cos (30 degrees) x side // // h // --- // ---- |r // / \ | // / \ | // \ / // \____/ // // Flat orientation (scale is off) // // /\ // / \ // / \ // | | // | | // | | // \ / // \ / // \/ // Pointy orientation (scale is off) h = CalcUtil.CalculateH(side); r = CalcUtil.CalculateR(side); int x_low, x_high, y_low, y_high = 0; switch (orientation) { case HexOrientation.Flat: // x,y coordinates are top left point points = new System.Drawing.PointF[6]; points[0] = new PointF(x, y); points[1] = new PointF(x + side, y); points[2] = new PointF(x + side + h, y + r); points[3] = new PointF(x + side, y + r + r); points[4] = new PointF(x, y + r + r); points[5] = new PointF(x - h, y + r); x_low = (int)System.Math.Ceiling(x - h); x_high = (int)System.Math.Floor(x + side + h); y_low = (int)System.Math.Ceiling(y); y_high = (int)System.Math.Floor(y + r + r); break; case HexOrientation.Pointy: //x,y coordinates are top center point points = new System.Drawing.PointF[6]; points[0] = new PointF(x, y); points[1] = new PointF(x + r, y + h); points[2] = new PointF(x + r, y + side + h); points[3] = new PointF(x, y + side + h + h); points[4] = new PointF(x - r, y + side + h); points[5] = new PointF(x - r, y + h); x_low = (int)System.Math.Ceiling(x - r); x_high = (int)System.Math.Floor(x + r); y_low = (int)System.Math.Ceiling(y); y_high = (int)System.Math.Floor(y + side + h); break; default: throw new Exception("No HexOrientation defined for Hex object."); } float cX = 0; float cY = 0; for (int i = 0; i < 6; i++) { cX += points[i].X; cY += points[i].Y; } centroid = new PointF(cX / 6, cY / 6); inPointSet = new List <System.Drawing.PointF> (); for (int iX = x_low; iX <= x_high; iX++) { for (int iY = y_low; iY <= y_high; iY++) { PointF p = new PointF(iX, iY); if (CalcUtil.InsidePolygon(points, 6, p)) { inPointSet.Add(p); } } } }