public static Vector2 IntegrateRK4(Vector2 position, float step, UniformGrid2DVector2 vectorField) { Vector2 v1 = vectorField.Interpolate(position); Vector2 v2 = vectorField.Interpolate(position + 0.5f * step * v1); Vector2 v3 = vectorField.Interpolate(position + 0.5f * step * v2); Vector2 v4 = vectorField.Interpolate(position + step * v3); float inverse6 = 1.0f / 6.0f; float inverse3 = 1.0f / 3.0f; return(position + step * (inverse6 * v1 + inverse3 * v2 + inverse3 * v3 + inverse6 * v4)); }
private void CalculateGradient() { // For each grid point in the terrain grid, do convolution using Sobel operator. // Values for points that are out of range are treated as the center value. // Initialize grid as a uniform grid of 2D vectors with the same size and number of points as the terrain grid. gradientGrid = new UniformGrid2DVector2(terrainGrid.minPoint, terrainGrid.maxPoint, terrainGrid.numPointsX, terrainGrid.numPointsY); for (int j = 0; j < terrainGrid.numPointsY; ++j) { for (int i = 0; i < terrainGrid.numPointsX; ++i) { // Extract the scalars. float[,] scalars = new float[3, 3]; for (int b = 0; b < 3; ++b) { // Indicates whether to subtract 1, add 0 or add 1 to the j index. int jTerm = b - 1; for (int a = 0; a < 3; ++a) { // Indicates whether to subtract 1, add 0 or add 1 to the i index. int iTerm = a - 1; // Try to access the scalar at the index. If at an edge of the grid, exception is thrown and scalar set to NaN. try { scalars[a, b] = terrainGrid[i + iTerm, j + jTerm]; } catch (IndexOutOfRangeException) { scalars[a, b] = float.NaN; } } } // Correct the NaN scalars. CorrectScalars(scalars); // The x-kernel takes the form: // 1, 0, -1 // 2, 0, -2 // 1, 0, -1 // The z-kernel takes the form: // -1, -2, -1 // 0, 0, 0 // 1, 2, 1 float partialX = scalars[0, 0] - scalars[2, 0] + 2 * scalars[0, 1] - 2 * scalars[2, 1] + scalars[0, 2] - scalars[2, 2]; float partialZ = scalars[0, 0] + 2 * scalars[1, 0] + scalars[2, 0] - scalars[0, 2] - 2 * scalars[1, 2] - scalars[2, 2]; gradientGrid[i, j] = new Vector2(partialX, partialZ); } } }
public static Vector3 IntegrateRK4(Vector3 position, float step, UniformGrid2DVector2 vectorField) { return(HV2ToV3(IntegrateRK4(V3ToHV2(position), step, vectorField))); }