Package ca.eandb.jmist.framework

Source Code of ca.eandb.jmist.framework.InvertibleAffineTransformation2

/**
* Java Modular Image Synthesis Toolkit (JMIST)
* Copyright (C) 2008-2013 Bradley W. Kimmel
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package ca.eandb.jmist.framework;

import java.io.Serializable;

import ca.eandb.jmist.math.AffineMatrix2;
import ca.eandb.jmist.math.HPoint2;
import ca.eandb.jmist.math.LinearMatrix2;
import ca.eandb.jmist.math.Point2;
import ca.eandb.jmist.math.Ray2;
import ca.eandb.jmist.math.Vector2;

/**
* A class for classes implementing <code>AffineTransformable2</code> that
* require the inverse of the transformation matrix.
*
* @author Brad Kimmel
*/
public class InvertibleAffineTransformation2 extends AffineTransformation2
    implements Serializable {

  /** Serialization version ID. */
  private static final long serialVersionUID = 338292224394167644L;

  /** The inverse transformation matrix. */
  private AffineMatrix2 inverse = null;

  /* (non-Javadoc)
   * @see ca.eandb.jmist.framework.AffineTransformation2#rotate(double)
   */
  @Override
  public void rotate(double angle) {
    super.rotate(angle);
    this.applyInverseTransformation(LinearMatrix2
        .rotateMatrix(-angle));
  }

  /*
   * (non-Javadoc)
   *
   * @see ca.eandb.jmist.framework.AffineTransformation2#scale(double)
   */
  @Override
  public void scale(double c) {
    super.scale(c);
    this.applyInverseTransformation(LinearMatrix2.scaleMatrix(1.0 / c));
  }

  /*
   * (non-Javadoc)
   *
   * @see ca.eandb.jmist.framework.AffineTransformation2#stretch(double,
   *      double, double)
   */
  @Override
  public void stretch(double cx, double cy) {
    super.stretch(cx, cy);
    this.applyInverseTransformation(LinearMatrix2.stretchMatrix(1.0 / cx,
        1.0 / cy));
  }

  /*
   * (non-Javadoc)
   *
   * @see ca.eandb.jmist.framework.AffineTransformation2#stretch(ca.eandb.jmist.toolkit.Vector2,
   *      double)
   */
  @Override
  public void stretch(Vector2 axis, double c) {
    super.stretch(axis, c);
    this.applyInverseTransformation(LinearMatrix2.stretchMatrix(axis,
        1.0 / c));
  }

  /*
   * (non-Javadoc)
   *
   * @see ca.eandb.jmist.framework.AffineTransformation2#stretchX(double)
   */
  @Override
  public void stretchX(double cx) {
    super.stretchX(cx);
    this.applyInverseTransformation(LinearMatrix2.stretchXMatrix(1.0 / cx));
  }

  /*
   * (non-Javadoc)
   *
   * @see ca.eandb.jmist.framework.AffineTransformation2#stretchY(double)
   */
  @Override
  public void stretchY(double cy) {
    super.stretchY(cy);
    this.applyInverseTransformation(LinearMatrix2.stretchYMatrix(1.0 / cy));
  }

  /*
   * (non-Javadoc)
   *
   * @see ca.eandb.jmist.framework.AffineTransformation2#transform(ca.eandb.jmist.toolkit.AffineMatrix2)
   */
  @Override
  public void transform(AffineMatrix2 T) {
    super.transform(T);
    this.applyInverseTransformation(T.inverse());
  }

  /*
   * (non-Javadoc)
   *
   * @see ca.eandb.jmist.framework.AffineTransformation2#transform(ca.eandb.jmist.toolkit.LinearMatrix2)
   */
  @Override
  public void transform(LinearMatrix2 T) {
    super.transform(T);
    this.applyInverseTransformation(T.inverse());
  }

  /*
   * (non-Javadoc)
   *
   * @see ca.eandb.jmist.framework.AffineTransformation2#translate(ca.eandb.jmist.toolkit.Vector2)
   */
  @Override
  public void translate(Vector2 v) {
    super.translate(v);
    this.applyInverseTransformation(AffineMatrix2.translateMatrix(v
        .opposite()));
  }

  /**
   * Applies the specified inverse transformation matrix to the current
   * inverse transformation.
   *
   * @param Tinv
   *            The inverse of the <code>AffineMatrix2</code> that is being
   *            applied.
   */
  private void applyInverseTransformation(AffineMatrix2 Tinv) {
    if (this.inverse == null) {
      this.inverse = Tinv;
    } else {
      this.inverse = this.inverse.times(Tinv);
    }
  }

  /**
   * Applies the specified inverse transformation matrix to the current
   * inverse transformation.
   *
   * @param Tinv
   *            The inverse of the <code>LinearMatrix2</code> that is being
   *            applied.
   */
  private void applyInverseTransformation(LinearMatrix2 Tinv) {
    this.applyInverseTransformation(new AffineMatrix2(Tinv));
  }

  /**
   * Gets the inverse transformation matrix.
   *
   * @return The <code>AffineMatrix2</code> representing the inverse of this
   *         transformation.
   */
  protected AffineMatrix2 getInverseTransformationMatrix() {
    return this.inverse != null ? this.inverse : AffineMatrix2.IDENTITY;
  }

  /**
   * Applies this transformation to the specified
   * <code>InvertibleAffineTransformation2</code>.
   *
   * @param trans
   *            The <code>InvertibleAffineTransformation2</code> to apply
   *            this transformation to.
   */
  public void apply(InvertibleAffineTransformation2 trans) {
    if (this.isDirty()) {
      trans.applyTransformation(super.getTransformationMatrix());
      trans.applyInverseTransformation(this.inverse);
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see ca.eandb.jmist.framework.AffineTransformation2#apply(ca.eandb.jmist.framework.AffineTransformable2)
   */
  @Override
  public void apply(AffineTransformable2 to) {
    if (to instanceof InvertibleAffineTransformation2) {
      this.apply((InvertibleAffineTransformation2) to);
    } else {
      super.apply(to);
    }
  }

  /**
   * Applies the inverse of this transformation to the specified
   * <code>InvertibleAffineTransformation2</code>.
   *
   * @param trans
   *            The <code>InvertibleAffineTransformation2</code> to apply
   *            the inverse of this transformation to.
   */
  public void applyInverse(InvertibleAffineTransformation2 trans) {
    if (this.isDirty()) {
      trans.applyTransformation(this.inverse);
      trans.applyInverseTransformation(super.getTransformationMatrix());
    }
  }

  /**
   * Applies the inverse of this <code>AffineTransformation2</code> to
   * another object that is affine transformable.
   *
   * @param to
   *            The <code>AffineTransformable2</code> object to apply the
   *            inverse of this transformation to.
   */
  public void applyInverse(AffineTransformable2 to) {
    if (to instanceof InvertibleAffineTransformation2) {
      this.applyInverse((InvertibleAffineTransformation2) to);
    } else if (this.inverse != null) {
      to.transform(this.inverse);
    }
  }

  /**
   * Applies the inverse of this <code>AffineTransformation2</code> to a
   * <code>AffineMatrix2</code>.
   *
   * @param matrix
   *            The <code>AffineMatrix2</code> object to apply the inverse
   *            of this transformation to.
   * @return The transformed <code>AffineMatrix2</code>.
   */
  public AffineMatrix2 applyInverse(AffineMatrix2 matrix) {
    return this.inverse != null ? this.inverse.times(matrix) : matrix;
  }

  /**
   * Applies the inverse of this <code>AffineTransformation2</code> to a
   * <code>HPoint2</code>.
   *
   * @param p
   *            The <code>HPoint2</code> object to apply the inverse of this
   *            transformation to.
   * @return The transformed <code>HPoint2</code>.
   */
  public HPoint2 applyInverse(HPoint2 p) {
    return this.inverse != null ? this.inverse.times(p) : p;
  }

  /**
   * Applies the inverse of this <code>AffineTransformation2</code> to a
   * <code>Point2</code>.
   *
   * @param p
   *            The <code>Point2</code> object to apply the inverse of this
   *            transformation to.
   * @return The transformed <code>Point2</code>.
   */
  public Point2 applyInverse(Point2 p) {
    return this.inverse != null ? this.inverse.times(p) : p;
  }

  /**
   * Applies the inverse of this <code>AffineTransformation2</code> to a
   * <code>Vector2</code>.
   *
   * @param v
   *            The <code>Vector2</code> object to apply the inverse of this
   *            transformation to.
   * @return The transformed <code>Vector2</code>.
   */
  public Vector2 applyInverse(Vector2 v) {
    return this.inverse != null ? this.inverse.times(v) : v;
  }

  /**
   * Applies the inverse of this <code>AffineTransformation2</code> to a
   * <code>Ray2</code>.
   *
   * @param ray
   *            The <code>Ray2</code> object to apply the inverse of this
   *            transformation to.
   * @return The transformed <code>Ray2</code>.
   */
  public Ray2 applyInverse(Ray2 ray) {
    return this.inverse != null ? ray.transform(this.inverse) : ray;
  }

  /* (non-Javadoc)
   * @see ca.eandb.jmist.framework.AffineTransformation2#reset()
   */
  @Override
  public void reset() {
    super.reset();
    this.inverse = null;
  }

}
TOP

Related Classes of ca.eandb.jmist.framework.InvertibleAffineTransformation2

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.