CB_UI_Base.Math.CB_RectF.java Source code

Java tutorial

Introduction

Here is the source code for CB_UI_Base.Math.CB_RectF.java

Source

/* 
 * Copyright (C) 2011-2012 team-cachebox.de
 *
 * Licensed under the : GNU General Public License (GPL);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.gnu.org/licenses/gpl.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package CB_UI_Base.Math;

import com.badlogic.gdx.math.Vector2;

import CB_Utils.Lists.CB_List;
import CB_Utils.Util.MoveableList;

/**
 * Eine Struktur fr RectF mit besonderen Methoden Speziel fr die Handhabung in der Verwendung der Berechneten Grssen und Positionen
 * einzelner UI Elemente in Cachebox
 * 
 * @author Longri
 */
public class CB_RectF {
    // Member

    /**
     * Holds all values <br>
     * <br>
     * [0] = Pos.x <br>
     * [1] = Pos.y <br>
     * [2] = width <br>
     * [3] = height <br>
     * [4] = halfWidth <br>
     * [5] = halfHeight <br>
     * [6] = crossPos.x <br>
     * [7] = crossPos.x <br>
     * [8] = centerPos.x <br>
     * [9] = centerPos.x <br>
     */
    protected float member[] = new float[] { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };

    public float getHalfWidth() {
        return member[4];
    }

    public float getHalfHeight() {
        return member[5];
    }

    // Constructors

    /**
     * Constructor der alle Member mit 0 initialisiert!
     */
    public CB_RectF() {
    }

    public CB_RectF(SizeF size) {
        member[3] = size.height;
        member[2] = size.width;
        calcCrossCorner();
    }

    /**
     * Constructor fr ein neues RectF mit Angabe der linken unteren Ecke und der Hhe und Breite
     * 
     * @param X
     * @param Y
     * @param Width
     * @param Height
     */
    public CB_RectF(float X, float Y, float Width, float Height) {
        member[0] = X;
        member[1] = Y;
        member[3] = Height;
        member[2] = Width;
        calcCrossCorner();
    }

    public CB_RectF(CB_RectF rec) {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed!; 
        if (rec != null && rec.member != null)
            System.arraycopy(rec.member, 0, this.member, 0, 10);
    }

    public void setWidth(float Width) {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed!;
        if (member[2] == Width)
            return;
        member[2] = Width;
        calcCrossCorner();
        CallRecChanged();
    }

    public void setHeight(float Height) {
        if (member[3] == Height)
            return;
        member[3] = Height;
        calcCrossCorner();
        CallRecChanged();
    }

    public boolean setSize(SizeF Size) {
        return setSize(Size.width, Size.height);
    }

    /**
     * Setzt die Werte fr Height und Width. Wenn sich einer der Werte gendert hat, wird ein True zurck gegeben, ansonsten False.
     * 
     * @param Width
     * @param Height
     * @return
     */
    public boolean setSize(float Width, float Height) {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed! false; // isDisposed!
        if (member[2] == Width && member[3] == Height)
            return false;
        member[2] = Width;
        member[3] = Height;
        calcCrossCorner();
        CallRecChanged();
        return true;
    }

    public boolean setSize(CB_RectF rec) {
        setSize(rec.member[2], rec.member[3]);
        return true;
    }

    public void setPos(Vector2 Pos) {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed!; // isDisposed!
        if (member[0] == Pos.x && member[1] == Pos.y)
            return;
        member[0] = Pos.x;
        member[1] = Pos.y;
        calcCrossCorner();
    }

    public CB_RectF offset(Vector2 Offset) {
        return offset(Offset.x, Offset.y);
    }

    public CB_RectF offset(float offX, float offY) {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed! null; // isDisposed!
        member[0] += offX;
        member[1] += offY;
        calcCrossCorner();
        return this;
    }

    public float getX() {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed! 0; // isDisposed!
        return member[0];
    }

    public float getY() {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed! 0; // isDisposed!
        return member[1];
    }

    public float getWidth() {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed! 0; // isDisposed!
        return member[2];
    }

    public float getHeight() {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed! 0; // isDisposed!
        return member[3];
    }

    /**
     * Berechnet die rechte obere Ecke
     */
    protected void calcCrossCorner() {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed!;// isDisposed!
        this.member[4] = this.member[2] / 2;
        this.member[5] = this.member[3] / 2;

        this.member[6] = this.member[0] + this.member[2];
        this.member[7] = this.member[1] + this.member[3];
        this.member[8] = this.member[0] + this.member[4];
        this.member[9] = this.member[1] + this.member[5];
    }

    public boolean contains(Vector2 ret) {
        if (ret == null)
            return false;
        return contains(ret.x, ret.y);
    }

    public boolean contains(float x, float y) {
        if (this.member == null)
            return false;

        try {
            // runde
            float rX = Math.round(x);
            float rY = Math.round(y);
            float rTX = Math.round(this.member[0]);
            float rTY = Math.round(this.member[1]);
            float rTCX = Math.round(this.member[6]);
            float rTCY = Math.round(this.member[7]);

            return this.member[2] > 0 && this.member[3] > 0 // check for empty first
                    && rX >= rTX && rX <= rTCX && rY >= rTY && rY <= rTCY;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * liefert True, wenn das bergebene Rechteck kommplett in diese rechteck Passt.
     * 
     * @param rec
     * @return
     */
    public boolean contains(CB_RectF rec) {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed! false; // isDisposed!
        if (rec == null)
            return false;
        boolean ret = this.contains(rec.member[0], rec.member[1]);
        ret &= this.contains(rec.member[6], rec.member[7]);

        return ret;
    }

    private CB_List<SizeChangedEvent> list = new CB_List<SizeChangedEvent>(1);

    public void Add(SizeChangedEvent event) {
        synchronized (list) {
            if (list == null)
                return; // is disposed
            list.add(event);
        }
    }

    public void Remove(SizeChangedEvent event) {
        synchronized (list) {
            if (list == null)
                return; // is disposed
            list.remove(event);
        }
    }

    public void CallRecChanged() {
        synchronized (list) {
            if (list == null)
                return; // is disposed

            resize(this.member[2], this.member[3]);

            if (list.size() > 0) {
                for (int i = 0, n = list.size(); i < n; i++) {
                    list.get(i).sizeChanged();
                }
            }
        }
    }

    public void resize(float width, float height) {
    }

    public boolean equals(CB_RectF rec) {
        if (member == null || rec.member == null)
            return false; // any is disposed!

        // Compare only x,y,width and height
        if (this.member[0] != rec.member[0])
            return false;
        if (this.member[1] != rec.member[1])
            return false;
        if (this.member[2] != rec.member[2])
            return false;
        if (this.member[3] != rec.member[3])
            return false;

        return true;
    }

    public CB_RectF copy() {
        return new CB_RectF(this);
    }

    public void setY(float i) {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed!; // isDisposed!
        if (this.member[1] == i)
            return;
        this.member[1] = i;
        calcCrossCorner();
        CallRecChanged();
    }

    public void setX(float i) {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed!; // isDisposed!
        if (this.member[0] == i)
            return;
        this.member[0] = i;
        calcCrossCorner();
        CallRecChanged();
    }

    // /**
    // * Setzt Height und Width auf die nchst grere Potenz von 2
    // */
    // public void setPO2()
    // {
    // int PO2width = getNextHighestPO2((int) this.member[2]);
    // int PO2height = getNextHighestPO2((int) this.member[3]);
    //
    // setSize(PO2width, PO2height);
    // }

    // /**
    // * Calculates the next highest power of two for a given integer.
    // *
    // * @param n
    // * the number
    // * @return a power of two equal to or higher than n
    // */
    // public static int getNextHighestPO2(int n)
    // {
    // n -= 1;
    // n = n | (n >> 1);
    // n = n | (n >> 2);
    // n = n | (n >> 4);
    // n = n | (n >> 8);
    // n = n | (n >> 16);
    // n = n | (n >> 32);
    // return n + 1;
    // }

    public CB_RectF ScaleCenter(float ScaleFactor) {
        return ScaleCenter(this, ScaleFactor);
    }

    public static CB_RectF ScaleCenter(CB_RectF rectangle, float ScaleFactor) {
        float newWidth = rectangle.getWidth() * ScaleFactor;
        float newHeight = rectangle.getHeight() * ScaleFactor;
        float newX = rectangle.member[0] + ((rectangle.getWidth() - newWidth) / 2);
        float newY = rectangle.member[1] + ((rectangle.getHeight() - newHeight) / 2);
        return new CB_RectF(newX, newY, newWidth, newHeight);
    }

    /**
     * Gibt den ersten Schnittpunkt des Rechtecks zwichen den Punkten P1 und P2 zurck! <img src="doc-files/rec-intersection.png"
     * width=537 height=307>
     * 
     * @param P1
     *            = start Punkt der Linie
     * @param P2
     *            = End Punkt der Line
     * @return Punkt (b) da dieser als erster Schnittpunkt gefunden wird.
     */
    public Vector2 getIntersection(Vector2 P1, Vector2 P2) {
        return getIntersection(P1, P2, 1);
    }

    /**
     * Gibt den ersten Schnittpunkt des Rechtecks zwichen den Punkten P1 und P2 zurck! </br> Wobei die als int bergebene Nummer der
     * Gerade des Rechtecks als erstes berprft wird. </br> <img src="doc-files/rec-intersection.png" width=537 height=307>
     * 
     * @param P1
     *            = start Punkt der Linie
     * @param P2
     *            = End Punkt der Line
     * @param first
     * @return Punkt (b) wenn first=1 </br> Punkt (a) wenn first=2,3 oder 4 </br>
     */
    public Vector2 getIntersection(Vector2 P1, Vector2 P2, int first) {

        // Array mit Geraden Nummern fllen
        if (Geraden.size() < 4) {
            Geraden.add(1);
            Geraden.add(2);
            Geraden.add(3);
            Geraden.add(4);
        }

        Geraden.MoveItemFirst(Geraden.indexOf(first));

        Vector2 ret = new Vector2();

        for (int i = 0, n = Geraden.size(); i < n; i++) {
            switch (Geraden.get(i)) {
            case 1:

                if (com.badlogic.gdx.math.Intersector.intersectSegments(P1, P2,
                        new Vector2(this.member[0], this.member[1]), new Vector2(this.member[6], this.member[1]),
                        ret)) {
                    if (contains(ret))
                        return ret; // 1 unten
                }
                break;

            case 2:
                if (com.badlogic.gdx.math.Intersector.intersectSegments(P1, P2,
                        new Vector2(this.member[0], this.member[1]), new Vector2(this.member[0], this.member[7]),
                        ret)) {
                    if (contains(ret))
                        return ret; // 2 links
                }
                break;

            case 3:
                if (com.badlogic.gdx.math.Intersector.intersectSegments(P1, P2,
                        new Vector2(this.member[6], this.member[7]), new Vector2(this.member[6], this.member[1]),
                        ret)) {
                    if (contains(ret))
                        return ret; // 3 rechts
                }

                break;

            case 4:
                if (com.badlogic.gdx.math.Intersector.intersectSegments(P1, P2,
                        new Vector2(this.member[6], this.member[7]), new Vector2(this.member[0], this.member[7]),
                        ret)) {
                    if (contains(ret))
                        return ret; // 4 oben
                }
                break;
            }
        }

        return null;
    }

    private static MoveableList<Integer> Geraden = new MoveableList<Integer>();

    /**
     * Returns the smallest X coordinate of the framing rectangle of the <code>CB_RectF</code> in <code>double</code> precision.
     * 
     * @return the smallest x coordinate of the framing rectangle of the <code>CB_RectF</code>.
     */
    public float getMinX() {
        return getX();
    }

    /**
     * Returns the smallest Y coordinate of the framing rectangle of the <code>CB_RectF</code> in <code>double</code> precision.
     * 
     * @return the smallest y coordinate of the framing rectangle of the <code>CB_RectF</code>.
     */
    public float getMinY() {
        return getY();
    }

    /**
     * Returns the largest X coordinate of the framing rectangle of the <code>CB_RectF</code> in <code>double</code> precision.
     * 
     * @return the largest x coordinate of the framing rectangle of the <code>CB_RectF</code>.
     */
    public float getMaxX() {
        return getX() + getWidth();
    }

    /**
     * Returns the largest Y coordinate of the framing rectangle of the <code>CB_RectF</code> in <code>double</code> precision.
     * 
     * @return the largest y coordinate of the framing rectangle of the <code>CB_RectF</code>.
     */
    public float getMaxY() {
        return getY() + getHeight();
    }

    public CB_RectF createIntersection(CB_RectF rec) {
        float x1 = Math.max(this.getMinX(), rec.getMinX());
        float y1 = Math.max(this.getMinY(), rec.getMinY());
        float x2 = Math.min(this.getMaxX(), rec.getMaxX());
        float y2 = Math.min(this.getMaxY(), rec.getMaxY());
        return new CB_RectF(x1, y1, x2 - x1, y2 - y1);
    }

    public SizeF getSize() {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed! new SizeF(); // isDisposed!
        return new SizeF(this.member[2], this.member[3]);
    }

    public void setRec(CB_RectF rec) {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed!; // isDisposed!
        if (rec == null)
            return;
        // chk of changes
        if (this.equals(rec))
            return;
        System.arraycopy(rec.member, 0, this.member, 0, 10);
        CallRecChanged();
    }

    @Override
    public String toString() {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed! "disposed Rec"; // isDisposed!
        return "rec X,Y/Width,Height = " + this.getX() + "," + this.getY() + "/" + this.member[2] + ","
                + this.member[3];
    }

    public void setPos(float x, float y) {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed!; // isDisposed!
        // chk of changes
        if (this.member[0] == x && this.member[1] == y)
            return;

        this.member[0] = x;
        this.member[1] = y;
        calcCrossCorner();
        CallRecChanged();
    }

    public float getCenterPosX() {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed! 0; // isDisposed!
        return this.member[8];
    }

    public float getCenterPosY() {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed! 0; // isDisposed!
        return this.member[9];
    }

    public void set(float x, float y, float width, float height) {
        if (member == null)
            throw new IllegalStateException("Is Disposed"); // isDisposed!
        // chk of changes
        if (this.member[0] == x && this.member[1] == y && this.member[2] == width && this.member[3] == height)
            return;
        this.member[0] = x;
        this.member[1] = y;
        this.member[2] = width;
        this.member[3] = height;
        calcCrossCorner();
        CallRecChanged();
    }

    public void dispose() {
        if (list != null) {
            synchronized (list) {
                list.clear();
                list = null;
            }
        }
        member = null;

    }
}