/* JWildfire - an image and animation processor written in Java Copyright (C) 1995-2011 Andreas Maschke This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this software; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jwildfire.create; import org.jwildfire.base.Property; import org.jwildfire.base.PropertyMin; import org.jwildfire.image.Pixel; import org.jwildfire.image.SimpleImage; public class PlasmaCreator extends ImageCreator { @Property(description = "Inverse cluster size") @PropertyMin(0.01) private double dimension = 150.0; @Property(description = "Seed for the random number generator") @PropertyMin(0) private int seed = 345; @Override protected void fillImage(SimpleImage res) { int width = res.getImageWidth(); int height = res.getImageHeight(); double frac = this.dimension; if (frac <= 0.0) frac = 20.0; PixelColor pixel = new PixelColor(); srand123(this.seed); int w2 = width; int h2 = height; double f13 = (float) 1.0 / (float) 3.0; double f14 = (float) 1.0 / (float) 4.0; double dimf = frac / ((float) h2 * (float) w2); int f[][] = new int[256][4]; f[0][0] = 0; f[0][1] = 0; f[0][2] = w2 - 1; f[0][3] = h2 - 1; double currr, currg, currb; currr = drand48(); currg = drand48(); currb = drand48(); fSetPixel(res, 0, 0, currr, currg, currb); currr = drand48(); currg = drand48(); currb = drand48(); fSetPixel(res, w2 - 1, 0, currr, currg, currb); currr = drand48(); currg = drand48(); currb = drand48(); fSetPixel(res, w2 - 1, h2 - 1, currr, currg, currb); currr = drand48(); currg = drand48(); currb = drand48(); fSetPixel(res, 0, h2 - 1, currr, currg, currb); int ptr = 0; while (ptr > -1) { int dimx = f[ptr][2] - f[ptr][0]; int dimy = f[ptr][3] - f[ptr][1]; if ((dimx > 1) || (dimy > 1)) { double rndf = (dimx * dimy) * dimf; int x1 = f[ptr][0]; int x3 = f[ptr][2]; int x2 = x1 + ((x3 - x1) >> 1); int y1 = f[ptr][1]; int y3 = f[ptr][3]; int y2 = y1 + ((y3 - y1) >> 1); fGetPixel(res, x1, y1, pixel); double c1r = pixel.r; double c1g = pixel.g; double c1b = pixel.b; fGetPixel(res, x3, y1, pixel); double c3r = pixel.r; double c3g = pixel.g; double c3b = pixel.b; fGetPixel(res, x3, y3, pixel); double c9r = pixel.r; double c9g = pixel.g; double c9b = pixel.b; fGetPixel(res, x1, y3, pixel); double c7r = pixel.r; double c7g = pixel.g; double c7b = pixel.b; double c5r = (c1r + c3r + c7r + c9r) * f14 + (rndf * (0.5 - drand48())); if (c5r > 1.0) c5r = 1.0; if (c5r < 0.0) c5r = 0.0; double c5g = (c1g + c3g + c7g + c9g) * f14 + (rndf * (0.5 - drand48())); if (c5g > 1.0) c5g = 1.0; if (c5g < 0.0) c5g = 0.0; double c5b = (c1b + c3b + c7b + c9b) * f14 + (rndf * (0.5 - drand48())); if (c5b > 1.0) c5b = 1.0; if (c5b < 0.0) c5b = 0.0; fSetPixel(res, x2, y2, c5r, c5g, c5b); fGetPixel(res, x2, y1, pixel); currr = pixel.r; currb = pixel.g; currg = pixel.b; if ((currr == 0.0) && (currg == 0.0) && (currb == 0.0)) { currr = (c1r + c3r + c5r) * f13; currg = (c1g + c3g + c5g) * f13; currb = (c1b + c3b + c5b) * f13; fSetPixel(res, x2, y1, currr, currg, currb); } fGetPixel(res, x1, y2, pixel); currr = pixel.r; currg = pixel.g; currb = pixel.b; if ((currr == 0.0) && (currg == 0.0) && (currb == 0.0)) { currr = (c1r + c7r + c5r) * f13; currg = (c1g + c7g + c5g) * f13; currb = (c1b + c7b + c5b) * f13; fSetPixel(res, x1, y2, currr, currg, currb); } fGetPixel(res, x3, y2, pixel); currr = pixel.r; currg = pixel.g; currb = pixel.b; if ((currr == 0.0) && (currg == 0.0) && (currb == 0.0)) { currr = (c3r + c9r + c5r) * f13; currg = (c3g + c9g + c5g) * f13; currb = (c3b + c9b + c5b) * f13; fSetPixel(res, x3, y2, currr, currg, currb); } fGetPixel(res, x2, y3, pixel); currr = pixel.r; currg = pixel.g; currb = pixel.b; if ((currr == 0.0) && (currg == 0.0) && (currb == 0.0)) { currr = (c7r + c9r + c5r) * f13; currg = (c7g + c9g + c5g) * f13; currb = (c7b + c9b + c5b) * f13; fSetPixel(res, x2, y3, currr, currg, currb); } f[ptr][2] = x2; f[ptr][3] = y2; ptr++; f[ptr][0] = x2; f[ptr][1] = y1; f[ptr][2] = x3; f[ptr][3] = y2; ptr++; f[ptr][0] = x2; f[ptr][1] = y2; f[ptr][2] = x3; f[ptr][3] = y3; ptr++; f[ptr][0] = x1; f[ptr][1] = y2; f[ptr][2] = x2; f[ptr][3] = y3; if (ptr > 250) { /* printf("stack overflow\n");*/ ptr = -1; } } else ptr--; } } private static class PixelColor { public double r; public double g; public double b; } private void fSetPixel(SimpleImage pImg, int pX, int pY, double pR, double pG, double pB) { int r = (int) (255.0 * pR + 0.5); int g = (int) (255.0 * pG + 0.5); int b = (int) (255.0 * pB + 0.5); pImg.setRGB(pX, pY, r, g, b); } Pixel toolPixel = new Pixel(); private void fGetPixel(SimpleImage pImg, int pX, int pY, PixelColor pPixelColor) { int argb = pImg.getARGBValue(pX, pY); toolPixel.setARGBValue(argb); pPixelColor.r = (float) toolPixel.r / 255.0; pPixelColor.g = (float) toolPixel.g / 255.0; pPixelColor.b = (float) toolPixel.b / 255.0; } private int a123 = 1; private final int RAND_MAX123 = 0x7fffffff; private int rand123() { return (a123 = a123 * 1103515245 + 12345) % RAND_MAX123; } private void srand123(int pSeed) { a123 = pSeed; } private double rrmax = 1.0 / (double) RAND_MAX123; private double drand48() { double res = ((double) (rand123() * rrmax)); return (res < 0) ? 0.0 - res : res; } public double getDimension() { return dimension; } public void setDimension(double dimension) { this.dimension = dimension; } public int getSeed() { return seed; } public void setSeed(int seed) { this.seed = seed; } }