Logo Search packages:      
Sourcecode: latexdraw version File versions  Download package

LaTeXDrawPolygon.java

package latexDraw.figures;

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Vector;

import latexDraw.figures.properties.DoubleBoundaryable;
import latexDraw.psTricks.DviPsColors;
import latexDraw.psTricks.PSTricksConstants;
import latexDraw.ui.LaTeXDrawFrame;
import latexDraw.ui.components.Delimitor;
import latexDraw.ui.components.MagneticGrid;
import latexDraw.util.LaTeXDrawException;
import latexDraw.util.LaTeXDrawPoint2D;

/** 
 * This class defines a polygon.<br>
 *<br>
 * This file is part of LaTeXDraw<br>
 * Copyright (c) 2005-2008 Arnaud BLOUIN<br>
 *<br>
 *  LaTeXDraw is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.<br>
 *<br>
 *  LaTeXDraw is distributed without any warranty; without even the 
 *  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
 *  PURPOSE. See the GNU General Public License for more details.<br>
 *<br>
 * 01/20/06<br>
 * @author Arnaud BLOUIN<br>
 * @version 2.0.0<br>
 * @java6 Replace GeneralPath by Path2D.Double
 */
00039 public class LaTeXDrawPolygon extends Figure implements DoubleBoundaryable
{
      private static final long serialVersionUID = 1L;

      /** All the corners of the polygon */
00044       protected Vector<LaTeXDrawPoint2D> pts;
      
      /** All delimiters of the polygon */
00047       protected Vector<Delimitor> delimiters;

      
      
      /**
       * The constructor by default
       */
00054       public LaTeXDrawPolygon(boolean increaseMeter)
      {
            super(increaseMeter);
            isBordersMovable = false;
            borders=null;
            pts = new Vector<LaTeXDrawPoint2D>();
            delimiters = new Vector<Delimitor>();
      }
      
      

      /**
       * Create a figure from one another.
       * @param f The figure to copy.
       * @param sameNumber True is the new figure must have the same number as the other.
       * @throws IllegalArgumentException If f is null or if f has no border.
       */
00071       public LaTeXDrawPolygon(Figure f, boolean sameNumber)
      {
            super(f, sameNumber);
            
            pts = new Vector<LaTeXDrawPoint2D>();
            delimiters = new Vector<Delimitor>();
            if(f==null) return;
            
            LaTeXDrawRectangle b = f.getBorders();
            
            if(b==null)
                  throw new IllegalArgumentException();
            
            borders = new LaTeXDrawRectangle((LaTeXDrawPoint2D)b.getPoint(0).clone(), (LaTeXDrawPoint2D)b.getPoint(-1).clone(), false);
            
            for(LaTeXDrawPoint2D pt : b.pts)
            {
                  pts.add((LaTeXDrawPoint2D)pt.clone());
                  Delimitor d = new Delimitor(pts.lastElement());
                  d.setColorSet3();
                  delimiters.add(d);
            }
            
            isBordersMovable = false;
            updateBorders();
            updateShape();
            setThickness(thickness);
      }
      
      
      
      /**
       * The constructor using two points
       * @param pt1 The first point of the polygon
       * @param pt2 The second point of the polygon
       */
00107       public LaTeXDrawPolygon(LaTeXDrawPoint2D pt1, LaTeXDrawPoint2D pt2, boolean increaseMeter)
      {
            super(increaseMeter);
            
            isBordersMovable = false;
            borders = new LaTeXDrawRectangle((LaTeXDrawPoint2D)pt1.clone(), (LaTeXDrawPoint2D)pt2.clone(), false);
            pts = new Vector<LaTeXDrawPoint2D>();
            delimiters = new Vector<Delimitor>();
            addPoint(pt1);
            addPoint(pt2);
            updateGravityCenter();
      }
      
      
      
      /**
       * The constructor using four points
       * @param pt1 The first point of the polygon
       * @param pt2 The second point of the polygon
       * @param pt3 The third point of the polygon
       * @param pt4 The fourth point of the polygon
       */
00129       public LaTeXDrawPolygon(LaTeXDrawPoint2D pt1, LaTeXDrawPoint2D pt2, 
                  LaTeXDrawPoint2D pt3, LaTeXDrawPoint2D pt4, boolean increaseMeter)
      {
            super(increaseMeter);
            borders = new LaTeXDrawRectangle((LaTeXDrawPoint2D)pt1.clone(),(LaTeXDrawPoint2D)pt2.clone(),
                                                             (LaTeXDrawPoint2D)pt3.clone(),(LaTeXDrawPoint2D)pt4.clone(),false);
            pts = new Vector<LaTeXDrawPoint2D>();
            delimiters = new Vector<Delimitor>();
            addPoint(pt1);
            addPoint(pt2);
            addPoint(pt3);
            addPoint(pt4);
            updateGravityCenter();
            isBordersMovable = false;
      }
      
      
      
      /**
       * Allows to add a point to the polygon
       * @param pt The point to be added
       * @return True if the point has been added
       */
00152       public boolean addPoint(LaTeXDrawPoint2D pt)
      {
            int id = pts.isEmpty() ? 0 : pts.size()-1;
            return addPointAt(pt, id);
      }

      
      
      
      /**
       * Allows to add a point to the polygon at a specific position.
       * @param pt The point to be added (-1=the last position).
       * @return True if the point has been added.
       */
00166       public boolean addPointAt(LaTeXDrawPoint2D pt, int id)
      {
            if(id == -1)
                  id = pts.size()-1;
            
            if(id<0 || id>pts.size())
                  throw new IllegalArgumentException(String.valueOf(id));
            
            if(pt!=null)
            {
                  Delimitor d = new Delimitor(pt);
                  d.setDim(Math.max(6, 1.33*thickness+3.33 +1.));
                  d.setColorSet3();

                  if(pts.size()-1==id || pts.isEmpty())
                  {
                        pts.add(pt);
                        delimiters.add(d);
                  }
                  else
                  {
                        pts.add(id, pt);
                        delimiters.add(id, d);
                  }
                  
                  if(borders!=null)
                        updateBorders(pt);
                  
                  return true;
            }
            return false;
      }
      
      
      
      /**
       * Allows to remove a point at the position id. If id = -1
       * the last point will be deleted
       * @param id The position of the point (-1 for the last point)
       */
00206       public void removePointAt(int id)
      {
            if(pts.isEmpty()) return ;
            
            if(id>=pts.size() || id<-1)
                  throw new IllegalArgumentException();

            if(id==-1)
                  id = pts.size()-1;
            
            pts.remove(id);
            delimiters.remove(id);
            if(borders!=null)
                  updateBorders();
            
            updateShape();
      }
      
      
      
      
      public Shape getInsideOutsideOrMiddleBorders()
      {
            return getBorders(0, true);
      }
      
      
      
      
      /**
       * Allow to get the point at the position id in the vector pts
       * @param id The position of the point asked (-1 = the last point)
       * @return The point asked
       */
00240       public synchronized LaTeXDrawPoint2D getPoint(int id)
      {
            if(pts==null) return null;
            
            if(id==-1) return pts.lastElement();
            if(id<0 || id>=pts.size())
                  throw new ArrayIndexOutOfBoundsException(id);
            
            return pts.elementAt(id);
      }
      
      
      
      
      /**
       * Allows to replace a given point of the polygon
       * @param pt The point to be replaced
       * @param id The position of the point in the vector pts
       */
00259       public synchronized void setPointAt(LaTeXDrawPoint2D pt, int id)
      {
            if(id<0 || id>=pts.size())
                  throw new IllegalArgumentException();
            
            if(!pt.equals(pts.elementAt(id)))
            {
                  pts.setElementAt(pt, id);
      
                  if(borders!=null)
                        updateBorders(pt);
                  
                  updateShape();
            }
      }
      
      
      
      @Override
00278       public void onDragged(Point formerPt, Point newPt) throws Exception 
      {     
            if(formerPt.equals(newPt)) return;
            
            if(isOnRotation && (borders.dSelected!=null || dSelected!=null))
                  addRotationAngle(computeRotationAngle(formerPt, newPt));
            else
            if(dSelected==null)// We dragged the figure or a delimiter of the 
            {//borders is selected
                  if(borders.dSelected==null)
                        shift(formerPt, newPt);
                  else
                        if(borders!=null && borders.dSelected!=null)
                        {
                              if(borders.dSelected==borders.dE || borders.dSelected==borders.dNE ||
                                    borders.dSelected==borders.dSE)
                              {
                                    double dEx = borders.dE.getX(), dWx = borders.dW.getX();
                                    // The user must not be able to reduce too much to figure
                                    if(dEx!=dWx && newPt.x-dWx>10)
                                          rescaleX(dEx, newPt.x, Math.abs((newPt.x-dWx)/(dEx-dWx)), borders);
                              }
                              if(borders.dSelected==borders.dW || borders.dSelected==borders.dNW ||
                                    borders.dSelected==borders.dSW)
                              {
                                    double dEx = borders.dE.getX(), dWx = borders.dW.getX();
                                    if(dEx!=dWx && dEx-newPt.x>10)
                                    //     The user must not be able to reduce too much to figure
                                          rescaleX(dWx, newPt.x, Math.abs((newPt.x-dEx)/(dWx-dEx)), borders);
                              }
                              if(borders.dSelected==borders.dN || borders.dSelected==borders.dNW ||
                                    borders.dSelected==borders.dNE)
                              {
                                    double dNy = borders.dN.getY(), dSy = borders.dS.getY();
                                    if(dNy!=dSy && dSy-newPt.y>10)
                                    //     The user must not be able to reduce too much to figure
                                          rescaleY(dNy, newPt.y, Math.abs((newPt.y-dSy)/(dNy-dSy)), borders);
                              }
                              if(borders.dSelected==borders.dS || borders.dSelected==borders.dSW ||
                                    borders.dSelected==borders.dSE)
                              {
                                    double dNy = borders.dN.getY(), dSy = borders.dS.getY();
                                    if(dNy!=dSy && newPt.y-dNy>10)
                                    //     The user must not be able to reduce too much to figure
                                          rescaleY(dSy, newPt.y, Math.abs((newPt.y-dNy)/(dSy-dNy)), borders);
                              }     
                        }
                  }//if(dSelected==null)
                  else
                  {
                        dSelected.setCoordinates(newPt.x, newPt.y);     
                        updateShape();
                  }
            
            updateBorders();
      }

      
      
      
      @Override
00339       public void draw(Graphics2D g, Object antiAlias, Object rendering, Object alphaInter, Object colorRendering)
      { 
            Color formerCol = g.getColor();
            double dx=0, dy=0;
            boolean changeFillStyle = false;
            
            if(hasShadow)
            {
                  LaTeXDrawPoint2D cg = getGravityCenter();
                  LaTeXDrawPoint2D shadowCg = (LaTeXDrawPoint2D)cg.clone();
                  shadowCg.setLocation(cg.x+shadowSize, cg.y);
                  shadowCg = Figure.rotatePoint(shadowCg, cg, shadowAngle);
                  dx = shadowCg.x-cg.x;
                  dy = cg.y-shadowCg.y;
            }
            
            if(shape==null)
                  shape = getInsideOutsideOrMiddleBorders();
            
            if(hasDoubleBoundary)
            {
                  g.setColor(linesColor);
                  BasicStroke wideline=null;
                  
                  if(lineStyle.equals(PSTricksConstants.LINE_NONE_STYLE))
                        wideline = new BasicStroke((float)(doubleSep+thickness*2.), BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
                  else 
                  if(lineStyle.equals(PSTricksConstants.LINE_DOTTED_STYLE))
                        wideline = new BasicStroke((float)(doubleSep+thickness*2.), BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER,
                                    1.f, new float[]{0,(float)(doubleSep+thickness*2.)+dotSep}, 0);
                  else
                        wideline = new BasicStroke((float)(doubleSep+thickness*2.), BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
                                    1.f, new float[]{blackDashLength, whiteDashLength}, 0);
                  
              Shape outline = wideline.createStrokedShape(shape);
              
              if(hasShadow)
                  {
                        Stroke stroke = g.getStroke();
                        g.setStroke(new BasicStroke((float)(doubleSep+thickness*2.), BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                        g.translate(dx, dy);
                        g.setColor(shadowColor);
                        g.fill(shape);
                        g.draw(shape);
                        g.translate(-dx, -dy);
                        g.setStroke(stroke);
                        
                        if(!isFilled)
                        {
                              changeFillStyle = true;
                              isFilled = true;
                        }
                  }
                  
                  fillFigure(g, antiAlias, rendering, alphaInter, colorRendering, shape);
                  g.setColor(linesColor);
                  g.fill(outline);
                  g.setColor(doubleColor);
                  wideline = new BasicStroke((float)doubleSep);
              outline = wideline.createStrokedShape(shape);
                  g.fill(outline);
            }
            else
            {
                  if(hasShadow)
                  {
                        g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                        g.translate(dx, dy);
                        g.setColor(shadowColor);
                        g.fill(shape);
                        g.draw(shape);
                        g.translate(-dx, -dy);
                        if(!isFilled)
                        {
                              changeFillStyle = true;
                              isFilled = true;
                        }
                        g.setColor(interiorColor);
                        g.draw(shape);
                  }
                  
                  if(lineStyle.equals(PSTricksConstants.LINE_NONE_STYLE))
                        g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                  else 
                  if(lineStyle.equals(PSTricksConstants.LINE_DOTTED_STYLE))
                  {
                        g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER,
                                    1.f, new float[]{0,thickness+dotSep}, 0));
                  }
                  else
                  if(lineStyle.equals(PSTricksConstants.LINE_DASHED_STYLE))
                  {
                        g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
                                    1.f, new float[]{blackDashLength, whiteDashLength}, 0));
                  }     
                  
                  fillFigure(g, antiAlias,rendering,alphaInter, colorRendering,shape);
                  g.setColor(linesColor);
                  g.draw(shape);
            }
            
            if(changeFillStyle) isFilled = false;
            g.setColor(formerCol);

            if(isSelected)
            {
                  int sizeD = delimiters.size();
                  for(int i=0; i<sizeD; i++)
                        delimiters.elementAt(i).draw(g);
                  
                  if(borders!=null)
                        borders.draw(g, false, antiAlias, rendering, alphaInter, colorRendering);
            }
      }

      
      
      
      
      @Override
00459       public void rescaleX(double formerX, double newX, double percent, LaTeXDrawRectangle bound)
      {
            if(percent==1.) return ;
            
            if(bound==null) throw new IllegalArgumentException();
            
            int i, size = getNbPoints();

            if(size>0)
            {
                  LaTeXDrawPoint2D NW = bound.getTheNWPoint(), SE = bound.getTheSEPoint(),farest,p;
      
                  if(formerX == SE.x)
                        farest = NW;
                  else
                        if(formerX == NW.x)
                              farest = SE;
                        else
                              throw new IllegalArgumentException();
            
                  for(i=0; i<size; i++)
                  {// We rescale each point
                        p = getPoint(i);
                        if(p.x!=farest.x)
                              p.x = farest.x+(p.x-farest.x)*percent;
                  }
                  
                  updateBorders();
            }
            
            updateShape();
      }
      
      
      
      
      
      @Override
00497       public void rescaleY(double formerY, double newY, double percent, LaTeXDrawRectangle bound)
      {
            if(percent==1.) return ;
            
            if(bound==null) throw new IllegalArgumentException();
            
            int i, size = getNbPoints();
            
            if(size>0)
            {
                  LaTeXDrawPoint2D NW = bound.getTheNWPoint(), SE = bound.getTheSEPoint(),farest,p;
      
                  if(formerY == SE.y)
                        farest = NW;
                  else
                        if(formerY == NW.y)
                              farest = SE;
                        else
                              throw new IllegalArgumentException();
                  
                  for(i=0; i<size; i++)
                  {// We rescale each point
                        p = getPoint(i);
                        if(p.y!=farest.y)
                              p.y = farest.y+(p.y-farest.y)*percent;
                  }
                  updateBorders();
            }
            updateShape();
      }
      
      
      
      
      @Override
00532       public synchronized void setLastPoint(LaTeXDrawPoint2D pt)
      {
            // We move the last point of the polygon
            if(!pts.isEmpty())
            {
                  pts.lastElement().setLocation(pt);
                  updateShape();
                  
                  if(borders!=null)
                        updateBorders();
            }     
      }
      
      
      
      @Override
00548       public synchronized void setFirstPoint(double x, double y)
      {
            // We move the last point of the polygon
            if(!pts.isEmpty())
            {
                  pts.firstElement().setLocation(x, y);
                  if(borders!=null)
                        updateBorders(new LaTeXDrawPoint2D(x,y));
                  
                  updateShape();
            }     
      }
      
      
      
      
      @Override
00565       public synchronized void setLastPoint(double x, double y)
      {
            setLastPoint(new LaTeXDrawPoint2D(x,y));
      }

      
      
      /**
       * Allows to set the coordinates of the last point of the figure with a Point
       * @param pt The point which will replace the last point (The last
       * point takes the coordinates of this point, the pointer doesn't change).
       */
00577       public synchronized void setLastPoint(Point pt)
      {
            setLastPoint(new LaTeXDrawPoint2D(pt.x,pt.y));  
      }
      
      
      
      
      @Override
00586       public LaTeXDrawPoint2D getTheSERotatedPoint()
      {
            return getTheSEPoint();
      }
      
      
      
      
      @Override
00595       public LaTeXDrawPoint2D getTheNWRotatedPoint()
      {
            return getTheNWPoint();
      }
            
      
      
      
      /**
       * Allows to get the number of points that the polygon contains
       * @return The number of points
       */
00607       public int getNbPoints()
      {
            if(pts!=null)
                  return pts.size();
            return 0;
      }
      
      
      
      
      @Override
00618       public LaTeXDrawPoint2D getTheNWPoint()
      {     
            if(borders!=null)
                  return borders.getTheNWPoint();
            return null;
      }

      
      
      
      @Override
00629       public LaTeXDrawPoint2D getTheSEPoint()
      {     
            if(borders!=null)
                  return borders.getTheSEPoint();
            return null;
      }

      
      
      
      @Override
00640       public boolean isIn(LaTeXDrawPoint2D pt)
      {
            if(isSelected && (borders.dNE.isIn(pt) || borders.dNW.isIn(pt) || 
                  borders.dSE.isIn(pt) || borders.dSW.isIn(pt) || borders.dS.isIn(pt)  || 
                  borders.dN.isIn(pt) || borders.dE.isIn(pt)  || borders.dW.isIn(pt)))
                  return true;
            
            boolean in = false;
            int i, sizeD = delimiters.size();
            
            // If the point is in a delimiter
            for(i=0; i<sizeD && !in; i++)
                  if(delimiters.elementAt(i).isIn(pt))
                        in = true;
            
            if(in) return true;
            
            Stroke wideline = new BasicStroke(hasDoubleBoundary ?(float)(thickness*2+doubleSep) : thickness, 
                        BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
            Shape s = wideline.createStrokedShape(shape);
            
            if(s.contains(pt))
                  return true;
            
            if(isFilled || hasShadow || hasGradient())
                  return shape.contains(pt);

            return false;
      }


      
      
      @Override
00674       public synchronized String getCodePSTricks(DrawBorders drawBorders, float ppc)
      {
            LaTeXDrawPoint2D d = drawBorders.getOriginPoint(), p;
            String coord="", add="", fillType=""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
            int i, size = getNbPoints();
            boolean isFilledWasChanged = false;
            
            if(size<2) return null;
            
            p = getPoint(0);
            
            // Creation of the coordinates of the polygon
            for(i=0; i<size; i++)
            {
                  p = getPoint(i);
                  coord+="("+(float)((p.x-d.x)/ppc)+","+ //$NON-NLS-1$//$NON-NLS-2$
                              (float)((d.y-p.y)/ppc)+")"; //$NON-NLS-1$
            }

            if(hasShadow)
            {
                  fillType+=",shadow=true";//$NON-NLS-1$
                  if(Math.toDegrees(shadowAngle)!=PSTricksConstants.DEFAULT_SHADOW_ANGLE)
                        fillType+=",shadowangle="+(float)Math.toDegrees(shadowAngle);//$NON-NLS-1$
                  
                  if(((float)shadowSize)!=((float)DEFAULT_SHADOW_SIZE))
                        fillType+=",shadowsize="+(float)(shadowSize/PPC);//$NON-NLS-1$
                  
                  if(!shadowColor.equals(PSTricksConstants.DEFAULT_SHADOW_COLOR))
                  {
                        String name = DviPsColors.getColourName(shadowColor);
                        if(name==null)
                        {
                              name = "color"+number+'e';//$NON-NLS-1$
                              DviPsColors.addUserColour(shadowColor, name); 
                        }
                        add += ",shadowcolor=" + name; //$NON-NLS-1$
                  }
                  if(!isFilled)
                  {
                        isFilled = true;
                        isFilledWasChanged = true;
                  }
            }
            
            String str = getPSTricksCodeFilling(ppc);
            if(str.length()>0) fillType=fillType+','+str;
            
            str = getPSTricksCodeLine(ppc);
            if(str.length()>0) add=add+','+str;
            
            if(hasDoubleBoundary)
            {
                  add+=",doubleline=true,doublesep="+(float)(doubleSep/ppc); //$NON-NLS-1$
                  
                  if(doubleColor!=PSTricksConstants.DEFAULT_DOUBLE_COLOR)
                  {
                        String name = DviPsColors.getColourName(doubleColor);
                        if(name==null)
                        {
                              name = "color"+number+'d';//$NON-NLS-1$
                              DviPsColors.addUserColour(doubleColor, name); 
                        }
                        add+= ",doublecolor="+name; //$NON-NLS-1$
                  }
            }
            
            if(isFilledWasChanged) isFilled = false;
            
            return "\\pspolygon[linewidth=" + (thickness/ppc)  //$NON-NLS-1$
            + add + fillType + "]"+coord; //$NON-NLS-1$
      }

      
      

      @Override
00751       public void onClick(Point pt)
      {
            isSelected = true;
            int i, sizeD = delimiters.size();
            boolean in = false;
            
            for(i=0; i<sizeD && !in; i++)
                  if(delimiters.elementAt(i).isIn(pt))
                        in = true;
            
            if(in)
                  dSelected = delimiters.elementAt(i-1);
            
            if(borders!=null)
                  borders.onClick(pt);
      }


      
      
      @Override
00772       public void shift(double shiftX, double shiftY) 
      {
            if(shiftX==0 && shiftY==0) return ;
            
            int i, size = pts.size();
            
            for(i=0; i<size; i++)
            {
                  LaTeXDrawPoint2D p = pts.elementAt(i);
                  p.x+=shiftX;
                  p.y+=shiftY;
            }
            
            if(borders!=null)
                  borders.shift(shiftX, shiftY);
            
            updateShape();
      }

      
      

      @Override
      public Object clone() throws CloneNotSupportedException
      {
            LaTeXDrawPolygon p = (LaTeXDrawPolygon) super.clone();
            
            p.pts = new Vector<LaTeXDrawPoint2D>();
            p.delimiters = new Vector<Delimitor>();
            int i, size;
            LaTeXDrawPoint2D pt;
            
            for(i=0, size=pts.size(); i<size; i++)
            {
                  pt = (LaTeXDrawPoint2D)pts.elementAt(i).clone();
                  p.pts.add(pt);
                  p.delimiters.add(new Delimitor(pt));
            }
            
            if(!p.pts.isEmpty() && borders!=null)
            {// We can't invoke borders.clone() because borders is a rectangle and a rectangle is a polygon, so ...
                  pt = p.pts.firstElement();
                  p.borders = new LaTeXDrawRectangle((LaTeXDrawPoint2D)pt.clone(), (LaTeXDrawPoint2D)pt.clone(),false);
                  p.borders.setSelected(isSelected);
                  p.updateBorders();
                  p.updateGravityCenter();
            }
                  
            p.setThickness(thickness);
            p.updateStyleOfDelimitors();
            p.updateShape();
            
            return p;
      }


      
      
      @Override
00831       public synchronized void updateGravityCenter() 
      {
            if(gravityCenter==null)
                  gravityCenter = new LaTeXDrawPoint2D();
            
            gravityCenter.setLocation(0, 0);
            
            if(pts.size()>0)
            {
                  for(LaTeXDrawPoint2D pt : pts)
                  {
                        gravityCenter.x+=pt.x;
                        gravityCenter.y+=pt.y;
                  }
                  
                  gravityCenter.x/=pts.size();
                  gravityCenter.y/=pts.size();
            }
      }

      
      
      
      @Override
00855       public synchronized void setThickness(float val)
      {
            super.setThickness(val);
            
            if(!Double.isInfinite(val) && !Double.isNaN(val) && val>0)
            {
                  double dim = Math.max(6,1.33*val+3.33 +1.);
                  int i, size = delimiters.size();
                  
                  // We change the size of the delimiters when the size of the figure change
                  for(i=0; i<size; i++)
                        delimiters.elementAt(i).setDim(dim);
                  
                  if(thickness!=val)
                  {
                        updateShape();
                        updateBorders();
                  }
            }
      }
      
      
      
      
      
      @Override
00881       public synchronized void setRotationAngle(double theta)
      {
            if(!Double.isInfinite(theta) && !Double.isNaN(theta))
                  addRotationAngle(theta-rotationAngle);
      }
      
      
      
      
      public synchronized void addRotationAngle(double theta)
      {
            if(!Double.isInfinite(theta) && !Double.isNaN(theta))
            {
                  theta%=(Math.PI*2);
                  int i, size = pts.size();
                  LaTeXDrawPoint2D p, pRot, formerGC = (LaTeXDrawPoint2D)getGravityCenter().clone();
                  
                  for(i=0; i<size; i++)
                  {
                        p = getPoint(i);
                        pRot = rotatePoint(p, formerGC, theta);
                        p.setLocation(pRot.x, pRot.y);
                  }
                  rotationAngle+=theta;
                  rotationAngle%=(Math.PI*2);
                  
                  updateBorders();
                  updateShape();
                  shift(getGravityCenter(), formerGC);
            }
      }
      
      


      @Override
00917       public void updateStyleOfDelimitors() 
      {
            int i, size = delimiters.size();
            if(isOnRotation)
                  for(i=0; i<size; i++)
                        delimiters.elementAt(i).setColorSet4();
            else
                  for(i=0; i<size; i++)
                        delimiters.elementAt(i).setColorSet3();
            
            if(borders!=null)
                  borders.updateStyleOfDelimitors();
      }
      
      
      
      
      /**
       * Allows to update the dimension of the borders of the polygon
       */
00937       public void updateBorders()
      {
            if(!pts.isEmpty())
            {
                  LaTeXDrawPoint2D pt = getPoint(0);
                  int i, size = pts.size();
                  double NWx, NWy, SEy, SEx;
                  NWx = SEx = pt.x;       
                  SEy = NWy = pt.y;
                  
                  for(i=1; i<size; i++)
                  {
                        pt = getPoint(i);
                        if(pt.x<NWx) NWx = pt.x;
                        else if(pt.x>SEx) SEx = pt.x;
                        if(pt.y<NWy) NWy = pt.y;
                        else if(pt.y>SEy) SEy = pt.y;
                  }
                  
                  if(borders==null)
                        borders = new LaTeXDrawRectangle(new LaTeXDrawPoint2D(NWx,NWy), new LaTeXDrawPoint2D(SEx,SEy), false);
                  else
                  {
                        borders.setLastPoint(SEx, SEy);
                        borders.setFirstPoint(NWx, NWy);
                  }
                  
                  updateGravityCenter();
            }
      }
      
      
      
      
      /**
       * Allows to update the dimension of the borders of the polygon when a point pt is added to the polygon
       * @param pt The added point
       */
00975       public void updateBorders(LaTeXDrawPoint2D pt)
      {
            if(pt==null || borders==null) return ;

            if(pts.size()>1)
            {
                  LaTeXDrawPoint2D NW = getBordersPoint(0);
                  LaTeXDrawPoint2D SE = getBordersPoint(-1);
                  
                  if(pt.x<NW.x)
                        if(pt.y<NW.y)
                               borders.setFirstPoint(pt);
                        else 
                        {
                              if(pt.y>SE.y)
                              {
                                     borders.setFirstPoint(pt.x,NW.y);
                                     borders.setLastPoint(SE.x,pt.y);
                              }
                              else borders.setFirstPoint(pt.x,NW.y);
                        }
                  else
                  {
                        if(pt.y<NW.y)
                               borders.setFirstPoint(NW.x,pt.y);
                        if(pt.x>SE.x)
                        {
                              if(pt.y>SE.y)
                                      borders.setLastPoint(pt);
                              else  borders.setLastPoint(pt.x, SE.y);         
                        }
                        else 
                              if(pt.y>SE.y) 
                                    borders.setLastPoint(SE.x,pt.y);
                  }
            }//if(pts.size()>1)
      }




      @Override
01017       public Shape createShape2D() 
      {
            if(hasDoubleBoundary)
            {
                  BasicStroke wideline = new BasicStroke((float)(doubleSep+thickness));
              Shape outline = wideline.createStrokedShape(shape);
              
              return outline;
            }
            
            return getInsideOutsideOrMiddleBorders();
      }

      
      
      
      
      @Override
01035       public Shape createNonRotatedShape2D() 
      {
             return createShape2D();
      }
      
      
      
      @SuppressWarnings("unchecked")
      private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException
      {
            canHaveShadow = true;
            isDoubleBoundaryable = true;
            interiorColor = (Color) ois.readObject();
            lineStyle = (String) ois.readObject();
            rotationAngle = ois.readDouble();
            thickness = ois.readFloat();
            isFilled = ois.readBoolean();
            isSelected = ois.readBoolean();
            isOnRotation = ois.readBoolean();
            linesColor = (Color) ois.readObject();
            blackDashLength = ois.readFloat();
            dotSep = ois.readFloat();
            whiteDashLength = ois.readFloat();
            pts = (Vector<LaTeXDrawPoint2D>) ois.readObject();
            
            delimiters = new Vector<Delimitor>();
            for(int i=0, size = pts.size();i<size; i++)
                  delimiters.add(new Delimitor(pts.elementAt(i)));      
            
            if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.5")>=0)//$NON-NLS-1$
            {
                  hasDoubleBoundary = ois.readBoolean();
                  doubleColor = (Color)ois.readObject();
                  doubleSep = ois.readDouble();
                  if(!(LaTeXDrawFrame.getVersionOfFile().compareTo("1.6")>=0)) //$NON-NLS-1$
                        ois.readBoolean();
                  hatchingAngle = ois.readDouble();
                  hatchingColor = (Color)ois.readObject();
                  hatchingStyle = (String)ois.readObject();
                  hatchingWidth = ois.readFloat();
                  
                  if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.6") < 0)//$NON-NLS-1$
                  {
                        if(hatchingStyle.equals(DECREPETED_FILL_CROSS))
                              hatchingStyle = PSTricksConstants.TOKEN_FILL_CROSSHATCH;
                        else if(hatchingStyle.equals(DECREPETED_FILL_HORIZ))
                              hatchingStyle = PSTricksConstants.TOKEN_FILL_HLINES;
                        else if(hatchingStyle.equals(DECREPETED_FILL_VERT))
                              hatchingStyle = PSTricksConstants.TOKEN_FILL_VLINES;
                        else if(hatchingStyle.equals(DECREPETED_FILL_NO))
                              hatchingStyle = PSTricksConstants.TOKEN_FILL_NONE;
                  }
            }
            else
            {
                  hasDoubleBoundary  = DEFAULT_HAS_DOUBLE_BOUNDARY;
                  doubleColor = DEFAULT_DOUBLE_COLOR;
                  doubleSep   = DEFAULT_DOUBLESEP;
                  hatchingAngle = DEFAULT_HATCH_ANGLE;
                  hatchingColor = DEFAULT_HATCH_COL;
                  hatchingStyle = DEFAULT_HATCH_STYLE;
                  hatchingWidth = DEFAULT_HATCH_WIDTH;
            }
            
            if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.7")>=0) //$NON-NLS-1$
            {
                  hasShadow   = ois.readBoolean();
                  shadowAngle = ois.readDouble();
                  shadowSize  = ois.readDouble();
                  shadowColor = (Color)ois.readObject();
                  gradientEndColor = (Color)ois.readObject();
                  gradientStartColor = (Color)ois.readObject();
                  gradientAngle = ois.readDouble();
                  gradientMidPoint = ois.readDouble();
            }
            else
            {
                  hasShadow   = DEFAULT_SHADOW_HAS;
                  shadowAngle = DEFAULT_SHADOW_ANGLE;
                  shadowSize  = DEFAULT_SHADOW_SIZE;
                  shadowColor = DEFAULT_SHADOW_COLOR;
                  gradientEndColor = PSTricksConstants.DEFAULT_GRADIENT_END_COLOR;
                  gradientStartColor = PSTricksConstants.DEFAULT_GRADIENT_START_COLOR;
                  gradientAngle = DEFAULT_GRADIENT_ANGLE;
                  gradientMidPoint = DEFAULT_GRADIENT_MID_POINT;
            }
            
            if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.8")>=0) //$NON-NLS-1$
                  hatchingSep = ois.readDouble();
            else
                  hatchingSep = DEFAULT_HATCH_SEP;
            
            setThickness(thickness);
            updateGravityCenter();
            shape = getInsideOutsideOrMiddleBorders();
      }



      
01135       public Shape[] getDbleBoundariesOutside(Shape classicBord)
      {// A Line cannot be double boundaries which move
            return getDbleBoundariesMiddle(classicBord);
      }

      
      
      
      
01144       public Shape[] getDbleBoundariesInside(Shape classicBord)
      {// A Line cannot be double boundaries which move
            return getDbleBoundariesMiddle(classicBord);
      }

      
      
      

01153       public Shape[] getDbleBoundariesMiddle(Shape classicBord)
      {
            LaTeXDrawPoint2D pt1 = getPoint(0), pt2 = getPoint(-1);
            Shape[] sx = new Shape[2];
            
            if(pt1.x<pt2.x+thickness && pt1.x>pt2.x-thickness)
            {
                  sx[0] = new GeneralPath(classicBord);
                  sx[1] = new GeneralPath(classicBord);
            }
            else
            {
                  sx[0] = getBorders(thickness+doubleSep, false);
                  sx[1] = getBorders(thickness+doubleSep, true);
            }
            
            return sx;
      }

      
      


01176       public Shape[] getDbleBoundariesOutInOrMiddle(Shape classicBord)
      {// A Line cannot be double boundaries which move
            return getDbleBoundariesMiddle(classicBord);
      }

      
      
      
      
      /**
       * Allows to get the outer or the inner borders following a distance
       * @param gap The distance of the borders
       * @param into True, you will get the borders inside the real borders
       */
01190       protected GeneralPath getBorders(double gap, boolean into)
      {
            int i, nbP = getNbPoints();
            LaTeXDrawPoint2D pt;
            double xs[] = new double[nbP], ys[] = new double[nbP];
            GeneralPath path = new GeneralPath();
            
            if(nbP<2)
                  return path;
            
            pt = pts.elementAt(0);
            path.moveTo((float)pt.x, (float)pt.y);
            
            for(i=1; i<nbP; i++)
            {
                  pt = pts.elementAt(i);
                  path.lineTo((float)pt.x, (float)pt.y);
            }
            
            path.closePath();
            
            if(gap!=0.)
                  try
                  {
                        if(!into) 
                              gap*=-1;
                        
                        Double b;
                        LaTeXDrawPoint2D inter;
                        LaTeXDrawPoint2D ptStart = pts.elementAt(0), ptEnd = pts.elementAt(1);
                        int endId = 2;
                        
                        if(ptStart.x==ptEnd.x)
                              while(endId<nbP && ptStart.x==pts.elementAt(endId).x)
                              {
                                    ptEnd = pts.elementAt(endId);
                                    endId++;
                              }
                        
                        Line l1 = new Line(ptStart, ptEnd, false), l2, l2Old, l0;
                        pt = l1.getMiddlePt();
                        LaTeXDrawPoint2D[] p = l1.getPerpendicularLine(pt, false).findPoints(pt, Math.abs(gap)); 
                        
                        if(p.length<2)
                              throw new IndexOutOfBoundsException();
                        
                        boolean dist = path.contains(p[0]);
                        
                        if( (into && dist) || (!into && !dist) )
                        {
                              b = p[0].y-l1.getA()*p[0].x;
                              l2Old = new Line(b, p[0],false);
                        }
                        else
                        {
                              b = p[1].y-l1.getA()*p[1].x;
                              l2Old = new Line(b, p[1],false);
                        }
                        
                        l0 = l2Old;
                        i = endId-1;
                        
                        while(i<nbP-1)
                        {
                              ptStart = pts.elementAt(i);
                              ptEnd   = pts.elementAt(i+1);
                              endId   = i+2;
                              
                              if(ptStart.x==ptEnd.x)
                                    while(endId<nbP && ptStart.x==pts.elementAt(endId).x)
                                    {
                                          ptEnd = pts.elementAt(endId);
                                          endId++;
                                    }
                              
                              l1 = new Line(ptStart, ptEnd, false);
                              pt = l1.getMiddlePt();
                              p = l1.getPerpendicularLine(pt, false).findPoints(pt, Math.abs(gap)); 
                              
                              if(p.length<2)
                                    throw new IndexOutOfBoundsException();
                              
                              dist = path.contains(p[0]);
                              
                              if( (into && dist) || (!into && !dist) )
                              {
                                    b = p[0].y-l1.getA()*p[0].x;
                                    l2 = new Line(b, p[0],false);
                              }
                              else
                              {
                                    b = p[1].y-l1.getA()*p[1].x;
                                    l2 = new Line(b, p[1],false);
                              }
                              
                              inter = l2Old.getIntersection(l2);
                              l2Old.setPointAt(inter, 1);
                              l2.setPointAt(inter, 0);
                              l2Old = l2;
                              xs[i] = (inter.x+ptStart.x)/2.;
                              ys[i] = (inter.y+ptStart.y)/2.;
                              
                              i = endId-1;
                        }// while
            
                        
                        if(endId<nbP)
                        {
                              // The last round
                              l1 = new Line(pts.elementAt(nbP-1), pts.elementAt(0), false);     
                              pt = l1.getMiddlePt();
                              p = l1.getPerpendicularLine(pt, false).findPoints(pt, Math.abs(gap)); 
                              
                              if(p.length<2)
                                    throw new IndexOutOfBoundsException();
                              
                              dist = path.contains(p[0]);
                              
                              if( (into && dist) || (!into && !dist) )
                              {
                                    b = p[0].y-l1.getA()*p[0].x;
                                    l2 = new Line(b, p[0], false);
                              }
                              else
                              {
                                    b = p[1].y-l1.getA()*p[1].x;
                                    l2 = new Line(b, p[1], false);
                              }
            
                              inter = l2Old.getIntersection(l2);
            
                              l2Old.setPointAt(inter, 1);
                              l2.setPointAt(inter, 0);
                              
                              xs[nbP-1] = (inter.x+pts.elementAt(nbP-1).x)/2.;
                              ys[nbP-1] = (inter.y+pts.elementAt(nbP-1).y)/2.;            
                              
                              inter = l2.getIntersection(l0);
            
                              xs[0] = (inter.x+pts.elementAt(0).x)/2.;
                              ys[0] = (inter.y+pts.elementAt(0).y)/2.;  
                        }
                        
                        path = new GeneralPath();
                        pt = pts.elementAt(0);
                        path.moveTo((float)xs[0], (float)ys[0]);
                        
                        for(i=1; i<nbP; i++)
                              path.lineTo((float)xs[i], (float)ys[i]);
                        
                        path.closePath();
                        
                  }catch(LaTeXDrawException e)
                  {
                        e.printStackTrace(); 
                        return path; 
                  }
            
            return path;
      }

      
      
      
      @Override
01355       public void updateShape()
      {
            updateGravityCenter();
            shape = getInsideOutsideOrMiddleBorders();
      }




      @Override
01365       public boolean isTooSmallToBeRescaled()
      {
            return borders.isTooSmallToBeRescaled();
      }
      
      
      
      
      @Override
01374       public Shape createShadowShape()
      {
            if(!canHaveShadow || !hasShadow) return shape;

            Shape shadowS;
            if(hasDoubleBoundary)
                   shadowS = getBorders(thickness*3+doubleSep, false); 
            else shadowS = getBorders(thickness, false); 
            
            double dx=0, dy=0;
            LaTeXDrawPoint2D cg = getGravityCenter();
            LaTeXDrawPoint2D shadowCg = (LaTeXDrawPoint2D)cg.clone();
            shadowCg.setLocation(cg.x+shadowSize, cg.y);
            shadowCg = Figure.rotatePoint(shadowCg, cg, shadowAngle);
            dx = shadowCg.x-cg.x;
            dy = cg.y-shadowCg.y;

            AffineTransform at = new AffineTransform();
            at.translate(dx, dy);
            return at.createTransformedShape(shadowS);
      }



      @Override
01399       public void mirrorHorizontal(LaTeXDrawPoint2D origin)
      {
            for(LaTeXDrawPoint2D pt : pts)
                  pt.setLocation(pt.horizontalSymmetry(origin));
            
            updateBorders();
            updateShape();
      }



      @Override
01411       public void mirrorVertical(LaTeXDrawPoint2D origin)
      {
            for(LaTeXDrawPoint2D pt : pts)
                  pt.setLocation(pt.verticalSymmetry(origin));
            
            updateBorders();
            updateShape();
      }



      @Override
01423       public synchronized LaTeXDrawPoint2D getLastPoint()
      {
            return pts.lastElement();
      }



      @Override
01431       public void updateToGrid(MagneticGrid grid)
      {
            for(LaTeXDrawPoint2D pt : pts)
                  pt.setLocation(grid.getTransformedPointToGrid(pt, false));
            
            updateBorders();
            updateShape();
      }



      @Override
01443       public int getSelectedDelimitorOrientation()
      {
            int del = super.getSelectedDelimitorOrientation();
            
            if(del!=DELIMITOR_ORIENTATION_NONE)
                  return del;
            
            if(borders!=null && borders.dSelected!=null)
                  return borders.getSelectedDelimitorOrientation();
            
            return DELIMITOR_ORIENTATION_NONE;
      }
      
      
      
      @Override
      public int hashCode()
      {
            return super.hashCode()*2;
      }
      
      
      
      /**
       * Set the coordinates of the point at id by the given coordinates.
       * @param x The X-coordinate
       * @param y The Y-coordinate
       * @param id The position of the point to replace
       * @since 1.9
       */
01473       public void setPoint(double x, double y, int id)
      {
            if(id<0 || id>=pts.size())
                  throw new IllegalArgumentException();
            
            pts.elementAt(id).setLocation(x, y);

            if(borders!=null)
                  updateBorders();
            
            updateShape();
      }



      /**
       * @return The points of the shape.
       * @since 2.0.0
       */
01492       public Vector<LaTeXDrawPoint2D> getPoints()
      {
            return pts;
      }
}

Generated by  Doxygen 1.6.0   Back to index