1 18 19 package org.apache.batik.ext.awt.image.rendered; 20 21 import java.awt.Rectangle ; 22 import java.awt.color.ColorSpace ; 23 import java.awt.geom.AffineTransform ; 24 import java.awt.geom.Rectangle2D ; 25 import java.awt.image.ColorModel ; 26 import java.awt.image.DataBuffer ; 27 import java.awt.image.DataBufferInt ; 28 import java.awt.image.DirectColorModel ; 29 import java.awt.image.SinglePixelPackedSampleModel ; 30 import java.awt.image.WritableRaster ; 31 63 public final class TurbulencePatternRed extends AbstractRed { 64 68 static final class StitchInfo { 69 72 int width; 73 74 77 int height; 78 79 84 int wrapX; 85 86 91 int wrapY; 92 93 96 StitchInfo(){ 97 } 98 99 102 StitchInfo(StitchInfo stitchInfo){ 103 this.width = stitchInfo.width; 104 this.height = stitchInfo.height; 105 this.wrapX = stitchInfo.wrapX; 106 this.wrapY = stitchInfo.wrapY; 107 } 108 109 final void assign(StitchInfo stitchInfo) { 110 this.width = stitchInfo.width; 111 this.height = stitchInfo.height; 112 this.wrapX = stitchInfo.wrapX; 113 this.wrapY = stitchInfo.wrapY; 114 } 115 116 127 final void doubleFrequency(){ 128 width *= 2; 129 height *= 2; 130 wrapX *= 2; 131 wrapY *= 2; 132 wrapX -= PerlinN; 133 wrapY -= PerlinN; 134 } 135 } 136 137 140 private StitchInfo stitchInfo = null; 141 142 146 private static final AffineTransform IDENTITY = new AffineTransform (); 147 148 151 private double baseFrequencyX; 152 153 156 private double baseFrequencyY; 157 158 161 private int numOctaves; 162 163 166 private int seed; 167 168 174 private Rectangle2D tile; 175 176 179 private AffineTransform txf; 180 181 184 private boolean isFractalNoise; 185 186 189 private int channels[]; 190 191 double tx[] = {1, 0}; 195 double ty[] = {0, 1}; 196 197 205 private static final int RAND_m = 2147483647; 206 private static final int RAND_a = 16807; 207 private static final int RAND_q = 127773; 208 private static final int RAND_r = 2836; 209 210 private static final int BSize = 0x100; 211 private static final int BM = 0xff; 212 private static final double PerlinN = 0x1000; 213 private static final int NP = 12 ; 214 private static final int NM = 0xfff; 215 private final int latticeSelector[] = new int[BSize + 1]; 216 private final double gradient[] = new double[(BSize+1)*8]; 217 218 public double getBaseFrequencyX(){ 219 return baseFrequencyX; 220 } 221 222 public double getBaseFrequencyY(){ 223 return baseFrequencyY; 224 } 225 226 public int getNumOctaves(){ 227 return numOctaves; 228 } 229 230 public int getSeed(){ 231 return seed; 232 } 233 234 public Rectangle2D getTile(){ 235 return (Rectangle2D )tile.clone(); 236 } 237 238 public boolean isFractalNoise(){ 239 return isFractalNoise; 240 } 241 242 public boolean[] getChannels(){ 243 boolean channels[] = new boolean[4]; 244 for(int i=0; i<this.channels.length; i++) 245 channels[this.channels[i]] = true; 246 247 return channels; 248 } 249 250 public final int setupSeed(int seed) { 251 if (seed <= 0) seed = -(seed % (RAND_m - 1)) + 1; 252 if (seed > RAND_m - 1) seed = RAND_m - 1; 253 return seed; 254 } 255 256 public final int random(int seed) { 257 int result = RAND_a * (seed % RAND_q) - RAND_r * (seed / RAND_q); 258 if (result <= 0) result += RAND_m; 259 return result; 260 } 261 262 private void initLattice(int seed) { 263 double u, v, s; 264 int i, j, k, s1, s2; 265 seed = setupSeed(seed); 266 267 for(k = 0; k < 4; k++){ 268 for(i = 0; i < BSize; i++){ 269 u = (((seed = random(seed)) % (BSize + BSize)) - BSize); 270 v = (((seed = random(seed)) % (BSize + BSize)) - BSize); 271 272 s = 1/Math.sqrt(u*u + v*v); 273 gradient[i*8 + k*2 ] = u*s; 274 gradient[i*8 + k*2 + 1] = v*s; 275 } 276 } 277 278 for(i = 0; i < BSize; i++) 279 latticeSelector[i] = i; 280 281 while(--i > 0){ 282 k = latticeSelector[i]; 283 j = (seed = random(seed)) % BSize; 284 latticeSelector[i] = latticeSelector[j]; 285 latticeSelector[j] = k; 286 287 s1 = i<<3; 290 s2 = j<<3; 291 for (j=0; j<8; j++) { 292 s = gradient[s1+j]; 293 gradient[s1+j] = gradient[s2+j]; 294 gradient[s2+j] = s; 295 } 296 } 297 latticeSelector[BSize] = latticeSelector[0]; 298 for (j=0; j<8; j++) 299 gradient[(BSize*8)+j] = gradient[j]; 300 } 301 302 303 private static final double s_curve(final double t) { 304 return (t * t * (3 - 2 * t) ); 305 } 306 307 private static final double lerp(double t, double a, double b) { 308 return ( a + t * (b - a) ); 309 } 310 311 319 private final void noise2(final double noise[], double vec0, double vec1) { 320 int b0, b1; 321 final int i, j; 322 final double rx0, rx1, ry0, ry1, sx, sy; 323 324 vec0 += PerlinN; 325 b0 = ((int)vec0)&BM; 326 327 i = latticeSelector[b0]; 328 j = latticeSelector[b0+1]; 329 330 rx0 = vec0 - (int)vec0; 331 rx1 = rx0 - 1.0; 332 sx = s_curve(rx0); 333 334 vec1 += PerlinN; 335 b0 = (int)vec1; 336 337 b1 = ((j + b0)&BM)<<3; 340 b0 = ((i + b0)&BM)<<3; 341 342 ry0 = vec1 - (int)vec1; 343 ry1 = ry0 - 1.0; 344 sy = s_curve(ry0); 345 346 switch (channels.length) { 347 case 4: 349 noise[3] = 350 lerp(sy, 351 lerp(sx, 352 rx0*gradient[b0+6] + ry0*gradient[b0+7], 353 rx1*gradient[b1+6] + ry0*gradient[b1+7]), 354 lerp(sx, 355 rx0*gradient[b0+8+6] + ry1*gradient[b0+8+7], 356 rx1*gradient[b1+8+6] + ry1*gradient[b1+8+7])); 357 case 3: 358 noise[2] = 359 lerp(sy, 360 lerp(sx, 361 rx0*gradient[b0+4] + ry0*gradient[b0+5], 362 rx1*gradient[b1+4] + ry0*gradient[b1+5]), 363 lerp(sx, 364 rx0*gradient[b0+8+4] + ry1*gradient[b0+8+5], 365 rx1*gradient[b1+8+4] + ry1*gradient[b1+8+5])); 366 case 2: 367 noise[1] = 368 lerp(sy, 369 lerp(sx, 370 rx0*gradient[b0+2] + ry0*gradient[b0+3], 371 rx1*gradient[b1+2] + ry0*gradient[b1+3]), 372 lerp(sx, 373 rx0*gradient[b0+8+2] + ry1*gradient[b0+8+3], 374 rx1*gradient[b1+8+2] + ry1*gradient[b1+8+3])); 375 case 1: 376 noise[0] = 377 lerp(sy, 378 lerp(sx, 379 rx0*gradient[b0+0] + ry0*gradient[b0+1], 380 rx1*gradient[b1+0] + ry0*gradient[b1+1]), 381 lerp(sx, 382 rx0*gradient[b0+8+0] + ry1*gradient[b0+8+1], 383 rx1*gradient[b1+8+0] + ry1*gradient[b1+8+1])); 384 } 385 } 386 387 397 private final void noise2Stitch(final double noise[], 398 final double vec0, final double vec1, 399 final StitchInfo stitchInfo){ 400 int b0, b1; 401 final int i, j, b00, b10, b01, b11; 402 double t; 403 final double rx0, rx1, ry0, ry1, sx, sy; 404 405 t = vec0 + PerlinN; 406 b0 = ((int)t); 407 b1 = b0+1; 408 if (b1 >= stitchInfo.wrapX) { 410 if (b0 >= stitchInfo.wrapX) { 411 b0 -= stitchInfo.width; 412 b1 -= stitchInfo.width; 413 } else { 414 b1 -= stitchInfo.width; 415 } 416 } 417 i = latticeSelector[b0&BM]; 418 j = latticeSelector[b1&BM]; 419 420 rx0 = t - (int)t; 421 rx1 = rx0 - 1.0; 422 sx = s_curve(rx0); 423 424 t = vec1 + PerlinN; 425 b0 = ((int)t); 426 b1 = b0+1; 427 if (b1 >= stitchInfo.wrapY) { 429 if (b0 >= stitchInfo.wrapY) { 430 b0 -= stitchInfo.height; 431 b1 -= stitchInfo.height; 432 } else { 433 b1 -= stitchInfo.height; 434 } 435 } 436 b00 = ((i + b0)&BM)<<3; 441 b10 = ((j + b0)&BM)<<3; 442 b01 = ((i + b1)&BM)<<3; 443 b11 = ((j + b1)&BM)<<3; 444 445 ry0 = t - (int)t; 446 ry1 = ry0 - 1.0; 447 sy = s_curve(ry0); 448 449 switch (channels.length) { 450 case 4: 452 noise[3] = 453 lerp(sy, 454 lerp(sx, 455 rx0*gradient[b00+6] + ry0*gradient[b00+7], 456 rx1*gradient[b10+6] + ry0*gradient[b10+7]), 457 lerp(sx, 458 rx0*gradient[b01+6] + ry1*gradient[b01+7], 459 rx1*gradient[b11+6] + ry1*gradient[b11+7])); 460 case 3: 461 noise[2] = 462 lerp(sy, 463 lerp(sx, 464 rx0*gradient[b00+4] + ry0*gradient[b00+5], 465 rx1*gradient[b10+4] + ry0*gradient[b10+5]), 466 lerp(sx, 467 rx0*gradient[b01+4] + ry1*gradient[b01+5], 468 rx1*gradient[b11+4] + ry1*gradient[b11+5])); 469 case 2: 470 noise[1] = 471 lerp(sy, 472 lerp(sx, 473 rx0*gradient[b00+2] + ry0*gradient[b00+3], 474 rx1*gradient[b10+2] + ry0*gradient[b10+3]), 475 lerp(sx, 476 rx0*gradient[b01+2] + ry1*gradient[b01+3], 477 rx1*gradient[b11+2] + ry1*gradient[b11+3])); 478 case 1: 479 noise[0] = 480 lerp(sy, 481 lerp(sx, 482 rx0*gradient[b00+0] + ry0*gradient[b00+1], 483 rx1*gradient[b10+0] + ry0*gradient[b10+1]), 484 lerp(sx, 485 rx0*gradient[b01+0] + ry1*gradient[b01+1], 486 rx1*gradient[b11+0] + ry1*gradient[b11+1])); 487 } 488 } 489 490 499 private final int turbulence_4(double pointX, 500 double pointY, 501 final double fSum[]) { 502 double n, ratio = 255; 503 int i, j, b0, b1, nOctave; 504 double px, py, rx0, rx1, ry0, ry1, sx, sy; 505 506 pointX *= baseFrequencyX; 507 pointY *= baseFrequencyY; 508 fSum[0] = fSum[1] = fSum[2] = fSum[3] = 0; 509 510 for (nOctave = numOctaves; nOctave > 0; nOctave--){ 511 px = pointX+PerlinN; 512 513 b0 = ((int)px)&BM; 514 i = latticeSelector[b0 ]; 515 j = latticeSelector[b0+1]; 516 517 rx0 = px - (int)px; 518 rx1 = rx0 - 1.0; 519 sx = s_curve(rx0); 520 521 py = pointY+PerlinN; 522 b0 = ((int)py) & BM; 523 b1 = (b0+1) & BM; 524 525 b1 = ((j + b0)&BM)<<3; 526 b0 = ((i + b0)&BM)<<3; 527 528 ry0 = py - (int)py; 529 ry1 = ry0 - 1.0; 530 sy = s_curve(ry0); 531 532 n = lerp(sy, 533 lerp(sx, 534 rx0*gradient[b0+0] + ry0*gradient[b0+1], 535 rx1*gradient[b1+0] + ry0*gradient[b1+1]), 536 lerp(sx, 537 rx0*gradient[b0+8+0] + ry1*gradient[b0+8+1], 538 rx1*gradient[b1+8+0] + ry1*gradient[b1+8+1])); 539 540 if (n<0) fSum[0] -= (n * ratio); 541 else fSum[0] += (n * ratio); 542 543 n = lerp(sy, 544 lerp(sx, 545 rx0*gradient[b0+2] + ry0*gradient[b0+3], 546 rx1*gradient[b1+2] + ry0*gradient[b1+3]), 547 lerp(sx, 548 rx0*gradient[b0+8+2] + ry1*gradient[b0+8+3], 549 rx1*gradient[b1+8+2] + ry1*gradient[b1+8+3])); 550 551 if (n<0) fSum[1] -= (n * ratio); 552 else fSum[1] += (n * ratio); 553 554 n = lerp(sy, 555 lerp(sx, 556 rx0*gradient[b0+4] + ry0*gradient[b0+5], 557 rx1*gradient[b1+4] + ry0*gradient[b1+5]), 558 lerp(sx, 559 rx0*gradient[b0+8+4] + ry1*gradient[b0+8+5], 560 rx1*gradient[b1+8+4] + ry1*gradient[b1+8+5])); 561 562 if (n<0) fSum[2] -= (n * ratio); 563 else fSum[2] += (n * ratio); 564 565 n = lerp(sy, 566 lerp(sx, 567 rx0*gradient[b0+6] + ry0*gradient[b0+7], 568 rx1*gradient[b1+6] + ry0*gradient[b1+7]), 569 lerp(sx, 570 rx0*gradient[b0+8+6] + ry1*gradient[b0+8+7], 571 rx1*gradient[b1+8+6] + ry1*gradient[b1+8+7])); 572 if (n<0) fSum[3] -= (n * ratio); 573 else fSum[3] += (n * ratio); 574 575 ratio *= .5; 576 pointX *= 2; 577 pointY *= 2; 578 } 579 580 i = (int)fSum[0]; 581 if ((i & 0xFFFFFF00) == 0) j = i<<16; 582 else j = ((i & 0x80000000) != 0)?0:0xFF0000; 583 584 i = (int)fSum[1]; 585 if ((i & 0xFFFFFF00) == 0) j |= i<<8; 586 else j |= ((i & 0x80000000) != 0)?0:0xFF00; 587 588 i = (int)fSum[2]; 589 if ((i & 0xFFFFFF00) == 0) j |= i; 590 else j |= ((i & 0x80000000) != 0)?0:0xFF; 591 592 i = (int)fSum[3]; 593 if ((i & 0xFFFFFF00) == 0) j |= i<<24; 594 else j |= ((i & 0x80000000) != 0)?0:0xFF000000; 595 return j; 596 } 597 598 599 608 private final void turbulence(final int rgb[], 609 double pointX, 610 double pointY, 611 final double fSum[], 612 final double noise[]) { 613 fSum[0] = fSum[1] = fSum[2] = fSum[3] = 0; 614 double ratio = 255; 615 pointX *= baseFrequencyX; 616 pointY *= baseFrequencyY; 617 switch (channels.length) { 618 case 4: 619 for(int nOctave = 0; nOctave < numOctaves; nOctave++){ 620 noise2(noise, pointX, pointY); 621 622 if (noise[0]<0) fSum[0] -= (noise[0] * ratio); 623 else fSum[0] += (noise[0] * ratio); 624 if (noise[1]<0) fSum[1] -= (noise[1] * ratio); 625 else fSum[1] += (noise[1] * ratio); 626 if (noise[2]<0) fSum[2] -= (noise[2] * ratio); 627 else fSum[2] += (noise[2] * ratio); 628 if (noise[3]<0) fSum[3] -= (noise[3] * ratio); 629 else fSum[3] += (noise[3] * ratio); 630 ratio *= .5; 631 pointX *= 2; 632 pointY *= 2; 633 } 634 635 rgb[0] = (int)fSum[0]; 636 if ((rgb[0] & 0xFFFFFF00) != 0) 637 rgb[0] = ((rgb[0] & 0x80000000) != 0)?0:255; 638 rgb[1] = (int)fSum[1]; 639 if ((rgb[1] & 0xFFFFFF00) != 0) 640 rgb[1] = ((rgb[1] & 0x80000000) != 0)?0:255; 641 rgb[2] = (int)fSum[2]; 642 if ((rgb[2] & 0xFFFFFF00) != 0) 643 rgb[2] = ((rgb[2] & 0x80000000) != 0)?0:255; 644 rgb[3] = (int)fSum[3]; 645 if ((rgb[3] & 0xFFFFFF00) != 0) 646 rgb[3] = ((rgb[3] & 0x80000000) != 0)?0:255; 647 break; 648 case 3: 649 for(int nOctave = 0; nOctave < numOctaves; nOctave++){ 650 noise2(noise, pointX, pointY); 651 652 if (noise[2]<0) fSum[2] -= (noise[2] * ratio); 653 else fSum[2] += (noise[2] * ratio); 654 if (noise[1]<0) fSum[1] -= (noise[1] * ratio); 655 else fSum[1] += (noise[1] * ratio); 656 if (noise[0]<0) fSum[0] -= (noise[0] * ratio); 657 else fSum[0] += (noise[0] * ratio); 658 ratio *= .5; 659 pointX *= 2; 660 pointY *= 2; 661 } 662 rgb[2] = (int)fSum[2]; 663 if ((rgb[2] & 0xFFFFFF00) != 0) 664 rgb[2] = ((rgb[2] & 0x80000000) != 0)?0:255; 665 rgb[1] = (int)fSum[1]; 666 if ((rgb[1] & 0xFFFFFF00) != 0) 667 rgb[1] = ((rgb[1] & 0x80000000) != 0)?0:255; 668 rgb[0] = (int)fSum[0]; 669 if ((rgb[0] & 0xFFFFFF00) != 0) 670 rgb[0] = ((rgb[0] & 0x80000000) != 0)?0:255; 671 break; 672 case 2: 673 for(int nOctave = 0; nOctave < numOctaves; nOctave++){ 674 noise2(noise, pointX, pointY); 675 676 if (noise[1]<0) fSum[1] -= (noise[1] * ratio); 677 else fSum[1] += (noise[1] * ratio); 678 if (noise[0]<0) fSum[0] -= (noise[0] * ratio); 679 else fSum[0] += (noise[0] * ratio); 680 ratio *= .5; 681 pointX *= 2; 682 pointY *= 2; 683 } 684 685 rgb[1] = (int)fSum[1]; 686 if ((rgb[1] & 0xFFFFFF00) != 0) 687 rgb[1] = ((rgb[1] & 0x80000000) != 0)?0:255; 688 rgb[0] = (int)fSum[0]; 689 if ((rgb[0] & 0xFFFFFF00) != 0) 690 rgb[0] = ((rgb[0] & 0x80000000) != 0)?0:255; 691 break; 692 case 1: 693 for(int nOctave = 0; nOctave < numOctaves; nOctave++){ 694 noise2(noise, pointX, pointY); 695 696 if (noise[0]<0) fSum[0] -= (noise[0] * ratio); 697 else fSum[0] += (noise[0] * ratio); 698 ratio *= .5; 699 pointX *= 2; 700 pointY *= 2; 701 } 702 703 rgb[0] = (int)fSum[0]; 704 if ((rgb[0] & 0xFFFFFF00) != 0) 705 rgb[0] = ((rgb[0] & 0x80000000) != 0)?0:255; 706 break; 707 } 708 } 709 710 720 private final void turbulenceStitch(final int rgb[], 721 double pointX, double pointY, 722 final double fSum[], 723 final double noise[], 724 StitchInfo stitchInfo){ 725 double ratio = 1; 726 pointX *= baseFrequencyX; 727 pointY *= baseFrequencyY; 728 fSum[0] = fSum[1] = fSum[2] = fSum[3] = 0; 729 switch (channels.length) { 730 case 4: 731 for(int nOctave = 0; nOctave < numOctaves; nOctave++){ 732 noise2Stitch(noise, pointX, pointY, stitchInfo); 733 734 if (noise[3]<0) fSum[3] -= (noise[3] * ratio); 735 else fSum[3] += (noise[3] * ratio); 736 if (noise[2]<0) fSum[2] -= (noise[2] * ratio); 737 else fSum[2] += (noise[2] * ratio); 738 if (noise[1]<0) fSum[1] -= (noise[1] * ratio); 739 else fSum[1] += (noise[1] * ratio); 740 if (noise[0]<0) fSum[0] -= (noise[0] * ratio); 741 else fSum[0] += (noise[0] * ratio); 742 ratio *= .5; 743 pointX *= 2; 744 pointY *= 2; 745 746 stitchInfo.doubleFrequency(); 747 } 748 rgb[3] = (int)(fSum[3] * 255); 749 if ((rgb[3] & 0xFFFFFF00) != 0) 750 rgb[3] = ((rgb[3] & 0x80000000) != 0)?0:255; 751 rgb[2] = (int)(fSum[2] * 255); 752 if ((rgb[2] & 0xFFFFFF00) != 0) 753 rgb[2] = ((rgb[2] & 0x80000000) != 0)?0:255; 754 rgb[1] = (int)(fSum[1] * 255); 755 if ((rgb[1] & 0xFFFFFF00) != 0) 756 rgb[1] = ((rgb[1] & 0x80000000) != 0)?0:255; 757 rgb[0] = (int)(fSum[0] * 255); 758 if ((rgb[0] & 0xFFFFFF00) != 0) 759 rgb[0] = ((rgb[0] & 0x80000000) != 0)?0:255; 760 break; 761 case 3: 762 for(int nOctave = 0; nOctave < numOctaves; nOctave++){ 763 noise2Stitch(noise, pointX, pointY, stitchInfo); 764 if (noise[2]<0) fSum[2] -= (noise[2] * ratio); 765 else fSum[2] += (noise[2] * ratio); 766 if (noise[1]<0) fSum[1] -= (noise[1] * ratio); 767 else fSum[1] += (noise[1] * ratio); 768 if (noise[0]<0) fSum[0] -= (noise[0] * ratio); 769 else fSum[0] += (noise[0] * ratio); 770 ratio *= .5; 771 pointX *= 2; 772 pointY *= 2; 773 774 stitchInfo.doubleFrequency(); 775 } 776 rgb[2] = (int)(fSum[2] * 255); 777 if ((rgb[2] & 0xFFFFFF00) != 0) 778 rgb[2] = ((rgb[2] & 0x80000000) != 0)?0:255; 779 rgb[1] = (int)(fSum[1] * 255); 780 if ((rgb[1] & 0xFFFFFF00) != 0) 781 rgb[1] = ((rgb[1] & 0x80000000) != 0)?0:255; 782 rgb[0] = (int)(fSum[0] * 255); 783 if ((rgb[0] & 0xFFFFFF00) != 0) 784 rgb[0] = ((rgb[0] & 0x80000000) != 0)?0:255; 785 break; 786 case 2: 787 for(int nOctave = 0; nOctave < numOctaves; nOctave++){ 788 noise2Stitch(noise, pointX, pointY, stitchInfo); 789 if (noise[1]<0) fSum[1] -= (noise[1] * ratio); 790 else fSum[1] += (noise[1] * ratio); 791 if (noise[0]<0) fSum[0] -= (noise[0] * ratio); 792 else fSum[0] += (noise[0] * ratio); 793 ratio *= .5; 794 pointX *= 2; 795 pointY *= 2; 796 797 stitchInfo.doubleFrequency(); 798 } 799 rgb[1] = (int)(fSum[1] * 255); 800 if ((rgb[1] & 0xFFFFFF00) != 0) 801 rgb[1] = ((rgb[1] & 0x80000000) != 0)?0:255; 802 rgb[0] = (int)(fSum[0] * 255); 803 if ((rgb[0] & 0xFFFFFF00) != 0) 804 rgb[0] = ((rgb[0] & 0x80000000) != 0)?0:255; 805 break; 806 case 1: 807 for(int nOctave = 0; nOctave < numOctaves; nOctave++){ 808 noise2Stitch(noise, pointX, pointY, stitchInfo); 809 if (noise[0]<0) fSum[0] -= (noise[0] * ratio); 810 else fSum[0] += (noise[0] * ratio); 811 ratio *= .5; 812 pointX *= 2; 813 pointY *= 2; 814 815 stitchInfo.doubleFrequency(); 816 } 817 rgb[0] = (int)(fSum[0] * 255); 818 if ((rgb[0] & 0xFFFFFF00) != 0) 819 rgb[0] = ((rgb[0] & 0x80000000) != 0)?0:255; 820 break; 821 } 822 } 823 824 832 private final int turbulenceFractal_4( double pointX, 833 double pointY, 834 final double fSum[]) { 835 int b0, b1, nOctave, i, j; 836 double px, py, rx0, rx1, ry0, ry1, sx, sy, ratio = 127.5; 837 838 pointX *= baseFrequencyX; 839 pointY *= baseFrequencyY; 840 fSum[0] = fSum[1] = fSum[2] = fSum[3] = 127.5; 841 842 for (nOctave = numOctaves; nOctave > 0; nOctave--){ 843 px = pointX+PerlinN; 844 845 b0 = ((int)px)&BM; 846 i = latticeSelector[b0 ]; 847 j = latticeSelector[b0+1]; 848 849 rx0 = px - (int)px; 850 rx1 = rx0 - 1.0; 851 sx = s_curve(rx0); 852 853 py = pointY+PerlinN; 854 b0 = ((int)py) & BM; 855 b1 = (b0+1) & BM; 856 857 b1 = ((j + b0)&BM)<<3; 858 b0 = ((i + b0)&BM)<<3; 859 860 ry0 = py - (int)py; 861 ry1 = ry0 - 1.0; 862 sy = s_curve(ry0); 863 864 fSum[0] += lerp(sy, 865 lerp(sx, 866 rx0*gradient[b0+0] + ry0*gradient[b0+1], 867 rx1*gradient[b1+0] + ry0*gradient[b1+1]), 868 lerp(sx, 869 rx0*gradient[b0+8+0] + ry1*gradient[b0+8+1], 870 rx1*gradient[b1+8+0] + ry1*gradient[b1+8+1]))*ratio; 871 872 fSum[1] += lerp(sy, 873 lerp(sx, 874 rx0*gradient[b0+2] + ry0*gradient[b0+3], 875 rx1*gradient[b1+2] + ry0*gradient[b1+3]), 876 lerp(sx, 877 rx0*gradient[b0+8+2] + ry1*gradient[b0+8+3], 878 rx1*gradient[b1+8+2] + ry1*gradient[b1+8+3]))*ratio; 879 880 fSum[2] += lerp(sy, 881 lerp(sx, 882 rx0*gradient[b0+4] + ry0*gradient[b0+5], 883 rx1*gradient[b1+4] + ry0*gradient[b1+5]), 884 lerp(sx, 885 rx0*gradient[b0+8+4] + ry1*gradient[b0+8+5], 886 rx1*gradient[b1+8+4] + ry1*gradient[b1+8+5]))*ratio; 887 888 fSum[3] += lerp(sy, 889 lerp(sx, 890 rx0*gradient[b0+6] + ry0*gradient[b0+7], 891 rx1*gradient[b1+6] + ry0*gradient[b1+7]), 892 lerp(sx, 893 rx0*gradient[b0+8+6] + ry1*gradient[b0+8+7], 894 rx1*gradient[b1+8+6] + ry1*gradient[b1+8+7]))*ratio; 895 896 ratio *= .5; 897 pointX *= 2; 898 pointY *= 2; 899 } 900 901 i = (int)fSum[0]; 902 if ((i & 0xFFFFFF00) == 0) j = i<<16; 903 else j = ((i & 0x80000000) != 0)?0:0xFF0000; 904 905 i = (int)fSum[1]; 906 if ((i & 0xFFFFFF00) == 0) j |= i<<8; 907 else j |= ((i & 0x80000000) != 0)?0:0xFF00; 908 909 i = (int)fSum[2]; 910 if ((i & 0xFFFFFF00) == 0) j |= i; 911 else j |= ((i & 0x80000000) != 0)?0:0xFF; 912 913 i = (int)fSum[3]; 914 if ((i & 0xFFFFFF00) == 0) j |= i<<24; 915 else j |= ((i & 0x80000000) != 0)?0:0xFF000000; 916 return j; 917 } 918 919 928 private final void turbulenceFractal(final int rgb[], 929 double pointX, 930 double pointY, 931 final double fSum[], 932 final double noise[]){ 933 double ratio = 127.5; 934 int nOctave; 935 fSum[0] = fSum[1] = fSum[2] = fSum[3] = 127.5; 936 pointX *= baseFrequencyX; 937 pointY *= baseFrequencyY; 938 for(nOctave = numOctaves; nOctave > 0; nOctave--){ 939 noise2(noise, pointX, pointY); 940 941 switch (channels.length) { 942 case 4: 943 fSum[3] += (noise[3] * ratio); 944 case 3: 945 fSum[2] += (noise[2] * ratio); 946 case 2: 947 fSum[1] += (noise[1] * ratio); 948 case 1: 949 fSum[0] += (noise[0] * ratio); 950 } 951 952 ratio *= .5; 953 pointX *= 2; 954 pointY *= 2; 955 } 956 957 switch (channels.length) { 958 case 4: 959 rgb[3] = (int)fSum[3]; 960 if ((rgb[3] & 0xFFFFFF00) != 0) 961 rgb[3] = ((rgb[3] & 0x80000000) != 0)?0:255; 962 case 3: 963 rgb[2] = (int)fSum[2]; 964 if ((rgb[2] & 0xFFFFFF00) != 0) 965 rgb[2] = ((rgb[2] & 0x80000000) != 0)?0:255; 966 case 2: 967 rgb[1] = (int)fSum[1]; 968 if ((rgb[1] & 0xFFFFFF00) != 0) 969 rgb[1] = ((rgb[1] & 0x80000000) != 0)?0:255; 970 case 1: 971 rgb[0] = (int)fSum[0]; 972 if ((rgb[0] & 0xFFFFFF00) != 0) 973 rgb[0] = ((rgb[0] & 0x80000000) != 0)?0:255; 974 } 975 } 976 977 987 private final void turbulenceFractalStitch(final int rgb[], 988 double pointX, 989 double pointY, 990 final double fSum[], 991 final double noise[], 992 StitchInfo stitchInfo){ 993 double ratio = 127.5; 994 int nOctave; 995 fSum[0] = fSum[1] = fSum[2] = fSum[3] = 127.5; 996 pointX *= baseFrequencyX; 997 pointY *= baseFrequencyY; 998 for(nOctave = numOctaves; nOctave > 0; nOctave--){ 999 noise2Stitch(noise, pointX, pointY, stitchInfo); 1000 1001 switch (channels.length) { 1002 case 4: 1003 fSum[3] += (noise[3] * ratio); 1004 case 3: 1005 fSum[2] += (noise[2] * ratio); 1006 case 2: 1007 fSum[1] += (noise[1] * ratio); 1008 case 1: 1009 fSum[0] += (noise[0] * ratio); 1010 } 1011 1012 ratio *= .5; 1013 pointX *= 2; 1014 pointY *= 2; 1015 stitchInfo.doubleFrequency(); 1016 } 1017 1018 switch (channels.length) { 1019 case 4: 1020 rgb[3] = (int)fSum[3]; 1021 if ((rgb[3] & 0xFFFFFF00) != 0) 1022 rgb[3] = ((rgb[3] & 0x80000000) != 0)?0:255; 1023 case 3: 1024 rgb[2] = (int)fSum[2]; 1025 if ((rgb[2] & 0xFFFFFF00) != 0) 1026 rgb[2] = ((rgb[2] & 0x80000000) != 0)?0:255; 1027 case 2: 1028 rgb[1] = (int)fSum[1]; 1029 if ((rgb[1] & 0xFFFFFF00) != 0) 1030 rgb[1] = ((rgb[1] & 0x80000000) != 0)?0:255; 1031 case 1: 1032 rgb[0] = (int)fSum[0]; 1033 if ((rgb[0] & 0xFFFFFF00) != 0) 1034 rgb[0] = ((rgb[0] & 0x80000000) != 0)?0:255; 1035 } 1036 } 1037 1038 1042 public WritableRaster copyData(WritableRaster dest) { 1043 if(dest==null) 1047 throw new IllegalArgumentException 1048 ("Cannot generate a noise pattern into a null raster"); 1049 1050 1051 int w = dest.getWidth(); 1052 int h = dest.getHeight(); 1053 1054 DataBufferInt dstDB = (DataBufferInt )dest.getDataBuffer(); 1056 SinglePixelPackedSampleModel sppsm; 1057 int minX = dest.getMinX(); 1058 int minY = dest.getMinY(); 1059 sppsm = (SinglePixelPackedSampleModel )dest.getSampleModel(); 1060 int dstOff = dstDB.getOffset() + 1061 sppsm.getOffset(minX - dest.getSampleModelTranslateX(), 1062 minY - dest.getSampleModelTranslateY()); 1063 1064 final int destPixels[] = dstDB.getBankData()[0]; 1065 int dstAdjust = sppsm.getScanlineStride() - w; 1066 1067 int i, end, dp=dstOff; 1069 final int rgb[] = new int[4]; 1070 final double fSum[] = {0, 0, 0, 0}; 1071 final double noise[] = {0, 0, 0, 0}; 1072 1073 final double tx0, tx1, ty0, ty1; 1074 tx0 = tx[0]; 1075 tx1 = tx[1]; 1076 ty0 = ty[0]-(w*tx0); 1079 ty1 = ty[1]-(w*tx1); 1080 1081 double p[] = {minX, minY}; 1082 txf.transform(p, 0, p, 0, 1); 1083 double point_0 = p[0]; 1084 double point_1 = p[1]; 1085 1086 if(isFractalNoise){ 1087 if(stitchInfo == null){ 1088 if (channels.length == 4) { 1089 for(i=0; i<h; i++){ 1090 for(end=dp+w; dp<end; dp++) { 1091 destPixels[dp] = turbulenceFractal_4 1092 (point_0, point_1, fSum); 1093 point_0 += tx0; 1094 point_1 += tx1; 1095 } 1096 point_0 += ty0; 1097 point_1 += ty1; 1098 dp += dstAdjust; 1099 } 1100 } else { 1101 for(i=0; i<h; i++){ 1102 for(end=dp+w; dp<end; dp++){ 1103 turbulenceFractal(rgb, point_0, point_1, fSum, noise); 1104 1105 destPixels[dp] = ((rgb[3]<<24) | 1107 (rgb[0]<<16) | 1108 (rgb[1]<<8) | 1109 (rgb[2] )); 1110 point_0 += tx0; 1111 point_1 += tx1; 1112 } 1113 point_0 += ty0; 1114 point_1 += ty1; 1115 dp += dstAdjust; 1116 } 1117 } 1118 } 1119 else{ 1120 StitchInfo si = new StitchInfo(); 1121 for(i=0; i<h; i++){ 1122 for(end=dp+w; dp<end; dp++){ 1123 si.assign(this.stitchInfo); 1124 turbulenceFractalStitch(rgb, point_0, point_1, 1125 fSum, noise, si); 1126 1127 destPixels[dp] = ((rgb[3]<<24) | 1129 (rgb[0]<<16) | 1130 (rgb[1]<<8) | 1131 (rgb[2] )); 1132 point_0 += tx0; 1133 point_1 += tx1; 1134 } 1135 point_0 += ty0; 1136 point_1 += ty1; 1137 dp += dstAdjust; 1138 } 1139 } 1140 } 1141 else{ if(stitchInfo == null){ 1143 if (channels.length == 4) { 1144 for(i=0; i<h; i++){ 1145 for(end=dp+w; dp<end; dp++){ 1146 destPixels[dp] = turbulence_4 1147 (point_0, point_1, fSum); 1148 1149 point_0 += tx0; 1150 point_1 += tx1; 1151 } 1152 point_0 += ty0; 1153 point_1 += ty1; 1154 dp += dstAdjust; 1155 } 1156 } else { 1157 for(i=0; i<h; i++){ 1158 for(end=dp+w; dp<end; dp++){ 1159 turbulence(rgb, point_0, point_1, fSum, noise); 1160 1161 destPixels[dp] = ((rgb[3]<<24) | 1163 (rgb[0]<<16) | 1164 (rgb[1]<<8) | 1165 (rgb[2] )); 1166 point_0 += tx0; 1167 point_1 += tx1; 1168 } 1169 point_0 += ty0; 1170 point_1 += ty1; 1171 dp += dstAdjust; 1172 } 1173 } 1174 } 1175 else{ 1176 StitchInfo si = new StitchInfo(); 1177 for(i=0; i<h; i++){ 1178 for(end=dp+w; dp<end; dp++){ 1179 si.assign(this.stitchInfo); 1180 turbulenceStitch(rgb, point_0, point_1, 1181 fSum, noise, si); 1182 1183 destPixels[dp] = ((rgb[3]<<24) | 1185 (rgb[0]<<16) | 1186 (rgb[1]<<8) | 1187 (rgb[2] )); 1188 point_0 += tx0; 1189 point_1 += tx1; 1190 } 1191 point_0 += ty0; 1192 point_1 += ty1; 1193 dp += dstAdjust; 1194 } 1195 } 1196 } 1197 1198 return dest; 1199 } 1200 1201 1217 public TurbulencePatternRed(double baseFrequencyX, 1218 double baseFrequencyY, 1219 int numOctaves, 1220 int seed, 1221 boolean isFractalNoise, 1222 Rectangle2D tile, 1223 AffineTransform txf, 1224 Rectangle devRect, 1225 ColorSpace cs, 1226 boolean alpha) { 1227 this.baseFrequencyX = baseFrequencyX; 1228 this.baseFrequencyY = baseFrequencyY; 1229 this.seed = seed; 1230 this.isFractalNoise = isFractalNoise; 1231 this.tile = tile; 1232 this.txf = txf; 1233 1234 if(this.txf == null) 1235 this.txf = IDENTITY; 1236 1237 int nChannels = cs.getNumComponents(); 1238 if (alpha) nChannels++; 1239 channels = new int[nChannels]; 1240 for(int i=0; i<channels.length; i++) 1241 channels[i] = i; 1242 1243 txf.deltaTransform(tx, 0, tx, 0, 1); 1244 txf.deltaTransform(ty, 0, ty, 0, 1); 1245 1246 double vecX[] = {.5, 0}; 1247 double vecY[] = {0, .5}; 1248 txf.deltaTransform(vecX, 0, vecX, 0, 1); 1249 txf.deltaTransform(vecY, 0, vecY, 0, 1); 1250 1251 1264 double dx = Math.max(Math.abs(vecX[0]), Math.abs(vecY[0])); 1265 int maxX = -(int)Math.round((Math.log(dx) + Math.log(baseFrequencyX))/ 1266 Math.log(2)); 1267 1268 double dy = Math.max(Math.abs(vecX[1]), Math.abs(vecY[1])); 1269 int maxY = -(int)Math.round((Math.log(dy) + Math.log(baseFrequencyY))/ 1270 Math.log(2)); 1271 1272 this.numOctaves = numOctaves > maxX? maxX : numOctaves; 1273 this.numOctaves = this.numOctaves > maxY? maxY : this.numOctaves; 1274 1275 if(this.numOctaves < 1 && numOctaves > 1) 1276 this.numOctaves = 1; 1277 1278 if (this.numOctaves > 8) 1279 this.numOctaves = 8; 1284 1285 if (tile != null) { 1286 double lowFreq = Math.floor(tile.getWidth()*baseFrequencyX)/tile.getWidth(); 1290 double highFreq = Math.ceil(tile.getWidth()*baseFrequencyX)/tile.getWidth(); 1291 if(baseFrequencyX/lowFreq < highFreq/baseFrequencyX) 1292 this.baseFrequencyX = lowFreq; 1293 else 1294 this.baseFrequencyX = highFreq; 1295 1296 lowFreq = Math.floor(tile.getHeight()*baseFrequencyY)/tile.getHeight(); 1297 highFreq = Math.ceil(tile.getHeight()*baseFrequencyY)/tile.getHeight(); 1298 if(baseFrequencyY/lowFreq < highFreq/baseFrequencyY) 1299 this.baseFrequencyY = lowFreq; 1300 else 1301 this.baseFrequencyY = highFreq; 1302 1303 stitchInfo = new StitchInfo(); 1308 stitchInfo.width = ((int)(tile.getWidth()*this.baseFrequencyX)); 1309 stitchInfo.height = ((int)(tile.getHeight()*this.baseFrequencyY)); 1310 stitchInfo.wrapX = ((int)(tile.getX()*this.baseFrequencyX + 1311 PerlinN + stitchInfo.width)); 1312 stitchInfo.wrapY = ((int)(tile.getY()*this.baseFrequencyY + 1313 PerlinN + stitchInfo.height)); 1314 1315 if(stitchInfo.width == 0) stitchInfo.width = 1; 1318 if(stitchInfo.height == 0) stitchInfo.height = 1; 1319 1320 } 1325 1326 initLattice(seed); 1327 1328 ColorModel cm; 1329 if (alpha) 1330 cm = new DirectColorModel 1331 (cs, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, 1332 false, DataBuffer.TYPE_INT); 1333 else 1334 cm = new DirectColorModel 1335 (cs, 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x0, 1336 false, DataBuffer.TYPE_INT); 1337 1338 int tileSize = AbstractTiledRed.getDefaultTileSize(); 1339 init((CachableRed)null, devRect, cm, 1340 cm.createCompatibleSampleModel(tileSize, tileSize), 1341 0, 0, null); 1342 } 1343 1344} 1345 | Popular Tags |