/*
* Copyright 2016 Laszlo Balazs-Csiki
*
* This file is part of Pixelitor. Pixelitor is free software: you
* can redistribute it and/or modify it under the terms of the GNU
* General Public License, version 3 as published by the Free
* Software Foundation.
*
* Pixelitor 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Pixelitor. If not, see <http://www.gnu.org/licenses/>.
*/
package pixelitor.filters.impl;
import com.jhlabs.image.ImageMath;
import com.jhlabs.image.WaveType;
import com.jhlabs.math.Noise;
import net.jafama.FastMath;
import pixelitor.filters.RadialWaves;
import java.awt.image.BufferedImage;
/**
* Radial waves in a polar coordinate system
*/
public class RadialWavesFilter extends CenteredTransformFilter {
private int angularDivision;
private double radialAmplitude;
private float phase;
private float zoom;
private int waveType;
private int maxSize;
public RadialWavesFilter() {
super(RadialWaves.NAME);
}
@Override
public BufferedImage filter(BufferedImage src, BufferedImage dst) {
maxSize = Math.max(src.getWidth(), src.getHeight());
return super.filter(src, dst);
}
@Override
protected void transformInverse(int x, int y, float[] out) {
float dx = x - cx;
float dy = y - cy;
double r = Math.sqrt(dx * dx + dy * dy);
double angle = FastMath.atan2(dy, dx);
// double angularWL = 1.0 / angularDivision;
double nr = angle * angularDivision - phase;
double fr;
switch (waveType) {
case WaveType.SINE:
fr = FastMath.sin(nr);
break;
case WaveType.SAWTOOTH:
fr = ImageMath.sinLikeSawtooth(nr);
break;
case WaveType.TRIANGLE:
fr = ImageMath.sinLikeTriangle(nr);
break;
case WaveType.NOISE:
fr = Noise.sinLikeNoise1((float)nr);
break;
default:
throw new IllegalStateException("waveType = " + waveType);
}
r += fr * radialAmplitude * r / maxSize;
double zoomedR = r / zoom;
float u = (float) (zoomedR * FastMath.cos(angle));
float v = (float) (zoomedR * FastMath.sin(angle));
out[0] = (u + cx);
out[1] = (v + cy);
}
public void setPhase(float phase) {
this.phase = phase;
}
public void setZoom(float zoom) {
this.zoom = zoom;
}
public void setWaveType(int waveType) {
this.waveType = waveType;
}
public void setAngularDivision(int angularDivision) {
this.angularDivision = angularDivision;
}
public void setRadialAmplitude(double radialAmplitude) {
this.radialAmplitude = radialAmplitude;
}
}