Я студент-архитектор, пытаюсь решить пространственную проблему с помощью C # в Grasshopper for Rhino.
Пространство, которое я пытаюсь создать, - это выставочное пространство в аэропорту. Пространство будет составлено из элементов одинаковой длины. Идея состоит в том, чтобы соединить их с помощью петли и, таким образом, позволить им создавать пространства различной планировки и размера в зависимости от количества используемых элементов.
Как вы можете видеть на иллюстрации, я бы хотел, чтобы пространство заканчивалось проемом на расстоянии длины элемента от начальной точки.
Моя первая попытка заключалась в создании равносторонних треугольников в зависимости от количества необходимых сегментов (стен). Короче говоря, из начальной точки создаются треугольники, а затем стороны треугольника, образующие внешнюю границу, добавляются в список точек. Этот список точек возвращается в приложение Grasshopper, которое рисует линии между точками. Небольшой момент в том, что я произвольно создал следующий треугольник либо со стороны AC, либо со стороны BC последнего треугольника.
Вот пример созданных пространств (для 12 - 8 - 14 - 20 элементов):
Вот исходный код, который создает эти списки точек:
private void RunScript(double radius, int walls, ref object A)
{
//
List pointList = new List();
List lastList = new List();
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);
}
Я бы хотел изменить создание этих форм, чтобы они были не только коридорами, но и напоминали мои первоначальные наброски. Я хотел бы, чтобы алгоритм вводил сегменты (количество и длину), а затем предлагал различные макеты пространства, которые можно создать с этим количеством сегментов. Думаю, из-за тесселяции пространство должно быть создано из треугольников, квадратов или шестиугольников? Как вы думаете, мне следует изучить этот алгоритм "максимальной площади": Покрытие произвольной области кругами равного радиуса здесь, в stackoverflow ?
Я был бы очень признателен за любую помощь по этому алгоритму. Ура, Эйрик