Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Language or package for drawing geometric diagrams

Tags:

I am looking for a language, or package in an existing language, that is good for specifying and drawing geometric diagrams.

For example, I would like to draw a hexagonal grid, with its dual triangular grid superimposed on it. Now, I could sit down, put some elbow grease in to work out the trig by hand and come up with some Postscript or SVG that will display such a grid. But I'm wondering if there are any languages or packages that will help me out with this; that make it easy to specify a hexagonal grid, find the centers, and draw a triangular grid over it.

What's the easiest way to do this?

Code examples, showing how easy it is to create such geometrically specified diagrams, would be appreciated. In particular, please demonstrate how easy it is to draw a hexagonal grid; while I could do that in any language by drawing all the lines by hand, I'm interested in languages or packages which make that sort of geometric diagram easy and clear.

Bounty

Since this question has been answered, but the answer is more complicated than I would prefer, I will offer a bounty to the person who can produce the shortest and simplest code, in any pre-existing language and using any pre-existing package, for drawing a hexagonal grid with its dual triangular grid superimposed on top of it; the dual triangular grid is the triangular grid you get if you connect the center of each hexagon to the center of each of the neighboring hexagons. See Antal S-Z's answer for example; his example does the job, but I was looking for a language that would make this problem easier. You may either produce a grid which is roughly rectangular, as in his example (the odd rows aligned, and the even rows aligned), or one in the style of a Hex board (every row shifted right by a half hex, forming a rhombus); both are acceptable.

The program may take input either in the form of a function or subroutine in the language which takes a number of rows and number of columns, or take input passed in on the command line indicating rows and columns. It should produce output in any standard and common graphics format, such as Postscript, PDF, SVG, PNG or PNM; the output should contain the hex grid and triangular grid, in some contrasting color, line weight, or line style to make the diagram clear.

I'm looking for the shortest and simplest answer, as a way to find the language or package that is best for describing these sorts of diagrams; the bounty will go to the shortest program that solves the problem. This is not code golf, so I won't be counting by character count or lines of code. If there is not an obvious shortest answer, then I will measure based on token count; how many tokens in your language does it take to express this problem? Thus, readable constants and variable names, using library functions, comments, whitespace and the like are all fine, as they don't increase the token count. It's still not a perfect metric (Lisps will have a few more tokens as you need more parentheses to delimit your arithmetic expressions, and I'm sure that if you over-optimize for this metric you can still produce some unreadable code), but it's a rough guide to how complex your code is.

So, the challenge, for the bounty, is to create the shortest program that draws a hex grid with its superimposed triangular grid. Please post your code, links to the language and any packages you've used, a rough token count if possible, and an example output image. The existing answer is the bar you'll have to beat to qualify; it does the job, but I would like something shorter and simpler.

In order to give me enough time to look at the answers and award the bounty, all answers must be submitted at least 24 hours before the bounty deadline. I may or may not consider any answers submitted less than 24 hours before the deadline.

like image 898
Brian Campbell Avatar asked Oct 23 '10 16:10

Brian Campbell


People also ask

Which software is used to draw geometric figures?

As of 2018, Desmos has released a geometry tool typically for drawing geometry diagrams. That means, using Desmos to draw diagrams no longer requires too much mathematical background.

How do you make a geometry diagram in Word?

Click in your document where you want to create the drawing. On the Insert tab, in the Illustrations group, click Shapes. When you find the shape you want to insert, double-click to insert it automatically, or click and drag to draw it in your document.


1 Answers

I would also like to recommend PGF/TikZ, with the caveat that it's in TeX. If you aren't comfortable doing TeX programming, it may be a bit of a headache, since there are some… idiosyncrasies. (Dealing with stray spaces can be an adventure, for instance.) If you are willing to do the TeX programming, though, I highly recommend it; I use it very frequently for drawing figures even if I'm not working in TeX. Additionally, its manual is absolutely amazing, and the TeXample gallery has tons of great examples.

The example code to draw a hex grid and triangulate it is as follows. I'll admit that it's pretty long, but I think it's really not that bad.

\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} 

The code before \newcommand{\hexgrid} just includes the required packages and sets up the keyword arguments: name sets the name used to refer back to the hexagons, size sets the corner-to-corner size of each hexagon, xpos and ypos position the top left corner of the whole grid, rows and cols determine the number of hexagons, the triangulate option allows you to optionally triangulate the grid, and the start shifted option has the first row start indented instead of the second row. We'll also allow the user to pass styling commands in the first, optional, argument of \hexgrid; every hexgrid hex/.style 2 args will allow them to style individual hexagons (and even query the position of that hex, if they want), and every hexgrid triangulator/.style will allow them to style the triangulating lines.

Skipping a bit, we come to the \pgfsetmacro lines; the diameter of the hexagons is specified, so we have to calculate the radius, the side length, and then the width from side to side. The following two \foreach loops are the meat of the drawing code, and should hopefully be pretty clear. Note that we have to take the thickness of the lines into account when determining vertical placement. After this comes an even longer block of code, between \ifHexgridTriangulate and \fi; this is responsible for triangulating the grid if such a thing is desired.

Finally, we get to see what this looks like:

Example hex grids.

like image 151
Antal Spector-Zabusky Avatar answered Oct 31 '22 22:10

Antal Spector-Zabusky