Пример #1
0
        /// <summary>
        /// Determines if the given Point is near any of the lines in
        /// Lines.LinesList. Sets HitLine to the first found or null if
        /// none found.
        /// </summary>
        /// <param name="point">The input point in PictureBox coordinates.</param>
        /// <returns>If found.</returns>
        public bool hitTestLine(Point point)
        {
            if (ActiveMode != Mode.EDIT)
            {
                return(false);
            }
            Point imgPoint = imagePoint(point);
            bool  res;

            HitLine  = null;
            HitPoint = null;
            Debug.WriteLine("hitTestLine: ActiveMode=" + ActiveMode
                            + " ZoomFactor=" + ZoomFactor + NL
                            + "    point=" + point + " imgPoint=" + imgPoint + NL
                            + "    LINE_WIDTH=" + LINE_WIDTH + " HIT_TOLERANCE=" + HIT_TOLERANCE);
            foreach (Line line in Lines.LinesList)
            {
                // First check the points
                // (Tolerance does not extend past the ends as it does transverse.)
                Region region;
                foreach (Point point1 in line.Points)
                {
                    region = new Region(centeredSquare(point1, HIT_TOLERANCE));
                    res    = region.IsVisible(imgPoint);
                    if (res)
                    {
                        HitPoint = new HitPoint(line, line.Points.IndexOf(point1));
                        HitLine  = line;
                        return(true);
                    }
                }
                // Then check the lines.
                using (var path = new GraphicsPath())
                    using (var pen = new Pen(Color.Black, HIT_TOLERANCE)) {
                        for (int i = 1; i < line.NPoints; i++)
                        {
                            path.AddLine(line.Points[i - 1], line.Points[i]);
                        }
                        res = path.IsOutlineVisible(imgPoint, pen);
                        if (res)
                        {
                            HitLine = line;
                            return(true);
                        }
                    }
            }
            return(false);
        }
Пример #2
0
        /// <summary>
        /// Adds a point to the HitLine after the point corresponding to the
        /// given Point and located between it and the next point at a distance
        /// depending on the ratio of the distances between those points and
        /// the diven point. If there is only one point in the line nothing will be done.
        /// </summary>
        /// <param name="point"></param>
        public void addPoint(Point point)
        {
            if (HitLine == null)
            {
                return;
            }
            Point        imgPoint = imagePoint(point);
            List <Point> points   = HitLine.Points;
            int          count    = points.Count;

            // Be sure there is more than one point
            if (count <= 1)
            {
                return;
            }
            Point lineStart = INVALID_POINT;
            bool  res;
            // First check the points
            // (Tolerance does not extend past the ends as it does transverse.)
            Region region;

            foreach (Point point1 in points)
            {
                region = new Region(centeredSquare(point1, HIT_TOLERANCE));
                res    = region.IsVisible(imgPoint);
                if (res)
                {
                    lineStart = point1;
                    break;
                }
            }
            // Then check the lines.
            if (lineStart == INVALID_POINT)
            {
                for (int i = 1; i < HitLine.NPoints; i++)
                {
                    using (var path = new GraphicsPath())
                        using (var pen = new Pen(Color.Black, HIT_TOLERANCE)) {
                            path.AddLine(points[i - 1], points[i]);
                            res = path.IsOutlineVisible(imgPoint, pen);
                            if (res)
                            {
                                lineStart = HitLine.Points[i - 1];
                                break;
                            }
                        }
                }
            }
            if (lineStart == INVALID_POINT)
            {
                return;
            }
            int indexStart = points.IndexOf(lineStart);

            if (indexStart == count - 1)
            {
                indexStart--;
            }
            if (points.IndexOf(lineStart) == count - 1)
            {
                lineStart = points[count - 2];
            }
            Point  lineEnd    = points[indexStart + 1];
            double distance12 = lineLength(lineStart, lineEnd);
            double distance01 = lineLength(lineStart, imgPoint);
            double distance02 = lineLength(imgPoint, lineEnd);
            double ratio;

            if (distance01 == 0 && distance02 == 0)
            {
                ratio = 0;
            }
            else
            {
                ratio = distance01 / (distance01 + distance02);
            }
            int   x2       = (int)Math.Round(lineStart.X + ratio * (lineEnd.X - lineStart.X));
            int   y2       = (int)Math.Round(lineStart.Y + ratio * (lineEnd.Y - lineStart.Y));
            Point newPoint = new Point(x2, y2);
            int   newIndex = indexStart + 1;

            points.Insert(indexStart + 1, newPoint);
            HitPoint = new HitPoint(HitLine, newIndex);
        }