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.TernaryVennLayout;
38
39 import static org.dishevelled.venn.layout.VennLayoutUtils.toImmutableBitSet;
40
41
42
43
44
45
46 public final class TernaryVennLayoutImpl
47 implements TernaryVennLayout
48 {
49
50 private final Shape firstShape;
51
52
53 private final Shape secondShape;
54
55
56 private final Shape thirdShape;
57
58
59 private final Point2D firstOnlyLuneCenter;
60
61
62 private final Point2D secondOnlyLuneCenter;
63
64
65 private final Point2D thirdOnlyLuneCenter;
66
67
68 private final Point2D firstSecondLuneCenter;
69
70
71 private final Point2D firstThirdLuneCenter;
72
73
74 private final Point2D secondThirdLuneCenter;
75
76
77 private final Point2D intersectionLuneCenter;
78
79
80 private final Map<ImmutableBitSet, Point2D> luneCenters;
81
82
83 private final Rectangle2D boundingRectangle;
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 public TernaryVennLayoutImpl(final Shape firstShape,
102 final Shape secondShape,
103 final Shape thirdShape,
104 final Point2D firstOnlyLuneCenter,
105 final Point2D secondOnlyLuneCenter,
106 final Point2D thirdOnlyLuneCenter,
107 final Point2D firstSecondLuneCenter,
108 final Point2D firstThirdLuneCenter,
109 final Point2D secondThirdLuneCenter,
110 final Point2D intersectionLuneCenter,
111 final Rectangle2D boundingRectangle)
112 {
113 if (firstShape == null)
114 {
115 throw new IllegalArgumentException("firstShape must not be null");
116 }
117 if (secondShape == null)
118 {
119 throw new IllegalArgumentException("secondShape must not be null");
120 }
121 if (thirdShape == null)
122 {
123 throw new IllegalArgumentException("thirdShape must not be null");
124 }
125 if (boundingRectangle == null)
126 {
127 throw new IllegalArgumentException("boundingRectangle must not be null");
128 }
129 this.firstShape = firstShape;
130 this.secondShape = secondShape;
131 this.thirdShape = thirdShape;
132 this.firstOnlyLuneCenter = firstOnlyLuneCenter;
133 this.secondOnlyLuneCenter = secondOnlyLuneCenter;
134 this.thirdOnlyLuneCenter = thirdOnlyLuneCenter;
135 this.firstSecondLuneCenter = firstSecondLuneCenter;
136 this.firstThirdLuneCenter = firstThirdLuneCenter;
137 this.secondThirdLuneCenter = secondThirdLuneCenter;
138 this.intersectionLuneCenter = intersectionLuneCenter;
139 this.boundingRectangle = boundingRectangle;
140
141 luneCenters = Maps.newHashMapWithExpectedSize(7);
142
143 luneCenters.put(toImmutableBitSet(0), this.firstOnlyLuneCenter);
144 luneCenters.put(toImmutableBitSet(1), this.secondOnlyLuneCenter);
145 luneCenters.put(toImmutableBitSet(2), this.thirdOnlyLuneCenter);
146
147 luneCenters.put(toImmutableBitSet(0, 1), this.firstSecondLuneCenter);
148 luneCenters.put(toImmutableBitSet(0, 2), this.firstThirdLuneCenter);
149 luneCenters.put(toImmutableBitSet(1, 2), this.secondThirdLuneCenter);
150
151 luneCenters.put(toImmutableBitSet(0, 1, 2), this.intersectionLuneCenter);
152 }
153
154
155
156 public Shape firstShape()
157 {
158 return firstShape;
159 }
160
161
162 public Shape secondShape()
163 {
164 return secondShape;
165 }
166
167
168 public Shape thirdShape()
169 {
170 return thirdShape;
171 }
172
173
174 public Point2D firstOnlyLuneCenter()
175 {
176 return firstOnlyLuneCenter;
177 }
178
179
180 public Point2D secondOnlyLuneCenter()
181 {
182 return secondOnlyLuneCenter;
183 }
184
185
186 public Point2D thirdOnlyLuneCenter()
187 {
188 return thirdOnlyLuneCenter;
189 }
190
191
192 public Point2D firstSecondLuneCenter()
193 {
194 return firstSecondLuneCenter;
195 }
196
197
198 public Point2D firstThirdLuneCenter()
199 {
200 return firstThirdLuneCenter;
201 }
202
203
204 public Point2D secondThirdLuneCenter()
205 {
206 return secondThirdLuneCenter;
207 }
208
209
210 public Point2D intersectionLuneCenter()
211 {
212 return intersectionLuneCenter;
213 }
214
215
216 public int size()
217 {
218 return 3;
219 }
220
221
222 public Shape get(final int index)
223 {
224 if (index < 0 || index > 2)
225 {
226 throw new IndexOutOfBoundsException("index out of bounds");
227 }
228 switch (index)
229 {
230 case 0:
231 return firstShape;
232 case 1:
233 return secondShape;
234 case 2:
235 return thirdShape;
236 default:
237 break;
238 }
239 throw new IllegalStateException("invalid index " + index);
240 }
241
242
243 public Point2D luneCenter(final int index, final int... additional)
244 {
245 int maxIndex = size() - 1;
246 if (index < 0 || index > maxIndex)
247 {
248 throw new IndexOutOfBoundsException("index out of bounds");
249 }
250 if (additional != null && additional.length > 0)
251 {
252 if (additional.length > maxIndex)
253 {
254 throw new IndexOutOfBoundsException("too many indices provided");
255 }
256 for (int i = 0, size = additional.length; i < size; i++)
257 {
258 if (additional[i] < 0 || additional[i] > maxIndex)
259 {
260 throw new IndexOutOfBoundsException("additional index [" + i + "] out of bounds");
261 }
262 }
263 }
264 return luneCenters.get(toImmutableBitSet(index, additional));
265 }
266
267
268 public Rectangle2D boundingRectangle()
269 {
270 return boundingRectangle;
271 }
272 }