Java source code of 'jhplot.jadraw.JaLine'

/*

 * Title: japlot.jaxodraw
 * Description: Graphical user interface for drawing Feynman diagrams
 * @author Daniele Binosi 
 * @author Lukas Theussl  

 Copyright (C) 2003-2006,  Daniele Binosi and Lukas Theussl

 See the file LICENSE in the source distribution home directory
 for a full copy of the GPL (GNU General Public License).

    This file is part of japlot.jaxodraw.

    japlot.jaxodraw 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.

    japlot.jaxodraw is distributed in the hope that it will be useful,
    but 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.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


 */
package jhplot.jadraw;

import japlot.jaxodraw.JaxoLineOptionsPanel;
import japlot.jaxodraw.JaxoMainPanel;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Composite;
import java.awt.Dimension;
import org.freehep.graphics2d.VectorGraphics;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

/**
 * Build a simple line
 * 
 * @author S.Chekanov
 * 
 */

public class JaLine extends JaLineObject {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private float transp;
	
	
	/**
	 * Build a line 
	 * @param x1 starting x
	 * @param y1 starting y
	 * @param x2 end of x
	 * @param y2 end of y
	 * @param what if "NDC", coordinate in NDC (from 0 to 1), if "USER" coordinates are 
     *                        in the user system given by the axes.
	 */
	public JaLine(double x1, double y1, double x2, double y2, String what) {
		super();
		setInflip(false);
		transp = 1.0f;
	        stroke=2.0f;
                setLocation(x1, y1, what);
                setRelWH(x2,y2, what);
		
      
        
		
	}

	
	
	/**
	 * Set location in pixel coordinates
	 * @param xin  x min
	 * @param yin  y min
	 * @param xfin x max
	 * @param yfin y max
	 */
        public void setLocationXY(int xin, int yin, int xfin, int yfin) {
        int relw = xfin - xin;
        int relh = yfin - yin;
        setRelWAndH(relw, relh);
        if ((relw >= 0) && (relh >= 0)) {
            setLocation(xin, yin);
        } else if ((relw >= 0) && (relh < 0)) {
            setLocation(xin, yfin);
        } else if ((relw < 0) && (relh >= 0)) {
            setLocation(xfin, yin);
        } else if ((relw < 0) && (relh < 0)) {
            setLocation(xfin, yfin);
        }
    }

	
	
	/** Constructor: calls super() and initializes inflip to false. */
	public JaLine() {
		super();
		setInflip(false);
		transp = 1.0f;
                stroke=2.0f;
	}





     /**
     * Get line width
     * @param pen width 
     */
    public float getPenWidth() {
                return stroke;
        }

    /**
     * Set line width
     * @param penwidth pen width 
     */
    public void setPenWidth(float penwidth) {
                stroke = penwidth;
        }






	
	/**
	 * Returns an exact copy of this JaFLine.
	 * 
	 * @return A copy of this JaFLine.
	 */
	public final JaObject copy() {
		JaLine temp = new JaLine();
		temp.setX(getX());
		temp.setY(getY());
		temp.setTransparency(getTransparency());
		temp.setColor(getColor());
		temp.setStroke(getStroke());
		temp.setArrow(isArrow());
		temp.setEnd(isEnd());
		temp.setFlip(isFlip());
		temp.setInflip(getInflip());
		temp.setDoubleLine(getDoubleLine());
		temp.setDLSeparation(getDLSeparation());
		temp.setSize(getWidth(), getHeight(), getRelw(), getRelh());
		temp.setBoundingBox(getBoundingBox());

		return temp;
	}

	/**
	 * Set transparency of this object
	 * 
	 * @param transp
	 *            transparency from 0 to 1
	 */
	public void setTransparency(float transp) {
		this.transp = transp;
	}

	/**
	 * Get the transparency of it
	 * 
	 * @return transparency
	 */
	public float getTransparency() {
		return transp;
	}

	/**
	 * Returns true if all serializable variables of this JaObject and those of
	 * the specified one are equal.
	 * 
	 * @param comp
	 *            A JaObject to compare with.
	 * @return True if the objects are equal, false otherwise.
	 */
	public final boolean isCopy(JaObject comp) {
		boolean isCopy = false;

		if (comp instanceof JaLine) {
			JaLine line = (JaLine) comp;
			if ((line.getX() == getX()) && (line.getY() == getY())
					&& line.getColor().equals(getColor())
					&& (line.getStroke() == getStroke())
					&& (line.isArrow() == isArrow())
					&& (line.isEnd() == isEnd()) && (line.isFlip() == isFlip())
					&& (line.getInflip() == getInflip())
					&& (line.getDoubleLine() == getDoubleLine())
					&& (line.getDLSeparation() == getDLSeparation())
					&& (line.getRelw() == getRelw())
					&& (line.getRelh() == getRelh())) {
				isCopy = true;
			}
		}

		return isCopy;

	}

	/**
	 * The method that draws this JaFLine.
	 * 
	 * @param g2
	 *            The graphics context where the JaFLine has to be drawn.
	 * @param drawToScreen
	 *            A boolean variable that indicates whether the drawing is done
	 *            on the screen or somewhere else. This is used for
	 *            exporting/printing, where the object handles should not be
	 *            painted, even if they are visible on the screen.
	 */
	public final void jaxoDraw(VectorGraphics g2, boolean drawToScreen) {
	
		
		
		g2.setColor(getColor());
		
		
        GeneralPath gptmp = new GeneralPath();
        GeneralPath gp = getGeneralPath();
        gp.reset();

        double length =
            Math.sqrt(((double) getWidth() * (double) getWidth())
                + ((double) getHeight() * (double) getHeight()));

        if (isArrow()) {
            if (getDoubleLine()) {
                gp = dLineArrow(g2, getColor(), length,
                        (float) 3 * getStroke(), getInflip(), getDLSeparation());
                gptmp.append(gp, false);
                gp.reset();
                gp = dLineArrow(g2, getColor(), length,
                        (float) 3 * getStroke(), getInflip(),
                        -getDLSeparation());
                gptmp.append(gp, false);
            } else {
                gp = lineArrow(g2, getColor(), length,
                        (float) 4 * getStroke(), getInflip());
                gptmp.append(gp, false);
            }
        }

        Composite cold = g2.getComposite();
		Composite c = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
				transp);
		g2.setComposite(c);
        
        g2.setStroke(new BasicStroke(getStroke()));
        gp.reset();

        if (getDoubleLine()) {
            gp.moveTo(0.f, getDLSeparation());
            gp.lineTo((float) length, getDLSeparation());
            gp = trans(gp, 1.f);
            gptmp.append(gp, false);
            gp.reset();
            gp.moveTo(0.f, -getDLSeparation());
            gp.lineTo((float) length, -getDLSeparation());
            gp = trans(gp, 1.f);
            gptmp.append(gp, false);
        } else {
            gp.moveTo(0.f, 0.f);
            gp.lineTo((float) length, 0.f);
            gp = trans(gp, 1.f);
            gptmp.append(gp, false);
        }

        g2.draw(gptmp);
        Rectangle2D bb = gptmp.getBounds2D();

        double[] bbox =
        {bb.getMinX(), bb.getMinY(), bb.getMaxX(), bb.getMaxY()};
        setBoundingBox(bbox);
		
		
		
        g2.setComposite(cold);
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
	}

	/**
	 * The LaTeX command that is necessary to draw this JaFLine using the
	 * axodraw.sty package.
	 * 
	 * @param scale
	 *            A scale factor to translate Java coordinates to LaTeX
	 *            coordinates.
	 * @param canvasDim
	 *            The current dimension of the canvas.
	 * @return The corresponding axodraw LaTeX command.
	 */
	public final String latexCommand(float scale, Dimension canvasDim) {
		int canvasHeight = canvasDim.height;

		Point2D startPoint = getLaTexStartPoint(scale, canvasHeight);
		Point2D endPoint = getLaTexEndPoint(scale, canvasHeight);
		String command = "";
		String base = "\\Line";

		if (isArrow()) {
			base = "\\ArrowLine";

			if (isEnd()) {
				base = "\\LongArrow";
			}
		}

		if (((int) endPoint.getX() == (int) startPoint.getX())
				&& ((int) endPoint.getY() == (int) startPoint.getY())) {
			command = "%";
		} else if (getDoubleLine()) {
			Point2D offSet = getOffSet(scale);

			if (isFlip()) {
				String command1 = base + "("
						+ D_FORMAT.format(endPoint.getX() + offSet.getX())
						+ ","
						+ D_FORMAT.format(endPoint.getY() + offSet.getY())
						+ ")" + "("
						+ D_FORMAT.format(startPoint.getX() + offSet.getX())
						+ ","
						+ D_FORMAT.format(startPoint.getY() + offSet.getY())
						+ ")";

				String command2 = base + "("
						+ D_FORMAT.format(endPoint.getX() - offSet.getX())
						+ ","
						+ D_FORMAT.format(endPoint.getY() - offSet.getY())
						+ ")" + "("
						+ D_FORMAT.format(startPoint.getX() - offSet.getX())
						+ ","
						+ D_FORMAT.format(startPoint.getY() - offSet.getY())
						+ ")";

				command = command1.concat(command2
						.concat("%%JaxoDrawID:DoubleLine" + "("
								+ D_FORMAT.format(-getDLSeparation()) + ")"));
			} else {
				String command1 = base + "("
						+ D_FORMAT.format(startPoint.getX() + offSet.getX())
						+ ","
						+ D_FORMAT.format(startPoint.getY() + offSet.getY())
						+ ")" + "("
						+ D_FORMAT.format(endPoint.getX() + offSet.getX())
						+ ","
						+ D_FORMAT.format(endPoint.getY() + offSet.getY())
						+ ")";

				String command2 = base + "("
						+ D_FORMAT.format(startPoint.getX() - offSet.getX())
						+ ","
						+ D_FORMAT.format(startPoint.getY() - offSet.getY())
						+ ")" + "("
						+ D_FORMAT.format(endPoint.getX() - offSet.getX())
						+ ","
						+ D_FORMAT.format(endPoint.getY() - offSet.getY())
						+ ")";

				command = command1.concat(command2
						.concat("%%JaxoDrawID:DoubleLine" + "("
								+ D_FORMAT.format(getDLSeparation()) + ")"));
			}
		} else {
			if (isFlip()) {
				command = base + "(" + D_FORMAT.format(endPoint.getX()) + ","
						+ D_FORMAT.format(endPoint.getY()) + ")" + "("
						+ D_FORMAT.format(startPoint.getX()) + ","
						+ D_FORMAT.format(startPoint.getY()) + ")";
			} else {
				command = base + "(" + D_FORMAT.format(startPoint.getX()) + ","
						+ D_FORMAT.format(startPoint.getY()) + ")" + "("
						+ D_FORMAT.format(endPoint.getX()) + ","
						+ D_FORMAT.format(endPoint.getY()) + ")";
			}
		}

		return command;
	}

	// ///////////////////////////////////////////////////////////////////////
	//
	// private auxiliary methods //
	//
	// ///////////////////////////////////////////////////////////////////////
	private Point2D getLaTexStartPoint(float scaleFactor, int canvasHeight) {
		Point2D startVec = new Point2D.Float();
		float x1;
		float y1;

		if (getRelw() <= 0) {
			x1 = getX() - getRelw();
		} else {
			x1 = getX();
		}

		if (getRelh() >= 0) {
			y1 = getY();
		} else {
			y1 = getY() - getRelh();
		}

		startVec.setLocation(x1 / scaleFactor, (canvasHeight - y1)
				/ scaleFactor);

		return startVec;
	}

	private Point2D getLaTexEndPoint(float scaleFactor, int canvasHeight) {
		Point2D endVec = new Point2D.Float();
		float x2;
		float y2;

		if (getRelw() >= 0) {
			x2 = getX() + getRelw();
		} else {
			x2 = getX();
		}

		if (getRelh() <= 0) {
			y2 = getY();
		} else {
			y2 = getY() + getRelh();
		}

		endVec.setLocation(x2 / scaleFactor, (canvasHeight - y2) / scaleFactor);

		return endVec;
	}

	private Point2D getOffSet(float scaleFactor) {
		Point2D offSet = new Point2D.Float();
		float lSep = getDLSeparation() / scaleFactor;
		double theta = (double) Math
				.atan2((float) getRelh(), (float) getRelw());

		offSet.setLocation((float) lSep * Math.sin(theta), (float) lSep
				* Math.cos(theta));

		return offSet;
	}

	/**
	 * Brings up the edit panel that allows to change the parameters of this
	 * object.
	 * 
	 * @return True if the editing actually changed the object, false if the
	 *         object has not been changed.
	 */
	public final boolean editPanel() {
		JaxoLineOptionsPanel lineop = new JaxoLineOptionsPanel(
				JaxoMainPanel.FLINE);
		lineop.initParams(this);
		lineop.setPanelIcon("japlot/jaxodraw/icons/fline.gif");
		lineop.setPanelTitle("Fermion_line_parameters");
		baseEditPanel(lineop);
		lineop.addLineArrowPanel(1, 0);
		lineop.addLineMiddlePanel(2, 0);
		lineop.addDlPanel(2, 1);

		boolean hasChanged = lineop.showPanel();

		return hasChanged;
	}
}