title: ActionScript Error: 1120: Access of undefined property myRec on a defined variable
body: <p>I'm trying to write a dollar recognizer in Flash Builder. I'm really new to actionscript and mxml, and I''m getting this error on the line "myRec.addTemplate..." in the code below:</p>
  
  <pre><code>import de.yuv.gestures.Recognizer;
  
  import flash.display.Graphics;
  import flash.display.Shape;
  import flash.display.Sprite;
  import flash.events.MouseEvent;
  import flash.geom.Point;
  
  var myRec:Recognizer = new Recognizer();
  
  myRec.addTemplate("triangle", new Array(new Point(137,139),new Point(135,141),new Point(133,144),new Point(132,146),new Point(130,149),new Point(128,151),new Point(126,155),new Point(123,160),new Point(120,166),new Point(116,171),new Point(112,177),new Point(107,183),new Point(102,188),new Point(100,191),new Point(95,195),new Point(90,199),new Point(86,203),new Point(82,206),new Point(80,209),new Point(75,213),new Point(73,213),new Point(70,216),new Point(67,219),new Point(64,221),new Point(61,223),new Point(60,225),new Point(62,226),new Point(65,225),new Point(67,226),new Point(74,226),new Point(77,227),new Point(85,229),new Point(91,230),new Point(99,231),new Point(108,232),new Point(116,233),new Point(125,233),new Point(134,234),new Point(145,233),new Point(153,232),new Point(160,233),new Point(170,234),new Point(177,235),new Point(179,236),new Point(186,237),new Point(193,238),new Point(198,239),new Point(200,237),new Point(202,239),new Point(204,238),new Point(206,234),new Point(205,230),new Point(202,222),new Point(197,216),new Point(192,207),new Point(186,198),new Point(179,189),new Point(174,183),new Point(170,178),new Point(164,171),new Point(161,168),new Point(154,160),new Point(148,155),new Point(143,150),new Point(138,148),new Point(136,148)));
  </code></pre>
  
  <p>It's really confusing me since I've defined myRec just above it. The same code, though, works in Flash Professional, which leads me to believe that I'm missing some import statement or other subtlety that isn't being made clear my this error message. </p>
  
  <p>Any help would be greatly appreciated.</p>
  
  <p>Thanks,
  NinjaSteph</p>
  
  <p>Edit (complete error message):
  Description Resource    Path    Location    Type
  1120: Access of undefined property myRec.   GestureRecognizer.mxml  /GestureRecognizer/src  line 17 Flex Problem</p>
  
  <p>Edit (complete mxml file): </p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
             xmlns:s="library://ns.adobe.com/flex/spark"
             xmlns:mx="library://ns.adobe.com/flex/mx"
             minWidth="955" minHeight="600" currentState="Title"&gt;
  &lt;fx:Script&gt;&lt;![CDATA[
      import de.yuv.gestures.Recognizer;
  
      import flash.display.Graphics;
      import flash.display.Shape;
      import flash.display.Sprite;
      import flash.events.MouseEvent;
      import flash.geom.Point;
  
      var myRec:Recognizer = new Recognizer();
  
      myRec.addTemplate("triangle", new Array(new Point(137,139),new Point(135,141),new Point(133,144),new Point(132,146),new Point(130,149),new Point(128,151),new Point(126,155),new Point(123,160),new Point(120,166),new Point(116,171),new Point(112,177),new Point(107,183),new Point(102,188),new Point(100,191),new Point(95,195),new Point(90,199),new Point(86,203),new Point(82,206),new Point(80,209),new Point(75,213),new Point(73,213),new Point(70,216),new Point(67,219),new Point(64,221),new Point(61,223),new Point(60,225),new Point(62,226),new Point(65,225),new Point(67,226),new Point(74,226),new Point(77,227),new Point(85,229),new Point(91,230),new Point(99,231),new Point(108,232),new Point(116,233),new Point(125,233),new Point(134,234),new Point(145,233),new Point(153,232),new Point(160,233),new Point(170,234),new Point(177,235),new Point(179,236),new Point(186,237),new Point(193,238),new Point(198,239),new Point(200,237),new Point(202,239),new Point(204,238),new Point(206,234),new Point(205,230),new Point(202,222),new Point(197,216),new Point(192,207),new Point(186,198),new Point(179,189),new Point(174,183),new Point(170,178),new Point(164,171),new Point(161,168),new Point(154,160),new Point(148,155),new Point(143,150),new Point(138,148),new Point(136,148)));
  
      var recordedPoints:Array;
      public function hideAllHighlights():void
      {
          for (var i:uint = 0; i &lt; myRec.Templates.length; i++){
  
              var mc:MovieClip = this["mc_"+myRec.Templates[i].Name];
              trace(mc);
              if (mc)
              {
                  mc.visible = false;
              }
          }
      }
  
      var record:Boolean = false;
  
      //hideAllHighlights();
  
      public function handleMouseDown (event:MouseEvent):void
      {
          trace('handleMouseDown:');
          record = true;
          hideAllHighlights();
          recordedPoints = new Array();
          //clear objects from stage that are not circles
          for(var i:int = 0; recPanel.stage.numChildren&gt;i; ){
              if(recPanel.stage.getChildAt(i).name == "circle")
                  recPanel.stage.removeChildAt(i);
              else
                  i++;
          }
      }
  
      public function handleMouseUp(event:MouseEvent):void
      {
          trace('handleMouseUp:');
          record = false;
          var myResult = myRec.recognize(recordedPoints);
          trace (myResult.Name);
          trace (myResult.Score);
          resLabel.text = myResult.Name;
          /*var mc:MovieClip = this["mc_"+myResult.Name];
          if (mc){
              mc.visible = true;
          }*/ 
      }
  
      public function drawCircle(x:Number, y:Number):void
      {
          var circle:Shape = new Shape;
          circle.name = "circle";
          var radius:Number = 1;
          circle.graphics.beginFill(0x000000);
          circle.graphics.drawCircle(x+recPanel.x, y+recPanel.y, radius);
          recPanel.stage.addChild(circle);
      }
  
      public function handleMouseMove(event:MouseEvent):void
      {
          if (record){
              trace('handleMouseMove'+event.localX+" "+event.localY);
              recordedPoints.push(new Point(event.localX,event.localY));
              drawCircle(event.localX,event.localY);
          }
      }
  
      //recPanel.addEventListener ( MouseEvent.MOUSE_DOWN, handleMouseDown );
      //recPanel.addEventListener ( MouseEvent.MOUSE_UP, handleMouseUp );
      //recPanel.addEventListener ( MouseEvent.MOUSE_MOVE, handleMouseMove );
  
      protected function startBkgd_clickHandler(event:MouseEvent):void
      {
          setCurrentState("RecognizerState");
      }
  
  ]]&gt;&lt;/fx:Script&gt;
  &lt;s:states&gt;
      &lt;s:State name="Title"/&gt;
      &lt;s:State name="RecognizerState"/&gt;
  &lt;/s:states&gt;
  &lt;fx:Declarations&gt;
      &lt;!-- Place non-visual elements (e.g., services, value objects) here --&gt;
  &lt;/fx:Declarations&gt;
  &lt;s:Label includeIn="Title" fontSize="36" horizontalCenter="0" text="Dollar Gesture Recognizer"
           textAlign="center" verticalAlign="middle" verticalCenter="-30"/&gt;
  &lt;s:Label includeIn="Title" fontSize="18" horizontalCenter="0" text=""
           verticalCenter="40"/&gt;
  &lt;s:Panel id="recPanel" includeIn="RecognizerState" left="50" width="400" height="400"
           color="#0B333C" fontSize="24" textAlign="center" title="Gesture Recognizer"
           verticalCenter="0" mouseDown="handleMouseDown(event)" mouseMove="handleMouseMove(event)"
           mouseUp="handleMouseUp(event)"&gt;
  &lt;/s:Panel&gt;
  &lt;s:Panel id="gesPanel" includeIn="RecognizerState" width="300" height="400" fontSize="24"
           horizontalCenter="0" textAlign="center" title="Available Gestures" verticalCenter="0"&gt;
  &lt;/s:Panel&gt;
  &lt;s:Label id="startBkgd" includeIn="Title" x="10" y="10" width="1263" height="591"
           click="startBkgd_clickHandler(event)" /&gt;
  &lt;s:Panel id="resMeme" includeIn="RecognizerState" right="50" width="400" height="400"
           fontSize="24" title="Resulting Meme" verticalCenter="0"&gt;
      &lt;s:Label id="resLabel" x="103" y="165" width="180" text="result" textAlign="center"/&gt;
  &lt;/s:Panel&gt;
  </code></pre>
  
  <p></p>
  
  <p>Recognizer class:</p>
  
  <pre><code>package de.yuv.gestures
  {
  import de.yuv.gestures.Result;
  import de.yuv.gestures.Template;
  
  import flash.geom.Point;
  import flash.geom.Rectangle;
  public class Recognizer {
  
      public static var NumPoints:int = 64;
  
  
      public static var SquareSize:Number = 250.0;
      public static var HalfDiagonal = 0.5 * Math.sqrt(250.0 * 250.0 + 250.0 * 250.0);
      public static var AngleRange = 45.0;
      public static var AnglePrecision = 2.0;
      public static var Phi = 0.5 * (-1.0 + Math.sqrt(5.0)); // Golden Ratio
      public var Templates:Array;
  
  
      public function Recognizer(){
              this.Templates = new Array();
      }
  
      public function recognize(points)
      {
          points = Resample(points, NumPoints);
          points = RotateToZero(points);
          points = ScaleToSquare(points, SquareSize);
          points = TranslateToOrigin(points);
  
          var b = +Infinity;
          var t;
          for (var i = 0; i &lt; this.Templates.length; i++)
          {
              var d = DistanceAtBestAngle(points, this.Templates[i], -AngleRange, +AngleRange, AnglePrecision);
              if (d &lt; b)
              {
                  b = d;
                  t = i;
              }
          }
          var score = 1.0 - (b / HalfDiagonal);
          return new Result(this.Templates[t].Name, score);
      };
      //
      // add/delete new templates
      //
      public function addTemplate(name, points)
      {
          this.Templates[this.Templates.length] = new Template(name, points); // append new template
          var num = 0;
          for (var i = 0; i &lt; this.Templates.length; i++)
          {
              if (this.Templates[i].Name == name)
                  num++;
          }
          return num;
      }
  
  
      // Helper functions
  
      public static function Resample(points, n)
      {
          var I = PathLength(points) / (n - 1); // interval length
          var D = 0.0;
          var newpoints = new Array(points[0]);
          for (var i = 1; i &lt; points.length; i++)
          {
              var d = Distance(points[i - 1], points[i]);
              if ((D + d) &gt;= I)
              {
                  var qx = points[i - 1].x + ((I - D) / d) * (points[i].x - points[i - 1].x);
                  var qy = points[i - 1].y + ((I - D) / d) * (points[i].y - points[i - 1].y);
                  var q = new Point(qx, qy);
                  newpoints[newpoints.length] = q; // append new point 'q'
                  points.splice(i, 0, q); // insert 'q' at position i in points s.t. 'q' will be the next i
                  D = 0.0;
              }
              else D += d;
          }
          // somtimes we fall a rounding-error short of adding the last point, so add it if so
          if (newpoints.length == n - 1)
          {
              newpoints[newpoints.length] = points[points.length - 1];
          }
          return newpoints;
      }
      public static function RotateToZero(points)
      {
          var c = Centroid(points);
          var theta = Math.atan2(c.y - points[0].y, c.x - points[0].x);
          return RotateBy(points, -theta);
      }
  
      public static function ScaleToSquare(points, size)
      {
          var B = BoundingBox(points);
          var newpoints = new Array();
          for (var i = 0; i &lt; points.length; i++)
          {
              var qx = points[i].x * (size / B.width);
              var qy = points[i].y * (size / B.height);
              newpoints[newpoints.length] = new Point(qx, qy);
          }
          return newpoints;
      }           
      public static function TranslateToOrigin(points)
      {
          var c = Centroid(points);
          var newpoints = new Array();
          for (var i = 0; i &lt; points.length; i++)
          {
              var qx = points[i].x - c.x;
              var qy = points[i].y - c.y;
              newpoints[newpoints.length] = new Point(qx, qy);
          }
          return newpoints;
      }
  
      public static function DistanceAtBestAngle(points, T, a, b, threshold)
      {
          var x1 = Phi * a + (1.0 - Phi) * b;
          var f1 = DistanceAtAngle(points, T, x1);
          var x2 = (1.0 - Phi) * a + Phi * b;
          var f2 = DistanceAtAngle(points, T, x2);
          while (Math.abs(b - a) &gt; threshold)
          {
              if (f1 &lt; f2)
              {
                  b = x2;
                  x2 = x1;
                  f2 = f1;
                  x1 = Phi * a + (1.0 - Phi) * b;
                  f1 = DistanceAtAngle(points, T, x1);
              }
              else
              {
                  a = x1;
                  x1 = x2;
                  f1 = f2;
                  x2 = (1.0 - Phi) * a + Phi * b;
                  f2 = DistanceAtAngle(points, T, x2);
              }
          }
          return Math.min(f1, f2);
      }
  
      public static function PathLength(points)
      {
          var d = 0.0;
          for (var i = 1; i &lt; points.length; i++)
              d += Distance(points[i - 1], points[i]);
          return d;
      }
  
      public static function Distance(p1, p2)
      {
          var dx = p2.x - p1.x;
          var dy = p2.y - p1.y;
          return Math.sqrt(dx * dx + dy * dy);
      }
      public static function Centroid(points)
      {
          var x = 0.0, y = 0.0;
          for (var i = 0; i &lt; points.length; i++)
          {
              x += points[i].x;
              y += points[i].y;
          }
          x /= points.length;
          y /= points.length;
          return new Point(x, y);
      }
      public static function RotateBy(points, theta) 
      {
          var c = Centroid(points);
          var cos = Math.cos(theta);
          var sin = Math.sin(theta);
  
          var newpoints = new Array();
          for (var i = 0; i &lt; points.length; i++)
          {
              var qx = (points[i].x - c.x) * cos - (points[i].y - c.y) * sin + c.x
              var qy = (points[i].x - c.x) * sin + (points[i].y - c.y) * cos + c.y;
              newpoints[newpoints.length] = new Point(qx, qy);
          }
          return newpoints;
      }
      public static function BoundingBox(points)
      {
          var minX = +Infinity, maxX = -Infinity, minY = +Infinity, maxY = -Infinity;
          for (var i = 0; i &lt; points.length; i++)
          {
              if (points[i].x &lt; minX)
                  minX = points[i].x;
              if (points[i].x &gt; maxX)
                  maxX = points[i].x;
              if (points[i].y &lt; minY)
                  minY = points[i].y;
              if (points[i].y &gt; maxY)
                  maxY = points[i].y;
          }
          return new Rectangle(minX, minY, maxX - minX, maxY - minY);
      }
  
      public static function DistanceAtAngle(points, T, theta)
      {
          var newpoints = RotateBy(points, theta);
          return PathDistance(newpoints, T.Points);
      }
  
      public static function PathDistance(pts1, pts2)
      {
          var d = 0.0;
          for (var i = 0; i &lt; pts1.length; i++) // assumes pts1.length == pts2.length
              d += Distance(pts1[i], pts2[i]);
          return d / pts1.length;
      }
  }
  </code></pre>
  
  <p>}</p>