Archive for the 'programming' Category

6 comments

2009-06-23

 

Posted in:
art,
computers,
music,
programming.

Gödel, Escher, Bach

I just finished reading Gödel, Escher, Bach by Douglas R. Hofstadter. I’ll wait for you to at least read the wikipedia description of the book.

Done? Ok… The main surprise for me was how many seemingly unrelated topics the book touches. Logic (Gödel), graphic art (Escher), music (Bach) to start with. But also mathematics, molecular biology, genetics, philosophy, zen buddhism, formal systems, artificial intelligence, programming, recursion and self-reference, various paradoxes, and much much more.

It is easily the best book I’ve ever read, although I can’t claim to have understood everything. If you want to borrow my copy, I’d be glad to help (the book is sort of expensive and really hard to get in Czechia).

10 comments

2009-03-15

 

Posted in:
programming,
typography.

New look again

I was thoroughly bored with the previous theme, and although I tried to revive it with the new header image, it was still bugging me. So I created a new one.

I had a draft of a new theme lying around for quite a long time, so I made few adjustments to it: made the code much longer and much less clean. But it seems to work.

Features of the new design include, but are not limited to:

  • big letters in headings (big letters rock)
  • even less images (none, except the two links to flickriver, smilies and images in posts)
  • half-fixed-width half-fluid design (the design is fixed width, but the sidebar is fluid — works well for many different widths of browser (800px — the sidebar isn’t displayed, it’s accessible through scrolling; 1024px — sidebar in one column, 1280px — two columns, more px — more columns (it is capped at three columns)))
  • emphasis on typography (lists, blockquotes, etc. are styled properly)
  • lines vertically in synch (left column, middle column and sidebar)
  • the old color scheme, I mostly like it and more importantly — couldn’t find a better one at the moment :)
  • justified text (I’m still very unsure here — justified looks way better, but left-aligned is more readable)

Bugs of the new design include, but are not limited to:

  • IE6 sometimes messes up the sidebar, not quite sure why
  • Opera doesn’t keep lines in synch when there are smileys (and I thought I had the solution, sigh…)
  • IE doesn’t align the comment date in the comment list (will look into that later)

Also, I spent ages dealing with various bugs in IE that caused things to disappear.
One such bug caused the sidebar not to appear (it was an absolutely positioned element next to a floated element — don’t ever do that), another sometimes caused titles to disappear (they were relatively positioned, now that they are static it seems ok, but I have no idea why). When repairing the sidebar, I had to move it in front of the actual content in the markup, which is wrong and I know it. I am sorry to all lynx/links users out there.

Bug reports, remarks and suggestions are welcome! ;-)

1 comment

2008-11-12

 

Posted in:
art,
programming.

Nothing is random, everything has a meaning.

Nothing is random.

Everything has a meaning.

The scene fits in under 100 lines of code (with comments! :)), so I decided to publish it here.

/**
 * Simple POV-Ray scene with reflective pillars
 *
 * @author   Vit ‘tasuki’ Brunner
 * @license  GNU GPL, http://www.gnu.org/copyleft/gpl.html
 * @version  2.7, 2008-11-05
 */

// dark and reflective texture
#declare ShinyDark =
texture {
    pigment { rgb 0 }
    finish {
        ambient 0
        // reflection .3 // dark version
        reflection .6 // light version
        specular 3
    }
}

// create a pillar of specified height
// kind of hackish, but I can’t find a better way
#macro pillar(xx, yy, height)
    #declare counter = height * 2;

    #while (counter > -1)
        superellipsoid {
            <.3, .3>
            texture { ShinyDark }
            translate y * counter * .5
            translate x * xx * 2.2
            translate z * yy * 2.2
        }

        #declare counter = counter - 1;
    #end
#end

// just some random (random, really?) pillars
pillar(-3, 3, 2)
pillar(-1, 3, 4)
pillar( 0, 3, 3)
pillar( 2, 3, 0)
pillar( 3, 3, 2)
pillar( 0, 2, 2)
pillar( 1, 2, 1)
pillar(-1, 1, 3)
pillar(-1, 0, 2)
pillar( 0, 0, 1)
pillar( 2, 0, 3)
pillar(-2,-1, 2)
pillar(-1,-1, 3)
pillar( 1,-1, 0)
pillar( 3,-1, 2)
pillar(-1,-2, 1)
pillar( 0,-2, 2)
pillar( 2,-2, 1)
pillar( 3,-2, 0)
// there’s no such thing as random…

// the sphere everything is wrapped in
sphere {
    <0, 100, 0>, 100
    hollow
    pigment { rgb 1 }
    finish {
        ambient .6
        reflection .05
    }
}

// get light quality from clock (+K in params)
#declare qualight = clock;

// back right less bright white light
light_source {
    <30, 25, 40> rgb .5
    area_light <0, 10, 0>, <0, 0, 10>, qualight, qualight
    adaptive 1 jitter circular orient
}

// front right white light
light_source {
    <30, 20, -30> rgb .7
    area_light <0, 10, 0>, <0, 0, 10>, qualight, qualight
    adaptive 1 jitter circular orient
}

// front left blue light
light_source {
    <-15, 25, -15> rgb <.3, .7, .9>
    area_light <0, 20, 0>, <0, 0, 20>, qualight, qualight
    adaptive 1 jitter circular orient
}

camera {
    location <7, 9, -14>
    look_at  <2, 1,   0>
}

To render the picture, you should run something like:

povray +Ifilename.pov +FN +W1024 +H768 +Q9 +QR +A0.5 +AM2 +K11

Well, that’s it. Hope you enjoyed ^^

Oh, you actually want to see the picture? Please check it out on deviantart.

And remember: Nothing is random, everything has a meaning…

6 comments

2008-10-29

 

Posted in:
programming.

.htaccess, document root and Zend Framework

It’s funny but I couldn’t find anyone having this issue. It certainly isn’t limited to Zend Framework, it affects everyone who doesn’t have access to apache configuration and wants to have document root in a deeper directory. Maybe I just can’t google very well.

Imagine a shared host. You can’t choose your document root, it’s firmly set to one particular directory. Now you want to install Zend Framework. Imagine you’d like to follow the standard directory structure (that means you more or less have these directories in your project: application (the application), library (zend and other libraries) and public (stuff accessible from the outside, images, css etc.)). Normally, you’d want to point your document root to the public directory, but when you can’t do that you can use .htaccess in the project directory to redirect everything to public.

RewriteEngine On
RewriteRule !\.(js|gif|jpg|png|css|txt)$ public/index.php [L]
RewriteRule ^(.*)$ public/$1 [L]

This was the first thing I wrote, and it works on certain servers. Other servers will kindly remind you that “Request exceeded the limit of 10 internal redirects due to probable configuration error.” Which kind of makes sense when you think about it. Makes me wonder how comes the above code actually worked on two different configurations.

Now here’s the code that works (and in my humble opinion it also should work, as opposed to the one above):

RewriteEngine On
RewriteRule !\.(js|gif|jpg|png|css|txt)$ public/index.php [L]
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(.*)$ public/$1 [L]

And finally a disclaimer: I am not sure about the security implications. If someone knows more about possible security issues with this, please do leave a comment.

3 comments

2008-06-14

 

Posted in:
photography,
programming.

Tone Mapping with GIMP

“Tone mapping reduces global contrast in images while increasing local contrast and shadow/highlight detail.” or so Gimp Addict’s Tone Mapper tutorial says. Go and read his tutorial, I will add few comments to it:
4) “radius of 100-500 is good” — yes, it usually is, but since we don’t know the size of the image, I’d rather say that 10% of image size (that is (width+height)/2) is a good starting point.
5) 75% is again a good starting point, but you might want to play around with the value.
7) It depends… if you want to increase the tonemapping effect, duplicating the “soft light” layer is the way to go (I’ve tried changing the layer mode and nothing else really worked at all).

So I wanted to create a script that would do this. After searching the GIMP Plugin Registry, I found Tone mapping script, which basically follows Gimp Addict’s guide. However, it only has two options – the amount of blur and the amount of layer transparency. That certainly isn’t enough for me. Luckily, the plugin is GPL…

(((GIMP’s Script-Fu) uses Scheme) (which is (a dialect) (of the (Lisp (programming language)))) ((Lisp is a (programming language)) (for people) (who (really (really (like parentheses))))))

And because I like parentheses almost half as much as an average Lisp programmer, I rewrote the Tone mapping script and created Advanced Tone Mapping script. Feel free to put it in your GIMP’s script directory (~/.gimp-2.4/scripts/ in my case).

There are four parameters for Advanced Tone Mapping script:

  • Gauss. Blur (% of img size) — is the amount saying how much the blurring should be used for the tone mapping. It is in percents of image size (where image size = (width+height)/2). Ten is a good default, but different values might be interesting too.
  • Opacity of blurred layer — this is the 75 default, which can be changed if you want stronger or weaker effect.
  • Opacity of merged layer — the default is 90. If 100 is not enough, consider increasing number of “copies of merged layer”.
  • Copies of merged layer — when one, it’s barely noticeable, you can deny any accusations of postprocessing easily. :) Three has a lot of “halo effect” and anything above five will completely mess all colours up.

The first set of pictures is simply a preview. The image on the left is the original image, and the image on the right is processed by Advanced Tone Mapping with Gaussian-blur set to 10, opacity of blurred layer equal 75, opacity of merged layer full 100, and finally three copies of the merged layer (note the way I use to show those values — it is also used for naming the layers, which can be handy if you later forget which layer is which or what you have done). The image on the right might be a bit over the top, but it shows nicely what can be done with Advanced Tone Mapping script:

Tone mapping

The next example shows some pretty conservative tone mapping. The one on the left was created with almost none blur, while the one on the right has 10% blur. Note the difference: the one on the left has no halo but appears a bit flat, while the one on the right has a slight halo but also has higher level of detail.

careful Tone mapping

Oh my… the following example shows what can go wrong with tone mapping (I’m sorry for all the people who already gouged their eyes out). The reason why image on the left appears so flat and awful is that almost no blur was applied. The image on the right is a comparison with healthy blur applied. Five copies is still a bit too much, but hey, at least it has kind of action-like look.

Tone mapping gone wrong

The last image shows the difference between the default blur and maximum blur available. As you can see in the right side picture, the halo is so huge it’s almost impossible to see. The bad news is that with maximum blur we lose a lot of detail near the borders of light/dark areas.

Tone mapping different halo

Ok, that’s it — now go and experiment with my script on your own photos. 8-)

PS: Underexpose your images — the dark areas can still be lightened, while the burned out areas are usually completely white and can’t be darkened.

PPS: The more contrast there is, the more layers you apply, the more blur you will usually need.

PPPS: Any kind of noise in your picture will be greatly amplified.

PPPPS: No, this is not HDR, this is just tone mapping of a single image (just jpeg, in my case). Tone mapping is a part of HDR, but HDR is not a part of tone mapping. ;)

1 comment

2008-04-23

 

Posted in:
programming,
rant.

Common sense and frustration

Do you know what common sense is?

Common sense is:

  • NOT setting fixed height for elements whose actual height can change anytime, and especially not setting this particular height to three elements next to each other, to keep them with the same height (common sense solution is to wrap it all in another element)
  • NOT calling your database tables j_aidx_1, j_aidx_2 … j_aidx_n and calling the columns m_1, m_2, m_3, etc; which leads to people writing queries like SELECT a.m_85, a.m_167, b.m_17, b.m_56 FROM j_aidx_5 AS a LEFT JOIN j_aidx_8 AS b ON a.m_103 = b.m_42 WHERE b.m_58 = ‘1′ AND a.12 = ‘0′
  • invoking the live server settings as default instead of using testing environment settings as default, because when something goes wrong in the decision process, you don’t want the live server to get fucked up
  • NOT having the very same function copied to several different “modules” of the application so as to make it extremely inconvenient to change
  • NOT calling your backups “new”, “!new”, “_new”, “____new”, “!!!!!new” etc, especially when each person uses a different flavour of this method
  • using a version control system, and if you are unable to do so, calling your backups by date (preferrably in YYYY-MM-DD format, since it sorts itself naturally)
  • using either tabs or any amount of spaces for indentation, but keeping it consistent (or at least, for fuck’s sake, keeping it consistent within one file)
  • NOT internally calling files for inclusion 1.html, 2.html, 3.html etc., especially when you already went through the hassle of creating nice looking URL’s
  • NOT totally breaking your URL’s and titles by adding a lot of random keywords just to game search engines, when that makes your site either unusable or extremely confusing for humans
  • using one language (human language, like English or Czech) in your application, or at least avoiding mixing up several languages inside one particular variable or function name (findAllNovinky is just lame function name)

… do you know what frustration is?

1 comment

2008-01-20

 

Posted in:
programming.

Object-oriented or procedural?

As I mentioned in the previous post, I needed a CAPTCHA algorithm. As I couldn’t find anything simple and usable that would do what I want (ie follow the basic principles of captcha creation (readibility for humans, and hopefully unreadibility for machines)), I decided to write my own. The purpose of this was just to generate the image, I left generating the text, passing it in a secure way and all the other boring stuff for others. And as an exercise, I’ve done both procedural and object-oriented versions.

I’m not an expert on object oriented programming, so my little class could have probably been written in a better (read: longer and even more confusing) way. Anyway, here it is:

/**
 * @name    TasuCaptcha
 * @author  Vit ‘tasuki’ Brunner
 * @license GNU GPL
 * @version 0.001
 *
 * remarks:
 * you need php (duh)
 * you need gd
 * you need the font file, in the same directory as this
 * (get it at http://www.sil.org/~gaultney/gentium/ )
 *
 * if you want to use antialiased line, you need function drawQSLine()
 * get it from http://php.net/manual/function.imageline.php
 * code_couturier at graffiti dot net
 * # antialiased draw_line function 1.1 (faster)
 */

class TasuCaptcha {
        private $bg;
        private $fg;
       
        // picture
        public $width; // width of the picture
        public $height; // height of the picture

        // letters
        public $font; // font for the letters
        public $fontHeight; // height of the letters
        public $maxAngle; // maximum angle for the letters
        public $top; // where the letters should start – y
        public $left; // where the letters should start – x
        public $letterWidth; // approximate width of each letter

        // line
        public $step; // the length of line between turns
        public $stepDiff; // the max height difference for step
        public $lineBorder; // borders for the middle line
        public $thickness; // thickness of the line
        public $antialiased; // if true, makes the line antialiased

        function __construct($text) {
                // picture
                $this->width = 170;
                $this->height = 50;
                $bgColor = ‘113355′;
                $fgColor = ‘CCCCCC’;

                // letters
                $this->text = $text;
                $this->font = ‘./gentium.ttf’;
                $this->fontHeight = 25;
                $this->maxAngle = 15;
                $this->top = 35;
                $this->left = 10;
                $this->letterWidth = 30;

                // center line
                $this->step = 5;
                $this->stepDiff = 5;
                $this->lineBorder = 15;
                $this->thickness = 2;
                $this->antialiased = false;

                $this->setBgColor($bgColor);
                $this->setFgColor($fgColor);
        }

        function setBgColor($color) {
                if (strlen($color) != ‘6′) die(’setBgColor needs 6 letter hex color’);
                $this->bg[‘r’] = hexdec(substr($color, 0, 2));
                $this->bg[‘g’] = hexdec(substr($color, 2, 2));
                $this->bg[‘b’] = hexdec(substr($color, 4, 2));
        }
        function setFgColor($color) {
                if (strlen($color) != ‘6′) die(’setFgColor needs 6 letter hex color’);
                $this->fg[‘r’] = hexdec(substr($color, 0, 2));
                $this->fg[‘g’] = hexdec(substr($color, 2, 2));
                $this->fg[‘b’] = hexdec(substr($color, 4, 2));
        }

        function drawImage() {
                // create image and set colors
                $im = imagecreatetruecolor($this->width, $this->height);
                $background = imagecolorallocate($im,
                        $this->bg[‘r’], $this->bg[‘g’], $this->bg[‘b’]);
                imagefill($im, 0, 0, $background);
                $textcolor = imagecolorallocate($im,
                        $this->fg[‘r’], $this->fg[‘g’], $this->fg[‘b’]);

                // draw letters
                for ($i = 0; $i < strlen($this->text); $i++) {
                        $this->angle = rand(- $this->maxAngle, $this->maxAngle);
                        imagettftext($im, $this->fontHeight, $this->angle,
                                $this->left + $this->letterWidth * $i, $this->top,
                                $textcolor, $this->font, $this->text{$i});
                }

                // draw the line
                $curheight = $this->height / 2;
                for ($i = 0; $i < ($this->width / $this->step); $i++) {
                        $lastheight = $curheight;
                        $curheight = $curheight + rand(-$this->stepDiff, $this->stepDiff);
                        if ($curheight > $this->height - $this->lineBorder)
                                $curheight -= $this->stepDiff;
                        if ($curheight < $this->lineBorder)
                                $curheight += $this->stepDiff;

                        // this could be done better…
                        for ($j = 0; $j < $this->thickness; $j++) {
                                if ($this->antialiased) // draw antialiased line
                                        drawQSLine($im, $this->step * $i, $lastheight - $j,
                                                $this->step * $i + $this->step, $curheight - $j,
                                                $this->fg[‘r’], $this->fg[‘g’], $this->fg[‘b’]);
                                else // draw aliased line
                                        imageline($im, $this->step * $i, $lastheight - $j,
                                                $this->step * $i + $this->step, $curheight - $j,
                                                $textcolor);
                        }
                }

                // output the image
                header(‘Content-type: image/png’);
                imagepng($im);
                imagedestroy($im);

                // maybe someone could find this useful
                return $this->text;
        }
}

// now we can try to use it:
$captcha = new TasuCaptcha($cnum);
$captcha->antialiased = true;
$captcha->drawImage();

Well, that was long, wasn’t it? And most of the time we were just moving values around… $this->shit = $shit;

Now the procedural version:

/**
 * @name    tasucaptcha
 * @author  Vit ‘tasuki’ Brunner
 * @license GNU GPL
 * @version 0.001
 *
 * remarks:
 * you need php (duh)
 * you need gd
 * you need the font file, in the same directory as this
 * (get it at http://www.sil.org/~gaultney/gentium/ )
 *
 * if you want to use antialiased line, you need function drawQSLine()
 * get it from http://php.net/manual/function.imageline.php
 * code_couturier at graffiti dot net
 * # antialiased draw_line function 1.1 (faster)
 */

function tasucaptcha($text) {
        // picture
        $width = 170; // width of the picture
        $height = 50; // height of the picture
        $bgcolor = ‘113355′; // please keep this 6 letters long
        $fgcolor = ‘CCCCCC’; // please keep this 6 letters long

        // letters
        $font = ‘./gentium.ttf’; // font for the letters
        $fontHeight = 25; // height of the letters
        $maxAngle = 15; // maximum angle for the letters
        $top = 35; // where the letters should start – y
        $left = 10; // where the letters should start – x
        $letterWidth = 30; // approximate width of each letter

        // center line
        $step = 5; // the length of line between turns
        $stepdiff = 5; // the max height difference for step
        $lineBorder = 15; // borders for the middle line
        $thickness = 2; // thickness of the line
        $antialiased = false; // if true, makes the line antialiased

        // END OF SETTINGS

        // get colors
        $bg[‘r’] = hexdec(substr($bgcolor, 0, 2));
        $bg[‘g’] = hexdec(substr($bgcolor, 2, 2));
        $bg[‘b’] = hexdec(substr($bgcolor, 4, 2));
        $color[‘r’] = hexdec(substr($fgcolor, 0, 2));
        $color[‘g’] = hexdec(substr($fgcolor, 2, 2));
        $color[‘b’] = hexdec(substr($fgcolor, 4, 2));

        // set up the image
        $im = imagecreatetruecolor($width, $height);
        $background = imagecolorallocate($im, $bg[‘r’], $bg[‘g’], $bg[‘b’]);
        imagefill($im, 0, 0, $background);
        $textcolor = imagecolorallocate($im, $color[‘r’], $color[‘g’], $color[‘b’]);

        // draw letters
        for ($i = 0; $i < strlen($text); $i++) {
                $angle = rand(-$maxAngle, $maxAngle);
                imagettftext($im, $fontHeight, $angle, $left + $letterWidth*$i,
                        $top, $textcolor, $font, $text{$i});
        }

        // draw the line
        $curheight = $height/2;
        for ($i = 0; $i < ($width / $step); $i++) {
                $lastheight = $curheight;
                $curheight = $curheight + rand(-$stepdiff, $stepdiff);
                if ($curheight > $height - $lineBorder) $curheight -= $stepdiff;
                if ($curheight < $lineBorder) $curheight += $stepdiff;

                //
                for ($j = 0; $j < $thickness; $j++) {
                        if ($antialiased) // create antialiased line
                                drawQSLine($im, $step * $i, $lastheight - $j, $step * $i + $step,
                                        $curheight - $j, $color[‘r’], $color[‘g’], $color[‘b’]);
                        else // draw aliased line
                                imageline($im, $step * $i, $lastheight - $j, $step * $i + $step,
                                        $curheight - $j, $textcolor);
                }
        }

        // draw the image
        header(‘Content-type: image/png’);
        imagepng($im);
        imagedestroy($im);

        return $text;
}
tasucaptcha($cnum);

Unless one is paid by lines of code, one must conclude that the second version is much better. It’s half as long and twice as readable.

As for the captcha itself — I can’t guarantee that the results are machine-unreadable, but at least they are human readable. :-)

Comments Off

2008-01-19

 

Posted in:
internet,
programming.

Few WordPress-related improvements

In wordpress database, column comment_status is of type enum(’open’, ‘closed’, ‘registered_only’). But for some reason, ‘registered_only’ is never used anywhere…

I use disable comments plugin, which is excellent because it is very simple. Here is the relevant part:

$wpdb->query(‘UPDATE wp_posts
SET comment_status = "closed", ping_status = "closed"
WHERE DATEDIFF(NOW(), post_date) > ‘
. $days);

And if you want it to set the comments to registered_only, you only need to change it to:

$wpdb->query(‘UPDATE wp_posts
SET comment_status = "registered_only", ping_status = "closed"
WHERE DATEDIFF(NOW(), post_date) > ‘
. $days);

Well… now if only ‘registered only’ did what it was supposed to, you’d be done with it. But as it doesn’t, we need to change some things. They are dependent on the theme you’re using, I’ll use the default theme to illustrate what needs to be changed. First, look into comments.php file for something this:

if (‘open’ == $post->comment_status)

and change it to:

if (‘open’ == $post->comment_status
    || ‘registered_only’ == $post->comment_status)

In the default theme, this needed to be changed at two places.

Then there’s one more thing:

if (get_option(‘comment_registration’) && !$user_ID)

should be changed to:

if ((get_option(‘comment_registration’)
    || (‘registered_only’ == $post->comment_status)) && !$user_ID)

After that, it pretty much works. You need to have user registration enabled in wordpress, though. Also, while I was at it, I decided to prevent against bots registering. So I installed Sabre. Sabre is nice, but its CAPTCHA rather sucks… well, anyway — more on that in the next post. 8-)

6 comments

2007-11-13

 

Posted in:
internet,
programming.

Fuytayblees

It all started about a year ago, at a go tournament in Blansko, where I played a game called “fujtajblíci”. I enjoyed it a lot, so I thought I could create online version. But as you might know, it is quite a huge leap from thinking about doing something to actually doing it.

Anyway, now I really couldn’t resist anymore… And I thought “fujtajblíci” might be a bit difficult for a lot of people to pronounce or remember, so I rewrote the name as “fuytayblees” (insert fanfares here).

There’s much more info (including the rules, for real) at the fuytayblees site itself, so just visit it, register and start playing. ;-)

4 comments

2007-10-27

 

Posted in:
programming.

JavaScript insanity

Seriously, what would you think about a language that is weakly typed and uses the same operator for concatenation and addition?

I think it’s insane.

Well, so much for my first encounter with JavaScript. And although I encountered way more problems (most of which were caused by my own stupidity, as usual), the fact that the plus sign (aka +) either adds or concatenates (based possibly on the current mood of the interpreter) struck me as the ultimate wtf.

Luckily, parseInt() comes to save the day. But still, why not rather use some other operator? I don’t really care which… just anything else, mmkay?