Package nodebox.graphics

Source Code of nodebox.graphics.Transform

package nodebox.graphics;

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;

public class Transform implements Cloneable {

    public enum Mode {
        CORNER, CENTER
    }

    private AffineTransform affineTransform;

    public static Transform translated(double tx, double ty) {
        Transform t = new Transform();
        t.translate(tx, ty);
        return t;
    }

    public static Transform translated(Point t) {
        return translated(t.x, t.y);
    }

    public static Transform rotated(double degrees) {
        Transform t = new Transform();
        t.rotate(degrees);
        return t;
    }

    public static Transform rotatedRadians(double radians) {
        Transform t = new Transform();
        t.rotateRadians(radians);
        return t;
    }

    public static Transform scaled(double scale) {
        Transform t = new Transform();
        t.scale(scale);
        return t;
    }

    public static Transform scaled(double sx, double sy) {
        Transform t = new Transform();
        t.scale(sx, sy);
        return t;
    }

    public static Transform scaled(Point s) {
        return scaled(s.x, s.y);
    }

    public static Transform skewed(double skew) {
        Transform t = new Transform();
        t.skew(skew);
        return t;
    }

    public static Transform skewed(double kx, double ky) {
        Transform t = new Transform();
        t.skew(kx, ky);
        return t;
    }

    public Transform() {
        affineTransform = new AffineTransform();
    }

    public Transform(double m00, double m10, double m01, double m11, double m02, double m12) {
        affineTransform = new AffineTransform(m00, m10, m01, m11, m02, m12);
    }

    public Transform(AffineTransform affineTransform) {
        this.affineTransform = affineTransform;
    }

    public Transform(Transform other) {
        this.affineTransform = (AffineTransform) other.affineTransform.clone();
    }

    //// Transform changes ////

    public void translate(Point point) {
        affineTransform.translate(point.x, point.y);
    }

    public void translate(double tx, double ty) {
        affineTransform.translate(tx, ty);
    }

    public void rotate(double degrees) {
        double radians = degrees * Math.PI / 180;
        affineTransform.rotate(radians);
    }

    public void rotateRadians(double radians) {
        affineTransform.rotate(radians);
    }

    public void scale(double scale) {
        affineTransform.scale(scale, scale);
    }

    public void scale(double sx, double sy) {
        affineTransform.scale(sx, sy);
    }

    public void skew(double skew) {
        skew(skew, skew);
    }

    public void skew(double kx, double ky) {
        kx = Math.PI * kx / 180.0;
        ky = Math.PI * ky / 180.0;
        affineTransform.concatenate(new AffineTransform(1, Math.tan(ky), -Math.tan(kx), 1, 0, 0));
    }

    public boolean invert() {
        try {
            affineTransform = affineTransform.createInverse();
            return true;
        } catch (NoninvertibleTransformException e) {
            return false;
        }
    }

    public void append(Transform t) {
        affineTransform.concatenate(t.affineTransform);
    }

    public void prepend(Transform t) {
        affineTransform.preConcatenate(t.affineTransform);
    }

    //// Operations ////

    public Point map(Point p) {
        Point2D.Double p2 = new Point2D.Double();
        affineTransform.transform(p.toPoint2D(), p2);
        return new Point(p2);
    }

    public Rect map(Rect r) {
        // TODO: The size conversion might be incorrect. (using deltaTransform) In that case, make topLeft and bottomRight points.
        Point2D origin = new Point2D.Double(r.getX(), r.getY());
        Point2D size = new Point2D.Double(r.getWidth(), r.getHeight());
        Point2D transformedOrigin = new Point2D.Double();
        Point2D transformedSize = new Point2D.Double();
        affineTransform.transform(origin, transformedOrigin);
        affineTransform.deltaTransform(size, transformedSize);
        return new Rect(transformedOrigin.getX(), transformedOrigin.getY(), transformedSize.getX(), transformedSize.getY());
    }

    public IGeometry map(IGeometry shape) {
        if (shape instanceof Path) {
            return map((Path) shape);
        } else if (shape instanceof Geometry) {
            return map((Geometry) shape);
        } else {
            throw new RuntimeException("Unsupported geometry type " + shape);
        }
    }

    public Path map(Path p) {
        Path newPath = new Path(p, false);
        for (Contour c : p.getContours()) {
            Contour newContour = new Contour(map(c.getPoints()), c.isClosed());
            newPath.add(newContour);
        }
        return newPath;
    }

    public Geometry map(Geometry g) {
        Geometry newGeometry = new Geometry();
        for (Path p : g.getPaths()) {
            Path newPath = map(p);
            newGeometry.add(newPath);
        }
        return newGeometry;
    }

    /**
     * Transform all the given points and return a list of transformed points.
     * Points are immutable, so they can not be transformed in-place.
     *
     * @param points The points to transform.
     * @return The list of transformed points.
     */
    public List<Point> map(List<Point> points) {
        // Prepare the points for the AffineTransform transformation.
        double[] coords = new double[points.size() * 2];
        int i = 0;
        for (Point pt : points) {
            coords[i++] = pt.x;
            coords[i++] = pt.y;
        }
        affineTransform.transform(coords, 0, coords, 0, points.size());

        // Convert the transformed points into a new List.
        List<Point> transformed = new ArrayList<Point>(points.size());
        int pointIndex = 0;
        for (i = 0; i < coords.length; i += 2) {
            transformed.add(new Point(coords[i], coords[i + 1], points.get(pointIndex).type));
            pointIndex++;
        }
        return transformed;
    }

    public Rect convertBoundsToFrame(Rect bounds) {
        AffineTransform t = fullTransform(bounds);
        Point2D transformedOrigin = new Point2D.Double();
        Point2D transformedSize = new Point2D.Double();
        t.transform(new Point2D.Double(bounds.getX(), bounds.getY()), transformedOrigin);
        t.deltaTransform(new Point2D.Double(bounds.getWidth(), bounds.getHeight()), transformedSize);
        return new Rect(transformedOrigin.getX(), transformedOrigin.getY(), transformedSize.getX(), transformedSize.getY());
    }

    private AffineTransform fullTransform(Rect bounds) {
        double cx = bounds.getX() + bounds.getWidth() / 2;
        double cy = bounds.getY() + bounds.getHeight() / 2;
        AffineTransform t = new AffineTransform();
        t.translate(cx, cy);
        t.preConcatenate(affineTransform);
        t.translate(-cx, -cy);
        return t;
    }

    @Override
    protected Transform clone() {
        return new Transform(this);
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Transform)) return false;
        return getAffineTransform().equals(((Transform) obj).getAffineTransform());
    }

    public void apply(Graphics2D g, Rect bounds) {
        AffineTransform t = fullTransform(bounds);
        g.transform(t);
    }

    public AffineTransform getAffineTransform() {
        return affineTransform;
    }
}
TOP

Related Classes of nodebox.graphics.Transform

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.