1/*
2 * Copyright 2012 AndroidPlot.com
3 *
4 *    Licensed under the Apache License, Version 2.0 (the "License");
5 *    you may not use this file except in compliance with the License.
6 *    You may obtain a copy of the License at
7 *
8 *        http://www.apache.org/licenses/LICENSE-2.0
9 *
10 *    Unless required by applicable law or agreed to in writing, software
11 *    distributed under the License is distributed on an "AS IS" BASIS,
12 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 *    See the License for the specific language governing permissions and
14 *    limitations under the License.
15 */
16
17package com.androidplot.xy;
18
19import android.graphics.PointF;
20import android.graphics.RectF;
21import com.androidplot.LineRegion;
22import com.androidplot.util.ValPixConverter;
23
24import java.util.ArrayList;
25import java.util.List;
26
27/**
28 * RectRegion is just a rectangle with additional methods for determining
29 * intersections with other RectRegion instances.
30 */
31public class RectRegion {
32
33    LineRegion xLineRegion;
34    LineRegion yLineRegion;
35    private String label;
36
37    /**
38     *
39     * @param minX
40     * @param maxX
41     * @param minY
42     * @param maxY
43     */
44    public RectRegion(Number minX, Number maxX, Number minY, Number maxY, String label) {
45        xLineRegion = new LineRegion(minX, maxX);
46        yLineRegion = new LineRegion(minY, maxY);
47        this.setLabel(label);
48    }
49
50    @SuppressWarnings("SameParameterValue")
51    public RectRegion(Number minX, Number maxX, Number minY, Number maxY) {
52        this(minX, maxX, minY, maxY, null);
53    }
54
55    public boolean containsPoint(PointF point) {
56        throw new UnsupportedOperationException("Not yet implemented.");
57    }
58
59    public boolean containsValue(Number x, Number y) {
60        throw new UnsupportedOperationException("Not yet implemented.");
61    }
62
63    public boolean containsDomainValue(Number value) {
64        //return RectRegion.isBetween(value, minX, maxX);
65        return xLineRegion.contains(value);
66    }
67
68    public boolean containsRangeValue(Number value) {
69        //return RectRegion.isBetween(value, minY, maxY);
70        return yLineRegion.contains(value);
71    }
72
73    public boolean intersects(RectRegion region) {
74        return intersects(region.getMinX(), region.getMaxX(), region.getMinY(), region.getMaxY());
75    }
76
77
78    /**
79     * Tests whether this region intersects the region defined by params.  Use
80     * null to represent infinity.  Negative and positive infinity is implied by
81     * the boundary edge, ie. a maxX of null equals positive infinity while a
82     * minX of null equals negative infinity.
83     * @param minX
84     * @param maxX
85     * @param minY
86     * @param maxY
87     * @return
88     */
89    public boolean intersects(Number minX, Number maxX, Number minY, Number maxY) {
90        return xLineRegion.intersects(minX, maxX) && yLineRegion.intersects(minY, maxY);
91    }
92
93    public boolean intersects(RectF region, Number visMinX, Number visMaxX, Number visMinY, Number visMaxY) {
94
95        RectF thisRegion = getRectF(region, visMinX.doubleValue(), visMaxX.doubleValue(),
96                visMinY.doubleValue(), visMaxY.doubleValue());
97        return RectF.intersects(thisRegion, region);
98    }
99
100    public RectF getRectF(RectF plotRect, Number visMinX, Number visMaxX, Number visMinY, Number visMaxY) {
101        PointF topLeftPoint = ValPixConverter.valToPix(
102                xLineRegion.getMinVal().doubleValue() != Double.NEGATIVE_INFINITY ? xLineRegion.getMinVal() : visMinX,
103                yLineRegion.getMaxVal().doubleValue() != Double.POSITIVE_INFINITY ? yLineRegion.getMaxVal() : visMaxY,
104                plotRect,
105                visMinX,
106                visMaxX,
107                visMinY,
108                visMaxY);
109        PointF bottomRightPoint = ValPixConverter.valToPix(
110                xLineRegion.getMaxVal().doubleValue() != Double.POSITIVE_INFINITY ? xLineRegion.getMaxVal() : visMaxX,
111                yLineRegion.getMinVal().doubleValue() != Double.NEGATIVE_INFINITY ? yLineRegion.getMinVal() : visMinY,
112                plotRect,
113                visMinX,
114                visMaxX,
115                visMinY,
116                visMaxY);
117        // TODO: figure out why the y-values are inverted
118        return new RectF(topLeftPoint.x, topLeftPoint.y, bottomRightPoint.x, bottomRightPoint.y);
119    }
120
121    /**
122     * Returns a list of XYRegions that either completely or partially intersect the area
123     * defined by params. A null value for any parameter represents infinity / no boundary.
124     * @param regions The list of regions to search through
125     * @param minX
126     * @param maxX
127     * @param minY
128     * @param maxY
129     * @return
130     */
131    public static List<RectRegion> regionsWithin(List<RectRegion> regions, Number minX, Number maxX, Number minY, Number maxY) {
132        ArrayList<RectRegion> intersectingRegions = new ArrayList<RectRegion>();
133        for(RectRegion r : regions) {
134            if(r.intersects(minX, maxX, minY, maxY)) {
135                intersectingRegions.add(r);
136            }
137        }
138        return intersectingRegions;
139    }
140
141
142    public Number getMinX() {
143        return xLineRegion.getMinVal();
144    }
145
146    public void setMinX(double minX) {
147        xLineRegion.setMinVal(minX);
148    }
149
150    public Number getMaxX() {
151        return xLineRegion.getMaxVal();
152    }
153
154    public void setMaxX(Number maxX) {
155        xLineRegion.setMaxVal(maxX);
156    }
157
158    public Number getMinY() {
159        return yLineRegion.getMinVal();
160    }
161
162    public void setMinY(Number minY) {
163        yLineRegion.setMinVal(minY);
164    }
165
166    public Number getMaxY() {
167        return yLineRegion.getMaxVal();
168    }
169
170    public void setMaxY(Number maxY) {
171        yLineRegion.setMaxVal(maxY);
172    }
173
174    public String getLabel() {
175        return label;
176    }
177
178    public void setLabel(String label) {
179        this.label = label;
180    }
181}
182