/// <summary> /// Returns the position of the nearest vertex. /// </summary> /// <returns> /// Grid 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 RectGrid grid, Vector3 point, CSystem system) { var gridPoint = grid.WorldToGrid(point); var roundedPoint = RoundVector3(gridPoint); return(system == CSystem.Grid ? roundedPoint : grid.GridToWorld(roundedPoint)); }
/// <summary> /// Returns the grid position of the nearest box. /// </summary> /// <returns> /// Grid position of the nearest box. /// </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 cell in the grid. Since cell lies /// between vertices all three values will always have +0.5 /// compared to vertex coordinates. /// </para> /// </remarks> /// <example> /// <code> /// GFRectGrid myGrid; /// Vector3 worldPoint; /// // something like (2.5, -1.5, 3.5) /// Vector3 box = myGrid.NearestBoxG(worldPoint); /// </code> /// </example> public static Vector3 NearestCell(this RectGrid grid, Vector3 point, CSystem system) { var shift = .5f * Vector3.one; var gridPoint = grid.WorldToGrid(point); var shifted = gridPoint - shift; var rounded = RoundVector3(shifted); var gridCell = rounded + shift; return(system == CSystem.Grid ? gridCell : grid.GridToWorld(gridCell)); }
/// <summary> /// Aligns a position vector onto the grid. /// </summary> /// <param name="grid"> /// The grid instance to extend. /// </param> /// <param name="vector"> /// The position in world-coordinates. /// </param> /// <param name="scale"> /// Used to determine whether to align to a cell or an edge, see /// remarks. /// </param> /// <returns> /// Position of the nearest face. /// </returns> /// <remarks> /// <para> /// The position will be interpreted to be the position of an /// object that has the size <c>scale</c>. If the scale in an odd /// multiple of the grid's spacing the position will be aligned to /// an edge, otherwise to a cell. /// </para> /// </remarks> public static Vector3 AlignVector3(this RectGrid grid, Vector3 vector, Vector3 scale) { const CoordinateSystem system = CoordinateSystem.Grid; var vertex = grid.NearestVertex(vector, system); var cell = grid.NearestCell(vector, system); var spacing = grid.Spacing; var aligned = new Vector3(); for (var i = 0; i < 3; ++i) { var fraction = Mathf.Max(scale[i] / spacing[i], 1f); var even = Mathf.RoundToInt(fraction) % 2 == 0; aligned[i] = even ? vertex[i] : cell[i]; } return(grid.GridToWorld(aligned)); }