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

Dot.java

package latexDraw.figures;

import static java.lang.Math.PI;
import static java.lang.Math.cos;
import static java.lang.Math.sin;

import java.awt.*;
import java.awt.geom.*;
import java.io.IOException;
import java.io.ObjectInputStream;

import javax.swing.JLabel;

import latexDraw.psTricks.DviPsColors;
import latexDraw.psTricks.PSTricksConstants;
import latexDraw.ui.components.Delimitor;
import latexDraw.ui.components.LaTeXDrawComboBox;
import latexDraw.ui.components.LabelListCellRenderer;
import latexDraw.ui.components.MagneticGrid;
import latexDraw.util.LaTeXDrawPoint2D;
import latexDraw.util.LaTeXDrawResources;


/**
 * This class defines a kind of figure: dots<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>
 */
00043 public class Dot extends Figure
{
      private static final long serialVersionUID = 1L;

      /** The centre of the dot */
00048       private LaTeXDrawPoint2D center;
      
      /** The thickness of the dot by default */
00051       public static final int DEFAULT_WIDTH = 6;
      
      /** Useful to calculate the thickness of dot with o style */
00054       public static final float THICKNESS_o_STYLE_FACTOR = 16 ;
      
      /** The style of the dot by default */
00057       public static final String DEFAULT_DOT_STYLE = PSTricksConstants.DEFAULT_DOT_STYLE;
      
      /** Corresponds to the golden angle (Useful for golden diamond) */
00060       public final double GOLDEN_ANGLE = 0.553574;
      
      /** The gap used to draw a plus */
00063       private double plusGap;
      
      /** The thickness of the plus shape is computes with that coefficient */
00066       public static final double PLUS_COEFF_WIDTH = 6.5;
      
      /** The gap used to draw a cross */
00069       private double crossGap;
      
      /** The gap used to draw a vertical bar */
00072       private double barGap;
      
      /** The thickness used to draw a vertical bar */
00075       private double barThickness;

      /** The current style of the circle */
00078       private String currentStyle;
      
      /** The width of the circle */
00081       private float width;
      
      private Delimitor d;
      
      
      /**
       * The constructor by default.
       */
00089       public Dot(boolean increaseMeter)
      {
            this(new LaTeXDrawPoint2D(), increaseMeter);
      }
      
      
      
      
      /**
       * The constructor by copy.
       * @param pt The new centre of the dot.
       */
00101       public Dot(LaTeXDrawPoint2D pt, boolean increaseMeter)
      {
            this(pt, DEFAULT_DOT_STYLE, DEFAULT_WIDTH, increaseMeter);
      }
      
      
      
      
      /**
       * The constructor by copy.
       * @param pt The new centre of the dot.
       * @param style The style of the dot.
       * @param size The size of the dot.
       */
00115       public Dot(LaTeXDrawPoint2D pt, String style, float size, boolean increaseMeter)
      {
            super(increaseMeter);
            
            canHaveShadow           = false;
            isBordersMovable  = false;
            isDashableOrDotable = false;
            isDoubleBoundaryable= false;
            isResizable = false;
            isThicknessable = false;
            d = new Delimitor();
            center = pt;
            width = size;
            updateGap();
            currentStyle = style;
            updateDelimitor();
            updateBorders();
            updateShape();
            updateCanBeFilled();
            updateGravityCenter();
      }
      
      
      
      @Deprecated
      @Override
00141       public void setIsFilled(boolean state)
      {
            /*
             * A dot is always filled.
             */
      }
      
      
      
      /**
       * Allows to update the delimiter following the size of the dot
       */
00153       public void updateDelimitor()
      {
            if(width<30)
                  d.setCoordinates(center.x+width*2./3., center.y-width*2./3.);
            else 
                  d.setCoordinates(center.x+width/2., center.y-width/2.);
      }
      
      
      
      /**
       * Allows to get the centre of the dot
       * @return The centre of the dot
       */
00167       public synchronized LaTeXDrawPoint2D getCenter()
      {
            return center;
      }
      
      
      
      
      /**
       * Allows to update the values of the gaps
       */
00178       public void updateGap()
      {
            plusGap  = width/160.;
            crossGap = width/10.; 
            barGap   = width/3.75;
            barThickness = width/8.;
      }
      
      
      
      
      /**
       * Allows to set the width of the dot
       * @param w The width of the dot
       */
00193       public synchronized void setWidth(float w)
      { 
            if(w<=0)
                  throw new IllegalArgumentException();
            
            width = w;
            updateGap();
            updateDelimitor();
            updateBorders();
            updateShape();
      }
      
      
      
      
      /**
       * Allows to get the width of the circle
       * @return The width of the circle
       */
00212       public synchronized float getWidth()
      {
            return width;
      }
      
      
      
      /**
       * Allows to set the style of the dot
       * @param newStyle The new style of the dot
       * @throws IllegalArgumentException If the new style is not valid.
       */
00224       public synchronized void setCurrentStyle(String newStyle)
      {
            if(!PSTricksConstants.isValidDotStyle(newStyle))
                  throw new IllegalArgumentException();
            
            currentStyle = newStyle;
            updateCanBeFilled();
            updateBorders();
            updateShape();
            updateGravityCenter();
      }
      
      
      
      
      public void updateBorders()
      {
            updateGap();
            
            Shape s = createNonRotatedShape2D();
            
            Rectangle2D rec = s.getBounds2D();
            
            if(borders==null)
                  borders = new LaTeXDrawRectangle(false);
      
            borders.setFirstPoint(new LaTeXDrawPoint2D(rec.getMinX(), rec.getMinY()));
            borders.setLastPoint(new LaTeXDrawPoint2D(rec.getMaxX(), rec.getMaxY()));
      }
      
      
      
      
      /**
       * Allows to get the current style of the dot
       * @return The current style of the dot
       */
00261       public synchronized String getCurrentStyle()
      {
            return currentStyle;
      }
      
      
      
      
      
      @Override
00271       public void onDragged(Point formerPt, Point newPt)
      {
            if(formerPt.equals(newPt)) return;
            
            if(dSelected==d)
            {
                  if(isOnRotation)
                        rotate(formerPt, newPt);
                  else
                  {
                        LaTeXDrawPoint2D pt = Figure.rotatePoint(new LaTeXDrawPoint2D(newPt), borders.gravityCenter, -rotationAngle);
                        float w = (float)(Math.abs(pt.x-center.x)*2.);
                        
                        if(w>0)
                              setWidth(w);
                        
                        updateDelimitor();
                  }
                  updateShape();
            }
            else
                  shift(formerPt, newPt);
      }

      
      
      @Override
00298       public Color getInteriorColor()
      {
            if(canBeFilled)
                  return interiorColor;
            
            return Color.BLACK;
      }
      
      
      
      
      
      @Override
00311       public void draw(Graphics2D g, Object antiAlias, Object rendering, Object alphaInter, Object colorRendering)
      {
            LaTeXDrawPoint2D NW = new LaTeXDrawPoint2D(center.x-width/2., center.y-width/2.);
            LaTeXDrawPoint2D SE = new LaTeXDrawPoint2D(center.x+width/2., center.y+width/2.);
            LaTeXDrawPoint2D NW2 = getTheNWPoint(), SE2 = getTheSEPoint();
            float dec = width/THICKNESS_o_STYLE_FACTOR;
            double cx = (NW2.x+SE2.x)/2., cy = (NW2.y+SE2.y)/2.;
            double c2x = Math.cos(rotationAngle)*cx - Math.sin(rotationAngle)*cy;
            double c2y = Math.sin(rotationAngle)*cx + Math.cos(rotationAngle)*cy;
            double c3x = Math.cos(-rotationAngle)*(cx-c2x) - Math.sin(-rotationAngle)*(cy-c2y);
            double c3y = Math.sin(-rotationAngle)*(cx-c2x) + Math.cos(-rotationAngle)*(cy-c2y);

            if(rotationAngle%(Math.PI*2)!=0)
            {           
                  g.rotate(rotationAngle);
                  g.translate(c3x,c3y);
            }
            
            Color formerCol = g.getColor();

            if(currentStyle.equals(PSTricksConstants.DOT_STYLE))
            {     
                  g.setColor(linesColor);
                  Ellipse2D.Double e = new Ellipse2D.Double(NW.x, NW.y, width, width);
                  g.fill(e); 
            }
            else if(currentStyle.equals(PSTricksConstants.O_STYLE) || currentStyle.equals(PSTricksConstants.OPLUS_STYLE) ||
                        currentStyle.equals(PSTricksConstants.OTIMES_STYLE))
            {
                  if(currentStyle.equals(PSTricksConstants.O_STYLE))
                        dec = (float)(width*(0.1/3.6))*2;
                  else
                        dec = (float)(width*(0.1/2.6))*2;
                  
                  Ellipse2D.Double e = new Ellipse2D.Double(NW.x+dec/2., NW.y+dec/2., width-dec, width-dec);
                  
                  if(!currentStyle.equals(PSTricksConstants.OPLUS_STYLE) && !currentStyle.equals(PSTricksConstants.OTIMES_STYLE))
                  {
                        g.setColor(isFilled ? interiorColor : Color.WHITE);
                        g.fill(e);
                  }
                  
                  g.setColor(linesColor);
                  g.setStroke(new BasicStroke(dec, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                  g.draw(e); 
                  
                  if(currentStyle.equals(PSTricksConstants.OPLUS_STYLE))
                  {
                        g.draw(new Line2D.Double((NW.x+SE.x)/2., NW.y+dec*2, (NW.x+SE.x)/2., SE.y-dec*2));
                        g.draw(new Line2D.Double(NW.x+dec*2, (NW.y+SE.y)/2., SE.x-dec*2, (NW.y+SE.y)/2.));
                  }
                  else if(currentStyle.equals(PSTricksConstants.OTIMES_STYLE))
                  {
                        LaTeXDrawPoint2D p1 = new LaTeXDrawPoint2D((NW.x+SE.x)/2., NW.y+dec*2);
                        LaTeXDrawPoint2D p2 = new LaTeXDrawPoint2D((NW.x+SE.x)/2., SE.y-dec*2);
                        
                        p1 = rotatePoint(p1, Math.PI/4.);
                        p2 = rotatePoint(p2, Math.PI/4.);
                        
                        g.draw(new Line2D.Double(p1.x, p1.y, p2.x, p2.y));
                        
                        p1.setLocation(NW.x+dec*2, (NW.y+SE.y)/2.);
                        p2.setLocation(SE.x-dec*2, (NW.y+SE.y)/2.);
                        p1 = rotatePoint(p1, Math.PI/4.);
                        p2 = rotatePoint(p2, Math.PI/4.);
                        
                        g.draw(new Line2D.Double(p1.x, p1.y, p2.x, p2.y));
                  }                 
            }
            else if(currentStyle.equals(PSTricksConstants.BAR_STYLE))
            {
                  g.setColor(linesColor);
                  g.setStroke(new BasicStroke((float)barThickness, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER));
                  g.draw(new Line2D.Double((NW.x+SE.x)/2.,NW.y+barThickness/2.,(NW.x+SE.x)/2., SE.y+ barGap));
            }
            else if(currentStyle.equals(PSTricksConstants.PLUS_STYLE))
            {
                  g.setColor(linesColor);
                  g.setStroke(new BasicStroke((float) (width/PLUS_COEFF_WIDTH), BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER));

                  GeneralPath gp = new GeneralPath();
                  
                  gp.moveTo((float)((NW.x+SE.x)/2.), (float)(NW.y-plusGap));
                  gp.lineTo((float)((NW.x+SE.x)/2.), (float)(SE.y+plusGap));
                  gp.moveTo((float)(NW.x-plusGap), (float)((NW.y+SE.y)/2.));
                  gp.lineTo((float)(SE.x+plusGap), (float)((NW.y+SE.y)/2.));
                  g.draw(gp);
            }
            else if(currentStyle.equals(PSTricksConstants.SQUARE_STYLE) || currentStyle.equals(PSTricksConstants.FSQUARE_STYLE))
            {
                  if(currentStyle.equals(PSTricksConstants.SQUARE_STYLE))
                        if(isFilled)
                               g.setColor(interiorColor);
                        else
                             g.setColor(Color.WHITE);
                  else 
                        g.setColor(linesColor);
                  
                  dec = (float)(width*(0.1/4))*2;
                  
                  g.fill(new Rectangle2D.Double(NW.x+dec*1.5, NW.y+dec*1.5, width-dec*3, width-dec*3));
                  g.setStroke(new BasicStroke(dec, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                  g.setColor(linesColor);
                  g.draw(new Rectangle2D.Double(NW.x+dec+dec/2., NW.y+dec+dec/2., width-dec*3, width-dec*3));
            }
            else if(currentStyle.equals(PSTricksConstants.TRIANGLE_STYLE) || currentStyle.equals(PSTricksConstants.FTRIANGLE_STYLE) ||
                        currentStyle.equals(PSTricksConstants.DIAMOND_STYLE) || currentStyle.equals(PSTricksConstants.FDIAMOND_STYLE) ||
                        currentStyle.equals(PSTricksConstants.PENTAGON_STYLE) || currentStyle.equals(PSTricksConstants.FPENTAGON_STYLE))
            {
                  Polygon p;
                  
                  if(currentStyle.equals(PSTricksConstants.TRIANGLE_STYLE) || currentStyle.equals(PSTricksConstants.FTRIANGLE_STYLE))
                        p = createTriangle();
                  else
                        if(currentStyle.equals(PSTricksConstants.DIAMOND_STYLE) || currentStyle.equals(PSTricksConstants.FDIAMOND_STYLE))
                              p = createDiamond();
                        else
                              p = createPentagon();
                  
                  if(currentStyle.equals(PSTricksConstants.TRIANGLE_STYLE) || currentStyle.equals(PSTricksConstants.DIAMOND_STYLE) ||
                        currentStyle.equals(PSTricksConstants.PENTAGON_STYLE))
                        if(isFilled)
                               g.setColor(interiorColor);
                        else
                               g.setColor(Color.WHITE);
                  else 
                        g.setColor(linesColor);
                  
                  g.fill(p);              
                  g.setStroke(new BasicStroke(dec, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER));
                  g.setColor(linesColor);
                  g.draw(p);              
            }
            else if(currentStyle.equals(PSTricksConstants.X_STYLE))
            {
                  g.setColor(linesColor);
                  g.setStroke(new BasicStroke((float)crossGap, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER));

                  GeneralPath gp = new GeneralPath();
                  
                  gp.moveTo((float)(NW.x+crossGap), (float)(NW.y+crossGap));
                  gp.lineTo((float)(SE.x-crossGap), (float)(SE.y-crossGap));
                  gp.moveTo((float)(SE.x-crossGap), (float)(NW.y+crossGap));
                  gp.lineTo((float)(NW.x+crossGap), (float)(SE.y-crossGap));
                  g.draw(gp);
            }
            else if(currentStyle.equals(PSTricksConstants.ASTERISK_STYLE))
            {
                  g.setColor(linesColor);
                  g.setStroke(new BasicStroke(dec, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER));
                  
                  double xCenter = (NW.x+SE.x)/2., yCenter = (NW.y+SE.y)/2.;
                  double radius = Math.abs((NW.y+width/10.)-(SE.y-width/10.))/2. + dec;
                  g.draw(new Line2D.Double((NW.x+SE.x)/2.,NW.y+width/10.-dec, (NW.x+SE.x)/2.,SE.y-width/10.+dec));
                  g.draw(new Line2D.Double((Math.cos(Math.PI/6.)*radius+xCenter), radius/2. + yCenter,
                                    Math.cos(7*Math.PI/6.)*radius+xCenter, Math.sin(7*Math.PI/6.)*radius+yCenter));
                  g.draw(new Line2D.Double((Math.cos(5*Math.PI/6.)*radius+xCenter),
                                    Math.sin(5*Math.PI/6.)*radius+yCenter,
                                    Math.cos(11*Math.PI/6.)*radius+xCenter, Math.sin(11*Math.PI/6.)*radius+yCenter));
            }
            
            if(d!=null && isSelected)
                  d.draw(g);
            
            g.setColor(formerCol);        

            if(rotationAngle%(Math.PI*2)!=0)
            {
                  g.translate(-c3x,-c3y);
                  g.rotate(-rotationAngle);
            }
      }

      
      
      
      /**
       * Allows to create a triangle (one of the possibles shapes of a dot).
       * @return The triangle
       */
00491       public Polygon createTriangle()
      {
            double NWx = center.x-width/2., NWy = center.y-width/2.;
            double SEx = center.x+width/2., SEy = center.y+width/2.;
            float dec = width/THICKNESS_o_STYLE_FACTOR;
            int nbPts = 3, xs[] = new int[nbPts], ys[] = new int[nbPts];
            
            xs[0] = (int) ((SEx + NWx)/2);      ys[0] = (int) (NWy-1.5*dec);  
            xs[1] = (int) ((int) (NWx)-0.3*dec);      ys[1] = (int) (SEy-3*dec);
            xs[2] = (int) ((int) (SEx)+0.3*dec);      ys[2] = (int) (SEy-3*dec);
            
            return new Polygon(xs, ys, nbPts);
      }
      
      
      
      
      /**
       * Allows to create a pentagon (one of the possibles shapes of a dot)
       * @return The pentagon
       */
00512       public Polygon createPentagon()
      {
            double NWx = center.x-width/2., NWy = center.y-width/2.;
            double SEx = center.x+width/2., SEy = center.y+width/2.;
            float dec = width/THICKNESS_o_STYLE_FACTOR;
            int nbPts = 5, xs[] = new int[nbPts], ys[] = new int[nbPts];
            double yCenter = (NWy+SEy)/2. - dec;
            double xCenter = (NWx+SEx)/2.;
            double dist = Math.abs(NWy-SEy)/2. + dec;
            double  c1 = 0.25*(Math.sqrt(5)-1.)*dist, 
                        s1 = Math.sin(2*Math.PI/5.)*dist, 
                        c2 = 0.25*(Math.sqrt(5)+1.)*dist, 
                        s2 = Math.sin(4*Math.PI/5.)*dist;

            xs[0] = (int)xCenter;
            xs[1] = (int)(s1 + xCenter);
            xs[2] = (int)(s2 + xCenter);
            xs[3] = (int)(-s2 + xCenter);
            xs[4] = (int)(-s1 + xCenter);
            ys[0] = (int)(NWy-dec);
            ys[1] = ys[4] = (int) (-c1 + yCenter + dec); 
            ys[2] = ys[3] = (int) (c2 + yCenter + dec);     
            
            return new Polygon(xs, ys, nbPts);
      }
      
      
      
      
      /**
       * Allows to create a list of the different style of the dot
       * @return The list
       */
00545       public static LaTeXDrawComboBox createDotStyleChoice()
      {
            LaTeXDrawComboBox dotChoice = new LaTeXDrawComboBox();
            dotChoice.setRenderer(new LabelListCellRenderer());
            JLabel label = new JLabel(PSTricksConstants.DOT_STYLE);
            label.setName(PSTricksConstants.DOT_STYLE);
            label.setIcon(LaTeXDrawResources.dotStyleNoneIcon);
      dotChoice.addItem(label);
      label = new JLabel(PSTricksConstants.ASTERISK_STYLE);
      label.setName(PSTricksConstants.ASTERISK_STYLE);
      label.setIcon(LaTeXDrawResources.dotStyleAsteriskIcon);
      dotChoice.addItem(label);
      label = new JLabel(PSTricksConstants.BAR_STYLE);
      label.setName(PSTricksConstants.BAR_STYLE);
      label.setIcon(LaTeXDrawResources.dotStyleBarIcon);
      dotChoice.addItem(label);
      label = new JLabel(PSTricksConstants.DIAMOND_STYLE);
      label.setName(PSTricksConstants.DIAMOND_STYLE);
      label.setIcon(LaTeXDrawResources.dotStyleDiamondIcon);
      dotChoice.addItem(label);
      label = new JLabel(PSTricksConstants.FDIAMOND_STYLE);
      label.setName(PSTricksConstants.FDIAMOND_STYLE);
      label.setIcon(LaTeXDrawResources.dotStyleDiamondFIcon);
      dotChoice.addItem(label);
      label = new JLabel(PSTricksConstants.O_STYLE);
      label.setName(PSTricksConstants.O_STYLE);
      label.setIcon(LaTeXDrawResources.dotStyleOIcon);
      dotChoice.addItem(label);
      label = new JLabel(PSTricksConstants.OPLUS_STYLE);
      label.setName(PSTricksConstants.OPLUS_STYLE);
      label.setIcon(LaTeXDrawResources.dotStyleOPlusIcon);
      dotChoice.addItem(label);
      label = new JLabel(PSTricksConstants.OTIMES_STYLE);
      label.setName(PSTricksConstants.OTIMES_STYLE);
      label.setIcon(LaTeXDrawResources.dotStyleOCrossIcon);
      dotChoice.addItem(label);
      label = new JLabel(PSTricksConstants.PLUS_STYLE);
      label.setName(PSTricksConstants.PLUS_STYLE);
      label.setIcon(LaTeXDrawResources.dotStylePlusIcon);
      dotChoice.addItem(label);
      label = new JLabel(PSTricksConstants.X_STYLE);
      label.setName(PSTricksConstants.X_STYLE);
      label.setIcon(LaTeXDrawResources.dotStyleCrossIcon);
      dotChoice.addItem(label);
      label = new JLabel(PSTricksConstants.TRIANGLE_STYLE);
      label.setName(PSTricksConstants.TRIANGLE_STYLE);
      label.setIcon(LaTeXDrawResources.dotStyleTriangleIcon);
      dotChoice.addItem(label);
      label = new JLabel(PSTricksConstants.FTRIANGLE_STYLE);
      label.setName(PSTricksConstants.FTRIANGLE_STYLE);
      label.setIcon(LaTeXDrawResources.dotStyleTriangleFIcon);
      dotChoice.addItem(label);
      label = new JLabel(PSTricksConstants.PENTAGON_STYLE);
      label.setName(PSTricksConstants.PENTAGON_STYLE);
      label.setIcon(LaTeXDrawResources.dotStylePentagonIcon);
      dotChoice.addItem(label);
      label = new JLabel(PSTricksConstants.FPENTAGON_STYLE);
      label.setName(PSTricksConstants.FPENTAGON_STYLE);
      label.setIcon(LaTeXDrawResources.dotStylePentagonFIcon);
      dotChoice.addItem(label);
      label = new JLabel(PSTricksConstants.SQUARE_STYLE);
      label.setName(PSTricksConstants.SQUARE_STYLE);
      label.setIcon(LaTeXDrawResources.dotStyleSquareIcon);
      dotChoice.addItem(label);
      label = new JLabel(PSTricksConstants.FSQUARE_STYLE);
      label.setName(PSTricksConstants.FSQUARE_STYLE);
      label.setIcon(LaTeXDrawResources.dotStyleSquareFIcon);
      dotChoice.addItem(label);
      
      return dotChoice;
      }
      
      
      
      
      
      /**
       * Allows to create a diamond (one of the possibles shapes of a dot)
       * @return The golden diamond
       */
00625       public Polygon createDiamond()
      {
            double NWx = center.x-width/2., NWy = center.y-width/2.;
            double SEx = center.x+width/2., SEy = center.y+width/2.;
            float dec = width/THICKNESS_o_STYLE_FACTOR;
            
            // This diamond is a golden diamond 
            // cf. http://mathworld.wolfram.com/GoldenRhombus.html
            int nbPts = 4, xs[] = new int[nbPts], ys[] = new int[nbPts];
            double a = Math.abs((NWx-SEx))/(2.*Math.sin(GOLDEN_ANGLE));
            double p = 2*a*Math.cos(GOLDEN_ANGLE);
            
            xs[1] = (int) ((SEx)-dec-.5*dec);         ys[1] = (int)(NWy+SEy)/2;
            xs[3] = (int) ((NWx)+dec+.5*dec);         ys[3] = (int)(NWy+SEy)/2;
            xs[0] = (xs[1]+xs[3])>>>1;
            ys[0] = (int) ((NWy+SEy)/2+p/2.-dec-.5*dec);    
            xs[2] = (xs[1]+xs[3])>>>1;    
            ys[2] = (int) ((NWy+SEy)/2-p/2.+dec+.5*dec);
            
            return new Polygon(xs, ys, nbPts);
      }
      
      
      
      

      @Override
00652       public boolean isIn(LaTeXDrawPoint2D pt) 
      {
            if(isSelected() && d.isIn(Figure.rotatePoint(pt, borders.gravityCenter, -rotationAngle))) 
                  return true;
            
            if(shape==null)
                  updateShape();
            
            boolean ok = shape.contains(pt);
      
            if(!ok && isFilled)
                  ok = createUnstrokedShape2D().contains(pt);
            
            return ok;
      }

      
      
      @Override
00671       public String getCodePSTricks(DrawBorders drawBorders, float ppc)
      {
            LaTeXDrawPoint2D o = drawBorders.getOriginPoint();
            double x = center.x - o.x, y = o.y - center.y;
            String start = "", end = "", add = ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

            if(!linesColor.equals(PSTricksConstants.DEFAULT_LINE_COLOR))
            { // add colour code
                  String name = DviPsColors.getColourName(linesColor);
                  if(name==null)
                  {
                        name = "color"+number;//$NON-NLS-1$
                        DviPsColors.addUserColour(linesColor, name); 
                  }
                  add += ",linecolor="+name;     //$NON-NLS-1$          
            }
            
            if(canBeFilled)
            {
                  add+= ",fillstyle=solid"; //$NON-NLS-1$
                  if(!interiorColor.equals(PSTricksConstants.DEFAULT_INTERIOR_COLOR))
                  {
                        String name = DviPsColors.getColourName(interiorColor);
                        if(name==null)
                        {
                              name = "color"+number+'b';//$NON-NLS-1$
                              DviPsColors.addUserColour(interiorColor, name); 
                        }
                        add+= ",fillcolor="+name; //$NON-NLS-1$
                  }
            }
            
            if(rotationAngle%(Math.PI*2)!=0.)
            {
                  LaTeXDrawPoint2D tmp = Figure.rotatePoint(center, borders.gravityCenter, rotationAngle);
                  float tmpX = (float)(tmp.x-center.x), tmpY = (float)(center.y-tmp.y) ;
                  add +=",dotangle="+(float)(Math.toDegrees(-rotationAngle)); //$NON-NLS-1$
                  
                  if(tmpX!=0f && tmpY!=0f)
                  {
                        start = "\\rput("+tmpX/ppc+", "+ tmpY/ppc +"){";  //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
                        end = "}"; //$NON-NLS-1$
                  }
            }
            
            if(!currentStyle.equals(PSTricksConstants.DOT_STYLE))
                  add +=",dotstyle="+currentStyle; //$NON-NLS-1$
            
            return start + "\\psdots[dotsize=" +  (width/ppc) + add  //$NON-NLS-1$
                        + "](" + (float)(x/ppc) + ',' + (float)(y/ppc) + ')' + end;//$NON-NLS-1$
      }

      

      

      @Override
00728       public void onClick(Point p) 
      {
            isSelected = true;
            LaTeXDrawPoint2D pt = Figure.rotatePoint(new LaTeXDrawPoint2D(p), borders.gravityCenter, -rotationAngle);
            if(d.isIn(pt)) dSelected = d;
      }

      
      

      @Override
00739       public void onRelease() 
      {
            isSelected = false;
            dSelected = null;
            setOnRotation(false);
      }


      

      @Override
00750       public void shift(double shiftX, double shiftY)
      {
            if(shiftX==0 && shiftY==0) return ;
            
            center.x+=shiftX;
            center.y+=shiftY;
            updateDelimitor();
            updateBorders();
            updateShape();
            updateGravityCenter();
      }

      
      
      @Override
      @Deprecated
00766       public synchronized void setLastPoint(double x, double y)
      {
            /*
             * Nothing to do.
             */
      }

      
      @Override
      @Deprecated
00776       public synchronized void setFirstPoint(double x, double y)
      {
            /*
             * Nothing to do.
             */
      }
      

      
      
      
      @Override
00788       public boolean canBeHatched()
      {
            return false;
      }
      
      
      
      
      @Override
      public Object clone() throws CloneNotSupportedException
      {
            Dot dot = (Dot) super.clone();
            dot.center = (LaTeXDrawPoint2D)center.clone();
            dot.barGap = barGap;
            dot.barThickness = barThickness;
            dot.crossGap = crossGap;
            dot.currentStyle = currentStyle;
            dot.plusGap = plusGap;
            dot.width = width;
            dot.d = (Delimitor) d.clone();
            dot.updateShape();
            dot.borders = null;
            dot.updateBorders();
            dot.updateCanBeFilled();
            dot.updateGravityCenter();
            
            return dot;
      }




      @Override
00821       public void updateStyleOfDelimitors() 
      {
            if(isOnRotation)
                   d.setColorSet4();
            else d.setColorSet1();
      }





      @Override
00833       public Shape createNonRotatedShape2D() 
      {
            LaTeXDrawPoint2D NW = new LaTeXDrawPoint2D(center.x-width/2., center.y-width/2.);
            LaTeXDrawPoint2D SE = new LaTeXDrawPoint2D(center.x+width/2., center.y+width/2.);
            float dec = width/THICKNESS_o_STYLE_FACTOR;

            if(currentStyle.equals(PSTricksConstants.DOT_STYLE) ||
                  currentStyle.equals(PSTricksConstants.O_STYLE) || 
                  currentStyle.equals(PSTricksConstants.OPLUS_STYLE) ||
                  currentStyle.equals(PSTricksConstants.OTIMES_STYLE))
                  return new Ellipse2D.Double(NW.x, NW.y, width, width);
            
            if(currentStyle.equals(PSTricksConstants.BAR_STYLE))
            {
                  BasicStroke wideline = new BasicStroke((float)barThickness);
              Shape outline = wideline.createStrokedShape(new Line2D.Double((NW.x+SE.x)/2.,
                                          NW.y+barThickness/2.,(NW.x+SE.x)/2., SE.y + barGap));
              
                  return outline;
            }

            if(currentStyle.equals(PSTricksConstants.PLUS_STYLE))
            {
                  GeneralPath gp = new GeneralPath();
                  
                  gp.moveTo((float)((NW.x+SE.x)/2.), (float)(NW.y-plusGap));
                  gp.lineTo((float)((NW.x+SE.x)/2.), (float)(SE.y+plusGap));
                  gp.moveTo((float)(NW.x-plusGap), (float)((NW.y+SE.y)/2.));
                  gp.lineTo((float)(SE.x+plusGap), (float)((NW.y+SE.y)/2.));
                  
                  BasicStroke wideline = new BasicStroke((float) (width/PLUS_COEFF_WIDTH));
              Shape outline = wideline.createStrokedShape(gp);
              
                  return outline;
            }
            
            if(currentStyle.equals(PSTricksConstants.SQUARE_STYLE) || 
                  currentStyle.equals(PSTricksConstants.FSQUARE_STYLE))
            {
                  BasicStroke wideline = new BasicStroke(dec);
              Shape outline = wideline.createStrokedShape(
                  new Rectangle2D.Double(NW.x+dec, NW.y+dec, Math.abs(NW.x-SE.x)-2*dec, Math.abs(NW.y - SE.y)-2*dec));
              
                  return outline;
            }
            
            if(currentStyle.equals(PSTricksConstants.TRIANGLE_STYLE) || 
                  currentStyle.equals(PSTricksConstants.FTRIANGLE_STYLE))
            {
                  BasicStroke wideline = new BasicStroke(dec);
              Shape outline = wideline.createStrokedShape(createTriangle());
              
                  return outline;
            }
            
            if(currentStyle.equals(PSTricksConstants.DIAMOND_STYLE) || 
                  currentStyle.equals(PSTricksConstants.FDIAMOND_STYLE))
            {
                  BasicStroke wideline = new BasicStroke(dec);
              Shape outline = wideline.createStrokedShape(createDiamond());
              
                  return outline;
            }
            
            if(currentStyle.equals(PSTricksConstants.PENTAGON_STYLE) || 
                  currentStyle.equals(PSTricksConstants.FPENTAGON_STYLE))
            {
                  BasicStroke wideline = new BasicStroke(dec);
              Shape outline = wideline.createStrokedShape(createPentagon());
              
                  return outline;
            }
            
            if(currentStyle.equals(PSTricksConstants.X_STYLE))
            {
                  GeneralPath gp = new GeneralPath();
                  
                  gp.moveTo((float)(NW.x+crossGap), (float)(NW.y+crossGap));
                  gp.lineTo((float)(SE.x-crossGap), (float)(SE.y-crossGap));
                  gp.moveTo((float)(SE.x-crossGap), (float)(NW.y+crossGap));
                  gp.lineTo((float)(NW.x+crossGap), (float)(SE.y-crossGap));
                  
                  BasicStroke wideline = new BasicStroke((float)crossGap);
              Shape outline = wideline.createStrokedShape(gp);
              
                  return outline;
            }
            
            if(currentStyle.equals(PSTricksConstants.ASTERISK_STYLE))
            {
                  double xCenter = (NW.x+SE.x)/2., yCenter = (NW.y+SE.y)/2.;
                  double radius = Math.abs((NW.y+width/10.)-(SE.y-width/10.))/2. + dec;
                  GeneralPath gp = new GeneralPath();
                  
                  gp.moveTo((float)((NW.x+SE.x)/2.), (float)(NW.y+width/10.)-dec);
                  gp.lineTo((float)((NW.x+SE.x)/2.), (float)(SE.y-width/10.)+dec);
                  gp.moveTo((float)((Math.cos(Math.PI/6.)*radius+xCenter)), (float)(radius/2. + yCenter));
                  gp.lineTo((float)(Math.cos(7*Math.PI/6.)*radius+xCenter), (float)(Math.sin(7*Math.PI/6.)*radius+yCenter));
                  gp.moveTo((float)(Math.cos(5*Math.PI/6.)*radius+xCenter), (float)(Math.sin(5*Math.PI/6.)*radius+yCenter));
                  gp.lineTo((float)(Math.cos(11*Math.PI/6.)*radius+xCenter), (float)(Math.sin(11*Math.PI/6.)*radius+yCenter));
                  
                  BasicStroke wideline = new BasicStroke(dec);
              Shape outline = wideline.createStrokedShape(gp);
              
                  return outline;
            }
            
            return null;
      }

      
      
      
      /**
       * @return The rotated shape of the dot but the stroke is not taken in account.
       * @since 1.9.1
       */
00950       public synchronized Shape createUnstrokedShape2D()
      {
            Shape area = createNonRotatedUnstrokedShape2D();

            if((rotationAngle % (2*PI)) != 0)
            {
                  LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
                  double cx = (NW.x+SE.x)/2., cy = (NW.y+SE.y)/2.;
                  double c2x = cos(rotationAngle)*cx - sin(rotationAngle)*cy;
                  double c2y = sin(rotationAngle)*cx + cos(rotationAngle)*cy;
                  AffineTransform at = AffineTransform.getTranslateInstance(cx - c2x, cy - c2y);
                  at.rotate(rotationAngle);
                  area = at.createTransformedShape(area);
            }

            return area;
      }
      

      
      /**
       * @return The shape of the dot but the stroke is not taken in account.
       * @since 1.9.1
       */
00974       public Shape createNonRotatedUnstrokedShape2D() 
      {
            LaTeXDrawPoint2D NW = new LaTeXDrawPoint2D(center.x-width/2., center.y-width/2.);
            LaTeXDrawPoint2D SE = new LaTeXDrawPoint2D(center.x+width/2., center.y+width/2.);
            float dec = width/THICKNESS_o_STYLE_FACTOR;
            
            if(currentStyle.equals(PSTricksConstants.DOT_STYLE) ||
                  currentStyle.equals(PSTricksConstants.O_STYLE) || 
                  currentStyle.equals(PSTricksConstants.OPLUS_STYLE) ||
                  currentStyle.equals(PSTricksConstants.OTIMES_STYLE))
                  return new Ellipse2D.Double(NW.x, NW.y, width, width);
            
            if(currentStyle.equals(PSTricksConstants.BAR_STYLE))
              return new Line2D.Double((NW.x+SE.x)/2.,NW.y+barThickness/2.,(NW.x+SE.x)/2., SE.y + barGap);

            if(currentStyle.equals(PSTricksConstants.PLUS_STYLE))
            {
                  GeneralPath gp = new GeneralPath();
                  
                  gp.moveTo((float)((NW.x+SE.x)/2.), (float)(NW.y-plusGap));
                  gp.lineTo((float)((NW.x+SE.x)/2.), (float)(SE.y+plusGap));
                  gp.moveTo((float)(NW.x-plusGap), (float)((NW.y+SE.y)/2.));
                  gp.lineTo((float)(SE.x+plusGap), (float)((NW.y+SE.y)/2.));
              
                  return gp;
            }
            
            if(currentStyle.equals(PSTricksConstants.SQUARE_STYLE) || 
                  currentStyle.equals(PSTricksConstants.FSQUARE_STYLE))
                  return new Rectangle2D.Double(NW.x+dec, NW.y+dec, Math.abs(NW.x-SE.x)-2*dec, Math.abs(NW.y - SE.y)-2*dec);
            
            if(currentStyle.equals(PSTricksConstants.TRIANGLE_STYLE) || 
                  currentStyle.equals(PSTricksConstants.FTRIANGLE_STYLE))
                  return createTriangle();
            
            if(currentStyle.equals(PSTricksConstants.DIAMOND_STYLE) || 
                  currentStyle.equals(PSTricksConstants.FDIAMOND_STYLE))
                  return createDiamond();
            
            if(currentStyle.equals(PSTricksConstants.PENTAGON_STYLE) || 
                  currentStyle.equals(PSTricksConstants.FPENTAGON_STYLE))
                  return createPentagon();
            
            if(currentStyle.equals(PSTricksConstants.X_STYLE))
            {
                  GeneralPath gp = new GeneralPath();
                  
                  gp.moveTo((float)(NW.x+crossGap), (float)(NW.y+crossGap));
                  gp.lineTo((float)(SE.x-crossGap), (float)(SE.y-crossGap));
                  gp.moveTo((float)(SE.x-crossGap), (float)(NW.y+crossGap));
                  gp.lineTo((float)(NW.x+crossGap), (float)(SE.y-crossGap));
              
                  return gp;
            }
            
            if(currentStyle.equals(PSTricksConstants.ASTERISK_STYLE))
            {
                  double xCenter = (NW.x+SE.x)/2., yCenter = (NW.y+SE.y)/2.;
                  double radius = Math.abs((NW.y+width/10.)-(SE.y-width/10.))/2. + dec;
                  GeneralPath gp = new GeneralPath();
                  
                  gp.moveTo((float)((NW.x+SE.x)/2.), (float)(NW.y+width/10.)-dec);
                  gp.lineTo((float)((NW.x+SE.x)/2.), (float)(SE.y-width/10.)+dec);
                  gp.moveTo((float)((Math.cos(Math.PI/6.)*radius+xCenter)), (float)(radius/2. + yCenter));
                  gp.lineTo((float)(Math.cos(7*Math.PI/6.)*radius+xCenter), (float)(Math.sin(7*Math.PI/6.)*radius+yCenter));
                  gp.moveTo((float)(Math.cos(5*Math.PI/6.)*radius+xCenter), (float)(Math.sin(5*Math.PI/6.)*radius+yCenter));
                  gp.lineTo((float)(Math.cos(11*Math.PI/6.)*radius+xCenter), (float)(Math.sin(11*Math.PI/6.)*radius+yCenter));
              
                  return gp;
            }
            
            return null;
      }
      
      


      @Override
01052       public void rescaleX(double formerX, double newX, double percent, LaTeXDrawRectangle bound) 
      {
            if(percent==1.) return ;

            LaTeXDrawPoint2D NW = bound.getTheNWPoint(), SE = bound.getTheSEPoint(),farest;

            if(Math.abs(newX-SE.x)<Math.abs(newX-NW.x))
                    farest = NW;
            else  farest = SE;

            // We rescale the centre
            center.x = farest.x+(center.x-farest.x)*percent;

            updateDelimitor();
            updateShape();
            updateBorders();
            updateGravityCenter();
      }




      @Override
01075       public void rescaleY(double formerY, double newY, double percent, LaTeXDrawRectangle bound) 
      {
            if(percent==1.) return ;

            LaTeXDrawPoint2D NW = bound.getTheNWPoint(), SE = bound.getTheSEPoint(),farest;

            if(Math.abs(newY-SE.y)<Math.abs(newY-NW.y))
                    farest = NW;
            else  farest = SE;

            // We rescale the centre
            center.y = farest.y+(center.y-farest.y)*percent;

            updateDelimitor();
            updateShape();
            updateBorders();
            updateGravityCenter();
      }
      
      
      
      
      private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException
      {
            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();
            
            barGap = ois.readDouble();
            barThickness = ois.readDouble();
            crossGap = ois.readDouble();
            plusGap = ois.readDouble();
            blackDashLength = ois.readFloat();
            dotSep = ois.readFloat();
            whiteDashLength = ois.readFloat();
            width = ois.readFloat();
            center = (LaTeXDrawPoint2D) ois.readObject();
            currentStyle = (String) ois.readObject();
            
            d = new Delimitor();
            updateDelimitor();
            updateShape();
            gravityCenter = new LaTeXDrawPoint2D();
            borders = new LaTeXDrawRectangle(false);
            updateGap();
            updateStyleOfDelimitors();
            updateShape();
            updateBorders();
            updateGravityCenter();
            updateCanBeFilled();
      }



      @Override
01135       public void updateShape()
      {
            shape = createShape2D();
      }



      

      @Override
01145       public boolean isTooSmallToBeRescaled()
      {
            return false;
      }




      @Override
01154       public void mirrorHorizontal(LaTeXDrawPoint2D origin)
      {
            LaTeXDrawPoint2D tmp = (LaTeXDrawPoint2D)borders.gravityCenter.horizontalSymmetry(origin);
            shift(borders.gravityCenter, tmp);
            rotationAngle=2*Math.PI-rotationAngle;
            updateBorders();
            updateShape();
            updateDelimitor();
            updateGravityCenter();
      }




      @Override
01169       public void mirrorVertical(LaTeXDrawPoint2D origin)
      {
            LaTeXDrawPoint2D tmp = (LaTeXDrawPoint2D)borders.gravityCenter.verticalSymmetry(origin);
            shift(borders.gravityCenter, tmp);
            setRotationAngle(2*Math.PI-rotationAngle);
            updateBorders();
            updateShape();
            updateDelimitor();
            updateGravityCenter();
      }




      @Override
01184       public synchronized LaTeXDrawPoint2D getLastPoint()
      {
            return null;
      }




      @Override
01193       public void updateToGrid(MagneticGrid grid)
      {
            center.setLocation(grid.getTransformedPointToGrid(center, false));
            updateDelimitor();
            updateBorders();
            updateShape();
            updateGravityCenter();
      }




      @Override
01206       public int getSelectedDelimitorOrientation()
      {
            int del = super.getSelectedDelimitorOrientation();
            
            if(del!=DELIMITOR_ORIENTATION_NONE)
                  return del;
            
            return DELIMITOR_ORIENTATION_NE;
      }



      /**
       * Set the centre. Warning: change the pointer, the former is replace by the newer,
       * the method {@link Point#setLocation(double, double)} is not used.
       * @param centre
       * @exception IllegalArgumentException If centre is null.
       * @since 1.9
       * @see #setCenter(double, double)
       */
01226       public synchronized void setCenter(LaTeXDrawPoint2D centre)
      {
            if(centre==null)
                  throw new IllegalArgumentException();
            
            this.center = centre;
            updateDelimitor();
            updateBorders();
            updateShape();
            updateGravityCenter();
      }
      
      
      
      /**
       * Set the centre.
       * @param x The new X-coordinate
       * @param y The new Y-coordinate
       * @since 1.9
       */
01246       public synchronized void setCenter(double x, double y)
      {
            center.setLocation(x, y);
            updateDelimitor();
            updateBorders();
            updateShape();
            updateGravityCenter();
      }
      
      
      @Override
      public int hashCode()
      {
            return super.hashCode()^(int)width;
      }
      
      
      
      /**
       * Define if the dot can be filled or not (depends of its current shape).
       * @since 1.9
       */
01268       public void updateCanBeFilled()
      {
            String current = getCurrentStyle();
            
            canBeFilled = current.equals(PSTricksConstants.DIAMOND_STYLE) ||
                                    current.equals(PSTricksConstants.PENTAGON_STYLE) ||
                                    current.equals(PSTricksConstants.SQUARE_STYLE) ||
                                    current.equals(PSTricksConstants.TRIANGLE_STYLE) ||
                                    currentStyle.equals(PSTricksConstants.O_STYLE);
            
            isFilled = canBeFilled || current.equals(PSTricksConstants.FDIAMOND_STYLE) ||
                              current.equals(PSTricksConstants.FPENTAGON_STYLE) ||
                              current.equals(PSTricksConstants.FSQUARE_STYLE) ||
                              current.equals(PSTricksConstants.FTRIANGLE_STYLE);
      }
      
      
      
      
      @Override
01288       public boolean isFilled()
      {
            return canBeFilled && isFilled;
      }
      
      
      
      @Override
01296       public synchronized Shape createShape2D()
      {
            Shape area = createNonRotatedShape2D();

            if((rotationAngle % (2*PI)) != 0)
            {
                  LaTeXDrawPoint2D NW = getTheNWPoint(), SE = getTheSEPoint();
                  double cx = (NW.x+SE.x)/2., cy = (NW.y+SE.y)/2.;
                  double c2x = cos(rotationAngle)*cx - sin(rotationAngle)*cy;
                  double c2y = sin(rotationAngle)*cx + cos(rotationAngle)*cy;
                  AffineTransform at = AffineTransform.getTranslateInstance(cx - c2x, cy - c2y);
                  at.rotate(rotationAngle);
                  area = at.createTransformedShape(area);
            }

            return area;
      }
      
      
      
      
      @Override
01318       public synchronized void updateGravityCenter()
      {
            if(gravityCenter==null)
                  gravityCenter = new LaTeXDrawPoint2D();
            
            gravityCenter.setLocation(center);
      }
      
      
      
      
      @Override
01330       public void rotate(LaTeXDrawPoint2D gravityC, double angle)
      {
            if(!gravityC.equals(borders.gravityCenter))
            {// We must rotate the position of the figure
                  LaTeXDrawPoint2D rotGC = rotatePoint(borders.gravityCenter, gravityC, angle);
                  shift(borders.gravityCenter, rotGC);
                  updateGravityCenter();
            }
            
            setRotationAngle(rotationAngle+angle);
      }


      /**
       * @return the crossGap.
       * @since 2.0.0
       */
01347       public synchronized double getCrossGap()
      {
            return crossGap;
      }


      /**
       * @return the plusGap.
       * @since 2.0.0
       */
01357       public synchronized double getPlusGap()
      {
            return plusGap;
      }


      /**
       * @return the barGap.
       * @since 2.0.0
       */
01367       public synchronized double getBarGap()
      {
            return barGap;
      }


      /**
       * @return the barThickness.
       * @since 2.0.0
       */
01377       public synchronized double getBarThickness()
      {
            return barThickness;
      }
}

Generated by  Doxygen 1.6.0   Back to index