Domanda

Ho 2 (VisualBasic.PowerPacks) LineShapes sulla mia forma:

alt text http://lh4.ggpht.com /_1TPOP7DzY1E/S2cIJan7eHI/AAAAAAAADAw/qwA0jFHEbBM/s800/intersection.png

Quando clicco su uno di essi, uno specifico viene visualizzato il menu contestuale. Le linee possono essere spostate dall'utente. Un menu contestuale è associato ad una linea. Tuttavia, se l'utente clicca nel punto di intersezione (se esiste) ho bisogno di visualizzare un altro menu, che sarà selezionare una delle linee di intersezione per eseguire un'azione.

Ora, mi chiedo come rilevare che 2 (o più) linee si intersecano nel punto di clic, perché un altro contesto-menu dovrebbe apparire in questo caso.

Quello che ho cercato di fare:

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

        }
    }

Suppongo di avere solo LineShapes nel contenitore. Ciò detto, lo ShapeContainer non sollevare un evento MouseDown eventuale LineShape sarà sotto il mouse.

Ma questo codice mi dà solo la linea mostTop, ma voglio una lista di altri.

È stato utile?

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

Altri suggerimenti

Nella rete di coordinate, sono disponibili due linee con y1 = ax + c1 e y2 = bx + c2. Trovare il punto di intersezione in cui x1=x2 e y1=y2
y = ax + c1, y = bx + c2
ax + c1 = bx + c2
x = (c2 - c1)/(a - b)
Poi controllare che il punto di intersezione non è al di là dei confini di linea e calcolare la vicinanza + -. Pixel o due

sarà necessario calcolare solo l'intersezione di due segmenti di linea. Questo è abbastanza semplice.

Una completa, algoritmo di lavoro è descritto qui . Funziona off segmenti di linea definita da due punti, così dovrebbe essere facile da adattare alla propria situazione.

Serhio, questo è semplice matematica ...

Calcolare i punti di intersezione delle linee (probabilmente fare questo quando vengono aggiunti e memorizza il risultato), poi vedere se il mouse è abbastanza vicino a warrent visualizzazione del menu di scelta rapida in modo da non avete bisogno di pixel perfetta clic.

A parte l'algoritmo linea di intersezione (come mostrato da diverse persone in questa pagina), è necessario disaccoppiare il menu contestuale dalle linee. In pseudo codice avrete bisogno di qualcosa di simile:

onLine1Click:
if intersection then handle intersection
else handle line1 click

onLine2Click:
if intersection then handle intersection
else handle line2 click

Questa gestione può essere che mostra il menu contestuale. Credo che questo if / then / else è necessario per risolvere il problema rimanente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top