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

Line.java

package latexDraw.figures;

import java.awt.*;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Vector;

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


/** 
 * This class defines a line.<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>
 */
00039 public class Line extends LaTeXDrawPolygon implements Arrowable
{
      private static final long serialVersionUID = 1L;
      
      /** the arrowhead of the first point */
00044       private ArrowHead arrowHeadL;
      
      /** The arrow head of the second point */
00047       private ArrowHead arrowHeadR;
      
      /** The director coefficient" of the line (y=ax+b) */
00050       private double a;
      
      /** y=ax+b */
00053       private double b;

      /** The number of points in a line */
00056       public static final short LINE_NB_POINTS = 2;


      
      
      /** The constructor by default */
00062       public Line(boolean increaseMeter)
      {
            this(new LaTeXDrawPoint2D(), new LaTeXDrawPoint2D(), increaseMeter);
      }

      
      
      public Line(double a, double b, boolean increaseMeter)
      {
            super(increaseMeter);
            
            canHaveArrow = true;
            borders=null;
            this.a = a;
            this.b = b;
            bordersPosition = PSTricksConstants.BORDERS_MIDDLE;
            isBordersMovable = false;
            LaTeXDrawPoint2D pt1 = new LaTeXDrawPoint2D(0,(int) b);
            addPoint(pt1);
            LaTeXDrawPoint2D pt2s[];
            
            try
            {
                  pt2s = findPoints(pt1, 10.);
                  
                  if(pt2s==null)
                        throw new IllegalArgumentException();
                  if(pt2s.length==0)
                        throw new IllegalArgumentException();
                  
                  addPoint(pt2s[0]);            
                  arrowHeadL = new ArrowHead(pt1, this, this);
                  arrowHeadR = new ArrowHead(pt2s[0], this, this);
                  
            }
            catch(LaTeXDrawException e) { throw new IllegalArgumentException(); } 

            updateGravityCenter();
            shape = createShape2D();
      }
      

      
      /**
       * Create a line by creating a second point with :
       * @param b y = ax+ b
       * @param p1 The first point
       */
00110       public Line(double b, LaTeXDrawPoint2D p1, boolean increaseMeter)
      {
            this(p1,Double.isInfinite(b) || Double.isNaN(b) ? new LaTeXDrawPoint2D(p1.x,p1.y-10) : 
                  new LaTeXDrawPoint2D(0,b),increaseMeter);
      }
      
      
      
      
      /**
       * Constructs a line with a line2D
       */
00122       public Line(Line2D.Double l, boolean increaseMeter)
      {
            this(new LaTeXDrawPoint2D(l.x1, l.y1), new LaTeXDrawPoint2D(l.x2, l.y2), increaseMeter);
      }
      
      
      
      
      /** 
       * The constructor using two points to create the line.
       * 
       */
00134       public Line(double x1, double y1, double x2, double y2, boolean increaseMeter)
      {
            this(new LaTeXDrawPoint2D(x1, y1), new LaTeXDrawPoint2D(x2, y2), increaseMeter);
      }
      
      
      
      
      /** 
       * The constructor using two points in order to create the line 
       * @param p1 The first point of the line
       * @param p2 The second point of the line
       */
00147       public Line(LaTeXDrawPoint2D p1, LaTeXDrawPoint2D p2, boolean increaseMeter)
      {
            super(increaseMeter);

            canHaveArrow = true;
            isBordersMovable = false;
            bordersPosition = PSTricksConstants.BORDERS_MIDDLE;
            borders=null;
            addPoint(p1);
            addPoint(p2);

            updateGravityCenter();
      
            updateAandB();
            
            arrowHeadL = new ArrowHead(p1, this, this);
            arrowHeadR = new ArrowHead(p2, this, this);

            canBeFilled = false;
            shape = createShape2D();
      }
      
      
      
      /**
       * @return Creates a Line2D.Double shape from the Line.
       * @since 2.0.0
       */
00175       public Line2D toLine2D()
      {
            return new Line2D.Double(getPt1().x, getPt1().y, getPt2().x, getPt2().y);
      }



      /**
       * Allows to update the y-intercept b and slope a
       */
00185       public void updateAandB()
      {
            LaTeXDrawPoint2D pt1 = getPoint(0);
            LaTeXDrawPoint2D pt2 = getPoint(1);
            
            a = (pt1.y - pt2.y)/(pt1.x - pt2.x);
            b = (pt1.y - a * pt1.x);
            updateGravityCenter();
      }
      
      
      
      
      
      @Override
00200       public void shift(double shiftX, double shiftY)
      {
            if(shiftX==0 && shiftY==0) return ;
            
            super.shift(shiftX, shiftY);

            updateAandB();
            shape = createShape2D();
      }
      
      
      
      
      @Override
00214       public void draw(Graphics2D g, Object antiAlias, Object rendering, Object alphaInter, Object colorRendering)
      {
            LaTeXDrawPoint2D pt1 = getPoint(0);
            LaTeXDrawPoint2D pt2 = getPoint(1);
            Color formerCol = g.getColor();
            g.setColor(linesColor);
            double x1, y1, x2, y2;
            double dx=0, dy=0;
            boolean arrow1Drawable = arrowHeadL.isDrawable() && arrowHeadL.getArrowStyle().compareTo(PSTricksConstants.NONEARROW_STYLE)!=0;
            boolean arrow2Drawable = arrowHeadR.isDrawable() && arrowHeadR.getArrowStyle().compareTo(PSTricksConstants.NONEARROW_STYLE)!=0;
            updateAandB();
            
            if(arrow1Drawable)
            {
                  double lineAngle = Math.atan(getA());
                  double xRot,yRot;
                  Point2D.Double pos = arrowHeadL.getPosition()==pt1 ? pt1 : pt2;
                  double lgth = arrowHeadL.getArrowHeadLength();
      
                  if(Math.abs(lineAngle)==(Math.PI/2.))
                  {
                        y1 = pt1.y<pt2.y ? pos.y+lgth : pos.y-lgth;
                        x1 = pos.x;
                  }
                  else
                  {
                        xRot = Math.cos(-lineAngle)*pos.x-Math.sin(-lineAngle)*(pos.y-b); 
                        yRot = Math.sin(-lineAngle)*pos.x+Math.cos(-lineAngle)*(pos.y-b)+b;
                        if(pt1.x<pt2.x) xRot+=lgth;
                        else xRot-=lgth;
                        x1 = Math.cos(lineAngle)*xRot-Math.sin(lineAngle)*(yRot-b);
                        y1 = Math.sin(lineAngle)*xRot+Math.cos(lineAngle)*(yRot-b)+b;     
                  }     
            }
            else
            {
                  x1 = pt1.x;
                  y1 = pt1.y;
            }
            
            
            if(arrow2Drawable)
            {
                  double lineAngle = Math.atan(getA());
                  double xRot,yRot;
                  Point2D.Double pos = arrowHeadR.getPosition()==pt1 ? pt1 : pt2;
                  double lgth = arrowHeadR.getArrowHeadLength();
                  
                  if(Math.abs(lineAngle)==(Math.PI/2.))
                  {
                        y2 = pt2.y<pt1.y ? pos.y+lgth : pos.y-lgth;                       
                        x2 = pos.x;
                  }
                  else
                  {
                        xRot = Math.cos(-lineAngle)*pos.x-Math.sin(-lineAngle)*(pos.y-b); 
                        yRot = Math.sin(-lineAngle)*pos.x+Math.cos(-lineAngle)*(pos.y-b)+b;
                        if(pt2.x<=pt1.x) xRot+=lgth;
                        else xRot-=lgth;
                        x2 = Math.cos(lineAngle)*xRot-Math.sin(lineAngle)*(yRot-b);
                        y2 = Math.sin(lineAngle)*xRot+Math.cos(lineAngle)*(yRot-b)+b;     
                  }     
            }
            else
            {
                  x2 = pt2.x;
                  y2 = pt2.y;
            }
            
            if(lineStyle.equals(PSTricksConstants.LINE_DOTTED_STYLE))
            {
                  double lineAngle = Math.atan(getA());
                  double xRot,yRot;
                  
                  if(Math.abs(lineAngle)==(Math.PI/2.))
                        y1 = pt2.y>pt1.y ? y1+thickness/2. : y1-thickness/2.;                   
                  else
                  {
                        xRot = Math.cos(-lineAngle)*x1-Math.sin(-lineAngle)*(y1-b); 
                        yRot = Math.sin(-lineAngle)*x1+Math.cos(-lineAngle)*(y1-b)+b;
                        if(pt2.x>pt1.x) xRot+=thickness/2.;
                        else xRot-=thickness/2.;
                        x1 = Math.cos(lineAngle)*xRot-Math.sin(lineAngle)*(yRot-b);
                        y1 = Math.sin(lineAngle)*xRot+Math.cos(lineAngle)*(yRot-b)+b;     
                  }     
            }
            
            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(((float)x1)==((float)x2) && ((float)y1)==((float)y2))
                  x2--;
            
            Line2D.Double l = new Line2D.Double(x1, y1, x2, y2);
            
            if(hasDoubleBoundary)
            {
                  if(lineStyle.equals(PSTricksConstants.LINE_NONE_STYLE))
                  {
                        Shape s[] = getDbleBoundariesOutInOrMiddle(l);
                        
                        if(hasShadow)
                        {
                              g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                              g.translate(dx, dy);
                              g.setColor(shadowColor);
                              g.draw(s[0]);
                              g.draw(s[1]);
                              Line2D l1 = (Line2D)s[0], l2 = (Line2D)s[1];
                              int[] xs = {(int)l1.getX1(), (int)l1.getX2(), (int)l2.getX2(), (int)l2.getX1()};
                              int[] ys = {(int)l1.getY1(), (int)l1.getY2(), (int)l2.getY2(), (int)l2.getY1()};
                              Polygon p = new Polygon(xs, ys, 4);
                              g.fill(p);
                              g.draw(p);
                              
                              if(arrow1Drawable)
                              {
                                    Stroke stroke = g.getStroke();
                                    Color old  = linesColor;
                                    linesColor = shadowColor;
                                    g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                                    arrowHeadL.draw(g, interiorColor, true);
                                    linesColor = old;
                                    g.setStroke(stroke);
                              }
                              
                              if(arrow2Drawable)
                              {
                                    Stroke stroke = g.getStroke();
                                    Color old  = linesColor;
                                    linesColor = shadowColor;
                                    g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                                    arrowHeadR.draw(g, interiorColor, true);
                                    linesColor = old;
                                    g.setStroke(stroke);
                              }
                              g.translate(-dx, -dy);
                        }
                        g.setColor(doubleColor);
                        g.setStroke(new BasicStroke((float)(doubleSep + thickness), BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                        g.draw(l);
                        g.setColor(linesColor);
                        g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                        g.draw(s[0]);
                        g.draw(s[1]);
                  }
                  else
                  {
                        if(hasShadow)
                        {
                              Stroke stroke = g.getStroke();
                              Shape s[] = getDbleBoundariesOutInOrMiddle(l);
                              g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                              g.translate(dx, dy);
                              g.setColor(shadowColor);
                              g.draw(s[0]);
                              g.draw(s[1]);
                              Line2D l1 = (Line2D)s[0], l2 = (Line2D)s[1];
                              int[] xs = {(int)l1.getX1(), (int)l1.getX2(), (int)l2.getX2(), (int)l2.getX1()};
                              int[] ys = {(int)l1.getY1(), (int)l1.getY2(), (int)l2.getY2(), (int)l2.getY1()};
                              Polygon p = new Polygon(xs, ys, 4);
                              g.fill(p);
                              g.draw(p);
                              
                              if(arrow1Drawable)
                              {
                                    Stroke stroke2 = g.getStroke();
                                    Color old  = linesColor;
                                    linesColor = shadowColor;
                                    g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                                    arrowHeadL.draw(g, interiorColor, true);
                                    linesColor = old;
                                    g.setStroke(stroke2);
                              }
                              
                              if(arrow2Drawable)
                              {
                                    Stroke stroke2 = g.getStroke();
                                    Color old  = linesColor;
                                    linesColor = shadowColor;
                                    g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                                    arrowHeadR.draw(g, interiorColor, true);
                                    linesColor = old;
                                    g.setStroke(stroke2);
                              }
                              g.translate(-dx, -dy);
                              g.setStroke(stroke);
                        }
                        
                        if(lineStyle.equals(PSTricksConstants.LINE_DOTTED_STYLE))
                              g.setStroke(new BasicStroke((float)(thickness*2+doubleSep), BasicStroke.CAP_ROUND,
                                          BasicStroke.JOIN_MITER,1.f,new float[]{0,(float)(thickness*2+doubleSep+dotSep)},0));
                        else
                              g.setStroke(new BasicStroke((float)(thickness*2+doubleSep),
                                                BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.f,
                                                new float[] { blackDashLength, whiteDashLength }, 0));
                              
                        g.setColor(linesColor);
                        g.draw(l);
                        g.setStroke(new BasicStroke((float)doubleSep, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                        g.setColor(doubleColor);
                        g.draw(l);
                  }     
            }
            else
            {
                  if(hasShadow)
                  {
                        g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
                        g.translate(dx, dy);
                        g.setColor(shadowColor);
                        g.draw(l);
                        
                        if(arrow1Drawable)
                        {
                              Color old  = linesColor;
                              linesColor = shadowColor;
                              arrowHeadL.draw(g, interiorColor, true);
                              linesColor = old;
                        }
                        
                        if(arrow1Drawable)
                        {
                              Color old  = linesColor;
                              linesColor = shadowColor;
                              arrowHeadR.draw(g, interiorColor, true);
                              linesColor = old;
                        }
                        g.translate(-dx, -dy);
                  }
                  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
                              g.setStroke(new BasicStroke(thickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.f,
                                                                        new float[] { blackDashLength, whiteDashLength }, 0));
                  
                  g.setColor(linesColor);
                  g.draw(l);
            }

            g.setStroke(new BasicStroke(hasDoubleBoundary() ? thickness*2f+(float)getDoubleSep() : thickness, 
                              BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
            
            if(arrow1Drawable)
                  arrowHeadL.draw(g, interiorColor, false);
            
            if(arrow2Drawable)
                  arrowHeadR.draw(g, interiorColor, false);
            
            g.setColor(formerCol);
            
            if(isSelected && delimiters.size()==2)
            {
                  delimiters.elementAt(0).draw(g);
                  delimiters.elementAt(1).draw(g);
            }
      }

      
      
      @Override
00486       public void setIsFilled(boolean filled)
      {
            /* A line cannot be filled. */
      }
            
      
      
      /**
       * Allows to set the style of the left arrow of the line
       * @param style The new style of the left arrow of the line
       */
00497       public synchronized void setArrow1Style(String style)
      {
            arrowHeadL.setArrowStyle(style);                
      }
      
      
      

      /**
       * Allows to set the style of the right arrow of the line
       * @param style The new style of the right arrow of the line
       */
00509       public synchronized void setArrow2Style(String style)
      {
            arrowHeadR.setArrowStyle(style);
      }
      
      
      
      
      @Override
00518       public synchronized void setLastPoint(LaTeXDrawPoint2D pt)
      {
            LaTeXDrawPoint2D pt1 = getPoint(0);
            LaTeXDrawPoint2D pt2 = getPoint(1);

            if(pt1.x!=pt.x || pt1.y!=pt.y)
            {
                  pt2.x = pt.x;
                  pt2.y = pt.y;                 
                  updateAandB();
                  shape = createShape2D();
            }
      }

      
      @Override
00534       public synchronized void setFirstPoint(LaTeXDrawPoint2D pt)
      {
            LaTeXDrawPoint2D pt1 = getPoint(0);
            LaTeXDrawPoint2D pt2 = getPoint(1);

            if(pt2.x!=pt.x || pt2.y!=pt.y)
            {
                  pt1.x = pt.x;
                  pt1.y = pt.y;                 
                  updateAandB();
                  shape = createShape2D();
            }
      }
      
      
      
      @Override
00551       public synchronized void setRotationAngle(double theta)
      {
            super.setRotationAngle(theta);
            updateAandB();
            shape = createShape2D();
      }
      
      
      
      
      
      @Override
00563       public synchronized void setThickness(float val) 
      {
            super.setThickness(val);
            
            if(!Double.isInfinite(val) && !Double.isNaN(val) && val>0)
            {
                  double dim = 1.33*val+3.33 +1;
                  if(dim<6.) 
                        dim = 6;
            
                  Delimitor d1 = delimiters.elementAt(0);
                  Delimitor d2 = delimiters.elementAt(1);
                  if(d1!=null) d1.setDim(dim);
                  if(d2!=null) d2.setDim(dim);
                  shape = createShape2D();
            }
      }
      
      
      
      
      
      @Override
00586       public LaTeXDrawPoint2D getTheNWPoint()
      {
            LaTeXDrawPoint2D pt1 = getPoint(0);
            LaTeXDrawPoint2D pt2 = getPoint(1);
            
            return new LaTeXDrawPoint2D(pt1.x<pt2.x ? pt1.x : pt2.x, pt1.y<pt2.y ? pt1.y : pt2.y);
      }

      
      
      
      
      @Override
00599       public LaTeXDrawPoint2D getTheNWRotatedPoint()
      {// For a line, there is no difference between the line and the rotated
            // line because at a change of the rotation angle, we really
            // rotate the points of the line, whereas for other figure, we create
            // a rotated figure at each display.
            return getTheNWPoint();
      }
      
      
      
      
      @Override
00611       public LaTeXDrawPoint2D getTheSERotatedPoint()
      {
//           For a line, there is no difference between the line and the rotated
            // line because at a change of the rotation angle, we really
            // rotate the points of the line, whereas for other figure, we create
            // a rotated figure at each display.
            return getTheSEPoint();
      }
      
      
      
      
      @Override
00624       public LaTeXDrawPoint2D getTheSEPoint()
      {
            LaTeXDrawPoint2D pt1 = getPoint(0);
            LaTeXDrawPoint2D pt2 = getPoint(1);
            
            return new LaTeXDrawPoint2D(pt1.x<pt2.x ? pt2.x : pt1.x, pt1.y<pt2.y ? pt2.y : pt1.y);
      }
      
      
      
      
      /**
       * Allows to get the style of the left arrow of the line
       * @return The style of the left arrow of the line
       */
00639       public synchronized String getArrow1Style() 
      {
            return arrowHeadL.getArrowStyle();
      }
      

      
      
      
      /**
       * Allows to get the style of the right arrow of the line
       * @return The style of the left arrow of the line
       */
00652       public synchronized String getArrow2Style()
      {
            return arrowHeadR.getArrowStyle();
      }
      
      
      
      
      
      @Override
00662       public boolean isIn(LaTeXDrawPoint2D pt) 
      {                 
            updateAandB();
            LaTeXDrawPoint2D pt1 = getPoint(0);
            LaTeXDrawPoint2D pt2 = getPoint(1);
            Delimitor d1 = delimiters.elementAt(0);
            Delimitor d2 = delimiters.elementAt(1);
            
            if(d1!=null && d2!=null)            
                  if(d1.isIn(pt)|| d2.isIn(pt))
                        return true;
            
            float dec;
            boolean in = true;
            
            if(hasDoubleBoundary)
                  dec = (float)(thickness+doubleSep/2.);
            else
                  dec = (float)(thickness/2.);

            if(pt1.y<pt2.y)
            {
                  if(pt.y<pt1.y-dec || pt.y>pt2.y+dec)
                        in = false; 
            }
            else
                  if(pt.y>pt1.y+dec || pt.y<pt2.y-dec)
                        in = false; 
            
            if(pt1.x<pt2.x)
            {
                  if(pt.x<pt1.x-dec || pt.x>pt2.x+dec)
                        in = false; 
            }
            else
                  if(pt.x>pt1.x+dec || pt.x<pt2.x-dec)
                        in = false; 

            // In the case : x = alpha (unable to compute a)
            if(in && pt1.x>=pt2.x-dec && pt1.x<=pt2.x+dec)
                  return true;
                  
                  
            // Calculate the equation of the line (y = ax + b)
            double axb = a*pt.x+b;

            if(in && a==0) // If the equation is y = alpha
            {
                  if(pt1.x<pt2.x)
                        in = pt.x>=pt1.x-dec && pt.x<=pt2.x+dec;
                  else
                        in = pt.x>=pt2.x-dec && pt.x<=pt1.x+dec;
            }
            
            if(in)
                  in = pt.y>=axb-dec && pt.y<=axb+dec;
            
            return in;
      } 

      
      
      
      @Override
00726       public synchronized String getCodePSTricks(DrawBorders drawBorders, float ppc)
      {
            LaTeXDrawPoint2D d = drawBorders.getOriginPoint();
            LaTeXDrawPoint2D pt1 = getPoint(0);
            LaTeXDrawPoint2D pt2 = getPoint(1);
            double x1 = pt1.x - d.x, x2 = pt2.x - d.x, y1 = d.y - pt1.y, 
                  y2 = d.y - pt2.y;
            String add ="", arrowsCode=""; //$NON-NLS-1$ //$NON-NLS-2$
            double threshold = 0.001;
            
            if(!linesColor.equals(PSTricksConstants.DEFAULT_LINE_COLOR))
            {
                  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(hasShadow)
            {
                  add+=",shadow=true";//$NON-NLS-1$
                  if(Math.toDegrees(shadowAngle)!=PSTricksConstants.DEFAULT_SHADOW_ANGLE)
                        add+=",shadowangle="+(float)Math.toDegrees(shadowAngle);//$NON-NLS-1$
                  
                  if(((float)shadowSize)!=((float)DEFAULT_SHADOW_SIZE))
                        add+=",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(!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(lineStyle.equals(PSTricksConstants.LINE_DOTTED_STYLE))
                  add += ",linestyle="+lineStyle+",dotsep="+ //$NON-NLS-1$ //$NON-NLS-2$
                  (dotSep/ppc)+ "cm";      //$NON-NLS-1$
            else
            if(lineStyle.equals(PSTricksConstants.LINE_DASHED_STYLE))
                  add += ",linestyle="+lineStyle+",dash=" +  //$NON-NLS-1$ //$NON-NLS-2$
                  (blackDashLength/ppc) + "cm "+  //$NON-NLS-1$
                  (whiteDashLength/ppc) + "cm"; //$NON-NLS-1$
            
            String currentArrowLStyle = arrowHeadL.getArrowStyle();
            String currentArrowRStyle = arrowHeadR.getArrowStyle();           
            String paramsR = ","+ arrowHeadR.getParametersCode(); //$NON-NLS-1$
            String paramsL = ","+ arrowHeadL.getParametersCode(); //$NON-NLS-1$
            if(paramsR.equals(",")) paramsR = ""; //$NON-NLS-1$ //$NON-NLS-2$
            if(paramsL.equals(",")) paramsL = ""; //$NON-NLS-1$ //$NON-NLS-2$
            
            if(!currentArrowLStyle.equals(PSTricksConstants.NONEARROW_STYLE))
            {
                  arrowsCode="{"+currentArrowLStyle+'-'; //$NON-NLS-1$
                  
                  if(!currentArrowRStyle.equals(PSTricksConstants.NONEARROW_STYLE))
                        arrowsCode+=currentArrowRStyle;
                  arrowsCode+='}';
                  
                  if(!arrowHeadL.isOfTheSameTypeAs(arrowHeadR))
                  {
                        if((currentArrowRStyle.equals(PSTricksConstants.LRBRACKET_STYLE) ||
                              currentArrowRStyle.equals(PSTricksConstants.RRBRACKET_STYLE)  ||
                              currentArrowRStyle.equals(PSTricksConstants.RSBRACKET_STYLE)  ||
                              currentArrowRStyle.equals(PSTricksConstants.RSBRACKET_STYLE))     &&
                              (currentArrowLStyle.equals(PSTricksConstants.BAREND_STYLE) ||
                              currentArrowLStyle.equals(PSTricksConstants.BARIN_STYLE) ||
                              currentArrowLStyle.equals(PSTricksConstants.LRBRACKET_STYLE) ||
                              currentArrowLStyle.equals(PSTricksConstants.RRBRACKET_STYLE)  ||
                              currentArrowLStyle.equals(PSTricksConstants.RSBRACKET_STYLE)  ||
                              currentArrowLStyle.equals(PSTricksConstants.RSBRACKET_STYLE)))
                              add = paramsR;
                        else
                              add+= paramsL + paramsR;
                  }else add+=paramsR;
            }
            else 
                  if(!currentArrowRStyle.equals(PSTricksConstants.NONEARROW_STYLE))
                  {
                        add+=paramsR;
                        arrowsCode="{-"+currentArrowRStyle+'}'; //$NON-NLS-1$
                  }
            
            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$
                  }
            }
            
            return "\\psline[linewidth=" + (thickness/ppc)+"cm"   //$NON-NLS-1$ //$NON-NLS-2$
                  + add + "]"+ arrowsCode + "(" + LaTeXDrawNumber.getCutNumber((float)(x1/ppc), threshold) + ","  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
                  + LaTeXDrawNumber.getCutNumber((float)(y1/ppc), threshold)  + ")(" //$NON-NLS-1$
                  + LaTeXDrawNumber.getCutNumber((float)(x2/ppc), threshold) + ","  //$NON-NLS-1$
                  + LaTeXDrawNumber.getCutNumber((float)(y2/ppc), threshold) + ")"; //$NON-NLS-1$
      }


      
      
      
      /**
       * Allows to get the X-coordinate thanks to the equation of the
       * line and the Y-coordinate of the point
       * @param y The Y-coordinate of the point
       * @return The X-coordinate of the point
       */
00860       public double getXWithEquation(double y)
      {
            updateAandB();
            return (y-b)/a;
      }
      
      
      
      
      
      
      /**
       * Allows to get the Y-coordinate thanks to the equation of the
       * line and the X-coordinate of the point
       * @param x The X-coordinate of the point
       * @return The Y-coordinate of the point
       */
00877       public double getYWithEquation(double x)
      {
            updateAandB();
            return a*x+b;
      }
      
      
      
      /**
       * Allows to get the points which are on the line and at the distance
       * "distance" of the point "p" of the line.
       * @param p The point of reference
       * @param distance The distance between p and the points we must find
       * @return The points found
       * @throws LaTeXDrawException
       */
00893       public LaTeXDrawPoint2D[] findPoints(Point p, double distance) throws LaTeXDrawException
      {     
            return findPoints(p.x, p.y, distance);
      }
      
      
      
      
      /**
       * Allows to get the points which are on the line and at the distance
       * "distance" of the point "p" of the line.
       * @param p The point of reference
       * @param distance The distance between p and the points we must find
       * @return The points found
       * @throws LaTeXDrawException
       */
00909       public LaTeXDrawPoint2D[] findPoints(LaTeXDrawPoint2D p, double distance) throws LaTeXDrawException
      {     
            return findPoints(p.x, p.y, distance);
      }
      
      
      
      
      /**
       * Allows to get the points which are on the line and at the distance
       * "distance" of the point "p" of the line.
       * @param x The x-coordinate of the point of reference
       * @param y The y-coordinate of the point of reference
       * @param distance The distance between p and the points we must find
       * @return The found points
       * @throws LaTeXDrawException
       */
00926       public LaTeXDrawPoint2D[] findPoints(double x, double y, double distance) throws LaTeXDrawException
      {
            if(distance==0)
            {
                  LaTeXDrawPoint2D[] sol = new LaTeXDrawPoint2D[1];
                  sol[0] = new LaTeXDrawPoint2D(x,y);
                  return sol;
            }
            
            updateAandB();
            
            if(Double.isInfinite(b) || Double.isNaN(b))
            {// A vertical line
                  LaTeXDrawPoint2D sol[] = new LaTeXDrawPoint2D[2];
                  sol[0] = new LaTeXDrawPoint2D(x, y-distance);
                  sol[1] = new LaTeXDrawPoint2D(x, y+distance);
                  
                  return sol;
            }
            
            double A = a*a+1, B = -2*(x+y*a-a*b);
            double C = b*b-(2*y*b)+y*y+x*x-(distance*distance);
            double delta = B*B-4*A*C;

            if(delta>0)
            {
                  double x1, x2, y1, y2;
                  LaTeXDrawPoint2D sol[] = new LaTeXDrawPoint2D[2];
                  x1 = (-B+Math.sqrt(delta))/(2*A);
                  x2 = (-B-Math.sqrt(delta))/(2*A);
                  y1 = a*x1+b;
                  y2 = a*x2+b;
                  sol[0] = new LaTeXDrawPoint2D(x1, y1);
                  sol[1] = new LaTeXDrawPoint2D(x2, y2);
                  return sol;
            }
            else
                  if(delta==0)
                  {
                        double x2, y2;
                        LaTeXDrawPoint2D sol[] = new LaTeXDrawPoint2D[1];
                        x2 = -B/2*A;
                        y2 = a*x2+b;
                        sol[0] = new LaTeXDrawPoint2D(x2, y2);
                        return sol;
                  }
                  else 
                        throw new LaTeXDrawException(LaTeXDrawException.INCORRECT_VALUE);
      }
      
      

      
      /**
       * Allows to create the line which is perpendicular to the current
       * line at the point pt
       * @param pt The point of crossing between the two lines
       * @return The perpendicular line
       */
00985       public Line getPerpendicularLine(LaTeXDrawPoint2D pt, boolean increaseMeter)
      {
            if(pt.x==0)
            {
                  LaTeXDrawPoint2D pt3 = getPt2();
                  LaTeXDrawPoint2D pt2 = Figure.rotatePoint(pt3, pt, Math.PI/2.);
                  return new Line(pt2, pt, increaseMeter);
            }
            double a2 = -1./a;
            return new Line(pt.y-a2*pt.x, pt, increaseMeter);
      }
      
      
      
      /**
       * Allows to translate the line following a gap t. In fact, we only
       * change the y-intersect
       * @param t The gap
       * @return A new line, result of this translation
       */
01005       public Line translate(double t, boolean increaseMeter)
      {
            return new Line(a, b+t, increaseMeter);
      }


      
      
      @Override
      public Object clone() throws CloneNotSupportedException
      {
            Line l = (Line) super.clone();
            l.borders = null;

            updateGravityCenter();
            
            l.arrowHeadL = arrowHeadL.clone(false);
            l.arrowHeadL.setPosition(l.getPoint(0));
            l.arrowHeadL.setLine(l);
            l.arrowHeadL.setFigure(l);

            l.arrowHeadR = arrowHeadR.clone(false);
            l.arrowHeadR.setPosition(l.getPoint(1));
            l.arrowHeadR.setLine(l);
            l.arrowHeadR.setFigure(l);
            
            l.canBeFilled = false;
            l.a = a;
            l.b = b;
            l.shape = l.createShape2D();
            
            return l;
      }

      
      
      
      @Override
01043       public void updateGravityCenter() 
      {
            if(pts.size()==LINE_NB_POINTS)
            {
                  LaTeXDrawPoint2D pt1 = getPoint(0);
                  LaTeXDrawPoint2D pt2 = getPoint(1);
                  gravityCenter.setLocation((pt1.x+pt2.x)/2., (pt1.y+pt2.y)/2.);
            }
      }

      
      /**
       * Allows to get the a from y=ax+b
       * @return The a
       */
01058       public double getA()
      {
            return a;
      }
      
      
      
      /**
       * Allows to get the b from y=ax+b
       * @return The b
       */
01069       public double getB()
      {
            return b;
      }
      
      
      
      
      @Override
01078       public LaTeXDrawRectangle getBorders()
      { 
            LaTeXDrawPoint2D NW = (LaTeXDrawPoint2D)getTheNWPoint().clone();
            LaTeXDrawPoint2D SE = (LaTeXDrawPoint2D)getTheSEPoint().clone();
            
            return new LaTeXDrawRectangle((LaTeXDrawPoint2D)NW.clone(), new LaTeXDrawPoint2D(SE.x,NW.y),
                        new LaTeXDrawPoint2D(NW.x,SE.y),SE, false);
      }

      
      
      
      @Deprecated
      @Override
01092       public void updateBorders(LaTeXDrawPoint2D pt)
      {     
            /* */
      }
      
      
      @Deprecated
      @Override
01100       public void updateBorders()
      {
            /* */
      }
      
      
      
      @Override
01108       public void removePointAt(int id)
      {
            if(id<0 || id>pts.size()) return ;
            
            if(pts.size()>2)
            {
                  pts.remove(id);
                  delimiters.remove(id);
                  if(id==0)
                  {
                        arrowHeadL.setPosition(getPoint(0));
                        arrowHeadR.setPosition(getPoint(1));
                        
                  }
                  else 
                        if(id==0)
                              arrowHeadR.setPosition(getPoint(1));
                        
                  updateAandB();
            }
      }
      
      
      
      

      @Override
01135       public void onDragged(Point formerPt, Point newPt) throws Exception 
      {     
            if(formerPt.equals(newPt)) return;
            
            if(isOnRotation && dSelected!=null)
            {
                  double theta = computeRotationAngle(formerPt, newPt);
                  double rotationA = rotationAngle+ theta;
                  rotationA%=(Math.PI*2);
                  setRotationAngle(rotationA);
            }
            else
            if(dSelected==null)// We dragged the figure or a delimiter of the 
                        shift(formerPt, newPt);
            else
                  dSelected.setCoordinates(newPt.x, newPt.y);                 
            
            updateGravityCenter();
            updateShape();
      }

      
      
      
      
      
      
      @Override
01163       public LaTeXDrawPoint2D getBordersPoint(int id)
      {
            LaTeXDrawPoint2D NW = getTheNWPoint();
            LaTeXDrawPoint2D SE = getTheSEPoint();
            
            if(id==-1 || id==3) return SE;
            if(id<0 || id>LaTeXDrawRectangle.NB_POINTS_FRAME-1)
                  throw new IllegalArgumentException();
            
            if(id==0) return NW;
            if(id==1) return new LaTeXDrawPoint2D(SE.x,NW.y);
            if(id==2) return new LaTeXDrawPoint2D(NW.x,SE.y);
            
            return null;
      }

      
      
      @SuppressWarnings("unchecked")
      private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException
      {
            canHaveShadow = true;
            canHaveArrow  = 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) ois.readObject();
            arrowHeadL = (ArrowHead) ois.readObject();
            arrowHeadR = (ArrowHead) ois.readObject();
            
            arrowHeadR.setArrowInset(arrowHeadL.getArrowInset());
            arrowHeadR.setArrowLength(arrowHeadL.getArrowLength());
            arrowHeadR.setArrowSizeDim(arrowHeadL.getArrowSizeDim());
            arrowHeadR.setArrowSizeNum(arrowHeadL.getArrowSizeNum());
            arrowHeadR.setBracketNum(arrowHeadL.getBracketNum());
            arrowHeadR.setDotSizeDim(arrowHeadL.getDotSizeDim());
            arrowHeadR.setDotSizeNum(arrowHeadL.getDotSizeNum());
            arrowHeadR.setRBracketNum(arrowHeadL.getRBracketNum());
            arrowHeadR.setTBarSizeDim(arrowHeadL.getTBarSizeDim());
            arrowHeadR.setTBarSizeNum(arrowHeadL.getTBarSizeNum());
            
            if(pts.size()!=LINE_NB_POINTS)
                  throw new ArrayIndexOutOfBoundsException();
            
            arrowHeadL.setPosition(pts.firstElement());
            arrowHeadR.setPosition(pts.elementAt(1));
            arrowHeadL.setFigure(this);
            arrowHeadR.setFigure(this);
            
            delimiters = new Vector();
            for(int i=0, size = pts.size();i<size; i++)
                  delimiters.add(new Delimitor(pts.elementAt(i)));
                  
            setThickness(thickness);
            updateAandB();
            updateGravityCenter();
            canBeFilled = false;
            
            if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.5")>=0)//$NON-NLS-1$
            {
                  hasDoubleBoundary = ois.readBoolean();
                  doubleColor = (Color)ois.readObject();
                  doubleSep = ois.readDouble();
            }
            else
            {
                  hasDoubleBoundary  = DEFAULT_HAS_DOUBLE_BOUNDARY;
                  doubleColor = DEFAULT_DOUBLE_COLOR;
                  doubleSep   = DEFAULT_DOUBLESEP;
            }
            
            if(LaTeXDrawFrame.getVersionOfFile().compareTo("1.7")>=0) //$NON-NLS-1$
            {
                  hasShadow   = ois.readBoolean();
                  shadowAngle = ois.readDouble();
                  shadowSize  = ois.readDouble();
                  shadowColor = (Color)ois.readObject();
            }
            else
            {
                  hasShadow   = DEFAULT_SHADOW_HAS;
                  shadowAngle = DEFAULT_SHADOW_ANGLE;
                  shadowSize  = DEFAULT_SHADOW_SIZE;
                  shadowColor = DEFAULT_SHADOW_COLOR;
            }
      }

      
      
      
      
      @Override
01263       public Shape createShape2D()
      {
            if(getNbPoints()<2)
                  return null;
            
            Shape area;
            Shape s = new Line2D.Double(getPt1(), getPt2());

            if(hasDoubleBoundary)
            {//Fixes #1557509
                  Line2D.Double[] s2 = (Line2D.Double[])getDbleBoundariesMiddle(s);
                  int[] xs = new int[4], ys = new int[5];
                  xs[0] = (int)s2[0].x1;
                  xs[1] = (int)s2[0].x2;
                  xs[2] = (int)s2[1].x1;
                  xs[3] = (int)s2[1].x2;
                  ys[0] = (int)s2[0].y1;
                  ys[1] = (int)s2[0].y2;
                  ys[2] = (int)s2[1].y1;
                  ys[3] = (int)s2[1].y2;
                  area = new Polygon(xs, ys, 4);
            }
            else
                  area = s;

            return area;
      }

      
      
      
      
      /**
       * @return Returns the arrowHead1.
       */
01298       public ArrowHead getArrowHead1()
      {
            return arrowHeadL;
      }

      
      
      /**
       * @return Returns the arrowHead2.
       */
01308       public ArrowHead getArrowHead2()
      {
            return arrowHeadR;
      }

      
      
      
      /**
       * Allows to get the intersection between two lines
       * @param l The second lines
       * @return The intersection
       */
01321       public LaTeXDrawPoint2D getIntersection(Line l)
      {
            if(l==null) return null;
            
            boolean bInf = false;
            double y;

            if(Double.isInfinite(b) || Double.isNaN(b))
                  // The equation is x = alpha;
                  bInf = true;
            
            if(Double.isInfinite(l.b) || Double.isNaN(l.b))
            {// The equation is x = alpha;
                  if(bInf)// The two lines a parallels
                        return null;
                  
                  y = a*l.getPt1().x+b;
                  return new LaTeXDrawPoint2D((y-b)/a, y);
            }
            
            if(bInf)
            {
                  y = l.a*getPt1().x+l.b;
                  return new LaTeXDrawPoint2D((y-l.b)/l.a, y);
            }
            double x = (b-l.b)/(l.a-a);

            return new LaTeXDrawPoint2D(x, a*x+b);
      }


      
      
      
      
      @Override
01357       public Shape[] getDbleBoundariesMiddle(Shape classicBord)
      {
            try
            {
                  Point2D.Double p1 = (Point2D.Double)((Line2D.Double)classicBord).getP1();
                  Point2D.Double p2 = (Point2D.Double)((Line2D.Double)classicBord).getP2();                 
                  Line l = new Line(new LaTeXDrawPoint2D(p1.x, p1.y), 
                                            new LaTeXDrawPoint2D(p2.x, p2.y), false);
                  
                  LaTeXDrawPoint2D[] pts1 = l.getPerpendicularLine(
                              (LaTeXDrawPoint2D)l.getPt1().clone(), false).findPoints(
                                                l.getPt1(), (doubleSep+thickness)/2.);
                  
                  LaTeXDrawPoint2D[] pts2 =l.getPerpendicularLine(
                              (LaTeXDrawPoint2D)l.getPt2().clone(), false).findPoints(
                                                l.getPt2(), (doubleSep+thickness)/2.);
                  
                  if(pts1.length<2 || pts2.length<2)
                        throw new IndexOutOfBoundsException();
                  
                  Shape[] s = new Line2D.Double[2];
                  s[0] = new Line2D.Double(pts1[0], pts2[0]);
                  s[1] = new Line2D.Double(pts1[1], pts2[1]);

                  return s;
                  
            }catch(Exception e)
            {
                  e.printStackTrace(); 
                  return null; 
            }
      }


      
      
      
      /** 
       * Allow to get the first point of the line
       * @return The first point of the line
       */
01398       public LaTeXDrawPoint2D getPt1() 
      { 
            return getPoint(0); 
      }
      
      
      
      
      /**
       * Allow to get the second point o the line
       * @return The second point of the line
       */
01410       public LaTeXDrawPoint2D getPt2() 
      { 
            return getPoint(1); 
      }
      
      
      
      
      
      /**
       * Allows to get the middle point of the line
       * @return The middle point of the line
       */
01423       public LaTeXDrawPoint2D getMiddlePt()
      {
            LaTeXDrawPoint2D p1 = pts.elementAt(0);
            LaTeXDrawPoint2D p2 = pts.elementAt(1);
            
            return new LaTeXDrawPoint2D((p1.x+p2.x)/2., (p1.y+p2.y)/2.);
      }
      
      
      
      
      
      
      /**
       * Allows to get the point of the intersection between of the two segments
       * @param l The second line
       * @return The intersection point
       */
01441       public LaTeXDrawPoint2D getIntersectsSegment(Line l)
      {
            if(l==null) return null;
            
            LaTeXDrawPoint2D p = getIntersection(l);
            
            if(p==null) return null;

            LaTeXDrawPoint2D NW = getTheNWPoint();
            LaTeXDrawPoint2D SE = getTheSEPoint();
            LaTeXDrawPoint2D NW2 = l.getTheNWPoint();
            LaTeXDrawPoint2D SE2 = l.getTheSEPoint();
            
            if( (p.x>NW.x && p.x<SE.x && p.y>NW.y && p.y<SE.y) &&
                  (p.x>NW2.x && p.x<SE2.x && p.y>NW2.y && p.y<SE2.y))
                  return p;
            return null;
      }
      
      
      
      @Override
01463       public boolean isTooSmallToBeRescaled()
      {
            return pts.firstElement().equals(pts.elementAt(1), 0);
      }



      @Override
      public String toString()
      {
            return getPt1()+" " +getPt2()+", a="+a+", b="+b;   //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
      }
      
      
      
      //Fixes #1557509
      @Override
01480       public void updateShape()
      {
            updateGravityCenter();
            shape = createShape2D();
      }
      
      
      
      @Override
      public int hashCode()
      {
            return super.hashCode()^arrowHeadL.getArrowStyle().hashCode();
      }



01496       public boolean hasTwoLeftArrows()
      {
            return false;
      }
}

Generated by  Doxygen 1.6.0   Back to index