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

com.threerings.puzzle.util.PointSet Maven / Gradle / Ivy

The newest version!
//
// $Id$
//
// Vilya library - tools for developing networked games
// Copyright (C) 2002-2012 Three Rings Design, Inc., All Rights Reserved
// http://code.google.com/p/vilya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.puzzle.util;

import java.util.Iterator;

import java.awt.Point;

import static com.threerings.puzzle.Log.log;

/**
 * The point set class provides an efficient implementation of a set containing two-dimensional
 * point values as (x, y).
 */
public class PointSet
{
    /**
     * Creates a point set that can contain points within the given range of values.
     *
     * @param rangeX the maximum x-axis range.
     * @param rangeY the maximum y-axis range.
     */
    public PointSet (int rangeX, int rangeY)
    {
        _rangeX = rangeX;
        _rangeY = rangeY;
        _points = new boolean[rangeX][rangeY];
    }

    /**
     * Adds a point to the set and returns whether the point was already present in the set.
     *
     * @param x the point x-coordinate.
     * @param y the point y-coordinate.
     *
     * @return true if the point was already present, false if not.
     */
    public boolean add (int x, int y)
    {
        boolean present = _points[x][y];
        _points[x][y] = true;
        if (!present) {
            _count++;
        }
        return present;
    }

    /**
     * Adds all points in the given set to this set.
     *
     * @param set the set containing points to add.
     */
    public void addAll (PointSet set)
    {
        Point pt;
        Iterator iter = set.iterator();
        while ((pt = iter.next()) != null) {
            add(pt.x, pt.y);
        }
    }

    /**
     * Clears all points from this set.
     */
    public void clear ()
    {
        if (_count == 0) {
            // no need to clear anything
            return;
        }

        for (int xx = 0; xx < _rangeX; xx++) {
            for (int yy = 0; yy < _rangeY; yy++) {
                _points[xx][yy] = false;
            }
        }
        _count = 0;
    }

    /**
     * Returns whether this set contains the given point.
     *
     * @param x the point x-coordinate.
     * @param y the point y-coordinate.
     *
     * @return true if the set contains the point, false if not.
     */
    public boolean contains (int x, int y)
    {
        return (_points[x][y]);
    }

    /**
     * Returns whether this set is empty.
     *
     * @return true if the set is empty, false if not.
     */
    public boolean isEmpty ()
    {
        return (_count == 0);
    }

    /**
     * Returns an iterator that iterates over the points in this set, returning them as
     * {@link Point} objects. Note that the iterator uses a single point object internally, and so
     * callers should create their own copy of the point if they plan to do something fancy with
     * it.
     *
     * @return the iterator over the set's points.
     */
    public Iterator iterator ()
    {
        return new PointIterator();
    }

    /**
     * Removes the given point from the set and returns whether the point was present in the set.
     *
     * @param x the point x-coordinate.
     * @param y the point y-coordinate.
     *
     * @return true if the point was present, false if not.
     */
    public boolean remove (int x, int y)
    {
        boolean present = _points[x][y];
        _points[x][y] = false;
        if (present) {
            _count--;
        }
        return present;
    }

    /**
     * Returns the number of points in the set.
     *
     * @return the number of points.
     */
    public int size ()
    {
        return _count;
    }

    @Override
    public String toString ()
    {
        StringBuilder buf = new StringBuilder();
        buf.append("[");
        Iterator iter = iterator();
        Point val;
        while ((val = iter.next()) != null) {
            buf.append("(").append(val.x);
            buf.append(",").append(val.y);
            buf.append(")");

            if (iter.hasNext()) {
                buf.append(", ");
            }
        }
        return buf.append("]").toString();
    }

    protected class PointIterator implements Iterator
    {
        public boolean hasNext ()
        {
            return (_curCount < _count);
        }

        public Point next ()
        {
            if (_curCount == _count) {
                return null;
            }

            while (!_points[_curX][_curY]) {
                advance();
            }

            _curCount++;
            _point.setLocation(_curX, _curY);

            if (_curCount < _count) {
                advance();
            }

            return _point;
        }

        public void remove ()
        {
            throw new UnsupportedOperationException();
        }

        protected void advance ()
        {
            if ((++_curX) >= _rangeX) {
                _curX = 0;
                _curY++;
            }

            if (_curY >= _rangeY) {
                log.warning("Advanced past point range.");
                _curY = 0;
            }
        }

        protected int _curCount = 0;
        protected int _curX = 0, _curY = 0;
        protected Point _point = new Point();
    }

    /** The dimensions of the point array. */
    protected int _rangeX, _rangeY;

    /** The points in the set. */
    protected boolean _points[][];

    /** The number of points in the set. */
    protected int _count;
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy