1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.dishevelled.venn.layout;
25
26 import java.awt.Shape;
27
28 import java.awt.geom.Point2D;
29 import java.awt.geom.Rectangle2D;
30
31 import java.util.Map;
32
33 import com.google.common.collect.Maps;
34
35 import org.dishevelled.bitset.ImmutableBitSet;
36
37 import org.dishevelled.venn.BinaryVennLayout;
38
39 import static org.dishevelled.venn.layout.VennLayoutUtils.toImmutableBitSet;
40
41
42
43
44
45
46 public final class BinaryVennLayoutImpl
47 implements BinaryVennLayout
48 {
49
50 private final Shape firstShape;
51
52
53 private final Shape secondShape;
54
55
56 private final Point2D firstOnlyLuneCenter;
57
58
59 private final Point2D secondOnlyLuneCenter;
60
61
62 private final Point2D intersectionLuneCenter;
63
64
65 private final Map<ImmutableBitSet, Point2D> luneCenters;
66
67
68 private final Rectangle2D boundingRectangle;
69
70
71
72
73
74
75
76
77
78
79
80
81 public BinaryVennLayoutImpl(final Shape firstShape,
82 final Shape secondShape,
83 final Point2D firstOnlyLuneCenter,
84 final Point2D secondOnlyLuneCenter,
85 final Point2D intersectionLuneCenter,
86 final Rectangle2D boundingRectangle)
87 {
88 if (firstShape == null)
89 {
90 throw new IllegalArgumentException("firstShape must not be null");
91 }
92 if (secondShape == null)
93 {
94 throw new IllegalArgumentException("secondShape must not be null");
95 }
96 if (boundingRectangle == null)
97 {
98 throw new IllegalArgumentException("boundingRectangle must not be null");
99 }
100
101 this.firstShape = firstShape;
102 this.secondShape = secondShape;
103 this.firstOnlyLuneCenter = firstOnlyLuneCenter;
104 this.secondOnlyLuneCenter = secondOnlyLuneCenter;
105 this.intersectionLuneCenter = intersectionLuneCenter;
106 this.boundingRectangle = boundingRectangle;
107
108 luneCenters = Maps.newHashMapWithExpectedSize(3);
109
110 luneCenters.put(toImmutableBitSet(0), this.firstOnlyLuneCenter);
111 luneCenters.put(toImmutableBitSet(1), this.secondOnlyLuneCenter);
112
113 luneCenters.put(toImmutableBitSet(0, 1), this.intersectionLuneCenter);
114
115 }
116
117
118
119 public Shape firstShape()
120 {
121
122 return firstShape;
123 }
124
125
126 public Shape secondShape()
127 {
128 return secondShape;
129 }
130
131
132 public Point2D firstOnlyLuneCenter()
133 {
134 return firstOnlyLuneCenter;
135 }
136
137
138 public Point2D secondOnlyLuneCenter()
139 {
140 return secondOnlyLuneCenter;
141 }
142
143
144 public Point2D intersectionLuneCenter()
145 {
146 return intersectionLuneCenter;
147 }
148
149
150 public int size()
151 {
152 return 2;
153 }
154
155
156 public Shape get(final int index)
157 {
158 if (index < 0 || index > 1)
159 {
160 throw new IndexOutOfBoundsException("index out of bounds");
161 }
162 switch (index)
163 {
164 case 0:
165 return firstShape;
166 case 1:
167 return secondShape;
168 default:
169 break;
170 }
171 throw new IllegalStateException("invalid index " + index);
172 }
173
174
175 public Point2D luneCenter(final int index, final int... additional)
176 {
177 int maxIndex = size() - 1;
178 if (index < 0 || index > maxIndex)
179 {
180 throw new IndexOutOfBoundsException("index out of bounds");
181 }
182 if (additional != null && additional.length > 0)
183 {
184 if (additional.length > maxIndex)
185 {
186 throw new IndexOutOfBoundsException("too many indices provided");
187 }
188 for (int i = 0, size = additional.length; i < size; i++)
189 {
190 if (additional[i] < 0 || additional[i] > maxIndex)
191 {
192 throw new IndexOutOfBoundsException("additional index [" + i + "] out of bounds");
193 }
194 }
195 }
196 return luneCenters.get(toImmutableBitSet(index, additional));
197 }
198
199
200 public Rectangle2D boundingRectangle()
201 {
202 return boundingRectangle;
203 }
204 }