public override double[,] NoiseMapNotAsync(int iterations, params int[] vals) { int len = vals.Length; int yLen = (len < 2 || vals[1] == 0) ? 1 : vals[1]; int xLen = vals[0]; var buffer = new double[yLen, xLen]; Setup(len); SimplexThread st = new SimplexThread(len); for (int y = 0; y < yLen; ++y) { if (len > 1) { st.values[1] = y; } for (int x = 0; x < xLen; ++x) { st.values[0] = x; buffer[y, x] = FractalFBM(iterations, len, st, st.values); } } return(buffer); }
private double FractalRigid(int iterations, int dimensions, SimplexThread st, params double[] vals) { double maxAmp = 0; double amp = 1; double freq = Scale; double noise = 0; for (int i = 0; i < iterations; ++i) { for (int j = 0; j < vals.Length; ++j) { st.nVals[j] = vals[j] * freq; } noise += (1 - Math.Abs(Noise(dimensions, st, st.nVals))) * amp; maxAmp += amp; amp *= Persistence; freq *= 2; } return(noise / maxAmp); }
public override async Task <double[, ]> NoiseMap(int iterations, FractalType type, params int[] vals) { int len = vals.Length; int yLen = (len < 2 || vals[1] == 0) ? 1 : vals[1]; int xLen = vals[0]; Task[] tasks = new Task[yLen]; var buffer = new double[yLen, xLen]; Setup(len); if (len == 3) { tasks = new Task[yLen / 8]; for (int y = 0, index = 0; y < yLen; y += 8, index++) { int yCopy = y; tasks[index] = Task.Run(() => { Vector <float> yin = new Vector <float>(new float[] { yCopy, yCopy + 1, yCopy + 2, yCopy + 3, yCopy + 4, yCopy + 5, yCopy + 6, yCopy + 7 }); for (int x = 0; x < xLen; ++x) { Vector <float> result = FractalFBM(iterations, new Vector <float>(x), yin, new Vector <float>(vals[2])); buffer[yCopy, x] = result[0]; buffer[yCopy + 1, x] = result[1]; buffer[yCopy + 2, x] = result[2]; buffer[yCopy + 3, x] = result[3]; buffer[yCopy + 4, x] = result[4]; buffer[yCopy + 5, x] = result[5]; buffer[yCopy + 6, x] = result[6]; buffer[yCopy + 7, x] = result[7]; } }); } } else { for (int y = 0; y < yLen; ++y) { int yCopy = y; tasks[y] = Task.Run(() => { SimplexThread st = new SimplexThread(len); if (len > 1) { st.values[1] = yCopy; } for (int x = 0; x < xLen; ++x) { st.values[0] = x; switch (type) { case FractalType.FBM: buffer[yCopy, x] = FractalFBM(iterations, len, st, st.values); break; case FractalType.Billow: buffer[yCopy, x] = FractalBillow(iterations, len, st, st.values); break; case FractalType.Rigid: buffer[yCopy, x] = FractalRigid(iterations, len, st, st.values); break; } } }); } } await Task.WhenAll(tasks).ConfigureAwait(false); return(buffer); }
private double Noise(int dimensions, SimplexThread st, params double[] vals) { double s = 0; foreach (double v in vals) { s += v; } s *= F; double t = 0; for (int i = 0; i < dimensions; ++i) { st.vvals[i] = 0; st.xvals[i] = 0; st.ranks[i] = 0; st.ivvals[i] = (int)(vals[i] + s); t += st.ivvals[i]; } t *= G; for (int i = dimensions - 1; i >= 0; --i) { st.xvals[i] = vals[i] - (st.ivvals[i] - t); for (int j = i + 1; j < dimensions; ++j) { if (st.xvals[i] > st.xvals[j]) { st.ranks[i]++; } else { st.ranks[j]++; } } } double n = 0; int temp = dimensions - 1; for (int i = 0; i < dimensions + 1; ++i) { t = 0.6; uint hash = Seed; for (int j = 0; j < dimensions; ++j) { int ival = 0; if (i > 0) { ival = (i == dimensions ? 1 : (st.ranks[j] >= temp ? 1 : 0)); } double vval = st.vvals[j] = i == 0 ? st.xvals[j] : st.xvals[j] - ival + i * G; t -= vval * vval; hash ^= (uint)(primeList[j % 4] * (st.ivvals[j] + ival)); } if (i > 0) { temp--; } if (t >= 0) { hash = hash * hash * hash * 60493; hash = (hash >> 13) ^ hash; hash &= 15; double result = 0.0; int current = 1; for (int j = dimensions - 1; j > -1; --j) { result += (hash & current) == 0 ? -st.vvals[j] : st.vvals[j]; current *= 2; } n += (t * t) * t * t * result; } } return(32.0 * n); }