Pergunta

Eu tenho 2 (VisualBasic.PowerPacks) linespapes no meu formulário:

TEXTO ALT http://lh4.ggpht.com/_1tpop7dzy1e/s2cijan7ehi/aaaaaaadaw/qwa0jfhebbm/s800/intersection.png

Quando clico em um deles, um menu de contexto específico é exibido. As linhas podem ser movidas pelo usuário. Um menu de contexto está associado a uma linha. No entanto, se o usuário clicar no ponto de interseção (se houver), precisará exibir um outro menu, que selecione uma das linhas de interseção para executar uma ação.

Agora, me pergunto como detectar que 2 (ou mais) linhas são cruzadas no ponto de clique, porque um outro menu de contexto deve aparecer neste caso.

O que eu tentei fazer:

    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));
            }

        }
    }

Suponho que tenho apenas linhas de linhas no contêiner. Isso disse que o ShapeContainer não aumentará um evento de Mousedown se alguma forma de linhas estiver sob o mouse.

Mas esse código me dá apenas a linha Mosttop, mas também quero uma lista de outras pessoas.

Foi útil?

Solução 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);
        }
    }

Outras dicas

Na sua rede de coordenadas, você tem duas linhas com y1 = ax + c1 e y2 = bx + c2. Encontre o ponto de interseção onde x1=x2 e y1=y2
y = ax + c1, y = bx + c2
ax + c1 = bx + c2
x = (c2 - c1)/(a - b)
Em seguida, verifique se o ponto de interseção não está além das fronteiras da linha e calcule a proximidade +- pixels ou dois.

Você precisará apenas calcular a interseção de dois segmentos de linha. Isso é bastante simples.

Um cheio, Algoritmo de trabalho é descrito aqui. Ele funciona fora dos segmentos de linha definidos por dois pontos, por isso deve ser fácil de se adaptar à sua situação.

Serhio, isso é simples Matemáticas...

Trabalhe os pontos de interseção de suas linhas (provavelmente faça isso quando forem adicionados e o resultado da loja), então veja se o mouse está próximo o suficiente para exibir o menu de contexto para que você não precise de cliques perfeitos do Pixel.

Além do algoritmo de interseção da linha (como mostrado por várias pessoas nesta página), você precisa dissociar o menu de contexto das linhas. No código pseudo, você precisará de algo como:

onLine1Click:
if intersection then handle intersection
else handle line1 click

onLine2Click:
if intersection then handle intersection
else handle line2 click

Esse manuseio pode estar mostrando o menu de contexto. Acredito que se/então/então/então for necessário resolver seu problema restante.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top