sidenote

Archívum
A(z) „ismeretterjesztő” kategória bejegyzései

Múlt héten keresett meg egy kedves barátom, a nap német szava blog szerzője, hogy egy darabig leáll a blog írásával, de szeretné, ha a bejegyzések PDF-ben is elérhetők lennének.

Hát összeálltunk. Ő fogta és lementette az összes posztot. Nagyjából* arra a formára hozta az anyagot, amiben előre megegyeztünk. Én írtam egy parsert LuaTeX-ben. És megszületett a PDF változat.

Ha hibát találtok benne, kérlek jelezzétek!

Az amúgy is zseniális blog bejegyzései mostantól A5-ös méretben, nyomtatásra optimalizáltan** elérhetők:

a nap német szava

* Azért benne hagyott közel kétszáz helytelen idézőjelet, és húsz-harminc rosszul tördelt sort, de sebaj, csak két órát basztam el a kijavításukkal.

** Már ha ki fogsz nyomtatni több, mint hétszáz oldalt. Amúgy képernyőn is jól néz ki.

Megosztás, like stb.

Az egymást követő nemzedékek külön-külön is nagy tehetségű tipográfusainak teljesítménye a mesterség, a szellemiség és a generációkon keresztül felhalmozódott tudás és tapasztalat öröklése révén gazdagodott. A Kner család örökségét a család harmadik generációjának kiemelkedő egyénisége Haiman György vitte tovább. Kiállításunk a száz éve született könyvtervező művésznek állít emléket.

Petőfi Irodalmi Múzeum

Megosztás, like stb.

The other day I thought about that it would be nice to program Conway’s Game of Life in LaTeX and create an animated PDF output. You could say that implementing the Game of Life is pretty easy. It is. But not in LaTeX, at least not for me. After using LaTeX for years I still find it hard to understand some codes and especially writing programs in “pure LaTeX”.

Since I use PGF/TikZ fairly often I decided to use pgfmath for the implementation. Pretty soon I got stuck, I needed to assign values to array elements, and I didn’t know how to overcome this problem in LaTeX. So I decided to ask a question on TeX.SX. This is the point that things get interesting.

I asked a question with the title “Assign value to array element (PGF/TikZ)”, I also wrote that my aim was to program Conway’s Game of Life in LaTeX, and posted my initial code. Before long two answers came, and the question was renamed to “Programming Conway’s Game of Life in LaTeX”. The first answer implemented the Game of Life in LaTeX, the second implemented it in LuaTeX. I was stunned. Especially from the LaTeX implementation. I didn’t – and still don’t – understand the code. :) At the end I decided I should get acquainted with LuaTeX, and write my own solution in it:

Glider

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
\documentclass{article}
\usepackage[a0paper]{geometry}

\usepackage{luacode}
\usepackage{animate}
\usepackage{tikz}
\usepackage{xcolor}
\usepackage[active, tightpage]{preview}
\PreviewEnvironment{animateinline
}
%\PreviewEnvironment{tikzpicture}

\tikzset{%
    cellframe/.style={%
        minimum size=5mm,%
        draw,%
        fill=white,%
        fill opacity=0%
    }%
}

\tikzset{%
    alivecell/.style={%
        circle,%
        inner sep=0pt,%
        minimum size=4mm,%
        fill=black%
    }%
}

\setlength{\PreviewBorder}{5mm}

\begin{document}

\begin{luacode*}
    iterations = 36
   
    grid = {{0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 1, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 1, 0, 0, 0},
        {0, 0, 0, 1, 1, 1, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 0, 0, 0, 0, 0}}
\end{luacode*}

\begin{luacode*}
    function evolve(grid)
        local temp = {}
        local gridsize = #grid
       
        for i = 1, gridsize do
            temp[i] = {}
            for j = 1, gridsize do
                temp[i][j] = 0
            end
        end
       
        for i = 1, gridsize do
            for j = 1, gridsize do
               
                iminus = i - 1
                iplus = i + 1
                jminus = j - 1
                jplus = j + 1
               
                if iminus == 0 then
                    iminus = gridsize
                end
               
                if iplus == gridsize + 1 then
                    iplus = 1
                end
               
                if jminus == 0 then
                    jminus = gridsize
                end
               
                if jplus == gridsize + 1 then
                    jplus = 1
                end
               
                neighbourcount = grid[iminus][jminus] +
                    grid[iminus][j] +
                    grid[iminus][jplus] +
                    grid[i][jminus] +
                    grid[i][jplus] +
                    grid[iplus][jminus] +
                    grid[iplus][j] +
                    grid[iplus][jplus]
               
                if (grid[i][j] == 1 and (neighbourcount == 2 or neighbourcount == 3)) or (grid[i][j] == 0 and neighbourcount == 3) then
                    temp[i][j] = 1
                else
                    temp[i][j] = 0
                end
            end
        end
       
        return temp
    end
   
    function display(grid)
        local gridsize = #grid
       
       
        for i = 1, gridsize do
            for j = 1, gridsize do
                tex.sprint([[\node[cellframe] at (]])
                tex.sprint((i - 1) * 5)
                tex.sprint([[mm,]])
                tex.sprint(-((j - 1) * 5))
                tex.sprint([[mm){0};]])
               
                if grid[j][i] == 1 then
                    tex.sprint([[\node[alivecell] at (]])
                    tex.sprint((i - 1) * 5)
                    tex.sprint([[mm,]])
                    tex.sprint(-((j - 1) * 5))
                    tex.sprint([[mm){1};]])
                end
            end
        end
    end
   
    function animate(grid, iterations)
        for i = 1, iterations - 1 do
            display(grid)
            tex.sprint([[\newframe]])
            grid = evolve(grid)
        end
        display(grid)
    end
   
    function frames(grid, iterations)
        for i = 1, iterations - 1 do
            tex.sprint([[\begin{tikzpicture}]])
           
            display(grid)
            grid = evolve(grid)
           
            tex.sprint([[\end{tikzpicture}]])
            tex.sprint([[\clearpage]])
        end
       
        tex.sprint([[\begin{tikzpicture}]])
        display(grid)
        tex.sprint([[\end{tikzpicture}]])
    end
\end{luacode*}

\noindent\begin{animateinline}[autoplay,loop,
begin={\begin{tikzpicture}[scale=1
]},
end={\end{tikzpicture}}]{5}
    \luadirect{animate(grid, iterations)}
\end{animateinline
}
%\noindent\luadirect{frames(grid, iterations)}

\end{document}

Note: More information about my implementation is available in my answer on TeX.SX.

It turned out to be pretty easy to do this in LuaTeX, however I struggled with the modulus operator (%) and printing from Lua to TeX. Still it became a pretty nice solution, I think.

Last but not least I’m very grateful for the answers on my question. Here are some nice outputs of jfbu’s and JLDiaz’s answers (if you have a TeX.SX registration then please post an upvote on them because they are really great):

Gosper glider gun
Glider Glider
Gosper glider gun

Megosztás, like stb.

Múlt héten jött a hír, hogy rendelhető a Raspberry Pi-hez készített infravörös filter nélküli kamera a Pi NoIR.

Pi NoIR

Kép: adafruit industries blog

Azonnal rendeltem is egyet, majd írtam egy kommentet a HUP-ra, hogy én mire használom a kamera modult. trey-nek megtetszett, amit írtam, és írt is egy bejegyzést az ételdobozból és Raspberry Pi-ból készített time-lapse kamerámról.

Ennek eredményeképpen több megkeresést kaptam, hogy mennyibe kerül egy ilyen hordozható time-lapse kamerát összeállítani, illetve milyen szoftvereket használok, ezt próbálom most összefoglalni.

Szeretném megjegyezni, hogy az eddig elkészült felvételek még nincsenek kész, nincsenek megvágva, nincs rajtuk javítás stb. A cél egy hosszabb videó, vagy klip vagy ilyesmi készítése, és még nagyon az elején járok a dolognak.

Miből áll és mennyibe kerül?

A legegyszerűbb, ha felsorolom az alkatrészeket. (Az árak mellett feltüntettem, hogy milyen pénznemben értendők, mert pár dolgot külföldről rendeltem.)

  • Raspberry Pi Model B (rev2): 35 USD – Napi árfolyam kérdése, hogy Forintban mennyi.
  • Raspberry Pi Camera Board: 16.56 GBP – Napi árfolyam kérdése, hogy Forintban mennyi.
  • Wi-Fi USB adapter: ~2000–4000 HUF – Nagyon fontos, hogy elég legyen neki az az áram, amit az RPi közvetlenül le tud adni, különben powered hubot kellene használni.
  • SD kártya: ~5000+ HUF – Legalább 16 GB-os, class 10-es SD kártyát ajánlok, mert egy-egy fotózás alkalmával simán összejön 4–5 GB fotó.
  • 2 db 4-es AA elemtartó: ~150 HUF – Bármelyik elektronikai üzletben kapható.
  • kapcsoló: ~25 HUF – Nem emlékszem, hogy mennyibe került, 100 HUF alatt van az biztos.
  • 8 db 2500 mAh-ás 1,2 V-os NiMH akkumulátor: ~4000–8000 HUF – Az ár a márkától függ, nekem eléggé noname van. :)
  • ételdoboz: ~1000 HUF – Fontos, hogy légmentesen zárható legyen, így eső esetén nem folyik be a víz, a köd nem okoz gondot stb.
  • matt akrilfesték spray (fekete és fehér): ~2000 HUF – Az ételdoboz belülről feketére, kívülről fehérre van fújva. Belül fekete, hogy a különböző ledek fényét, villogását elnyelje nehogy becsillanjon a kamerába. Kívülről azért fehér, hogy visszaverje a fényt a melegedést elkerülendő.
  • UV szűrő: használtan ~500–1200 HUF
  • csavarok, alátétek: ~100 HUF
  • fényképezőgép állvány: Ehhez inkább nem írok árat (nekem korábbról volt már egy). Viszont nagyon fontos, hogy ha állvánnyal dolgozom, akkor legyen az állványon alul valami kampó, vagy más, hogy súly lehessen akasztani az aljára. Ugyanis az ételdoboz nagyobb, mint egy átlagos fényképezőgép, és a súlya még elemmel együtt is kicsi, ezért könnyen belekap a szél.
  • egyebek: maszkolószalag, szigetelőszalag, drót, forrasztópáka, forrasztóón, fenyőléc, laminált padlódarab. Utóbbi rögzíti a dobozt az állványra; úgy „faragtam”, hogy az állvány fejébe illeszkedjen. Ezek mind voltak itthon, árat nem tudok mondani.

Végösszeg: 28284 HUF (mindenből a legolcsóbbal és a mai USD és GBP árfolyammal számoltam).

Ebben nincs benne a fényképezőgép állvány, az itthon talált felhasznált anyagok, alkatrészek, sem az a készíttetett gyűrű, amelybe az UV szűrő illeszkedik. Nem gondoltam volna, hogy ennyit költöttem rá. Sőt, nekem 32 GB-os SD kártyám van, és nem is mindenből a legolcsóbb cucc, ráadásul több kamera modulom is van (NOiR is)… Szóval én valahol 50 ezer felett járok.

Szoftver

A legutóbb ennyit írtam a szoftverről:

A fényképezés mobiltelefonról vezérelhető:

  • A Pi egy USB-s WiFi modul hostapd és isc-dhcp-server segítségével szolgáltat hálózatot.
  • Egy SSH klienssel be lehet jelentkezni a Pi-re.
  • Egy egyszerű shell script a raspistill alkalmazással preview képet készít, amit netcat-tal browserbe továbbítva lehet megtekinteni.
  • Szintén egy shell scripttel lehet elindítani a fényképezést (5000 ms timeout).

Most ezt megpróbálom kicsit jobban kifejteni.

Az RPi-n „gyári” Raspbian fut, a fényképezéshez pedig a raspistill programot használom. Az SSH szerver szintén a „gyári”, a hostapd és az isc-dhcp-server konfigurációját pedig egyszerűen innen puskáztam:

A használt scriptek pedig letölthetők:

Nincs bennük semmi magic. A fényképezésre külön scriptek vannak (capture-*.sh), amelyekben csak a két kép közötti timeout az eltérő. Preview-t pedig a preview.sh scripttel lehet készíteni. Ez utóbbi ahhoz kell, hogy a fényképezés elindítása előtt rendesen be lehessen állítani az állványt és a kamerát.

Képek feldolgozása

A képek bizgetéséhez ImageMagick-et használok. Itt egy szokásos, csak croppoláshoz és átméretezéshez használt parancs, ami végigmegy a megadott könyvtárban található összes jpg fájlon:

mogrify -gravity northwest -crop 2592x1458+0+308 +repage -resize 1920x -format png \
-path /media/szantaii/Tibor/capture/cap1_processed/ /media/szantaii/Tibor/capture/cap1/*.jpg

Egy másik paraméterezéssel már a színeket is állítgattam (ennek az eredménye látható a poszt végén):

mogrify -gravity northwest -contrast -contrast -color-matrix "1.2 -0.1 -0.1 -0.1 1.2 -0.1 -0.1 -0.1 1.2" \
-crop 2592x1458+0+243 +repage -resize 1920x -format png \
-path /media/szantaii/Tibor/capture/cap28_processed_enhanced/ /media/szantaii/Tibor/cap28/*.jpg

Az utolsó példában pedig egy 1,6 fokos forgatás, vágás és átméretezés van:

mogrity -gravity center -background "rgb(0,255,0)" -rotate "1.60" +repage -gravity northwest \
-crop 2446x1376+54+176 +repage -resize 1920x -format png \
-path /media/szantaii/Tibor/capture/cap30_processed/ /media/szantaii/Tibor/capture/cap30/*.jpg

A felsoroltakon kívül még az ImageMagick -sigmoidal-contrast operátorával „játszottam”.

Az eddigi parancsokkal csak a képeket dolgoztam fel. A képekből a videót pedig FFmpeg-gel fűzöm össze. A végeredményt 30 és 60 fps-be is ki szoktam renderelni, hogy lássam melyik néz ki jobban. A 30 és a 60 fps generálása között csak annyi a különbség, hogy az FFmpeg-nek meg kell adni, hogyan értelmezze a bemenetként szolgáló képeket, vagyis az -r kapcsoló után 30-at vagy 60-at kell írni.

ffmpeg -r 30 -i %06d.png -vcodec libx264 -vprofile high444 -vlevel 4.2 -pix_fmt yuv420p ~/Desktop/test_30fps.mp4
ffmpeg -r 60 -i %06d.png -vcodec libx264 -vprofile high444 -vlevel 4.2 -pix_fmt yuv420p ~/Desktop/test_60fps.mp4

Hirtelen (az elmúlt másfél órában) ennyi jutott eszembe.

Megosztás, like stb.

A több éves hagyománynak megfelelően minden évben egy konferenciával tervezzük ünnepelni a szabad szoftverek világnapját. Célunk, hogy egyre többen lássák meg a szabad szoftverekben rejlő lehetőségeket új ismereteket és emberi kapcsolatokat szerezve, legyen az akár kezdő otthoni felhasználó, rendszergazda, vállalkozó, kormányzati vagy oktatási felhasználó.

Idén, 2013-ban terveink szerint november 29-én, pénteken tervezzük a konferencia megrendezését.

Tervezett szekcióink:

  • Mobil szekció: szabad szoftveres mobil platformok, pl. Android, Firefox OS, Ubuntu Phone
  • Hardverközeli szekció: szabad szoftverrel programozható, konfigurálható „kütyük”, alap hardveres kapcsolásokkal, pl. Raspberry Pi, Arduino, Udoo, OpenWrt routerken
  • Felhasználói szekció: népszerű és még kevésbé ismert felhasználói programok, pl. LibreOffice, Mozilla, Gimp, …
  • Rendszergazdai szekció: asterisk, biztonsági kérdések
  • Geoinformatikai szekció: a GIS-ben egyre jobban teret nyerő desktop (pl. QGIS, GRASS) és szerver (pl. GeoServer, OpenLayers) megoldások
  • Multimédia, jog: nyílt formátumok, szabad licencek, jogi kérdések

A belépés ingyenes lesz. A megrendezéshez a korábbi évektől eltérően sajnos nem áll rendelkezésünkre pályázati forrás, így azt teljes egészében szponzori felajánlásokból kell összegyűjtenünk. Számításaink szerint 1,4 millió forintra lenne szükségünk, hogy igényesen meg tudjuk rendezni (de minimálisan 1,1 millióra), amelyet – a helyszínnel való megállapodásunk szerint – 2013. szeptember végéig kell összegyűjtenünk. Ha van lehetőséged (neked, cégednek, ismerősődnek), akkor támogasd, hogy megvalósulhasson a konferencia.

Szabad Szoftver Konferencia Szeged 2013

Mindenféle (média)megjelenés, és akármilyen kicsi adomány is sokat számít. Tessék reblogolni, támogatni, mert jó ügyre megy!

Megosztás, like stb.

Butterick’s Practical Typography

This book is partly an experiment in taking the web se­ri­ous­ly as a book-pub­lish­ing medi­um. I have a role to play in mak­ing the ex­per­i­ment work. And so do you.

For my part, I want­ed to de­liv­er a lev­el of writ­ing and de­sign qual­i­ty that you’d find in a print­ed book. Not that print will al­ways be the gold stan­dard. But to­day it is. Because so far, web-based books—nice ones, any­how—have been slow to emerge.

[…]

Matthew Butterick

Most kezdtem csak olvasni, de a Practical Typography egy nagyon jó, hiánypótló könyv. Egyszerűen, érthetően, példákkal alátámasztva mesél a tipográfiáról. (Kötelező.)

Ingyenesen elérhető, Butterick csak annyit kér, hogy vegyék meg a fontjait, vagy korábbi könyvét, és akkor így is marad. Szerintem méltányos, de én azt hiszem maradok az 5–10 dolláros PayPal adománynál.

Butterick’s Practical Typography

Megosztás, like stb.

Eric S. Raymond: A katedrális és a bazár

Tíz éve el kellett volna olvasnom már ezt a könyvet.

Megosztás, like stb.

5. Retro video- és kvarcjáték kiállítás

Inkább képes beszámoló lesz ez, mintsem leírnám mi volt. Annyit mégis, hogy jó volt látni, ahogy a kisgyerekek élvezettel tolták a Wizard of Wor-t, a Super Mario-t, vagy a Pong-ot.

Kvarcjátékok

Orosz csodák Kvarcjátékok Mortal Kombat kvarcjáték
Kinyitható Nintendo megoldás Kétjátékos Nintendo cucc kontrollerrel Super Mario karóra – kéne!

Néhány régi gép

ZX gépek További ZX csodák Commodore
Amiga Híradástechnika Szövetkezet HT1080Z Iskolaszámítógép Magyar Pong!

5. Retro video- és kvarcjáték kiállítás

Apple

Newton Macintosh SE Macintosh PowerBook Duo 2300c

A képekért köszönet Rednek.

Megosztás, like stb.

Pont azután olvastam Plastik Józsi angelday Commodore 64 BASIC „grafikás” posztját, hogy nekiálltam, és meghegesztettem a Gorillas-t, hogy fusson Windowson és Linuxon. Tökéletes időzítés.

Ezzel az egy sorból kiindulva készült egy könyv, ami a számítógépek és a procedurális BASIC grafikák világát, benne a Commodore 64-et mutatja be – 10print.org. […]

Plastik média – 10 PRINT CHR$(205.5+RND(1)); : GOTO 10

Nagyon jó könyv, gyönyörű dolgok vannak benne.

10 PRINT CHR$(205.5+RND(1)); : GOTO 10

Gondoltam egyet, és átírtam a 10 PRINT CHR$(205.5+RND(1)); : GOTO 10 sort Batch-be, PowerShellbe és Bash-be is. Sajnos az első három változat nem produkál olyan szép „képet”, mint C64-en, viszont ha kicseréljük a „/” (slash) és „\” (backslash) karaktereket „-” és „|” (vertical bar) karakterekre, akkor egész szép labirintusokat kapunk. Linux-on Unicode terminált használva szinte tökéletes az output.

  • Batch

    1
    2
    3
    4
    5
    6
    7
    8
    9
    :LOOP
        @ECHO OFF
        SET /A R=%RANDOM% %%2
        IF %R%%2==0 (
                ECHO|SET /P=/
            ) ELSE (
                ECHO|SET /P=\
            )
    GOTO LOOP

  • PowerShell

    1
    While($true) {Write-Host -NoNewline $(if ((Get-Random -Minimum 0 -Maximum 2) -eq 0){"/"} else {"\"})}

  • Bash (Mac)

    1
    while true ; do if [ $((RANDOM % 2)) -eq 0 ] ; then printf "/" ; else printf "\" ; fi done

  • Bash (Linux)

    1
    while true ; do printf "\u257$(($RANDOM % 2 + 1))"; done

Hála a fent említett könyvnek, ismét felfedeztem a Processinget. Remélem sikerül valami érdekeset szépet alkotnom vele.

Megosztás, like stb.

Gorillas

Image source: File:Gorillas screenshot.png – Wikipedia

I hope there are still some of you out there who remember the game Gorillas written in Basic. I have friends who still play this game from time to time.

These guys use Linux as their main operating system, so getting Gorillas to work needed the following workaround. First you had to get QBasic (from Microsoft or another source), then install DOSBox under Linux, start QBasic in DOSBox, load the source of Gorillas, and start the game. Each time you wanted to play you had to go through these steps, plus you had to adjust the game speed in DOSBox for your computer. I admit this isn’t difficult, but it is pokey.

So the other day I thought about rewriting this game in Basic and make it work under Windows and Linux. Finding the original(?) source wasn’t hard. The next step was to find a Basic compiler. I knew FreeBASIC, and after looking into it a little I’ve found out I can use the original graphics library of QBasic using FreeBASIC. The only problem was that I couldn’t set up FreeBASIC under 64 bit Linux, and there was the issue that FreeBASIC is a 32 bit only compiler too. I diched FreeBASIC and started to search for another Basic compiler, and luckily I’ve found QB64.

“Over 45 years of compatibility…” said the QB64 website. This aroused my interest, I thought that I might not need to rewrite the game at all but I may be able to compile the original source with QB64. To cut a long story short I had to touch only five lines of code in the original source to get the game work under Windows and Linux. Here is the receipt.

  1. QB64 doesn’t like the inline definition on line 211, so comment it out.

    211
    'DEF FnRan (x) = INT(RND(1) * x) + 1

  2. Add a new function declaration to the code (around line 90 in the original source).

    1
    DECLARE FUNCTION FnRan (x)

  3. Add the following function definition to the end of the file.

    1
    2
    3
    4
    5
    FUNCTION FnRan (x)

        FnRan = INT(RND(1) * x) + 1

    END FUNCTION

  4. Adjust the CONST SPEEDCONST constant’s value from 500 to 100,000,000 (line 123 in the original source). Note that you may need to use a different value, depending your computer.

    123
    CONST SPEEDCONST = 100000000

  5. Compile.

That’s it. After these modifications the code will compile without any errors. I tried it on Windows and Linux. (I don’t have a Mac but I’m pretty sure this will work under OS X too.) See the proof below.

Gorillas running under Windows 7 Gorillas running under Ubuntu 12.04 (64 bit)

Edit #1

I’m posting a patch which contains all described modifications. To patch the original source first unpack the linked tar.gz file then enter the following command in your terminal.

1
patch gorilla.bas -o gorilla-patched.bas < gorilla.bas.patch

Note that you will need the diff and patch programs for this operation (available through Cygwin under Windows).

Megosztás, like stb.