Wie generieren Quadrate (zufällig befindet sich, gleich große, zufällig gedreht), die sich nicht überschneiden?
Habe ich gearbeitet, auf die Schaffung einer Schicht von zufällig gedreht und platziert Quadrate auf einem 1x1 Gitter. Ich war in der Lage, generieren Sie ein einzelnes Quadrat, das ist zufällig platziert und gedreht auf dem raster, aber ich bin mir nicht sicher, wie Sie Sie, den code zu verbessern, mehr zu erzeugen zufällige Quadrate, die nicht miteinander überschneiden. Aktuelle code unten gesehen:
Beispiel meiner Einer Randomisierten Platz
from math import cos, pi, sin
from random import randint
from matplotlib.mlab import frange
from matplotlib.pyplot import plot, axis, show
def flake_position_layer1(): #Determines the initial position of one corner of the square
x0 = randint(0, 100) / 100
y0 = randint(0, 100) / 100
theta = randint(0, 90) * pi / 180 #Angle of rotation for the square
return x0, y0, theta
def flake_shape(): #generates the other 3 corners of the square
x0, y0, z, theta = flake_position_layer1()
x1 = x0 + (0.1 * cos(theta))
x2 = x1 + (0.1 * cos((90 * pi/180) + theta))
x3 = x2 + (0.1 * cos((180 * pi/180) + theta))
y1 = y0 + (0.1 * sin(theta))
y2 = y1 + (0.1 * sin((90 * pi/180) + theta))
y3 = y2 + (0.1 * sin((180 * pi/180) + theta))
return x0, x1, x2, x3, y0, y1, y2, y3
def display(): #connects the 4 corners on a plot
x0, x1, x2, x3, y0, y1, y2, y3 = flake_shape()
return plot([x0, x1, x2, x3, x0], [y0, y1, y2, y3, y0])
display()
axis([0,1,0,1]) #1x1 grid
show()
Habe ich nicht ein CS-hintergrund (ich bin ein environmental engineering major) und ich bin sehr unerfahren mit Programmieren. Bitte geben Sie mir irgendwelche Empfehlungen, die Sie haben, für mich zu versuchen und dieses problem anzugehen mit!
- Ist es möglich, zu prüfen, eine kreisförmige enveloppe rund um den Platz ? In einem solchen Fall können Sie das Zentrum der einzelnen Plätze und stellen Sie sicher, dass der Abstand zwischen den beiden center > 2*z.
- Verwenden rejection sampling, mehr zu erzeugen Quadrate:
if(current square overlaps) reject(); else add_square_to_list();
- Wie groß tun, die Plätze werden müssen? Wenn Sie können, machen Sie weniger als ~70% (1/√2) die grid-Größe, die Sie nie überlappen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Mathematischen hintergrund
1. Algebra
f(x) = a * x + b
(eine und b Konstanten, x variable)2. Ebene Geometrie
Einer Ebene besteht aus einer (unendlichen) Anzahl der Punkte: wir bezeichnen Sie einen Punkt durch seine Koordinaten, die genannt werden kann:
Die Punkte in der Ebene, verteilt auf 2 Dimensionen
y0 == f(x0)
, der Punkt ist sich auf , dass gerade Linie (und mehr: je nach y0 wird größer /unteren als f(x0), P0 befindet sich oben /unten die gerade Linie in der xOy Flugzeug). Wieder möchte ich Ihnen mitteilen, dass für nicht-lineare Funktionen,y = f(x)
gilt weiterhin (wie es die Allgemeine Gleichung Formel), aber auch andere Operatoren (z.B. <, >) nichty = a * x + b
(in unserem Beispiel:y = ((y0 - y1) /(x0 - x1)) * x + (y0 - x0 * ((y0 - y1) /(x0 - x1)))
); !! Natürlich ist es erwähnenswert, die "vertikale" (parallel zu Oy) Linie !! nicht eine Funktion !!Beispiel: 2 verschiedene parallel (nicht Bolyai 🙂 ) Linien:
f0(x) = a * x + b0
undf1(x) = a * x + b1
(eine ist die gleiche für beide Linien - das ist der Zustand für Sie zu sein, parallel) und einem externen Punkt P0(x0, y0) (die natürlich nicht gehören zu einer der Linien). Wie Sie feststellen, ob P0 ist zwischen den 2 Zeilen? Gut, der Punkt muss oben sein (die untere) ein, und unter die andere (die höhere). Übersetzt in Mathematik (unter Berücksichtigung f0 wird die untere):y0 > f0(x0)
(y0 - f0(x0) > 0
)y0 < f1(x0)
(y0 - f1(x0) < 0
)Aus der obigen Beobachtungen (und es kann mehr Weisheit), das ist die Bedingung, dass die Koordinaten der Punkte erfüllen müssen:
(y0 - f0(x0)) * (y0 - f1(x0)) < 0
Weiter: ein Quadrat besteht aus 2 Gruppen von parallelen Linien (Seiten); wenn ein Punkt zwischen den einzelnen Linien-pair-Mädchen, dann ist der Punkt in dem Quadrat.
code.py:
Hinweise:
Ich nicht die Arbeit mit matplotlib vor (tatsächlich, ich
pip install
ed es für diese Aufgabe)Allgemeine Bemerkungen:
Ausgabe:
* - Einige Worte über die Quadrate generation
allow_overlapping = True
, Generierten Werte in der Ausgabe wird mit der Anzahl der Quadrate (MAX_SQUARES)Okay, hier ist was ich habe kommen mit, mit ein wenig Hilfe von der formschöne Paket. Installations-Hilfe ist in der unten hier. Das ultimative Ergebnis:
Code walkthrough
distance
ist eine Hilfsfunktion, mit derPoint
Klasse von wohlgeformten zu finden, den Abstand zwischen zwei Koordinaten. Nur eine Hilfsfunktion für später.Square
Instanziierungen ein neues polygon. Es hat 4 Ecken, jeweils (x,y) - paar, die eine Koordinate für den Mittelpunkt, und einen skalaren Wert, der gleich der Hälfte der Entfernung seiner diagonalen.test_overlap
ist ziemlich selbsterklärend durch den Titel. Aber logisch, was es tut, ist dies: der Abstand von Mitte zu Mitte zwischen den beiden Formen. Dann finden Sie die Summe der halben Diagonale der einzelnen Formen. Wenn der center-to-center-Abstand größer als die Summe der Quadrate nicht überlappen.Squares
beginnt mit einem leeren container (leere Liste) und versucht, hinzufügen Plätze zu. Aber für jeden möglichen Neuzugang, es Premieren tests, dass es keine überschneidungen mit den bestehenden Plätzen.- Code
Beispiel
Installieren
shapely
Installieren Sie das Anaconda-Verteilung, wenn Sie nicht bereits. Dann verwenden Sie einfach
conda-forge
zu installieren, formschön. Voncmd
run:Eklatanten Mangel
An einem bestimmten Punkt Ihres Containers der Quadrate gefüllt wird, bis und es gibt einen minimalen Raum gelassen, um neue Formen. Auch wenn genügend Raum vorhanden ist, die Funktion ist im Grunde trial-and-error, so wird lange dauern hohe Form zählt. Das passiert bei rund 20-25 Plätzen (im 1.0x1.0-Feld) im moment.
Benötigen Sie eine Funktion, um zu bestimmen, ob zwei Würfel schneiden.