El objetivo de este desafío es producir una animación de un sistema de transmisión por cadena , compuesto por un conjunto de engranajes de piñón conectados entre sí por una cadena .
requerimientos generales
Su programa recibirá una lista de ruedas dentadas , especificadas como (x, y, radius)
trillizos. El sistema de accionamiento de la cadena resultante se compone de estas ruedas dentadas, conectadas entre sí por una cadena tensa cerrada que pasa sobre cada una de ellas, en orden . Su objetivo es producir una animación de bucle infinito , que muestre el sistema en movimiento. Por ejemplo, dada la entrada
(0, 0, 16), (100, 0, 16), (100, 100, 12), (50, 50, 24), (0, 100, 12)
, la salida debería verse algo así
.
El sistema de coordenadas debe ser tal que el eje x apunte hacia la derecha y el eje y apunte hacia arriba. Puede suponer que los radios son números pares mayores o iguales a 8 (veremos por qué esto importa más adelante). También puede suponer que hay al menos dos ruedas dentadas y que las ruedas dentadas no se cruzan entre sí. Las unidadesde la entrada no son demasiado críticos. Todos los ejemplos y casos de prueba en esta publicación usan píxeles como unidades de entrada (por lo tanto, por ejemplo, el radio de la rueda dentada central en la figura anterior es de 24 píxeles;) trate de no desviarse demasiado de estas unidades. En el resto del desafío, se entiende que las cantidades espaciales se dan en las mismas unidades que la entrada; ¡asegúrese de mantener las proporciones correctas! Las dimensiones de la salida deben ser ligeramente más grandes que el cuadro delimitador de todas las ruedas dentadas, lo suficientemente grandes como para que todo el sistema sea visible. En particular, las posiciones absolutas de las ruedas dentadas no deberían afectar la salida; solo sus posiciones relativas deberían (así, por ejemplo, si cambiamos todas las ruedas dentadas en el ejemplo anterior por la misma cantidad, la salida seguirá siendo la misma).
La cadena debe ser tangente a las ruedas dentadas sobre las que pasa en todos los puntos de contacto, y en línea recta en cualquier otro lugar. La cadena debe pasar sobre las ruedas dentadas de manera que los segmentos de cadena adyacentes (es decir, partes de la cadena entre dos ruedas dentadas, que se encuentran en la misma rueda dentada) no se crucen entre sí.
.
Por ejemplo, mientras que el sistema izquierdo de arriba es válido, el del medio no lo es, ya que los dos segmentos de cadena adyacentes que pasan sobre la rueda dentada inferior izquierda se cruzan. Sin embargo, tenga en cuenta que el sistema correcto es válido, ya que los dos segmentos de la cadena de intersección no son adyacentes (sin embargo, este sistema es producido por una entrada diferente a los otros dos).
Para simplificar las cosas (r), puede suponer que ninguna rueda dentada se cruza con el casco convexo de sus dos ruedas dentadas vecinas, o las cascas convexas de cada uno de sus vecinos y su otro vecino. En otras palabras, la rueda dentada superior en el siguiente diagrama puede no cruzarse con ninguna de las regiones sombreadas.
Los segmentos de cadena pueden cruzarse con ruedas dentadas distintas de las que pasan (como en el último caso de prueba). En este caso, la cadena siempre debe aparecer delante de las ruedas dentadas.
Requerimientos visuales
La cadena debe consistir en una serie de eslabones de anchos alternos. El ancho del enlace estrecho debe ser de aproximadamente 2, y el ancho del enlace ancho debe ser de aproximadamente 5. La longitud de ambos tipos de enlaces debe ser aproximadamente igual. El periodode la cadena, es decir, la longitud total de un par de enlaces ancho / estrecho, debe ser el número más cercano a 4π que se ajuste a un número entero de veces en la longitud de la cadena. Por ejemplo, si la longitud de la cadena es 1,000, entonces su período debe ser 12.5, que es el número más cercano a 4π (12.566 ...) que se ajusta a un número entero de veces (80) en 1,000. Es importante que el período se ajuste a un número entero de veces en la longitud de la cadena, para que no haya artefactos en el punto donde la cadena se enrolla.
Una rueda dentada de radio R debe constar de tres partes concéntricas: un eje central , que debe ser un círculo de radio de aproximadamente 3; el cuerpo del piñón , alrededor del eje, que debería ser un círculo de radio alrededor de R - 4.5; y el borde de la rueda dentada , alrededor del cuerpo, que debería ser un círculo de radio alrededor de
R - 1.5. El borde también debe contener los dientes del piñón , que deben tener un ancho de aproximadamente 4; El tamaño y el espacio de los dientes deben coincidir con los tamaños de los eslabones de la cadena, para que encajen perfectamente.
El período de los dientes de la rueda dentada, es decir, la distancia entre dos dientes consecutivos a lo largo de la circunferencia de la rueda dentada, debe coincidir con el período de la cadena. Como el período es de aproximadamente 4π, y dado que se garantiza que el radio de la rueda dentada sea uniforme, el período debe caber en la circunferencia de la rueda dentada un número casi entero de veces, de modo que no debería haber artefactos notables en el punto donde los dientes de la rueda dentada se enrollan.
Puede usar cualquier combinación de colores para la cadena, las diferentes partes de la rueda dentada y el fondo, siempre que sean fácilmente distinguibles . El fondo puede ser transparente. Los ejemplos en este post se usan #202020
para la cadena, #868481
para el eje y el borde #646361
de la rueda dentada , y para el cuerpo de la rueda dentada.
Requisitos de animación
La primera rueda dentada en la lista de entrada debe girar en sentido horario ; El resto de las ruedas dentadas deben girar en consecuencia. La cadena debe moverse a una velocidad de aproximadamente 16π (aproximadamente 50) unidades por segundo; la velocidad de fotogramas depende de usted, pero la animación debería verse lo suficientemente suave.
La animación debería repetirse sin problemas .
Conformidad
Algunos de los atributos y proporciones visuales se especifican intencionalmente solo de manera aproximada: no es necesario que coincidan exactamente . La salida de su programa no tiene que ser una réplica de píxel a píxel de los ejemplos dados aquí, pero debería ser similar. En particular, las proporciones exactas de la cadena y las ruedas dentadas, y la forma exacta de los eslabones y los dientes de la cadena, son flexibles.
Los puntos más importantes a seguir son estos:
- La cadena debe pasar sobre las ruedas dentadas, en el orden de entrada, desde la dirección correcta.
- La cadena debe ser tangente a las ruedas dentadas en todos los puntos de contacto.
- Los eslabones de la cadena y los dientes de las ruedas dentadas deben engranarse perfectamente, al menos para corregir la separación y la fase.
- El espacio entre los eslabones de la cadena y los dientes de las ruedas dentadas debe ser tal que no haya artefactos notables en el punto donde se envuelven.
- Las ruedas dentadas deben girar en la dirección correcta.
- La animación debería repetirse sin problemas.
Como nota final, mientras que, técnicamente, el objetivo de este desafío es escribir el código más corto, si tienes ganas de ser creativo y producir un resultado más elaborado, ¡hazlo!
Desafío
Escriba un programa o una función , tome una lista de ruedas dentadas y produzca la animación correspondiente del sistema de transmisión por cadena, como se describió anteriormente.
Entrada y salida
Puede tomar la entrada a través de la línea de comando , a través de STDIN , como argumentos de función , o utilizando un método equivalente . Puede usar cualquier formato conveniente para la entrada, pero asegúrese de especificarlo en su publicación.
Como salida , puede mostrar la animación directamente , producir un archivo de animación (por ejemplo, un GIF animado) o producir una secuencia de archivos de marco (sin embargo, hay una pequeña penalización en este caso; ver más abajo). Si usa la salida de archivo, asegúrese de que el número de fotogramas sea razonable (los ejemplos en esta publicación usan muy pocos fotogramas;) el número de fotogramas no tiene que ser mínimo, pero no debe producir demasiados fotogramas superfluos. Si genera una secuencia de fotogramas, asegúrese de especificar la velocidad de fotogramas en su publicación.
Puntuación
Este es el código de golf . La respuesta más corta , en bytes, gana.
Penalización de + 10% Si su programa produce una secuencia de cuadros como salida, en lugar de mostrar la animación directamente o producir un solo archivo de animación, agregue 10% a su puntaje.
Casos de prueba
Prueba 1
(0, 0, 26), (120, 0, 26)
Prueba 2
(100, 100, 60), (220, 100, 14)
Prueba 3
(100, 100, 16), (100, 0, 24), (0, 100, 24), (0, 0, 16)
Prueba 4
(0, 0, 60), (44, 140, 16), (-204, 140, 16), (-160, 0, 60), (-112, 188, 12),
(-190, 300, 30), (30, 300, 30), (-48, 188, 12)
Prueba 5
(0, 128, 14), (46.17, 63.55, 10), (121.74, 39.55, 14), (74.71, -24.28, 10),
(75.24, -103.55, 14), (0, -78.56, 10), (-75.24, -103.55, 14), (-74.71, -24.28, 10),
(-121.74, 39.55, 14), (-46.17, 63.55, 10)
Prueba 6
(367, 151, 12), (210, 75, 36), (57, 286, 38), (14, 181, 32), (91, 124, 18),
(298, 366, 38), (141, 3, 52), (80, 179, 26), (313, 32, 26), (146, 280, 10),
(126, 253, 8), (220, 184, 24), (135, 332, 8), (365, 296, 50), (248, 217, 8),
(218, 392, 30)
Respuestas:
JavaScript (ES6),
2557191518971681 bytesEsto no es super- golfista realmente; está minimizado, en parte a mano, pero eso no es nada especial. Sin duda, podría ser más corto si hubiera jugado más golf antes de minificar, pero ya he dedicado (más que) suficiente tiempo a esto.
Editar: Ok, así que pasé más tiempo en él y jugué el código más antes de minificar (esta vez de forma muy manual). El código sigue usando el mismo enfoque y estructura general, pero aun así terminé ahorrando 642 bytes. No está mal, si lo digo yo mismo. Probablemente perdí algunas oportunidades de ahorro de bytes, pero en este momento ni siquiera estoy seguro de cómo funciona. Lo único que es diferente en términos de salida, es que ahora usa colores ligeramente diferentes que podrían escribirse más brevemente.
Edición 2 (mucho más tarde): guardado 18 bytes. Gracias a ConorO'Brien en los comentarios por señalar lo cegadoramente obvio que me había perdido por completo.
Edición 3: Entonces, pensé en aplicar ingeniería inversa a mi propio código, porque, francamente, no podía recordar cómo lo había hecho, y perdí las versiones sin golf. Así que revisé, y he aquí que encontré otros 316 bytes para ahorrar reestructurando y haciendo un poco de micro golf.
La función anterior agrega un elemento SVG (incluidas animaciones) al documento. Por ejemplo, para mostrar el segundo caso de prueba:
Parece ser una delicia, al menos aquí en Chrome.
Pruébelo en el fragmento a continuación (al hacer clic en los botones se dibujarán cada uno de los casos de prueba de OP).
Mostrar fragmento de código
El código dibuja la cadena y los dientes del engranaje como trazos discontinuos. Luego usa
animate
elementos para animar elstroke-dashoffset
atributo. El elemento SVG resultante es autocontenido; no hay animación basada en JS o estilo CSS.Para que las cosas se alineen bien, el anillo de dientes de cada engranaje se dibuja en realidad como una ruta que consta de dos arcos, por lo que la ruta puede comenzar justo en el punto tangente donde toca la cadena. Esto hace que sea mucho más simple alinearlo.
Además, parece que hay muchos errores de redondeo al usar los trazos discontinuos de SVG. Al menos, eso es lo que vi; cuanto más larga sea la cadena, peor se engranará con cada equipo sucesivo. Entonces, para minimizar el problema, la cadena está compuesta de varias rutas. Cada ruta consiste en un segmento de arco alrededor de un engranaje y una línea recta al siguiente engranaje. Sus compensaciones de tablero se calculan para que coincidan. Sin embargo, la parte delgada "interna" de la cadena es solo una ruta de bucle, ya que no está animada.
fuente
R=g=>...
<g>
, sino que lo puse directamente en la raíz svg. También encontré un lugar donde transformó la bandera de barrido y la bandera de arco grande de booleano a número usando1*x
, pero podría usar+x
C # 3566 bytes
No juega golf en absoluto, perofunciona (creo)Ungolfed en la historia de edición.
Utiliza Magick.NET para renderizar gif.
La clase P tiene una función F; Ejemplo:
fuente
public
modificador antes de cada campo de tu clase?using
que deben incluirse las cláusulas correspondientes , o los tipos completamente calificados cuando se usan, y la referencia a System.Drawing debe tenerse en cuenta en la respuesta (si debería agregar al puntaje no lo sé). Impresionante respuesta de todos modos.JavaScript (ES6) 1626 bytes
Esta solución es el resultado de la ingeniería inversa de la solución de @ Flambino, la publico con su acuerdo.
La versión sin golf:
fuente