Das Viereck ist konvex, wenn beide Diagonalen innerhalb des Vierecks liegen und sich somit schneiden. Die untere linke Ecke ist der Punkt, der sich unterhalb und links vom Schnittpunkt befindet. Analoge Bedingungen gelten für die anderen drei Ecken.
Wenn Sie die Reihenfolge der Punkte nicht im Voraus kennen, kennen Sie keine gegenüberliegenden Ecken, daher die Diagonalen. In diesem Fall müssen Sie den Schnittpunkt aller möglichen sechs Segmente berechnen. Wenn das Polygon konvex ist, erhalten Sie genau einen Schnittpunkt und Sie können damit die vier Ecken bestimmen. Wenn das Polygon nicht konvex ist, gibt es keinen Schnittpunkt.
UPDATE
habe ich ein Programm kleines C# meinen Vorschlag zu prüfen. Konvex-konkav-Erkennung funktioniert wie erwartet, aber es gibt immer noch Fälle, in denen die Eckenerkennung fehlschlägt (siehe Testfall 3 im Code). Aber es sollte ziemlich einfach sein, dieses Problem zu lösen.
CODE
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
namespace Quadrilaterals
{
public class Program
{
public static void Main()
{
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
Int32[,] tests = { { 0, 1, 2, 3 }, { 0, 2, 1, 3 }, { 0, 3, 1, 2 } };
PointF[] points = { new PointF(4, -2), new PointF(2, 5), new PointF(8, -6), new PointF(10, 7) };
//PointF[] points = { new PointF(0, 0), new PointF(10, 0), new PointF(5, 10), new PointF(5, 3) };
//PointF[] points = { new PointF(4, -2), new PointF(3, -1), new PointF(0, 0), new PointF(1, 0) };
PointF? p = null;
for (Int32 i = 0; i < 3; i++)
{
Console.WriteLine("Intersecting segments ({0}|{1}) and ({2}|{3}).", tests[i, 0], tests[i, 1], tests[i, 2], tests[i, 3]);
Single? f1 = IntersectLines(points[tests[i, 0]], points[tests[i, 1]], points[tests[i, 2]], points[tests[i, 3]]);
Single? f2 = IntersectLines(points[tests[i, 2]], points[tests[i, 3]], points[tests[i, 0]], points[tests[i, 1]]);
if ((f1 != null) && (f2 != null))
{
PointF pp = PointOnLine(points[tests[i, 0]], points[tests[i, 1]], f1.Value);
Console.WriteLine(" Lines intersect at ({0}|{1}) with factors {2} and {3}.", pp.X, pp.Y, f1, f2);
if ((f1 > 0) && (f1 < 1) && (f2 > 0) && (f2 < 1))
{
Console.WriteLine(" Segments intersect.");
p = pp;
}
else
{
Console.WriteLine(" Segments do not intersect.");
}
}
else
{
Console.WriteLine(" Lines are parallel.");
}
}
if (p == null)
{
Console.WriteLine("The quadrilateral is concave.");
}
else
{
Console.WriteLine("The quadrilateral is convex.");
for (Int32 j = 0; j < 4; j++)
{
Console.WriteLine(" Point {0} ({3}|{4}) is the {1} {2} corner.", j, (points[j].Y < p.Value.Y) ? "bottom" : "top", (points[j].X < p.Value.X) ? "left" : "right", points[j].X, points[j].Y);
}
}
Console.ReadLine();
}
private static Single? IntersectLines(PointF a1, PointF a2, PointF b1, PointF b2)
{
PointF r = Difference(a1, b1);
PointF a = Difference(a2, a1);
PointF b = Difference(b2, b1);
Single p = r.X * b.Y - r.Y * b.X;
Single q = a.Y * b.X - a.X * b.Y;
return (Math.Abs(q) > Single.Epsilon) ? (p/q) : (Single?)null;
}
private static PointF Difference(PointF a, PointF b)
{
return new PointF(a.X - b.X, a.Y - b.Y);
}
private static PointF PointOnLine(PointF a, PointF b, Single f)
{
return new PointF(a.X + f * (b.X - a.X), a.Y + f * (b.Y - a.Y));
}
}
}
OUTPUT
Intersecting segments (0|1) and (2|3).
Lines intersect at (7|-12.5) with factors -1.5 and -0.5.
Segments do not intersect.
Intersecting segments (0|2) and (1|3).
Lines intersect at (-2|4) with factors -1.5 and -0.5.
Segments do not intersect.
Intersecting segments (0|3) and (1|2).
Lines intersect at (5|-0.4999999) with factors 0.1666667 and 0.5.
Segments intersect.
The quadrilateral is convex.
Point 0 (4|-2) is the bottom left corner.
Point 1 (2|5) is the top left corner.
Point 2 (8|-6) is the bottom right corner.
Point 3 (10|7) is the top right corner.
Haben Sie die Reihenfolge der Punkte wissen oder sind die Punkte, ungeordnete? –
Die Reihenfolge der Punkte muss bekannt sein; Es gibt mehrere Polygone mit 4 Ecken. –
Es gibt die folgenden Fälle. 1. Drei Punkte bilden ein Dreieck und der letzte Punkt befindet sich innerhalb dieses Dreiecks. In diesem Fall gibt es drei mögliche Vierecke und sie sind alle nicht konvex. 2. In allen anderen Fällen gibt es auch drei mögliche Vierecke. Einer ist konvex und die anderen zwei sind sich selbst schneidend. Daher können die Fragen auch beantwortet werden, wenn die Reihenfolge nicht bekannt ist (und sich selbst schneidende Vierecke nicht berücksichtigt werden). –