001package squidpony.squidmath; 002 003/** 004 * A container class for various interfaces and implementing classes that affect continuous noise, such as that produced 005 * by {@link WhirlingNoise} or {@link SeededNoise}, as well as static utility methods used throughout noise code. 006 * <br> 007 * Created by Tommy Ettinger on 3/17/2017. 008 */ 009public class Noise { 010 public static final SeededNoise alternate = new SeededNoise(0xFEEDCAFE); 011 /** 012 * Like {@link Math#floor}, but returns a long. 013 * Doesn't consider weird doubles like INFINITY and NaN. 014 * 015 * @param t the double to find the floor for 016 * @return the floor of t, as a long 017 */ 018 public static long longFloor(double t) { 019 return t >= 0.0 ? (long) t : (long) t - 1L; 020 } 021 /** 022 * Like {@link Math#floor(double)}, but takes a float and returns a long. 023 * Doesn't consider weird floats like INFINITY and NaN. 024 * 025 * @param t the double to find the floor for 026 * @return the floor of t, as a long 027 */ 028 public static long longFloor(float t) { 029 return t >= 0f ? (long) t : (long) t - 1L; 030 } 031 /** 032 * Like {@link Math#floor(double)} , but returns an int. 033 * Doesn't consider weird doubles like INFINITY and NaN. 034 * @param t the float to find the floor for 035 * @return the floor of t, as an int 036 */ 037 public static int fastFloor(double t) { 038 return t >= 0.0 ? (int) t : (int) t - 1; 039 } 040 /** 041 * Like {@link Math#floor(double)}, but takes a float and returns an int. 042 * Doesn't consider weird floats like INFINITY and NaN. 043 * @param t the float to find the floor for 044 * @return the floor of t, as an int 045 */ 046 public static int fastFloor(float t) { 047 return t >= 0f ? (int) t : (int) t - 1; 048 } 049 /** 050 * Like {@link Math#ceil(double)}, but returns an int. 051 * Doesn't consider weird doubles like INFINITY and NaN. 052 * @param t the float to find the ceiling for 053 * @return the ceiling of t, as an int 054 */ 055 public static int fastCeil(double t) { 056 return t >= 0.0 ? -(int) -t + 1: -(int)-t; 057 } 058 /** 059 * Like {@link Math#ceil(double)}, but takes a float and returns an int. 060 * Doesn't consider weird floats like INFINITY and NaN. 061 * @param t the float to find the ceiling for 062 * @return the ceiling of t, as an int 063 */ 064 public static int fastCeil(float t) { 065 return t >= 0f ? -(int) -t + 1: -(int)-t; 066 } 067 068 /** 069 * Cubic-interpolates between start and end (valid doubles), with a between 0 (yields start) and 1 (yields end). 070 * Will smoothly transition toward start or end as a approaches 0 or 1, respectively. Somewhat faster than 071 * quintic interpolation ({@link #querp(double, double, double)}), but slower (and smoother) than 072 * {@link #lerp(double, double, double)}. 073 * @param start a valid double 074 * @param end a valid double 075 * @param a a double between 0 and 1 inclusive 076 * @return a double between start and end inclusive 077 */ 078 public static double cerp(final double start, final double end, double a) { 079 return (1.0 - (a *= a * (3.0 - 2.0 * a))) * start + a * end; 080 } 081 082 /** 083 * Cubic-interpolates between start and end (valid floats), with a between 0 (yields start) and 1 (yields end). 084 * Will smoothly transition toward start or end as a approaches 0 or 1, respectively. Somewhat faster than 085 * quintic interpolation ({@link #querp(float, float, float)}), but slower (and smoother) than 086 * {@link #lerp(float, float, float)}. 087 * @param start a valid float 088 * @param end a valid float 089 * @param a a float between 0 and 1 inclusive 090 * @return a float between start and end inclusive 091 */ 092 public static float cerp(final float start, final float end, float a) { 093 return (1f - (a *= a * (3f - 2f * a))) * start + a * end; 094 } 095 /* 096 * Quintic-interpolates between start and end (valid doubles), with a between 0 (yields start) and 1 (yields end). 097 * Will smoothly transition toward start or end as a approaches 0 or 1, respectively. 098 * @param start a valid double, as in, not infinite or NaN 099 * @param end a valid double, as in, not infinite or NaN 100 * @param a a double between 0 and 1 inclusive 101 * @return a double between x and y inclusive 102 */ 103 public static double querp(final double start, final double end, double a){ 104 return (1.0 - (a *= a * a * (a * (a * 6.0 - 15.0) + 10.0))) * start + a * end; 105 } 106 /* 107 * Quintic-interpolates between start and end (valid floats), with a between 0 (yields start) and 1 (yields end). 108 * Will smoothly transition toward start or end as a approaches 0 or 1, respectively. 109 * @param start a valid float, as in, not infinite or NaN 110 * @param end a valid float, as in, not infinite or NaN 111 * @param a a float between 0 and 1 inclusive 112 * @return a float between x and y inclusive 113 */ 114 public static float querp(final float start, final float end, float a){ 115 return (1f - (a *= a * a * (a * (a * 6f - 15f) + 10f))) * start + a * end; 116 } 117 118 119 /** 120 * Linear-interpolates between start and end (valid doubles), with a between 0 (yields start) and 1 (yields end). 121 * @param start a valid double, as in, not infinite or NaN 122 * @param end a valid double, as in, not infinite or NaN 123 * @param a a double between 0 and 1 inclusive 124 * @return a double between x and y inclusive 125 */ 126 public static double lerp(final double start, final double end, final double a) { 127 return (1.0 - a) * start + a * end; 128 } 129 130 /** 131 * Linear-interpolates between start and end (valid floats), with a between 0 (yields start) and 1 (yields end). 132 * @param start a valid float, as in, not infinite or NaN 133 * @param end a valid float, as in, not infinite or NaN 134 * @param a a float between 0 and 1 inclusive 135 * @return a float between x and y inclusive 136 */ 137 public static float lerp(final float start, final float end, final float a) { 138 return (1f - a) * start + a * end; 139 } 140 141 /** 142 * Given a float {@code a} from 0.0 to 1.0 (both inclusive), this gets a float that adjusts a to be closer to the 143 * end points of that range (if less than 0.5, it gets closer to 0.0, otherwise it gets closer to 1.0). 144 * @param a a float between 0.0f and 1.0f inclusive 145 * @return a float between 0.0f and 1.0f inclusive that is more likely to be near the extremes 146 */ 147 public static double emphasize(final double a) 148 { 149 return a * a * (3.0 - 2.0 * a); 150 } 151 /** 152 * Given a float {@code a} from -1.0 to 1.0 (both inclusive), this gets a float that adjusts a to be closer to the 153 * end points of that range (if less than 0, it gets closer to -1.0, otherwise it gets closer to 1.0). 154 * <br> 155 * Used by {@link ClassicNoise} and {@link JitterNoise} to increase the frequency of high and low results, which 156 * improves the behavior of {@link Ridged2D} and other Ridged noise when it uses those noise algorithms. 157 * @param a a float between -1.0f and 1.0f inclusive 158 * @return a float between -1.0f and 1.0f inclusive that is more likely to be near the extremes 159 */ 160 public static double emphasizeSigned(double a) 161 { 162 a = a * 0.5 + 0.5; 163 return a * a * (6.0 - 4.0 * a) - 1.0; 164 } 165 166 /** 167 * Given a double {@code a} from 0.0 to 1.0 (both inclusive), this gets a double that adjusts a to be much closer to 168 * the end points of that range (if less than 0.5, it gets closer to 0.0, otherwise it gets closer to 1.0). 169 * @param a a double between 0.0 and 1.0 inclusive 170 * @return a double between 0.0 and 1.0 inclusive that is more likely to be near the extremes 171 */ 172 public static double extreme(final double a) 173 { 174 return a * a * a * (a * (a * 6 - 15) + 10); 175 } 176 177 /** 178 * Given a double {@code a} from -1.0 to 1.0 (both inclusive), this gets a double that adjusts a to be much closer 179 * to the end points of that range (if less than 0, it gets closer to -1.0, otherwise it gets closer to 1.0). 180 * @param a a double between -1.0 and 1.0 inclusive 181 * @return a double between -1.0 and 1.0 inclusive that is more likely to be near the extremes 182 */ 183 public static double extremeSigned(double a) 184 { 185 a = a * 0.5 + 0.5; 186 return a * a * a * (a * (a * 12 - 30) + 20) - 1.0; 187 } 188 189 public interface Noise1D { 190 double getNoise(double x); 191 double getNoiseWithSeed(double x, long seed); 192 } 193 194 public interface Noise2D { 195 double getNoise(double x, double y); 196 double getNoiseWithSeed(double x, double y, long seed); 197 } 198 199 public interface Noise3D { 200 double getNoise(double x, double y, double z); 201 double getNoiseWithSeed(double x, double y, double z, long seed); 202 } 203 204 public interface Noise4D { 205 double getNoise(double x, double y, double z, double w); 206 double getNoiseWithSeed(double x, double y, double z, double w, long seed); 207 } 208 209 public interface Noise6D { 210 double getNoise(double x, double y, double z, double w, double u, double v); 211 double getNoiseWithSeed(double x, double y, double z, double w, double u, double v, long seed); 212 } 213 214 public static class Layered1D implements Noise1D { 215 protected int octaves; 216 protected Noise1D basis; 217 public double frequency; 218 public double lacunarity; 219 public Layered1D() { 220 this(Basic1D.instance); 221 } 222 223 public Layered1D(Noise1D basis) { 224 this(basis, 2); 225 } 226 227 public Layered1D(Noise1D basis, final int octaves) { 228 this(basis, octaves, 1.0); 229 } 230 public Layered1D(Noise1D basis, final int octaves, double frequency) { 231 this(basis, octaves, frequency, 0.5); 232 } 233 public Layered1D(Noise1D basis, final int octaves, double frequency, double lacunarity) { 234 this.basis = basis; 235 this.frequency = frequency; 236 this.octaves = Math.max(1, Math.min(63, octaves)); 237 this.lacunarity = lacunarity; 238 } 239 240 241 @Override 242 public double getNoise(double x) { 243 x *= frequency; 244 int s = 1; 245 double n = 0.0, i_s = 2.0; 246 for (int o = 0; o < octaves; o++, s <<= 1) { 247 n += basis.getNoise(x * (i_s *= lacunarity) + (o << 6)) * s; 248 } 249 return n / ((1 << octaves) - 1.0); 250 } 251 252 @Override 253 public double getNoiseWithSeed(double x, long seed) { 254 x *= frequency; 255 int s = 1; 256 double n = 0.0, i_s = 2.0; 257 for (int o = 0; o < octaves; o++, s <<= 1) { 258 n += basis.getNoiseWithSeed(x * (i_s *= lacunarity), (seed += 0x9E3779B97F4A7C15L)) * s; 259 } 260 return n / ((1 << octaves) - 1.0); 261 } 262 } 263 264 public static class Layered2D implements Noise2D { 265 protected int octaves; 266 protected Noise2D basis; 267 public double frequency; 268 public double lacunarity; 269 public Layered2D() { 270 this(SeededNoise.instance); 271 } 272 273 public Layered2D(Noise2D basis) { 274 this(basis, 2); 275 } 276 277 public Layered2D(Noise2D basis, final int octaves) { 278 this(basis, octaves, 1.0); 279 } 280 public Layered2D(Noise2D basis, final int octaves, double frequency) { 281 this(basis, octaves, frequency, 0.5); 282 } 283 public Layered2D(Noise2D basis, final int octaves, double frequency, double lacunarity) { 284 this.basis = basis; 285 this.frequency = frequency; 286 this.octaves = Math.max(1, Math.min(63, octaves)); 287 this.lacunarity = lacunarity; 288 } 289 290 @Override 291 public double getNoise(double x, double y) { 292 x *= frequency; 293 y *= frequency; 294 int s = 1; 295 double n = 0.0, i_s = 2.0; 296 for (int o = 0; o < octaves; o++, s <<= 1) { 297 n += basis.getNoise(x * (i_s *= lacunarity) + (o << 6), y * i_s + (o << 7)) * s; 298 } 299 return n / ((1 << octaves) - 1.0); 300 } 301 302 @Override 303 public double getNoiseWithSeed(double x, double y, long seed) { 304 x *= frequency; 305 y *= frequency; 306 int s = 1; 307 double n = 0.0, i_s = 2.0; 308 for (int o = 0; o < octaves; o++, s <<= 1) { 309 n += basis.getNoiseWithSeed(x * (i_s *= lacunarity), y * i_s, (seed += 0x9E3779B97F4A7C15L)) * s; 310 } 311 return n / ((1 << octaves) - 1.0); 312 } 313 } 314 public static class Layered3D implements Noise3D { 315 protected int octaves; 316 protected Noise3D basis; 317 public double frequency; 318 public double lacunarity; 319 public Layered3D() { 320 this(SeededNoise.instance); 321 } 322 323 public Layered3D(Noise3D basis) { 324 this(basis, 2); 325 } 326 327 public Layered3D(Noise3D basis, final int octaves) { 328 this(basis, octaves, 1.0); 329 } 330 public Layered3D(Noise3D basis, final int octaves, double frequency) { 331 this(basis, octaves, frequency, 0.5); 332 } 333 public Layered3D(Noise3D basis, final int octaves, double frequency, double lacunarity) { 334 this.basis = basis; 335 this.frequency = frequency; 336 this.octaves = Math.max(1, Math.min(63, octaves)); 337 this.lacunarity = lacunarity; 338 } 339 340 @Override 341 public double getNoise(double x, double y, double z) { 342 x *= frequency; 343 y *= frequency; 344 z *= frequency; 345 int s = 1; 346 double n = 0.0, i_s = 2.0; 347 for (int o = 0; o < octaves; o++, s <<= 1) { 348 n += basis.getNoise(x * (i_s *= lacunarity) + (o << 6), y * i_s + (o << 7), z * i_s + (o << 8)) * s; 349 } 350 return n / ((1 << octaves) - 1.0); 351 } 352 353 @Override 354 public double getNoiseWithSeed(double x, double y, double z, long seed) { 355 x *= frequency; 356 y *= frequency; 357 z *= frequency; 358 int s = 1; 359 double n = 0.0, i_s = 2.0; 360 for (int o = 0; o < octaves; o++, s <<= 1) { 361 n += basis.getNoiseWithSeed(x * (i_s *= lacunarity), y * i_s, z * i_s, (seed += 0x9E3779B97F4A7C15L)) * s; 362 } 363 return n / ((1 << octaves) - 1.0); 364 } 365 } 366 public static class Layered4D implements Noise4D { 367 protected int octaves; 368 protected Noise4D basis; 369 public double frequency; 370 public double lacunarity; 371 public Layered4D() { 372 this(SeededNoise.instance); 373 } 374 375 public Layered4D(Noise4D basis) { 376 this(basis, 2); 377 } 378 379 public Layered4D(Noise4D basis, final int octaves) { 380 this(basis, octaves, 1.0); 381 } 382 public Layered4D(Noise4D basis, final int octaves, double frequency) { 383 this(basis, octaves, frequency, 0.5); 384 } 385 public Layered4D(Noise4D basis, final int octaves, double frequency, double lacunarity) { 386 this.basis = basis; 387 this.frequency = frequency; 388 this.octaves = Math.max(1, Math.min(63, octaves)); 389 this.lacunarity = lacunarity; 390 } 391 392 @Override 393 public double getNoise(double x, double y, double z, double w) { 394 x *= frequency; 395 y *= frequency; 396 z *= frequency; 397 w *= frequency; 398 int s = 1; 399 double n = 0.0, i_s = 2.0; 400 for (int o = 0; o < octaves; o++, s <<= 1) { 401 n += basis.getNoise(x * (i_s *= lacunarity) + (o << 6), y * i_s + (o << 7), z * i_s + (o << 8), w * i_s + (o << 9)) * s; 402 } 403 return n / ((1 << octaves) - 1.0); 404 } 405 406 @Override 407 public double getNoiseWithSeed(double x, double y, double z, double w, long seed) { 408 x *= frequency; 409 y *= frequency; 410 z *= frequency; 411 w *= frequency; 412 int s = 1; 413 double n = 0.0, i_s = 2.0; 414 for (int o = 0; o < octaves; o++, s <<= 1) { 415 n += basis.getNoiseWithSeed(x * (i_s *= lacunarity), y * i_s, z * i_s, w * i_s, (seed += 0x9E3779B97F4A7C15L)) * s; 416 } 417 return n / ((1 << octaves) - 1.0); 418 } 419 } 420 public static class Layered6D implements Noise6D { 421 protected int octaves; 422 protected Noise6D basis; 423 public double frequency; 424 public double lacunarity; 425 public Layered6D() { 426 this(SeededNoise.instance); 427 } 428 429 public Layered6D(Noise6D basis) { 430 this(basis, 2); 431 } 432 433 public Layered6D(Noise6D basis, final int octaves) { 434 this(basis, octaves, 1.0); 435 } 436 public Layered6D(Noise6D basis, final int octaves, double frequency) { 437 this(basis, octaves, frequency, 0.5); 438 } 439 public Layered6D(Noise6D basis, final int octaves, double frequency, double lacunarity) { 440 this.basis = basis; 441 this.frequency = frequency; 442 this.octaves = Math.max(1, Math.min(63, octaves)); 443 this.lacunarity = lacunarity; 444 } 445 446 @Override 447 public double getNoise(double x, double y, double z, double w, double u, double v) { 448 x *= frequency; 449 y *= frequency; 450 z *= frequency; 451 w *= frequency; 452 u *= frequency; 453 v *= frequency; 454 int s = 1; 455 double n = 0.0, i_s = 2.0; 456 for (int o = 0; o < octaves; o++, s <<= 1) { 457 n += basis.getNoise(x * (i_s *= lacunarity) + (o << 6), y * i_s + (o << 7), z * i_s + (o << 8) 458 , w * i_s + (o << 9), u * i_s + (o << 10), v * i_s + (o << 11)) * s; 459 } 460 return n / ((1 << octaves) - 1.0); 461 } 462 463 @Override 464 public double getNoiseWithSeed(double x, double y, double z, double w, double u, double v, long seed) { 465 x *= frequency; 466 y *= frequency; 467 z *= frequency; 468 w *= frequency; 469 u *= frequency; 470 v *= frequency; 471 int s = 1; 472 double n = 0.0, i_s = 2.0; 473 for (int o = 0; o < octaves; o++, s <<= 1) { 474 n += basis.getNoiseWithSeed(x * (i_s *= lacunarity), y * i_s, z * i_s 475 , w * i_s, u * i_s, v * i_s, (seed += 0x9E3779B97F4A7C15L)) * s; 476 } 477 return n / ((1 << octaves) - 1.0); 478 } 479 } 480 481 public static class InverseLayered1D implements Noise1D { 482 protected int octaves; 483 protected Noise1D basis; 484 public double frequency; 485 /** 486 * A multiplier that affects how much the frequency changes with each layer; the default is 0.5 . 487 */ 488 public double lacunarity = 0.5; 489 public InverseLayered1D() { 490 this(Basic1D.instance); 491 } 492 493 public InverseLayered1D(Noise1D basis) { 494 this(basis, 2); 495 } 496 497 public InverseLayered1D(Noise1D basis, final int octaves) { 498 this(basis, octaves, 1.0); 499 } 500 public InverseLayered1D(Noise1D basis, final int octaves, double frequency) { 501 this.basis = basis; 502 this.frequency = frequency; 503 this.octaves = Math.max(1, Math.min(63, octaves)); 504 } 505 public InverseLayered1D(Noise1D basis, final int octaves, double frequency, double lacunarity){ 506 this(basis, octaves, frequency); 507 this.lacunarity = lacunarity; 508 } 509 510 @Override 511 public double getNoise(double x) { 512 x *= frequency; 513 int s = 1 << (octaves - 1); 514 double n = 0.0, i_s = 2.0; 515 for (int o = 0; o < octaves; o++, s >>= 1) { 516 n += basis.getNoise(x * (i_s *= lacunarity) + (o << 6)) * s; 517 } 518 return n / ((1 << octaves) - 1.0); 519 } 520 521 @Override 522 public double getNoiseWithSeed(double x, long seed) { 523 x *= frequency; 524 int s = 1 << (octaves - 1); 525 double n = 0.0, i_s = 2.0; 526 for (int o = 0; o < octaves; o++, s >>= 1) { 527 n += basis.getNoiseWithSeed(x * (i_s *= lacunarity), (seed += 0x9E3779B97F4A7C15L)) * s; 528 } 529 return n / ((1 << octaves) - 1.0); 530 } 531 } 532 533 public static class InverseLayered2D implements Noise2D { 534 protected int octaves; 535 protected Noise2D basis; 536 public double frequency; 537 /** 538 * A multiplier that affects how much the frequency changes with each layer; the default is 0.5 . 539 */ 540 public double lacunarity = 0.5; 541 public InverseLayered2D() { 542 this(SeededNoise.instance, 2); 543 } 544 545 public InverseLayered2D(Noise2D basis) { 546 this(basis, 2); 547 } 548 549 public InverseLayered2D(Noise2D basis, final int octaves) { 550 this(basis, octaves, 1.0); 551 } 552 public InverseLayered2D(Noise2D basis, final int octaves, double frequency) { 553 this.basis = basis; 554 this.frequency = frequency; 555 this.octaves = Math.max(1, Math.min(63, octaves)); 556 } 557 public InverseLayered2D(Noise2D basis, final int octaves, double frequency, double lacunarity){ 558 this(basis, octaves, frequency); 559 this.lacunarity = lacunarity; 560 } 561 562 @Override 563 public double getNoise(double x, double y) { 564 x *= frequency; 565 y *= frequency; 566 int s = 1 << (octaves - 1); 567 double n = 0.0, i_s = 2.0; 568 for (int o = 0; o < octaves; o++, s >>= 1) { 569 n += basis.getNoise(x * (i_s *= lacunarity) + (o << 6), y * i_s + (o << 7)) * s; 570 } 571 return n / ((1 << octaves) - 1.0); 572 } 573 574 @Override 575 public double getNoiseWithSeed(double x, double y, long seed) { 576 x *= frequency; 577 y *= frequency; 578 int s = 1 << (octaves - 1); 579 double n = 0.0, i_s = 2.0; 580 for (int o = 0; o < octaves; o++, s >>= 1) { 581 n += basis.getNoiseWithSeed(x * (i_s *= lacunarity), y * i_s, (seed += 0x9E3779B97F4A7C15L)) * s; 582 } 583 return n / ((1 << octaves) - 1.0); 584 } 585 } 586 public static class InverseLayered3D implements Noise3D { 587 protected int octaves; 588 protected Noise3D basis; 589 public double frequency; 590 /** 591 * A multiplier that affects how much the frequency changes with each layer; the default is 0.5 . 592 */ 593 public double lacunarity = 0.5; 594 public InverseLayered3D() { 595 this(SeededNoise.instance, 2); 596 } 597 598 public InverseLayered3D(Noise3D basis) { 599 this(basis, 2); 600 } 601 602 public InverseLayered3D(Noise3D basis, final int octaves) { 603 this(basis, octaves, 1.0); 604 } 605 public InverseLayered3D(Noise3D basis, final int octaves, double frequency) { 606 this.basis = basis; 607 this.frequency = frequency; 608 this.octaves = Math.max(1, Math.min(63, octaves)); 609 } 610 public InverseLayered3D(Noise3D basis, final int octaves, double frequency, double lacunarity){ 611 this(basis, octaves, frequency); 612 this.lacunarity = lacunarity; 613 } 614 615 @Override 616 public double getNoise(double x, double y, double z) { 617 x *= frequency; 618 y *= frequency; 619 z *= frequency; 620 int s = 1 << (octaves - 1); 621 double n = 0.0, i_s = 2.0; 622 for (int o = 0; o < octaves; o++, s >>= 1) { 623 n += basis.getNoise(x * (i_s *= lacunarity) + (o << 6), y * i_s + (o << 7), z * i_s + (o << 8)) * s; 624 } 625 return n / ((1 << octaves) - 1.0); 626 } 627 628 @Override 629 public double getNoiseWithSeed(double x, double y, double z, long seed) { 630 x *= frequency; 631 y *= frequency; 632 z *= frequency; 633 int s = 1 << (octaves - 1); 634 double n = 0.0, i_s = 2.0; 635 for (int o = 0; o < octaves; o++, s >>= 1) { 636 n += basis.getNoiseWithSeed(x * (i_s *= lacunarity), y * i_s, z * i_s, (seed += 0x9E3779B97F4A7C15L)) * s; 637 } 638 return n / ((1 << octaves) - 1.0); 639 } 640 } 641 public static class InverseLayered4D implements Noise4D { 642 protected int octaves; 643 protected Noise4D basis; 644 public double frequency; 645 /** 646 * A multiplier that affects how much the frequency changes with each layer; the default is 0.5 . 647 */ 648 public double lacunarity = 0.5; 649 public InverseLayered4D() { 650 this(SeededNoise.instance, 2); 651 } 652 653 public InverseLayered4D(Noise4D basis) { 654 this(basis, 2); 655 } 656 657 public InverseLayered4D(Noise4D basis, final int octaves) { 658 this(basis, octaves, 1.0); 659 } 660 public InverseLayered4D(Noise4D basis, final int octaves, double frequency) { 661 this.basis = basis; 662 this.frequency = frequency; 663 this.octaves = Math.max(1, Math.min(63, octaves)); 664 } 665 public InverseLayered4D(Noise4D basis, final int octaves, double frequency, double lacunarity){ 666 this(basis, octaves, frequency); 667 this.lacunarity = lacunarity; 668 } 669 670 @Override 671 public double getNoise(double x, double y, double z, double w) { 672 x *= frequency; 673 y *= frequency; 674 z *= frequency; 675 w *= frequency; 676 int s = 1 << (octaves - 1); 677 double n = 0.0, i_s = 2.0; 678 for (int o = 0; o < octaves; o++, s >>= 1) { 679 n += basis.getNoise(x * (i_s *= lacunarity) + (o << 6), y * i_s + (o << 7), z * i_s + (o << 8), w * i_s + (o << 9)) * s; 680 } 681 return n / ((1 << octaves) - 1.0); 682 } 683 684 @Override 685 public double getNoiseWithSeed(double x, double y, double z, double w, long seed) { 686 x *= frequency; 687 y *= frequency; 688 z *= frequency; 689 w *= frequency; 690 int s = 1 << (octaves - 1); 691 double n = 0.0, i_s = 2.0; 692 for (int o = 0; o < octaves; o++, s >>= 1) { 693 n += basis.getNoiseWithSeed(x * (i_s *= lacunarity), y * i_s, z * i_s, w * i_s, (seed += 0x9E3779B97F4A7C15L)) * s; 694 } 695 return n / ((1 << octaves) - 1.0); 696 } 697 } 698 public static class InverseLayered6D implements Noise6D { 699 protected int octaves; 700 protected Noise6D basis; 701 public double frequency; 702 /** 703 * A multiplier that affects how much the frequency changes with each layer; the default is 0.5 . 704 */ 705 public double lacunarity = 0.5; 706 public InverseLayered6D() { 707 this(SeededNoise.instance, 2); 708 } 709 710 public InverseLayered6D(Noise6D basis) { 711 this(basis, 2); 712 } 713 714 public InverseLayered6D(Noise6D basis, final int octaves) { 715 this(basis, octaves, 1.0); 716 } 717 public InverseLayered6D(Noise6D basis, final int octaves, double frequency) { 718 this.basis = basis; 719 this.frequency = frequency; 720 this.octaves = Math.max(1, Math.min(63, octaves)); 721 } 722 public InverseLayered6D(Noise6D basis, final int octaves, double frequency, double lacunarity){ 723 this(basis, octaves, frequency); 724 this.lacunarity = lacunarity; 725 } 726 727 @Override 728 public double getNoise(double x, double y, double z, double w, double u, double v) { 729 x *= frequency; 730 y *= frequency; 731 z *= frequency; 732 w *= frequency; 733 u *= frequency; 734 v *= frequency; 735 int s = 1 << (octaves - 1); 736 double n = 0.0, i_s = 2.0; 737 for (int o = 0; o < octaves; o++, s >>= 1) { 738 n += basis.getNoise(x * (i_s *= lacunarity) + (o << 6), y * i_s + (o << 7), z * i_s + (o << 8) 739 , w * i_s + (o << 9), u * i_s + (o << 10), v * i_s + (o << 11)) * s; 740 } 741 return n / ((1 << octaves) - 1.0); 742 } 743 744 @Override 745 public double getNoiseWithSeed(double x, double y, double z, double w, double u, double v, long seed) { 746 x *= frequency; 747 y *= frequency; 748 z *= frequency; 749 w *= frequency; 750 u *= frequency; 751 v *= frequency; 752 int s = 1 << (octaves - 1); 753 double n = 0.0, i_s = 2.0; 754 for (int o = 0; o < octaves; o++, s >>= 1) { 755 n += basis.getNoiseWithSeed(x * (i_s *= lacunarity), y * i_s, z * i_s 756 , w * i_s, u * i_s, v * i_s, (seed += 0x9E3779B97F4A7C15L)) * s; 757 } 758 return n / ((1 << octaves) - 1.0); 759 } 760 } 761 762 763 public static class Scaled1D implements Noise1D { 764 protected double scaleX; 765 protected Noise1D basis; 766 767 public Scaled1D() { 768 this(Basic1D.instance); 769 } 770 771 public Scaled1D(Noise1D basis) { 772 this(basis, 2.0); 773 } 774 775 public Scaled1D(Noise1D basis, final double scaleX) { 776 this.basis = basis; 777 this.scaleX = scaleX; 778 } 779 780 @Override 781 public double getNoise(final double x) { 782 return basis.getNoise(x * scaleX); 783 } 784 785 @Override 786 public double getNoiseWithSeed(final double x, long seed) { 787 return basis.getNoiseWithSeed(x * scaleX, seed); 788 } 789 } 790 791 public static class Scaled2D implements Noise2D { 792 protected double scaleX, scaleY; 793 protected Noise2D basis; 794 795 public Scaled2D() { 796 this(SeededNoise.instance); 797 } 798 799 public Scaled2D(Noise2D basis) { 800 this(basis, 2.0, 2.0); 801 } 802 803 public Scaled2D(Noise2D basis, double scale) { 804 this(basis, scale, scale); 805 } 806 807 public Scaled2D(Noise2D basis, final double scaleX, final double scaleY) { 808 this.basis = basis; 809 this.scaleX = scaleX; 810 this.scaleY = scaleY; 811 } 812 813 @Override 814 public double getNoise(final double x, final double y) { 815 return basis.getNoise(x * scaleX, y * scaleY); 816 } 817 818 @Override 819 public double getNoiseWithSeed(final double x, final double y, long seed) { 820 return basis.getNoiseWithSeed(x * scaleX, y * scaleY, seed); 821 } 822 } 823 public static class Scaled3D implements Noise3D { 824 protected double scaleX, scaleY, scaleZ; 825 protected Noise3D basis; 826 827 public Scaled3D() { 828 this(SeededNoise.instance); 829 } 830 831 public Scaled3D(Noise3D basis) { 832 this(basis, 2.0, 2.0, 2.0); 833 } 834 835 public Scaled3D(Noise3D basis, double scale) { 836 this(basis, scale, scale, scale); 837 } 838 839 public Scaled3D(Noise3D basis, final double scaleX, final double scaleY, final double scaleZ) { 840 this.basis = basis; 841 this.scaleX = scaleX; 842 this.scaleY = scaleY; 843 this.scaleZ = scaleZ; 844 } 845 846 @Override 847 public double getNoise(final double x, final double y, final double z) { 848 return basis.getNoise(x * scaleX, y * scaleY, z * scaleZ); 849 } 850 851 @Override 852 public double getNoiseWithSeed(final double x, final double y, final double z, long seed) { 853 return basis.getNoiseWithSeed(x * scaleX, y * scaleY, z * scaleZ, seed); 854 } 855 } 856 public static class Scaled4D implements Noise4D { 857 protected double scaleX, scaleY, scaleZ, scaleW; 858 protected Noise4D basis; 859 860 public Scaled4D() { 861 this(SeededNoise.instance); 862 } 863 864 public Scaled4D(Noise4D basis) { 865 this(basis, 2.0, 2.0, 2.0, 2.0); 866 } 867 868 public Scaled4D(Noise4D basis, double scale) { 869 this(basis, scale, scale, scale, scale); 870 } 871 872 public Scaled4D(Noise4D basis, final double scaleX, final double scaleY, final double scaleZ, final double scaleW) { 873 this.basis = basis; 874 this.scaleX = scaleX; 875 this.scaleY = scaleY; 876 this.scaleZ = scaleZ; 877 this.scaleW = scaleW; 878 } 879 880 @Override 881 public double getNoise(final double x, final double y, final double z, final double w) { 882 return basis.getNoise(x * scaleX, y * scaleY, z * scaleZ, w * scaleW); 883 } 884 885 @Override 886 public double getNoiseWithSeed(final double x, final double y, final double z, final double w, long seed) { 887 return basis.getNoiseWithSeed(x * scaleX, y * scaleY, z * scaleZ, w * scaleW, seed); 888 } 889 } 890 public static class Scaled6D implements Noise6D { 891 protected double scaleX, scaleY, scaleZ, scaleW, scaleU, scaleV; 892 protected Noise6D basis; 893 894 public Scaled6D() { 895 this(SeededNoise.instance); 896 } 897 898 public Scaled6D(Noise6D basis) { 899 this(basis, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0); 900 } 901 902 public Scaled6D(Noise6D basis, double scale) { 903 this(basis, scale, scale, scale, scale, scale, scale); 904 } 905 906 public Scaled6D(Noise6D basis, final double scaleX, final double scaleY, final double scaleZ, 907 final double scaleW, final double scaleU, final double scaleV) { 908 this.basis = basis; 909 this.scaleX = scaleX; 910 this.scaleY = scaleY; 911 this.scaleZ = scaleZ; 912 this.scaleW = scaleW; 913 this.scaleU = scaleU; 914 this.scaleV = scaleV; 915 } 916 917 @Override 918 public double getNoise(final double x, final double y, final double z, final double w, 919 final double u, final double v) { 920 return basis.getNoise(x * scaleX, y * scaleY, z * scaleZ, w * scaleW, u * scaleU, v * scaleV); 921 } 922 923 @Override 924 public double getNoiseWithSeed(final double x, final double y, final double z, final double w, 925 final double u, final double v, long seed) { 926 return basis.getNoiseWithSeed(x * scaleX, y * scaleY, z * scaleZ, w * scaleW, u * scaleU, 927 v * scaleV, seed); 928 } 929 } 930 931 public static class Ridged2D implements Noise2D { 932 protected int octaves; 933 public double frequency; 934 protected double correct; 935 protected Noise2D basis; 936 937 public Ridged2D() { 938 this(SeededNoise.instance, 2, 1.25); 939 } 940 941 public Ridged2D(Noise2D basis) { 942 this(basis, 2, 1.25); 943 } 944 945 public Ridged2D(Noise2D basis, int octaves, double frequency) { 946 this.basis = basis; 947 this.frequency = frequency; 948 setOctaves(octaves); 949 } 950 951 public void setOctaves(int octaves) 952 { 953 this.octaves = (octaves = Math.max(1, Math.min(63, octaves))); 954 correct = 1.0; 955 for (int o = 1; o < octaves; o++) { 956 correct += Math.pow(2.0, -o); 957 } 958 correct = 2.0 / correct; 959 } 960 961 962 @Override 963 public double getNoise(double x, double y) { 964 double sum = 0, amp = 1.0; 965 x *= frequency; 966 y *= frequency; 967 for (int i = 0; i < octaves; ++i) { 968 double n = basis.getNoise(x + (i << 6), y + (i << 7)); 969 n = 1.0 - Math.abs(n); 970 sum += amp * n; 971 amp *= 0.5; 972 x *= 2.0; 973 y *= 2.0; 974 } 975 return sum * correct - 1.0; 976 } 977 978 @Override 979 public double getNoiseWithSeed(double x, double y, long seed) { 980 double sum = 0, amp = 1.0; 981 x *= frequency; 982 y *= frequency; 983 for (int i = 0; i < octaves; ++i) { 984 double n = basis.getNoiseWithSeed(x, y, (seed += 0x9E3779B97F4A7C15L)); 985 n = 1.0 - Math.abs(n); 986 sum += amp * n; 987 amp *= 0.5; 988 x *= 2.0; 989 y *= 2.0; 990 } 991 return sum * correct - 1.0; 992 } 993 } 994 995 public static class Ridged3D implements Noise3D { 996 protected int octaves; 997 public double frequency; 998 protected double correct; 999 protected Noise3D basis; 1000 public Ridged3D() { 1001 this(SeededNoise.instance, 2, 1.25); 1002 } 1003 1004 public Ridged3D(Noise3D basis) { 1005 this(basis, 2, 1.25); 1006 } 1007 1008 public Ridged3D(Noise3D basis, int octaves) { 1009 this(basis, octaves, 1.25); 1010 } 1011 public Ridged3D(Noise3D basis, int octaves, double frequency) { 1012 this.basis = basis; 1013 this.frequency = frequency; 1014 setOctaves(octaves); 1015 } 1016 public void setOctaves(int octaves) 1017 { 1018 this.octaves = (octaves = Math.max(1, Math.min(63, octaves))); 1019 correct = 1.0; 1020 for (int o = 1; o < octaves; o++) { 1021 correct += Math.pow(2.0, -o); 1022 } 1023 correct = 2.0 / correct; 1024 } 1025 1026 @Override 1027 public double getNoise(double x, double y, double z) { 1028 double sum = 0, amp = 1.0; 1029 x *= frequency; 1030 y *= frequency; 1031 z *= frequency; 1032 for (int i = 0; i < octaves; ++i) { 1033 double n = basis.getNoise(x + (i << 6), y + (i << 7), z + (i << 8)); 1034 n = 1.0 - Math.abs(n); 1035 sum += amp * n; 1036 amp *= 0.5; 1037 x *= 2.0; 1038 y *= 2.0; 1039 z *= 2.0; 1040 } 1041 return sum * correct - 1.0; 1042 } 1043 1044 @Override 1045 public double getNoiseWithSeed(double x, double y, double z, long seed) { 1046 double sum = 0, amp = 1.0; 1047 x *= frequency; 1048 y *= frequency; 1049 z *= frequency; 1050 for (int i = 0; i < octaves; ++i) { 1051 double n = basis.getNoiseWithSeed(x, y, z, (seed += 0x9E3779B97F4A7C15L)); 1052 n = 1.0 - Math.abs(n); 1053 sum += amp * n; 1054 amp *= 0.5; 1055 x *= 2.0; 1056 y *= 2.0; 1057 z *= 2.0; 1058 } 1059 return sum * correct - 1.0; 1060 } 1061 } 1062 1063 1064 public static class Ridged4D implements Noise4D { 1065 public double[] exp; 1066 protected int octaves; 1067 public double frequency, correct; 1068 public Noise4D basis; 1069 1070 public Ridged4D() { 1071 this(SeededNoise.instance, 2, 1.25); 1072 } 1073 1074 public Ridged4D(Noise4D basis) { 1075 this(basis, 2, 1.25); 1076 } 1077 1078 public Ridged4D(Noise4D basis, int octaves, double frequency) { 1079 this.basis = basis; 1080 this.frequency = frequency; 1081 setOctaves(octaves); 1082 } 1083 public void setOctaves(int octaves) 1084 { 1085 this.octaves = (octaves = Math.max(1, Math.min(63, octaves))); 1086 exp = new double[octaves]; 1087 double maxvalue = 0.0; 1088 for (int i = 0; i < octaves; ++i) { 1089 maxvalue += (exp[i] = Math.pow(2.0, -i)); 1090 } 1091 correct = 2.0 / maxvalue; 1092 } 1093 1094 @Override 1095 public double getNoise(double x, double y, double z, double w) { 1096 double sum = 0.0, n; 1097 x *= frequency; 1098 y *= frequency; 1099 z *= frequency; 1100 w *= frequency; 1101 for (int i = 0; i < octaves; ++i) { 1102 n = basis.getNoise(x + (i << 6), y + (i << 7), z + (i << 8), w + (i << 9)); 1103 n = 1.0 - Math.abs(n); 1104 sum += n * n * exp[i]; 1105 x *= 2.0; 1106 y *= 2.0; 1107 z *= 2.0; 1108 w *= 2.0; 1109 } 1110 return sum * correct - 1.0; 1111 } 1112 1113 @Override 1114 public double getNoiseWithSeed(double x, double y, double z, double w, long seed) { 1115 double sum = 0, n; 1116 x *= frequency; 1117 y *= frequency; 1118 z *= frequency; 1119 w *= frequency; 1120 for (int i = 0; i < octaves; ++i) { 1121 n = basis.getNoiseWithSeed(x, y, z, w, (seed += 0x9E3779B97F4A7C15L)); 1122 n = 1.0 - Math.abs(n); 1123 sum += n * n * exp[i]; 1124 x *= 2.0; 1125 y *= 2.0; 1126 z *= 2.0; 1127 w *= 2.0; 1128 } 1129 return sum * correct - 1.0; 1130 } 1131 } 1132 1133 1134 public static class Ridged6D implements Noise6D 1135 { 1136 protected double[] exp; 1137 protected int octaves; 1138 public double frequency, correct; 1139 public Noise6D basis; 1140 public Ridged6D() 1141 { 1142 this(SeededNoise.instance, 2, 1.25); 1143 } 1144 public Ridged6D(Noise6D basis) 1145 { 1146 this(basis, 2, 1.25); 1147 } 1148 public Ridged6D(Noise6D basis, int octaves, double frequency) 1149 { 1150 this.basis = basis; 1151 this.frequency = frequency; 1152 setOctaves(octaves); 1153 } 1154 public void setOctaves(int octaves) 1155 { 1156 this.octaves = (octaves = Math.max(1, Math.min(63, octaves))); 1157 exp = new double[octaves]; 1158 double maxvalue = 0.0; 1159 for (int i = 0; i < octaves; ++i) { 1160 maxvalue += (exp[i] = Math.pow(2.0, -i)); 1161 } 1162 correct = 2.0 / maxvalue; 1163 } 1164 1165 @Override 1166 public double getNoise(double x, double y, double z, double w, double u, double v) { 1167 double sum = 0.0, n; 1168 x *= frequency; 1169 y *= frequency; 1170 z *= frequency; 1171 w *= frequency; 1172 u *= frequency; 1173 v *= frequency; 1174 1175 for (int i = 0; i < octaves; ++i) { 1176 n = basis.getNoise(x + (i << 6), y + (i << 7), z + (i << 8), w + (i << 9), u + (i << 10), v + (i << 11)); 1177 n = 1.0 - Math.abs(n); 1178 sum += n * n * exp[i]; 1179 x *= 2.0; 1180 y *= 2.0; 1181 z *= 2.0; 1182 w *= 2.0; 1183 u *= 2.0; 1184 v *= 2.0; 1185 } 1186 return sum * correct - 1.0; 1187 } 1188 1189 @Override 1190 public double getNoiseWithSeed(double x, double y, double z, double w, double u, double v, long seed) { 1191 double sum = 0, n; 1192 x *= frequency; 1193 y *= frequency; 1194 z *= frequency; 1195 w *= frequency; 1196 u *= frequency; 1197 v *= frequency; 1198 for (int i = 0; i < octaves; ++i) { 1199 n = basis.getNoiseWithSeed(x, y, z, 1200 w, u, v, (seed += 0x9E3779B97F4A7C15L)); 1201 n = 1.0 - Math.abs(n); 1202 sum += n * n * exp[i]; 1203 x *= 2.0; 1204 y *= 2.0; 1205 z *= 2.0; 1206 w *= 2.0; 1207 u *= 2.0; 1208 v *= 2.0; 1209 } 1210 return sum * correct - 1.0; 1211 } 1212 } 1213 1214 public static class Turbulent2D implements Noise2D { 1215 protected int octaves; 1216 protected Noise2D basis, disturbance; 1217 public double frequency; 1218 public final double correct; 1219 1220 public Turbulent2D() { 1221 this(SeededNoise.instance, alternate, 1); 1222 } 1223 1224 public Turbulent2D(Noise2D basis, Noise2D disturb) { 1225 this(basis, disturb, 1); 1226 } 1227 1228 public Turbulent2D(Noise2D basis, Noise2D disturb, final int octaves) { 1229 this(basis, disturb, octaves, 1.0); 1230 } 1231 public Turbulent2D(Noise2D basis, Noise2D disturb, final int octaves, final double frequency) { 1232 this.basis = basis; 1233 this.frequency = frequency; 1234 disturbance = disturb; 1235 this.octaves = Math.max(1, Math.min(63, octaves)); 1236 correct = 1.0 / ((1 << this.octaves) - 1.0); 1237 } 1238 1239 @Override 1240 public double getNoise(double x, double y) { 1241 x *= frequency; 1242 y *= frequency; 1243 x += disturbance.getNoise(x, y); 1244 int s = 1; 1245 double n = 0.0, i_s = 2.0; 1246 for (int o = 0; o < octaves; o++, s <<= 1) { 1247 i_s *= 0.5; 1248 n += basis.getNoise(x * i_s + (o << 6), y * i_s + (o << 7)) * s; 1249 } 1250 return n * correct; 1251 } 1252 1253 @Override 1254 public double getNoiseWithSeed(double x, double y, long seed) { 1255 x *= frequency; 1256 y *= frequency; 1257 x += disturbance.getNoiseWithSeed(x, y, seed); 1258 int s = 1; 1259 double n = 0.0, i_s = 2.0; 1260 for (int o = 0; o < octaves; o++, s <<= 1) { 1261 i_s *= 0.5; 1262 n += basis.getNoiseWithSeed(x * i_s, y * i_s, seed += 0x9E3779B97F4A7C15L) * s; 1263 } 1264 return n * correct; 1265 } 1266 } 1267 public static class Turbulent3D implements Noise3D { 1268 protected int octaves; 1269 protected Noise3D basis, disturbance; 1270 public double frequency; 1271 public final double correct; 1272 1273 public Turbulent3D() { 1274 this(SeededNoise.instance, alternate, 1); 1275 } 1276 1277 public Turbulent3D(Noise3D basis, Noise3D disturb) { 1278 this(basis, disturb, 1); 1279 } 1280 1281 public Turbulent3D(Noise3D basis, Noise3D disturb, final int octaves) { 1282 this(basis, disturb, octaves, 1.0); 1283 } 1284 public Turbulent3D(Noise3D basis, Noise3D disturb, final int octaves, final double frequency) { 1285 this.basis = basis; 1286 this.frequency = frequency; 1287 disturbance = disturb; 1288 this.octaves = Math.max(1, Math.min(63, octaves)); 1289 correct = 1.0 / ((1 << this.octaves) - 1.0); 1290 } 1291 1292 @Override 1293 public double getNoise(double x, double y, double z) { 1294 x *= frequency; 1295 y *= frequency; 1296 z *= frequency; 1297 x += disturbance.getNoise(x, y, z); 1298 int s = 1; 1299 double n = 0.0, i_s = 2.0; 1300 for (int o = 0; o < octaves; o++, s <<= 1) { 1301 i_s *= 0.5; 1302 n += basis.getNoise(x * i_s + (o << 6), y * i_s + (o << 7), z * i_s + (o << 8)) * s; 1303 } 1304 return n * correct; 1305 } 1306 1307 @Override 1308 public double getNoiseWithSeed(double x, double y, double z, long seed) { 1309 x *= frequency; 1310 y *= frequency; 1311 z *= frequency; 1312 x += disturbance.getNoiseWithSeed(x, y, z, seed); 1313 int s = 1; 1314 double n = 0.0, i_s = 2.0; 1315 for (int o = 0; o < octaves; o++, s <<= 1) { 1316 i_s *= 0.5; 1317 n += basis.getNoiseWithSeed(x * i_s, y * i_s, z * i_s, seed += 0x9E3779B97F4A7C15L) * s; 1318 } 1319 return n * correct; 1320 } 1321 } 1322 1323 public static class Turbulent4D implements Noise4D { 1324 protected int octaves; 1325 protected Noise4D basis, disturbance; 1326 public double frequency; 1327 public final double correct; 1328 public Turbulent4D() { 1329 this(SeededNoise.instance, alternate, 1); 1330 } 1331 1332 public Turbulent4D(Noise4D basis, Noise4D disturb) { 1333 this(basis, disturb, 1); 1334 } 1335 1336 1337 public Turbulent4D(Noise4D basis, Noise4D disturb, final int octaves) { 1338 this(basis, disturb, octaves, 1.0); 1339 } 1340 public Turbulent4D(Noise4D basis, Noise4D disturb, final int octaves, final double frequency) { 1341 this.basis = basis; 1342 this.frequency = frequency; 1343 disturbance = disturb; 1344 this.octaves = Math.max(1, Math.min(63, octaves)); 1345 correct = 1.0 / ((1 << this.octaves) - 1.0); 1346 } 1347 1348 @Override 1349 public double getNoise(double x, double y, double z, double w) { 1350 x *= frequency; 1351 y *= frequency; 1352 z *= frequency; 1353 w *= frequency; 1354 x += disturbance.getNoise(x, y, z, w); 1355 int s = 1; 1356 double n = 0.0, i_s = 2.0; 1357 for (int o = 0; o < octaves; o++, s <<= 1) { 1358 i_s *= 0.5; 1359 n += basis.getNoise(x * i_s + (o << 6), y * i_s + (o << 7), z * i_s + (o << 8), w * i_s + (o << 9)) * s; 1360 } 1361 return n * correct; 1362 } 1363 1364 @Override 1365 public double getNoiseWithSeed(double x, double y, double z, double w, long seed) { 1366 x *= frequency; 1367 y *= frequency; 1368 z *= frequency; 1369 w *= frequency; 1370 x += disturbance.getNoiseWithSeed(x, y, z, w, seed); 1371 int s = 1; 1372 double n = 0.0, i_s = 2.0; 1373 for (int o = 0; o < octaves; o++, s <<= 1) { 1374 i_s *= 0.5; 1375 n += basis.getNoiseWithSeed(x * i_s, y * i_s, z * i_s, w * i_s, seed += 0x9E3779B97F4A7C15L) * s; 1376 } 1377 return n * correct; 1378 } 1379 } 1380 public static class Turbulent6D implements Noise6D { 1381 protected int octaves; 1382 protected Noise6D basis, disturbance; 1383 public double frequency; 1384 public final double correct; 1385 public Turbulent6D() { 1386 this(SeededNoise.instance, alternate, 1); 1387 } 1388 1389 public Turbulent6D(Noise6D basis, Noise6D disturb) { 1390 this(basis, disturb, 1); 1391 } 1392 1393 public Turbulent6D(Noise6D basis, Noise6D disturb, final int octaves) { 1394 this(basis, disturb, octaves, 1.0); 1395 } 1396 public Turbulent6D(Noise6D basis, Noise6D disturb, final int octaves, final double frequency) { 1397 this.basis = basis; 1398 this.frequency = frequency; 1399 disturbance = disturb; 1400 this.octaves = Math.max(1, Math.min(63, octaves)); 1401 correct = 1.0 / ((1 << this.octaves) - 1.0); 1402 } 1403 @Override 1404 public double getNoise(double x, double y, double z, double w, double u, double v) { 1405 x *= frequency; 1406 y *= frequency; 1407 z *= frequency; 1408 w *= frequency; 1409 u *= frequency; 1410 v *= frequency; 1411 x += disturbance.getNoise(x, y, z, w, u, v); 1412 int s = 1; 1413 double n = 0.0, i_s = 2.0; 1414 for (int o = 0; o < octaves; o++, s <<= 1) { 1415 i_s *= 0.5; 1416 n += basis.getNoise(x * i_s + (o << 6), y * i_s + (o << 7), z * i_s + (o << 8), w * i_s + (o << 9), u * i_s + (o << 10), v * i_s + (o << 11)) * s; 1417 } 1418 return n * correct; 1419 } 1420 1421 @Override 1422 public double getNoiseWithSeed(double x, double y, double z, double w, double u, double v, long seed) { 1423 x *= frequency; 1424 y *= frequency; 1425 z *= frequency; 1426 w *= frequency; 1427 u *= frequency; 1428 v *= frequency; 1429 x += disturbance.getNoiseWithSeed(x, y, z, w, u, v, seed); 1430 int s = 1; 1431 double n = 0.0, i_s = 2.0; 1432 for (int o = 0; o < octaves; o++, s <<= 1) { 1433 i_s *= 0.5; 1434 n += basis.getNoiseWithSeed(x * i_s, y * i_s, z * i_s, w * i_s, u * i_s, v * i_s, seed += 0x9E3779B97F4A7C15L) * s; 1435 } 1436 return n * correct; 1437 } 1438 } 1439 1440 public static class Viny2D implements Noise2D { 1441 protected int octaves; 1442 protected Noise2D basis, disturbance; 1443 public double frequency; 1444 1445 public Viny2D() { 1446 this(SeededNoise.instance, alternate, 1); 1447 } 1448 1449 public Viny2D(Noise2D basis, Noise2D disturb) { 1450 this(basis, disturb, 1); 1451 } 1452 1453 public Viny2D(Noise2D basis, Noise2D disturb, final int octaves) { 1454 this(basis, disturb, octaves, 1.0); 1455 } 1456 public Viny2D(Noise2D basis, Noise2D disturb, final int octaves, final double frequency) { 1457 this.basis = basis; 1458 this.frequency = frequency; 1459 disturbance = disturb; 1460 this.octaves = Math.max(1, Math.min(63, octaves)); 1461 } 1462 1463 @Override 1464 public double getNoise(double x, double y) { 1465 x *= frequency; 1466 y *= frequency; 1467 int s = 2 << (octaves - 1); 1468 double n = 0.0, i_s = 1.0 / s, xx, yy; 1469 for (int o = 0; o < octaves; o++) { 1470 xx = x * (i_s *= 2.0) + (o << 6); 1471 yy = y * i_s + (o << 7); 1472 n += basis.getNoise(xx, yy) * s + disturbance.getNoise(xx, yy) * (s >>= 1); 1473 } 1474 return n / ((3 << octaves) - 3.0); 1475 } 1476 1477 @Override 1478 public double getNoiseWithSeed(double x, double y, long seed) { 1479 x *= frequency; 1480 y *= frequency; 1481 int s = 2 << (octaves - 1); 1482 double n = 0.0, i_s = 1.0 / s, xx, yy; 1483 for (int o = 0; o < octaves; o++) { 1484 xx = x * (i_s *= 2.0) + (o << 6); 1485 yy = y * i_s + (o << 7); 1486 n += basis.getNoiseWithSeed(xx, yy, seed) * s + disturbance.getNoiseWithSeed(xx, yy, seed) * (s >>= 1); 1487 } 1488 return n / ((3 << octaves) - 3.0); 1489 } 1490 } 1491 public static class Viny3D implements Noise3D { 1492 protected int octaves; 1493 protected Noise3D basis, disturbance; 1494 public double frequency; 1495 1496 public Viny3D() { 1497 this(SeededNoise.instance, alternate, 1); 1498 } 1499 1500 public Viny3D(Noise3D basis, Noise3D disturb) { 1501 this(basis, disturb, 1); 1502 } 1503 1504 public Viny3D(Noise3D basis, Noise3D disturb, final int octaves) { 1505 this(basis, disturb, octaves, 1.0); 1506 } 1507 public Viny3D(Noise3D basis, Noise3D disturb, final int octaves, final double frequency) { 1508 this.basis = basis; 1509 this.frequency = frequency; 1510 disturbance = disturb; 1511 this.octaves = Math.max(1, Math.min(63, octaves)); 1512 } 1513 1514 @Override 1515 public double getNoise(double x, double y, double z) { 1516 x *= frequency; 1517 y *= frequency; 1518 z *= frequency; 1519 int s = 2 << (octaves - 1); 1520 double n = 0.0, i_s = 1.0 / s, xx, yy, zz; 1521 for (int o = 0; o < octaves; o++) { 1522 xx = x * (i_s *= 2.0) + (o << 6); 1523 yy = y * i_s + (o << 7); 1524 zz = z * i_s + (o << 8); 1525 n += basis.getNoise(xx, yy, zz) * s + disturbance.getNoise(xx, yy, zz) * (s >>= 1); 1526 } 1527 return n / ((3 << octaves) - 3.0); 1528 } 1529 1530 @Override 1531 public double getNoiseWithSeed(double x, double y, double z, long seed) { 1532 x *= frequency; 1533 y *= frequency; 1534 z *= frequency; 1535 int s = 2 << (octaves - 1); 1536 double n = 0.0, i_s = 1.0 / s, xx, yy, zz; 1537 for (int o = 0; o < octaves; o++) { 1538 seed += 0x9E3779B97F4A7C15L; 1539 xx = x * (i_s *= 2.0) + (o << 6); 1540 yy = y * i_s + (o << 7); 1541 zz = z * i_s + (o << 8); 1542 n += basis.getNoiseWithSeed(xx, yy, zz, seed) * s + disturbance.getNoiseWithSeed(xx, yy, zz, seed) * (s >>= 1); 1543 } 1544 return n / ((3 << octaves) - 3.0); 1545 } 1546 } 1547 1548 public static class Viny4D implements Noise4D { 1549 protected int octaves; 1550 protected Noise4D basis, disturbance; 1551 public double frequency; 1552 1553 public Viny4D() { 1554 this(SeededNoise.instance, alternate, 1); 1555 } 1556 1557 public Viny4D(Noise4D basis, Noise4D disturb) { 1558 this(basis, disturb, 1); 1559 } 1560 1561 1562 public Viny4D(Noise4D basis, Noise4D disturb, final int octaves) { 1563 this(basis, disturb, octaves, 1.0); 1564 } 1565 public Viny4D(Noise4D basis, Noise4D disturb, final int octaves, final double frequency) { 1566 this.basis = basis; 1567 this.frequency = frequency; 1568 disturbance = disturb; 1569 this.octaves = Math.max(1, Math.min(63, octaves)); 1570 } 1571 @Override 1572 public double getNoise(double x, double y, double z, double w) { 1573 x *= frequency; 1574 y *= frequency; 1575 z *= frequency; 1576 w *= frequency; 1577 int s = 2 << (octaves - 1); 1578 double n = 0.0, i_s = 1.0 / s, xx, yy, zz, ww; 1579 for (int o = 0; o < octaves; o++) { 1580 xx = x * (i_s *= 2.0) + (o << 6); 1581 yy = y * i_s + (o << 7); 1582 zz = z * i_s + (o << 8); 1583 ww = w * i_s + (o << 9); 1584 n += basis.getNoise(xx, yy, zz, ww) * s + disturbance.getNoise(xx, yy, zz, ww) * (s >>= 1); 1585 } 1586 return n / ((3 << octaves) - 3.0); 1587 } 1588 1589 @Override 1590 public double getNoiseWithSeed(double x, double y, double z, double w, long seed) { 1591 x *= frequency; 1592 y *= frequency; 1593 z *= frequency; 1594 w *= frequency; 1595 int s = 2 << (octaves - 1); 1596 double n = 0.0, i_s = 1.0 / s, xx, yy, zz, ww; 1597 for (int o = 0; o < octaves; o++) { 1598 seed += 0x9E3779B97F4A7C15L; 1599 xx = x * (i_s *= 2.0) + (o << 6); 1600 yy = y * i_s + (o << 7); 1601 zz = z * i_s + (o << 8); 1602 ww = w * i_s + (o << 9); 1603 n += basis.getNoiseWithSeed(xx, yy, zz, ww, seed) * s + disturbance.getNoiseWithSeed(xx, yy, zz, ww, seed) * (s >>= 1); 1604 } 1605 return n / ((3 << octaves) - 3.0); 1606 } 1607 } 1608 public static class Viny6D implements Noise6D { 1609 protected int octaves; 1610 protected Noise6D basis, disturbance; 1611 public double frequency; 1612 public Viny6D() { 1613 this(SeededNoise.instance, alternate, 1); 1614 } 1615 1616 public Viny6D(Noise6D basis, Noise6D disturb) { 1617 this(basis, disturb, 1); 1618 } 1619 1620 public Viny6D(Noise6D basis, Noise6D disturb, final int octaves) { 1621 this(basis, disturb, octaves, 1.0); 1622 } 1623 public Viny6D(Noise6D basis, Noise6D disturb, final int octaves, final double frequency) { 1624 this.basis = basis; 1625 this.frequency = frequency; 1626 disturbance = disturb; 1627 this.octaves = Math.max(1, Math.min(63, octaves)); 1628 } 1629 @Override 1630 public double getNoise(double x, double y, double z, double w, double u, double v) { 1631 x *= frequency; 1632 y *= frequency; 1633 z *= frequency; 1634 w *= frequency; 1635 u *= frequency; 1636 v *= frequency; 1637 int s = 2 << (octaves - 1); 1638 double n = 0.0, i_s = 1.0 / s, xx, yy, zz, ww, uu, vv; 1639 for (int o = 0; o < octaves; o++) { 1640 xx = x * (i_s *= 2.0) + (o << 6); 1641 yy = y * i_s + (o << 7); 1642 zz = z * i_s + (o << 8); 1643 ww = w * i_s + (o << 9); 1644 uu = u * i_s + (o << 10); 1645 vv = v * i_s + (o << 11); 1646 n += basis.getNoise(xx, yy, zz, ww, uu, vv) * s + disturbance.getNoise(xx, yy, zz, ww, uu, vv) * (s >>= 1); 1647 } 1648 return n / ((3 << octaves) - 3.0); 1649 } 1650 1651 @Override 1652 public double getNoiseWithSeed(double x, double y, double z, double w, double u, double v, long seed) { 1653 x *= frequency; 1654 y *= frequency; 1655 z *= frequency; 1656 w *= frequency; 1657 u *= frequency; 1658 v *= frequency; 1659 int s = 2 << (octaves - 1); 1660 double n = 0.0, i_s = 1.0 / s, xx, yy, zz, ww, uu, vv; 1661 for (int o = 0; o < octaves; o++) { 1662 seed += 0x9E3779B97F4A7C15L; 1663 xx = x * (i_s *= 2.0) + (o << 6); 1664 yy = y * i_s + (o << 7); 1665 zz = z * i_s + (o << 8); 1666 ww = w * i_s + (o << 9); 1667 uu = u * i_s + (o << 10); 1668 vv = v * i_s + (o << 11); 1669 n += basis.getNoiseWithSeed(xx, yy, zz, ww, uu, vv, seed) * s + disturbance.getNoiseWithSeed(xx, yy, zz, ww, uu, vv, seed) * (s >>= 1); 1670 } 1671 return n / ((3 << octaves) - 3.0); 1672 } 1673 } 1674 1675 1676 public static class Slick2D implements Noise2D { 1677 protected int octaves; 1678 protected Noise2D basis, disturbance; 1679 1680 public Slick2D() { 1681 this(SeededNoise.instance, alternate, 1); 1682 } 1683 1684 public Slick2D(Noise2D basis, Noise2D disturb) { 1685 this(basis, disturb, 1); 1686 } 1687 1688 public Slick2D(Noise2D basis, Noise2D disturb, final int octaves) { 1689 this.basis = basis; 1690 disturbance = disturb; 1691 this.octaves = Math.max(1, Math.min(63, octaves)); 1692 } 1693 1694 @Override 1695 public double getNoise(final double x, final double y) { 1696 double n = 0.0, i_s = 1.0, xx, yy; 1697 int s = 1 << (octaves - 1); 1698 for (int o = 0; o < octaves; o++, s >>= 1) { 1699 xx = x * (i_s *= 0.5) + (o << 6); 1700 yy = y * i_s + (o << 7); 1701 n += basis.getNoise(xx + disturbance.getNoise(x, y), yy) * s; 1702 } 1703 return n / ((1 << octaves) - 1.0); 1704 } 1705 1706 @Override 1707 public double getNoiseWithSeed(final double x, final double y, long seed) { 1708 double n = 0.0, i_s = 1.0, xx, yy; 1709 1710 int s = 1 << (octaves - 1); 1711 for (int o = 0; o < octaves; o++, s >>= 1) { 1712 seed += 0x9E3779B97F4A7C15L; 1713 xx = x * (i_s *= 0.5) + (o << 6); 1714 yy = y * i_s + (o << 7); 1715 n += basis.getNoiseWithSeed(xx + disturbance.getNoiseWithSeed(x, y, seed), yy, seed) * s; 1716 } 1717 return n / ((1 << octaves) - 1.0); 1718 } 1719 } 1720 public static class Slick3D implements Noise3D { 1721 protected int octaves; 1722 protected Noise3D basis, disturbance; 1723 1724 public Slick3D() { 1725 this(SeededNoise.instance, alternate, 1); 1726 } 1727 1728 public Slick3D(Noise3D basis, Noise3D disturb) { 1729 this(basis, disturb, 1); 1730 } 1731 1732 public Slick3D(Noise3D basis, Noise3D disturb, final int octaves) { 1733 this.basis = basis; 1734 disturbance = disturb; 1735 this.octaves = Math.max(1, Math.min(63, octaves)); 1736 } 1737 1738 @Override 1739 public double getNoise(final double x, final double y, final double z) { 1740 double n = 0.0, i_s = 1.0, xx, yy, zz; 1741 int s = 1 << (octaves - 1); 1742 for (int o = 0; o < octaves; o++, s >>= 1) { 1743 xx = x * (i_s *= 0.5) + (o << 6); 1744 yy = y * i_s + (o << 7); 1745 zz = z * i_s + (o << 8); 1746 n += basis.getNoise(xx + disturbance.getNoise(x, y, z), yy, zz) * s; 1747 } 1748 return n / ((1 << octaves) - 1.0); 1749 } 1750 1751 @Override 1752 public double getNoiseWithSeed(final double x, final double y, final double z, long seed) { 1753 double n = 0.0, i_s = 1.0, xx, yy, zz; 1754 int s = 1 << (octaves - 1); 1755 for (int o = 0; o < octaves; o++, s >>= 1) { 1756 seed += 0x9E3779B97F4A7C15L; 1757 xx = x * (i_s *= 0.5) + (o << 6); 1758 yy = y * i_s + (o << 7); 1759 zz = z * i_s + (o << 8); 1760 n += basis.getNoiseWithSeed(xx + disturbance.getNoiseWithSeed(x, y, z, seed), yy, zz, seed) * s; 1761 } 1762 return n / ((1 << octaves) - 1.0); 1763 } 1764 } 1765 public static class Slick4D implements Noise4D { 1766 protected int octaves; 1767 protected Noise4D basis, disturbance; 1768 1769 public Slick4D() { 1770 this(SeededNoise.instance, alternate, 1); 1771 } 1772 1773 public Slick4D(Noise4D basis, Noise4D disturb) { 1774 this(basis, disturb, 1); 1775 } 1776 1777 public Slick4D(Noise4D basis, Noise4D disturb, final int octaves) { 1778 this.basis = basis; 1779 disturbance = disturb; 1780 this.octaves = Math.max(1, Math.min(63, octaves)); 1781 } 1782 1783 @Override 1784 public double getNoise(final double x, final double y, final double z, final double w) { 1785 double n = 0.0, i_s = 1.0, xx, yy, zz, ww; 1786 int s = 1 << (octaves - 1); 1787 for (int o = 0; o < octaves; o++, s >>= 1) { 1788 xx = x * (i_s *= 0.5) + (o << 6); 1789 yy = y * i_s + (o << 7); 1790 zz = z * i_s + (o << 8); 1791 ww = w * i_s + (o << 9); 1792 n += basis.getNoise(xx + disturbance.getNoise(x, y, z, w), yy, zz, ww) * s; 1793 } 1794 return n / ((1 << octaves) - 1.0); 1795 } 1796 1797 @Override 1798 public double getNoiseWithSeed(final double x, final double y, final double z, final double w, long seed) { 1799 double n = 0.0, i_s = 1.0, xx, yy, zz, ww; 1800 int s = 1 << (octaves - 1); 1801 for (int o = 0; o < octaves; o++, s >>= 1) { 1802 seed += 0x9E3779B97F4A7C15L; 1803 xx = x * (i_s *= 0.5) + (o << 6); 1804 yy = y * i_s + (o << 7); 1805 zz = z * i_s + (o << 8); 1806 ww = w * i_s + (o << 9); 1807 n += basis.getNoiseWithSeed(xx + disturbance.getNoiseWithSeed(x, y, z, w, seed), yy, zz, ww, seed) * s; 1808 } 1809 return n / ((1 << octaves) - 1.0); 1810 } 1811 } 1812 public static class Slick6D implements Noise6D { 1813 protected int octaves; 1814 protected Noise6D basis, disturbance; 1815 1816 public Slick6D() { 1817 this(SeededNoise.instance, alternate, 1); 1818 } 1819 1820 public Slick6D(Noise6D basis, Noise6D disturb) { 1821 this(basis, disturb, 1); 1822 } 1823 1824 public Slick6D(Noise6D basis, Noise6D disturb, final int octaves) { 1825 this.basis = basis; 1826 disturbance = disturb; 1827 this.octaves = Math.max(1, Math.min(63, octaves)); 1828 } 1829 1830 @Override 1831 public double getNoise(final double x, final double y, final double z, final double w, final double u, final double v) { 1832 double n = 0.0, i_s = 1.0, xx, yy, zz, ww, uu, vv; 1833 int s = 1 << (octaves - 1); 1834 for (int o = 0; o < octaves; o++, s >>= 1) { 1835 xx = x * (i_s *= 0.5) + (o << 6); 1836 yy = y * i_s + (o << 7); 1837 zz = z * i_s + (o << 8); 1838 ww = w * i_s + (o << 9); 1839 uu = u * i_s + (o << 10); 1840 vv = v * i_s + (o << 11); 1841 n += basis.getNoise(xx + disturbance.getNoise(x, y, z, w, u, v), yy, zz, ww, uu, vv) * s; 1842 } 1843 return n / ((1 << octaves) - 1.0); 1844 } 1845 1846 @Override 1847 public double getNoiseWithSeed(final double x, final double y, final double z, final double w, final double u, final double v, long seed) { 1848 double n = 0.0, i_s = 1.0, xx, yy, zz, ww, uu, vv; 1849 int s = 1 << (octaves - 1); 1850 for (int o = 0; o < octaves; o++, s >>= 1) { 1851 seed += 0x9E3779B97F4A7C15L; 1852 xx = x * (i_s *= 0.5) + (o << 6); 1853 yy = y * i_s + (o << 7); 1854 zz = z * i_s + (o << 8); 1855 ww = w * i_s + (o << 9); 1856 uu = u * i_s + (o << 10); 1857 vv = v * i_s + (o << 11); 1858 n += basis.getNoiseWithSeed(xx + disturbance.getNoiseWithSeed(x, y, z, w, u, v, seed), yy, zz, ww, uu, vv, seed) * s; 1859 } 1860 return n / ((1 << octaves) - 1.0); 1861 } 1862 } 1863 1864 1865 public static class Exponential1D implements Noise1D { 1866 protected Noise1D basis; 1867 protected double sharpness, adjustment; 1868 public Exponential1D() { 1869 this(Basic1D.instance); 1870 } 1871 1872 public Exponential1D(Noise1D basis) { 1873 this(basis, 0.125); 1874 } 1875 public Exponential1D(Noise1D basis, double sharpness) { 1876 this.basis = basis; 1877 this.sharpness = sharpness - fastFloor(sharpness) - 1.0; 1878 this.adjustment = 2.0 / Math.log1p(this.sharpness * 0.9999999999999999); 1879 this.sharpness *= 0.5; 1880 } 1881 1882 1883 @Override 1884 public double getNoise(double x) { 1885 return Math.log(1.0 + sharpness * (basis.getNoise(x) + 1.0)) * adjustment - 1.0; 1886 } 1887 1888 @Override 1889 public double getNoiseWithSeed(double x, long seed) { 1890 return Math.log(1.0 + sharpness * (basis.getNoiseWithSeed(x, seed) + 1.0)) * adjustment - 1.0; 1891 } 1892 } 1893 1894 public static class Exponential2D implements Noise2D { 1895 protected Noise2D basis; 1896 protected double sharpness, adjustment; 1897 public Exponential2D() { 1898 this(SeededNoise.instance); 1899 } 1900 1901 public Exponential2D(Noise2D basis) { 1902 this(basis, 0.125); 1903 } 1904 public Exponential2D(Noise2D basis, double sharpness) { 1905 this.basis = basis; 1906 this.sharpness = sharpness - fastFloor(sharpness) - 1.0; 1907 this.adjustment = 2.0 / Math.log1p(this.sharpness * 0.9999999999999999); 1908 this.sharpness *= 0.5; 1909 } 1910 1911 @Override 1912 public double getNoise(double x, double y) { 1913 return Math.log(1.0 + sharpness * (basis.getNoise(x, y) + 1.0)) * adjustment - 1.0; 1914 } 1915 1916 @Override 1917 public double getNoiseWithSeed(double x, double y, long seed) { 1918 return Math.log(1.0 + sharpness * (basis.getNoiseWithSeed(x, y, seed) + 1.0)) * adjustment - 1.0; 1919 } 1920 } 1921 public static class Exponential3D implements Noise3D { 1922 protected Noise3D basis; 1923 protected double sharpness, adjustment; 1924 public Exponential3D() { 1925 this(SeededNoise.instance); 1926 } 1927 1928 public Exponential3D(Noise3D basis) { 1929 this(basis, 0.125); 1930 } 1931 public Exponential3D(Noise3D basis, double sharpness) { 1932 this.basis = basis; 1933 this.sharpness = sharpness - fastFloor(sharpness) - 1.0; 1934 this.adjustment = 2.0 / Math.log1p(this.sharpness * 0.9999999999999999); 1935 this.sharpness *= 0.5; 1936 } 1937 1938 @Override 1939 public double getNoise(double x, double y, double z) { 1940 return Math.log(1.0 + sharpness * (basis.getNoise(x, y, z) + 1.0)) * adjustment - 1.0; 1941 } 1942 1943 @Override 1944 public double getNoiseWithSeed(double x, double y, double z, long seed) { 1945 return Math.log(1.0 + sharpness * (basis.getNoiseWithSeed(x, y, z, seed) + 1.0)) * adjustment - 1.0; 1946 } 1947 } 1948 public static class Exponential4D implements Noise4D { 1949 protected Noise4D basis; 1950 protected double sharpness, adjustment; 1951 public Exponential4D() { 1952 this(SeededNoise.instance); 1953 } 1954 1955 public Exponential4D(Noise4D basis) { 1956 this(basis, 0.125); 1957 } 1958 public Exponential4D(Noise4D basis, double sharpness) { 1959 this.basis = basis; 1960 this.sharpness = sharpness - fastFloor(sharpness) - 1.0; 1961 this.adjustment = 2.0 / Math.log1p(this.sharpness * 0.9999999999999999); 1962 this.sharpness *= 0.5; 1963 } 1964 1965 @Override 1966 public double getNoise(double x, double y, double z, double w) { 1967 return Math.log(1.0 + sharpness * (basis.getNoise(x, y, z, w) + 1.0)) * adjustment - 1.0; 1968 } 1969 1970 @Override 1971 public double getNoiseWithSeed(double x, double y, double z, double w, long seed) { 1972 return Math.log(1.0 + sharpness * (basis.getNoiseWithSeed(x, y, z, w, seed) + 1.0)) * adjustment - 1.0; 1973 } 1974 } 1975 public static class Exponential6D implements Noise6D { 1976 protected Noise6D basis; 1977 protected double sharpness, adjustment; 1978 public Exponential6D() { 1979 this(SeededNoise.instance); 1980 } 1981 1982 public Exponential6D(Noise6D basis) { 1983 this(basis, 0.125); 1984 } 1985 public Exponential6D(Noise6D basis, double sharpness) { 1986 this.basis = basis; 1987 this.sharpness = sharpness - fastFloor(sharpness) - 1.0; 1988 this.adjustment = 2.0 / Math.log1p(this.sharpness * 0.9999999999999999); 1989 this.sharpness *= 0.5; 1990 } 1991 1992 @Override 1993 public double getNoise(double x, double y, double z, double w, double u, double v) { 1994 return Math.log(1.0 + sharpness * (basis.getNoise(x, y, z, w, u, v) + 1.0)) * adjustment - 1.0; 1995 } 1996 1997 @Override 1998 public double getNoiseWithSeed(double x, double y, double z, double w, double u, double v, long seed) { 1999 return Math.log(1.0 + sharpness * (basis.getNoiseWithSeed(x, y, z, w, u, v, seed) + 1.0)) * adjustment - 1.0; 2000 } 2001 } 2002 2003 2004 /** 2005 * Produces a 2D array of noise with values from -1.0 to 1.0 that is seamless on all boundaries. 2006 * Uses (x,y) order. Allows a seed to change the generated noise. 2007 * If you need to call this very often, consider {@link #seamless2D(double[][], int, int)}, which re-uses the array. 2008 * @param width the width of the array to produce (the length of the outer layer of arrays) 2009 * @param height the height of the array to produce (the length of the inner arrays) 2010 * @param seed an int seed that affects the noise produced, with different seeds producing very different noise 2011 * @param octaves how many runs of differently sized and weighted noise generations to apply to the same area 2012 * @return a freshly-allocated seamless-bounded array, a {@code double[width][height]}. 2013 */ 2014 public static double[][] seamless2D(final int width, final int height, final int seed, final int octaves) { 2015 return seamless2D(new double[width][height], seed, octaves); 2016 } 2017 2018 /** 2019 * Fills the given 2D array (modifying it) with noise, using values from -1.0 to 1.0, that is seamless on all 2020 * boundaries. This overload doesn't care what you use for x or y axes, it uses the exact size of fill fully. 2021 * Allows a seed to change the generated noise. 2022 * @param fill a 2D array of double; must be rectangular, so it's a good idea to create with {@code new double[width][height]} or something similar 2023 * @param seed an int seed that affects the noise produced, with different seeds producing very different noise 2024 * @param octaves how many runs of differently sized and weighted noise generations to apply to the same area 2025 * @return {@code fill}, after assigning it with seamless-bounded noise 2026 */ 2027 public static double[][] seamless2D(final double[][] fill, final int seed, final int octaves) { 2028 return seamless2D(fill, seed, octaves, SeededNoise.instance); 2029 } 2030 2031 public static double total; 2032 /** 2033 * Fills the given 2D array (modifying it) with noise, using values from -1.0 to 1.0, that is seamless on all 2034 * boundaries. This overload doesn't care what you use for x or y axes, it uses the exact size of fill fully. 2035 * Allows a seed to change the generated noise. DOES NOT clear the values in fill, so if it already has non-zero 2036 * elements, the result will be different than if it had been cleared beforehand. That does allow you to utilize 2037 * this method to add multiple seamless noise values on top of each other, though that allows values to go above or 2038 * below the normal minimum and maximum (-1.0 to 1.0). 2039 * @param fill a 2D array of double; must be rectangular, so it's a good idea to create with {@code new double[width][height]} or something similar 2040 * @param seed an int seed that affects the noise produced, with different seeds producing very different noise 2041 * @param octaves how many runs of differently sized and weighted noise generations to apply to the same area 2042 * @return {@code fill}, after assigning it with seamless-bounded noise 2043 */ 2044 public static double[][] seamless2D(final double[][] fill, long seed, final int octaves, final Noise.Noise4D generator) { 2045 final int height, width; 2046 if (fill == null || (width = fill.length) <= 0 || (height = fill[0].length) <= 0 2047 || octaves <= 0 || octaves >= 63) 2048 return fill; 2049 final double i_w = 6.283185307179586 / width, i_h = 6.283185307179586 / height; 2050 int s = 1 << (octaves - 1); 2051 total = 0.0; 2052 double p, q, 2053 ps, pc, 2054 qs, qc, 2055 i_s = 0.5 / s; 2056 for (int o = 0; o < octaves; o++, s >>= 1) { 2057 seed += 0x9E3779B97F4A7C15L; 2058 i_s *= 2.0; 2059 for (int x = 0; x < width; x++) { 2060 p = x * i_w; 2061 ps = NumberTools.sin(p) * i_s; 2062 pc = NumberTools.cos(p) * i_s; 2063 for (int y = 0; y < height; y++) { 2064 q = y * i_h; 2065 qs = NumberTools.sin(q) * i_s; 2066 qc = NumberTools.cos(q) * i_s; 2067 fill[x][y] += generator.getNoiseWithSeed(pc, ps, qc, qs, seed) * s; 2068 } 2069 } 2070 } 2071 i_s = 1.0 / ((1 << octaves) - 1.0); 2072 for (int x = 0; x < width; x++) { 2073 for (int y = 0; y < height; y++) { 2074 total += (fill[x][y] *= i_s); 2075 } 2076 } 2077 return fill; 2078 } 2079 2080 /** 2081 * Produces a 3D array of noise with values from -1.0 to 1.0 that is seamless on all boundaries. 2082 * Allows a seed to change the generated noise. 2083 * Because most games that would use this would use it for maps, and maps are often top-down, the returned 3D array 2084 * uses the order (z,x,y), which allows a 2D slice of x and y to be taken as an element from the top-level array. 2085 * If you need to call this very often, consider {@link #seamless3D(double[][][], long, int)}, which re-uses the 2086 * array instead of re-generating it. 2087 * @param width the width of the array to produce (the length of the middle layer of arrays) 2088 * @param height the height of the array to produce (the length of the innermost arrays) 2089 * @param depth the depth of the array to produce (the length of the outermost layer of arrays) 2090 * @param seed an int seed that affects the noise produced, with different seeds producing very different noise 2091 * @param octaves how many runs of differently sized and weighted noise generations to apply to the same area 2092 * @return a freshly-allocated seamless-bounded array, a {@code double[depth][width][height]}. 2093 */ 2094 public static double[][][] seamless3D(final int depth, final int width, final int height, final long seed, final int octaves) { 2095 return seamless3D(new double[depth][width][height], seed, octaves); 2096 } 2097 2098 /** 2099 * Fills the given 3D array (modifying it) with noise, using values from -1.0 to 1.0, that is seamless on all 2100 * boundaries. This overload doesn't care what you use for x, y, or z axes, it uses the exact size of fill fully. 2101 * Allows a seed to change the generated noise. 2102 * @param fill a 3D array of double; must be rectangular, so it's a good idea to create with {@code new double[depth][width][height]} or something similar 2103 * @param seed an int seed that affects the noise produced, with different seeds producing very different noise 2104 * @param octaves how many runs of differently sized and weighted noise generations to apply to the same area 2105 * @return {@code fill}, after assigning it with seamless-bounded noise 2106 */ 2107 public static double[][][] seamless3D(final double[][][] fill, final long seed, final int octaves) { 2108 return seamless3D(fill, seed, octaves, SeededNoise.instance); 2109 } 2110 2111 /** 2112 * Fills the given 3D array (modifying it) with noise, using values from -1.0 to 1.0, that is seamless on all 2113 * boundaries. This overload doesn't care what you use for x, y, or z axes, it uses the exact size of fill fully. 2114 * Allows a seed to change the generated noise. 2115 * @param fill a 3D array of double; must be rectangular, so it's a good idea to create with {@code new double[depth][width][height]} or something similar 2116 * @param seed an int seed that affects the noise produced, with different seeds producing very different noise 2117 * @param octaves how many runs of differently sized and weighted noise generations to apply to the same area 2118 * @return {@code fill}, after assigning it with seamless-bounded noise 2119 */ 2120 public static double[][][] seamless3D(final double[][][] fill, long seed, final int octaves, final Noise.Noise6D generator) { 2121 final int depth, height, width; 2122 if(fill == null || (depth = fill.length) <= 0 || (width = fill[0].length) <= 0 || (height = fill[0][0].length) <= 0 2123 || octaves <= 0 || octaves >= 63) 2124 return fill; 2125 final double i_w = 6.283185307179586 / width, i_h = 6.283185307179586 / height, i_d = 6.283185307179586 / depth; 2126 int s = 1<<(octaves-1); 2127 total = 0.0; 2128 double p, q, r, 2129 ps, pc, 2130 qs, qc, 2131 rs, rc, i_s = 0.5 / s; 2132 for (int o = 0; o < octaves; o++, s>>=1) { 2133 seed += 0x9E3779B97F4A7C15L; 2134 i_s *= 2.0; 2135 for (int x = 0; x < width; x++) { 2136 p = x * i_w; 2137 ps = NumberTools.sin(p) * i_s; 2138 pc = NumberTools.cos(p) * i_s; 2139 for (int y = 0; y < height; y++) { 2140 q = y * i_h; 2141 qs = NumberTools.sin(q) * i_s; 2142 qc = NumberTools.cos(q) * i_s; 2143 for (int z = 0; z < depth; z++) { 2144 r = z * i_d; 2145 rs = NumberTools.sin(r) * i_s; 2146 rc = NumberTools.cos(r) * i_s; 2147 fill[z][x][y] += generator.getNoiseWithSeed(pc, ps, qc, qs, rc, rs, seed) * s; 2148 } 2149 } 2150 } 2151 } 2152 i_s = 1.0 / ((1<<octaves) - 1.0); 2153 for (int x = 0; x < width; x++) { 2154 for (int y = 0; y < height; y++) { 2155 for (int z = 0; z < depth; z++) { 2156 total += (fill[z][x][y] *= i_s); 2157 } 2158 } 2159 } 2160 return fill; 2161 } 2162 2163 /** 2164 * Fills the given 3D array (modifying it) with noise, using values from -1.0 to 1.0, that is seamless on all 2165 * boundaries. This overload doesn't care what you use for x, y, or z axes, it uses the exact size of fill fully. 2166 * Allows a seed to change the generated noise. 2167 * @param fill a 3D array of double; must be rectangular, so it's a good idea to create with {@code new double[depth][width][height]} or something similar 2168 * @param seed an int seed that affects the noise produced, with different seeds producing very different noise 2169 * @param octaves how many runs of differently sized and weighted noise generations to apply to the same area 2170 * @return {@code fill}, after assigning it with seamless-bounded noise 2171 */ 2172 public static float[][][] seamless3D(final float[][][] fill, long seed, final int octaves) { 2173 final int depth, height, width; 2174 if(fill == null || (depth = fill.length) <= 0 || (width = fill[0].length) <= 0 || (height = fill[0][0].length) <= 0 2175 || octaves <= 0 || octaves >= 63) 2176 return fill; 2177 final double i_w = 6.283185307179586 / width, i_h = 6.283185307179586 / height, i_d = 6.283185307179586 / depth; 2178 int s = 1<<(octaves-1); 2179 double p, q, r, 2180 ps, pc, 2181 qs, qc, 2182 rs, rc, i_s = 0.5 / s; 2183 for (int o = 0; o < octaves; o++, s>>=1) { 2184 seed += 0x9E3779B97F4A7C15L; 2185 i_s *= 2.0; 2186 for (int x = 0; x < width; x++) { 2187 p = x * i_w; 2188 ps = NumberTools.sin(p) * i_s; 2189 pc = NumberTools.cos(p) * i_s; 2190 for (int y = 0; y < height; y++) { 2191 q = y * i_h; 2192 qs = NumberTools.sin(q) * i_s; 2193 qc = NumberTools.cos(q) * i_s; 2194 for (int z = 0; z < depth; z++) { 2195 r = z * i_d; 2196 rs = NumberTools.sin(r) * i_s; 2197 rc = NumberTools.cos(r) * i_s; 2198 fill[z][x][y] += SeededNoise.noise(pc, ps, qc, qs, rc, rs, seed) * s; 2199 } 2200 } 2201 } 2202 } 2203 i_s = 1.0 / ((1<<octaves) - 1.0); 2204 for (int x = 0; x < width; x++) { 2205 for (int y = 0; y < height; y++) { 2206 for (int z = 0; z < depth; z++) { 2207 fill[z][x][y] *= i_s; 2208 } 2209 } 2210 } 2211 return fill; 2212 } 2213 2214 /** 2215 * Like {@link #seamless2D(double[][], long, int, Noise4D)}, but this produces 1D noise that "tiles" by repeating 2216 * its output every {@code sizeX} units that {@code x} increases or decreases by. This doesn't precalculate an 2217 * array, instead calculating just one value so that later calls with different x will tile seamlessly. 2218 * <br> 2219 * Internally, this just samples out of a circle from a source of 2D noise. 2220 * @param noise a Noise2D implementation such as a {@link SeededNoise} or {@link FastNoise} 2221 * @param x the x-coordinate to sample 2222 * @param sizeX the range of x to generate before repeating; must be greater than 0 2223 * @param seed the noise seed, as a long 2224 * @return continuous noise from -1.0 to 1.0, inclusive 2225 */ 2226 public static double seamless1D(Noise2D noise, double x, double sizeX, long seed) 2227 { 2228 x *= 6.283185307179586 / sizeX; 2229 return noise.getNoiseWithSeed(NumberTools.cos(x), NumberTools.sin(x), seed); 2230 } 2231 2232 /** 2233 * Like {@link #seamless2D(double[][], long, int, Noise4D)}, but this doesn't precalculate noise into an array, 2234 * instead calculating just one 2D point so that later calls with different x or y will tile seamlessly. 2235 * @param noise a Noise4D implementation such as a {@link SeededNoise} or {@link FastNoise} 2236 * @param x the x-coordinate to sample 2237 * @param y the y-coordinate to sample 2238 * @param sizeX the range of x to generate before repeating; must be greater than 0 2239 * @param sizeY the range of y to generate before repeating; must be greater than 0 2240 * @param seed the noise seed, as a long 2241 * @return continuous noise from -1.0 to 1.0, inclusive 2242 */ 2243 public static double seamless2D(Noise4D noise, double x, double y, double sizeX, double sizeY, long seed) 2244 { 2245 x *= 6.283185307179586 / sizeX; 2246 y *= 6.283185307179586 / sizeY; 2247 return noise.getNoiseWithSeed(NumberTools.cos(x), NumberTools.sin(x), NumberTools.cos(y), NumberTools.sin(y), 2248 seed); 2249 } 2250 2251 2252 /** 2253 * Like {@link #seamless3D(double[][][], long, int, Noise6D)}, but this doesn't precalculate noise into an array, 2254 * instead calculating just one 3D point so that later calls with different x, y, or z will tile seamlessly. 2255 * @param noise a Noise6D implementation such as a {@link SeededNoise} or {@link FastNoise} 2256 * @param x the x-coordinate to sample 2257 * @param y the y-coordinate to sample 2258 * @param z the z-coordinate to sample 2259 * @param sizeX the range of x to generate before repeating; must be greater than 0 2260 * @param sizeY the range of y to generate before repeating; must be greater than 0 2261 * @param sizeZ the range of z to generate before repeating; must be greater than 0 2262 * @param seed the noise seed, as a long 2263 * @return continuous noise from -1.0 to 1.0, inclusive 2264 */ 2265 public static double seamless3D(Noise6D noise, double x, double y, double z, double sizeX, double sizeY, double sizeZ, long seed) 2266 { 2267 x *= 6.283185307179586 / sizeX; 2268 y *= 6.283185307179586 / sizeY; 2269 z *= 6.283185307179586 / sizeZ; 2270 return noise.getNoiseWithSeed(NumberTools.cos(x), NumberTools.sin(x), NumberTools.cos(y), NumberTools.sin(y), 2271 NumberTools.cos(z), NumberTools.sin(z), seed); 2272 } 2273 2274 /** 2275 * A very simple 1D noise implementation, because a full-blown Perlin or Simplex noise implementation is probably 2276 * overkill for 1D noise. This does produce smoothly sloping lines, like Simplex noise does for higher dimensions. 2277 * The shape of the line varies over time, but <a href="https://i.imgur.com/83R3WLN.png">can look like this</a>. 2278 * If you give this a seed with {@link #getNoiseWithSeed(double, long)} instead of using {@link #getNoise(double)}, 2279 * it will use a small extra step to adjust the spacing of peaks and valleys based on the seed, so getNoiseWithSeed 2280 * is slower than getNoise. If you use any Noise classes like {@link Noise.Layered1D}, they should use a seed anyway 2281 * because different octaves won't have different enough shapes otherwise. 2282 */ 2283 public static class Basic1D implements Noise1D 2284 { 2285 public static final Basic1D instance = new Basic1D(); 2286 public double alter1, alter2, alter3, alter4; 2287 public long lastSeed; 2288 public Basic1D() 2289 { 2290 this(1L); 2291 } 2292 public Basic1D(long seed) 2293 { 2294 lastSeed = seed; 2295 alter1 = (DiverRNG.determine(seed) >> 11) * 0x1.8p-54; 2296 alter2 = (DiverRNG.determine(seed + 11111) >> 11) * 0x1p-53; 2297 alter3 = (DiverRNG.determine(seed + 22222) >> 11) * 0x1.8p-53; 2298 alter4 = (DiverRNG.determine(seed + 33333) >> 11) * 0x1p-52; 2299 } 2300 @Override 2301 public double getNoise(double x) { 2302 return (cubicSway(x * alter1) * 0.4375f + 2303 cubicSway(x * alter2) * 0.3125f + 2304 cubicSway(x * alter3) * 0.1875f + 2305 cubicSway(x * alter4) * 0.0625f); 2306 } 2307 2308 @Override 2309 public double getNoiseWithSeed(double x, long seed) { 2310 if(lastSeed != seed) 2311 { 2312 lastSeed = seed; 2313 alter1 = (DiverRNG.determine(seed) >> 11) * 0x1.8p-54; 2314 alter2 = (DiverRNG.determine(seed + 11111) >> 11) * 0x1p-53; 2315 alter3 = (DiverRNG.determine(seed + 22222) >> 11) * 0x1.8p-53; 2316 alter4 = (DiverRNG.determine(seed + 33333) >> 11) * 0x1p-52; 2317 } 2318 return (cubicSway(x * alter1) * 0.4375f + 2319 cubicSway(x * alter2) * 0.3125f + 2320 cubicSway(x * alter3) * 0.1875f + 2321 cubicSway(x * alter4) * 0.0625f); 2322 } 2323 public static double cubicSway(double value) 2324 { 2325 long floor = (value >= 0.0 ? (long) value : (long) value - 1L); 2326 value -= floor; 2327 floor = (-(floor & 1L) | 1L); 2328 return value * value * (3.0 - 2.0 * value) * (floor << 1) - floor; 2329 } 2330 2331 public static double noise(double x, long seed) { 2332 final double 2333 alter1 = (DiverRNG.determine(seed) >> 11) * 0x1.8p-54, 2334 alter2 = (DiverRNG.determine(seed + 11111) >> 11) * 0x1p-53, 2335 alter3 = (DiverRNG.determine(seed + 22222) >> 11) * 0x1.8p-53, 2336 alter4 = (DiverRNG.determine(seed + 33333) >> 11) * 0x1p-52; 2337 return (cubicSway(x * alter1) * 0.4375f + 2338 cubicSway(x * alter2) * 0.3125f + 2339 cubicSway(x * alter3) * 0.1875f + 2340 cubicSway(x * alter4) * 0.0625f); 2341 } 2342 } 2343 public static class Sway1D implements Noise1D 2344 { 2345 public static final Sway1D instance = new Sway1D(); 2346 public long seed; 2347 public Sway1D() 2348 { 2349 seed = 0L; 2350 } 2351 public Sway1D(long seed) 2352 { 2353 this.seed = seed; 2354 } 2355 2356 @Override 2357 public double getNoise(double x) { 2358 return NumberTools.swayRandomized(seed, x); 2359 } 2360 2361 @Override 2362 public double getNoiseWithSeed(double x, long seed) { 2363 return NumberTools.swayRandomized(seed, x); 2364 } 2365 } 2366 public static class Sway2D implements Noise2D 2367 { 2368 public static final Sway2D instance = new Sway2D(); 2369 public long seed; 2370 public Sway2D() 2371 { 2372 seed = 12345L; 2373 } 2374 public Sway2D(long seed) 2375 { 2376 this.seed = seed; 2377 } 2378 2379 @Override 2380 public double getNoise(double x, double y) { 2381 return getNoiseWithSeed(x, y, seed); 2382 } 2383 2384 @Override 2385 public double getNoiseWithSeed(double x, double y, long seed) { 2386// double xx = NumberTools.swayRandomized(seed - 0xC13FA9A902A6328FL, x + y) * 0.75, 2387// yy = NumberTools.swayRandomized(seed - 0xABC98388FB8FAC03L, y - x) * 0.75; 2388// return NumberTools.sway((NumberTools.swayRandomized(seed, x + yy) + 2389// NumberTools.swayRandomized(0x8CB92BA72F3D8DD7L - seed, y + xx)) * 1.25 + 0.5); 2390 2391// return NumberTools.swayRandomized(seed, 2392// (NumberTools.swayRandomized(seed + 0x8CB92BA72F3D8DD7L, (x + y)) 2393// + NumberTools.swayRandomized(seed + 0xC13FA9A902A6328FL, x * 0.5 - y * 1.5) 2394// + NumberTools.swayRandomized(seed + 0xABC98388FB8FAC03L, x * 1.5 - y * 0.5)) * 4.0); 2395 2396// double adjust0 = NumberTools.swayRandomized(seed + 0xC13FA9A902A6328FL, x * 1.75 + y * -0.25) + 1., 2397// adjust1 = NumberTools.swayRandomized(seed + 0x8CB92BA72F3D8DD7L, x * 0.25 + y * -1.75) + 1., 2398// adjust2 = NumberTools.swayRandomized(seed - 0x8CB92BA72F3D8DD7L, x + y) + 1.; 2399// return NumberTools.sway( 2400// (NumberTools.swayRandomized(seed + 0xC13FA9A902A6328FL, x * 1.5 + y * 0.5) * adjust0 2401// + NumberTools.swayRandomized(seed + 0xABC98388FB8FAC03L, x * 0.5 + y * 1.5) * adjust1 2402// + NumberTools.swayRandomized(seed + 0x8CB92BA72F3D8DD7L, x - y) * adjust2 2403// ) * 0.75 + 0.5); 2404 final long floorX = x >= 0.0 ? (long) x : (long) x - 1L, 2405 floorY = y >= 0.0 ? (long) y : (long) y - 1L; 2406// long seedX = seed * 0xC13FA9A902A6328FL + floorX * 0x91E10DA5C79E7B1DL, 2407// seedY = seed * 0x91E10DA5C79E7B1DL + floorY * 0xC13FA9A902A6328FL; 2408// final long startX = ((seedX ^ (seedX >>> 25)) * (seedX | 0xA529L)), 2409// endX = (((seedX += 0x91E10DA5C79E7B1DL) ^ (seedX >>> 25)) * (seedX | 0xA529L)); 2410// final long startY = ((seedY ^ (seedY >>> 25)) * (seedY | 0xA529L)), 2411// endY = (((seedY += 0xC13FA9A902A6328FL) ^ (seedY >>> 25)) * (seedY | 0xA529L)); 2412// final int x0y0 = (int) (startX + startY >>> 56), 2413// x1y0 = (int) (endX + startY >>> 56), 2414// x0y1 = (int) (startX + endY >>> 56), 2415// x1y1 = (int) (endX + endY >>> 56); 2416 final int x0y0 = HastyPointHash.hash256(floorX, floorY, seed), 2417 x1y0 = HastyPointHash.hash256(floorX+1, floorY, seed), 2418 x0y1 = HastyPointHash.hash256(floorX, floorY+1, seed), 2419 x1y1 = HastyPointHash.hash256(floorX+1, floorY+1, seed); 2420 x -= floorX; 2421 y -= floorY; 2422// x *= x * (3.0 - 2.0 * x); 2423// y *= y * (3.0 - 2.0 * y); 2424// x *= x; 2425// y *= y; 2426 final double ix = 1.0 - x, iy = 1.0 - y; 2427// final double ix = (1 - x) * (1 - x), iy = (1 - y) * (1 - y); 2428// final double ix = x, iy = y; 2429// x = 1.0 - x; 2430// y = 1.0 - y; 2431 // double ret = ((ix * SeededNoise.phiGrad2[x0y0][0] + iy * SeededNoise.phiGrad2[x0y0][1]) 2432// + (x * SeededNoise.phiGrad2[x1y0][0] + iy * SeededNoise.phiGrad2[x1y0][1]) 2433// + (ix * SeededNoise.phiGrad2[x0y1][0] + y * SeededNoise.phiGrad2[x0y1][1]) 2434// + (x * SeededNoise.phiGrad2[x1y1][0] + y * SeededNoise.phiGrad2[x1y1][1]) 2435// ); 2436 return ((SeededNoise.phiGrad2[x0y0][0] + SeededNoise.phiGrad2[x0y0][1]) * (ix * iy) 2437 + (SeededNoise.phiGrad2[x1y0][0] + SeededNoise.phiGrad2[x1y0][1]) * (x * iy) 2438 + (SeededNoise.phiGrad2[x0y1][0] + SeededNoise.phiGrad2[x0y1][1]) * (ix * y) 2439 + (SeededNoise.phiGrad2[x1y1][0] + SeededNoise.phiGrad2[x1y1][1]) * (x * y) 2440 ) * 0.7071067811865475; 2441// long xf = x >= 0.0 ? (long) x : (long) x - 1L; 2442// long yf = y >= 0.0 ? (long) y : (long) y - 1L; 2443// long s = ((0x91E10DA5C79E7B1DL ^ seed ^ yf)) * 0xC13FA9A902A6328FL, s2 = ((0x91E10DA5C79E7B1DL ^ seed ^ yf + 1L)) * 0xC13FA9A902A6328FL; 2444// double xSmall = x - xf; 2445// //, 0xABC98388FB8FAC03L, 0x8CB92BA72F3D8DD7L 2446// double start = (((s += xf * 0x6C8E9CF570932BD5L) ^ (s >>> 25)) * (s | 0xA529L)) * 0x0.fffffffffffffbp-63, 2447// start2 = (((s2 += xf * 0x6C8E9CF570932BD5L) ^ (s2 >>> 25)) * (s2 | 0xA529L)) * 0x0.fffffffffffffbp-63, 2448// end = (((s += 0x6C8E9CF570932BD5L) ^ (s >>> 25)) * (s | 0xA529L)) * 0x0.fffffffffffffbp-63, 2449// end2 = (((s2 += 0x6C8E9CF570932BD5L) ^ (s2 >>> 25)) * (s2 | 0xA529L)) * 0x0.fffffffffffffbp-63; 2450//// double x0y0 = HastyPointHash.hashAll(xf, yf, seed) * 0x0.fffffffffffffbp-63, 2451//// x1y0 = HastyPointHash.hashAll(xf+1L, yf, seed) * 0x0.fffffffffffffbp-63, 2452//// x0y1 = HastyPointHash.hashAll(xf, yf+1L, seed) * 0x0.fffffffffffffbp-63, 2453//// x1y1 = HastyPointHash.hashAll(xf+1L, yf+1L, seed) * 0x0.fffffffffffffbp-63, y0, y1; 2454// xSmall = xSmall * xSmall * (3.0 - 2.0 * xSmall); 2455//// double a2 = xSmall * xSmall, a4 = a2 * a2, a6 = a4 * a2; 2456//// xSmall = 0x1.c71c71c71c71cp-2 * a6 + -0x1.e38e38e38e38ep0 * a4 + 0x1.38e38e38e38e4p1 * a2; 2457//// y0 = (1.0 - xSmall) * x0y0 + xSmall * x1y0; 2458//// y1 = (1.0 - xSmall) * x0y1 + xSmall * x1y1; 2459// double ySmall = y - yf; 2460// ySmall = ySmall * ySmall * (3.0 - 2.0 * ySmall); 2461//// a2 = ySmall * ySmall; 2462//// a4 = a2 * a2; 2463//// a6 = a4 * a2; 2464//// ySmall = 0x1.c71c71c71c71cp-2 * a6 + -0x1.e38e38e38e38ep0 * a4 + 0x1.38e38e38e38e4p1 * a2; 2465// return (1.0 - ySmall) * ((1.0 - xSmall) * start + xSmall * end) + ySmall * ((1.0 - xSmall) * start2 + xSmall * end2); 2466//// x1 = (1.0 - xSmall) * start2 + xSmall * end2; 2467//// s = HastyPointHash.hashAll(xf, yf, seed);//((0xC13FA9A902A6328FL ^ seed)) * 0x91E10DA5C79E7B1DL; 2468//// start = (((s += yf * 0x6C8E9CF570932BD5L) ^ (s >>> 25)) * (s | 0xA529L)) * 0x0.fffffffffffffbp-63; 2469////// start2 = (((s2 = s * 0xD1B54A32D192ED03L) ^ (s2 >>> 25)) * (s2 | 0xA529L)) * 0x0.fffffffffffffbp-63; 2470//// end = (((s += 0x6C8E9CF570932BD5L) ^ (s >>> 25)) * (s | 0xA529L)) * 0x0.fffffffffffffbp-63; 2471////// end2 = (((s2 = s * 0xD1B54A32D192ED03L) ^ (s2 >>> 25)) * (s2 | 0xA529L)) * 0x0.fffffffffffffbp-63; 2472//// y0 = (1.0 - ySmall) * start + ySmall * end; 2473////// y1 = (1.0 - ySmall) * start2 + ySmall * end2; 2474//// return NumberTools.sway(x0 + y0 + 0.5); 2475 } 2476 } 2477 2478 /** 2479 * A hybrid between value and gradient noise that may be faster for 1D noise. Every integer value of x given to this 2480 * will produce a result of 0. This only hashes one coordinate per noise call, unlike most value noise that needs 2 2481 * hashes in 1D and many more in higher dimensions. Based on <a href="https://www.shadertoy.com/view/3sd3Rs">Inigo 2482 * Quilez' "Basic Noise"</a>. 2483 */ 2484 public static class QuilezNoise implements Noise1D, Noise2D { 2485 2486 public long seed; 2487 public QuilezNoise() { 2488 this(0xB0BAFE77L); 2489 } 2490 2491 public QuilezNoise(long seed) { 2492 this.seed = seed; 2493 } 2494 @Override 2495 public double getNoise(double x) { 2496 return getNoiseWithSeed(x, seed); 2497 } 2498// xFloor = (xFloor ^ xFloor << 7 ^ 0x9E3779B97F4A7C15L) * 0xD1B54A32D192ED03L; 2499// xFloor = (xFloor ^ xFloor >>> 41 ^ xFloor >>> 23) * (xFloor ^ xFloor >> 25 | 1) >>> 32; 2500// final double h = xFloor * 0x1p-28 - 4.0; 2501// seed = (seed ^ xFloor ^ 0x9E3779B97F4A7C15L) * 0xD1B54A32D192ED03L; // XLCG, helps randomize upper bits 2502// // this next 'h' part finishes randomizing (not amazing quality, but fast), uses only the upper bits, 2503// // and reduces it to a double between -8.0 and almost 8.0. 2504// final double h = ((seed ^ seed >>> 26) * (seed | 0xA529) >>> 32) * 0x1p-28 - 8.0; 2505 2506 @Override 2507 public double getNoiseWithSeed(double x, final long seed) { 2508 x += ((seed & 0xFFFFFFFFL) ^ (seed >>> 32)) * 0x1p-24; // offset x by between 0.0 and almost 256.0 2509 final long xFloor = x >= 0.0 ? (long) x : (long) x - 1, // floor of x as a long 2510 rise = 1L - ((x >= 0.0 ? (long) (x * 2.0) : (long) (x * 2.0) - 1) & 2L); // either 1 or -1 2511 x -= xFloor; 2512 // and now we flip the switch from "magic" to "more magic..." 2513 // this directly sets the bits that describe a double. this might seem like it should be slow; it is not. 2514 // seed and xFloor are XORed to roughly mix them together; adding would work too probably. 2515 // the two huge longs don't really matter except for their last digits: 2516 // the one that uses ^ must end in 5 or D (both hex) 2517 // the one that uses * must end in 3 or B (both hex) 2518 // and that makes this a valid "XLCG," a cousin of the commonly used LCG random number generator. 2519 // it improves the randomness in the upper bits more than the lower ones, where the upper bits will become 2520 // more significant decimal places in the resulting double. 2521 // we unsigned-right-shift by 12, which puts the random bits all in the double's mantissa (which is how far 2522 // it is between the previous power of two and next power of two, roughly). 2523 // we bitwise OR with 0x4030000000000000L, which is the exponent section for a double between 16.0 and 32.0. 2524 // we work our magic and convert the bits to double. 2525 // subtracting 24.0 takes the range to -4.0 to 12.0, where we want it (Quilez used this). 2526 final double h = NumberTools.longBitsToDouble((seed ^ xFloor ^ 0x9E3779B97F4A7C15L) * 0xD1B54A32D192ED03L >>> 12 | 2527 0x4040000000000000L) - 52.0; 2528// 0x4030000000000000L) - 20.0; 2529 // Quilez' quartic curve; uses the "rise" calculated earlier to determine if this is on the rising or 2530 // the falling side. Uses that complicated "h" as the height of the peak or valley in the middle. 2531 return rise * x * (x - 1.0) * (h * x * (x - 1.0) - 1.0); 2532 } 2533 2534 @Override 2535 public double getNoise(double x, double y) { 2536 return getNoiseWithSeed(x, y, seed); 2537 } 2538 2539 @Override 2540 public double getNoiseWithSeed(double x, double y, long seed) { 2541 double n = 0.0; 2542 for (int i = 0; i < 4; i++) { 2543 seed += 0x9E3779B97F4A7C15L; 2544 double xEdit = x += (((seed & 0x55555555L) | (seed >>> 32 & 0xAAAAAAAAL))) * 0x1p-29 + 0.5698402909980532; 2545 double yEdit = y += (((seed & 0xAAAAAAAAL) | (seed >>> 32 & 0x55555555L))) * 0x1p-29 + 0.7548776662466927; 2546 final long 2547 xFloor = xEdit >= 0.0 ? (long) xEdit : (long) xEdit - 1, 2548 yFloor = yEdit >= 0.0 ? (long) yEdit : (long) yEdit - 1; 2549 xEdit -= xFloor; 2550 yEdit -= yFloor; 2551 xEdit *= (xEdit - 1.0); 2552 yEdit *= (yEdit - 1.0); 2553 final double m = (xEdit + yEdit) * 0.5; 2554 final double h = NumberTools.longBitsToDouble(HastyPointHash.hashAll(xFloor, yFloor, seed) >>> 12 | 0x4040000000000000L) - 52.0; 2555// final double i = NumberTools.longBitsToDouble((~seed + yFloor ^ 0x9E3779B97F4A7C15L) * 0xD1B54A32D192ED03L >>> 12 | 0x4030000000000000L) - 24.0; 2556 n += (m * (h * m - 1.0)); 2557 } 2558 return n * 0.25; 2559//// cerp( 2560// 0.5 * ( 2561// (xRise * m * (h * m - 1.0)) + 2562// (yRise * m * (i * m - 1.0)) 2563// ); 2564// //, 0.5 + (y - x) * 0.5); 2565 } 2566 2567 } 2568}