CodePlexProject Hosting for Open Source Software

This elegant algorithm is from
James McNeill. I cannot say much to improve on his explanation, so I will only note that a few details specific to this implementation have been filled in.

From the**Grid Coordinates** section of **HexgridPanel.cs**:

From the

/// Mathemagically (left as exercise for the reader) our 'picking' matrices are /// these, assuming: /// - origin at upper-left corner of hex (0,0); /// - 'straight' hex-axis vertically down; and /// - 'oblique' hex-axis up-and-to-right (at 120 degrees from 'straight'). private Matrix matrixX { get { return new Matrix((3.0F/2.0F)/GridSize.Width, (3.0F/2.0F)/GridSize.Width, 1.0F/GridSize.Height, -1.0F/GridSize.Height, -0.5F,-0.5F); } } private Matrix matrixY { get { return new Matrix( 0.0F, (3.0F/2.0F)/GridSize.Width, 2.0F/GridSize.Height, 1.0F/GridSize.Height, -0.5F,-0.5F); } } /// <summary>Canonical coordinates for a selected hex for a given AutoScroll position.</summary> /// <param name="point">Screen point specifying hex to be identified.</param> /// <param name="autoScroll">AutoScrollPosition for game-display Panel.</param> /// <returns>Canonical coordinates for a hex specified by a screen point.</returns> /// <see cref="HexGridAlgorithm.mht"/> protected ICoordsCanon GetHexCoords(Point point, Size autoScroll) { if( Host == null ) return Coords.EmptyCanon; autoScroll = TransposeSize(autoScroll); /// Adjust for origin not as assumed by GetCoordinate(). var grid = new Size((int)(GridSize.Width*2F/3F), (int)GridSize.Height); var margin = new Size((int)(MapMargin.Width *MapScale), (int)(MapMargin.Height*MapScale)); point -= autoScroll + margin + grid; return Coords.NewCanonCoords( GetCoordinate(matrixX, point), GetCoordinate(matrixY, point) ); } Size TransposeSize(Size size) { return IsTransposed ? new Size (size.Height, size.Width) : size; } /// <summary>Calculates a (canonical X or Y) grid-coordinate for a point, from the supplied 'picking' matrix.</summary> /// <param name="matrix">The 'picking' matrix</param> /// <param name="point">The screen point identifying the hex to be 'picked'.</param> /// <returns>A (canonical X or Y) grid coordinate of the 'picked' hex.</returns> private static int GetCoordinate (Matrix matrix, Point point){ var pts = new Point[] {point}; matrix.TransformPoints(pts); return (int) Math.Floor( (pts[0].X + pts[0].Y + 2F) / 3F ); }

Last edited Feb 23, 2013 at 10:30 PM by pgeerkens, version 5