public List <UnitPoint> FindPath(UnitPoint startPt, UnitPoint endPt, bool passEndPoint = false)
        {
            if (_pathFinder == null)
            {
                return(null);
            }
            Point pStart = ScreenUtils.ConvertPoint(_canvas.ToScreen(startPt));
            Point pEnd   = ScreenUtils.ConvertPoint(_canvas.ToScreen(endPt));

            if (pStart == pEnd || !EndPointIsValid(pStart) || !EndPointIsValid(pEnd))
            {
                return(null);
            }
            //if the canvas control'size has changed, we need to update the matrix
            if (NeedReconstructMatrix())
            {
                m_pixelMatrix = null;
                Init();
            }
            //-----------------------------------------------------------------------
            #region debug
            bool export = false;
            if (export)
            {
                int nItems = m_pixelMatrix.GetUpperBound(0) + 1;
                int maxX = -1, maxY = -1, minX = 100000, minY = 100000;
                for (int ii = 0; ii < nItems; ++ii)     //row
                {
                    for (int jj = 0; jj < nItems; ++jj) //column
                    {
                        int val = m_pixelMatrix[jj, ii];
                        if (val != 0)
                        {
                            continue;
                        }
                        if (jj < minX)
                        {
                            minX = jj;
                        }
                        if (jj > maxX)
                        {
                            maxX = jj;
                        }
                        if (ii < minY)
                        {
                            minY = ii;
                        }
                        if (ii > maxY)
                        {
                            maxY = ii;
                        }
                    }
                }
                PointF    tmpPt = new PointF(minX, minY);
                UnitPoint pt1   = _canvas.ToUnit(tmpPt);
                tmpPt = new PointF(maxX, maxY);
                UnitPoint pt2 = _canvas.ToUnit(tmpPt);

                for (int ii = 0; ii < nItems; ++ii)
                {
                    for (int jj = 0; jj < nItems; ++jj)
                    {
                        int val = m_pixelMatrix[jj, ii];
                        Console.Write("{0},", val);
                    }
                    Console.Write("\n");
                }
            }
            #endregion
            //-----------------------------------------------------------------------
            _pathFinder.FindPathStop();
            List <PathFinderNode> path = _pathFinder.FindPath(pStart, pEnd);
            if (path == null || path.Count < 1)
            {
                return(null);
            }
            List <PathFinderNode> cornerNodesPath = ExtractConnerNodes(path);
            List <UnitPoint>      allPts          = new List <UnitPoint>();

            PointF ptLeftBottom = PointF.Empty;
            PointF ptRightTop   = PointF.Empty;
            foreach (var tmpNode in cornerNodesPath)
            {
                PointF    pt          = new PointF(tmpNode.X, tmpNode.Y);
                UnitPoint convertedPt = _canvas.ToUnit(pt);
                allPts.Add(convertedPt);
                //get bounding box
                if (ptLeftBottom == PointF.Empty)
                {
                    ptLeftBottom.X = (float)convertedPt.X;
                    ptLeftBottom.Y = (float)convertedPt.Y;
                    ptRightTop.X   = (float)convertedPt.X;
                    ptRightTop.Y   = (float)convertedPt.Y;
                }
                else
                {
                    if (convertedPt.X < ptLeftBottom.X)
                    {
                        ptLeftBottom.X = (float)convertedPt.X;
                    }
                    if (convertedPt.Y < ptLeftBottom.Y)
                    {
                        ptLeftBottom.Y = (float)convertedPt.Y;
                    }
                    if (convertedPt.X > ptRightTop.X)
                    {
                        ptRightTop.X = (float)convertedPt.X;
                    }
                    if (convertedPt.Y > ptRightTop.Y)
                    {
                        ptRightTop.Y = (float)convertedPt.Y;
                    }
                }
            }
            _boundingBox = new RectangleF(ptLeftBottom,
                                          new SizeF(ptRightTop.X - ptLeftBottom.X, ptRightTop.Y - ptLeftBottom.Y));
            List <UnitPoint> snapedPts = SnapToStartEndNodes(allPts, startPt, endPt);
            //List<UnitPoint> snapedPts = allPts;
            return(snapedPts);
        }