001/**
002 * 
003 */
004package icy.type.dimension;
005
006import java.awt.Dimension;
007
008/**
009 * The <code>Dimension3D</code> class is to encapsulate a 3D dimension (X,Y,Z).
010 * 
011 * @author Stephane
012 */
013public abstract class Dimension3D implements Cloneable
014{
015    /**
016     * Returns the size of the X dimension in double precision.
017     * 
018     * @return the size of the X dimension.
019     */
020    public abstract double getSizeX();
021
022    /**
023     * Returns the size of the Y dimension in double precision.
024     * 
025     * @return the size of the Y dimension.
026     */
027    public abstract double getSizeY();
028
029    /**
030     * Returns the size of the Z dimension in double precision.
031     * 
032     * @return the size of the Z dimension.
033     */
034    public abstract double getSizeZ();
035
036    /**
037     * Sets the size of the X dimension of this <code>Dimension3D</code> in <code>double</code>
038     * precision.
039     */
040    public abstract void setSizeX(double value);
041
042    /**
043     * Sets the size of the Y dimension of this <code>Dimension3D</code> in <code>double</code>
044     * precision.
045     */
046    public abstract void setSizeY(double value);
047
048    /**
049     * Sets the size of the Z dimension of this <code>Dimension3D</code> in <code>double</code>
050     * precision.
051     */
052    public abstract void setSizeZ(double value);
053
054    /**
055     * Sets the size of this <code>Dimension3D</code> object.
056     * 
057     * @param sizeX
058     *        the new size for the X dimension
059     * @param sizeY
060     *        the new size for the Y dimension
061     * @param sizeZ
062     *        the new size for the Z dimension
063     */
064    public abstract void setSize(double sizeX, double sizeY, double sizeZ);
065
066    /**
067     * Sets the size of this <code>Dimension3D</code> object to match the specified size.
068     * 
069     * @param d
070     *        the new size for the <code>Dimension3D</code> object
071     */
072    public void setSize(Dimension3D d)
073    {
074        setSize(d.getSizeX(), d.getSizeY(), d.getSizeZ());
075    }
076
077    /**
078     * Returns <code>true</code> if the X dimension should be considered as infinite.
079     */
080    public abstract boolean isInfiniteX();
081
082    /**
083     * Returns <code>true</code> if the Y dimension should be considered as infinite.
084     */
085    public abstract boolean isInfiniteY();
086
087    /**
088     * Returns <code>true</code> if the Z dimension should be considered as infinite.
089     */
090    public abstract boolean isInfiniteZ();
091
092    /**
093     * Convert to 2D dimension.
094     */
095    public abstract java.awt.geom.Dimension2D toDimension2D();
096
097    /**
098     * Returns an integer {@link Dimension3D} that encloses the double <code>Dimension3D</code>.<br>
099     * The returned <code>Dimension3D.Integer</code> might also fail to completely enclose the
100     * original double <code>Dimension3D</code> if it overflows the limited range of the integer
101     * data type.
102     * 
103     * @return an integer <code>Dimension3D</code> that completely encloses
104     *         the actual double <code>Dimension3D</code>.
105     */
106
107    public Dimension3D.Integer toInteger()
108    {
109        return new Dimension3D.Integer((int) Math.ceil(getSizeX()), (int) Math.ceil(getSizeY()),
110                (int) Math.ceil(getSizeZ()));
111    }
112
113    @Override
114    public boolean equals(Object obj)
115    {
116        if (obj instanceof Dimension3D)
117        {
118            final Dimension3D dim = (Dimension3D) obj;
119            return (getSizeX() == dim.getSizeX()) && (getSizeY() == dim.getSizeY()) && (getSizeZ() == dim.getSizeZ());
120        }
121
122        return super.equals(obj);
123    }
124
125    /**
126     * Creates a new object of the same class as this object.
127     * 
128     * @return a clone of this instance.
129     * @exception OutOfMemoryError
130     *            if there is not enough memory.
131     * @see java.lang.Cloneable
132     */
133    @Override
134    public Object clone()
135    {
136        try
137        {
138            return super.clone();
139        }
140        catch (CloneNotSupportedException e)
141        {
142            // this shouldn't happen, since we are Cloneable
143            throw new InternalError();
144        }
145    }
146
147    @Override
148    public String toString()
149    {
150        return getClass().getName() + "[" + getSizeX() + "," + getSizeY() + "," + getSizeZ() + "]";
151    }
152
153    public static class Double extends Dimension3D
154    {
155        public double sizeX;
156        public double sizeY;
157        public double sizeZ;
158
159        public Double(double sizeX, double sizeY, double sizeZ)
160        {
161            super();
162
163            this.sizeX = sizeX;
164            this.sizeY = sizeY;
165            this.sizeZ = sizeZ;
166        }
167
168        public Double(double[] sizeXYZ)
169        {
170            final int len = sizeXYZ.length;
171
172            if (len > 0)
173                this.sizeX = sizeXYZ[0];
174            if (len > 1)
175                this.sizeY = sizeXYZ[1];
176            if (len > 2)
177                this.sizeZ = sizeXYZ[2];
178        }
179
180        public Double()
181        {
182            this(0d, 0d, 0d);
183        }
184
185        @Override
186        public double getSizeX()
187        {
188            return sizeX;
189        }
190
191        @Override
192        public double getSizeY()
193        {
194            return sizeY;
195        }
196
197        @Override
198        public double getSizeZ()
199        {
200            return sizeZ;
201        }
202
203        @Override
204        public void setSizeX(double value)
205        {
206            sizeX = value;
207        }
208
209        @Override
210        public void setSizeY(double value)
211        {
212            sizeY = value;
213        }
214
215        @Override
216        public void setSizeZ(double value)
217        {
218            sizeZ = value;
219        }
220
221        @Override
222        public void setSize(double sizeX, double sizeY, double sizeZ)
223        {
224            this.sizeX = sizeX;
225            this.sizeY = sizeY;
226            this.sizeZ = sizeZ;
227        }
228
229        @Override
230        public boolean isInfiniteX()
231        {
232            return (getSizeX() == java.lang.Double.POSITIVE_INFINITY);
233        }
234
235        @Override
236        public boolean isInfiniteY()
237        {
238            return (getSizeY() == java.lang.Double.POSITIVE_INFINITY);
239        }
240
241        @Override
242        public boolean isInfiniteZ()
243        {
244            return (getSizeZ() == java.lang.Double.POSITIVE_INFINITY);
245        }
246
247        @Override
248        public java.awt.geom.Dimension2D toDimension2D()
249        {
250            return new Dimension2D.Double(sizeX, sizeY);
251        }
252    }
253
254    public static class Float extends Dimension3D
255    {
256        public float sizeX;
257        public float sizeY;
258        public float sizeZ;
259
260        public Float(float sizeX, float sizeY, float sizeZ)
261        {
262            super();
263
264            this.sizeX = sizeX;
265            this.sizeY = sizeY;
266            this.sizeZ = sizeZ;
267        }
268
269        public Float(float[] sizeXYZ)
270        {
271            final int len = sizeXYZ.length;
272
273            if (len > 0)
274                this.sizeX = sizeXYZ[0];
275            if (len > 1)
276                this.sizeY = sizeXYZ[1];
277            if (len > 2)
278                this.sizeZ = sizeXYZ[2];
279        }
280
281        public Float()
282        {
283            this(0f, 0f, 0f);
284        }
285
286        @Override
287        public double getSizeX()
288        {
289            return sizeX;
290        }
291
292        @Override
293        public double getSizeY()
294        {
295            return sizeY;
296        }
297
298        @Override
299        public double getSizeZ()
300        {
301            return sizeZ;
302        }
303
304        @Override
305        public void setSizeX(double value)
306        {
307            sizeX = (float) value;
308        }
309
310        @Override
311        public void setSizeY(double value)
312        {
313            sizeY = (float) value;
314        }
315
316        @Override
317        public void setSizeZ(double value)
318        {
319            sizeZ = (float) value;
320        }
321
322        @Override
323        public void setSize(double sizeX, double sizeY, double sizeZ)
324        {
325            this.sizeX = (float) sizeX;
326            this.sizeY = (float) sizeY;
327            this.sizeZ = (float) sizeZ;
328        }
329
330        @Override
331        public boolean isInfiniteX()
332        {
333            return (getSizeX() == java.lang.Float.POSITIVE_INFINITY);
334        }
335
336        @Override
337        public boolean isInfiniteY()
338        {
339            return (getSizeY() == java.lang.Float.POSITIVE_INFINITY);
340        }
341
342        @Override
343        public boolean isInfiniteZ()
344        {
345            return (getSizeZ() == java.lang.Float.POSITIVE_INFINITY);
346        }
347
348        @Override
349        public java.awt.geom.Dimension2D toDimension2D()
350        {
351            return new Dimension2D.Float(sizeX, sizeY);
352        }
353    }
354
355    public static class Integer extends Dimension3D
356    {
357        public int sizeX;
358        public int sizeY;
359        public int sizeZ;
360
361        public Integer(int sizeX, int sizeY, int sizeZ)
362        {
363            super();
364
365            this.sizeX = sizeX;
366            this.sizeY = sizeY;
367            this.sizeZ = sizeZ;
368        }
369
370        public Integer(int[] sizeXYZ)
371        {
372            final int len = sizeXYZ.length;
373
374            if (len > 0)
375                this.sizeX = sizeXYZ[0];
376            if (len > 1)
377                this.sizeY = sizeXYZ[1];
378            if (len > 2)
379                this.sizeZ = sizeXYZ[2];
380        }
381
382        public Integer()
383        {
384            this(0, 0, 0);
385        }
386
387        @Override
388        public double getSizeX()
389        {
390            return sizeX;
391        }
392
393        @Override
394        public double getSizeY()
395        {
396            return sizeY;
397        }
398
399        @Override
400        public double getSizeZ()
401        {
402            return sizeZ;
403        }
404
405        @Override
406        public void setSizeX(double value)
407        {
408            sizeX = (int) Math.ceil(value);
409        }
410
411        @Override
412        public void setSizeY(double value)
413        {
414            sizeY = (int) Math.ceil(value);
415        }
416
417        @Override
418        public void setSizeZ(double value)
419        {
420            sizeZ = (int) Math.ceil(value);
421        }
422
423        @Override
424        public void setSize(double sizeX, double sizeY, double sizeZ)
425        {
426            this.sizeX = (int) Math.ceil(sizeX);
427            this.sizeY = (int) Math.ceil(sizeY);
428            this.sizeZ = (int) Math.ceil(sizeZ);
429        }
430
431        @Override
432        public boolean isInfiniteX()
433        {
434            return (getSizeX() == java.lang.Integer.MAX_VALUE);
435        }
436
437        @Override
438        public boolean isInfiniteY()
439        {
440            return (getSizeY() == java.lang.Integer.MAX_VALUE);
441        }
442
443        @Override
444        public boolean isInfiniteZ()
445        {
446            return (getSizeZ() == java.lang.Integer.MAX_VALUE);
447        }
448
449        @Override
450        public java.awt.geom.Dimension2D toDimension2D()
451        {
452            return new Dimension(sizeX, sizeY);
453        }
454
455        @Override
456        public Integer toInteger()
457        {
458            return (Integer) clone();
459        }
460    }
461}