001/* An actor that converts Cartesian coordinates to polar form.
002
003 Copyright (c) 1998-2014 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027 */
028package ptolemy.actor.lib.conversions;
029
030import ptolemy.actor.TypedAtomicActor;
031import ptolemy.actor.TypedIOPort;
032import ptolemy.data.DoubleToken;
033import ptolemy.data.type.BaseType;
034import ptolemy.kernel.CompositeEntity;
035import ptolemy.kernel.util.IllegalActionException;
036import ptolemy.kernel.util.NameDuplicationException;
037
038///////////////////////////////////////////////////////////////////
039/// CartesianToPolar
040
041/**
042 <p>Convert a Cartesian pair, which is represented by two double tokens (x and y),
043 to a polar form, which is also represented by two double tokens (magnitude
044 and angle).  The angle is in radians.
045 </p><p>
046 The implementation uses java.lang.Math.atan2(double, double).</p>
047 @see java.lang.Math#atan2(double, double)
048
049 @author Michael Leung, Edward A. Lee, Paul Whitaker
050 @version $Id$
051 @since Ptolemy II 1.0
052 @Pt.ProposedRating Green (pwhitake)
053 @Pt.AcceptedRating Green (pwhitake)
054 */
055public class CartesianToPolar extends TypedAtomicActor {
056    /** Construct an actor with the given container and name.
057     *  @param container The container.
058     *  @param name The name of this actor.
059     *  @exception IllegalActionException If the actor cannot be contained
060     *   by the proposed container.
061     *  @exception NameDuplicationException If the container already has an
062     *   actor with this name.
063     */
064    public CartesianToPolar(CompositeEntity container, String name)
065            throws NameDuplicationException, IllegalActionException {
066        super(container, name);
067
068        x = new TypedIOPort(this, "x", true, false);
069        x.setTypeEquals(BaseType.DOUBLE);
070
071        y = new TypedIOPort(this, "y", true, false);
072        y.setTypeEquals(BaseType.DOUBLE);
073
074        magnitude = new TypedIOPort(this, "magnitude", false, true);
075        magnitude.setTypeEquals(BaseType.DOUBLE);
076
077        angle = new TypedIOPort(this, "angle", false, true);
078        angle.setTypeEquals(BaseType.DOUBLE);
079
080        _attachText("_iconDescription",
081                "<svg>\n" + "<polygon points=\"-15,-15 15,15 15,-15 -15,15\" "
082                        + "style=\"fill:white\"/>\n" + "</svg>\n");
083    }
084
085    ///////////////////////////////////////////////////////////////////
086    ////                         public variables                  ////
087
088    /** The x coordinate of the input pair, which has type DoubleToken. */
089    public TypedIOPort x;
090
091    /** The y coordinate of the input pair, which has type DoubleToken. */
092    public TypedIOPort y;
093
094    /** The magnitude component of the output pair, which has type
095     DoubleToken. */
096    public TypedIOPort magnitude;
097
098    /** The angle component of the output pair, which has type DoubleToken. */
099    public TypedIOPort angle;
100
101    ///////////////////////////////////////////////////////////////////
102    ////                         public methods                    ////
103
104    /** Consume one double token from each of the two input ports (x and y),
105     *  and output one new double token on each of the two output ports
106     *  (magnitude and angle). The output is a polar form representation of
107     *  the Cartesian pair given at the inputs. The angle is in radians.
108     *  @exception IllegalActionException If there is no director.
109     */
110    @Override
111    public void fire() throws IllegalActionException {
112        super.fire();
113        double xValue = ((DoubleToken) x.get(0)).doubleValue();
114        double yValue = ((DoubleToken) y.get(0)).doubleValue();
115
116        double magnitudeValue = Math.sqrt(xValue * xValue + yValue * yValue);
117        double angleValue = Math.atan2(yValue, xValue);
118
119        magnitude.send(0, new DoubleToken(magnitudeValue));
120        angle.send(0, new DoubleToken(angleValue));
121    }
122
123    /** Return false if either of the input ports has no token, otherwise
124     *  return what the superclass returns (presumably true).
125     *  @exception IllegalActionException If there is no director.
126     */
127    @Override
128    public boolean prefire() throws IllegalActionException {
129        if (!x.hasToken(0) || !y.hasToken(0)) {
130            return false;
131        }
132
133        return super.prefire();
134    }
135}