/* This error function was taken from http://www.volume-gfx.com/ * However, it has a major flaw when points sampled have a very similar value * The only way to fix it is to sample from more points, have a maximum container size, or sample random points * This can still lead to the error falsely being calculated as negligible though for certain functions, such as noise functions * The only way (to my knowledge) is to sample points on a uniform grid as the original DMC paper suggests * It can be done efficiently though, like sampling the corners and mid points initially, then the in-between points, etc * And breaking early if the error exceeds the threshold */ public float GetError(float threshold) { float error = 0; float[] values = new float[4]; Vector2[] positions = new Vector2[5]; Vector2[] middle_positions = { new Vector2(0.5f, 0.0f), new Vector2(0.0f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(1.0f, 0.5f), new Vector2(0.5f, 1.0f) }; for (int i = 0; i < 5; i++) { positions[i] = position + size * middle_positions[i]; if (i < 4) { values[i] = Sampler.Sample(position + size * new Vector2(i / 2, i % 2)); } } for (int i = 0; i < 5; i++) { float center_value = Sampler.Sample(positions[i]); Vector2 gradient = Sampler.GetGradient(positions[i]); float interpolated = Interpolate(values[0], values[1], values[2], values[3], middle_positions[i]); float mag = Math.Max(1.0f, gradient.Length()); error += Math.Abs(center_value - interpolated) / mag; if (error >= threshold) { break; } } return(error); }