示例#1
0
        /// <summary>
        ///   Returns the position of the nearest vertex.
        /// </summary>
        /// <returns>
        ///   Position of the nearest vertex.
        /// </returns>
        ///
        /// <param name="grid">
        ///   The rectangular grid instance.
        /// </param>
        /// <param name="point">
        ///   Point in world space.
        /// </param>
        /// <param name="system">
        ///   Coordinate system to use.
        /// </param>
        ///
        /// <remarks>
        ///   Returns the position of the nearest vertex from a given point in
        ///   either grid- or world space.
        /// </remarks>
        public static Vector3 NearestVertex(this HexGrid grid, Vector3 point, CoordinateSystem system)
        {
            // Vertices in the hex-grid are dual to faces in the triangular
            // tessellation of the grid. Convert the point to cubic coordinates
            var cubicPoint = grid.WorldToCubic(point);

            cubicPoint.x = Mathf.Floor(cubicPoint.x) + .5f;
            cubicPoint.y = Mathf.Floor(cubicPoint.y) + .5f;
            cubicPoint.z = Mathf.Floor(cubicPoint.z) + .5f;
            cubicPoint.w = Mathf.Round(cubicPoint.w);

            switch (system)
            {
            case CoordinateSystem.Cubic:
                return(cubicPoint);

            case CoordinateSystem.HerringboneUp:
                return(grid.CubicToHerringU(cubicPoint));

            case CoordinateSystem.HerringboneDown:
                return(grid.CubicToHerringD(cubicPoint));

            case CoordinateSystem.RhombicUp:
                return(grid.CubicToRhombic(cubicPoint));

            case CoordinateSystem.RhombicDown:
                return(grid.CubicToRhombicD(cubicPoint));

            case CoordinateSystem.World:
                return(grid.CubicToWorld(cubicPoint));
            }
            throw new System.ComponentModel.InvalidEnumArgumentException();
        }
示例#2
0
        /// <summary>
        ///   Returns the position of the nearest face.
        /// </summary>
        /// <returns>
        ///   Position of the nearest face.
        /// </returns>
        /// <param name="grid">
        ///   The rectangular grid instance.
        /// </param>
        /// <param name="point">
        ///   Point in world space.
        /// </param>
        /// <param name="system">
        ///   Coordinate system to use.
        /// </param>
        /// <remarks>
        ///   <para>
        ///     Returns the coordinates of a face on the grid closest to a
        ///     given point. Since the face is enclosed by four vertices, the
        ///     returned value is the point in between all four of the
        ///     vertices. You also need to specify on which plane the face
        ///     lies.
        ///   </para>
        /// </remarks>
        public static Vector3 NearestFace(
            this HexGrid grid, Vector3 point, CoordinateSystem system
            )
        {
            // Faces in the hex-grid are dual to vertices in the triangular
            // tessellation of the grid. Convert the point to cubic coordinates
            var cubic = grid.WorldToCubic(point);
            // We need the original cubic coordinates and the rounded ones, so
            // use a separate variable
            var rounded = new Vector4(
                Mathf.Round(cubic.x),
                Mathf.Round(cubic.y),
                Mathf.Round(cubic.z),
                Mathf.Round(cubic.w)
                );

            // Rounding all three coordinates does not guarantee that their sum
            // is zero. Therefore we will find the coordinate with the largest
            // change and compute its value from the other two instead of its
            // rounded value.
            var deltaX = Mathf.Abs(rounded.x - cubic.x);
            var deltaY = Mathf.Abs(rounded.y - cubic.y);
            var deltaZ = Mathf.Abs(rounded.z - cubic.z);

            if (deltaX > deltaY && deltaX > deltaZ)
            {
                rounded.x = -rounded.y - rounded.z;
            }
            else if (deltaY > deltaZ)
            {
                rounded.y = -rounded.x - rounded.z;
            }
            else
            {
                rounded.z = -rounded.x - rounded.y;
            }

            switch (system)
            {
            case CoordinateSystem.Cubic:
                return(rounded);

            case CoordinateSystem.HerringboneUp:
                return(grid.CubicToHerringU(rounded));

            case CoordinateSystem.HerringboneDown:
                return(grid.CubicToHerringD(rounded));

            case CoordinateSystem.RhombicUp:
                return(grid.CubicToRhombic(rounded));

            case CoordinateSystem.RhombicDown:
                return(grid.CubicToRhombicD(rounded));

            case CoordinateSystem.World:
                return(grid.CubicToWorld(rounded));
            }
            throw new System.ComponentModel.InvalidEnumArgumentException();
        }