Autor Beitrag
AXMD
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Di 30.05.06 14:12 
Hi!

Ich suche nach einer Routine, mit der ich herausfinden kann, ob ein Punkt in einem bestimmten Bereich liegt. Recherchen in der MSDN haben auf System.Drawing.Region hingewiesen - so weit, so gut. Allerdings finde ich keine Routine, mit der ich herausfinden kann, ob ein Punkt in dieser Region liegt.
Konkret geht es um ein "schiefes" Rechteck (um einen bestimmten Winkel gedreht) - ich muss herausfinden, ob ein Mausklick auf eine Grafik innerhalb dieses Rechtecks (siehe Grafik, halbtransparenter Bereich) liegt oder nicht. Gibt es da eine Methode? In Delphi gab es PtInRect für "normale" Rechtecke...

Dust Signs

PS. Crosspost DP
Einloggen, um Attachments anzusehen!
AXMD Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: So 04.06.06 21:08 
Für alle, die es interessiert: ich hab eine Lösung für das Problem gefunden (vielen Dank an BenBE für den Ansatz): man nimmt alle Seiten des Rechtecks als Vektoren an (also AB, BC, CD, DA) und macht von jedem Eckpunkt einen Vektor zum Punkt (AP, BP, CP, DP). Nun macht man die Vektorprodukte AB*AP, BC*BP, CD*CP, DA*DP und schaut, ob eines davon negativ ist - dann liegt der Punkt außerhalb, ansonsten innerhalb. Die Idee dahinter ist die Formel für den Winkel zwischen zwei Vektoren - der Betrag ist hier nicht interessant, es geht nur um's Vorzeichen, daher wird der Betrag hier auch nicht berechnet. Hab leider kein passendes Programm, um das zeichnen zu können, aber mit einer Zeichnung wird das klarer - es ist wirklich nicht schwer.
Wen der C#-Code interessiert:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
        /// <summary>
        /// Determines if the specified point is within the given selection border
        /// </summary>
        /// <param name="Point">Point (px)</param>
        /// <param name="SelectionBorder">Selection border coordinates (px)</param>
        /// <returns>True if the point is within the specified points, false if it is not</returns>
        public static bool PointInSelectionBorder(PointF Point, PointF[] SelectionBorder)
        {
            for (int i = 0; i < SelectionBorder.Length; i++)
            {
                NormVector BorderVector = new NormVector(SelectionBorder[i == SelectionBorder.Length - 1 ? 0 : i + 1].X - SelectionBorder[i].X, SelectionBorder[i == SelectionBorder.Length - 1 ? 0 : i + 1].Y - SelectionBorder[i].Y); //Vector from current selection border point to the next one
                NormVector PointVector = new NormVector(Point.X - SelectionBorder[i].X, Point.Y - SelectionBorder[i].Y); //Vector from current selection border point to Point
                double VectorProduct = BorderVector.X * PointVector.X + BorderVector.Y * PointVector.Y;
                if (VectorProduct < 0//If vector product is negative, angle between BorderVector and PointVector is negative,...
                    return false//...so Point is outside SelectionBorder => return false
            }
            return true//If all vector products are positive, Point is in SelectionBorder => return true
        }

NormVector ist hierbei ein Typ, der einfach nur die Koordinaten X und Y speichert.

AXMD