~ubuntu-branches/debian/squeeze/latexdraw/squeeze

« back to all changes in this revision

Viewing changes to latexDraw/figures/Ellipse.java

  • Committer: Bazaar Package Importer
  • Author(s): Stuart Prescott
  • Date: 2009-05-03 23:49:35 UTC
  • Revision ID: james.westby@ubuntu.com-20090503234935-cls7n48x018g0vk2
Tags: upstream-2.0.2+1
ImportĀ upstreamĀ versionĀ 2.0.2+1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package latexDraw.figures;
 
2
 
 
3
import java.awt.*;
 
4
import java.awt.geom.*;
 
5
import java.io.IOException;
 
6
import java.io.ObjectInputStream;
 
7
 
 
8
import latexDraw.figures.properties.BordersMovable;
 
9
import latexDraw.figures.properties.DoubleBoundaryable;
 
10
import latexDraw.psTricks.DviPsColors;
 
11
import latexDraw.psTricks.PSTricksConstants;
 
12
import latexDraw.ui.LaTeXDrawFrame;
 
13
import latexDraw.ui.components.MagneticGrid;
 
14
import latexDraw.util.LaTeXDrawPoint2D;
 
15
 
 
16
 
 
17
/** 
 
18
 * This class defines an Ellipse.<br>
 
19
 *<br>
 
20
 * This file is part of LaTeXDraw<br>
 
21
 * Copyright (c) 2005-2008 Arnaud BLOUIN<br>
 
22
 *<br>
 
23
 *  LaTeXDraw is free software; you can redistribute it and/or modify
 
24
 *  it under the terms of the GNU General Public License as published by
 
25
 *  the Free Software Foundation; either version 2 of the License, or
 
26
 *  (at your option) any later version.<br>
 
27
 *<br>
 
28
 *  LaTeXDraw is distributed without any warranty; without even the 
 
29
 *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
 
30
 *  PURPOSE. See the GNU General Public License for more details.<br>
 
31
 *<br>
 
32
 * 01/20/06<br>
 
33
 * @author Arnaud BLOUIN<br>
 
34
 * @version 2.0.0<br>
 
35
 */
 
36
public class Ellipse extends Figure implements BordersMovable, DoubleBoundaryable
 
37
{
 
38
        private static final long serialVersionUID = 1L;
 
39
 
 
40
 
 
41
        /**
 
42
         * The constructor by default
 
43
         */
 
44
        public Ellipse(boolean increaseMeter)
 
45
        {
 
46
                this(new LaTeXDrawPoint2D(), new LaTeXDrawPoint2D(), new LaTeXDrawPoint2D(), new LaTeXDrawPoint2D(), increaseMeter);
 
47
        }
 
48
        
 
49
        
 
50
                
 
51
        /**
 
52
         * The constructor using four points
 
53
         * @param pt1 The top left point of rectangle containing the ellipse
 
54
         * @param pt2 The top right point of the rectangle containing the ellipse
 
55
         * @param pt3 The bottom left point
 
56
         * @param pt4 The bottom right point
 
57
         */
 
58
        public Ellipse(LaTeXDrawPoint2D pt1, LaTeXDrawPoint2D pt2, LaTeXDrawPoint2D pt3, LaTeXDrawPoint2D pt4, boolean increaseMeter)
 
59
        {
 
60
                super(increaseMeter);
 
61
                borders = new LaTeXDrawRectangle(pt1, pt2, pt3, pt4, false);
 
62
                updateGravityCenter();
 
63
                shape = getInsideOutsideOrMiddleBorders();
 
64
        }
 
65
        
 
66
        
 
67
        
 
68
        /**
 
69
         * @param f The figure to copy
 
70
         * @param sameNumber True if the figure will have the same number of the copy.
 
71
         */
 
72
        public Ellipse(Figure f, boolean sameNumber)
 
73
        {
 
74
                super(f, sameNumber);
 
75
                
 
76
                try 
 
77
                { 
 
78
                        borders = new LaTeXDrawRectangle((LaTeXDrawPoint2D)f.getBordersPoint(0).clone(),
 
79
                                                                (LaTeXDrawPoint2D)f.getBordersPoint(-1).clone(), false);
 
80
                        updateGravityCenter();
 
81
                        updateShape();
 
82
                        LaTeXDrawPoint2D nw = borders.getTheNWPoint();
 
83
                        LaTeXDrawPoint2D cg = getGravityCenter();
 
84
                        double c = Math.abs(cg.x-nw.x)*3./2.25;
 
85
                        double a = (Math.sqrt((cg.x-nw.x+c)*(cg.x-nw.x+c)+((cg.y-nw.y)*(cg.y-nw.y)))+
 
86
                                                Math.sqrt((cg.x-nw.x-c)*(cg.x-nw.x-c)+((cg.y-nw.y)*(cg.y-nw.y))))/2.;
 
87
                        double b = Math.sqrt(a*a-c*c);
 
88
                        borders.setFirstPoint(cg.x-a, cg.y-b);
 
89
                        borders.setLastPoint(cg.x+a, cg.y+b);
 
90
                } 
 
91
                catch (Exception e)
 
92
                { borders = new LaTeXDrawRectangle(false); }
 
93
                
 
94
                updateGravityCenter();
 
95
                updateShape();
 
96
        }
 
97
 
 
98
 
 
99
 
 
100
        @Override
 
101
        public void onDragged(Point formerPt, Point newPt) 
 
102
        {
 
103
                if(formerPt.equals(newPt)) return;
 
104
 
 
105
                borders.onDragged(formerPt, newPt);
 
106
                rotationAngle = borders.getRotationAngle();//update the angle(when rotation)
 
107
                updateGravityCenter();//update centre of gravity when reshaping
 
108
                shape = getInsideOutsideOrMiddleBorders();
 
109
        }
 
110
 
 
111
        
 
112
        
 
113
        
 
114
        @Override
 
115
        public void draw(Graphics2D g, Object antiAlias, Object rendering, Object alphaInter, Object colorRendering)
 
116
        {
 
117
                LaTeXDrawPoint2D NW = borders.getTheNWPoint(), SE = borders.getTheSEPoint();
 
118
                Color formerCol = g.getColor();
 
119
                double cx = (NW.x+SE.x)/2., cy = (NW.y+SE.y)/2.;
 
120
                double c2x = Math.cos(rotationAngle)*cx - Math.sin(rotationAngle)*cy;
 
121
                double c2y = Math.sin(rotationAngle)*cx + Math.cos(rotationAngle)*cy;
 
122
                double c3x = Math.cos(-rotationAngle)*(cx-c2x) - Math.sin(-rotationAngle)*(cy-c2y);
 
123
                double c3y = Math.sin(-rotationAngle)*(cx-c2x) + Math.cos(-rotationAngle)*(cy-c2y);
 
124
                double dx=0, dy=0;
 
125
                boolean changeFillStyle = false;
 
126
 
 
127
                if(rotationAngle%(Math.PI*2)!=0)
 
128
                {               
 
129
                        g.rotate(rotationAngle);
 
130
                        g.translate(c3x,c3y);
 
131
                }
 
132
                
 
133
                if(hasShadow)
 
134
                {
 
135
                        LaTeXDrawPoint2D cg = getGravityCenter();
 
136
                        LaTeXDrawPoint2D shadowCg = (LaTeXDrawPoint2D)cg.clone();
 
137
                        shadowCg.setLocation(cg.x+shadowSize, cg.y);
 
138
                        shadowCg = Figure.rotatePoint(shadowCg, cg, shadowAngle);
 
139
                        dx = shadowCg.x-cg.x;
 
140
                        dy = cg.y-shadowCg.y;
 
141
                }
 
142
 
 
143
                if(hasDoubleBoundary)
 
144
                {
 
145
                        Shape s0 = shape;
 
146
                        Shape s[] = getDbleBoundariesOutInOrMiddle(s0);
 
147
                        Shape s1, s2, s3;
 
148
 
 
149
                        if(bordersPosition.equals(PSTricksConstants.BORDERS_INSIDE))
 
150
                        {
 
151
                                s1 = s0;
 
152
                                s2 = s[0];
 
153
                                s3 = s[1];
 
154
                        }
 
155
                        else
 
156
                                if(bordersPosition.equals(PSTricksConstants.BORDERS_MIDDLE))
 
157
                                {
 
158
                                        s1 = s[0];
 
159
                                        s2 = s0;
 
160
                                        s3 = s[1];
 
161
                                }
 
162
                                else
 
163
                                {
 
164
                                        s1 = s[0];
 
165
                                        s2 = s[1];
 
166
                                        s3 = s0;
 
167
                                }
 
168
                        
 
169
                        Shape sTooSmall = getTooSmallShape(s1);
 
170
 
 
171
                        if(lineStyle.equals(PSTricksConstants.LINE_NONE_STYLE))
 
172
                        {
 
173
                                g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
 
174
                                if(hasShadow)
 
175
                                {
 
176
                                        g.translate(dx, dy);
 
177
                                        g.setColor(shadowColor);
 
178
                                        g.fill(s1);
 
179
                                        
 
180
                                        if(sTooSmall==null)
 
181
                                                g.draw(s1);
 
182
                                        else
 
183
                                                g.draw(sTooSmall);
 
184
                                        
 
185
                                        g.translate(-dx, -dy);
 
186
                                        
 
187
                                        if(!isFilled)
 
188
                                        {
 
189
                                                changeFillStyle = true;
 
190
                                                isFilled = true;
 
191
                                        }
 
192
                                }
 
193
                                
 
194
                                g.setColor(doubleColor);
 
195
                                g.setStroke(new BasicStroke((float)(doubleSep + thickness), 
 
196
                                                                BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
 
197
                                g.draw(s2);
 
198
                                fillFigure(g, antiAlias, rendering, alphaInter, colorRendering, s3);
 
199
                                g.setColor(linesColor);
 
200
                                g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
 
201
                                
 
202
                                if(sTooSmall==null)
 
203
                                        g.draw(s1);
 
204
                                else
 
205
                                        g.draw(sTooSmall);
 
206
                                
 
207
                                g.draw(s3);
 
208
                        }
 
209
                        else
 
210
                        {
 
211
                                if(hasShadow)
 
212
                                {
 
213
                                        g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
 
214
                                        g.translate(dx, dy);
 
215
                                        g.setColor(shadowColor);
 
216
                                        g.fill(s1);
 
217
                                        
 
218
                                        if(sTooSmall==null)
 
219
                                                g.draw(s1);
 
220
                                        else
 
221
                                                g.draw(sTooSmall);
 
222
                                        
 
223
                                        g.translate(-dx, -dy);
 
224
                                        g.setColor(interiorColor);
 
225
                                        g.setStroke(new BasicStroke((float)(thickness*2+doubleSep), 
 
226
                                                        BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
 
227
                                        g.draw(s2);
 
228
                                        
 
229
                                        if(!isFilled)
 
230
                                        {
 
231
                                                changeFillStyle = true;
 
232
                                                isFilled = true;
 
233
                                        }
 
234
                                }
 
235
                                
 
236
                                if(lineStyle.equals(PSTricksConstants.LINE_DOTTED_STYLE))
 
237
                                        g.setStroke(new BasicStroke((float)(thickness*2+doubleSep), BasicStroke.CAP_ROUND,
 
238
                                                        BasicStroke.JOIN_MITER, 1.f, new float[] { 0, (float)(thickness*2+doubleSep + dotSep) }, 0));
 
239
                                else
 
240
                                        g.setStroke(new BasicStroke((float)(thickness*2+doubleSep),
 
241
                                                        BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.f,
 
242
                                                        new float[] { blackDashLength, whiteDashLength }, 0));
 
243
                                        
 
244
                                fillFigure(g, antiAlias, rendering, alphaInter, colorRendering, s2);
 
245
                                g.setColor(linesColor);
 
246
                                
 
247
                                Shape sTooSmall2 = getTooSmallShape(s2);
 
248
                                if(sTooSmall2==null)
 
249
                                        g.draw(s2);
 
250
                                else
 
251
                                        g.draw(sTooSmall2);
 
252
                                
 
253
                                g.setStroke(new BasicStroke((float)doubleSep, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
 
254
                                g.setColor(doubleColor);
 
255
                                
 
256
                                if(sTooSmall2==null)
 
257
                                        g.draw(s2);
 
258
                                else
 
259
                                        g.draw(sTooSmall2);
 
260
                        }                               
 
261
                }
 
262
                else
 
263
                {
 
264
                        Shape sTooSmall = getTooSmallShape(shape);
 
265
                        
 
266
                        if(hasShadow)
 
267
                        {
 
268
                                g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
 
269
                                g.translate(dx, dy);
 
270
                                g.setColor(shadowColor);
 
271
                                g.fill(shape);
 
272
                                
 
273
                                if(sTooSmall==null)
 
274
                                        g.draw(shape);
 
275
                                else
 
276
                                        g.draw(sTooSmall);
 
277
                                
 
278
                                g.translate(-dx, -dy);
 
279
                                if(!isFilled)
 
280
                                {
 
281
                                        changeFillStyle = true;
 
282
                                        isFilled = true;
 
283
                                }
 
284
                                g.setColor(interiorColor);
 
285
                                g.draw(shape);
 
286
                        }
 
287
                        
 
288
                        if(lineStyle.equals(PSTricksConstants.LINE_NONE_STYLE))
 
289
                                g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
 
290
                        else
 
291
                                if(lineStyle.equals(PSTricksConstants.LINE_DOTTED_STYLE))
 
292
                                {
 
293
                                        g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_ROUND,
 
294
                                                                BasicStroke.JOIN_MITER, 1.f, new float[] { 0, thickness + dotSep }, 0));
 
295
                                }
 
296
                                else
 
297
                                        g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.f,
 
298
                                                                new float[] { blackDashLength, whiteDashLength }, 0));
 
299
                        
 
300
                        fillFigure(g, antiAlias, rendering, alphaInter, colorRendering, shape);
 
301
                        g.setColor(linesColor);
 
302
                        
 
303
                        if(sTooSmall==null)
 
304
                                g.draw(shape);
 
305
                        else
 
306
                                g.draw(sTooSmall);
 
307
                }
 
308
                 
 
309
                if(changeFillStyle) isFilled = false;
 
310
                g.setColor(formerCol);
 
311
 
 
312
                if(rotationAngle%(Math.PI*2)!=0)
 
313
                {
 
314
                        g.translate(-c3x, -c3y);
 
315
                        g.rotate(-rotationAngle);
 
316
                }
 
317
                
 
318
                if(isSelected)
 
319
                        borders.draw(g, false, antiAlias, rendering, alphaInter, colorRendering);
 
320
        }
 
321
 
 
322
        
 
323
                
 
324
        
 
325
        @Override
 
326
        public synchronized void setLastPoint(double x, double y)
 
327
        {
 
328
                borders.setLastPoint(x, y);
 
329
                updateGravityCenter();
 
330
                shape = getInsideOutsideOrMiddleBorders();
 
331
        }
 
332
 
 
333
        
 
334
        
 
335
        @Override
 
336
        public synchronized void setFirstPoint(double x, double y)
 
337
        {
 
338
                borders.setFirstPoint(x, y);
 
339
                updateGravityCenter();
 
340
                shape = getInsideOutsideOrMiddleBorders();
 
341
        }
 
342
        
 
343
        
 
344
        
 
345
        @Override
 
346
        public synchronized void setBordersPosition(String doubleLinePosition)
 
347
        {
 
348
                super.setBordersPosition(doubleLinePosition);
 
349
                shape = getInsideOutsideOrMiddleBorders();
 
350
        }
 
351
        
 
352
        
 
353
        
 
354
        
 
355
        @Override
 
356
        public boolean isIn(LaTeXDrawPoint2D p) 
 
357
        {               
 
358
                LaTeXDrawPoint2D pt = rotateInvertPoint(p);
 
359
                
 
360
                if(isSelected && (borders.dNE.isIn(pt) || borders.dNW.isIn(pt) || borders.dSE.isIn(pt) || 
 
361
                        borders.dSW.isIn(pt) || borders.dS.isIn(pt)  || borders.dN.isIn(pt)   || borders.dE.isIn(pt)  || borders.dW.isIn(pt)))
 
362
                        return true;
 
363
                
 
364
                LaTeXDrawPoint2D NW = getTheNWNonRotatedBoundPoint();
 
365
                LaTeXDrawPoint2D SE = getTheSENonRotatedBoundPoint();
 
366
                Shape s = new Ellipse2D.Double(NW.x, NW.y, Math.abs(NW.x - SE.x), Math.abs(NW.y - SE.y));
 
367
 
 
368
                Rectangle2D bounds = s.getBounds2D();
 
369
        
 
370
                if(bounds.getHeight()<=1)
 
371
                {
 
372
                        Line l;
 
373
                        if(bounds.getWidth()<=1)
 
374
                                l = new Line(bounds.getMaxX(), Math.max(1, bounds.getMaxY()), bounds.getMaxX(), Math.max(1, bounds.getMaxY()), false);
 
375
                        else
 
376
                                l = new Line(bounds.getMinX(), Math.max(1, bounds.getMinY()), bounds.getMaxX(), Math.max(1, bounds.getMaxY()), false);
 
377
                        
 
378
                        return l.isIn(pt);
 
379
                }
 
380
                
 
381
                if(bounds.getWidth()<=1)
 
382
                {
 
383
                        Line l = new Line(Math.max(1, bounds.getMaxX()), bounds.getMinY(), Math.max(1, bounds.getMaxX()), bounds.getMaxY(), false);
 
384
                        
 
385
                        return l.isIn(pt);
 
386
                }
 
387
                
 
388
                if(!s.contains(pt))
 
389
                        return false;
 
390
 
 
391
                if(isFilled || hasShadow || hasGradient())
 
392
                        return true;
 
393
 
 
394
                Shape s2;
 
395
 
 
396
                if(hasDoubleBoundary)
 
397
                        s2 = new Ellipse2D.Double(NW.x + thickness * 2 + doubleSep, NW.y + thickness * 2 + doubleSep, 
 
398
                                                Math.abs(NW.x - SE.x)- 4 * thickness - 2 * doubleSep, Math.abs(NW.y- SE.y) - 4 * thickness - 2 * doubleSep);
 
399
                else
 
400
                        s2 = new Ellipse2D.Double(NW.x + thickness, NW.y + thickness, Math.abs(NW.x - SE.x) - 2 * thickness, 
 
401
                                                                        Math.abs(NW.y- SE.y)- 2 * thickness);
 
402
 
 
403
                return !s2.contains(pt);
 
404
        }
 
405
 
 
406
        
 
407
        
 
408
        
 
409
        @Override
 
410
        public String getCodePSTricks(DrawBorders drawBorders, float ppc)
 
411
        {
 
412
                LaTeXDrawPoint2D d = drawBorders.getOriginPoint();
 
413
                LaTeXDrawPoint2D pt1 = borders.getPoint(0), pt2 = borders.getPoint(1);
 
414
                LaTeXDrawPoint2D pt3 = borders.getPoint(2);
 
415
                String add = "", addBegin="", addEnd="", fillType=""; //$NON-NLS-1$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-4$
 
416
                double x = (pt1.x+pt2.x)/2. - d.x, y = d.y - (pt1.y+pt3.y)/2. ;
 
417
                double width  = Math.abs(pt1.x-pt2.x);
 
418
                double height = Math.abs(pt1.y-pt3.y);
 
419
                boolean isFilledWasChanged = false;
 
420
                
 
421
                if(hasShadow)
 
422
                {
 
423
                        fillType+=",shadow=true";//$NON-NLS-1$
 
424
                        if(Math.toDegrees(shadowAngle)!=PSTricksConstants.DEFAULT_SHADOW_ANGLE)
 
425
                                fillType+=",shadowangle="+(float)Math.toDegrees(shadowAngle);//$NON-NLS-1$
 
426
                        
 
427
                        if(((float)shadowSize)!=((float)DEFAULT_SHADOW_SIZE))
 
428
                                fillType+=",shadowsize="+(float)(shadowSize/PPC);//$NON-NLS-1$
 
429
                        
 
430
                        if(!shadowColor.equals(PSTricksConstants.DEFAULT_SHADOW_COLOR))
 
431
                        {
 
432
                                String name = DviPsColors.getColourName(shadowColor);
 
433
                                if(name==null)
 
434
                                {
 
435
                                        name = "color"+number+'e';//$NON-NLS-1$
 
436
                                        DviPsColors.addUserColour(shadowColor, name); 
 
437
                                }
 
438
                                add += ",shadowcolor=" + name; //$NON-NLS-1$
 
439
                        }
 
440
                        if(!isFilled)
 
441
                        {
 
442
                                isFilled = true;
 
443
                                isFilledWasChanged = true;
 
444
                        }
 
445
                }
 
446
                
 
447
                String str = getPSTricksCodeFilling(ppc);
 
448
                if(str.length()>0) fillType=fillType+','+str;
 
449
                
 
450
                str = getPSTricksCodeLine(ppc);
 
451
                if(str.length()>0) add=add+','+str;
 
452
                
 
453
                if(rotationAngle%(Math.PI*2)!=0.)
 
454
                {
 
455
                        double angle = -Math.toDegrees(rotationAngle);
 
456
                        double cx = (gravityCenter.x-d.x)/ppc;
 
457
                        double cy = (d.y-gravityCenter.y)/ppc;
 
458
                        double x2 = -Math.cos(-rotationAngle)*cx+
 
459
                                                Math.sin(-rotationAngle)*cy+cx;
 
460
                        double y2 =  -Math.sin(-rotationAngle)*cx-
 
461
                                                Math.cos(-rotationAngle)*cy+cy;
 
462
 
 
463
                        if(Math.abs(x2) < 0.001) x2 = 0;
 
464
                        if(Math.abs(y2) < 0.001) y2 = 0;
 
465
                        
 
466
                        addBegin +="\\rput{"+(float)angle+ "}("+(float)x2+','+(float)y2+"){"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 
467
                        addEnd = "}"; //$NON-NLS-1$
 
468
                }
 
469
                
 
470
                add+=",dimen="+bordersPosition;  //$NON-NLS-1$
 
471
                
 
472
                if(hasDoubleBoundary)
 
473
                {
 
474
                        add+=",doubleline=true,doublesep="+(float)(doubleSep/ppc); //$NON-NLS-1$
 
475
                        
 
476
                        if(doubleColor!=PSTricksConstants.DEFAULT_DOUBLE_COLOR)
 
477
                        {
 
478
                                String name = DviPsColors.getColourName(doubleColor);
 
479
                                if(name==null)
 
480
                                {
 
481
                                        name = "color"+number+'d';//$NON-NLS-1$
 
482
                                        DviPsColors.addUserColour(doubleColor, name); 
 
483
                                }
 
484
                                add+= ",doublecolor="+name; //$NON-NLS-1$
 
485
                        }
 
486
                }
 
487
                
 
488
                if(Math.abs(x) < 0.001) x = 0;
 
489
                if(Math.abs(y) < 0.001) y = 0;
 
490
                if(isFilledWasChanged) isFilled = false;
 
491
                
 
492
                return addBegin+"\\psellipse[linewidth=" + (thickness/ppc) +  //$NON-NLS-1$
 
493
                        add + fillType + "](" + (float)(x/ppc) + ',' + (float)(y/ppc) + ")("  //$NON-NLS-1$ //$NON-NLS-2$
 
494
                                + (float)((width/2.)/ppc) + ',' + (float)((height/2.)/ppc) + ')'+addEnd;
 
495
        }
 
496
 
 
497
 
 
498
 
 
499
        @Override
 
500
        public void shift(double shiftX,double shiftY)
 
501
        {
 
502
                if(shiftX==0 && shiftY==0) return ;
 
503
 
 
504
                borders.shift(shiftX, shiftY);
 
505
                updateGravityCenter();
 
506
                shape = getInsideOutsideOrMiddleBorders();
 
507
        }
 
508
 
 
509
 
 
510
 
 
511
 
 
512
        @Override
 
513
        public Object clone() throws CloneNotSupportedException
 
514
        {
 
515
                Ellipse e = (Ellipse) super.clone();
 
516
                e.borders = (LaTeXDrawRectangle) borders.clone();
 
517
                e.gravityCenter = (LaTeXDrawPoint2D)gravityCenter.clone();
 
518
                e.shape = getInsideOutsideOrMiddleBorders();
 
519
                
 
520
                return e;
 
521
        }
 
522
 
 
523
        
 
524
        
 
525
        @Override
 
526
        public Shape createShape2D()
 
527
        {
 
528
                LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
 
529
                Shape area = createNonRotatedShape2D();
 
530
 
 
531
                if(rotationAngle%(Math.PI*2)!=0)
 
532
                {
 
533
                        double cx = (NW.x+SE.x)/2., cy = (NW.y+SE.y)/2.;
 
534
 
 
535
                        double c2x = Math.cos(rotationAngle)*cx-Math.sin(rotationAngle)*cy;
 
536
                        double c2y = Math.sin(rotationAngle)*cx+Math.cos(rotationAngle)*cy;
 
537
 
 
538
                        AffineTransform at = AffineTransform.getTranslateInstance(cx-c2x, cy-c2y);
 
539
                        at.rotate(rotationAngle);
 
540
                        area = at.createTransformedShape(area);
 
541
                }
 
542
 
 
543
                return area;
 
544
        }
 
545
 
 
546
 
 
547
 
 
548
 
 
549
        @Override
 
550
        public void rescaleX(double formerX, double newX, double percent, LaTeXDrawRectangle bound) 
 
551
        {
 
552
                if(percent==1.) return ;
 
553
                
 
554
                borders.rescaleX(formerX, newX, percent, bound);
 
555
                updateGravityCenter();//update centre of gravity when reshaping
 
556
                shape = getInsideOutsideOrMiddleBorders();
 
557
        }
 
558
 
 
559
 
 
560
 
 
561
 
 
562
        @Override
 
563
        public void rescaleY(double formerY, double newY, double percent, LaTeXDrawRectangle bound) 
 
564
        {
 
565
                if(percent==1.) return ;
 
566
                
 
567
                borders.rescaleY(formerY, newY, percent, bound);
 
568
                updateGravityCenter();//update centre of gravity when reshaping
 
569
                shape = getInsideOutsideOrMiddleBorders();
 
570
        }
 
571
 
 
572
        
 
573
        
 
574
        
 
575
        private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException
 
576
        {
 
577
                canHaveShadow = true;
 
578
                interiorColor = (Color) ois.readObject();
 
579
                lineStyle = (String) ois.readObject();
 
580
                rotationAngle = ois.readDouble();
 
581
                thickness = ois.readFloat();
 
582
                isFilled = ois.readBoolean();
 
583
                isSelected = ois.readBoolean();
 
584
                isOnRotation = ois.readBoolean();
 
585
                linesColor = (Color) ois.readObject();
 
586
                blackDashLength = ois.readFloat();
 
587
                dotSep = ois.readFloat();
 
588
                whiteDashLength = ois.readFloat();
 
589
                borders = (LaTeXDrawRectangle) ois.readObject();
 
590
 
 
591
                if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.5")>=0)//$NON-NLS-1$
 
592
                {
 
593
                        hasDoubleBoundary = ois.readBoolean();
 
594
                        doubleColor = (Color)ois.readObject();
 
595
                        doubleSep = ois.readDouble();
 
596
                        bordersPosition = (String)ois.readObject();
 
597
                        if(!(LaTeXDrawFrame.getVersionOfFile().compareTo("1.6")>=0)) //$NON-NLS-1$
 
598
                                ois.readBoolean();
 
599
                        hatchingAngle = ois.readDouble();
 
600
                        hatchingColor = (Color)ois.readObject();
 
601
                        hatchingStyle = (String)ois.readObject();
 
602
                        hatchingWidth = ois.readFloat();
 
603
                        
 
604
                        if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.6") < 0)//$NON-NLS-1$
 
605
                        {
 
606
                                if(hatchingStyle.equals(DECREPETED_FILL_CROSS))
 
607
                                        hatchingStyle = PSTricksConstants.TOKEN_FILL_CROSSHATCH;
 
608
                                else if(hatchingStyle.equals(DECREPETED_FILL_HORIZ))
 
609
                                        hatchingStyle = PSTricksConstants.TOKEN_FILL_HLINES;
 
610
                                else if(hatchingStyle.equals(DECREPETED_FILL_VERT))
 
611
                                        hatchingStyle = PSTricksConstants.TOKEN_FILL_VLINES;
 
612
                                else if(hatchingStyle.equals(DECREPETED_FILL_NO))
 
613
                                        hatchingStyle = PSTricksConstants.TOKEN_FILL_NONE;
 
614
                        }
 
615
                }
 
616
                else
 
617
                {
 
618
                        hasDoubleBoundary  = DEFAULT_HAS_DOUBLE_BOUNDARY;
 
619
                        doubleColor = DEFAULT_DOUBLE_COLOR;
 
620
                        doubleSep   = DEFAULT_DOUBLESEP;
 
621
                        bordersPosition = DEFAULT_BORDERS_POSITION;
 
622
                        hatchingAngle = DEFAULT_HATCH_ANGLE;
 
623
                        hatchingColor = DEFAULT_HATCH_COL;
 
624
                        hatchingStyle = DEFAULT_HATCH_STYLE;
 
625
                        hatchingWidth = DEFAULT_HATCH_WIDTH;
 
626
                }
 
627
                
 
628
                if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.7")>=0) //$NON-NLS-1$
 
629
                {
 
630
                        hasShadow       = ois.readBoolean();
 
631
                        shadowAngle = ois.readDouble();
 
632
                        shadowSize      = ois.readDouble();
 
633
                        shadowColor     = (Color)ois.readObject();
 
634
                        gradientEndColor = (Color)ois.readObject();
 
635
                        gradientStartColor = (Color)ois.readObject();
 
636
                        gradientAngle = ois.readDouble();
 
637
                        gradientMidPoint = ois.readDouble();
 
638
                }
 
639
                else
 
640
                {
 
641
                        hasShadow       = DEFAULT_SHADOW_HAS;
 
642
                        shadowAngle     = DEFAULT_SHADOW_ANGLE;
 
643
                        shadowSize      = DEFAULT_SHADOW_SIZE;
 
644
                        shadowColor     = DEFAULT_SHADOW_COLOR;
 
645
                        gradientEndColor = PSTricksConstants.DEFAULT_GRADIENT_END_COLOR;
 
646
                        gradientStartColor = PSTricksConstants.DEFAULT_GRADIENT_START_COLOR;
 
647
                        gradientAngle = DEFAULT_GRADIENT_ANGLE;
 
648
                        gradientMidPoint = DEFAULT_GRADIENT_MID_POINT;
 
649
                }
 
650
                
 
651
                if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.8")>=0) //$NON-NLS-1$
 
652
                        hatchingSep = ois.readDouble();
 
653
                else
 
654
                        hatchingSep = DEFAULT_HATCH_SEP;
 
655
                
 
656
                updateGravityCenter();
 
657
                updateStyleOfDelimitors();
 
658
                shape = getInsideOutsideOrMiddleBorders();
 
659
        }
 
660
        
 
661
        
 
662
        
 
663
        
 
664
        /**
 
665
         * Allows to create the tangent to the ellipse at the point point
 
666
         * @param angle The position of the tangent point in radian
 
667
         * @param orientation Change the orientation of the tangent
 
668
         * @return The tangent
 
669
         */
 
670
        public Line2D.Double getTangenteAt(double angle, boolean orientation)
 
671
        {
 
672
                Line2D.Double l = new Line2D.Double();
 
673
                LaTeXDrawPoint2D NW = getTheNWPoint();
 
674
                LaTeXDrawPoint2D SE = getTheSEPoint();
 
675
                LaTeXDrawPoint2D grav = getGravityCenter();
 
676
                LaTeXDrawPoint2D pt = rotatePoint(new LaTeXDrawPoint2D(SE.x, (SE.y+NW.y)/2.), -angle);
 
677
                double a = Math.abs(NW.x-grav.x);
 
678
                double b = Math.abs(NW.y-grav.y);
 
679
                double dec = 5.;
 
680
                
 
681
                l.x1 = pt.x;
 
682
                l.y1 = pt.y;
 
683
        
 
684
                if(((float)angle)%((float)Math.PI)<=0.01)//0. is not possible
 
685
                {
 
686
                        l.x2 = pt.x;
 
687
                        if(orientation)
 
688
                                l.y2 = pt.y - dec;
 
689
                        else
 
690
                                l.y2 = pt.y + dec;
 
691
                }
 
692
                else
 
693
                {
 
694
                        if(orientation)
 
695
                                l.x2 = pt.x-dec;
 
696
                        else
 
697
                                l.x2 = pt.x+dec;
 
698
                        
 
699
                        if(((float)angle)%((float)Math.PI/2f)<=0.01)//0. is not possible
 
700
                                l.y2 = pt.y;
 
701
                        else
 
702
                                l.y2 = - (b*(pt.x-grav.x)*(l.x2-pt.x))/(a*(pt.y-grav.y)) + pt.y;
 
703
                }
 
704
                
 
705
                return l;
 
706
        }
 
707
 
 
708
 
 
709
 
 
710
 
 
711
        public Shape getInsideBorders()
 
712
        {
 
713
                LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
 
714
 
 
715
                return new Ellipse2D.Double(NW.x + thickness / 2., NW.y + thickness/ 2., 
 
716
                                                        Math.max(Math.abs(NW.x - SE.x) - thickness, 1), Math.max(Math.abs(NW.y - SE.y) - thickness, 1));
 
717
        }
 
718
 
 
719
        
 
720
 
 
721
 
 
722
        public Shape getOutsideBorders()
 
723
        {
 
724
                LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
 
725
 
 
726
                return new Ellipse2D.Double(NW.x - thickness / 2., NW.y - thickness/ 2., 
 
727
                                                        Math.max(Math.abs(NW.x - SE.x) + thickness, 1), Math.max(Math.abs(NW.y - SE.y) + thickness, 1));
 
728
        }
 
729
 
 
730
        
 
731
 
 
732
 
 
733
        public Shape getMiddleBorders()
 
734
        {
 
735
                LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
 
736
 
 
737
                return new Ellipse2D.Double(NW.x, NW.y, Math.max(Math.abs(NW.x - SE.x), 1), Math.max(Math.abs(NW.y - SE.y), 1));
 
738
        }
 
739
 
 
740
 
 
741
 
 
742
 
 
743
        public Shape getInsideOutsideOrMiddleBorders()
 
744
        {
 
745
                Shape s;
 
746
 
 
747
                if(bordersPosition.equals(PSTricksConstants.BORDERS_INSIDE))
 
748
                        s = getInsideBorders();
 
749
                else
 
750
                        if(bordersPosition.equals(PSTricksConstants.BORDERS_OUTSIDE))
 
751
                                s = getOutsideBorders();
 
752
                        else
 
753
                                s = getMiddleBorders();
 
754
 
 
755
                return s;
 
756
        }
 
757
 
 
758
 
 
759
 
 
760
 
 
761
 
 
762
        public Shape[] getDbleBoundariesOutside(Shape classicBord)
 
763
        {
 
764
                if(classicBord == null)
 
765
                        return null;
 
766
 
 
767
                Ellipse2D.Double r = (Ellipse2D.Double)classicBord;
 
768
                Shape[] s = new Shape[2];
 
769
 
 
770
                s[0] = new Ellipse2D.Double(r.x - doubleSep - thickness, r.y- doubleSep - thickness, 
 
771
                                                                        r.width + 2*(doubleSep + thickness), r.height + 2*(doubleSep + thickness));
 
772
                s[1] = new Ellipse2D.Double(r.x - (doubleSep + thickness) / 2., r.y - (doubleSep + thickness) / 2.,
 
773
                                                                        r.width + doubleSep+ thickness, r.height + doubleSep + thickness);
 
774
 
 
775
                return s;
 
776
        }
 
777
 
 
778
 
 
779
 
 
780
 
 
781
        public Shape[] getDbleBoundariesInside(Shape classicBord)
 
782
        {
 
783
                if(classicBord == null)
 
784
                        return null;
 
785
 
 
786
                Ellipse2D.Double r = (Ellipse2D.Double)classicBord;
 
787
                Shape[] s = new Shape[2];
 
788
 
 
789
                s[0] = new Ellipse2D.Double(r.x + (doubleSep + thickness) / 2., r.y + (doubleSep + thickness) / 2., 
 
790
                                                                        r.width - doubleSep- thickness, r.height - doubleSep - thickness);
 
791
                s[1] = new Ellipse2D.Double(r.x + doubleSep + thickness, r.y + doubleSep + thickness, 
 
792
                                        r.width - 2*(doubleSep + thickness), r.height - 2 * (doubleSep + thickness));
 
793
 
 
794
                return s;
 
795
        }
 
796
 
 
797
 
 
798
 
 
799
 
 
800
        public Shape[] getDbleBoundariesMiddle(Shape classicBord)
 
801
        {
 
802
                if(classicBord == null)
 
803
                        return null;
 
804
 
 
805
                Ellipse2D.Double r = (Ellipse2D.Double)classicBord;
 
806
                Shape[] s = new Shape[2];
 
807
                double add = (doubleSep + thickness) / 2.;
 
808
 
 
809
                s[0] = new Ellipse2D.Double(r.x - add, r.y - add, r.width + doubleSep + thickness, r.height + doubleSep + thickness);
 
810
                s[1] = new Ellipse2D.Double(r.x + add, r.y + add, r.width - doubleSep - thickness, r.height - doubleSep - thickness);
 
811
 
 
812
                return s;
 
813
        }
 
814
 
 
815
 
 
816
 
 
817
 
 
818
        public Shape[] getDbleBoundariesOutInOrMiddle(Shape classicBord)
 
819
        {
 
820
                Shape[] s;
 
821
 
 
822
                if(bordersPosition.equals(PSTricksConstants.BORDERS_INSIDE))
 
823
                        s = getDbleBoundariesInside(classicBord);
 
824
                else
 
825
                        if(bordersPosition.equals(PSTricksConstants.BORDERS_OUTSIDE))
 
826
                                s = getDbleBoundariesOutside(classicBord);
 
827
                        else
 
828
                                s = getDbleBoundariesMiddle(classicBord);
 
829
 
 
830
                return s;
 
831
        }
 
832
 
 
833
 
 
834
        
 
835
 
 
836
 
 
837
        @Override
 
838
        public Shape createNonRotatedShape2D()
 
839
        {
 
840
                Shape area;
 
841
                Shape s = getInsideOutsideOrMiddleBorders();
 
842
 
 
843
                if(hasDoubleBoundary)
 
844
                {
 
845
                        Shape[] s2 = getDbleBoundariesOutInOrMiddle(s);
 
846
                        Shape min;
 
847
                        Shape max;
 
848
 
 
849
                        if(bordersPosition.equals(PSTricksConstants.BORDERS_INSIDE))
 
850
                        {
 
851
                                max = s;
 
852
                                min = s2[1];
 
853
                        }
 
854
                        else
 
855
                                if(bordersPosition.equals(PSTricksConstants.BORDERS_MIDDLE))
 
856
                                {
 
857
                                        max = s2[0];
 
858
                                        min = s2[1];
 
859
                                }
 
860
                                else
 
861
                                {
 
862
                                        max = s2[0];
 
863
                                        min = s;
 
864
                                }
 
865
 
 
866
                        area = new Area(max);
 
867
                        ((Area)area).exclusiveOr(new Area(min));
 
868
                        
 
869
                        Shape tooSmallShape = getTooSmallShape(area);
 
870
                        
 
871
                        if(tooSmallShape!=null)
 
872
                        {
 
873
                                Rectangle2D bounds = max.getBounds2D();
 
874
                                area = new Line2D.Double(Math.max(1, bounds.getMinX()), Math.max(1, bounds.getMinY()),
 
875
                                                Math.max(1, bounds.getMaxX()), Math.max(1, bounds.getMaxY()));
 
876
                        }
 
877
                }
 
878
                else
 
879
                        area = s;
 
880
 
 
881
                return area;
 
882
        }
 
883
 
 
884
 
 
885
 
 
886
 
 
887
        @Override
 
888
        public synchronized void setThickness(float value)
 
889
        {
 
890
                super.setThickness(value);
 
891
                shape = getInsideOutsideOrMiddleBorders();
 
892
        }
 
893
 
 
894
 
 
895
 
 
896
        @Override
 
897
        public void updateShape()
 
898
        {
 
899
                shape = getInsideOutsideOrMiddleBorders();
 
900
        }
 
901
 
 
902
 
 
903
 
 
904
        
 
905
        @Override
 
906
        public boolean isTooSmallToBeRescaled()
 
907
        {
 
908
                return borders.isTooSmallToBeRescaled();
 
909
        }
 
910
 
 
911
 
 
912
 
 
913
        
 
914
        
 
915
        @Override
 
916
        public Shape createShadowShape()
 
917
        {
 
918
                if(!canHaveShadow || !hasShadow) return shape;
 
919
                
 
920
                Rectangle2D b = createShape2D().getBounds2D();
 
921
                double dx=0, dy=0;
 
922
                LaTeXDrawPoint2D cg = getGravityCenter();
 
923
                LaTeXDrawPoint2D shadowCg = (LaTeXDrawPoint2D)cg.clone();
 
924
                
 
925
                shadowCg.setLocation(cg.x+shadowSize, cg.y);
 
926
                shadowCg = Figure.rotatePoint(shadowCg, cg, shadowAngle);
 
927
                dx = shadowCg.x-cg.x;
 
928
                dy = cg.y-shadowCg.y;
 
929
                
 
930
                return new Ellipse2D.Double(b.getX()+dx-thickness/2.,b.getY()+dy-thickness/2.,
 
931
                                                                        b.getWidth()+thickness, b.getHeight()+thickness);
 
932
        }
 
933
 
 
934
 
 
935
 
 
936
        @Override
 
937
        public void mirrorHorizontal(LaTeXDrawPoint2D origin)
 
938
        {
 
939
                borders.mirrorHorizontal(origin);
 
940
                updateShape();
 
941
        }
 
942
 
 
943
 
 
944
 
 
945
        @Override
 
946
        public void mirrorVertical(LaTeXDrawPoint2D origin)
 
947
        {
 
948
                borders.mirrorVertical(origin);
 
949
                updateShape();
 
950
        }
 
951
 
 
952
 
 
953
 
 
954
        @Override
 
955
        public synchronized LaTeXDrawPoint2D getLastPoint()
 
956
        {
 
957
                return borders.getLastPoint();
 
958
        }
 
959
 
 
960
 
 
961
 
 
962
        @Override
 
963
        public void updateToGrid(MagneticGrid grid)
 
964
        {
 
965
                borders.updateToGrid(grid);
 
966
                updateShape();
 
967
        }
 
968
 
 
969
 
 
970
 
 
971
        
 
972
        @Override
 
973
        public int getSelectedDelimitorOrientation()
 
974
        {
 
975
                return borders.getSelectedDelimitorOrientation();
 
976
        }
 
977
        
 
978
        
 
979
        
 
980
        @Override
 
981
        public int hashCode()
 
982
        {
 
983
                return (int)(super.hashCode()*1.5);
 
984
        }
 
985
}