Подтвердить что ты не робот

Язык или пакет для рисования геометрических диаграмм

Я ищу язык или пакет на существующем языке, который хорош для указания и рисования геометрических диаграмм.

Например, я хотел бы нарисовать гексагональную сетку, наложенную на нее двойную треугольную сетку. Теперь, я мог бы сесть, положить немного жира в локоть, чтобы выработать триггер вручную и придумать некоторые Postscript или SVG, которые будут отображать такую ​​сетку. Но мне интересно, есть ли какие-либо языки или пакеты, которые помогут мне в этом; что позволяет легко определить гексагональную сетку, найти центры и нарисовать треугольную сетку над ней.

Какой самый простой способ сделать это?

Приводятся примеры кода, показывающие, как легко создавать такие геометрически определенные диаграммы. В частности, пожалуйста, продемонстрируйте, насколько легко нарисовать гексагональную сетку; в то время как я мог бы сделать это на любом языке, рисуя все строки вручную, меня интересуют языки или пакеты, которые делают эту геометрическую диаграмму простой и понятной.

Bounty

Поскольку на этот вопрос был дан ответ, но ответ более сложный, чем я бы предпочел, я предлагаю награду человеку, который может создать самый короткий и простейший код на любом уже существующем языке и использовать любые ранее существовавшие пакет, для рисования шестиугольной сетки с двойной треугольной сеткой, наложенной поверх нее; двойная треугольная сетка - это треугольная сетка, которую вы получаете, если вы соединяете центр каждого шестиугольника с центром каждого из соседних шестиугольников. См. ответ Анталя S-Z; его пример выполняет эту работу, но я искал язык, который облегчил бы эту проблему. Вы можете либо создать сетку, которая имеет прямоугольную форму, как в его примере (нечетные строки выровнены, так и четные строки выровнены) или один в стиле Hex (каждая строка сдвигается вправо на половину гекса, образуя ромб); оба приемлемы.

Программа может принимать входные данные либо в виде функции, либо подпрограммы на языке, который занимает несколько строк и количество столбцов, или принимать входные данные в командной строке, указывающие строки и столбцы. Он должен производить вывод в любом стандартном и общем графическом формате, таком как Postscript, PDF, SVG, PNG или PNM; выход должен содержать шестнадцатеричную сетку и треугольную сетку, в каком-то контрастирующем цвете, линейном весе или стиле линии, чтобы сделать диаграмму прозрачной.

Я ищу кратчайший и самый простой ответ, как способ найти язык или пакет, который лучше всего подходит для описания этих типов диаграмм; щедрость перейдет к кратчайшей программе, которая решает проблему. Это не кодекс гольфа, поэтому я не буду рассчитывать по количеству символов или строкам кода. Если нет очевидного кратчайшего ответа, я буду измерять на основе количества токенов; сколько же токенов на вашем языке требуется, чтобы выразить эту проблему? Таким образом, читаемые константы и имена переменных, использующие функции библиотеки, комментарии, пробелы и т.п., Все в порядке, поскольку они не увеличивают количество токенов. Это еще не идеальный показатель (у Lisps будет еще несколько токенов, так как вам нужно больше скобок, чтобы разграничить ваши арифметические выражения, и я уверен, что если вы переопределяете этот показатель, вы все равно можете создать нечитаемый код), но он приблизительное руководство к тому, насколько сложным является ваш код.

Итак, задача для щедрот - создать кратчайшую программу, которая рисует шестнадцатеричную сетку с наложенной треугольной сеткой. Пожалуйста, разместите свой код, ссылки на язык и все использованные вами пакеты, приблизительный подсчет маркера, а также примерное выходное изображение. Существующий ответ - это бар, который вам нужно будет обыграть; он выполняет эту работу, но мне хотелось бы сделать что-то более короткое и простое.

Чтобы дать мне достаточно времени, чтобы посмотреть ответы и присудить награду, все ответы должны быть представлены не позднее, чем за 24 часа до крайнего срока награждения. Я могу или не могу рассматривать любые ответы, представленные менее чем за 24 часа до истечения срока.

4b9b3361

Ответ 1

Я также хотел бы порекомендовать PGF/TikZ, с предостережением, что это в TeX. Если вам не удобно делать TeX-программирование, это может быть немного головной болью, так как есть некоторые... идиосинкразии. (Например, обращение с блуждающими пространствами может быть приключением.) Если вы хотите сделать TeX-программирование, я настоятельно рекомендую его; Я использую его очень часто для рисования фигур, даже если я не работаю в TeX. Кроме того, его руководство абсолютно потрясающее, а галерея TeXample имеет массу отличных примеров.

Пример кода для рисования шестнадцатеричной сетки и триангуляции заключается в следующем. Я признаю, что это довольно долго, но я думаю, что это действительно не так уж плохо.

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

Код до \newcommand{\hexgrid} включает только необходимые пакеты и устанавливает аргументы ключевого слова: name устанавливает имя, используемое для обращения к шестиугольникам, size устанавливает размер угла в угол каждого шестиугольника, xpos и ypos поместите верхний левый угол всей сетки, rows и cols определите количество шестиугольников, параметр triangulate позволяет вам по желанию triangulate сетку, а опция start shifted первая строка начинается с отступом вместо второй строки. Мы также разрешим пользователю передавать команды стилизации в первом необязательном аргументе \hexgrid; every hexgrid hex/.style 2 args позволит им стилизовать отдельные шестиугольники (и даже запросить позицию этого шестнадцатеричного, если они захотят), а every hexgrid triangulator/.style позволит им стилизовать триангулирующие строки.

Пропустив немного, мы перейдем к строкам \pgfsetmacro; указан диаметр шестиугольников, поэтому мы должны рассчитать радиус, длину стороны, а затем ширину из стороны в сторону. Следующие две петли \foreach - это мясо кода чертежа, и, надеюсь, будет довольно ясным. Обратите внимание, что при определении вертикального размещения мы должны учитывать толщину линий. После этого появляется еще более длинный блок кода, между \ifHexgridTriangulate и \fi; это отвечает за триангуляцию сетки, если такая вещь желательна.

Наконец, мы увидим, как это выглядит:

Example hex grids.

Ответ 2

Xy-pic или MetaPost которые, вероятно, уже установлены на вашем компьютере, если у вас есть TeX.

ОБНОВЛЕНИЕ: после попытки вспомнить, как использовать MetaPost и сбой... Я использовал SketchUp из Google. Тривиально для макета. Возможно, вам может понравиться другая программа САПР. Но использование программы рисования на сегодняшний день является самым простым. Возможно, OpenOffice Draw? Похоже на обман, но он быстрее выполнил свою работу.

Вот краткое изображение, сделанное в OpenOffice Draw за несколько минут. Требуется небольшая работа по соотношению сторон, но она показывает основы.

ОБНОВЛЕНИЕ второй. Пришло в голову, что инструмент, который использует декларативный стиль, например Groovy GraphicsBuilder лучше. К сожалению, GraphicsBuilder, похоже, нуждается в обратном уровне Groovy 1.6-beta-2. Поэтому, обращаясь к чему-то другому, наиболее похожее оказывается... JavaFX. Вот код (очень хромой, но показывает, что можно сделать):

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

В результате этого (и я признаю, что это может быть намного лучше):

alt text

Преимущества по сравнению с другими ответами: могут использоваться для композитных произвольных изображений, текста, анимаций и т.д., полного языка программирования, java interop. Также поставляется с большими учебниками и обширной документацией. Netbeans IDE имеет очень приятную кнопку предварительного просмотра, которая очень полезна для почти мгновенного просмотра результатов.

И да, я мог бы сделать много чего лучше в коде, но с преобразованиями и заполнением были некоторые жуткие вещи. Поэтому я сделал это уродливо.

Кстати, это моя первая программа javafx. Я был бы признателен за исправления и изменения.

Ответ 3

Как говорили другие, наиболее расширяемый и документированный язык, который подходит вашим потребностям, вероятно, PGF/TikZ. Я только что узнал очень простой TikZ меньше, чем неделю назад, поэтому, надеюсь, это демонстрирует свою силу:

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

Вот результат:

alt text

Как и в другом ответе, шесть линий являются только шаблонами для LaTeX. Обратите внимание, что мне не нужно делать никаких вычислений, кроме как осознавать, что 60 градусов составляет одну шестую от 360 градусов. Я избегаю квадратного корня из трех (расстояние между шестиугольниками), используя преобразования и множество полярных координат. Если вам не нравятся блуждающие линии в двойной сетке, вы можете обрезать их, используя область отсечения, вставленную после второго комментария:

\clip (0,0)
\hexcoord{ 4}{0}--(0,0)
\hexcoord{ 0}{4}--(0,0)
\hexcoord{-4}{0}--(0,0)
-- cycle;

Изменить. На самом деле область отсечения выглядит немного плохой. Здесь более интересная версия, в полном объеме:

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

Вот результат:

alt text

Ответ 4

Asymptote также может быть полезно. (аналогично метапосту)

Ответ 5

... самый короткий и простейший код, в любом существующий язык и использование любых уже существующий пакет, для шестиугольная сетка с двойным треугольная сетка, наложенная сверху Это;...

В стандарте Mathematica 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 может экспортировать изображения в: {pdf, web-страницу, html, bmp, eps, gif, jpg, jpg2000, pcx, png, pnm, pxr, raw bitmap, svg, tiff, ega, emf, wmf}. < ш >

Как использовать многоугольник в Mathematica: (ссылка)
Что такое тесселяция: (ссылка)

Выход для: draw2T[4, 8]

alt text

Перед публикацией я заметил:

двойная треугольная сетка является треугольная сетка, которую вы получаете, если вы подключаетесь центр каждого шестиугольника к центра каждого из соседних шестиугольники.

Для этого вам просто нужно компенсировать вторую графику. Обратите внимание, что перед сохранением его в любом формате он представляет собой набор фигур, и вы можете редактировать каждый отдельный элемент (Thats просто потрясающий).

Изменить:

С исправлением

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

alt text

Ответ 6

Хотя gnuplot предназначен для визуализации математических функций и данных в интерактивном режиме, его также можно использовать для рисования некоторых диаграмм. Этот код является примером:

#!/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

Это результат:

polygons

Ответ 7

Попробуйте MetaPost.

Ответ 8

Я бы всегда рекомендовал PGF/TikZ, хотя я никогда не пытался автоматизировать создание диаграммы с ним. Взгляните на впечатляющий список примеров здесь.

Ответ 9

Там также mkhexgrid, но я не пробовал. Также hexpaper, который, вероятно, легко адаптируется к вашим потребностям.

Ответ 10

Вы должны проверить rfig.

Это слой поверх метапоста, который позволяет рисовать произвольные цифры (и делать слайды PDF) с использованием ruby. Вы можете определить свои собственные функции, которые принимают аргументы и рисуют форму (например, шестиугольник). Затем вы можете повторно называть свои функции и т.д. Это дает вам возможность метапоста с гибкостью программирования в рубине.

Существует пример некоторых цифр, сгенерированных с помощью rfig на веб-сайте, который дает довольно хороший образец функциональности.

Ответ 11

ИМО асимптота лучше подходит для такого рода вещей (если вы не хотите использовать интерактивный инструмент, например geogebra).

Это просто и много прямо. Выход по умолчанию .eps. Например:

size(10cm,0);

guide ppath;  /* for a hexagon path */
guide tpath;  /* for a triangle 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);
        }
}

Output of asymptote code

Возможно, есть еще более простой способ сделать это, но я недостаточно осведомлен об асимптоте.

Ответ 12

Я обычно использую MATLAB для этого.