language agnostic - Idioma o paquete para dibujar diagramas geométricos.
language-agnostic math (12)
... el código más corto y simple, en cualquier idioma preexistente y utilizando cualquier paquete preexistente, para dibujar una cuadrícula hexagonal con su cuadrícula triangular doble superpuesta encima de ella; ...
En Mathematica estándar 7:
Tessellation[nr_, x_, y_] := Line[Table[{Cos[2 Pi k/nr] + x, Sin[2 Pi k/nr] + y}, {k, nr + 1}]]
draw2T [in_, jn_] := Graphics[{
{EdgeForm[Opacity[.5]], Thickness[Tiny], LightGray, Table[Tessellation[6, 3 i + 3 ((-1)^j + 1)/4, Sqrt[3]/2 j], {i, in}, {j, jn}]},
{EdgeForm[Opacity[.5]], Thickness[Large], Gray, Table[Tessellation[3, 3 i + 3 ((-1)^j + 1)/4, (Sqrt[3]/2 j)], {i, in}, {j, jn}]}}]
Mathematica puede exportar imágenes a: {pdf, página web, html, bmp, eps, gif, jpg, jpg2000, pcx, png, pnm, pxr, mapa de bits sin formato, svg, tiff, ega, emf, wmf}.
Cómo usar el polígono en Mathematica: ( link )
Qué es tesselation: ( link )
Salida para: draw2T[4, 8]
Justo antes de publicar, me di cuenta:
la cuadrícula triangular dual es la cuadrícula triangular que obtienes si conectas el centro de cada hexágono al centro de cada uno de los hexágonos vecinos.
Para eso, solo necesitas desplazar los segundos gráficos. Tenga en cuenta que antes de guardarlo en cualquier formato, es una colección de formas, y puede editar todos los elementos visuales (Eso es simplemente impresionante).
Editar:
Con arreglo
draw2T [in_, jn_] := Graphics[{
{EdgeForm[Opacity[.5]], Thickness[Tiny], LightGray, Table[Tessellation[6, 3 i + 3 ((-1)^j + 1)/4, Sqrt[3]/2 j], {i, in}, {j, jn}]},
{EdgeForm[Opacity[.5]], Thickness[Large], Gray, Table[Tessellation[3, 0.5 + 3 i + 3 ((-1)^j + 1)/4, Sqrt[3]/2 + (Sqrt[3]/2 j)], {i, in}, {j, jn}]}}]
Estoy buscando un idioma, o paquete en un idioma existente, que sea bueno para especificar y dibujar diagramas geométricos.
Por ejemplo, me gustaría dibujar una cuadrícula hexagonal, con su cuadrícula triangular doble superpuesta en ella. Ahora, podría sentarme, poner un poco de grasa en el codo para trabajar el gatillo a mano y crear un PostScript o SVG que muestre dicha cuadrícula. Pero me pregunto si hay algún idioma o paquete que me ayude con esto; que facilitan la especificación de una cuadrícula hexagonal, encontrar los centros y dibujar una cuadrícula triangular sobre ella.
¿Cuál es la forma más fácil de hacer esto?
Se agradecerán ejemplos de código, que muestran lo fácil que es crear diagramas geométricamente especificados. En particular, demuestre lo fácil que es dibujar una cuadrícula hexagonal; Si bien puedo hacerlo en cualquier idioma dibujando todas las líneas a mano, me interesan los idiomas o paquetes que hacen que este tipo de diagrama geométrico sea fácil y claro.
Generosidad
Dado que esta pregunta ha sido respondida, pero la respuesta es más complicada de lo que preferiría, ofreceré una recompensa a la persona que pueda producir el código más corto y sencillo, en cualquier idioma preexistente y utilizando cualquier paquete preexistente, por ejemplo. dibujando una cuadrícula hexagonal con su cuadrícula triangular doble superpuesta encima de ella; la cuadrícula triangular dual es la cuadrícula triangular que obtienes si conectas el centro de cada hexágono al centro de cada uno de los hexágonos vecinos. Vea la respuesta de Antal S-Z por ejemplo; Su ejemplo hace el trabajo, pero estaba buscando un lenguaje que facilitara este problema. Puede producir una cuadrícula que sea aproximadamente rectangular, como en su ejemplo (las filas impares alineadas y las filas pares alineadas), o una en el estilo de un tablero Hex (cada fila se desplaza a la derecha en un medio hexágono, formando un rombo). ); ambos son aceptables
El programa puede tomar entrada ya sea en forma de una función o subrutina en el lenguaje que toma un número de filas y número de columnas, o tomar la entrada pasada en la línea de comando que indica filas y columnas. Debe producir resultados en cualquier formato de gráficos estándar y común, como PostScript, PDF, SVG, PNG o PNM ; la salida debe contener la cuadrícula hexagonal y la cuadrícula triangular, en un color de contraste, grosor de línea o estilo de línea para que el diagrama sea claro.
Estoy buscando la respuesta más corta y sencilla, como una forma de encontrar el idioma o el paquete que mejor describa este tipo de diagramas; La recompensa irá al programa más corto que resuelva el problema. Esto no es código de golf, por lo que no contaré por conteo de caracteres o líneas de código. Si no hay una respuesta obvia, la medida se basará en el conteo de fichas; ¿Cuántas fichas en su idioma se necesitan para expresar este problema? Por lo tanto, las constantes legibles y los nombres de variables, mediante el uso de funciones de biblioteca, comentarios, espacios en blanco y similares, están bien, ya que no aumentan el conteo de tokens. Todavía no es una métrica perfecta (Lisps tendrá algunos tokens más, ya que necesitará más paréntesis para delimitar sus expresiones aritméticas, y estoy seguro de que si optimiza en exceso para esta métrica aún puede producir un código ilegible), pero es Una guía aproximada de cuán complejo es su código.
Entonces, el desafío, para la recompensa, es crear el programa más corto que dibuja una cuadrícula hexagonal con su cuadrícula triangular superpuesta. Publique su código, los enlaces al idioma y cualquier paquete que haya usado, un conteo aproximado de token si es posible, y una imagen de salida de ejemplo. La respuesta existente es la barra que tendrás que superar para calificar; hace el trabajo, pero me gustaría algo más corto y más simple.
Para darme el tiempo suficiente para ver las respuestas y otorgar la recompensa, todas las respuestas deben enviarse al menos 24 horas antes de la fecha límite de la recompensa. Puedo o no considerar cualquier respuesta enviada menos de 24 horas antes de la fecha límite.
Aunque gnuplot
está diseñado para visualizar interactivamente funciones y datos matemáticos, también se puede usar para dibujar algunos diagramas. Este código es un ejemplo:
#!/usr/local/bin/gnuplot -p
set size ratio -1 # x and y axes have same unit length
unset border # erases the axes
unset tics # erases tic labels
# polygon-center is translated by vector (x0,y0)
x0 = 2.0 * cos(pi/6.0)**2
y0 = sin(pi/3.0)
jmax=4
imax=3
# drawing a triangular grid (joining the centers)
set for [i=0:imax] arrow from i*x0,i*y0 to (i+jmax)*x0,(i-jmax)*y0 nohead lc rgb ''gray'' back
set for [j=0:jmax] arrow from j*x0,-j*y0 to (imax+j)*x0,(imax-j)*y0 nohead lc rgb ''gray'' back
set for [k=1:imax+jmax-1] arrow /
from k*x0, (k<=imax ? k : 2*imax-k)*y0 /
to k*x0,-(k<=jmax ? k : 2*jmax-k)*y0 nohead lc rgb ''gray'' back
# drawing an hexagonal diagram
do for [j=0:jmax] { # translates center right-down
do for [i=0:imax] { # translates center right-up
# center coordinates
x(t) = (i+j)*x0 + cos(t*pi/180.0)
y(t) = (i-j)*y0 + sin(t*pi/180.0)
# draw an hexagon
set obj polygon from x(0),y(0) /
to x(60),y(60) to x(120),y(120) to x(180),y(180) /
to x(240),y(240) to x(300),y(300) to x(0),y(0)
}
}
# draws the canvas, 1/0=NAN is used to plot nothing :)
plot [-1:13][-5:5] 1/0 notitle
Este es el resultado:
Como han dicho otros, el lenguaje más extensible y documentado que se adapta a sus necesidades es probablemente PGF / TikZ. Acabo de aprender TikZ muy básico hace menos de una semana, así que espero que esto demuestre su poder:
/documentclass{article}
/usepackage{tikz}
/begin{document}
/begin{tikzpicture}
/newcommand{/hexcoord}[2]
{[shift=(0:#1),shift=(60:#1),shift=(0:#2),shift=(-60:#2)]}
% Five-by-five hexagonal grid
/foreach /x in {0,...,4}
/foreach /y in {0,...,4}
/draw/hexcoord{/x}{/y}
(0:1)--(60:1)--(120:1)--(180:1)--(-120:1)--(-60:1)--cycle;
% Dual triangular grid
/foreach /x in {0,...,4}
/foreach /y in {0,...,4}
/foreach /z in {0,60,...,300}
/draw[help lines]/hexcoord{/x}{/y}
(0,0) [rotate=/z,shift=(0:.5),shift=(60:.5)] -- (0,0);
/end{tikzpicture}
/end{document}
Aquí está el resultado:
Como en la otra respuesta, seis líneas son solo repetitivo para LaTeX. Tenga en cuenta que no tengo que hacer ningún cálculo, excepto para darme cuenta de que 60 grados es una sexta parte de 360 grados. Evito la raíz cuadrada de tres (la distancia entre hexágonos) utilizando transformaciones y muchas coordenadas polares. Si no te gustan las líneas dispersas en la cuadrícula dual, puedes recortarlas usando una región de recorte insertada después del segundo comentario:
/clip (0,0)
/hexcoord{ 4}{0}--(0,0)
/hexcoord{ 0}{4}--(0,0)
/hexcoord{-4}{0}--(0,0)
-- cycle;
Editar En realidad, la región de recorte se ve un poco mal. Aquí hay una versión más divertida, completa:
/documentclass{article}
/usepackage{tikz}
/begin{document}
/begin{tikzpicture}
/newcommand{/hexcoord}[2]
{[shift=(0:#1),shift=(60:#1),shift=(0:#2),shift=(-60:#2)]}
% Five-by-five hexagonal grid
/foreach /x in {0,...,4}
/foreach /y in {0,...,4}
/draw/hexcoord{/x}{/y}
(0:1)--(60:1)--(120:1)--(180:1)--(-120:1)--(-60:1)--cycle;
% Dual triangular grid
/foreach /x in {0,...,4}
/draw[help lines] /hexcoord{0}{/x}(0,0) /hexcoord{4}{0}--(0,0)
/hexcoord{-4}{4}/hexcoord{/x}{-/x}--(0,0)
/hexcoord{0}{-4}--(0,0) /hexcoord{-/x}{/x}--(0,0);
/end{tikzpicture}
/end{document}
Aquí está el resultado:
Generalmente uso MATLAB para esto.
La asíntota de la OMI es más adecuada para este tipo de cosas (a menos que desee una herramienta interactiva como geogebra ).
Es sencillo y muy sencillo. La salida por defecto es .eps
. Por ejemplo:
size(10cm,0);
guide ppath; /* for a hexagon''s path */
guide tpath; /* for a triangle''s path */
for (int i=1; i<=6; ++i) ppath=ppath--rotate((i-1)*360/6)*E;
for (int i=1; i<=6; ++i) tpath=tpath--rotate((i-1)*360/6)*((0,0)--(0,sqrt(3)/2));
transform T0=shift(1.5,sqrt(3)/2); /* shift to form a higher row */
transform T1=shift(1.5,-sqrt(3)/2); /* shift to form a lower row */
transform T2=shift(3,0); /* shift to the right */
for (int j=0; j<=4; ++j) {
for (int i=0; i<=4-j; ++i) {
draw(T0^j*T2^i*(ppath--cycle),blue); /* multiply each path */
draw(T0^j*T2^i*tpath,gray); /* by the transformation */
draw(T1^j*T2^i*(ppath--cycle),blue);
draw(T1^j*T2^i*tpath,gray);
}
}
Probablemente haya una forma aún más fácil de hacer esto, pero no estoy lo suficientemente familiarizado con la asíntota.
Pruebe MetaPost .
También me gustaría recomendar PGF / TikZ, con la advertencia de que está en TeX. Si no te sientes cómodo con la programación de TeX, puede ser un dolor de cabeza, ya que hay algunas ... idiosincrasias. (Tratar con espacios perdidos puede ser una aventura, por ejemplo). Sin embargo, si está dispuesto a hacer la programación TeX, lo recomiendo ampliamente; Lo uso con mucha frecuencia para dibujar figuras, incluso si no estoy trabajando en TeX. Además, su manual es absolutamente increíble , y la galería TeXample tiene muchísimos ejemplos excelentes.
El código de ejemplo para dibujar una cuadrícula hexagonal y triangularla es el siguiente. Admito que es bastante largo, pero creo que realmente no es tan malo.
/documentclass{article}
/usepackage{tikz}
/usepackage{ifthen}
/usetikzlibrary{calc}
/usetikzlibrary{shapes.geometric}
/tikzset{hexagon/.style={regular polygon, regular polygon sides = 6}}
/newif/ifHexgridTriangulate
/newif/ifHexgridStartShifted
/pgfqkeys{/hexgrid}
{ name/.store in = /HexgridName
, xpos/.store in = /HexgridX
, ypos/.store in = /HexgridY
, rows/.store in = /HexgridRows
, cols/.store in = /HexgridCols
, size/.code = {/pgfmathsetmacro{/HexDiameter}{#1}}
, triangulate/.is if = HexgridTriangulate
, start shifted/.is if = HexgridStartShifted }
/tikzset{ every hexgrid hex/.style 2 args = {draw}
, every hexgrid triangulator/.style = {}}
/newcommand{/hexgrid}[2][]{
/pgfqkeys{/hexgrid}{ name = hexgrid , size = 1cm
, xpos = 0 , ypos = 0
, triangulate = false
, start shifted = false
,#2 }
/ifHexgridStartShifted
/def/HexShiftModCheck{0}
/else
/def/HexShiftModCheck{1}
/fi
/begin{scope}[xshift=/HexgridX, yshift=/HexgridY,#1]
/pgfmathsetmacro{/HexRadius}{/HexDiameter/2}
/pgfmathsetmacro{/HexSide}{sqrt(3)*/HexRadius/2}
/pgfmathsetmacro{/HexWidth}{2*/HexSide}
/tikzset{every node/.style={hexagon, minimum size=/HexDiameter}}
/foreach /row in {1,...,/HexgridRows} {
/foreach /col in {1,...,/HexgridCols} {
/pgfmathsetmacro{/HexX}%
{/HexWidth*( (/col-1)
+ (mod(/row,2) == /HexShiftModCheck
? 0 : .5))}
/pgfmathsetmacro{/HexY}%
{-(/HexRadius + /HexSide/2 + 2*/pgflinewidth)*(/row-1)}
/node [hexagon, rotate=90, every hexgrid hex = {/row}{/col}]
(/HexgridName-/row-/col)
at (/HexX pt ,/HexY pt)
{} ;
}
}
/ifHexgridTriangulate
/begin{scope}[every path/.style={every hexgrid triangulator}]
/foreach /row in {1,...,/HexgridRows} {
/foreach /col in {1,...,/HexgridCols} {
% Using /pgfmathsetmacro always includes a decimal point, which
% breaks /ifnum.
/pgfmathparse{int(/row-1)}/let/prow/pgfmathresult
/pgfmathparse{int(/col-1)}/let/pcol/pgfmathresult
/ifnum/prow>0
/draw (/HexgridName-/prow-/col.center)
-- (/HexgridName-/row-/col.center) ;
/fi
/ifnum/pcol>0
/draw (/HexgridName-/row-/pcol.center)
-- (/HexgridName-/row-/col.center) ;
/fi
/ifnum/prow>0/ifnum/pcol>0
/pgfmathparse{mod(/prow,2) == /HexShiftModCheck}
/ifnum/pgfmathresult=1
/draw (/HexgridName-/prow-/col.center)
-- (/HexgridName-/row-/pcol.center) ;
/else
/draw (/HexgridName-/prow-/pcol.center)
-- (/HexgridName-/row-/col.center) ;
/fi
/fi/fi
}
}
/end{scope}
/fi
/end{scope}
}
/begin{document}
/begin{center}/begin{tikzpicture}
% Simplest case
/hexgrid{rows = 5, cols = 5}
% Every possible option at once
/hexgrid[ every hexgrid hex/.style 2 args = {ultra thick, draw=blue}
, every hexgrid triangulator/.style = {color=black!75} ]
{ name = thg , size = 1.5cm
, xpos = 0 , ypos = -5cm
, rows = 5 , cols = 5
, triangulate
, start shifted}
% Mark the center of that grid, just because we can.
/filldraw [red] (thg-3-3) circle (2pt) ;
/end{tikzpicture}/end{center}
/end{document}
El código anterior a /newcommand{/hexgrid}
solo incluye los paquetes necesarios y configura los argumentos de las palabras clave: name
establece el nombre utilizado para referirse a los hexágonos, size
establece el size
esquina a esquina de cada hexágono, posición xpos
y posición de ypos
la esquina superior izquierda de toda la cuadrícula, las rows
y las cols
determinan el número de hexágonos, la opción de triangulate
permite triangular la cuadrícula de manera opcional, y la opción de start shifted
tiene el inicio de la primera fila con sangría en lugar de la segunda fila. También permitiremos que el usuario pase comandos de estilo en el primer argumento opcional de /hexgrid
; every hexgrid hex/.style 2 args
les permitirá every hexgrid hex/.style 2 args
hexágonos individuales (e incluso consultar la posición de ese hex, si lo desean), y every hexgrid triangulator/.style
les permitirá every hexgrid triangulator/.style
las líneas de triangulación.
Saltando un poco, llegamos a las líneas /pgfsetmacro
; El diámetro de los hexágonos se especifica, por lo que tenemos que calcular el radio, la longitud del lado y luego el ancho de lado a lado. Los siguientes dos bucles /foreach
son la parte principal del código de dibujo, y espero que sean bastante claros. Tenga en cuenta que debemos tener en cuenta el grosor de las líneas al determinar la colocación vertical. Después de esto viene un bloque de código aún más largo, entre /ifHexgridTriangulate
y /fi
; esto es responsable de triangular la cuadrícula si se desea tal cosa.
Finalmente, podemos ver cómo se ve esto:
Usted debe revisar rfig .
Es una capa encima de metapost que le permite dibujar figuras arbitrarias (y hacer diapositivas en PDF) usando rubí. Puede definir sus propias funciones que toman argumentos y dibujan una forma (por ejemplo, un hexágono). Luego puede llamar a sus funciones repetidamente, etc. Le da el poder de metapost con la flexibilidad de programación en ruby.
Hay un ejemplo de algunas cifras generadas utilizando rfig en el sitio web que ofrece una buena muestra de la funcionalidad.
Asymptote también podría ser útil. (similar a metapost)
Xy-pic o MetaPost que probablemente ya estén instalados en tu computadora si tienes TeX.
ACTUALIZACIÓN : Después de intentar recordar cómo usar MetaPost y fallar ... Usé SketchUp de Google. Trivial para el diseño. Tal vez un programa de CAD diferente podría adaptarse a usted. Pero usar un programa de dibujo es, con mucho, lo más fácil. OpenOffice Draw, tal vez? Parece trampa, pero hizo el trabajo más rápido.
Aquí hay una imagen rápida realizada en OpenOffice Draw en unos minutos. Necesita un poco de trabajo en la relación de aspecto pero muestra lo básico.
ACTUALICE la segunda Se me ocurrió que una herramienta que usa un estilo declarativo como el GraphicsBuilder de Groovy es la mejor. Desafortunadamente, GraphicsBuilder parece requerir un nuevo nivel Groovy 1.6-beta-2. Así que volviendo a otra cosa, lo más similar resulta ser ... JavaFX . Aquí está el código (muy escaso, pero muestra lo que se puede hacer):
package hexgrid;
import javafx.scene.shape.Polygon;
import javafx.scene.paint.Color;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.shape.Line;
import javafx.scene.shape.Circle;
import javafx.util.Math;
/**
* @author arouse
*/
var scale = 60;
var width = 400;
var height = 400;
function hexagon(x: Number, y: Number): Polygon {
var basicpoints = [1, 0, 0.5, -0.866, -0.5, -0.866, -1, 0, -0.5, 0.866, 0.5, 0.866];
basicpoints = for (i in basicpoints) i * scale;
return Polygon {
points: basicpoints
fill: Color.WHITE
translateX: x
translateY: y
strokeWidth: 2
stroke: Color.BLUE
opacity: 0.3
}
}
var hexes = Group {
content: [
for (x in [0..width step scale * 3]) {
for (y in [0..height step 0.866 * scale * 2]) {
hexagon(x, y);
}
}
for (x in [0..width step scale * 3]) {
for (y in [0..height step 0.866 * scale * 2]) {
hexagon(x + 1.5 * scale, y + 0.866 * scale);
}
}
]
}
var lines60 = Group {
content: [
for (y in [0..height step scale]) {
Line {
startX: 0, startY: 2 * y * 0.866
endX: 3 * y, endY: 0
strokeWidth: 1
stroke: Color.BLACK
}
}
]
}
var lines120 = Group {
content: [
for (y in [(-Math.floor(height/10)*scale)..height step scale]) {
Line {
startX: 0, startY: 2*0.866*y
endX: width, endY: 2*0.866/3*width + 2*0.866*y
strokeWidth: 1
stroke: Color.BLACK
}
}
]
}
var linesdown = Group {
content: [
for (x in [0..width step scale*1.5]) {
Line {
startX: x, startY: 0
endX: x, endY: height
strokeWidth: 1
stroke: Color.BLACK
}}
]
}
Stage {
title: "Hex Grid with dual triangular grid"
scene: Scene {
width: width
height: height
fill: Color.WHITE
content: [
hexes,
lines60,
lines120,
linesdown
]
}
}
Lo que resulta en esto (y admito que podría ser mucho mejor):
Ventajas sobre otras respuestas: se puede utilizar para componer imágenes arbitrarias, texto, animaciones, etc., lenguaje de programación completo, interoperabilidad de Java. También viene con grandes tutoriales y extensa documentación. Netbeans IDE tiene un botón de vista previa muy agradable que es muy útil para una visualización casi instantánea de los resultados.
Y sí, podría haber hecho muchas cosas mejor en el código, pero hubo algunas cosas complicadas con las transformaciones y el relleno. Así que lo hice de la manera fea.
Por cierto, este es mi primer programa javafx. Apreciaría arreglos y cambios.