View Javadoc

1   /*
2   
3       dsh-venn  Lightweight components for venn diagrams.
4       Copyright (c) 2009-2013 held jointly by the individual authors.
5   
6       This library is free software; you can redistribute it and/or modify it
7       under the terms of the GNU Lesser General Public License as published
8       by the Free Software Foundation; either version 3 of the License, or (at
9       your option) any later version.
10  
11      This library is distributed in the hope that it will be useful, but WITHOUT
12      ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
13      FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14      License for more details.
15  
16      You should have received a copy of the GNU Lesser General Public License
17      along with this library;  if not, write to the Free Software Foundation,
18      Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.
19  
20      > http://www.fsf.org/licensing/licenses/lgpl.html
21      > http://www.opensource.org/licenses/lgpl-license.php
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   * Immutable implementation of TernaryVennLayout.
43   *
44   * @author  Michael Heuer
45   */
46  public final class TernaryVennLayoutImpl
47      implements TernaryVennLayout
48  {
49      /** Shape for the first set. */
50      private final Shape firstShape;
51  
52      /** Shape for the second set. */
53      private final Shape secondShape;
54  
55      /** Shape for the third set. */
56      private final Shape thirdShape;
57  
58      /** Lune center of the first only area. */
59      private final Point2D firstOnlyLuneCenter;
60  
61      /** Lune center of the second only area. */
62      private final Point2D secondOnlyLuneCenter;
63  
64      /** Lune center of the third only area. */
65      private final Point2D thirdOnlyLuneCenter;
66  
67      /** Lune center of the first second area. */
68      private final Point2D firstSecondLuneCenter;
69  
70      /** Lune center of the first third area. */
71      private final Point2D firstThirdLuneCenter;
72  
73      /** Lune center of the second third area. */
74      private final Point2D secondThirdLuneCenter;
75  
76      /** Lune center of the intersection area. */
77      private final Point2D intersectionLuneCenter;
78  
79      /** Map of lune centers keyed by bit set. */
80      private final Map<ImmutableBitSet, Point2D> luneCenters;
81  
82      /** Bounding rectangle. */
83      private final Rectangle2D boundingRectangle;
84  
85  
86      /**
87       * Create a new ternary venn layout with the specified parameters.
88       *
89       * @param firstShape shape for the first set, must not be null
90       * @param secondShape shape for the second set, must not be null
91       * @param thirdShape shape for the third set, must not be null
92       * @param firstOnlyLuneCenter lune center for the first only area
93       * @param secondOnlyLuneCenter lune center for the second only area
94       * @param thirdOnlyLuneCenter lune center for the third only area
95       * @param firstSecondLuneCenter lune center for the first second area
96       * @param firstThirdLuneCenter lune center for the first third area
97       * @param secondThirdLuneCenter lune center for the second third area
98       * @param intersectionLuneCenter lune center for the intersection area
99       * @param boundingRectangle bounding rectangle, must not be null
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     /** {@inheritDoc} */
156     public Shape firstShape()
157     {
158         return firstShape;
159     }
160 
161     /** {@inheritDoc} */
162     public Shape secondShape()
163     {
164         return secondShape;
165     }
166 
167     /** {@inheritDoc} */
168     public Shape thirdShape()
169     {
170         return thirdShape;
171     }
172 
173     /** {@inheritDoc} */
174     public Point2D firstOnlyLuneCenter()
175     {
176         return firstOnlyLuneCenter;
177     }
178 
179     /** {@inheritDoc} */
180     public Point2D secondOnlyLuneCenter()
181     {
182         return secondOnlyLuneCenter;
183     }
184 
185     /** {@inheritDoc} */
186     public Point2D thirdOnlyLuneCenter()
187     {
188         return thirdOnlyLuneCenter;
189     }
190 
191     /** {@inheritDoc} */
192     public Point2D firstSecondLuneCenter()
193     {
194         return firstSecondLuneCenter;
195     }
196 
197     /** {@inheritDoc} */
198     public Point2D firstThirdLuneCenter()
199     {
200         return firstThirdLuneCenter;
201     }
202 
203     /** {@inheritDoc} */
204     public Point2D secondThirdLuneCenter()
205     {
206         return secondThirdLuneCenter;
207     }
208 
209     /** {@inheritDoc} */
210     public Point2D intersectionLuneCenter()
211     {
212         return intersectionLuneCenter;
213     }
214 
215     /** {@inheritDoc} */
216     public int size()
217     {
218         return 3;
219     }
220 
221     /** {@inheritDoc} */
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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
268     public Rectangle2D boundingRectangle()
269     {
270         return boundingRectangle;
271     }
272 }