private void btnApplyTransformation_Click(object sender, EventArgs e)
        {
            Transformation align = LLSOTransform.ComputeTransformation(Shape1, Shape2);

            MessageBox.Show("Cost = " + LLSOTransform.ComputeCost(Shape1, Shape2, align).ToString());
            List <Point> Shape2Transformed = ApplyTransformation(align, Shape2);
            Pen          pRed  = new Pen(Brushes.Red, 1);
            Pen          pBlue = new Pen(Brushes.Blue, 1);
            Graphics     g     = panTransformed.CreateGraphics();

            DisplayShape(Shape1, pBlue, g);
            DisplayShape(Shape2Transformed, pRed, g);
        }
        List <Point>[] ExhaustiveEvaluation()
        {
            List <Point>   Shape1Temp;
            List <Point>   Shape2Temp;
            List <Point>   Shape1NoOutliers = new List <Point>(Shape1);
            List <Point>   Shape2NoOutliers = new List <Point>(Shape2);
            Transformation transform        = LLSOTransform.ComputeTransformation(Shape1, Shape2);
            double         prevcost         = LLSOTransform.ComputeCost(Shape1, Shape2, transform);
            double         costwithoutI     = 0;
            int            count            = Shape1NoOutliers.Count;
            int            i = 0;

            while (i < count)
            {
                Shape1Temp = new List <Point>(Shape1NoOutliers);
                Shape2Temp = new List <Point>(Shape2NoOutliers);
                Shape1Temp.RemoveAt(i);
                Shape2Temp.RemoveAt(i);
                transform    = LLSOTransform.ComputeTransformation(Shape1Temp, Shape2Temp);
                costwithoutI = LLSOTransform.ComputeCost(Shape1Temp, Shape2Temp, transform);
                //MessageBox.Show("New Cost = " + costwithoutI.ToString());
                if (costwithoutI < (prevcost * 0.8))
                {
                    Shape1NoOutliers.RemoveAt(i);
                    Shape2NoOutliers.RemoveAt(i);
                    Shape2NoOutliers = ApplyTransformation(transform, Shape2NoOutliers);
                    i--;//since every element with greater index is moved to the rigth
                    count--;
                    prevcost = costwithoutI;
                    MessageBox.Show("New Cost = " + costwithoutI.ToString());
                }
                i++;
            }
            List <Point>[] shapesNoOutliers = { Shape1NoOutliers, Shape2NoOutliers };
            return(shapesNoOutliers);
        }
        List <Point>[] Ransac(int minPointsNum, int iterNum, double threshold, int requiredPointsNum, out Transformation bestModel)
        {
            //data is Shape1, Shape2 globally accessible
            bestModel = new Transformation();
            List <Point>[] bestConsensusSet = new List <Point> [2];
            double         bestError        = 10000;
            int            iteration        = 0;

            List <Point>[] maybeInliers  = new List <Point> [2];
            List <Point>[] maybeOutliers = new List <Point> [2];
            Transformation maybeModel    = new Transformation();

            List <Point>[] consensusSet = new List <Point> [2];
            Random         random       = new Random();

            while (iteration < iterNum)
            {
                maybeOutliers[0] = new List <Point>(Shape1);
                maybeOutliers[1] = new List <Point>(Shape2);
                maybeInliers[0]  = new List <Point>();
                maybeInliers[1]  = new List <Point>();
                int[] intArray = Enumerable.Range(0, Shape1.Count).OrderBy(t => random.Next()).Take(minPointsNum).ToArray();//Range(start,countOfElem)
                foreach (int x in intArray)
                {
                    maybeInliers[0].Add(Shape1[x]);
                    maybeInliers[1].Add(Shape2[x]);
                    maybeOutliers[0].Remove(Shape1[x]);
                    maybeOutliers[1].Remove(Shape2[x]);
                }
                maybeModel      = LLSOTransform.ComputeTransformation(maybeInliers[0], maybeInliers[1]);
                consensusSet[0] = new List <Point>(maybeInliers[0]);
                consensusSet[1] = new List <Point>(maybeInliers[1]);
                //for every point in data not in maybe_inliers, meaning is in maybe_outliers
                for (int i = 0; i < maybeOutliers[0].Count; i++)
                {
                    if (LLSOTransform.ComputeCost(maybeOutliers[0][i], maybeOutliers[1][i], maybeModel) < threshold)
                    {
                        consensusSet[0].Add(maybeOutliers[0][i]);
                        consensusSet[1].Add(maybeOutliers[1][i]);
                    }
                }
                if (consensusSet[0].Count > requiredPointsNum)
                {
                    //implies that we may have found a good model, now test how good it is
                    Transformation better_model = LLSOTransform.ComputeTransformation(consensusSet[0], consensusSet[1]);
                    double         thisError    = LLSOTransform.ComputeCost(consensusSet[0], consensusSet[1], better_model);
                    if (thisError < bestError)
                    {
                        //we have found a model which is better than any of the previous ones
                        bestModel.A  = better_model.A;
                        bestModel.B  = better_model.B;
                        bestModel.T1 = better_model.T1;
                        bestModel.T2 = better_model.T2;
                        //sort consensus set accoring to inital shape order of connections
                        bestConsensusSet[0] = consensusSet[0].OrderBy(item => Shape1.IndexOf(item)).ToList();
                        bestConsensusSet[1] = consensusSet[1].OrderBy(item => Shape2.IndexOf(item)).ToList();
                        bestError           = thisError;
                    }
                }
                iteration++;
            }
            MessageBox.Show("New Cost = " + bestError.ToString());
            return(bestConsensusSet);
        }