/*

 * 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.JaxoColor;
import japlot.jaxodraw.JaxoLineOptionsPanel;

import java.awt.BasicStroke;
import java.awt.Color;
import org.freehep.graphics2d.VectorGraphics;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;

import japlot.jaxodraw.JaxoPrefs;


/** A general line object. */
public abstract class JaLineObject extends JaObject {
    /** The stroke (line width) of this line object. */
    protected float stroke;

    /** The dash size of the line object
     * (only used for ghost and scalar lines).
     */
    private float dash;

    /** The frequency of the line object
     * (only used for photon, gluon and zigzag lines).
     */
    private float freq;

    /** A boolean variable that indicates wether this line object
     * has an arrow or not.
     */
    private boolean arrow;

    /** A boolean variable that indicates wether this line object
     * has an arrow in the end (true) or at the end (false); used only
     * for fermionic lines.
     */
    private boolean end;

    /** Boolean variable that indicates whether the arrow of this line
     * object should be flipped with respect to the initial orientation or not.
     */
    private boolean flip;

    /** A boolean variable that specifies the internal flip with respect
     * to the relative width and height of this line.
     */
    private boolean inflip;

    /** The symmetry of a gluon, photon or zigzag line,
     * (the direction in which the wiggles start).
     */
    private boolean symm;

    /** A boolean variable that specifies the internal flip with respect
     * to the handle that the user grabs to drag this line.
     */
    private boolean back;

    /** The amplitude for photon, gluon and zigzag lines. */
    private int amp;

    /** A boolean variable that indicates whether this object should be
     * drawn with double lines.
     */
    private boolean doubleLine;

    /** The separation of the double lines. */
    private float dlSeparation;

    /** Constructor: sets the width, height, relative width and height,
     * to a default value of JaObject.INIT_SIZE.
     */
    public JaLineObject() {
        setRelw(INIT_SIZE);
        setRelh(INIT_SIZE);


        setAmp(JaxoPrefs.getIntPref(JaxoPrefs.PREF_AMPLITUDE));
        setFreq(20.0f);
        setColor(JaxoColor.getColor(JaxoPrefs.getPref(
                    JaxoPrefs.PREF_COLOR)));
        setStroke(JaxoPrefs.getFloatPref(JaxoPrefs.PREF_LINEWIDTH));
        setSymm(false);
        setDoubleLine(false);
        setDLSeparation(JaxoPrefs.getFloatPref(JaxoPrefs.PREF_DLSEP));


    }

    // Bean getter and setter methods

    /** Returns the stroke property of this line object.
     * @return The stroke property of this line object.
     */
    public final float getStroke() {
        return stroke;
    }

    /** Sets the stroke property of this line object.
     * @param newStroke The stroke property of this line object.
     */
    public final void setStroke(float newStroke) {
        this.stroke = newStroke;
    }

    /** Returns the dash property of this line object.
     * @return  The dash property of this line object.
     */
    public final float getDash() {
        return dash;
    }

    /** Sets the dash property of this line object.
     * @param newDash The dash property of this line object.
     */
    public final void setDash(float newDash) {
        this.dash = newDash;
    }

    /** Returns the freq property of this line object.
     * @return The freq property of this line object.
     */
    public final float getFreq() {
        return freq;
    }

    /** Sets the freq property of this line object.
     * @param newFreq The freq property of this line object.
     */
    public final void setFreq(float newFreq) {
        this.freq = newFreq;
    }

    /** Determines whether the arrow property of this line object is set or not.
     * @return The arrow property of this line object.
     */
    public final boolean isArrow() {
        return arrow;
    }

    /** Returns the arrow property of this line object.
     * @return The arrow property of this line object.
     */
    public final boolean getArrow() {
        return arrow;
    }

    /** Sets the arrow property of this line object.
     * @param arr The arrow property of this line object.
     */
    public final void setArrow(boolean arr) {
        this.arrow = arr;
    }

    /** Determines whether the end property of this line object is set or not.
     * @return The end property of this line object.
     */
    public final boolean isEnd() {
        return end;
    }

    /** Returns the end property of this line object.
     * @return The end property of this line object.
     */
    public final boolean getEnd() {
        return end;
    }

    /** Sets the end property of this line object.
     * @param mid The end property of this line object.
     */
    public final void setEnd(boolean mid) {
        this.end = mid;
    }

    /**Determines whether the flip property of this line object is set or not.
     * @return The flip property of this line object.
     */
    public final boolean isFlip() {
        return flip;
    }

    /** Returns the flip property of this line object.
     * @return The flip property of this line object.
     */
    public final boolean getFlip() {
        return flip;
    }

    /** Sets the  flip property of this line object.
     * @param newFlip The flip property of this line object.
     */
    public final void setFlip(boolean newFlip) {
        this.flip = newFlip;
    }

    /**Determines whether the back property of this line object is set or not.
     * @return The back property of this line object.
     */
    public final boolean isBack() {
        return back;
    }

    /** Returns the back property of this line object.
     * @return The back property of this line object.
     */
    public final boolean getBack() {
        return back;
    }

    /** Sets the back property of this line object.
     * @param newBack The back property of this line object.
     */
    public final void setBack(boolean newBack) {
        this.back = newBack;
    }

    /**Determines whether the inflip property of this line object is set or not.
     * @return The inflip property of this line object.
     */
    public final boolean isInflip() {
        return inflip;
    }

    /** Returns the inflip property of this line object.
     * @return The inflip property of this line object.
     */
    public final boolean getInflip() {
        return inflip;
    }

    /** Sets the inflip property of this line object.
     * @param newInflip The inflip property of this line object.
     */
    public final void setInflip(boolean newInflip) {
        this.inflip = newInflip;
    }

    /**Determines whether the symm property of this line object is set or not.
     * @return The symm property of this line object.
     */
    public final boolean isSymm() {
        return symm;
    }

    /** Returns the symm property of this line object.
     * @return The symm property of this line object.
     */
    public final boolean getSymm() {
        return symm;
    }

    /** Sets the symm property of this line object.
     * @param newSymm The symm property of this line object.
     */
    public final void setSymm(boolean newSymm) {
        this.symm = newSymm;
    }

    /** Returns the amp property of this line object.
     * @return The amp property of this line object.
     */
    public final int getAmp() {
        return amp;
    }

    /** Sets the amp property of this line object.
     * @param newAmp The amp property of this line object.
     */
    public final void setAmp(int newAmp) {
        this.amp = newAmp;
    }

    /** Sets the double line property.
     * @param dline The double line boolean variable.
     */
    public final void setDoubleLine(boolean dline) {
        this.doubleLine = dline;
    }

    /** Returns the double line property.
     * @return The double line boolean variable of this object.
     */
    public final boolean getDoubleLine() {
        return doubleLine;
    }

    /** Sets the double line property.
     * @param dlsep The double line property.
     */
    public final void setDLSeparation(float dlsep) {
        this.dlSeparation = dlsep;
    }

    /** Returns the double line property.
     * @return The double line boolean variable of this object.
     */
    public final float getDLSeparation() {
        return dlSeparation;
    }

    /** Determines which handle the user has selected to move/resize/edit this line.
     * @param clickX The x coordinate where the mouse click has ocurred.
     * @param clickY The y coordinate where the mouse click has ocurred.
     * @param editmode The current edit mode.
     * @return One of the static variables SELECT_* defined in JaObject that specifies the
     * handle which the user has clicked.
     */
    public final int getGrabbedHandle(int clickX, int clickY, int editmode) {
        int x = getX();
        int y = getY();
        int w = getWidth();
        int h = getHeight();
        int l2 = LENGTH / 2;

        if ((editmode == MOVE) || (editmode == COPY)) {
            if ((getRelw() > 0) && (getRelh() >= 0)) {
                if ((clickX >= (x - l2)) && (clickX <= (x + l2))
                        && (clickY >= (y - l2)) && (clickY <= (y + l2))) {
                    return SELECT_BODY;
                } else if ((clickX >= ((x + (w / 2)) - l2))
                        && (clickX <= (x + (w / 2) + l2))
                        && (clickY >= ((y + (h / 2)) - l2))
                        && (clickY <= (y + (h / 2) + l2))) {
                    return SELECT_BODY;
                } else if ((clickX >= ((x + w) - l2))
                        && (clickX <= (x + w + l2))
                        && (clickY >= ((y + h) - l2))
                        && (clickY <= (y + h + l2))) {
                    return SELECT_BODY;
                }
            } else if ((getRelw() < 0) && (getRelh() <= 0)) {
                if ((clickX >= (x - l2)) && (clickX <= (x + l2))
                        && (clickY >= (y - l2)) && (clickY <= (y + l2))) {
                    return SELECT_BODY;
                } else if ((clickX >= ((x + (w / 2)) - l2))
                        && (clickX <= (x + (w / 2) + l2))
                        && (clickY >= ((y + (h / 2)) - l2))
                        && (clickY <= (y + (h / 2) + l2))) {
                    return SELECT_BODY;
                } else if ((clickX >= ((x + w) - l2))
                        && (clickX <= (x + w + l2))
                        && (clickY >= ((y + h) - l2))
                        && (clickY <= (y + h + l2))) {
                    return SELECT_BODY;
                }
            } else if ((getRelw() >= 0) && (getRelh() < 0)) {
                if ((clickX >= (x - l2)) && (clickX <= (x + l2))
                        && (clickY >= ((y + h) - l2))
                        && (clickY <= (y + h + l2))) {
                    return SELECT_BODY;
                } else if ((clickX >= ((x + (w / 2)) - l2))
                        && (clickX <= (x + (w / 2) + l2))
                        && (clickY >= ((y + (h / 2)) - l2))
                        && (clickY <= (y + (h / 2) + l2))) {
                    return SELECT_BODY;
                } else if ((clickX >= ((x + w) - l2))
                        && (clickX <= (x + w + l2)) && (clickY >= (y - l2))
                        && (clickY <= (y + l2))) {
                    return SELECT_BODY;
                }
            } else if ((getRelw() <= 0) && (getRelh() > 0)) {
                if ((clickX >= (x - l2)) && (clickX <= (x + l2))
                        && (clickY >= ((y + h) - l2))
                        && (clickY <= (y + h + l2))) {
                    return SELECT_BODY;
                } else if ((clickX >= ((x + (w / 2)) - l2))
                        && (clickX <= (x + (w / 2) + l2))
                        && (clickY >= ((y + (h / 2)) - l2))
                        && (clickY <= (y + (h / 2) + l2))) {
                    return SELECT_BODY;
                } else if ((clickX >= ((x + w) - l2))
                        && (clickX <= (x + w + l2)) && (clickY >= (y - l2))
                        && (clickY <= (y + l2))) {
                    return SELECT_BODY;
                }
            }

            return SELECT_NONE;
        } else if (editmode == RESIZE) {
            if ((getRelw() > 0) && (getRelh() >= 0)) {
                if ((clickX >= (x - l2)) && (clickX <= (x + l2))
                        && (clickY >= (y - l2)) && (clickY <= (y + l2))) {
                    setBack(true);
                    setInflip(!getInflip());
                    this.setRelWAndH(-getRelw(), -getRelh());

                    return SELECT_UL;
                } else if ((clickX >= ((x + w) - l2))
                        && (clickX <= (x + w + l2))
                        && (clickY >= ((y + h) - l2))
                        && (clickY <= (y + h + l2))) {
                    return SELECT_LR;
                }
            } else if ((getRelw() < 0) && (getRelh() <= 0)) {
                if ((clickX >= (x - l2)) && (clickX <= (x + l2))
                        && (clickY >= (y - l2)) && (clickY <= (y + l2))) {
                    return SELECT_UL;
                } else if ((clickX >= ((x + w) - l2))
                        && (clickX <= (x + w + l2))
                        && (clickY >= ((y + h) - l2))
                        && (clickY <= (y + h + l2))) {
                    setBack(true);
                    setInflip(!getInflip());
                    this.setRelWAndH(-getRelw(), -getRelh());

                    return SELECT_LR;
                }
            } else if ((getRelw() >= 0) && (getRelh() < 0)) {
                if ((clickX >= (x - l2)) && (clickX <= (x + l2))
                        && (clickY >= ((y + h) - l2))
                        && (clickY <= (y + h + l2))) {
                    setBack(true);
                    setInflip(!getInflip());
                    this.setRelWAndH(-getRelw(), -getRelh());

                    return SELECT_LL;
                } else if ((clickX >= ((x + w) - l2))
                        && (clickX <= (x + w + l2)) && (clickY >= (y - l2))
                        && (clickY <= (y + l2))) {
                    return SELECT_UR;
                }
            } else if ((getRelw() <= 0) && (getRelh() > 0)) {
                if ((clickX >= (x - l2)) && (clickX <= (x + l2))
                        && (clickY >= ((y + h) - l2))
                        && (clickY <= (y + h + l2))) {
                    return SELECT_LL;
                } else if ((clickX >= ((x + w) - l2))
                        && (clickX <= (x + w + l2)) && (clickY >= (y - l2))
                        && (clickY <= (y + l2))) {
                    setBack(true);
                    setInflip(!getInflip());
                    this.setRelWAndH(-getRelw(), -getRelh());

                    return SELECT_UR;
                }
            }

            return SELECT_NONE;
        }

        return SELECT_NONE;
    }

    /** Draws the handles of this line object.
     * @param g2 The current graphics context
     */
    public final void drawHandles(VectorGraphics g2) {
        int x = getX();
        int y = getY();
        int w = getWidth();
        int h = getHeight();
        int l2 = LENGTH / 2;

        if (((getRelw() >= 0) && (getRelh() >= 0))
                || ((getRelw() <= 0) && (getRelh() <= 0))) {
            g2.setColor(JaxoColor.RED);
            g2.setStroke(new BasicStroke(1.2f));
            g2.drawRect(x - l2, y - l2, LENGTH, LENGTH);
            g2.drawRect(x + ((w - LENGTH) / 2), y + ((h - LENGTH) / 2),
                LENGTH, LENGTH);
            g2.drawRect((x + w) - l2, (y + h) - l2, LENGTH, LENGTH);

            if (isMarked()) {
                g2.setColor(JaxoColor.GRAYSCALE150);
                g2.fillRect(x - l2 + 1, y - l2 + 1, LENGTH - 1, LENGTH - 1);
                g2.fillRect(x + ((w - LENGTH) / 2) + 1,
                    y + ((h - LENGTH) / 2) + 1, LENGTH - 1, LENGTH - 1);
                g2.fillRect((x + w) - l2 + 1, (y + h) - l2 + 1, LENGTH - 1,
                    LENGTH - 1);
            }
        } else if (((getRelw() < 0) && (getRelh() > 0))
                || ((getRelw() > 0) && (getRelh() < 0))) {
            g2.setColor(JaxoColor.RED);
            g2.setStroke(new BasicStroke(1.2f));
            g2.drawRect(x - l2, (y + h) - l2, LENGTH, LENGTH);
            g2.drawRect(x + ((w - LENGTH) / 2), y + ((h - LENGTH) / 2),
                LENGTH, LENGTH);
            g2.drawRect((x + w) - l2, y - l2, LENGTH, LENGTH);

            if (isMarked()) {
                g2.setColor(JaxoColor.GRAYSCALE150);
                g2.fillRect(x - l2 + 1, (y + h) - l2 + 1, LENGTH - 1,
                    LENGTH - 1);
                g2.fillRect(x + ((w - LENGTH) / 2) + 1,
                    y + ((h - LENGTH) / 2) + 1, LENGTH - 1, LENGTH - 1);
                g2.fillRect((x + w) - l2 + 1, y - l2 + 1, LENGTH - 1,
                    LENGTH - 1);
            }
        }
    }

    /** Draws an arrow on this line.
     * @param g2 The graphics context.
     * @param c The color of the arrow.
     * @param length The length of this line.
     * @param size The size of the arrow.
     * @param fl The flip property of this line.
     * @return A GeneralPath object of the arrow.
     */
    protected final GeneralPath lineArrow(VectorGraphics g2, Color c,
        double length, float size, boolean fl) {
        g2.setStroke(new BasicStroke(2.0f));

        GeneralPath gp = new GeneralPath();
        float arrowsize = (5.f * size) / 8.f;
        gp.moveTo((float) arrowsize, 0.f);
        gp.lineTo(-arrowsize, arrowsize / 1.5f);
        gp.lineTo(-arrowsize / 1.5f, 0.f);
        gp.lineTo(-arrowsize, -arrowsize / 1.5f);
        gp.closePath();

        AffineTransform at = new AffineTransform();
        if (isEnd()) {
            at.translate(length, 0.d);
        } else {
            at.translate(length / 2, 0.d);
        }

        if (fl) {
            if (isEnd()) {
                at.translate(-length, 0.d);
            }
            at.rotate(Math.toRadians(180), 0.f, 0.f);
        }

        gp.transform(at);
        gp = trans(gp, 1.f);

        g2.setPaint(c);
        g2.fill(gp);

        return gp;
    }

    /** Draws arrows on a double line.
     * @param g2 The graphics context.
     * @param c The color of the arrow.
     * @param length The length of this line.
     * @param size The size of the arrow.
     * @param fl The flip property of this line.
     * @param dlSep The separation of the double line.
     * @return A GeneralPath object of the arrow.
     */
    protected final GeneralPath dLineArrow(VectorGraphics g2, Color c,
        double length, float size, boolean fl, float dlSep) {
        g2.setStroke(new BasicStroke(2.0f));

        GeneralPath gp = new GeneralPath();
        float arrowsize = (5.f * size) / 8.f;
        gp.moveTo((float) arrowsize, dlSep);
        gp.lineTo(-arrowsize, (arrowsize / 1.5f) + dlSep);
        gp.lineTo(-arrowsize / 1.5f, dlSep);
        gp.lineTo(-arrowsize, (-arrowsize / 1.5f) + dlSep);
        gp.closePath();

        AffineTransform at = new AffineTransform();
        if (isEnd()) {
            at.translate(length, 0.d);
        } else {
            at.translate(length / 2, 0.d);
        }

        if (fl) {
            if (isEnd()) {
                at.translate(-length, 0.d);
            }
            at.rotate(Math.toRadians(180), 0.f, 0.f);
        }

        gp.transform(at);
        gp = trans(gp, 1.f);

        g2.setPaint(c);
        g2.fill(gp);

        return gp;
    }

    /** Rescales this JaxoLine by the scale factor scale,
     * keeping the point (orx, ory) fixed.
     * @param orx The x-coordinate of the fixed point.
     * @param ory The y-coordinate of the fixed point.
     * @param scale The scale parameter.
     */
    public final void rescaleObject(int orx, int ory, float scale) {
        int oldWidth = this.getSize().width;
        int oldHeight = this.getSize().height;
        int newWidth = (int) Math.round(oldWidth * scale);
        int newHeight = (int) Math.round(oldHeight * scale);
        int newRelWidth = (int) Math.round(this.getRelSize().width * scale);
        int newRelHeight = (int) Math.round(this.getRelSize().height * scale);
        int newAmp = (int) (this.getAmp() * scale);

        int wiggleNumbers = 0;

        if (this instanceof JaGlLine) {
            wiggleNumbers =
                (int) Math.round((
                        Math.sqrt((oldWidth * oldWidth)
                            + (oldHeight * oldHeight)) - getFreq()
                    ) / getFreq() / 0.6f);
        } else {
            wiggleNumbers =
                (int) Math.round(Math.sqrt((oldWidth * oldWidth)
                        + (oldHeight * oldHeight)) / getFreq());
        }

        float newFreq = 0.f;

        if (this instanceof JaGlLine) {
            newFreq =
                (float) (
                    Math.sqrt((newWidth * newWidth) + (newHeight * newHeight)) / (
                        (wiggleNumbers * 0.6f) + 1
                    )
                );
        } else {
            newFreq =
                (float) (
                    Math.sqrt((newWidth * newWidth) + (newHeight * newHeight)) / wiggleNumbers
                );
        }

        Point2D newP =
            this.scalePoint(orx, ory, scale, this.getX(), this.getY());

        this.setX((int) Math.round(newP.getX()));
        this.setY((int) Math.round(newP.getY()));
        this.setRelWAndH(newRelWidth, newRelHeight);
        this.setFreq(newFreq);
        this.setAmp(newAmp);
    }

    /** Adds components to the edit panel that are common to all line objects.
     * @param lineop The option panel of the line object.
     */
    public final void baseEditPanel(JaxoLineOptionsPanel lineop) {
        lineop.addFinalDimSPanel(0, 0);
        lineop.addFinalStrSPanel(0, 1);
        lineop.addColorPanel(1, 1);
    }

    /** The LaTeX command that sets the width for this Line,
     *  using the axodraw.sty package.
     * @return The corresponding LaTeX command.
     */
    public final String latexWidth() {
        // a default getStroke() value of 1.0 corresponds to a
        // default width in axodraw of  0.5;
        String thisValue = Float.toString(getStroke() / 2.f);
        String base = "\\SetWidth{";
        String closing = "}";
        String lineWidth = base.concat(thisValue.concat(closing));

        return lineWidth;
    }
}

 

Ads help maintain this website.