Я студент архитектуры, пытающийся решить пространственную проблему с C # в Grasshopper для Rhino.
Пространство, которое я пытаюсь создать, - это выставочное пространство в аэропорту. Пространство будет состоять из элементов одинаковой длины. Идея состоит в том, чтобы соединить их шарниром и тем самым позволить им создавать пространства разной планировки и размера в зависимости от того, сколько элементов используется.
Как вы можете видеть из иллюстрации, я бы хотел, чтобы пространство заканчивалось открытием элемента на расстоянии от начальной точки.
Моей первой попыткой было создание равносторонних треугольников в зависимости от количества необходимых сегментов (стенок).
Короче говоря, из начальной точки создаются треугольники, а затем стороны треугольника, которые формируют внешнюю границу, добавляются в список точек. Этот список точек возвращается в приложение Grasshopper, которое рисует линии между точками. Небольшой момент в том, что я сделал случайным образом создание следующего треугольника со стороны AC или BC из последнего треугольника.
Вот пример созданных пробелов (для 12 - 8 - 14 - 20 элементов):
Вот исходный код, который создает эти списки точек:
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);
}
Что я хотел бы сделать, так это изменить создание этих фигур так, чтобы они были не только коридорами, но и напоминали мои первоначальные наброски. Я хотел бы, чтобы алгоритм взял ввод сегментов (число и длина), а затем предложил различные макеты пространства, которые можно создать с этим количеством сегментов. Я думаю, из-за тесселяции пространство должно было бы быть создано с помощью треугольников, квадратов или шестиугольников? Как вы думаете, мне следует изучить алгоритм «максимальной площади»: Покрытие произвольной области кружками равного радиуса здесь в stackoverflow ?
Буду очень признателен за любую помощь по этому алгоритму. Ура, Эйрик