/*
* Copyright 2017 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 net.jafama.FastMath;
import pixelitor.filters.Sphere3D;
/**
*
*/
public class Sphere3DFilter extends CenteredTransformFilter {
private float alpha;
private float beta;
private float gamma;
public Sphere3DFilter() {
super(Sphere3D.NAME);
}
@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 theta = FastMath.atan2(dy, dx) + Math.PI;
double rd = 0.45 * Math.min(srcWidth, srcHeight);
if (r > rd) {
out[0] = -1;
out[1] = -1;
return;
}
double sa = FastMath.sin(alpha);
double sb = FastMath.sin(beta);
double ca = FastMath.cos(alpha);
double cb = FastMath.cos(beta);
double phi = FastMath.acos(r / rd);
double x0 = FastMath.cos(theta) * FastMath.cos(phi);
double y0 = FastMath.sin(theta) * FastMath.cos(phi);
double z0 = FastMath.sin(phi);
double x1 = ca * x0 + sa * y0;
double z1 = -sa * -sb * x0 + ca * -sb * y0 + cb * z0;
double y1 = cb * -sa * x0 + cb * ca * y0 + sb * z0;
double theta1 = FastMath.atan(-x1 / y1);
double phi1 = FastMath.asin(z1);
int X = srcWidth / 2;
int Y = srcHeight / 2;
out[0] = (float) ((((((theta1 * 2) + gamma) % (2 * Math.PI)) - Math.PI) / Math.PI) * X);
out[1] = (float) (-phi1 / (Math.PI / 2) * Y);
}
public void setAlpha(float alpha) {
this.alpha = (float) (2 * Math.PI * alpha);
}
public void setBeta(float beta) {
this.beta = (float) (2 * Math.PI * beta);
}
public void setGamma(float gamma) {
this.gamma = (float) (2 * Math.PI * gamma);
}
}