001/* An actor that converts polar coordinates to a complex token. 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.ComplexToken; 033import ptolemy.data.DoubleToken; 034import ptolemy.data.type.BaseType; 035import ptolemy.kernel.CompositeEntity; 036import ptolemy.kernel.util.IllegalActionException; 037import ptolemy.kernel.util.NameDuplicationException; 038import ptolemy.math.Complex; 039 040/////////////////////////////////////////////////////////////////// 041/// PolarToComplex 042 043/** 044 045 This actor reads two double tokens (magnitude and angle) and outputs 046 a single complex token. The output is a complex token representation of 047 the coordinates given at the inputs in polar form. The complex token 048 has two parts: the first part correspond to the real part, which is 049 magnitude * cos(angle, and the second part is the imaginary part, which is 050 magnitude * sin(angle). Note that the angle input is 051 assumed to be in radians. If either input is NaN or infinity, 052 then the output is NaN or infinity. 053 054 @author Michael Leung, Edward A. Lee, Paul Whitaker 055 @version $Id$ 056 @since Ptolemy II 1.0 057 @Pt.ProposedRating Green (pwhitake) 058 @Pt.AcceptedRating Green (pwhitake) 059 */ 060public class PolarToComplex extends TypedAtomicActor { 061 /** Construct an actor with the given container and name. 062 * @param container The container. 063 * @param name The name of this actor. 064 * @exception IllegalActionException If the actor cannot be contained 065 * by the proposed container. 066 * @exception NameDuplicationException If the container already has an 067 * actor with this name. 068 */ 069 public PolarToComplex(CompositeEntity container, String name) 070 throws NameDuplicationException, IllegalActionException { 071 super(container, name); 072 073 magnitude = new TypedIOPort(this, "magnitude", true, false); 074 magnitude.setTypeEquals(BaseType.DOUBLE); 075 076 angle = new TypedIOPort(this, "angle", true, false); 077 angle.setTypeEquals(BaseType.DOUBLE); 078 079 output = new TypedIOPort(this, "output", false, true); 080 output.setTypeEquals(BaseType.COMPLEX); 081 082 _attachText("_iconDescription", 083 "<svg>\n" + "<polygon points=\"-15,-15 15,15 15,-15 -15,15\" " 084 + "style=\"fill:white\"/>\n" + "</svg>\n"); 085 } 086 087 /////////////////////////////////////////////////////////////////// 088 //// public variables //// 089 090 /** The input port for the magnitude component, which has type 091 DoubleToken. */ 092 public TypedIOPort magnitude; 093 094 /** The input port for the angle component (in radians), which has 095 type DoubleToken. */ 096 public TypedIOPort angle; 097 098 /** The port for the output, which has type ComplexToken. */ 099 public TypedIOPort output; 100 101 /////////////////////////////////////////////////////////////////// 102 //// public methods //// 103 104 /** Consume a double token from each input port (magnitude and angle) 105 * and output a new complex token on the output port. The output is 106 * a complex representation of the coordinates given at the inputs in 107 * polar form. The input angle is assumed to be in radians. If either 108 * input has no token, then do nothing. 109 * @exception IllegalActionException If there is no director. 110 */ 111 @Override 112 public void fire() throws IllegalActionException { 113 super.fire(); 114 double magnitudeValue = ((DoubleToken) magnitude.get(0)).doubleValue(); 115 double angleValue = ((DoubleToken) angle.get(0)).doubleValue(); 116 117 double xValue = magnitudeValue * Math.cos(angleValue); 118 double yValue = magnitudeValue * Math.sin(angleValue); 119 120 output.send(0, new ComplexToken(new Complex(xValue, yValue))); 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 (!magnitude.hasToken(0) || !angle.hasToken(0)) { 130 return false; 131 } 132 133 return super.prefire(); 134 } 135}