Найти LineSegment, который содержит точку - PullRequest
0 голосов
/ 26 августа 2010

У меня есть Path, и когда пользователь нажимает на сегмент, я должен разделить его на два сегмента.

У меня есть точка, где пользователь щелкает, но я не могу найти метод для получения LineSegment, который содержит эту точку.

Мне не нужно находить элемент Path ... но нажата LineSegment коллекции сегментов, которые создают PathGeometry пути.

Как я могу это сделать?

Ответы [ 4 ]

2 голосов
/ 26 августа 2010

У меня есть код, который делает это.Каждая из моих точек хранится в коллекции Points, а не в виде LineSegments, но я думаю, что она должна работать для вас.Параметр толщины - это толщина линии.

    public int HitTestSegments(Point point, double thickness)
    {
        for (int i = 0; i < Points.Count; ++i)
        {
            Point p0 = Points[i];
            Point p1 = (i + 1 < Points.Count) ? Points[i + 1] : Points[0];
            Vector v = p1 - p0;
            Vector w = point - p0;
            double c1 = w * v;
            double c2 = v * v;
            double b = c1 / c2;
            Point pb = p0 + b * v;
            double distance = (point - pb).Length;

            if (distance < thickness)
            {
                return i;
            }
        }

        return -1;
    }

Я взломал это вместе с различными образцами в Интернете, и моя математика не удивительна.Это может быть не самый лучший код - если нет, пожалуйста, предложите улучшения.

0 голосов
/ 26 августа 2010

Из геометрии мы знаем, что (y1 - y2) * x + (x2 - x1) * y + (x1 * y2 - x2 * y1) = 0, где x1, y1 - первая точка вашего отрезка их2, у2 второй.Это формула линии.Чтобы определить, принадлежит ли данная точка P (X, Y) линии, вы должны заменить ее координаты на левую сторону формулы строки, а результат на правой стороне должен быть 0 или 0 + - \ epsilon.

Но у вас нет линии, у вас есть ее сегмент, поэтому вам нужно будет добавить больше проверок, например, Px должно быть не меньше x1, не больше x2 и т. Д.

0 голосов
/ 26 августа 2010

Чтобы подробнее рассказать о том, что сказали шаманы и Лукас, вы действительно хотите найти отрезок линии, ближайший к точке щелчка (поскольку нельзя ожидать, что пользователь точно щелкнет по линии)

Чтобы сделать это, пройдите через каждый из отрезков и примените к нему формулу `(y1 - y2) * x + (x2 - x1) * y + (x1 * y2 - x2 * y1) 'и удалите знакответа - линейный сегмент, который дает наименьший результат, - это тот, который ближе всего к точке щелчка.

Если у вас на пути много сегментов, выполнение может занять много времени, поэтомуВероятно, необходимо провести некоторые оптимизации, но это, как говорится, совершенно новая история.

0 голосов
/ 26 августа 2010

Но у вас есть свойство Point, поэтому в основном вы получаете коллекцию из n + 1 очков. Линия между точками - это простое уравнение Линена. Вы должны проверить, решает ли точка вашей мыши это уравнение (проходит через коллекцию для всех линий).

Уравнение: 0 = Ax + By + C или просто y = ax + b

Есть много способов получить его параметры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...