Frage : Bestellpunkte in der Lagerhaltung im Viereck

Ich habe eine Reihe, vier willkürliche Punkte zu enthalten. Ich muss diese in der „normalen“ Vierecksreihenfolge bestellen. oberste linke, äußerste Rechte, unteres Recht, unteres left.

What ist eine gute Weise, dies zu tun?

Antwort : Bestellpunkte in der Lagerhaltung im Viereck

Ich hoffe, dass ich gerade ernsthaft overthunk dieses habe und es wirklich eine einfachere Weise gibt.  Was ich getan, berechnet die Durchschnittpunkte zwischen den Linien, die verursacht, indem man die Punkte des Polygons anschließt und, um geprüft zu sehen, die, wenn dieser Durchschnitt NICHT einer der Gipfel ist.  Wenn dieses der Fall dann ich ist, die passenden zwei Punkte austauschen, um das Polygon korrektes „einfaches“ zu bilden:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
6:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
Allgemeine Kategorie Form1

    Private Polygone als neue Liste (der Liste (des Punktes))
    Privates KSpoints als Liste (des Punktes) = nichts

    Privates Unterseeboot PictureBox1_MouseUp (ByVal Absender als Gegenstand, ByVal e als System.Windows.Forms.MouseEventArgs) behandelt PictureBox1.MouseUp
        Wenn IsNothing (KSpoints) dann
            KSpoints = neue Liste (des Punktes)
            Polygons.Add (KSpoints)
        Beenden wenn
        KSpoints.Add (e.Location)
        Wenn KSpoints.Count = 4 dann
            Schwacher ptE, PTF als Punkt
            Schwache einfache, wie Boolesch = ausrichten en
            Wenn Geometry.SegmentIntersect (KSpoints (0), KSpoints (3), KSpoints (1), KSpoints (2), ptE, PTF) = Geometry.SegmentIntersection.Point dann
                'auf Durchschnitt zwischen den Linien überprüfen, die durch 0 bis 3 und 1 bis 2. gebildet.
                Für jeden Pint als Punkt in KSpoints
                    Wenn nicht Pint. Gleichgestellte (ptE) dann
                        Einfach = falsch
                        Für herausnehmen
                    Beenden wenn
                Zunächst
                Wenn nicht einfach dann
                    'die letzten zwei Punkte austauschen
                    Pint als Punkt = KSpoints verdunkeln (3)
                    KSpoints.RemoveAt (3)
                    KSpoints.Insert (2, Pint)
                Beenden wenn
                KSpoints = nichts
                PictureBox1.Refresh ()
                Unterseeboot herausnehmen
            Beenden wenn

            Wenn Geometry.SegmentIntersect (KSpoints (0), KSpoints (1), KSpoints (2), KSpoints (3), ptE, PTF) = Geometry.SegmentIntersection.Point dann
                'auf Durchschnitt zwischen den Linien überprüfen, die durch 0 bis 1 und 2 bis 3. gebildet.
                Für jeden Pint als Punkt in KSpoints
                    Wenn nicht Pint. Gleichgestellte (ptE) dann
                        Einfach = falsch
                        Für herausnehmen
                    Beenden wenn
                Zunächst
                Wenn nicht einfach dann
                    'die zwei mittleren Punkte austauschen
                    Pint als Punkt = KSpoints verdunkeln (2)
                    KSpoints.RemoveAt (2)
                    KSpoints.Insert (1, Pint)
                    KSpoints = nichts
                    PictureBox1.Refresh ()
                    Unterseeboot herausnehmen
                Beenden wenn
            Beenden wenn

            KSpoints = nichts
            PictureBox1.Refresh ()
        Sonst
            PictureBox1.Refresh ()
        Beenden wenn
    Unterseeboot beenden

    Privates Unterseeboot PictureBox1_Paint (ByVal Absender als Gegenstand, ByVal e als System.Windows.Forms.PaintEventArgs) behandelt PictureBox1.Paint
        Statische Farben () als Farbe = {Color.Red, Color.Green, Color.Blue, Color.Purple}
        Für jedes Polygon als Liste (des Punktes) in den Polygonen
            Wenn Polygon. Zählimpuls > 1 dann
                Für i als ganze Zahl = 0 zum Polygon. Zählimpuls - 2
                    Using P als neue Feder (Farben (i))
                        e.Graphics.DrawLine (P, Polygon (i), Polygon (i + 1))
                    Ende Using
                Zunächst
                Wenn Polygon. Zählimpuls > 2 dann
                    Using P als neue Feder (Farben (Polygon. Zählimpuls - 1))
                        e.Graphics.DrawLine (P, Polygon (Polygon. Zählimpuls - 1), Polygon (0))
                    Ende Using
                Beenden wenn
            Beenden wenn
            Für jeden Pint als Punkt im Polygon
                Schwaches rc als neues Viereck (Pint, neue Größe (1, 1))
                rc. Aufblasen (3, 3)
                e.Graphics.FillRectangle (Brushes.Black, rc)
            Zunächst
        Zunächst
    Enden-Unterseeboot

Enden-Kategorie

Allgemeine Kategorien-Geometrie

    Allgemeines Enum SegmentIntersection
        Keine = 0 'die Segmente sind Ähnlichkeit und schneiden nie
        Punkt = 1, ', welches die Segmente physikalisch in einem Punkt schneiden
        ExtrapolatedPoint = 2, ', welches die Segmente physikalisch in einem Punkt schneiden, wenn eine oder beide Segmente ausgedehnt waren
        = 3 überschneiden ', die Segmente sind Ähnlichkeit und Deckung in einem Punkt oder Segment
    Ende Enum

    Öffentlichkeit geteilte Funktion SegmentIntersect (_
        ByVal A als Punkt, ByVal B als Punkt, _
        ByVal C als Punkt, ByVal D als Punkt, _
        ByRef E als Punkt, ByRef F als Punkt) als SegmentIntersection

        'Wenn eins oder beide der Segmente, die innen geführt, wirklich ein Punkt dann einfach ist, eine PointToSegmentDistance () Berechnung tun:
        Wenn A.Equals (B) OrElse C.Equals (D) dann
            Wenn A.Equals (B) AndAlso C.Equals (D) dann
                Wenn A.Equals (C) dann
                    E = A
                    F = A
                    RückholGeometry.SegmentIntersection.Point
                Sonst
                    RückholGeometry.SegmentIntersection.None
                Beenden wenn
            ElseIf A.Equals (B) dann
                Wenn Geometry.PointToSegmentDistance (A.X, A.Y, C.X, C.Y, D.X, D.Y) = 0 dann
                    E = A
                    F = A
                    RückholGeometry.SegmentIntersection.Point
                Beenden wenn
            ElseIf C.Equals (D) dann
                Wenn Geometry.PointToSegmentDistance (C.X, C.Y, A.X, A.Y, B.X, B.Y) = 0 dann
                    E = C
                    F = C
                    RückholGeometry.SegmentIntersection.Point
                Beenden wenn
            Beenden wenn
            Geometry.SegmentIntersection.None zurückbringen
        Beenden wenn

        'Wir haben zwei tatsächliche Segmente… ließen uns die Berechnungen für Det1 und Det2 tun:
        Schwaches Det1 als Doppeltes = (A.Y - C.Y) * (D.X - C.X) - (A.X - C.X) * (D.Y - C.Y)
        Schwaches Det2 als Doppeltes = (B.X - A.X) * (D.Y - C.Y) - (B.Y - A.Y) * (D.X - C.X)

        Wenn 0 <> dann 'nicht parallele Segmente Det2 (sie schneiden oder schneiden, wenn ausgedehnt)
            Schwaches Det3 als Doppeltes = (A.Y - C.Y) * (B.X - A.X) - (A.X - C.X) * (B.Y - A.Y)
            Schwaches Det4 als Doppeltes = (B.X - A.X) * (D.Y - C.Y) - (B.Y - A.Y) * (D.X - C.X)

            Schwaches r als Doppeltes = Det1/Det2
            Schwaches s als Doppeltes = Det3/Det4

            'Den Durchschnittpunkt berechnen:
            E.X = A.X + r * (B.X - A.X)
            E.Y = A.Y + r * (B.Y - A.Y)
            F = E

            Wenn (r >= 0 AndAlso r <>= 0 AndAlso s <> 0 dann 'nichtüberlappend
                RückholGeometry.SegmentIntersection.None
            'Sonst überschneiden (ein Punkt oder ein Segment)
                'Die parallelen Segmente sind die selben
                Wenn (A.Equals (C) AndAlso B.Equals (D)) OrElse (A.Equals (D) AndAlso B.Equals (C)) dann
                    E = A
                    F = B
                    RückholGeometry.SegmentIntersection.Overlapping
                Beenden wenn

                'Die parallelen Segmente überschneiden in genau einem Punkt
                Wenn B.Equals (C) OrElse B.Equals (D) dann
                    E = B
                    F = B
                    RückholGeometry.SegmentIntersection.Overlapping
                Beenden wenn
                Wenn A.Equals (C) OrElse A.Equals (D) dann
                    E = A
                    F = A
                    RückholGeometry.SegmentIntersection.Overlapping
                Beenden wenn

                'Die parallelen Segmente überschneiden in einem Segment
                Wenn Geometry.SegmentContainsPoint (A, B, C) AndAlso Geometry.SegmentContainsPoint (C, D, B) dann
                    E = C
                    F = B
                    RückholGeometry.SegmentIntersection.Overlapping
                ElseIf Geometry.SegmentContainsPoint (A, B, D) AndAlso Geometry.SegmentContainsPoint (D, C, B) dann
                    E = D
                    F = B
                    RückholGeometry.SegmentIntersection.Overlapping
                ElseIf Geometry.SegmentContainsPoint (B, A, C) AndAlso Geometry.SegmentContainsPoint (C, D, A) dann
                    E = C
                    F = A
                    RückholGeometry.SegmentIntersection.Overlapping
                ElseIf Geometry.SegmentContainsPoint (B, A, D) AndAlso Geometry.SegmentContainsPoint (D, C, A) dann
                    E = D
                    F = A
                    RückholGeometry.SegmentIntersection.Overlapping
                ElseIf Geometry.SegmentContainsPoint (C, D, A) AndAlso Geometry.SegmentContainsPoint (A, B, D) dann
                    E = A
                    F = D
                    RückholGeometry.SegmentIntersection.Overlapping
                ElseIf Geometry.SegmentContainsPoint (C, D, B) AndAlso Geometry.SegmentContainsPoint (B, A, D) dann
                    E = B
                    F = D
                    RückholGeometry.SegmentIntersection.Overlapping
                ElseIf Geometry.SegmentContainsPoint (D, C, A) AndAlso Geometry.SegmentContainsPoint (A, B, C) dann
                    E = A
                    F = C
                    RückholGeometry.SegmentIntersection.Overlapping
                ElseIf Geometry.SegmentContainsPoint (D, C, B) AndAlso Geometry.SegmentContainsPoint (B, A, C) dann
                    E = B
                    F = C
                    RückholGeometry.SegmentIntersection.Overlapping
                Beenden wenn

                'Ein Segment enthält vollständig das andere
                Wenn Geometry.SegmentContainsPoint (A, B, C) AndAlso Geometry.SegmentContainsPoint (A, B, D) dann
                    E = C
                    F = D
                    RückholGeometry.SegmentIntersection.Overlapping
                Beenden wenn
                Wenn Geometry.SegmentContainsPoint (C, D, A) AndAlso Geometry.SegmentContainsPoint (C, D, B) dann
                    E = A
                    F = B
                    RückholGeometry.SegmentIntersection.Overlapping
                Beenden wenn

                'Segmente sind parallel aber nicht berührend
                RückholGeometry.SegmentIntersection.None
            Beenden wenn
        Beenden wenn
    Funktion beenden

    Öffentlichkeit geteilte Funktion PointToPointDistance (ByVal Axt, wie einzeln, _
        ByVal Ay, wie einzeln, ByVal Bx, wie einzeln, ByVal vorbei als einzelnes) _
        Wie einzeln
        'PointToPointDist = SquareRoot ((Bx - Axt) ^2 + (durch - Ay) ^2)
        RückholMath.Sqrt ((Bx - Axt) * (Bx - Axt) + (durch - Ay) * (durch - Ay))
    Enden-Funktion

    Öffentlichkeit geteilte Funktion PointToSegmentDistance (_
            ByVal Px, wie einzeln, ByVal PY, wie einzeln, _
            ByVal Axt, wie einzeln, ByVal Ay, wie einzeln, _
            ByVal Bx, wie einzeln, ByVal vorbei, wie einzeln) wie einzeln
        Schwaches q, wie einzeln

        Wenn (Axt = Bx) und (Ay = vorbei) dann
            'A und B überschritten definieren innen einen Punkt, nicht eine Linie.
            'Punkt-zu-Punktabstand
            RückholPointToPointDistance (Px, PY, Axt, Ay)
        Sonst
            'Abstand ist die Länge der Linie, die benötigt, um den Punkt an anzuschließen
            'die (Segment) so, dass die zwei Linien senkrecht sein.

            'q ist der parameterisierte Wert, der benötigt, um zum Durchschnitt zu kommen
            q = ((Px - Axt) * (Bx - Axt) + (PY - Ay) * (durch - Ay)) /_
                ((Bx - Axt) * (Bx - Axt) + (durch - Ay) * (durch - Ay))

            'Q bis 0 1 <> begrenzen dann q = 1

            'Abstand
            RückholPointToPointDistance (_
                Px, PY, (1 - Q) * Axt + q * Bx, (1 - Q) * Ay + q * vorbei)
        Beenden wenn
    Funktion beenden

    Öffentlichkeit geteilte Funktion SegmentContainsPoint (_
        ByVal A als Punkt, ByVal B als Punkt, ByVal C als Punkt) wie Boolesch
        'Zwei Segmente AB und CD bereits festgestellt worden its, um zu haben 
        'die gleiche Steigung und die, die sie überschneiden.
        'AB ist das Segment, und C ist der fragliche Punkt.
        'Wenn AB C dann Rückholzutreffendes enthält, andernfalls die Rückkehr falsch
        Wenn C.Equals (A) oder C.Equals (B) dann
            Rückhol ausrichten
        ElseIf A.X = B.X dann 'projektieren zum Y-Axis für vertikale Linien
            Schwaches minY als ganze Zahl = Math.Min (A.Y, B.Y)
            Schwaches maxY als ganze Zahl = Math.Max (A.Y, B.Y)
            Wenn minY  <>
           
Weitere Lösungen  
 
programming4us programming4us