Вопрос

У меня есть 2 (visualbasic.powerpacks) lineShapes по моей форме:

Alt Text http://lh4.ggpht.com/_1tpop7dzy1e/s2cijan7ehi/aaaaaaaadaw/qwa0jfhebbm/s800/interception.png.png.png.

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

Теперь мне интересно, как обнаружить, что 2 (или более) строки пересекаются в точке клики, потому что в этом случае следует появиться другое контекстное меню.

Что я пытался сделать:

    private void shapeContainer1_MouseDown(object sender, MouseEventArgs e)
    {
        // right click only
        if (e.Button == MouseButtons.Right)
        {
            LineShape target = 
                (shapeContainer1.GetChildAtPoint(e.Location) as LineShape);

            if (target != null)
            {
                Console.WriteLine(new Point(target.X1, target.Y1));
            }

        }
    }

Я полагаю, у меня только белые в контейнере. Это сказало, что ShapeContainer не поднимает событие Mousedown, если любой LineShape будет под мышью.

Но этот код дает мне только линию всего в сети, но я тоже хочу список других.

Это было полезно?

Решение 5

    /// obtains a list of shapes from a click point
    private List<LineShape> GetLinesFromAPoint(Point p) 
    {
        List<LineShape> result = new List<LineShape>();
        Point pt = shapeContainer1.PointToScreen(p);

        foreach (Shape item in shapeContainer1.Shapes)
        {
            LineShape line = (item as LineShape);
            if (line != null && line.HitTest(pt.X, pt.Y))
            {
                result.Add(line);                    
            }
        }
        return result;
    }

    private void shapeContainer1_MouseDown(object sender, MouseEventArgs e)
    {
        // right click only
        if (e.Button == MouseButtons.Right)
        {
            List<LineShape> shapesList = GetLinesFromAPoint(e.Location);
            Console.WriteLine(DateTime.Now);
            Console.WriteLine("At this point {0} there are {1} lines.", 
                e.Location, shapesList.Count);
        }
    }

Другие советы

В вашей координатной сети у вас есть две строки с y1 = ax + c1 а также y2 = bx + c2. Отказ Найдите точку пересечения, где x1=x2 а также y1=y2
y = ax + c1, y = bx + c2
ax + c1 = bx + c2
x = (c2 - c1)/(a - b)
Затем убедитесь, что точка пересечения не находится за пределами линии границ и рассчитывает близость + - пиксель или два.

Вам нужно будет просто вычитать пересечение двух линий сегментов. Это довольно просто.

Полный, Рабочий алгоритм описан здесь. Отказ Он работает от сегментов линии, определенные двумя точками, поэтому должно быть легко адаптироваться к вашей ситуации.

Сермио, это просто Математика...

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

Помимо алгоритма пересечения линии (как показано несколько человек на этой странице), вам нужно разделить контекстное меню из строк. В псевдо-коде вам понадобится что-то вроде:

onLine1Click:
if intersection then handle intersection
else handle line1 click

onLine2Click:
if intersection then handle intersection
else handle line2 click

Эта обработка может отображаться контекстное меню. Я верю в это, если / затем / else требуется для разрешения вашего оставшегося вопроса.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top