1
package latexDraw.figures;
4
import java.awt.geom.*;
5
import java.io.IOException;
6
import java.io.ObjectInputStream;
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;
18
* This class defines an Ellipse.<br>
20
* This file is part of LaTeXDraw<br>
21
* Copyright (c) 2005-2008 Arnaud BLOUIN<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>
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>
33
* @author Arnaud BLOUIN<br>
36
public class Ellipse extends Figure implements BordersMovable, DoubleBoundaryable
38
private static final long serialVersionUID = 1L;
42
* The constructor by default
44
public Ellipse(boolean increaseMeter)
46
this(new LaTeXDrawPoint2D(), new LaTeXDrawPoint2D(), new LaTeXDrawPoint2D(), new LaTeXDrawPoint2D(), increaseMeter);
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
58
public Ellipse(LaTeXDrawPoint2D pt1, LaTeXDrawPoint2D pt2, LaTeXDrawPoint2D pt3, LaTeXDrawPoint2D pt4, boolean increaseMeter)
61
borders = new LaTeXDrawRectangle(pt1, pt2, pt3, pt4, false);
62
updateGravityCenter();
63
shape = getInsideOutsideOrMiddleBorders();
69
* @param f The figure to copy
70
* @param sameNumber True if the figure will have the same number of the copy.
72
public Ellipse(Figure f, boolean sameNumber)
78
borders = new LaTeXDrawRectangle((LaTeXDrawPoint2D)f.getBordersPoint(0).clone(),
79
(LaTeXDrawPoint2D)f.getBordersPoint(-1).clone(), false);
80
updateGravityCenter();
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);
92
{ borders = new LaTeXDrawRectangle(false); }
94
updateGravityCenter();
101
public void onDragged(Point formerPt, Point newPt)
103
if(formerPt.equals(newPt)) return;
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();
115
public void draw(Graphics2D g, Object antiAlias, Object rendering, Object alphaInter, Object colorRendering)
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);
125
boolean changeFillStyle = false;
127
if(rotationAngle%(Math.PI*2)!=0)
129
g.rotate(rotationAngle);
130
g.translate(c3x,c3y);
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;
143
if(hasDoubleBoundary)
146
Shape s[] = getDbleBoundariesOutInOrMiddle(s0);
149
if(bordersPosition.equals(PSTricksConstants.BORDERS_INSIDE))
156
if(bordersPosition.equals(PSTricksConstants.BORDERS_MIDDLE))
169
Shape sTooSmall = getTooSmallShape(s1);
171
if(lineStyle.equals(PSTricksConstants.LINE_NONE_STYLE))
173
g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
177
g.setColor(shadowColor);
185
g.translate(-dx, -dy);
189
changeFillStyle = true;
194
g.setColor(doubleColor);
195
g.setStroke(new BasicStroke((float)(doubleSep + thickness),
196
BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
198
fillFigure(g, antiAlias, rendering, alphaInter, colorRendering, s3);
199
g.setColor(linesColor);
200
g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
213
g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
215
g.setColor(shadowColor);
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));
231
changeFillStyle = true;
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));
240
g.setStroke(new BasicStroke((float)(thickness*2+doubleSep),
241
BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.f,
242
new float[] { blackDashLength, whiteDashLength }, 0));
244
fillFigure(g, antiAlias, rendering, alphaInter, colorRendering, s2);
245
g.setColor(linesColor);
247
Shape sTooSmall2 = getTooSmallShape(s2);
253
g.setStroke(new BasicStroke((float)doubleSep, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
254
g.setColor(doubleColor);
264
Shape sTooSmall = getTooSmallShape(shape);
268
g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
270
g.setColor(shadowColor);
278
g.translate(-dx, -dy);
281
changeFillStyle = true;
284
g.setColor(interiorColor);
288
if(lineStyle.equals(PSTricksConstants.LINE_NONE_STYLE))
289
g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
291
if(lineStyle.equals(PSTricksConstants.LINE_DOTTED_STYLE))
293
g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_ROUND,
294
BasicStroke.JOIN_MITER, 1.f, new float[] { 0, thickness + dotSep }, 0));
297
g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.f,
298
new float[] { blackDashLength, whiteDashLength }, 0));
300
fillFigure(g, antiAlias, rendering, alphaInter, colorRendering, shape);
301
g.setColor(linesColor);
309
if(changeFillStyle) isFilled = false;
310
g.setColor(formerCol);
312
if(rotationAngle%(Math.PI*2)!=0)
314
g.translate(-c3x, -c3y);
315
g.rotate(-rotationAngle);
319
borders.draw(g, false, antiAlias, rendering, alphaInter, colorRendering);
326
public synchronized void setLastPoint(double x, double y)
328
borders.setLastPoint(x, y);
329
updateGravityCenter();
330
shape = getInsideOutsideOrMiddleBorders();
336
public synchronized void setFirstPoint(double x, double y)
338
borders.setFirstPoint(x, y);
339
updateGravityCenter();
340
shape = getInsideOutsideOrMiddleBorders();
346
public synchronized void setBordersPosition(String doubleLinePosition)
348
super.setBordersPosition(doubleLinePosition);
349
shape = getInsideOutsideOrMiddleBorders();
356
public boolean isIn(LaTeXDrawPoint2D p)
358
LaTeXDrawPoint2D pt = rotateInvertPoint(p);
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)))
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));
368
Rectangle2D bounds = s.getBounds2D();
370
if(bounds.getHeight()<=1)
373
if(bounds.getWidth()<=1)
374
l = new Line(bounds.getMaxX(), Math.max(1, bounds.getMaxY()), bounds.getMaxX(), Math.max(1, bounds.getMaxY()), false);
376
l = new Line(bounds.getMinX(), Math.max(1, bounds.getMinY()), bounds.getMaxX(), Math.max(1, bounds.getMaxY()), false);
381
if(bounds.getWidth()<=1)
383
Line l = new Line(Math.max(1, bounds.getMaxX()), bounds.getMinY(), Math.max(1, bounds.getMaxX()), bounds.getMaxY(), false);
391
if(isFilled || hasShadow || hasGradient())
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);
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);
403
return !s2.contains(pt);
410
public String getCodePSTricks(DrawBorders drawBorders, float ppc)
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;
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$
427
if(((float)shadowSize)!=((float)DEFAULT_SHADOW_SIZE))
428
fillType+=",shadowsize="+(float)(shadowSize/PPC);//$NON-NLS-1$
430
if(!shadowColor.equals(PSTricksConstants.DEFAULT_SHADOW_COLOR))
432
String name = DviPsColors.getColourName(shadowColor);
435
name = "color"+number+'e';//$NON-NLS-1$
436
DviPsColors.addUserColour(shadowColor, name);
438
add += ",shadowcolor=" + name; //$NON-NLS-1$
443
isFilledWasChanged = true;
447
String str = getPSTricksCodeFilling(ppc);
448
if(str.length()>0) fillType=fillType+','+str;
450
str = getPSTricksCodeLine(ppc);
451
if(str.length()>0) add=add+','+str;
453
if(rotationAngle%(Math.PI*2)!=0.)
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;
463
if(Math.abs(x2) < 0.001) x2 = 0;
464
if(Math.abs(y2) < 0.001) y2 = 0;
466
addBegin +="\\rput{"+(float)angle+ "}("+(float)x2+','+(float)y2+"){"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
467
addEnd = "}"; //$NON-NLS-1$
470
add+=",dimen="+bordersPosition; //$NON-NLS-1$
472
if(hasDoubleBoundary)
474
add+=",doubleline=true,doublesep="+(float)(doubleSep/ppc); //$NON-NLS-1$
476
if(doubleColor!=PSTricksConstants.DEFAULT_DOUBLE_COLOR)
478
String name = DviPsColors.getColourName(doubleColor);
481
name = "color"+number+'d';//$NON-NLS-1$
482
DviPsColors.addUserColour(doubleColor, name);
484
add+= ",doublecolor="+name; //$NON-NLS-1$
488
if(Math.abs(x) < 0.001) x = 0;
489
if(Math.abs(y) < 0.001) y = 0;
490
if(isFilledWasChanged) isFilled = false;
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;
500
public void shift(double shiftX,double shiftY)
502
if(shiftX==0 && shiftY==0) return ;
504
borders.shift(shiftX, shiftY);
505
updateGravityCenter();
506
shape = getInsideOutsideOrMiddleBorders();
513
public Object clone() throws CloneNotSupportedException
515
Ellipse e = (Ellipse) super.clone();
516
e.borders = (LaTeXDrawRectangle) borders.clone();
517
e.gravityCenter = (LaTeXDrawPoint2D)gravityCenter.clone();
518
e.shape = getInsideOutsideOrMiddleBorders();
526
public Shape createShape2D()
528
LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
529
Shape area = createNonRotatedShape2D();
531
if(rotationAngle%(Math.PI*2)!=0)
533
double cx = (NW.x+SE.x)/2., cy = (NW.y+SE.y)/2.;
535
double c2x = Math.cos(rotationAngle)*cx-Math.sin(rotationAngle)*cy;
536
double c2y = Math.sin(rotationAngle)*cx+Math.cos(rotationAngle)*cy;
538
AffineTransform at = AffineTransform.getTranslateInstance(cx-c2x, cy-c2y);
539
at.rotate(rotationAngle);
540
area = at.createTransformedShape(area);
550
public void rescaleX(double formerX, double newX, double percent, LaTeXDrawRectangle bound)
552
if(percent==1.) return ;
554
borders.rescaleX(formerX, newX, percent, bound);
555
updateGravityCenter();//update centre of gravity when reshaping
556
shape = getInsideOutsideOrMiddleBorders();
563
public void rescaleY(double formerY, double newY, double percent, LaTeXDrawRectangle bound)
565
if(percent==1.) return ;
567
borders.rescaleY(formerY, newY, percent, bound);
568
updateGravityCenter();//update centre of gravity when reshaping
569
shape = getInsideOutsideOrMiddleBorders();
575
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException
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();
591
if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.5")>=0)//$NON-NLS-1$
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$
599
hatchingAngle = ois.readDouble();
600
hatchingColor = (Color)ois.readObject();
601
hatchingStyle = (String)ois.readObject();
602
hatchingWidth = ois.readFloat();
604
if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.6") < 0)//$NON-NLS-1$
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;
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;
628
if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.7")>=0) //$NON-NLS-1$
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();
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;
651
if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.8")>=0) //$NON-NLS-1$
652
hatchingSep = ois.readDouble();
654
hatchingSep = DEFAULT_HATCH_SEP;
656
updateGravityCenter();
657
updateStyleOfDelimitors();
658
shape = getInsideOutsideOrMiddleBorders();
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
670
public Line2D.Double getTangenteAt(double angle, boolean orientation)
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);
684
if(((float)angle)%((float)Math.PI)<=0.01)//0. is not possible
699
if(((float)angle)%((float)Math.PI/2f)<=0.01)//0. is not possible
702
l.y2 = - (b*(pt.x-grav.x)*(l.x2-pt.x))/(a*(pt.y-grav.y)) + pt.y;
711
public Shape getInsideBorders()
713
LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
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));
722
public Shape getOutsideBorders()
724
LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
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));
733
public Shape getMiddleBorders()
735
LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
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));
743
public Shape getInsideOutsideOrMiddleBorders()
747
if(bordersPosition.equals(PSTricksConstants.BORDERS_INSIDE))
748
s = getInsideBorders();
750
if(bordersPosition.equals(PSTricksConstants.BORDERS_OUTSIDE))
751
s = getOutsideBorders();
753
s = getMiddleBorders();
762
public Shape[] getDbleBoundariesOutside(Shape classicBord)
764
if(classicBord == null)
767
Ellipse2D.Double r = (Ellipse2D.Double)classicBord;
768
Shape[] s = new Shape[2];
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);
781
public Shape[] getDbleBoundariesInside(Shape classicBord)
783
if(classicBord == null)
786
Ellipse2D.Double r = (Ellipse2D.Double)classicBord;
787
Shape[] s = new Shape[2];
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));
800
public Shape[] getDbleBoundariesMiddle(Shape classicBord)
802
if(classicBord == null)
805
Ellipse2D.Double r = (Ellipse2D.Double)classicBord;
806
Shape[] s = new Shape[2];
807
double add = (doubleSep + thickness) / 2.;
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);
818
public Shape[] getDbleBoundariesOutInOrMiddle(Shape classicBord)
822
if(bordersPosition.equals(PSTricksConstants.BORDERS_INSIDE))
823
s = getDbleBoundariesInside(classicBord);
825
if(bordersPosition.equals(PSTricksConstants.BORDERS_OUTSIDE))
826
s = getDbleBoundariesOutside(classicBord);
828
s = getDbleBoundariesMiddle(classicBord);
838
public Shape createNonRotatedShape2D()
841
Shape s = getInsideOutsideOrMiddleBorders();
843
if(hasDoubleBoundary)
845
Shape[] s2 = getDbleBoundariesOutInOrMiddle(s);
849
if(bordersPosition.equals(PSTricksConstants.BORDERS_INSIDE))
855
if(bordersPosition.equals(PSTricksConstants.BORDERS_MIDDLE))
866
area = new Area(max);
867
((Area)area).exclusiveOr(new Area(min));
869
Shape tooSmallShape = getTooSmallShape(area);
871
if(tooSmallShape!=null)
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()));
888
public synchronized void setThickness(float value)
890
super.setThickness(value);
891
shape = getInsideOutsideOrMiddleBorders();
897
public void updateShape()
899
shape = getInsideOutsideOrMiddleBorders();
906
public boolean isTooSmallToBeRescaled()
908
return borders.isTooSmallToBeRescaled();
916
public Shape createShadowShape()
918
if(!canHaveShadow || !hasShadow) return shape;
920
Rectangle2D b = createShape2D().getBounds2D();
922
LaTeXDrawPoint2D cg = getGravityCenter();
923
LaTeXDrawPoint2D shadowCg = (LaTeXDrawPoint2D)cg.clone();
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;
930
return new Ellipse2D.Double(b.getX()+dx-thickness/2.,b.getY()+dy-thickness/2.,
931
b.getWidth()+thickness, b.getHeight()+thickness);
937
public void mirrorHorizontal(LaTeXDrawPoint2D origin)
939
borders.mirrorHorizontal(origin);
946
public void mirrorVertical(LaTeXDrawPoint2D origin)
948
borders.mirrorVertical(origin);
955
public synchronized LaTeXDrawPoint2D getLastPoint()
957
return borders.getLastPoint();
963
public void updateToGrid(MagneticGrid grid)
965
borders.updateToGrid(grid);
973
public int getSelectedDelimitorOrientation()
975
return borders.getSelectedDelimitorOrientation();
981
public int hashCode()
983
return (int)(super.hashCode()*1.5);