private void drawStr(Graphics g, String str, MyPoint p, float fontSize, Color fontColor)
        {
            MyPoint offset = new MyPoint((float)(-fontSize * 0.05), (float)(-fontSize * 0.17));

            g.DrawString(str, new Font("宋体", fontSize), new SolidBrush(fontColor), p.add(new MyPoint(-fontSize / 2, -fontSize / 2)).add(offset).toPointF());
        }
 private void drawLine(Graphics g, MyPoint from, MyPoint to, Color color)
 {
     g.DrawLine(new Pen(color), from.toPointF(), to.toPointF());
 }
 public MyPoint sub(MyPoint p)
 {
     return(new MyPoint(this.X - p.X, this.Y - p.Y));
 }
 public MyPoint add(MyPoint p)
 {
     return(new MyPoint(this.X + p.X, this.Y + p.Y));
 }
 public int push(MyPoint p)
 {
     values.Add(p);
     return(values.Count);
 }
 private MyPoint pointMulti(MyPoint p, double t)
 {
     return(new MyPoint(p.X * t, p.Y * t));
 }
        //************helpful math function*************
        private ArrayOfPoints createPoints(char[] seqs, char[] matches)
        {
            log("creating points....");
            ArrayOfPoints points = new ArrayOfPoints();
            int           loopL = -1, loopR = -1;
            int           tailL, tailR;
            int           l, r;

            l = 0; r = matches.Length - 1;

            while (l < r && matches[l] != '1')
            {
                l++;
            }

            if (l < r)
            {
                log("contain both 1 and 0");

                while (l < r && matches[r] != '1')
                {
                    r--;
                }

                tailL = l;
                tailR = r;
                //
                loopL = l;
                loopR = r;
                while (l < r)
                {
                    l++;
                    while (l < r && matches[l] != '1')
                    {
                        l++;
                    }
                    if (l == r)
                    {
                        break;
                    }
                    loopL = l;
                    r--;
                    while (matches[r] != '1')
                    {
                        r--;
                    }
                }
                loopR = r;
                l     = loopL;
                log("loopL:" + loopL);
                log("loopR:" + loopR);
                log("tailL:" + tailL);
                log("tailR:" + tailR);

                //
                arrayFill(createLoop(r - l + 1), points, l);
                log("len of loop:" + (r - l + 1));
                ArrayOfPoints leftPoints;
                ArrayOfPoints rightPoints;
                while (true)
                {
                    for (l = loopL - 1; l >= tailL; l--)
                    {
                        if (matches[l] == '1')
                        {
                            break;
                        }
                    }
                    for (r = loopR + 1; r <= tailR; r++)
                    {
                        if (matches[r] == '1')
                        {
                            break;
                        }
                    }
                    if (matches[l] != '1')
                    {
                        break;
                    }
                    //
                    leftPoints  = createSideLoop(loopL - l + 1);
                    leftPoints  = arrayMultiP(leftPoints, new MyPoint(-1, 1));
                    rightPoints = createSideLoop(r - loopR + 1);
                    //
                    double heightL = arrayGetHeight(leftPoints);
                    double heightR = arrayGetHeight(rightPoints);
                    if (heightL < heightR)
                    {
                        leftPoints = arrayMultiP(leftPoints, new MyPoint(1, heightR / heightL));
                    }
                    else if (heightL > heightR)
                    {
                        rightPoints = arrayMultiP(rightPoints, new MyPoint(1, heightL / heightR));
                    }
                    //
                    arrayFill(arrayAdd(leftPoints, points[loopL]).reverse(), points, l);
                    arrayFill(arrayAdd(rightPoints, points[loopR]), points, loopR + 1);
                    //
                    loopL = l;
                    loopR = r;
                    if (loopR == tailR)
                    {
                        break;
                    }
                }

                leftPoints  = createLine(tailL + 1);
                leftPoints  = arrayMultiP(leftPoints, new MyPoint(-1, 1));
                rightPoints = createLine(matches.Length - tailR);
                //
                arrayFill(arrayAdd(leftPoints, points[loopL]).reverse(), points, 0);
                arrayFill(arrayAdd(rightPoints, points[loopR]), points, tailR + 1);
                //
            }
            else
            {
                log("contain only 0");
                points[0] = new MyPoint(0, 0);
                arrayFill(createLine(matches.Length), points, 1);
            }
            log("created points:" + points);
            return(points);
        }