decluttermatrix.java

来自「OpenMap是一个基于JavaBeansTM的开发工具包。利用OpenMap你」· Java 代码 · 共 1,032 行 · 第 1/3 页

JAVA
1,032
字号
        /**         * Test to see if the object is on the matrix. Assumes that the matrix         * is not null.         *          * @return true if object is on matrix.         */        public boolean objOnMatrix(int objXIndex, int objYIndex,                                   int objIndexLength, int objIndexHeight) {            if (objXIndex + objIndexLength < 0 || // left off-matrix                    objYIndex + objIndexHeight < 0 || // below matrix                    // right off-matrix and above matrix                    objXIndex > maxx || objYIndex > maxy) {                return false;            }            return true;        }    }    /**     * Set whether names can appear partially on/off the map. True means they     * can, i.e., the spaces off the map are by default, clear.     */    public void setAllowPartials(boolean value) {        allowPartials = value;    }    /**     * Find out whether the spaces off the map are counted as clear and     * available. If they are, then objects can appear partially on the map.     */    public boolean isAllowPartials() {        return allowPartials;    }    /** ******************************************************************* */    /**     * Construct a new DeclutterMatrix, given the screen dimensions and the size     * of the matrix cells     */    public DeclutterMatrix(int width, int height, int x_pix_interval,            int y_pix_interval) {        this.width = width;        this.height = height;        if (x_pix_interval != 0) {            this.x_pix_interval = x_pix_interval;        } else {            x_pix_interval = 1;        }        if (y_pix_interval != 0) {            this.y_pix_interval = y_pix_interval;        } else {            y_pix_interval = 1;        }        this.matrix = null;        this.maxx = (this.width / this.x_pix_interval) - 1;        this.maxy = (this.height / this.y_pix_interval) - 1;        create();        Debug.message("declutter", "Decluttering matrix created."                + "  Width = " + width + " Height = " + height);    }    /**     * Construct a new matrix, given the screen dimensions, and using the     * default matrix cell size     */    public DeclutterMatrix(int width, int height) {        this(width, height, 1, 1);    }    /** Create a new matrix, with null dimensions */    public DeclutterMatrix() {        this(0, 0);    }    /*     * Any of these delete the current matrix if it exists and resets the     * variable. create() needs to be called to recreate a new matrix after all     * the changes.     */    public void setXInterval(int x_pix_interval) {        if (x_pix_interval != 0) {            this.x_pix_interval = x_pix_interval;        } else {            this.x_pix_interval = 1; // To avoid DBZ error?        }        this.maxx = (this.width / this.x_pix_interval) - 1;        needToRecreate = true;        Debug.message("declutter",                "Decluttering matrix: x_pix_interval changed to "                        + x_pix_interval);    }    public void setYInterval(int y_pix_interval) {        if (y_pix_interval != 0) {            this.y_pix_interval = y_pix_interval;        } else {            this.y_pix_interval = 1;        }        this.maxy = (this.height / this.y_pix_interval) - 1;        needToRecreate = true;        Debug.message("declutter",                "Decluttering matrix: y_pix_interval changed to "                        + y_pix_interval);    }    public void setWidth(int width) {        this.width = width;        this.maxx = (this.width / this.x_pix_interval) - 1;        needToRecreate = true;        Debug.message("declutter", "Decluttering matrix: Width reset to "                + width);    }    public void setHeight(int height) {        this.height = height;        this.maxy = (this.height / this.y_pix_interval) - 1;        needToRecreate = true;        Debug.message("declutter", "Decluttering matrix: height reset to "                + height);    }    /**     * Allocate the matrix.     *      * @return true if successful, and if the height and width settings were     *         valid (>0).     */    public boolean create() {        if ((height > 0) && (width > 0)) {            matrix = new boolean[maxx + 1][maxy + 1];            needToRecreate = false;            return true;        }        needToRecreate = true;        return false;    }    /**     * Query whether the matrix is clear, given a set of indexes.     *      * @param indexes the set of indexes     * @param markAsTaken mark the spaces as used if they are previously clear.     * @return true if they were clear previously.     */    protected boolean isClear(MatrixIndexes indexes, boolean markAsTaken) {        Debug.message("declutterdetail",                "DeclutterMatrix: Checking space for clear.");        if (this.matrix == null) {            return false;        }        if (!indexes.withinMatrix) {            // But, withinMatrix doesn't tell you if there is a            // partial. It only tells you if any part of the object            // is over the matrix. So, if it's not within the Matrix,            // the answer should be yes, all the time, because you            // don't have to declutter what you can't see...            // return allowPartials;            return true;        }        if (!allowPartials && indexes.partial) {            return false;        }        // OK - the above check should verify that some part of the        // object is on the matrix - so there is a reason to set the        // limits for the matrix search below, and not worry about        // dealing with funky index values.        boolean notClear = false;        // Since we have the matrix index limits, have two loops, the        // first to check for the open cells, the other to mark the        // cells as occupied. The second loop only gets run if the        // markAsTaken flag is set by the caller.        for (int taken = 0; taken < 2; taken++) {            // Check to see if the horizontal indexes are on the            // matrix - i should be at least greater than zero here,            // as should j.            for (int i = indexes.xStart; i <= indexes.xEnd; i++) {                // Check for loop - the first loop is to see if                // the spaces are open.                if (taken == 0) {                    notClear = isMatrixLocationTaken(i,                            indexes.yStart,                            indexes.yEnd - indexes.yStart + 1);                    if (notClear) {                        return false;                    }                } else {                    // The second loop is to mark the cells as                    // taken                    setTaken(i, indexes.yStart, indexes.yEnd - indexes.yStart                            + 1);                }            }            // This will prevent the second loop from occuring if it's            // not supposed to - the caller just wanted to check the            // spaces, rather than check and mark.            if (!markAsTaken) {                return true;            }        }        return true;    }    /**     * Check a vertical portion of the matrix, to see if it has already been     * taken. If a query occurs that is outside the matrix, this returns false.     *      * @param horizontalIndex the horizontal index of the matrix to check.     * @param verticalIndex the vertical starting index of the matrix to check.     * @param numCellsToCheck the number of matrix cells to check for taken.     * @return true if taken, false if available.     */    protected boolean isMatrixLocationTaken(int horizontalIndex,                                            int verticalIndex,                                            int numCellsToCheck) {        try {            for (int i = numCellsToCheck - 1; i >= 0; i--) {                if (matrix[horizontalIndex][verticalIndex + i]) {                    return true;                }            }        } catch (ArrayIndexOutOfBoundsException aioobe) {            return allowPartials;        }        return false;    }    /**     * Mark a vertical portion of the matrix as taken.     *      * @param horizontalIndex the horizontal index of the matrix to mark.     * @param verticalIndex the vertical starting index of the matrix to mark.     * @param numCellsToMark the number of matrix cells to mark as taken.     */    protected void setTaken(int horizontalIndex, int verticalIndex,                            int numCellsToMark) {        try {            for (int i = numCellsToMark - 1; i >= 0; i--) {                matrix[horizontalIndex][verticalIndex + i] = true;            }        } catch (ArrayIndexOutOfBoundsException aioobe) {        }    }    /**     * SetTaken returns true if the space was clear before the it was taken,     * false if it was not. Either way, the spaces are marked. Except if the     * matrix is not built, in which case false is returned anyway.     *      * @param indexes the start and end matrix indexes for an object.     * @return true if successful.     */    protected boolean setTaken(MatrixIndexes indexes) {        if (this.matrix == null) {            return false;        }        if (!indexes.withinMatrix) {            return allowPartials;        }        for (int i = indexes.xStart; i < indexes.xEnd; i++) {            setTaken(i, indexes.yStart, indexes.yEnd - indexes.yStart + 1);        }        return true;    }    /**     * Set an area as taken, given a point and a length of pixels. The length is     * checked from left to right.     */    public boolean setTaken(Point point, int pixelLength) {        return setTaken(point, pixelLength, y_pix_interval);    }    /**     * Set an area as taken, given a point, a length of pixels and a height of     * pixels. The length is from left to right, the height from the bottom to     * top (NOT like screen coordinates)     */    public boolean setTaken(Point point, int pixelLength, int pixelHeight) {        if (needToRecreate)            create();        indexes.setFromPixels(point.x, point.y, pixelLength, pixelHeight);        return setTaken(indexes);    }    /**     * The method to call if you are trying to set something in an open place,     * anywhere on the map.     *      * @param point the window point     * @param pixelLength the pixel length of space from left to right.     * @param pixelHeight the pixel height from bottom to top.     * @return Point of closest open space.     */    public Point setNextOpen(Point point, int pixelLength, int pixelHeight) {        return setNextOpen(point, pixelLength, pixelHeight, -1);    }    /**     * The method to call if you are trying to set something in an open place,     * but want to limit how far away the object could be placed.     *      * @param point the window point     * @param pixelLength the pixel length of space from left to right.     * @param pixelHeight the pixel height from bottom to top.     * @param pixelAwayLimit the pixel distance away from the original location     *        that where an object will be discarded if it's not at least that     *        close. -1 means find anywhere on the map where the object will     *        fit.     * @return Point of closest open space.     */    public Point setNextOpen(Point point, int pixelLength, int pixelHeight,                             int pixelAwayLimit) {        Debug.message("declutterdetail",                "DeclutterMatrix: Trying to find an open space.");        if (needToRecreate)            create();        boolean set = false;        // mark the original spot. These are indexes, not pixels.        int windex = point.x / x_pix_interval;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?