Ich bin ein Architekturstudent versucht, ein räumliches Problem mit C# in Grasshopper für Rhino zu lösen.Algorithmus für einen zufälligen Raum durch Elemente gleicher Länge
Der Raum, den ich versuche zu schaffen, ist ein Ausstellungsraum in einem Flughafen. Der Raum besteht aus Elementen ähnlicher Länge. Die Idee besteht darin, sie mit einem Scharnier zu verbinden und ihnen dadurch zu ermöglichen, Räume mit unterschiedlichem Layout und unterschiedlicher Größe zu schaffen, je nachdem wie viele Elemente verwendet werden.
Wie Sie aus der Abbildung sehen kann, würde ich den Raum wie mit einer Öffnung eines Elements Länge Auswärtspunkt vom Start zu beenden.
Mein erster Versuch bestand darin, je nach Anzahl der benötigten Segmente (Wände) gleichseitige Dreiecke zu erstellen. Kurz gesagt, vom Ausgangspunkt werden Dreiecke erstellt, und dann werden die Seiten des Dreiecks, die den äußeren Rahmen bilden, zu einer Liste von Punkten hinzugefügt. Diese Punktliste wird an die Grasshopper-Anwendung zurückgegeben, die Linien zwischen den Punkten zeichnet. Ein kleiner Punkt ist, dass ich die Erstellung des nächsten Dreiecks entweder von der Seite AC oder BC aus dem letzten Dreieck zufällig gemacht habe.
Hier ist ein Beispiel der Räume erzeugt (12 - 8 - 14 bis 20 Elemente):
Hier ist der Quellcode, der diese Punktlisten erstellt:
private void RunScript(double radius, int walls, ref object A)
{
//
List<Point3d> pointList = new List<Point3d>();
List<Point3d> lastList = new List<Point3d>();
bool alternate = true;
bool swapped = false;
Random turn = new Random();
// set up the first part of the triangle
Point3d point1 = new Point3d(0, 0, 0);
Point3d point2 = new Point3d(0, radius, 0);
pointList.Add(point1);
pointList.Add(point2);
Point3d calcPoint;
for(int i = 0; i < walls - 1; i++) // walls - 1, is because I need one less triangle to get to the amount of walls
{
// use the method to create two similar circles and return the intersection point
// in order to create an equilateral triangle
calcPoint = FindCircleIntersections(point1.X, point1.Y, point2.X, point2.Y, radius, alternate);
// random generator: will decide if the new triangle should be created from side BC or AC
bool rotate = turn.Next(2) != 0;
Print("\n" + rotate);
// set the 2nd and 3rd point as 1st and 2nd - depending on random generator.
if(rotate)
{
point1 = point2;
if(swapped == true)
swapped = false;
else
swapped = true;
}
// if the direction is swapped, the next point created will not be a part of the outer border
if(swapped)
lastList.Add(calcPoint);
else
pointList.Add(calcPoint);
point2 = calcPoint;
// swap direction of intersection
if(rotate)
{
if(alternate)
alternate = false;
else
alternate = true;
}
}
lastList.Reverse();
foreach (Point3d value in lastList)
{
pointList.Add(value);
}
A = pointList;
}
// Find the points where the two circles intersect.
private Point3d FindCircleIntersections(
double cx0, double cy0, double cx1, double cy1, double rad, bool alternate)
{
// Find the distance between the centers.
double dx = cx0 - cx1;
double dy = cy0 - cy1;
double dist = Math.Sqrt(dx * dx + dy * dy);
// Find a and h.
double a = (rad * rad - rad * rad + dist * dist)/(2 * dist);
double h = Math.Sqrt(rad * rad - a * a);
// Find P2.
double cx2 = cx0 + a * (cx1 - cx0)/dist;
double cy2 = cy0 + a * (cy1 - cy0)/dist;
// Get the points P3.
if(alternate)
return new Point3d((double) (cx2 + h * (cy1 - cy0)/dist), (double) (cy2 - h * (cx1 - cx0)/dist), 0);
else
return new Point3d((double) (cx2 - h * (cy1 - cy0)/dist), (double) (cy2 + h * (cx1 - cx0)/dist), 0);
}
Was ich tun möchte, ist, die Gestaltung dieser Formen zu variieren, so dass sie nicht nur Korridore sind, sondern meinen ersten Skizzen ähneln. Ich möchte, dass ein Algorithmus eine Eingabe von Segmenten (Anzahl und Länge) vornimmt und dann verschiedene Raumlayouts vorschlägt, die mit dieser Anzahl von Segmenten erstellt werden können. Ich denke, wegen der Tesselation müsste der Raum mit Dreiecken, Quadraten oder Sechsecken erstellt werden? Denkst du, ich sollte in diesen "Maximum Area" -Algorithmus schauen: Covering an arbitrary area with circles of equal radius here on stackoverflow?
Ich würde jede Hilfe bei diesem Algorithmus sehr schätzen. Prost, Eirik
Sie haben erklärt, was Sie zu tun versuchen. Aber was willst du eigentlich und grundsätzlich? – Dialecticus
Es gibt eine exponentiell große Anzahl von deutlich unterschiedlichen Formen, die ein Algorithmus vorschlagen könnte, da Sie nur ** Einschränkungen ** bereitstellen. Sie müssen auch einige Parameter/Ziele/Metriken angeben, um wünschenswerte gegenüber unerwünschten Formen zu unterscheiden. – RBarryYoung
Danke für Ihre Kommentare Dialecticus und RBarryYoung. Ich denke, was ich will, kann beantwortet werden, indem ich auf die Anfrage nach Parametern/Zielen antworte. Eine Alternative besteht darin, die maximale Fläche mit den bereitgestellten numer_of_segments zu erstellen. Wenn ich einen zweiten Parameter hinzufügen würde; number_of_rooms kann man sich vorstellen, dass die Segmente eine Linie bilden, die an mehrere gleich große Räume grenzt, die mit einem Korridor verbunden sind. In diesem Szenario möchte ich einen Algorithmus, der den maximalen geschlossenen Raum mit einer Anzahl von Segmenten erstellen kann. – Eirik