Los datos son el contenido de nuestros programas. Viajan a través de cables proporcionando entradas a los nodos, donde se procesan y se transforman en una nueva forma de datos de salida. Revisemos la definición de los datos, cómo se estructuran y cómo utilizarlos en Dynamo.
Los datos son un conjunto de valores de variables cualitativas o cuantitativas. La forma de datos más sencilla son números como, por ejemplo, 0
, 3.14
o 17
. Sin embargo, los datos también puede ser de diferentes tipos: una variable que representa números cambiantes (height
); caracteres (myName
); geometría (Circle
), o una lista de elementos de datos (1,2,3,5,8,13,...
).
En Dynamo, añadimos o introducimos datos en los puertos de entrada de los nodos; podemos tener datos sin acciones, pero nos hacen falta datos para procesar las acciones que representan nuestros nodos. Cuando se añade un nodo al espacio de trabajo, si no se le proporciona ninguna entrada, el resultado será una función y no el resultado de la acción en sí.
Datos simples.
Datos y una acción (un nodo); se ejecuta correctamente.
Una acción (un nodo) sin entradas de datos; devuelve una función genérica.
Cuidado con los valores nulos. El tipo 'null'
representa la ausencia de datos. Aunque se trata de un concepto abstracto, es probable que esto ocurra mientras trabaja con programación visual. Si una acción no crea un resultado válido, el nodo devolverá un valor "null".
Comprobar si existen valores "null" y eliminarlos de la estructura de datos es una parte crucial para crear programas sólidos.
Cuando somos programadores visuales, podemos generar una gran cantidad de datos rápidamente y requerir un medio de administración de su jerarquía. Esta es la función de las estructuras de datos, los esquemas organizativos en los que almacenamos los datos. Las características específicas de las estructuras de datos y su uso varían de un lenguaje de programación a otro.
En Dynamo, se añade jerarquía a los datos a través de las listas. Exploraremos esto en profundidad en capítulos posteriores, pero empecemos con algo sencillo.
Una lista representa una colección de elementos colocados en una estructura de datos:
Tengo cinco dedos (elementos) en la mano (lista).
Hay diez casas (elementos) en mi calle (lista).
Un nodo Number Sequence define una lista de números mediante entradas start, amount y step. Con estos nodos, hemos creado dos listas independientes de diez números, una que abarca de 100 a 109 y otra de 0 a 9.
El nodo List.GetItemAtIndex selecciona un elemento de una lista en un índice determinado. Al seleccionar 0, se obtiene el primer elemento de la lista (100 en este caso).
Al aplicar el mismo proceso a la segunda lista, obtenemos un valor de 0, el primer elemento de la lista.
Ahora combinamos las dos listas en una mediante el nodo List.Create. Observe que el nodo crea una lista de listas. Esto cambia la estructura de los datos.
Al volver a utilizar List.GetItemAtIndex, con el índice establecido en 0, se obtiene la primera lista de la lista de listas. Esto es lo que significa tratar una lista como un elemento, lo cual es ligeramente diferente de otros lenguajes de secuencias de comandos. En capítulos posteriores, nos adentraremos más en la manipulación de listas y la estructura de datos.
El concepto clave para comprender la jerarquía de datos en Dynamo es que en relación con la estructura de datos, las listas se consideran elementos. En otras palabras, Dynamo funciona con un proceso descendente para comprender las estructuras de datos. Implicaciones Veámoslo con un ejemplo.
Descargue el archivo de ejemplo. Para ello, haga clic en el vínculo siguiente.
En el Apéndice, se incluye una lista completa de los archivos de ejemplo.
En este primer ejemplo, vamos a ensamblar un cilindro vaciado que recorre la jerarquía de geometría tratada en esta sección.
1. Añada Point.ByCoordinates: después de añadir el nodo al lienzo, se muestra un punto en el origen de la rejilla de vista preliminar de Dynamo. Los valores por defecto de las entradas x, y y z son 0,0, lo que nos da un punto en esta ubicación.
2. Plane.ByOriginNormal: el siguiente paso en la jerarquía de geometría es un plano. Existen varias formas de construir un plano; utilizaremos un origen y una normal para la entrada. El origen es el nodo de punto creado en el paso anterior.
Vector.ZAxis: es un vector unificado en la dirección Z. Observe que no hay entradas, solo un vector con un valor [0,0,1]. Se utiliza como la entrada normal para el nodo Plane.ByOriginNormal. Esto nos proporciona un plano rectangular en la vista preliminar de Dynamo.
3. Circle.ByPlaneRadius: ascendiendo en la jerarquía, ahora creamos una curva a partir del plano del paso anterior. Después de conectar el nodo, se obtiene un círculo en el origen. El radio por defecto del nodo es el valor de 1.
4. Curve.Extrude: ahora vamos a hacer que este elemento crezca dándole profundidad y añadiendo la tercera dimensión. Este nodo crea una superficie a partir de una curva mediante su extrusión. La distancia por defecto en el nodo es 1 y debería aparecer un cilindro en la ventana gráfica.
5. Surface.Thicken: este nodo nos proporciona un sólido cerrado mediante el desfase de la superficie con la distancia especificada y el cierre de la forma. El valor de grosor por defecto es 1 y vemos un cilindro vaciado en la ventana gráfica en línea con estos valores.
6. Number Slider: en lugar de utilizar los valores por defecto para todas estas entradas, vamos a añadir algún control paramétrico al modelo.
Edición del dominio: después de añadir el control deslizante de número al lienzo, haga clic en el signo de intercalación situado en la parte superior izquierda para ver las opciones de dominio.
Min/Max/Step: cambie los valores min, max y step a 0, 2 y 0,01 respectivamente. Esto lo hacemos para controlar el tamaño de la geometría global.
7. Nodos Number Slider: en todas las entradas por defecto, copiemos y peguemos este control deslizante de número (seleccione el control deslizante, pulse Ctrl+C y, a continuación, Ctrl+V) varias veces hasta que todas las entradas con valores por defecto tengan un control deslizante. Algunos de los valores del control deslizante tendrán que ser mayores que cero para que la definición funcione (es decir, para que una superficie se engrose, se necesita una profundidad de extrusión).
8. Hemos creado un cilindro paramétrico vaciado con estos controles deslizantes. Pruebe a modificar algunos de estos parámetros y ver cómo la geometría se actualiza de forma dinámica en la ventana gráfica de Dynamo.
Nodos Number Slider: al avanzar en este ejemplo, hemos añadido muchos controles deslizantes al lienzo y debemos limpiar la interfaz de la herramienta que acabamos de crear. Haga clic con el botón derecho en un control deslizante, seleccione "Cambiar nombre" y cambie cada control deslizante al nombre apropiado para su parámetro (Grosor, Radio, Altura, etc.).
9. En este punto, hemos creado un fantástico elemento de cilindro engrosado. Se trata de un objeto actualmente; veamos cómo crear una matriz de cilindros que permanezca enlazada de forma dinámica. Para ello, vamos a crear una lista de cilindros en lugar de trabajar con un único elemento.
Adición (+): nuestro objetivo es añadir una fila de cilindros junto al cilindro que hemos creado. Si se desea añadir un cilindro adyacente al actual, se deben tener en cuenta el radio del cilindro y el grosor del vaciado. Para obtener este número, se añaden los dos valores de los controles deslizantes.
10. Este paso es más complejo, por lo que pasaremos por él más lentamente. El objetivo es crear una lista de números que defina las ubicaciones de cada cilindro en una fila.
a. Multiplicación: deseamos multiplicar primero el valor del paso anterior por 2. El valor del paso anterior representa un radio y queremos mover el cilindro por el diámetro completo.
b. Number Sequence: creamos una matriz de números con este nodo. La primera entrada es el nodo de multiplicación del paso anterior en el valor step. El valor start se puede establecer en 0,0 mediante un nodo Number.
c. Control deslizante de enteros: para el valor amount, conectamos un control deslizante de entero. Esto definirá cuántos cilindros se crean.
d. Salida: esta lista muestra la distancia desplazada para cada cilindro de la matriz y la manejan paramétricamente los controles deslizantes originales.
11. Este paso es bastante sencillo: conecte la secuencia definida en el paso anterior a la entrada x del Point.ByCoordinates original. De este modo, se sustituye el control deslizante pointX, que se puede suprimir Ahora vemos una matriz de cilindros en la ventana gráfica (asegúrese de que el control deslizante de enteros sea mayor que 0).
12. La cadena de cilindros sigue enlazada dinámicamente a todos los controles deslizantes. Mueva cada uno de los controles deslizantes para ver cómo se actualiza la definición.
El color es un excelente tipo de datos para crear imágenes convincentes, así como para renderizar la diferencia en la salida del programa visual. Cuando se trabaja con datos abstractos y números variables, a veces es difícil ver qué se está cambiando y en qué grado. Esta es una aplicación excelente para los colores.
Los colores de Dynamo se crean con entradas de ARGB. Estas corresponden a los canales alfa, rojo, verde y azul. El canal alfa representa la transparencia del color, mientras que los otros tres se utilizan como colores principales para generar todo el espectro de color sincronizado.
Icono | Nombre (sintaxis) | Entradas | Salidas |
---|---|---|---|
Los colores de la tabla siguiente consultan las propiedades utilizadas para definir el color: alfa, rojo, verde y azul. Observe que el nodo Color.Components nos proporciona las cuatro salidas diferentes, lo que hace que este nodo sea preferible para consultar las propiedades de un color.
Icono | Nombre (sintaxis) | Entradas | Salidas |
---|---|---|---|
Los colores de la tabla siguiente corresponden al espacio de color HSB. La división del color en el matiz, la saturación y el brillo es, probablemente, más intuitiva en la forma en que se interpreta el color: ¿Qué color debería ser? ¿Debería ser más o menos colorido? ¿Y debería ser más o menos claro u oscuro? Este es el desglose del matiz, la saturación y el brillo respectivamente.
Icono | Nombre (sintaxis) | Entradas | Salidas |
---|---|---|---|
El rango de color es similar al nodo Remap Range del ejercicio #part-ii-from-logic-to-geometry; asigna de nuevo una lista de números a otro dominio. Sin embargo, en lugar de asignarla a un dominio de número, la asigna a un degradado de color basado en números de entrada que van del 0 al 1.
El nodo actual funciona bien, pero puede resultar un poco incómodo para que todo funcione la primera vez. La mejor forma de familiarizarse con el degradado de color es probarlo de forma interactiva. Hagamos un ejercicio rápido para revisar cómo configurar un degradado con colores de salida que corresponden a números.
Definir tres colores: con un nodo Code Block, defina rojo, verde y azul mediante la conexión de las combinaciones adecuadas de 0 y 255.
Crear lista:fusione los tres colores en una lista.
Definir índices: cree una lista para definir las posiciones de pinzamiento de cada color (de 0 a 1). Observe el valor de 0,75 para el verde. De este modo, se coloca el color verde a tres cuartos de camino en el degradado horizontal del control deslizante de rango de colores.
Code Block: valores de entrada (entre 0 y 1) para convertir en colores.
El nodo Display.ByGeometry nos permite colorear la geometría en la ventana gráfica de Dynamo. Esto resulta útil para separar diferentes tipos de geometría, demostrar un concepto paramétrico o definir una leyenda de análisis para la simulación. Las entradas son sencillas, geometría y color. Para crear un degradado como el de la imagen anterior, la entrada de color se conecta al nodo Color Range.
El nodo Display.BySurfaceColors nos permite asignar datos en una superficie mediante los colores. Esta función ofrece posibilidades interesantes para visualizar los datos obtenidos a través de análisis independientes como análisis solares, de energía o de proximidad. La aplicación de color a una superficie en Dynamo es similar a la aplicación de una textura a un material en otros entornos de CAD. Vamos a demostrar cómo utilizar esta herramienta en el siguiente ejercicio breve.
Descargue el archivo de ejemplo. Para ello, haga clic en el vínculo siguiente.
En el Apéndice, se incluye una lista completa de los archivos de ejemplo.
Este ejercicio se centra en el control paramétrico del color en paralelo a la geometría. La geometría es una hélice básica que se define a continuación mediante el bloque de código. Esta es una forma rápida y sencilla de crear una función paramétrica y, como nuestro enfoque está en el color (en lugar de en la geometría), utilizamos el bloque de código para crear la hélice de forma eficaz sin sobrecargar el lienzo. Utilizaremos el bloque de código con más frecuencia a medida que el manual de introducción se adentre en materiales más avanzados.
Code Block: defina los dos bloques de código con las fórmulas mostradas anteriormente. Este es un método paramétrico rápido para crear una espiral.
Point.ByCoordinates: conecte las tres salidas del bloque de código a las coordenadas del nodo.
Ahora se muestra una matriz de puntos que crean una hélice. El siguiente paso consiste en crear una curva que atraviese los puntos para que podamos visualizar la hélice.
PolyCurve.ByPoints: conecte la salida Point.ByCoordinates en la entrada points del nodo. Se obtiene una curva helicoidal.
Curve.PointAtParameter: conecte la salida de PolyCurve.ByPoints a la entrada curve. La finalidad de este paso es crear un punto atractor paramétrico que se deslice a lo largo de la curva. Dado que la curva está evaluando un punto en el parámetro, necesitaremos introducir un valor en param entre 0 y 1.
Number Slider: después de añadirlo al lienzo, cambie el valor mínimo a 0,0, el valor máximo a 1,0 y el valor de paso a 0,01. Conecte la salida del control deslizante a la entrada param de Curve.PointAtParameter. Ahora se muestra un punto a lo largo de la longitud de la hélice representado por un porcentaje del control deslizante (0 en el punto inicial, 1 en el punto final).
Con el punto de referencia creado, ahora comparamos la distancia desde el punto de referencia a los puntos originales que definen la hélice. Este valor de distancia controlará la geometría y el color.
Geometry.DistanceTo: conecte la salida de Curve.PointAtParameter a la entrada. Conecte Point.ByCoordinates en la entrada geometry.
Watch: la salida resultante muestra una lista de las distancias desde cada punto helicoidal hasta el punto de referencia a lo largo de la curva.
El siguiente paso consiste en controlar los parámetros con la lista de distancias entre los puntos helicoidales y el punto de referencia. Utilizamos estos valores de distancia para definir los radios de una serie de esferas a lo largo de la curva. Para mantener las esferas en un tamaño adecuado, es necesario reasignar los valores de la distancia.
Math.RemapRange: conecte la salida de Geometry.DistanceTo a la entrada "numbers".
Code Block: conecte un bloque de código con un valor de 0,01 a la entrada newMin y un bloque de código con un valor de 1 a la entrada newMax.
Watch: conecte la salida de Math.RemapRange a un nodo y la salida de Geometry.DistanceTo a otro. Compare los resultados.
Este paso ha reasignado la lista de distancias para que tenga un rango más pequeño. Podemos editar los valores de newMin y newMax según consideremos adecuado. Los valores se reasignarán y tendrán la misma relación de distribución en todo el dominio.
Sphere.ByCenterPointRadius: conecte la salida de Math.RemapRange a la entrada radius y la salida de Point.ByCoordinates original a la entrada centerPoint.
Cambie el valor del control deslizante de número y observe cómo se actualiza el tamaño de las esferas. Ahora tenemos una guía paramétrica.
El tamaño de las esferas muestra la matriz paramétrica definida por un punto de referencia a lo largo de la curva. Usaremos el mismo concepto para que el radio de la esfera controle su color.
Color Range: añádalo al lienzo. Al pasar el cursor sobre la entrada value, observamos que los números solicitados se encuentran entre 0 y 1. Es necesario volver a asignar los números de la salida de Geometry.DistanceTo para que sean compatibles con este dominio.
Sphere.ByCenterPointRadius: por el momento, desactivemos la vista preliminar en este nodo (Haga clic con el botón derecho > Vista preliminar).
Math.RemapRange: este proceso debería resultarle familiar. Conecte la salida de Geometry.DistanceTo a la entrada "numbers".
Code Block: como hicimos en un paso anterior, cree el valor 0 para la entrada newMin y el valor 1 para la entrada newMax. Observe que, en este caso, podemos definir dos salidas de un bloque de código.
Color Range: conecte la salida de Math.RemapRange a la entrada value.
Color.ByARGB: esto es lo que haremos para crear dos colores. Aunque este proceso puede parecer incómodo, es el mismo que el utilizado con los colores RGB en otro software, solo que usamos programación visual para ello.
Code Block: cree dos valores de 0 y 255. Conecte las dos salidas a las dos entradas de Color.ByARGB de acuerdo con la imagen anterior (o cree sus dos colores favoritos).
Color Range: la entrada colors requiere una lista de colores. Se debe crear esta lista a partir de los dos colores creados en el paso anterior.
List.Create: combine los dos colores en una lista. Conecte la salida a la entrada colors de Color Range.
Display.ByGeometryColor: conecte Sphere.ByCenterPointRadius a la entrada geometry y Color Range a la entrada color. Ahora tenemos un degradado suave en el dominio de la curva.
Si se cambia el valor del control deslizante de número mostrado anteriormente, se actualizan los colores y los tamaños. Los colores y el tamaño del radio están directamente relacionados en este caso; ahora tenemos un vínculo visual entre dos parámetros.
Descargue el archivo de ejemplo. Para ello, haga clic en el vínculo siguiente.
En el Apéndice, se incluye una lista completa de los archivos de ejemplo.
Es necesario crear primero una superficie o hacer referencia a ella para utilizarla como entrada en el nodo Display.BySurfaceColors. En este ejemplo, se realiza la solevación entre una curva seno y coseno.
Este grupo de nodos crea puntos a lo largo del eje Z y los desplaza según las funciones de seno y coseno. Las dos listas de puntos se utilizan a continuación para generar curvas NURBS.
Surface.ByLoft: genere una superficie interpolada entre las curvas NURBS de la lista.
File Path: seleccione un archivo de imagen para muestrear datos de píxeles.
Utilice File.FromPath para convertir la ruta de archivo en un archivo y, a continuación, páselo a Image.ReadFromFile para obtener una imagen para el muestreo.
Image.Pixels: introduzca una imagen y proporcione un valor de muestra para utilizarlo en las cotas X e Y de la imagen.
Control deslizante: proporcione valores de muestra para Image.Pixels.
Display.BySurfaceColors: asigne los valores de matriz de color de la superficie a lo largo de X e Y respectivamente.
Vista preliminar ampliada de la superficie de salida con resolución de 400 x 300 muestras
Una vez que estemos listos para profundizar en el desarrollo de programas visuales, necesitaremos una mejor comprensión de los componentes de construcción que utilizaremos. En este capítulo, se presentan conceptos fundamentales sobre los datos: el contenido que recorre los cables de nuestro programa de Dynamo.
Formalmente, una cadena es una secuencia de caracteres que representa una constante literal o algún tipo de variable. Informalmente, una cadena es texto en la jerga de la programación. Hemos trabajado con números, enteros y decimales, para controlar los parámetros y podemos hacer lo mismo con el texto.
Las cadenas se pueden utilizar para una amplia gama de aplicaciones, como la definición de parámetros personalizados, la anotación de conjuntos de documentación y el análisis mediante conjuntos de datos basados en texto. El nodo string se encuentra en la categoría Core > Input.
Los nodos de ejemplo anteriores son cadenas. Un número puede representarse como una cadena, al igual que una letra o una matriz completa de texto.
Descargue el archivo de ejemplo. Para ello, haga clic en el vínculo siguiente.
En el Apéndice, se incluye una lista completa de los archivos de ejemplo.
Puede analizar rápidamente grandes cantidades de datos consultando cadenas. Hablaremos de algunas operaciones básicas que pueden acelerar un flujo de trabajo y ayudar a mejorar la interoperabilidad de software.
La imagen siguiente se basa en una cadena de datos procedentes de una hoja de cálculo externa. La cadena representa los vértices de un rectángulo en el plano XY. Vamos a desglosar algunas operaciones de división de cadenas en un ejercicio de miniaturas:
El separador ";" divide cada vértice del rectángulo. De este modo, se crea una lista con tres elementos para cada vértice.
Al pulsar "+" en el centro del nodo, se crea un nuevo separador.
Añada una cadena "," al lienzo y conéctela a la nueva entrada de separador.
Nuestro resultado es ahora una lista de diez artículos. El nodo realiza la división primero en función de separator0 y, a continuación, en función de separator1.
Aunque los elementos de la lista anterior pueden tener el aspecto de números, se siguen considerando cadenas individuales en Dynamo. Para crear puntos, su tipo de datos debe convertirse de una cadena a un número. Esto se realiza con el nodo String.ToNumber.
Este nodo es sencillo. Conecte los resultados de String.Split a la entrada. La salida no tiene un aspecto diferente, pero el tipo de datos es ahora un número en lugar de una cadena.
Con algunas operaciones básicas adicionales, ahora se ha dibujado un triángulo en el origen en función de la entrada de cadena original.
Dado que una cadena es un objeto de texto genérico, alberga una amplia gama de aplicaciones. Echemos un vistazo a algunas de las acciones principales de la categoría Core > String de Dynamo:
Este es un método para fusionar dos cadenas en orden. Toma cada cadena literal de una lista y crea una cadena combinada.
A continuación, se representa la concatenación de tres cadenas:
Añada o sustraiga cadenas a la concatenación haciendo clic en los botones +/- del centro del nodo.
La salida es una cadena concatenada, incluidos espacios y signos de puntuación.
El método de unión es muy similar a la concatenación, excepto que tiene una capa añadida de signos de puntuación.
Si ha trabajado en Excel, es posible que haya encontrado un archivo CSV. Se trata de un archivo de valores separados por comas. Se puede utilizar una coma (o, en este caso, dos guiones) como separador con el nodo String.Join para crear una estructura de datos similar.
La imagen anterior representa la unión de dos cadenas:
La entrada "separator" permite crear una cadena que divide las cadenas unidas.
En este ejercicio, vamos a usar métodos de consulta y manipulación de cadenas para deconstruir la última estrofa del poema Alto en el bosque en una noche de invierno de Robert Frost. No es la aplicación más práctica, pero nos ayudará a comprender las acciones de cadenas conceptuales a medida que las aplicamos a líneas legibles de ritmo y rima.
Comencemos con una división de cadenas básica de la estrofa. Primero, observamos que el formato de la escritura se basa en comas. Utilizaremos este formato para separar cada línea en elementos individuales.
La cadena base se pega en un nodo String.
Se utiliza otro nodo String para indicar el separador. En este caso, usamos una coma.
Se añade un nodo String.Split al lienzo y se conecta a las dos cadenas.
La salida muestra ahora que hemos separado las líneas en elementos individuales.
Ahora, vamos a la parte buena del poema: las dos últimas líneas. La estrofa original era un elemento de datos. En el primer paso, separamos estos datos en elementos individuales. Ahora debemos buscar el texto que deseamos encontrar. Y, aunque podemos hacerlo seleccionando los dos últimos elementos de la lista, si se tratara de un libro completo, no sería un método eficaz leerlo todo y aislar manualmente los elementos.
En lugar de realizar una búsqueda manual, se utiliza un nodo String.Contains para realizar una búsqueda de un conjunto de caracteres. Esto es similar a utilizar el comando "Buscar" en un procesador de texto. En este caso, obtenemos un valor de "verdadero" o "falso" si se encuentra esa subcadena en el elemento.
En la entrada searchFor, definimos la subcadena que buscamos dentro de la estrofa. Vamos a usar un nodo String con el texto "And miles".
La salida nos proporciona una lista de resultados de verdadero y falso. Utilizaremos esta lógica booleana para filtrar los elementos en el siguiente paso.
List.FilterByBoolMask es el nodo que debemos utilizar para seleccionar los resultados con valor "false" (falso) y "true" (verdadero). La salida "in" devuelve las instrucciones con una entrada "mask" de "verdadero", mientras que la salida "out" devuelve las que tienen un valor de "falso".
Nuestra salida de "in" es como se esperaba, ya que devuelve las dos frases finales de la estrofa.
Ahora, vamos a dejar clara la repetición de la estrofa fusionando las dos líneas. Al visualizar el resultado del paso anterior, observamos que hay dos elementos en la lista:
Mediante dos nodos List.GetItemAtIndex, se pueden aislar los elementos con los valores 0 y 1 como entrada del índice.
La salida de cada nodo nos proporciona, por orden, las dos líneas finales.
Para fusionar estos dos elementos en uno, se utiliza el nodo String.Join:
Después de añadir el nodo String.Join, observamos que necesitamos un separador.
Para crear el separador, se añade un nodo String al lienzo y se escribe una coma.
La última salida ha fusionado los dos últimos elementos en uno.
Puede parecer muy laborioso aislar las dos últimas líneas y es cierto que, a menudo, las operaciones de cadena requieren trabajo inicial. Pero son escalables y se pueden aplicar a grandes conjuntos de datos con relativa facilidad. Si trabaja paramétricamente con hojas de cálculo e interoperabilidad, asegúrese de mantener en mente las operaciones de cadena.
Si la forma más sencilla de datos es el número, la forma más sencilla de relacionarlos es mediante las matemáticas. Desde operadores sencillos como la división a funciones trigonométricas y fórmulas más complejas, las matemáticas son un método excelente para empezar a explorar relaciones y patrones numéricos.
Los operadores son un conjunto de componentes que utilizan funciones algebraicas con dos valores numéricos de entrada que dan como resultado un valor de salida (suma, resta, multiplicación, división, etc.). Estos se pueden encontrar en Operators > Actions.
Icono | Nombre (sintaxis) | Entradas | Salidas |
---|---|---|---|
Descargue el archivo de ejemplo. Para ello, haga clic en el vínculo siguiente.
En el Apéndice, se incluye una lista completa de los archivos de ejemplo.
Combine operadores y variables para formar una relación más compleja mediante fórmulas. Utilice los controles deslizantes para crear una fórmula que se pueda manejar con parámetros de entrada.
1. Cree la secuencia numérica que representa la "t" de la ecuación paramétrica, por lo que debemos utilizar una lista lo suficientemente grande como para definir una espiral.
Number Sequence: defina una secuencia de números basada en tres entradas: start, amount y step.
2. En el paso anterior, hemos creado una lista de números para definir el dominio paramétrico. A continuación, cree un grupo de nodos que representen la ecuación de la espiral dorada.
La espiral dorada se define como la siguiente ecuación:
La imagen siguiente representa la espiral dorada en forma de programación visual. Al desplazarse por el grupo de nodos, intente prestar atención al paralelismo entre el programa visual y la ecuación por escrito.
a. Number Slider: añada dos controles deslizantes de número al lienzo. Estos controles deslizantes representarán las variables a y b de la ecuación paramétrica. Estas representan una constante que es flexible o parámetros que podemos ajustar hacia el resultado deseado.
b. Multiplication (*): el nodo de multiplicación se representa mediante un asterisco. Lo usaremos con frecuencia para conectar variables de multiplicación.
c. Math.RadiansToDegrees: los valores de "t" se deben convertir a grados para que se evalúen en las funciones trigonométricas. Recuerde que Dynamo utiliza por defecto los grados para evaluar estas funciones.
d. Math.Pow: como función de "t" y del número "e", crea la secuencia Fibonacci.
e. Math.Cos y Math.Sin: estas dos funciones trigonométricas distinguirán la coordenada X y la coordenada Y, respectivamente, de cada punto paramétrico.
f. Watch: ahora vemos que las salidas son dos listas, que serán las coordenadas x e y de los puntos utilizados para generar la espiral.
El cúmulo de nodos del paso anterior funcionará correctamente, pero conlleva mucho trabajo. Para crear un flujo de trabajo más eficiente, consulte DesignScript a fin de definir una cadena de expresiones de Dynamo en un nodo. En la siguiente serie de pasos, veremos cómo utilizar la ecuación paramétrica para dibujar la espiral Fibonacci.
Point.ByCoordinates: conecte el nodo de multiplicación superior a la entrada "x" y el inferior a la entrada "y". Ahora se muestra una espiral paramétrica de puntos en la pantalla.
Polycurve.ByPoints: conecte Point.ByCoordinates del paso anterior a points. Podemos dejar connectLastToFirst sin entrada porque no estamos creando una curva cerrada. Se crea una espiral que pasa a través de cada punto definido en el paso anterior.
Ya hemos completado la espiral Fibonacci. Vamos a profundizar en estos conceptos con dos ejercicios separados a partir de aquí; a uno lo llamaremos caracol y al otro girasol. Se trata de abstracciones de sistemas naturales, pero las dos aplicaciones diferentes de la espiral Fibonacci estarán bien representadas.
Circle.ByCenterPointRadius: utilizaremos aquí un nodo de círculo con las mismas entradas que en el paso anterior. El valor por defecto del radio es 1,0, por lo que vemos una salida de círculos inmediata. Se hace inmediatamente evidente cómo los puntos divergen más respecto al origen.
Number Sequence: es la matriz original de "t". Al conectarlo con el valor del radio de Circle.ByCenterPointRadius, los centros de círculo siguen divergiendo más respecto del origen, pero el radio de los círculos aumenta, lo que crea un gráfico de círculos Fibonacci con mucho estilo.
Un premio para quién consiga convertirlo a 3D.
Ahora que hemos hecho una concha de caracol circular, vamos a pasar a las rejillas paramétricas. Vamos a usar una rotación básica en la espiral Fibonacci para crear una rejilla Fibonacci y modelar el resultado según el crecimiento de las semillas de girasol.
Como punto de partida, vamos a realizar el mismo paso del ejercicio anterior: crear una matriz de puntos de espiral con el nodo Point.ByCoordinates.
![](../images/5-3/2/math-part IV-01.jpg)
A continuación, siga estos pequeños pasos para generar una serie de espirales en varias rotaciones.
a. Geometry.Rotate: existen varias opciones de Geometry.Rotate; asegúrese de que ha elegido el nodo que contiene las entradas geometry, basePlane y degrees. Conecte Point.ByCoordinates en la entrada geometry. Haga clic con el botón derecho en este nodo y asegúrese de que el encaje se haya establecido en "Producto vectorial".
b. Plano.XY: conéctelo a la entrada basePlane. Rotaremos alrededor del origen, que es la misma ubicación que la base de la espiral.
c. Number Range: para la entrada de grados, vamos a crear varias rotaciones. Esto se puede realizar rápidamente con un componente Number Range. Conéctelo a la entrada degrees.
d. Number: para definir el rango de números, añada tres nodos numéricos al lienzo en orden vertical. De arriba a abajo, asigne valores de 0,0; 360,0 y 120,0 respectivamente. Estos valores controlan la rotación de la espiral. Observe los resultados de las salidas del nodo Number Range después de conectar los tres nodos numéricos al mismo.
Nuestro resultado empieza a parecerse a un remolino. Ajustemos algunos de los parámetros de Number Range y veamos cómo cambian los resultados.
Cambie el tamaño de paso del nodo Number Range de 120,0 a 36,0. Observe que esto crea más rotaciones y que, por tanto, nos proporciona una rejilla más densa.
Cambie el tamaño de paso del nodo Number Range de 36,0 a 3,6. Esto nos da una rejilla mucho más densa y la dirección de la espiral no está clara. Damas y caballeros, hemos creado un girasol.
La lógica o, más específicamente, la lógica condicional nos permite especificar una acción o un conjunto de acciones basadas en una prueba. Tras evaluar la prueba, dispondremos de un valor booleano que representa True
o False
que podemos utilizar para controlar el flujo del programa.
Las variables numéricas pueden almacenar una gran variedad de números diferentes. Las variables booleanas solo pueden almacenar dos valores denominados Verdadero o Falso, Sí o No, 1 o 0. Rara vez utilizamos booleanos para realizar cálculos debido a su rango limitado.
La instrucción "If" ("si") es un concepto clave en la programación: "Si esto es cierto, eso ocurre; de lo contrario, otra cosa ocurre. La acción resultante de la instrucción se rige por un valor booleano. Hay varias formas de definir una instrucción "If" en Dynamo:
Icono | Nombre (sintaxis) | Entradas | Salidas |
---|
Veamos un breve ejemplo de cada uno de estos tres nodos en acción mediante la instrucción condicional "If".
En esta imagen, el nodo Boolean se ha establecido en Verdadero (True), lo que significa que el resultado es una cadena que dice: "este es el resultado si es verdadero". Los tres nodos que crean la instrucción If funcionan de la misma forma aquí.
De nuevo, los nodos funcionan de la misma forma. Si el nodo Boolean se cambia a Falso (False), el resultado es el número Pi, tal y como se define en la instrucción If original.
Descargue el archivo de ejemplo. Para ello, haga clic en el vínculo siguiente.
En el Apéndice, se incluye una lista completa de los archivos de ejemplo.
Usemos la lógica para separar una lista de números en una lista de números pares y una lista de números impares.
a. Number Range: añada un rango de números al lienzo.
b. Nodos Number: añada tres nodos numéricos al lienzo. El valor de cada nodo numérico debe ser 0,0 para start, 10,0 para end y 1,0 para step.
c. Salida: nuestra salida es una lista de 11 números que van del 0 al 10.
d. Módulo (%): Number Range se conecta a x y 2,0 a y. De este modo, se calcula el resto de cada número de la lista dividido por 2. La salida de esta lista nos proporciona una lista de valores alternantes entre 0 y 1.
e. Prueba de igualdad (==): añada una prueba de igualdad al lienzo. Conecte la salida de módulo a la entrada x y 0,0 en la entrada y.
f. Watch: la salida de la prueba de igualdad es una lista de valores que alterna entre verdadero y falso. Estos son los valores utilizados para separar los elementos de la lista. 0 (o true) representa números pares y 1 (o false) representa números impares.
g. List.FilterByBoolMask: este nodo filtrará los valores en dos listas diferentes en función del valor booleano de entrada. Conecte el nodo Number Range original a la entrada list y la salida de la prueba de igualdad en la entrada mask. La salida in representa los valores verdaderos, mientras que la salida out representa los valores falsos.
h. Watch: como resultado, ahora tenemos una lista de números pares y una de impares. Hemos utilizado operadores lógicos para separar las listas en patrones.
Basándonos en la lógica establecida en el primer ejercicio, vamos a aplicar esta configuración en una operación de modelado.
2. Comenzaremos por donde dejamos el ejercicio anterior, con los mismos nodos. Las únicas excepciones (además de cambiar el formato) son las siguientes:
a. Utilice un nodo Sequence con estos valores de entrada.
b. Se ha desconectado la entrada list en List.FilterByBoolMask. Dejaremos estos nodos a un lado por ahora, pero en fases posteriores del ejercicio serán muy útiles.
3. Creemos primero un grupo independiente de gráficos, como se muestra en la imagen anterior. Este grupo de nodos representa una ecuación paramétrica para definir una curva de línea. Información que debemos tener en cuenta:
a. El primer control deslizante de número representa la frecuencia de la onda; debe tener un mínimo de 1, un máximo de 4 y un paso de 0,01.
b. El segundo control deslizante de número representa la amplitud de la onda; debe tener un mínimo de 0, un máximo de 1 y un paso de 0,01.
c. PolyCurve.ByPoints: si se copia el diagrama de nodos anterior, el resultado es una curva de seno en la ventana de vista preliminar de Dynamo.
El método que se sigue para las entradas es utilizar nodos numéricos para las propiedades más estáticas y controles deslizantes de número para las más flexibles. Vamos a mantener el rango de números original que definimos al principio de este paso. Sin embargo, la curva de seno que se crea aquí debe tener cierta flexibilidad. Se pueden mover estos controles deslizantes para ver cómo se actualiza la frecuencia y la amplitud de la curva.
4. Vamos a saltar un poco en la definición, así que veamos el resultado final para que podamos tener como referencia lo que vamos a conseguir. Los dos primeros pasos se realizan por separado; ahora queremos conectar los dos. Utilizaremos la curva de seno base para controlar la ubicación de los componentes de cremallera y utilizaremos la lógica de verdadero/falso para alternar entre cuadros pequeños y cuadros más grandes.
a. Math.RemapRange: con la secuencia de números creada en el paso 02, vamos a crear una nueva serie de números reasignando el rango. Los números originales del paso 01 van del 0 al 100. Estos números oscilan entre 0 y 1 en las entradas newMin y newMax respectivamente.
5. Cree un nodo Curve.PointAtParameter y, a continuación, conecte la salida Math.RemapRange del paso 04 como su entrada param.
Este paso crea puntos a lo largo de la curva. Hemos reasignado los números a entre 0 y 1 porque la entrada param busca valores en este rango. El valor 0 representa el punto inicial; el valor 1 representa los puntos finales. Todos los números que se encuentran en medio se evalúan dentro del rango de [0,1].
6. Conecte la salida de Curve.PointAtParameter a List.FilterByBoolMask para separar la lista de índices pares e impares.
a. List.FilterByBoolMask: conecte el nodo Curve.PointAtParameter del paso anterior a la entrada list.
b. Watch: un nodo de visualización para in y otro para out indican que hay dos listas que representan índices pares e impares. Estos puntos se ordenan de la misma forma en la curva, que se muestra en el siguiente paso.
7. A continuación, vamos a utilizar el resultado de salida de List.FilterByBoolMask en el paso 05 para generar geometrías con tamaños según sus índices.
Cuboid.ByLengths: reproduzca las conexiones representadas en la imagen anterior para obtener una cremallera a lo largo de la curva de seno. Un cubo es solo un cuadro, y estamos definiendo su tamaño basándonos en el punto de curva del centro del cuadro. La lógica de la división par/impar debería ser clara ahora en el modelo.
a. Lista de ortoedros en índices uniformes.
b. Lista de ortoedros en índices impares.
Y eso es todo. Acaba de programar un proceso para definir las cotas de geometría de acuerdo con la operación lógica que se muestra en este ejercicio.
Icono | Nombre/sintaxis | Entradas | Salidas |
---|---|---|---|
Object.IsNull
obj
bool
Color ARGB (Color.ByARGB)
A,R,G,B
color
Alfa (Color.Alpha)
color
A
Rojo (Color.Red)
color
R
Verde (Color.Green)
color
G
Azul (Color.Blue)
color
B
Componentes (Color.Components)
color
A, R, G, B
Matiz (Color.Hue)
color
Matiz
Saturación (Color.Saturation)
color
Saturación
Brillo (Color.Brightness)
color
Brillo
Sumar (+)
var[]...[], var[]...[]
var[]...[]
Restar (-)
var[]...[], var[]...[]
var[]...[]
Multiplicar (*)
var[]...[], var[]...[]
var[]...[]
Dividir (/)
var[]...[], var[]...[]
var[]...[]
If (If) | test, true, false | resultado |
Formula (IF(x,y,z)) | x, y, z | resultado |
Code Block ((x?y:z);) | x? y, z | resultado |