/*

 * 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 java.awt.BasicStroke;
import java.awt.Dimension;
import org.freehep.graphics2d.VectorGraphics;
import java.awt.geom.FlatteningPathIterator;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;


import japlot.jaxodraw.*;

/** A photon loop. */
public class JaPLoop extends JaLoopObject {
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/** Constructor: just calls super(). */
    public JaPLoop() {
        super();


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



    }

    /** Returns an exact copy of this JaPLoop.
     * @return A copy of this JaPLoop.
     */
    public final JaObject copy() {
        JaPLoop temp = (JaPLoop) copy(new JaPLoop());
        temp.setAmp(getAmp());
        temp.setFreq(getFreq());

        return temp;
    }

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

        if (comp instanceof JaPLoop) {
            if (super.isCopy(comp)
                    && (((JaPLoop) comp).getAmp() == getAmp())
                    && (((JaPLoop) comp).getFreq() == getFreq())) {
                isCopy = true;
            }
        }

        return isCopy;
    }

    /** The method that draws this JaPLoop.
     * @param g2 The graphics context where the JaPLoop 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());
        g2.setStroke(new BasicStroke(getStroke()));

        GeneralPath gp = getGeneralPath();
        gp.reset();

        int a = getAmp();
        int n;
        float ts;
        double length =
            Math.sqrt(((double) getWidth() * (double) getWidth())
                + ((double) getHeight() * (double) getHeight()));

        if (length < 8) {
            length = 0;
        }

        length = 2 * length * Math.PI;

        n = 2 * ((int) (length / getFreq()));
        ts = (float) length / n;

        if (getDoubleLine()) {
            gp.moveTo(0.f, getDLSeparation());

            for (int i = 1; i <= n; i++) {
                gp.quadTo((((2 * i) - 1) * ts) / 2.f, -a + getDLSeparation(),
                    i * ts, getDLSeparation());
                a = -a;
            }

            gp.moveTo(0.f, -getDLSeparation());

            for (int i = 1; i <= n; i++) {
                gp.quadTo((((2 * i) - 1) * ts) / 2.f, -a - getDLSeparation(),
                    i * ts, -getDLSeparation());
                a = -a;
            }
        } else {
            gp.moveTo(0.f, 0.f);

            for (int i = 1; i <= n; i++) {
                gp.quadTo((((2 * i) - 1) * ts) / 2.f, (float) -a, i * ts, 0.f);
                a = -a;
            }
        }

        gp = conformalGP(gp, length, 2 * Math.PI);

        gp = transl(gp, 1 / Math.PI);
        g2.draw(gp);

        Rectangle2D bb = gp.getBounds2D();

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

    /** The LaTeX command that is necessary to draw this JaPLoop
     * 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 center = getLaTexCenter(scale, canvasHeight);
        float radius = getLaTexRadius(scale);
        Point2D angles = getLaTexAngles();
        float amplitude = getLaTexAmplitude(2.f * scale);
        float wiggles = getLaTexWiggleNumber(1.0f);
        String command = "";
        String base = "\\PhotonArc";

        if ((int) radius == 0) {
            command = "%";
        } else if (getDoubleLine()) {
            float offSet = getDLSeparation() / scale;

            String command1 =
                base + "(" + D_FORMAT.format(center.getX()) + ","
                + D_FORMAT.format(center.getY()) + ")" + "("
                + D_FORMAT.format(radius + offSet) + ","
                + D_FORMAT.format(angles.getX()) + ","
                + D_FORMAT.format(angles.getY()) + ")" + "{"
                + D_FORMAT.format(amplitude) + "}" + "{"
                + D_FORMAT.format(wiggles) + "}";

            String command2 =
                base + "(" + D_FORMAT.format(center.getX()) + ","
                + D_FORMAT.format(center.getY()) + ")" + "("
                + D_FORMAT.format(radius - offSet) + ","
                + D_FORMAT.format(angles.getX()) + ","
                + D_FORMAT.format(angles.getY()) + ")" + "{"
                + D_FORMAT.format(amplitude) + "}" + "{"
                + D_FORMAT.format(wiggles) + "}";

            command =
                command1.concat(command2.concat("%%JaxoDrawID:DoubleLine"
                        + "(" + D_FORMAT.format(getDLSeparation()) + ")"));
        } else {
            command =
                base + "(" + D_FORMAT.format(center.getX()) + ","
                + D_FORMAT.format(center.getY()) + ")" + "("
                + D_FORMAT.format(radius) + ","
                + D_FORMAT.format(angles.getX()) + ","
                + D_FORMAT.format(angles.getY()) + ")" + "{"
                + D_FORMAT.format(amplitude) + "}" + "{"
                + D_FORMAT.format(wiggles) + "}";
        }

        return command;
    }

    /////////////////////////////////////////////////////////////////////////
    //
    //   private auxiliary methods  //
    //
    /////////////////////////////////////////////////////////////////////////
    protected final Point2D getLaTexAngles() {
        Point2D anglesPoint = new Point2D.Float();
        int sAngle;
        int eAngle;

        if (getRelw() == 0) {
            sAngle = 90;
        }

        sAngle =
            (int) Math.round((
                    Math.atan2((float) getRelh(), (float) getRelw()) * 180.f
                ) / Math.PI);

        sAngle = -sAngle;
        eAngle = sAngle + 360;
        anglesPoint.setLocation(sAngle, eAngle);

        return anglesPoint;
    }

    private float getLaTexAmplitude(float scaleFactor) {
        float a = getAmp() / scaleFactor;

        return a;
    }

    private float getLaTexWiggleNumber(float scaleFactor) {
        double length =
            Math.sqrt(((double) getWidth() * (double) getWidth())
                + ((double) getHeight() * (double) getHeight()));

        float n = (float) ((length * 2 * Math.PI) / getFreq());

        n = (float) Math.round(n / scaleFactor);

        return n;
    }

    private Point2D conformal(float px, float py, double length, double angle) {
        float nx =
            (float) (
                length / 2 * (
                    1
                    + (
                        Math.exp((py * angle) / length) * Math.cos((
                                px * angle
                            ) / length)
                    )
                )
            );
        float ny =
            (float) (
                -length / 2 * Math.exp((py * angle) / length) * Math.sin((
                        -px * angle
                    ) / length)
            );

        return new Point2D.Float(nx, ny);
    }

    private GeneralPath conformalGP(GeneralPath gpp, double length,
        double angle) {
        GeneralPath gp2 = new GeneralPath();
        FlatteningPathIterator pi =
            new FlatteningPathIterator(gpp.getPathIterator(null), 0.05);

        float[] segm = new float[6];
        int type;
        float corr = (1 - (20.f / (float) length));

        gp2.moveTo(0.f, 0.f);

        while (!pi.isDone()) {
            type = pi.currentSegment(segm);

            float px1 =
                (float) conformal(segm[0], segm[1], length, angle).getX();
            float py1 =
                (float) conformal(segm[0], segm[1], length, angle).getY();
            float px2 =
                (float) conformal(segm[2], segm[3], length, angle).getX();
            float py2 =
                (float) conformal(segm[2], segm[3], length, angle).getY();
            float px3 =
                (float) conformal(segm[4], segm[5], length, angle).getX();
            float py3 =
                (float) conformal(segm[4], segm[5], length, angle).getY();

            if (type == PathIterator.SEG_MOVETO) {
                gp2.moveTo(px1, py1);
            } else if (type == PathIterator.SEG_LINETO) {
                gp2.lineTo(px1, py1);
            } else if (type == PathIterator.SEG_QUADTO) {
                px1 = (float) conformal(segm[0], corr * segm[1], length, angle)
                                  .getX();
                py1 = (float) conformal(segm[0], corr * segm[1], length, angle)
                                  .getY();
                gp2.quadTo(px1, py1, px2, py2);
            } else if (type == PathIterator.SEG_CUBICTO) {
                gp2.curveTo(px1, py1, px2, py2, px3, py3);
            } else {
                gp2.closePath();
            }

            pi.next();
        }

        return gp2;
    }
}

 

Ads help maintain this website.