Блоґ одного кібера

Історія хвороби контуженого інформаційним вибухом

Графіки та інша векторна графіка в будь-якій мові програмування

with 6 comments

Результат - графік параболоїда


Спеціально для тих, кому терміново треба графік функції, і вони не хочуть встановлювати всякі важкі графічні бібліотеки, а тим більше їх вивчати. Зображення буде створюватись в файлі, тому якщо ваша мова вміє записувати в файли текст – то ви зможете створити в ній зображення. Хто вже знає що таке SVG – може далі не читати. Кому це справді треба – прошу критикувати. Я можу написати більше і зрозуміліше, якщо сильно попросите. Основне – задавайте питання.

На прикладі Python, але принцип такий же і в інших мовах (недавно я написав функцію на C, яка малювала гістограми. Теж влізла в один екран). Двовимірні графіки нудні, тому перейдемо одразу до трьох вимірів, і спробуємо намалювати параболоїд. Все одно вийде занадто просто.

Загалом, нам навіть не потрібна мова програмування. Для того, щоб намалювати зображення подібне до того що справа, нам досить створити текстовий файл picture.svg (чи з іншою_назвою.svg), і написати в ньому наступний текст:

<svg width="800" height="600" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><line x1="330" y1="370" x2="730" y2="370" stroke-width="1" stroke="green" /><line x1="330" y1="370" x2="70" y2="630" stroke-width="1" stroke="green" /><line x1="317" y1="383" x2="717" y2="383" stroke-width="1" stroke="green" /><line x1="350" y1="370" x2="90" y2="630" stroke-width="1" stroke="green" /><line x1="304" y1="396" x2="704" y2="396" stroke-width="1" stroke="green" /><line x1="370" y1="370" x2="110" y2="630" stroke-width="1" stroke="green" /><line x1="291" y1="409" x2="691" y2="409" stroke-width="1" stroke="green" />...

Еей! Це швидко надоїдає. Ще два-три відрізки щоб намалювати осі – куди не йшло. Але для графіка цього мало. Тому, будемо генерувати програмно. Та й навіть той текст що вище писав не я, а програма. Хоча бувають випадки коли ручна робота – таки простіше.

SVG, як і HTML починається з одного кореневого тега. Тільки називається він відповідно:

<svg width="800" height="600" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
<!-- всі інші теги-->
</svg>

Основні його атрибути – ширина і висота зображення. В пікселях. Це дещо схоже на задання графічного режиму. Все це зберігається в файлі з розширенням svg, і може переглядатись в сучасному браузері, або в якомусь гарному оглядачі зображень. Стандартний гномівський eog – відкриває, тільки на жаль не вміє виконувати javascript, тому приклади з минулого поста показує тільки браузер. Може ще якийсь крутий графічний редактор, але це треба перевірити.

Щоб не забути дописати оцей початковий тег, можна зробити клас, який це все (відкриває файл, дописує заголовок) робить автоматично в конструкторі:

class SVG:
        def __init__(self,filename,res):
                """ Create svg file with name, and resolution (tuple) """
                self.f = open(filename,"w")
                self.f.write('<svg width="%d" height="%d" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">' % res)
                self.resolution = res
                self.fill = "white" # Заливка
                self.stroke = "black" # Лінії
                self.strokewidth = 1 # Товщина лінії

Окрім цього об’єкт ініціалізує деякі параметри, такі як колір і товщина ліній, та колір заливки, щоб потім всюди їх використовувати за замовчуванням.

Ну й зрозуміло, що після цього треба закрити тег, і закрити файл. Але хай воно робиться автоматично, коли ми знищуємо об’єкт:

        def __del__(self):
                self.f.write('</svg>')
                self.f.close()

Тепер можемо створити найпростіший файл написавши в програмі всього один рядок:

svg = SVG("paraboloid.svg",(800,600))

Файл буде відкриватись, але на ньому нічого не буде видно. Тому, треба намалювати хоч щось. Відрізок наприклад.

Відрізок як вже можна було здогадатись з тексту вище малюється так:

<line x1="330" y1="370" x2="730" y2="370" stroke-width="1" stroke="green" />

Але всякі там кольори, і товщина – речі другорядні, тому, щоб спростити його малювання теж заганяємо його в функцію, їй передаємо координати, а всякі атрибути оформлення беремо з атрибутів класу.

def _line(self,x1,y1,x2,y2):
		self.f.write('<line x1="%d" y1="%d" x2="%d" y2="%d" stroke-width="%d" stroke="%s" />' % (x1,y1,x2,y2,self.strokewidth,self.stroke))

Щось я не вкладаюсь в терміни. Як працює 3d, і які ще є в SVG примітиви окрім відрізків – завтра, чи пізніше… Напевне в цій же публікації.

Кнопка щоб подивитись яку розмітку генерує редактор.


А ще, гарний метод порозбиратись з SVG – подивитись, як це робить графічний редактор.

Advertisements

Written by bunyk

Квітень 18, 2011 at 23:45

Оприлюднено в Графіка, Кодерство, Розмітка

Tagged with

Відповідей: 6

Subscribe to comments with RSS.

  1. Клас, я про таке навіть не думав. Дякую за класний спосіб малювати графіки!

    Okspen

    Квітень 19, 2011 at 00:49

  2. Погано, що малюєш через теги “лінія”. Їх виходить дуже багато. Спробуй викорисатати тег <path>

    danbst

    Квітень 21, 2011 at 20:10

  3. Дякую за гарну статтю. Наштовхнули мене на одну думку у власнім проекті. І тоді зразу питання: чи не знаєте, чи є можливість обрахувати якою буде ширина певного тексту в пікселях в SVG-малюнку (з врахуванням стилю та розміру)? Наперед вдячний.

    jona

    Серпень 15, 2014 at 22:50

    • Чесно кажучи не знаю, ніколи не доводилось. Думаю зараз я б створював елемент за допомогою JavaScript в браузері, а тоді дивився б його ширину. (І тоді змінював би позицію чи вміст, аби воно краще виглядало).

      bunyk

      Серпень 18, 2014 at 10:24

      • дякую. я, власне, так само і подумав. тільки використовував Тк.

        jona

        Серпень 18, 2014 at 13:03


Залишити відповідь

Заповніть поля нижче або авторизуйтесь клікнувши по іконці

Лого WordPress.com

Ви коментуєте, використовуючи свій обліковий запис WordPress.com. Log Out / Змінити )

Twitter picture

Ви коментуєте, використовуючи свій обліковий запис Twitter. Log Out / Змінити )

Facebook photo

Ви коментуєте, використовуючи свій обліковий запис Facebook. Log Out / Змінити )

Google+ photo

Ви коментуєте, використовуючи свій обліковий запис Google+. Log Out / Змінити )

З’єднання з %s

%d блогерам подобається це: