public dataElement(XmlElement buildFrom)
        {
            associatedCharacter = buildFrom.Attributes[0].InnerText.ToCharArray()[0];
            cleanedData = new List<mPoint>();
            if (buildFrom.HasChildNodes)
            {
                XmlNodeList points = buildFrom.ChildNodes;

                foreach (XmlNode point in points)
                {
                    mPoint temp = new mPoint(Double.Parse(point.Attributes[0].Value), Double.Parse(point.Attributes[1].Value), int.Parse(point.Attributes[2].Value));
                    cleanedData.Add(temp);
                }
            }
        }
 public abstract void updateData(mPoint newPoint);
 public int getDirection(mPoint a, mPoint b)
 {
     int output = 0;
     /*
      * 0: invalid
      * 1: up
      * 2: down
      * 3: left
      * 4: right
      * 5: up-left
      * 6: up-right
      * 7: down-left
      * 8: down-right
      */
     if (a.X == b.X && withLines)
     {
         //up or down
         if (a.Y == b.Y)
         {
             //no Y change
             output = 0;
         }
         else if (a.Y > b.Y)
         {
             //down
             output = 2;
         }
         else if (a.Y < b.Y)
         {
             //up
             output = 1;
         }
     }
     else if (a.X < b.X)
     {
         //going right
         if (a.Y == b.Y && withLines)
         {
             //no Y change
             output = 4;
         }
         else if (a.Y >= b.Y)
         {
             //down
             output = 8;
         }
         else if (a.Y < b.Y)
         {
             //up
             output = 6;
         }
     }
     else if (a.X >= b.X)
     {
         //going left
         if (a.Y == b.Y && withLines)
         {
             //no Y change
             output = 3;
         }
         else if (a.Y >= b.Y)
         {
             //down
             output = 5;
         }
         else if (a.Y < b.Y)
         {
             //up
             output = 7;
         }
     }
     return output;
 }
 protected double distanceIgnoreLine(mPoint a, mPoint b)
 {
     return Math.Sqrt(Math.Pow((a.X - b.X), 2) + Math.Pow((a.Y - b.Y), 2));
 }
 private double distance(mPoint a, mPoint b)
 {
     double deltaX = b.X - a.X;
     double deltaY = b.Y - a.Y;
     return Math.Sqrt((deltaX * deltaX) + (deltaY * deltaY));
 }
 private double lineDistance(mPoint a, mPoint b, mPoint c)
 {
     //a and b make line, return distance c from line
     double uX = b.X - a.X;
     double uY = b.Y - a.Y;
     double vX = c.X - a.X;
     double vY = c.Y - a.Y;
     double val = ((uX * vX) + (uY * vY)) / ((uX * uX) + (uY * uY));
     mPoint other = new mPoint(uX * val + a.X, uY * val + a.Y, c.line);
     double output = double.PositiveInfinity;
     if (val >= 0.0 && val <= 1.0)
     {
         output = distance(c, other);
     }
     return output;
 }
        private void addingToSampled(mPoint adding, double minDistance)
        {
            if (scaling == null)
            {
                scaling = new List<mPoint>();
            }
            if (resampling == null)
            {
                resampling = new List<mPoint>();
            }

            bool changed = addToScale(adding, scaling);

            if (scaling.Count > 1 && resampling.Count > 1)
            {
                int startPos = 1;
                List<mPoint> data = new List<mPoint>(scaling);
                double bigD = 0;
                double lilD = 0;
                List<mPoint> output = new List<mPoint>();

                if (!changed)
                {
                    startPos = data.Count - 1;
                    output = new List<mPoint>(resampling);
                    mPoint a = output[output.Count - 2], b = output[output.Count - 1], c = data[startPos];
                    bigD = distance(a, b);
                    lilD = distance(b, c);
                    output.RemoveAt(output.Count - 1);
                    if (b.line != c.line || a.line != b.line)
                    {
                        output.Add(b);
                    }
                    else if (bigD > minDistance)
                    {
                        output.Add(b);
                    }
                    else if (bigD + lilD > minDistance)
                    {
                        mPoint temp = new mPoint((b.X + ((minDistance - bigD) / lilD) * (c.X - b.X)),
                            (b.Y + ((minDistance - bigD) / lilD) * (c.Y - b.Y)),
                            c.line);
                        output.Add(temp);
                    }
                    output.Add(c);
                }
                else
                {
                    output.Add(data[0]);
                    for (int i = startPos; i < data.Count; i++)
                    {
                        lilD = distance(data[i], data[i - 1]);
                        if (bigD + lilD > minDistance)
                        {
                            mPoint temp = new mPoint((data[i - 1].X + ((minDistance - bigD) / lilD) * (data[i].X - data[i - 1].X)),
                                (data[i - 1].Y + ((minDistance - bigD) / lilD) * (data[i].Y - data[i - 1].Y)),
                                data[i].line);
                            output.Add(temp);
                            data.Insert(i, temp);
                            bigD = 0;
                        }
                        else
                        {
                            if (lilD == 0 || i == data.Count - 1)
                            {
                                bigD = 0;
                                output.Add(data[i]);
                            }
                            bigD += lilD;
                        }
                    }
                }

                resampling = new List<mPoint>(output);
            }
            else
            {
                resampling = new List<mPoint>(scaling);
            }
        }
        public int getDirection(mPoint a, mPoint b)
        {
            int output = 0;
            /*
             * 0: invalid
             * 1: right
             * 2: up-right
             * 3: up
             * 4: up-left
             * 5: left
             * 6: down-left
             * 7: down
             * 8: down-right
             */
            if (a.line == b.line)
            {
                //the vector values

                double X = b.X - a.X;
                double Y = b.Y - a.Y;
                output = smartFitTo45(X, Y);
            }
            return output;
        }
 private double xChange(mPoint a, mPoint b)
 {
     return (a.X - b.X);
 }
        private List<mPoint> resample(List<mPoint> data, double spaceBetweenPoints)
        {
            if (length(data) > 3 * spaceBetweenPoints)
            {
                double bigD = 0;
                double lilD = 0;
                List<mPoint> output = new List<mPoint>();
                output.Add(data[0]);
                for (int i = 1; i < data.Count; i++)
                {
                    lilD = distance(data[i], data[i - 1]);
                    if (bigD + lilD > spaceBetweenPoints)
                    {
                        mPoint temp = new mPoint((data[i - 1].X + ((spaceBetweenPoints - bigD) / lilD) * (data[i].X - data[i - 1].X)),
                            (data[i - 1].Y + ((spaceBetweenPoints - bigD) / lilD) * (data[i].Y - data[i - 1].Y)),
                            data[i].line);
                        output.Add(temp);
                        data.Insert(i, temp);
                        bigD = 0;
                    }
                    else
                    {
                        if (lilD == 0 || i == data.Count - 1)
                        {
                            bigD = 0;
                            output.Add(data[i]);
                        }
                        bigD += lilD;
                    }
                }

                return output;
            }
            else { return data; }
        }
 private double lineDistance(mPoint a, mPoint b, mPoint c)
 {
     //a and b make line, return distance c from line
     Point u = new Point(b.X - a.X, b.Y - a.Y);
     Point v = new Point(c.X - a.X, c.Y - a.Y);
     double value = dotProduct(u, v) / dotProduct(u, u);
     Point p = new Point(u.X * value + a.X, u.Y * value + a.Y);
     double output = double.PositiveInfinity;
     if (value >= 0.0 && value <= 1.0) {
         output = distance(c, new mPoint(p, c.line));
     }
     return output;
 }
        private int getDirection(mPoint startPoint, mPoint endPoint)
        {
            /*
             * 0: up
             * 1: down
             * 2: left
             * 3: right
             * 4: up-left
             * 5: up-right
             * 6: down-left
             * 7: down-right
             */
            int direction = -1;
            double deltaX = xChange(startPoint, endPoint);
            double deltaY = yChange(startPoint, endPoint);

            if (deltaY < 0)
            {
                //up
                if (deltaX > 0)
                {
                    //right
                    direction = 5;
                }
                else
                {
                    //left
                    direction = 4;
                }
            }
            else
            {
                //down
                if (deltaX > 0)
                {
                    //right
                    direction = 7;
                }
                else
                {
                    //left
                    direction = 6;
                }
            }

            return direction;
        }
 private double distance(mPoint a, mPoint b)
 {
     return Math.Sqrt(Math.Pow((a.X - b.X), 2) + Math.Pow((a.Y - b.Y), 2));
 }
        public List<mPoint> scaleList(List<mPoint> data)
        {
            double newScale;
            bool worked = true;
            double xMin = double.PositiveInfinity, yMin = double.PositiveInfinity, xMax = 0, yMax = 0;
            List<mPoint> output = new List<mPoint>();
            if (data.Count > 1)
            {
                for (int i = 0; i < data.Count; i++)
                {
                    if (xMin > data[i].X) { xMin = data[i].X; }
                    if (yMin > data[i].Y) { yMin = data[i].Y; }

                    if (xMax < data[i].X) { xMax = data[i].X; }
                    if (yMax < data[i].Y) { yMax = data[i].Y; }
                }
                newScale = (xMax - xMin);
                if (yMax - yMin > newScale) { newScale = yMax - yMin; }
                worked = !double.IsNaN(newScale) && !double.IsInfinity(newScale) && newScale != 0.0;
                for (int i = 0; i < data.Count && worked; i++)
                {
                    mPoint temp = new mPoint(((data[i].X - xMin) / newScale), ((data[i].Y - yMin) / newScale), data[i].line);
                    output.Add(temp);
                }
            }
            else { worked = false; }

            if (!worked)
            {
                output = data;
            }

            return output;
        }
 protected double distance(mPoint a, mPoint b)
 {
     double output = 0;
     if (a.line == b.line)
     {
         output = Math.Sqrt(Math.Pow((a.X - b.X), 2) + Math.Pow((a.Y - b.Y), 2));
     }
     return output;
 }
        public override void updateData(mPoint newPoint)
        {
            double minDistance = .1;
            /*
             * 0 is rescaling
             * 1 is the other thing
             */

            //add new point
            elapsedTime[0] += Time(() =>
            {
                addingToSampled(newPoint, minDistance);
            });
            //display the resampled data
            if (resampleID >= 0)
            {
                core.TextBreakDown[resampleID].newData(new List<mPoint>(resampling));
                core.TextBreakDown[resampleID].titleText = TAG + " Resample: " + core.originalData.Count + "\nTo: " + resampling.Count + "\nTime: " + (elapsedTime[0].TotalMilliseconds);
            }

            //Current Unique Stuff

            //get sections
            List<mPoint> cleaned = new List<mPoint>();
            elapsedTime[1] += Time(() =>
            {
                cleaned = cleanSections(Sections(new List<mPoint>(resampling)));
            });
            if (sectionsID >= 0)
            {
                core.TextBreakDown[sectionsID].newData(new List<mPoint>(cleaned));
                core.TextBreakDown[sectionsID].titleText = TAG + " Sections: " + core.originalData.Count + "\nTo: " + cleaned.Count + "\nTotal Time: " + ((elapsedTime[0]).TotalMilliseconds + (elapsedTime[1]).TotalMilliseconds);
            }

            if (myTree != null && guessOutputID >= 0)
            {
                Tuple<String, String> results = new Tuple<string, string>("", "");
                List<Tuple<String, int>> breakdown = null;
                elapsedTime[2] += Time(() =>
                {
                    breakdown = (getSectionBreakDown(resampling));
                    results = myTree.getTotalString(myTree.searchTree(breakdown));
                });
                String thisGuess = "";
                for (int i = 0; breakdown != null && i < breakdown.Count; i++)
                {
                    thisGuess += breakdown[i].Item1 + " " + breakdown[i].Item2;
                    if (i < breakdown.Count - 1)
                    {
                        thisGuess += " , ";
                    }
                }
                core.guessOutput.updateGuess(guessOutputID,
                    TAG + " guess:" +
                    "\n" + thisGuess +
                    "\nPossible letters: " + results.Item1 +
                    "\nCurrent Guess: " + results.Item2 +
                    "\nTotal time: " + (elapsedTime[0].TotalMilliseconds + elapsedTime[2].TotalMilliseconds));
            }
        }
 private double yChange(mPoint a, mPoint b)
 {
     return (a.Y - b.Y);
 }
        public override void updateData(mPoint nextPoint)
        {
            double minDistance = .1;
            int timeId = 0;
            /*
             * 0 is rescaling
             * 1 is the other thing
             */

            //add new point
            elapsedTime[timeId] += Time(() =>
            {
                addingToSampled(nextPoint, minDistance);
            });
            //display the resampled data
            if (resampleID >= 0)
            {
                core.TextBreakDown[resampleID].newData(new List<mPoint>(resampling));
                core.TextBreakDown[resampleID].titleText = TAG + " Resample: " + core.originalData.Count + "\nTo: " + resampling.Count + "\nTime: " + (elapsedTime[timeId].TotalMilliseconds);
            }

            //Current Unique Stuff

            //get sections
            timeId = 1;
            List<mPoint> cleaned = new List<mPoint>();
            elapsedTime[timeId] += Time(() =>
            {
                cleaned = Sections(new List<mPoint>(resampling));
            });
            if (sectionsID >= 0)
            {
                core.TextBreakDown[sectionsID].newData(new List<mPoint>(cleaned));
                core.TextBreakDown[sectionsID].titleText = TAG + " Sections: " + core.originalData.Count + "\nTo: " + cleaned.Count + "\nTime: " + (elapsedTime[timeId]).TotalMilliseconds;
            }
        }
        private Tuple<List<mPoint>, char> getDataElement(XmlElement xmlement)
        {
            char associatedChar = xmlement.Attributes[0].InnerText.ToCharArray()[0];
            List<mPoint> data = new List<mPoint>();
            if (xmlement.HasChildNodes)
            {
                XmlNodeList points = xmlement.ChildNodes;

                foreach (XmlNode point in points)
                {
                    mPoint temp = new mPoint(Double.Parse(point.Attributes[0].Value), Double.Parse(point.Attributes[1].Value), int.Parse(point.Attributes[2].Value));
                    data.Add(temp);
                }
            }
            return new Tuple<List<mPoint>,char>(data, associatedChar);
        }
        private bool addToScale(mPoint adding, List<mPoint> addTo)
        {
            if (addTo.Count == 0)
            {
                minX = adding.X;
                minY = adding.Y;
                scale = 1.0;
            }

            bool changed = false;

            double yToAdd = 0.0, xToAdd = 0.0;

            if (minY > adding.Y)
            {
                yToAdd = (minY - adding.Y) / scale;
                minY = adding.Y;
                changed = true;
            }

            if (minX > adding.X)
            {
                xToAdd = (minX - adding.X) / scale;
                minX = adding.X;
                changed = true;
            }

            mPoint newPoint = new mPoint((adding.X - minX) / scale, (adding.Y - minY) / scale, adding.line);

            bool changeFromMax = !changed;
            bool newScaleX = true;
            if (!changed)
            {
                if (newPoint.X > newPoint.Y && newPoint.X > 1)
                {
                    changed = true;
                    newScaleX = true;
                }
                else if (newPoint.Y > newPoint.X && newPoint.Y > 1)
                {
                    changed = true;
                    newScaleX = false;
                }
            }

            addTo.Add(newPoint);

            if (changed)
            {
                double max = double.NegativeInfinity;

                for (int i = 0; i < addTo.Count; i++)
                {
                    if (i != addTo.Count - 1)
                    {
                        addTo[i].X += xToAdd;
                    }
                    if (i != addTo.Count - 1)
                    {
                        addTo[i].Y += yToAdd;
                    }
                    if (!changeFromMax)
                    {
                        if (max < addTo[i].X)
                        {
                            max = addTo[i].X;
                        }
                        if (max < addTo[i].Y)
                        {
                            max = addTo[i].Y;
                        }
                    }
                    else if (newScaleX)
                    {
                        if (max < addTo[i].X)
                        {
                            max = addTo[i].X;
                        }
                    }
                    else
                    {
                        if (max < addTo[i].Y)
                        {
                            max = addTo[i].Y;
                        }
                    }
                }

                for (int i = 0; i < addTo.Count; i++)
                {
                    addTo[i].X /= max;
                    addTo[i].Y /= max;
                }
                scale *= max;
            }

            return changed;
        }
        public int getDirectionIgnoreLine(mPoint a, mPoint b)
        {
            /* except scale is backwards so up <=> down
             * 0: invalid
             * 1: right
             * 2: up-right
             * 3: up
             * 4: up-left
             * 5: left
             * 6: down-left
             * 7: down
             * 8: down-right
             */
            //the vector values

            double X = b.X - a.X;
            double Y = b.Y - a.Y;
            return smartFitTo45(X, Y);
        }
 private mPoint roundedPoint(mPoint input, double toRound)
 {
     return new mPoint(RoundToNearest(input.X, toRound), RoundToNearest(input.Y, toRound), input.line);
 }
        public List<mPoint> getSections2(List<mPoint> input)
        {
            //create list of points and their directions
            List<mPoint> points = new List<mPoint>();
            if (input.Count > 2)
            {
                int sLoc = 0;
                double initialRound = .05;
                double unitScale = .01;
                List<double> lengths = new List<double>();
                List<int> directions = new List<int>();
                List<mPoint> newLinePoints = new List<mPoint>();
                newLinePoints.Add(input[0]);
                double unitLength = 0;

                int sDir = getDirectionCircular(input[0], input[1]);
                for (int i = 0; i < (input.Count - 1); i++)
                {
                    bool sameSlope = input[sLoc].line == input[i + 1].line && sDir == getDirectionCircular(input[i], input[i + 1]);
                    if (!sameSlope)
                    {
                        if (input[sLoc].line == input[i].line)
                        {
                            double length = distance(input[sLoc], input[i]);
                            if (unitLength == 0)
                            {
                                unitLength = RoundToNearest(length, initialRound);
                            }
                            else
                            {
                                length = RoundToNearest(length, unitScale * unitLength);
                            }
                            lengths.Add(length);
                            directions.Add(sDir);
                        }
                        else
                        {
                            //assume lenght of line would never be negative;
                            lengths.Add(-1);
                            directions.Add(-1);
                            newLinePoints.Add(input[i]);
                        }

                        sLoc = i;
                        sDir = getDirectionCircular(input[sLoc], input[sLoc + 1]);
                    }
                }

                double length2 = distance(input[sLoc], input[input.Count - 1]);
                if (unitLength == 0)
                {
                    unitLength = RoundToNearest(length2, initialRound);
                }
                else
                {
                    length2 = RoundToNearest(length2, unitScale * unitLength);
                }
                lengths.Add(length2);
                directions.Add(sDir);

                int lineAt = 0;
                mPoint lastPoint = newLinePoints[lineAt];
                points.Add(lastPoint);

                for (int i = 0; i < lengths.Count; i++)
                {
                    if (lengths[i] >= 0)
                    {
                        double angle = degreesToRadians((directions[i] - 1) * 45.0);
                        double newX = (Math.Cos(angle) * lengths[i]) + lastPoint.X;
                        double newY = (Math.Sin(angle) * lengths[i]) + lastPoint.Y;

                        mPoint thisPoint = new mPoint(newX, newY, lineAt);
                        points.Add(thisPoint);
                        lastPoint = thisPoint;
                    }
                    else
                    {
                        lineAt++;
                        lastPoint = newLinePoints[lineAt];
                        lastPoint.line = lineAt;
                        points.Add(lastPoint);
                    }
                }
            }
            else
            {
                points = input;
            }
            return points;
        }