2012-04-18 8 views
5

Ich suche nach einer Methode, um ein achsenausgerichtetes Rechteck innerhalb eines konkaven oder konvexen Polygons zu finden.Ein begrenztes Rechteck innerhalb eines konkaven/konvexen Polygons finden

Ich habe im Internet gesucht, die nächsten Lösungen, die ich finden konnte, würden nur ein konvexes und kein konkaves Polygon passen. Zum Beispiel -

Finding an axis-aligned rectangle inside a polygon

Um ehrlich zu sein, ich bin kein große Mathe wiz, also würde ich eher Codebeispiele oder eine Code-Bibliothek finden, aber ich glaube, ich könnte etwas Mathematik von mir handhaben, oder jemanden finden um mir dabei zu helfen.

Es wäre wirklich schön, wenn die Lösung auch in Java sein könnte, aber vielleicht bin ich zu gierig: P

bearbeiten: Als Antwort auf Russells Kommentar, ich bin ein bisschen mehr Informationen hinzufügen.

Das begrenzte Rechteck sollte so groß wie möglich sein. Das Rechteck soll Text darin enthalten. Maximal 1 bis 4 Wörter, mit Unterstützung für Textumbruch. Wenn es zum Beispiel zu dünn wäre, würde ich den Text vertikal statt horizontal platzieren. Für das Seitenverhältnis muss es also ausreichen, um 1-4 Wörter entweder vertikal oder horizontal mit Wortumbruch zu enthalten. Ich kann die Größe des Textes ändern, wenn das Rechteck klein ist, aber vorzugsweise sollte der Text so groß wie möglich sein. Eine andere Anforderung, die wünschenswert wäre, wäre, dass, wenn die allgemeine Ausrichtung des Polygons diagonal ist und der Text viel besser passt, wenn er diagonal ausgerichtet ist, dann das Rechteck nicht unbedingt mit der Achse "aber ausgerichtet" wäre stattdessen mit den diagonalen Linien des Polygons ausgerichtet sein. Ich denke, diese Nachfrage macht das wirklich schwierig, aber wenn ihr es für möglich hält, wäre es großartig!

Ich denke, ich habe jetzt alle Anforderungen abgedeckt. : P

Vielen Dank!

+0

Gibt es weitere Einschränkungen für das Rechteck? Willst du, dass es maximal ist? Von einer bestimmten Höhe oder Breite? Oder vielleicht ein bestimmtes Seitenverhältnis? Sollte es die Kanten an mindestens zwei Ecken berühren? Für konkave Polygone, wo es mehrere verschiedene mögliche Platzierungen geben kann, gibt es eine Heuristik, für die es besser ist? –

+0

Hallo Russell, danke für deine Antwort! Ich habe meine Frage aktualisiert. – Dror

Antwort

1

Da Sie dies für Text tun möchten, nehme ich an, Geschwindigkeit ist wichtig, Genauigkeit weniger wichtig. Ich schlage das dann vor:

  1. Platzieren Sie das Polygon auf einem Raster mit Zellen proportional zu Textbemaßungen.
  2. Entfernen Sie die Zellen an der Grenze mit Bresenham's line algorithm..
  3. entfernen Zellen außerhalb der Grenzzellen (durch nach innen von den Kanten des Gitters zu arbeiten.
  4. das maximale Rechteck auf den verbleibenden Zellen finden, beispielsweise das Verfahren here gezeigt.

Siehe auch Puzzle: Find largest rectangle (maximal rectangle problem).

EDIT: Ich habe gerade die Anfrage, dass dieser Algorithmus anpassen, wenn das Polygon in einem Winkel ausgerichtet ist. Mein Vorschlag ist, die principle axes des Polygons zu finden, um die Ausrichtung zu überprüfen, sie zu drehen, um die dominante Achse an der x-Achse auszurichten, und den obigen Algorithmus anzuwenden.

Auch möchte ich darauf hinweisen, dass "Entfernen einer Zelle" wirklich nur bedeutet, ein Bit in einem 2D-Array, das die Rasterzellen darstellt.

+0

Danke DeepYellow! Ihr Algorithmus scheint elegant genug zu sein. Leider werde ich im Moment keine Zeit haben es zu implementieren, da es ziemlich komplex ist. Aber ich bezeichne das trotzdem als Antwort. Ich hoffe, ich werde es bald umsetzen können. – Dror

+0

Diese Lösung ist nicht ausreichend. Stellen Sie sich ein konkaves Polygon vor, das sich fast selbst berührt - die Füllung von außen füllt die Kavität nicht. – SudoNhim

+0

@SudoNhim, ich stimme nicht zu, es funktioniert genauso gut, ob konkav oder konvex. Wo denkst du, dass es schief geht? –

1

Ich habe einmal ein ähnliches System in einer sehr kluge Art und Weise implementiert, indem ich einfach nach möglichen Rechtecken suchte und Shape.contains() darauf verwendete. Es war etwas langsam - vielleicht 1s Layout für die Gettsburg Adresse in einem Oval - aber nützlich für statischen Text und für kleinen Text in einfachen Formen.

Wenn Sie interessiert sind, könnten Sie die JAR-Datei here entpacken und unter TextWrappingLayout aussehen. Es ist wahrscheinlich viel komplizierter als das, was Sie brauchen würden, denn anstatt in einem einzelnen Rechteck zu liegen, versucht es, jede Linie so nahe wie möglich am Rand zu platzieren, aber Sie können die Grundidee sehen.

+0

Danke Russell! Es ist wirklich komplex :) Ich denke, es wäre besser für mich, es mit DeepYellows Methode zu implementieren, obwohl dies immer noch eine großartige Referenz sein könnte! Danke vielmals! – Dror