2010-12-11 4 views
8

Soy un estudiante de arquitectura que intenta resolver un problema espacial con C# en Grasshopper para Rhino.algoritmo para un espacio aleatorio bordeado por elementos de igual longitud

El espacio que intento crear es un espacio de exhibición en un aeropuerto. El espacio estará formado por elementos de longitud similar. La idea es conectarlos con una bisagra y, de ese modo, permitirles crear espacios de diseño y tamaño diferentes según la cantidad de elementos que se utilicen.

illustration

Como se puede ver en la ilustración Me gustaría que el espacio para terminar con una apertura de una longitud del elemento de distancia del punto de partida.

Mi primer intento ha sido crear triángulos equiláteros dependiendo de la cantidad de segmentos (muros) necesarios. En resumen, desde el punto de partida, se crean triángulos, y luego los lados del triángulo que forman el borde exterior se agregan a una lista de puntos. Esta lista de puntos se devuelve a la aplicación Grasshopper, que dibuja líneas entre los puntos. Un pequeño punto es que hice la creación del siguiente triángulo al azar, ya sea desde el lado AC o BC desde el último triángulo.

Aquí es un ejemplo de los espacios creados (por 12 - 8 - 14 - 20 elementos):

various generated shapes

Aquí está el código fuente que crea estas listas de puntos:

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); 
} 

Lo que me gustaría hacer es variar la creación de estas formas, para que no solo sean corredores, sino que se asemejen a mis bocetos iniciales. Me gustaría que un algoritmo tome una entrada de segmentos (número y longitud) y luego proponga diferentes diseños de espacio que es posible crear con este número de segmentos. Supongo que debido a la teselación, el espacio tendría que crearse con triángulos, cuadrados o hexágonos. ¿Crees que debería ver este algoritmo de "área máxima": Covering an arbitrary area with circles of equal radius here on stackoverflow?

Agradeceria cualquier ayuda con este algoritmo. Cheers, Eirik

+1

Usted ha explicado qué está tratando de HACER. Pero, ¿qué es lo que realmente y básicamente QUIERES? – Dialecticus

+4

Hay un número exponencialmente grande de formas significativamente diferentes que un algoritmo podría proponer, ya que solo proporciona ** restricciones **. También debe proporcionar algunos parámetros/metas/métricas para distinguir/clasificar las formas deseables frente a las indeseables. – RBarryYoung

+0

Gracias por sus comentarios Dialecticus y RBarryYoung. Creo que lo que deseo se puede responder respondiendo a la solicitud de parámetros/objetivos. Una alternativa es crear el área máxima con los numer_of_segments proporcionados. Si tuviera que agregar un segundo parámetro; number_of_rooms, uno podría imaginar que los segmentos forman una línea que bordea varios espacios que son de igual tamaño y están conectados con un corredor. En este escenario, quiero un algoritmo que pueda crear el máximo espacio cerrado con un number_of_segments. – Eirik

Respuesta

1

Si solo está interesado en un programa para generar instancias que se evaluarán externamente (y no en todas las instancias), podría "inflar" su curva. Por ejemplo, en la instancia de 14 segmentos en su segunda imagen, hay un lugar donde la curva se interna y se duplica - por lo que su lista de puntos tiene un punto repetido. Para curvas como esta, puede cortar todo entre los dos puntos (idénticos) (A y B), así como uno de los puntos circundantes (A o B), y ha recuperado algunos puntos para expandir su curva, lo que posiblemente resulte en una estructura sin corredor Sin embargo, es posible que deba trabajar algo de magia para asegurarse de que sea una curva "cerrada", y al mismo tiempo compre segmentos agregados en la parte frontal y posterior de la curva.

Otra oportunidad: si puede identificar el interior de la curva (y hay algoritmos para esto), en cualquier lugar en que dos segmentos formen un ángulo cóncavo con respecto a su curva, podría hacerlo desaparecer para formar un área no acorde . P.ej. el segundo y tercer segmentos de la curva de 14 segmentos anteriores podrían explotarse hacia la izquierda.

La aplicación sucesiva de estos dos métodos a su curva tipo corredor debe generar muchas de las formas que está buscando. ¡Buena suerte!

+0

¡Gracias por la gran contribución! Como dices, para mí podría ser interesante generar instancias para evaluar externamente en lugar de obtener solo la alternativa más eficiente/correcta. Intentaré agregar un cheque para puntos idénticos antes de devolver la lista, e "inflar" la lista en ese punto. ¿Podría recorrer la lista y usar el método FindIndex para lograr esto? – Eirik

Cuestiones relacionadas