/// <summary>
 /// Creates a new detection result
 /// </summary>
 /// <param name="marker">A reference to the found marker.</param>
 /// <param name="confidence">The confidence / quality  of the result.</param>
 /// <param name="transformation">The transformation matrix for the marker.</param>
 /// <param name="square">The pixel coordinates where the square marker was found. </param>
 public DetectionResult(Marker marker, double confidence, Matrix3D transformation, Square square)
 {
    this.Marker          = marker;
    this.Confidence      = confidence;
    this.Transformation  = transformation;
    this.Square          = square;
 }
      /// <summary>
      /// Listener method called when something was detected.
      /// </summary>
      /// <param name="callingDetector">The detector that called the method.</param>
      /// <param name="coordsX">The four x coordinates of the detected marker square.</param>
      /// <param name="coordsY">The four y coordinates of the detected marker square.</param>
      /// <param name="coordCount">The number of coordinates.</param>
      /// <param name="coordIndices">The indices of the coordiantes in the coords array.</param>
      public void onSquareDetect(NyARSquareContourDetector callingDetector, int[] coordsX, int[] coordsY, int coordCount, int[] coordIndices)
      {
         // Init variables            
         points[0].x = coordsX[coordIndices[0]];
         points[0].y = coordsY[coordIndices[0]];
         points[1].x = coordsX[coordIndices[1]];
         points[1].y = coordsY[coordIndices[1]];
         points[2].x = coordsX[coordIndices[2]];
         points[2].y = coordsY[coordIndices[2]];
         points[3].x = coordsX[coordIndices[3]];
         points[3].y = coordsY[coordIndices[3]];

         // Evaluate and find best match
         if (this.colorPattern.pickFromRaster(this.Buffer, points))
         {
            // Find best matching marker
            this.patternMatchDeviationData.setRaster(this.colorPattern);
            Marker foundMarker = null;
            int foundDirection = NyARMatchPattResult.DIRECTION_UNKNOWN;
            double bestConfidence = 0;

            foreach (var patMat in patternMatchers)
            {
               // Evaluate
               patMat.evaluate(this.patternMatchDeviationData, evaluationResult);

               // Best match?
               if (evaluationResult.confidence > bestConfidence)
               {
                  foundMarker = patMat.Marker;
                  foundDirection = evaluationResult.direction;
                  bestConfidence = evaluationResult.confidence;
               }
            }

            // Calculate found marker square
            var square = new NyARSquare();
            var len = coordIndices.Length;
            for (int i = 0; i < len; i++)
            {
               int idx = (i + len - foundDirection) % len;
               this.coordinationMapper.coord2Line(coordIndices[idx], coordIndices[(idx + 1) % len], coordsX, coordsY, coordCount, square.line[i]);
            }
            // Calculate normal
            for (int i = 0; i < len; i++)
            {
               NyARLinear.crossPos(square.line[i], square.line[(i + 3) % len], square.sqvertex[i]);
            }

            // Calculate matrix using continued mode
            if (foundMarker != null)
            {
               var nymat = new NyARTransMatResult();
               matrixCalculator.transMatContinue(square, foundMarker.RectOffset, nymat);

               // Create and add result to collection
               var v = square.sqvertex;
               var resultSquare = new Square(v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, v[3].x, v[3].y);
               Results.Add(new DetectionResult(foundMarker, bestConfidence, nymat.ToMatrix3D(), resultSquare));
            }
         }
      }