private float calcSat(float mixFactor) { float s = lerp(mixFactor, sat, otherSat) + extraSat; if (s > 1.0f) { s = 1.0f; } else if (s < 0.0f) { s = 0.0f; } return s; }
private float[] getInterpolatedPositions(float progress, GState grEndState) { float[] interpolatedPositions = new float[thumbPositions.length]; for (int i = 0; i < thumbPositions.length; i++) { float initial = thumbPositions[i]; float end = grEndState.thumbPositions[i]; float interpolated = ImageMath.lerp(progress, initial, end); interpolatedPositions[i] = interpolated; } return interpolatedPositions; }
/** * Linear interpolation of ARGB values. * @param t the interpolation parameter * @param rgb1 the lower interpolation range * @param rgb2 the upper interpolation range * @return the interpolated value */ public static int mixColors(float t, int rgb1, int rgb2) { int a1 = (rgb1 >> 24) & 0xff; int r1 = (rgb1 >> 16) & 0xff; int g1 = (rgb1 >> 8) & 0xff; int b1 = rgb1 & 0xff; int a2 = (rgb2 >> 24) & 0xff; int r2 = (rgb2 >> 16) & 0xff; int g2 = (rgb2 >> 8) & 0xff; int b2 = rgb2 & 0xff; a1 = lerp(t, a1, a2); r1 = lerp(t, r1, r2); g1 = lerp(t, g1, g2); b1 = lerp(t, b1, b2); return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1; }
/** * Linear interpolation of ARGB values. * * @param t * the interpolation parameter * @param rgb1 * the lower interpolation range * @param rgb2 * the upper interpolation range * @return the interpolated value */ public static int mixColors(float t, int rgb1, int rgb2) { int a1 = (rgb1 >> 24) & 0xff; int r1 = (rgb1 >> 16) & 0xff; int g1 = (rgb1 >> 8) & 0xff; int b1 = rgb1 & 0xff; int a2 = (rgb2 >> 24) & 0xff; int r2 = (rgb2 >> 16) & 0xff; int g2 = (rgb2 >> 8) & 0xff; int b2 = rgb2 & 0xff; a1 = lerp(t, a1, a2); r1 = lerp(t, r1, r2); g1 = lerp(t, g1, g2); b1 = lerp(t, b1, b2); return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1; }
/** * Linear interpolation of ARGB values. * * @param t the interpolation parameter * @param rgb1 the lower interpolation range * @param rgb2 the upper interpolation range * @return the interpolated value */ public static int mixColors(float t, int rgb1, int rgb2) { int a1 = (rgb1 >> 24) & 0xff; int r1 = (rgb1 >> 16) & 0xff; int g1 = (rgb1 >> 8) & 0xff; int b1 = rgb1 & 0xff; int a2 = (rgb2 >> 24) & 0xff; int r2 = (rgb2 >> 16) & 0xff; int g2 = (rgb2 >> 8) & 0xff; int b2 = rgb2 & 0xff; a1 = lerp(t, a1, a2); r1 = lerp(t, r1, r2); g1 = lerp(t, g1, g2); b1 = lerp(t, b1, b2); return (a1 << 24) | (r1 << 16) | (g1 << 8) | b1; }
public void lerp(float t, WarpGrid destination, WarpGrid intermediate) { if (rows != destination.rows || cols != destination.cols) throw new IllegalArgumentException("source and destination are different sizes"); if (rows != intermediate.rows || cols != intermediate.cols) throw new IllegalArgumentException("source and intermediate are different sizes"); int index = 0; for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { intermediate.xGrid[index] = (float)ImageMath.lerp(t, xGrid[index], destination.xGrid[index]); intermediate.yGrid[index] = (float)ImageMath.lerp(t, yGrid[index], destination.yGrid[index]); index++; } } }
@Override public ParamState interpolate(ParamState endState, double progress) { IPPState ippEndState = (IPPState) endState; double interpolatedX = ImageMath.lerp(progress, relativeX, ippEndState.relativeX); double interpolatedY = ImageMath.lerp(progress, relativeY, ippEndState.relativeY); return new IPPState(interpolatedX, interpolatedY); } }
/** * A linear interpolation for hue values, * taking their circular nature into account */ public static float lerpHue(float mixFactor, float hue1, float hue2) { float diff = hue1 - hue2; if (diff < 0.5f && diff > -0.5f) { return ImageMath.lerp(mixFactor, hue1, hue2); } else if (diff >= 0.5f) { // hue1 is big, hue2 is small hue2 += 1.0f; float mix = ImageMath.lerp(mixFactor, hue1, hue2); if (mix > 1.0f) { mix -= 1.0f; } return mix; } else if (diff <= 0.5f) { // hue2 is big, hue1 is small hue1 += 1.0f; float mix = ImageMath.lerp(mixFactor, hue1, hue2); if (mix > 1.0f) { mix -= 1.0f; } return mix; } else { throw new IllegalStateException("should not get here"); } }
/** * Just like the above lerpHue method, but taking the average * that is on the opposite side of the circle. Not very useful. */ public static float lerpHueLong(float mixFactor, float hue1, float hue2) { float diff = hue1 - hue2; if (diff > 0.5f || diff < -0.5f) { return ImageMath.lerp(mixFactor, hue1, hue2); } else if (hue2 > hue1) { // hue2 is slightly bigger hue1 += 1.0f; float mix = ImageMath.lerp(mixFactor, hue1, hue2); if (mix > 1.0f) { mix -= 1.0f; } return mix; } else if (hue1 >= hue2) { // hue1 is slightly bigger hue2 += 1.0f; float mix = ImageMath.lerp(mixFactor, hue1, hue2); if (mix > 1.0f) { mix -= 1.0f; } return mix; } else { throw new IllegalStateException("should not get here"); } }
@Override protected void transformInverse(int x, int y, float[] out) { double outside = shape.isOutside(x, y); if (invert) { outside = 1.0 - outside; } if (outside == 1.0) { // outside out[0] = x; out[1] = y; return; } else if (outside == 0.0) { // innermost region out[0] = radiusRatio * x + (1 - radiusRatio) * cx; out[1] = radiusRatio * y + (1 - radiusRatio) * cy; return; } else { // between the inner and outer radius double simpleX = radiusRatio * x + (1 - radiusRatio) * cx; double simpleY = radiusRatio * y + (1 - radiusRatio) * cy; out[0] = (float) ImageMath.lerp(outside, simpleX, x); out[1] = (float) ImageMath.lerp(outside, simpleY, y); } }
@Override public ParamState interpolate(ParamState endState, double progress) { APState apEndState = (APState) endState; double interpolatedAngle = ImageMath.lerp(progress, angle, apEndState.angle); return new APState(interpolatedAngle); } }
@Override public ParamState interpolate(ParamState endState, double progress) { GRState apEndState = (GRState) endState; double[] interpolatedValues = new double[values.length]; for (int i = 0; i < values.length; i++) { interpolatedValues[i] = ImageMath.lerp( progress, values[i], apEndState.values[i]); } return new GRState(interpolatedValues); } }
@Override public RPState interpolate(ParamState endState, double progress) { RPState rpEndState = (RPState) endState; double interpolated = ImageMath.lerp(progress, value, rpEndState.value); return new RPState(interpolated); }
public BufferedImage filter( BufferedImage src, BufferedImage dst ) { this.width = width; this.height = height; if ( inLines != null && outLines != null ) { intermediateLines = new Line[inLines.length]; for (int line = 0; line < inLines.length; line++) { Line l = intermediateLines[line] = new Line( ImageMath.lerp(amount, inLines[line].x1, outLines[line].x1), ImageMath.lerp(amount, inLines[line].y1, outLines[line].y1), ImageMath.lerp(amount, inLines[line].x2, outLines[line].x2), ImageMath.lerp(amount, inLines[line].y2, outLines[line].y2) ); l.setup(); inLines[line].setup(); } dst = super.filter( src, dst ); intermediateLines = null; return dst; } return src; }
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); g.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR ); g.setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, ImageMath.lerp( (float)i/(iterations-1), startAlpha, endAlpha ) ) );
public int filterRGB(int x, int y, int rgb) { float dx = x-centreX; float dy = y-centreY; float distance = dx*dx+dy*dy; float angle = (float)Math.atan2(dy, dx); float d = (angle+ImageMath.PI) / (ImageMath.TWO_PI) * rays; int i = (int)d; float f = d - i; if (radius != 0) { float length = ImageMath.lerp(f, rayLengths[i % rays], rayLengths[(i+1) % rays]); float g = length*length / (distance+0.0001f); g = (float)Math.pow(g, (100-amount) / 50.0); f -= 0.5f; // f *= amount/50.0f; f = 1 - f*f; f *= g; } f = ImageMath.clamp(f, 0, 1); return ImageMath.mixColors(f, rgb, color); }
public int filterRGB(int x, int y, int rgb) { float dx = x-icentreX; float dy = y-icentreY; float distance = (float)Math.sqrt(dx*dx+dy*dy); float a = (float)Math.exp(-distance*distance*gauss)*mix + (float)Math.exp(-distance*linear)*(1-mix); float ring; a *= baseAmount; if (distance > radius + ringWidth) a = ImageMath.lerp((distance - (radius + ringWidth))/falloff, a, 0); if (distance < radius - ringWidth || distance > radius + ringWidth) ring = 0; else { ring = Math.abs(distance-radius)/ringWidth; ring = 1 - ring*ring*(3 - 2*ring); ring *= ringAmount; } a += ring; float angle = (float)Math.atan2(dx, dy)+ImageMath.PI; angle = (ImageMath.mod(angle/ImageMath.PI*17 + 1.0f + Noise.noise1(angle*10), 1.0f) - 0.5f)*2; angle = Math.abs(angle); angle = (float)Math.pow(angle, 5.0); float b = rayAmount * angle / (1 + distance*0.1f); a += b; a = ImageMath.clamp(a, 0, 1); return ImageMath.mixColors(a, rgb, color); }
/** * A 2D version of the algorithm from http://mrl.nyu.edu/~perlin/noise/ */ private static float perlinNoise2D(float x, float y) { // find unit grid cell containing point + wrap the integer cells at 255 int gridX = ((int) x) & 255; int gridY = ((int) y) & 255; // get relative coordinates of point within cell x -= ((int) x); y -= ((int) y); // compute the fade curves for x and y float u = fade(x); float v = fade(y); // calculate hashed gradient indices int a = p[gridX] + gridY; int aa = p[a]; int ab = p[a + 1]; int b = p[gridX + 1] + gridY; int ba = p[b]; int bb = p[b + 1]; float noiseSE = grad2D(p[aa], x, y); float noiseSW = grad2D(p[ba], x - 1, y); float noiseNE = grad2D(p[ab], x, y - 1); float noiseNW = grad2D(p[bb], x - 1, y - 1); float noiseS = ImageMath.lerp(u, noiseSE, noiseSW); float noiseN = ImageMath.lerp(u, noiseNE, noiseNW); float noise = ImageMath.lerp(v, noiseS, noiseN); // noise is in the range [-1..1] return noise; }
@Override public void addButtons(PalettePanel panel) { for (int y = 0; y < numRows; y++) { float briStep = calcBriStep(); for (int x = 0; x < numCols; x++) { Color c; if (numRows == 1) { float mixFactor = calcMixFactor(x); float h = calcHue(mixFactor); float s = calcSat(mixFactor); float b = lerp(mixFactor, bri, otherBri); c = new Color(Color.HSBtoRGB(h, s, b)); } else { float mixFactor = calcMixFactor(x); float h = calcHue(mixFactor); float s = calcSat(mixFactor); float b = lerp(mixFactor, bri, otherBri); float startBri = b - MAX_BRI_DEVIATION; b = startBri + y * briStep; if (b > 1.0f) { b = 1.0f; } else if (b < 0.0f) { b = 0.0f; } c = new Color(Color.HSBtoRGB(h, s, b)); } panel.addButton(x, y, c); } } }
float length = lerp(f, rayLengths[i % rays], rayLengths[(i + 1) % rays]); float g = length * length / (distance + 0.0001f);