All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.codename1.ui.geom.Rectangle2D Maven / Gradle / Ivy

There is a newer version: 7.0.164
Show newest version
/*
 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores
 * CA 94065 USA or visit www.oracle.com if you need additional information or
 * have any questions.
 */
package com.codename1.ui.geom;

import com.codename1.ui.Transform;

/**
 * Represents a Rectangle position (x, y) and {@link Dimension} (width, height),
 * this is useful for measuring coordinates within the application.
 * 
 * @author Chen Fishbein
 */
public class Rectangle2D implements Shape {

    private double x;
    private double y;
    private Dimension2D size;
    private GeneralPath path;

    /** 
     * Creates a new instance of Rectangle 
     */
    public Rectangle2D() {
        size = new Dimension2D();
    }

    /**
     * Creates a new instance of Rectangle at position (x, y) and with 
     * predefine dimension
     * 
     * @param x the x coordinate of the rectangle
     * @param y the y coordinate of the rectangle
     * @param size the {@link Dimension} of the rectangle
     */
    public Rectangle2D(double x, double y, Dimension2D size) {
        this.x = x;
        this.y = y;
        this.size = size;
    }

    /**
     * Creates a new instance of Rectangle at position (x, y) and with 
     * predefine width and height
     * 
     * @param x the x coordinate of the rectangle
     * @param y the y coordinate of the rectangle
     * @param w the width of the rectangle
     * @param h the height of the rectangle
     */
    public Rectangle2D(double x, double y, double w, double h) {
        this.x = x;
        this.y = y;
        this.size = new Dimension2D(w, h);
    }

    /** 
     * A copy Constructor

     * @param rect the Rectangle to copy
     */
    public Rectangle2D(Rectangle2D rect) {
        this(rect.getX(), rect.getY(),
                rect.getSize().getWidth(), rect.getSize().getHeight());
    }

    /**
     * Helper method to set coordinates
     */
    public void setBounds(double x, double y, double w, double h) {
        this.x = x;
        this.y = y;
        this.size.setWidth(w);
        this.size.setHeight(h);
        path = null;
    }
    
    /**
     * Convenience method for getSize().getWidth();
     * @return width
     */
    public double getWidth() {
        return size.getWidth();
        
    }
    
    /**
     * Convenience method for getSize().setWidth();
     * @param w the width
     */
    public void setWidth(double w) {
        size.setWidth(w);
        path=null;
    }

    /**
     * Convenience method for getSize().setHeight();
     * @param h the height
     */
    public void setHeight(double h) {
        size.setHeight(h);
        path=null;
    }

    /**
     * Convenience method for getSize().getHeight();
     * @return height
     */
    public double getHeight() {
        return size.getHeight();
    }
    
    /**
     * Return the dimension of the rectangle
     * 
     * @return the size of the rectangle
     */
    public Dimension2D getSize() {
        return size;
    }

    /**
     * Return the x coordinate of the rectangle
     * 
     * @return the x coordinate of the rectangle
     */
    public double getX() {
        return x;
    }

    /**
     * Return the y coordinate of the rectangle
     * 
     * @return the y coordinate of the rectangle
     */
    public double getY() {
        return y;
    }

    /**
     * {@inheritDoc}
     */
    public String toString() {
        return "x = " + x + " y = " + y + " size = " + size;
    }

    /**
     * Sets the x position of the rectangle
     * 
     * @param x the x coordinate of the rectangle
     */
    public void setX(int x) {
        this.x = x;
        path=null;
    }
    
    
    /**
     * Sets the x position of the rectangle as a double.
     * @param x 
     */
    public void setX(double x) {
        this.x = x;
        path = null;
    }

    /**
     * Sets the y position of the rectangle
     * 
     * @param y the y coordinate of the rectangle
     */
    public void setY(int y) {
        this.y = y;
        path=null;
    }
    
    /**
     * Sets the y position of the rectangle as a double.
     * @param y The y position
     */
    public void setY(double y) {
        this.y = y;
        path = null;
    }

    /**
     * Checks whether or not this Rectangle entirely contains the specified 
     * Rectangle.
     * 
     * @param rect the specified Rectangle 
     * @return true if the Rectangle is contained entirely inside this 
     * Rectangle; false otherwise
     */
    public boolean contains(Rectangle2D rect) {
        return contains(rect.x, rect.y, rect.size.getWidth(), rect.size.getHeight());
    }

    /**
     * Checks whether this Rectangle entirely contains the Rectangle 
     * at the specified location (rX, rY) with the specified 
     * dimensions (rWidth, rHeight).
     * 
     * @param rX the specified x coordinate
     * @param rY the specified y coordinate
     * @param rWidth the width of the Rectangle
     * @param rHeight the height of the Rectangle
     * @return true if the Rectangle specified by (rX, rY, rWidth, rHeight) 
     * is entirely enclosed inside this Rectangle; false otherwise.
     */
    public boolean contains(double rX, double rY, double rWidth, double rHeight) {
        return x <= rX && y <= rY && x + size.getWidth() >= rX + rWidth &&
                y + size.getHeight() >= rY + rHeight;
    }

    /**
     * Checks wheather the 2nd rectangle is contained in the first rectangle
     * 
     * @param x1 first rect x
     * @param y1 first rect y
     * @param w1 first rect w
     * @param h1 first rect h
     * @param x2 second rect x
     * @param y2 second rect y
     * @param w2 second rect w
     * @param h2 second rect h
     * 
     * @return true if x2, y2, w2, h2 is contained in x1, y1, w1, h1
     */
    public static boolean contains(double x1, double y1, double w1, double h1,
            double x2, double y2, double w2, double h2) {
        return x1 <= x2 && y1 <= y2 && x1 + w1 >= x2 + w2 &&
                y1 + h1 >= y2 + h2;
    }
    
    /**
     * Checks whether or not this Rectangle contains the point at the specified 
     * location (rX, rY).
     * 
     * @param rX the specified x coordinate
     * @param rY the specified y coordinate
     * @return true if the point (rX, rY) is inside this Rectangle; 
     * false otherwise.
     */
    public boolean contains(double rX, double rY) {
        return x <= rX && y <= rY && x + size.getWidth() >= rX &&
                y + size.getHeight() >= rY;
    }

    /**
     * Returns a rectangle that intersects the given rectangle with this rectangle
     *
     * @param rX rectangle to intersect with this rectangle
     * @param rY rectangle to intersect with this rectangle
     * @param rW rectangle to intersect with this rectangle
     * @param rH rectangle to intersect with this rectangle
     * @return the intersection
     */
    public Rectangle2D intersection(double rX, double rY, double rW, double rH) {
        double tx1 = this.x;
        double ty1 = this.y;
        double rx1 = rX;
        double ry1 = rY;
        double tx2 = tx1; tx2 += this.size.getWidth();
        double ty2 = ty1; ty2 += this.size.getHeight();
        double rx2 = rx1; rx2 += rW;
        double ry2 = ry1; ry2 += rH;
        if (tx1 < rx1) {
            tx1 = rx1;
        }
        if (ty1 < ry1) {
            ty1 = ry1;
        }
        if (tx2 > rx2) {
            tx2 = rx2;
        }
        if (ty2 > ry2) {
            ty2 = ry2;
        }
        tx2 -= tx1;
        ty2 -= ty1;
        // tx2,ty2 will never overflow (they will never be
        // larger than the smallest of the two source w,h)
        // they might underflow, though...
        if (tx2 < Integer.MIN_VALUE) {
            tx2 = Integer.MIN_VALUE;
        }
        if (ty2 < Integer.MIN_VALUE) {
            ty2 = Integer.MIN_VALUE;
        }
        return new Rectangle2D(tx1, ty1, tx2, ty2);
    }

    /**
     * Returns a rectangle that intersects the given rectangle with this rectangle
     *
     * @param rrX rectangle to intersect with this rectangle
     * @param rrY rectangle to intersect with this rectangle
     * @param rrW rectangle to intersect with this rectangle
     * @param rrH rectangle to intersect with this rectangle
     * @param rtx1 rectangle to intersect with this rectangle
     * @param rty1 rectangle to intersect with this rectangle
     * @param rtw2 rectangle to intersect with this rectangle
     * @param rth2 rectangle to intersect with this rectangle
     * @param dest result of the intersection are stored here
     */
    public static void intersection(double rrX, double rrY, double rrW, double rrH, double rtx1, double rty1, double rtw2, double rth2, Rectangle2D dest) {
        double tx1 = rtx1;
        double ty1 = rty1;
        double rx1 = rrX;
        double ry1 = rrY;
        double tx2 = tx1; 
        tx2 += rtw2;
        double ty2 = ty1; 
        ty2 += rth2;
        double rx2 = rx1; rx2 += rrW;
        double ry2 = ry1; ry2 += rrH;
        if (tx1 < rx1) {
            tx1 = rx1;
        }
        if (ty1 < ry1) {
            ty1 = ry1;
        }
        if (tx2 > rx2) {
            tx2 = rx2;
        }
        if (ty2 > ry2) {
            ty2 = ry2;
        }
        tx2 -= tx1;
        ty2 -= ty1;
        
        // tx2,ty2 will never overflow (they will never be
        // larger than the smallest of the two source w,h)
        // they might underflow, though...
        if (tx2 < Integer.MIN_VALUE) {
            tx2 = Integer.MIN_VALUE;
        }
        if (ty2 < Integer.MIN_VALUE) {
            ty2 = Integer.MIN_VALUE;
        }
        
        dest.x = tx1;
        dest.y = ty1;
        dest.size.setWidth(tx2);
        dest.size.setHeight(ty2);
    }

    /**
     * Returns a rectangle that intersects the given rectangle with this rectangle
     * 
     * @param r rectangle to intersect with this rectangle
     * @return the intersection
     */
    public Rectangle2D intersection(Rectangle2D r) {
        return intersection(r.x, r.y, r.size.getWidth(), r.size.getHeight());
    }


    /**
     * Determines whether or not this Rectangle and the specified Rectangle 
     * location (x, y) with the specified dimensions (width, height),
     * intersect. Two rectangles intersect if their intersection is nonempty.
     * 
     * @param x the specified x coordinate
     * @param y the specified y coordinate
     * @param width the width of the Rectangle
     * @param height the height of the Rectangle
     * @return true if the specified Rectangle and this Rectangle intersect; 
     * false otherwise.
     */
    public boolean intersects(double x, double y, double width, double height) {
        double tw = size.getWidth();
        double th = size.getHeight();
        return intersects(this.x, this.y, tw, th, x, y, width, height);
    }

    /**
     * Determines whether or not this Rectangle and the specified Rectangle 
     * location (x, y) with the specified dimensions (width, height),
     * intersect. Two rectangles intersect if their intersection is nonempty.
     * 
     * @param rect the Rectangle to check intersection with
     * @return true if the specified Rectangle and this Rectangle intersect; 
     * false otherwise.
     */
    public boolean intersects(Rectangle2D rect) {
        return intersects(rect.getX(), rect.getY(),
                rect.getSize().getWidth(), rect.getSize().getHeight());
    }

    /**
     * Helper method allowing us to determine if two coordinate sets intersect. This saves
     * us the need of creating a rectangle object for a quick calculation
     * 
     * @param tx x of first rectangle
     * @param ty y of first rectangle
     * @param tw width of first rectangle
     * @param th height of first rectangle
     * @param x x of second rectangle
     * @param y y of second rectangle
     * @param width width of second rectangle
     * @param height height of second rectangle
     * @return true if the rectangles intersect
     */
    public static boolean intersects(double tx, double ty, double tw, double th, double x, double y, double width, double height) {
        double rw = width;
        double rh = height;
        if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) {
            return false;
        }
        double rx = x;
        double ry = y;
        rw += rx;
        rh += ry;
        tw += tx;
        th += ty;
        return ((rw < rx || rw > tx) &&
                (rh < ry || rh > ty) &&
                (tw < tx || tw > rx) &&
                (th < ty || th > ry));

    }

    /**
     * {{@inheritDoc}}
     */
    public PathIterator getPathIterator(Transform m) {
        if ( path == null ){
            path = new GeneralPath();
            path.moveTo(x, y);
            path.lineTo(x+size.getWidth(), y);
            path.lineTo(x+size.getWidth(), y+size.getHeight());
            path.lineTo(x, y+size.getHeight());
            path.closePath();
            
        }
        return path.getPathIterator(m);
        
    }
    
    /**
     * {{@inheritDoc}}
     */
    public PathIterator getPathIterator(){
        return getPathIterator(null);
    }

    /**
     * {{@inheritDoc}}
     */
    public Rectangle getBounds() {
        return new Rectangle(
                    (int)Math.floor(getX()), 
                (int)Math.floor(getY()), 
                (int)Math.ceil(getWidth()), 
                (int)Math.ceil(getHeight())
        );
    }
    
    /**
     * {{@inheritDoc}}
     */
    public float[] getBounds2D(){
        return new float[]{(float)getX(), (float)getY(), (float)getWidth(), (float)getHeight()};
    }
    
    /**
     * {{@inheritDoc}}
     */
    public boolean isRectangle(){
        return true;
    }

    public boolean contains(int x, int y) {
        return contains((double)x, (double)y);
    }

    public Shape intersection(Rectangle rect) {
        Rectangle2D r2 = new Rectangle2D(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
        return intersection(r2);
    }
    
    public void translate(double x, double y){
        this.x+=x;
        this.y+=y;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy