Package org.jwildfire.transform

Source Code of org.jwildfire.transform.ShearTransformer$AxisEditor

/*
  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.transform;

import org.jwildfire.base.Property;
import org.jwildfire.base.PropertyCategory;
import org.jwildfire.base.PropertyMax;
import org.jwildfire.base.PropertyMin;
import org.jwildfire.base.Tools;
import org.jwildfire.base.mathlib.MathLib;
import org.jwildfire.image.Pixel;
import org.jwildfire.image.SimpleImage;
import org.jwildfire.image.WFImage;

import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;

public class ShearTransformer extends Mesh2DTransformer {

  public enum Axis {
    X, Y
  };

  @Property(description = "X-coordinate of the effect origin")
  private double centreX = 400.0;

  @Property(description = "Y-coordinate of the effect origin")
  private double centreY = 400.0;

  @Property(description = "Shear axis", editorClass = AxisEditor.class)
  private Axis axis = Axis.X;

  @Property(category = PropertyCategory.SECONDARY, description = "Global zoom factor for the whole image")
  @PropertyMin(0.01)
  @PropertyMax(100.0)
  private double zoom = 1.0;

  @Property(description = "Damping of the effect", category = PropertyCategory.SECONDARY)
  private double damping = -0.04;

  @Property(description = "Shear amount")
  private double amount = 60.0;

  @Property(description = "Damping on/off", category = PropertyCategory.SECONDARY)
  private boolean damp = true;

  @Override
  protected void performPixelTransformation(WFImage pImg) {
    SimpleImage img = (SimpleImage) pImg;
    if (axis == Axis.X) {
      if (!damp || (Math.abs(damping) < MathLib.EPSILON))
        shearX(img);
      else
        shearX_Damp(img);
    }
    else if (axis == Axis.Y) {
      if (!damp || (Math.abs(damping) < MathLib.EPSILON))
        shearY(img);
      else
        shearY_Damp(img);
    }
    applySmoothing(img, 1);
  }

  private void shearX(SimpleImage pImg) {
    int width = pImg.getImageWidth();
    int height = pImg.getImageHeight();
    Pixel pPixel = new Pixel();
    double cx = (double) width / 2.0 - 0.5;
    double cy = (double) height / 2.0 - 0.5;
    double oy = this.centreY - cy;
    double zoom = this.zoom;
    if (zoom < 0.01)
      zoom = 0.01;
    zoom = 1.0 / zoom;
    double fshift = this.amount / (100.0 - 1.0);
    double shift = 0.0 - fshift;
    double w1 = (double) width - 1.0;
    double h1 = (double) height - 1.0;
    for (int i = 0; i < height; i++) {
      double y0 = (double) i - cy;
      for (int j = 0; j < width; j++) {
        /* transform the point */
        double x0 = (double) j - cx;
        double amp = (y0 - oy) * shift;
        double x = (x0 + amp) * zoom + cx;
        double y = y0 * zoom + cy;
        /* render it */
        double xi = Tools.fmod33(x);
        double yi = Tools.fmod33(y);
        if ((x < 0.0) || (x > w1) || (y < 0.0) || (y > h1)) {
          pPixel.r = pPixel.g = pPixel.b = 0;
        }
        else {
          readSrcPixels(x, y);
          pPixel.r = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.r) + xi * (srcQ.r)) + yi
              * ((1.0 - xi) * (srcR.r) + xi * (srcS.r))));
          pPixel.g = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.g) + xi * (srcQ.g)) + yi
              * ((1.0 - xi) * (srcR.g) + xi * (srcS.g))));
          pPixel.b = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.b) + xi * (srcQ.b)) + yi
              * ((1.0 - xi) * (srcR.b) + xi * (srcS.b))));
        }
        pImg.setRGB(j, i, pPixel.r, pPixel.g, pPixel.b);
      }
    }
  }

  private void shearX_Damp(SimpleImage pImg) {
    int width = pImg.getImageWidth();
    int height = pImg.getImageHeight();
    Pixel pPixel = new Pixel();
    double cx = (double) width / 2.0 - 0.5;
    double cy = (double) height / 2.0 - 0.5;
    double ox = this.centreX - cx;
    double oy = this.centreY - cy;
    double zoom = this.zoom;
    if (zoom < 0.01)
      zoom = 0.01;
    zoom = 1.0 / zoom;
    double fshift = this.amount / (100.0 - 1.0);
    double shift = 0.0 - fshift;
    double damping = this.damping;
    double w1 = (double) width - 1.0;
    double h1 = (double) height - 1.0;
    for (int i = 0; i < height; i++) {
      double y0 = (double) i - cy;
      for (int j = 0; j < width; j++) {
        /* transform the point */
        double x0 = (double) j - cx;
        double amp = (y0 - oy) * shift;
        double dl2 = x0 - ox;
        if (dl2 < 0.0)
          dl2 = 0.0 - dl2;
        amp = amp * Math.exp(dl2 * damping);
        double x = (x0 + amp) * zoom + cx;
        double y = y0 * zoom + cy;
        /* render it */
        double xi = Tools.fmod33(x);
        double yi = Tools.fmod33(y);
        if ((x < 0.0) || (x > w1) || (y < 0.0) || (y > h1)) {
          pPixel.r = pPixel.g = pPixel.b = 0;
        }
        else {
          readSrcPixels(x, y);
          pPixel.r = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.r) + xi * (srcQ.r)) + yi
              * ((1.0 - xi) * (srcR.r) + xi * (srcS.r))));
          pPixel.g = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.g) + xi * (srcQ.g)) + yi
              * ((1.0 - xi) * (srcR.g) + xi * (srcS.g))));
          pPixel.b = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.b) + xi * (srcQ.b)) + yi
              * ((1.0 - xi) * (srcR.b) + xi * (srcS.b))));
        }
        pImg.setRGB(j, i, pPixel.r, pPixel.g, pPixel.b);
      }
    }
  }

  private void shearY(SimpleImage pImg) {
    int width = pImg.getImageWidth();
    int height = pImg.getImageHeight();
    Pixel pPixel = new Pixel();
    double cx = (double) width / 2.0 - 0.5;
    double cy = (double) height / 2.0 - 0.5;
    double ox = this.centreX - cx;
    double zoom = this.zoom;
    if (zoom < 0.01)
      zoom = 0.01;
    zoom = 1.0 / zoom;
    double fshift = this.amount / (100.0 - 1.0);
    double shift = 0.0 - fshift;
    double w1 = (double) width - 1.0;
    double h1 = (double) height - 1.0;
    for (int i = 0; i < height; i++) {
      double y0 = (double) i - cy;
      for (int j = 0; j < width; j++) {
        /* transform the point */
        double x0 = (double) j - cx;
        double amp = (x0 - ox) * shift;
        double x = x0 * zoom + cx;
        double y = (y0 + amp) * zoom + cy;
        /* render it */
        double xi = Tools.fmod33(x);
        double yi = Tools.fmod33(y);
        if ((x < 0.0) || (x > w1) || (y < 0.0) || (y > h1)) {
          pPixel.r = pPixel.g = pPixel.b = 0;
        }
        else {
          readSrcPixels(x, y);
          pPixel.r = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.r) + xi * (srcQ.r)) + yi
              * ((1.0 - xi) * (srcR.r) + xi * (srcS.r))));
          pPixel.g = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.g) + xi * (srcQ.g)) + yi
              * ((1.0 - xi) * (srcR.g) + xi * (srcS.g))));
          pPixel.b = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.b) + xi * (srcQ.b)) + yi
              * ((1.0 - xi) * (srcR.b) + xi * (srcS.b))));
        }
        pImg.setRGB(j, i, pPixel.r, pPixel.g, pPixel.b);

      }
    }
  }

  private void shearY_Damp(SimpleImage pImg) {
    int width = pImg.getImageWidth();
    int height = pImg.getImageHeight();
    Pixel pPixel = new Pixel();
    double cx = (double) width / 2.0 - 0.5;
    double cy = (double) height / 2.0 - 0.5;
    double ox = this.centreX - cx;
    double oy = this.centreY - cy;
    double zoom = this.zoom;
    if (zoom < 0.01)
      zoom = 0.01;
    zoom = 1.0 / zoom;
    double fshift = this.amount / (100.0 - 1.0);
    double shift = 0.0 - fshift;
    double damping = this.damping;
    double w1 = (double) width - 1.0;
    double h1 = (double) height - 1.0;
    for (int i = 0; i < height; i++) {
      double y0 = (double) i - cy;
      for (int j = 0; j < width; j++) {
        /* transform the point */
        double x0 = (double) j - cx;
        double amp = (x0 - ox) * shift;
        double dl2 = y0 - oy;
        if (dl2 < 0.0)
          dl2 = 0.0 - dl2;
        amp = amp * Math.exp(dl2 * damping);
        double x = x0 * zoom + cx;
        double y = (y0 + amp) * zoom + cy;
        /* render it */
        double xi = Tools.fmod33(x);
        double yi = Tools.fmod33(y);
        if ((x < 0.0) || (x > w1) || (y < 0.0) || (y > h1)) {
          pPixel.r = pPixel.g = pPixel.b = 0;
        }
        else {
          readSrcPixels(x, y);
          pPixel.r = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.r) + xi * (srcQ.r)) + yi
              * ((1.0 - xi) * (srcR.r) + xi * (srcS.r))));
          pPixel.g = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.g) + xi * (srcQ.g)) + yi
              * ((1.0 - xi) * (srcR.g) + xi * (srcS.g))));
          pPixel.b = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.b) + xi * (srcQ.b)) + yi
              * ((1.0 - xi) * (srcR.b) + xi * (srcS.b))));
        }
        pImg.setRGB(j, i, pPixel.r, pPixel.g, pPixel.b);

      }
    }
  }

  @Override
  public void initDefaultParams(WFImage pImg) {
    int width = pImg.getImageWidth();
    int height = pImg.getImageHeight();
    double rr = Math.sqrt(width * width + height * height);
    centreX = Math.round((double) width / 2.0);
    centreY = Math.round((double) height / 2.0);
    amount = Math.round(rr / 6);
    axis = Axis.X;
    zoom = 1.0;
    damping = -0.01;
    damp = false;
  }

  public static class AxisEditor extends ComboBoxPropertyEditor {
    public AxisEditor() {
      super();
      setAvailableValues(new Axis[] { Axis.X, Axis.Y });
    }
  }

  public double getCentreX() {
    return centreX;
  }

  public void setCentreX(double centreX) {
    this.centreX = centreX;
  }

  public double getCentreY() {
    return centreY;
  }

  public void setCentreY(double centreY) {
    this.centreY = centreY;
  }

  public Axis getAxis() {
    return axis;
  }

  public void setAxis(Axis axis) {
    this.axis = axis;
  }

  public double getZoom() {
    return zoom;
  }

  public void setZoom(double zoom) {
    this.zoom = zoom;
  }

  public double getDamping() {
    return damping;
  }

  public void setDamping(double damping) {
    this.damping = damping;
  }

  public double getAmount() {
    return amount;
  }

  public void setAmount(double amount) {
    this.amount = amount;
  }

  public boolean isDamp() {
    return damp;
  }

  public void setDamp(boolean damp) {
    this.damp = damp;
  }

}
TOP

Related Classes of org.jwildfire.transform.ShearTransformer$AxisEditor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.