PHP & More

A technical blog about programming in PHP and about technology in general: programming, workarounds and troubleshooting

Meltdown – The Computer Lab Prank — October 29, 2015

Meltdown – The Computer Lab Prank

I remember that little prank from the days I was a student. You work on an X terminal, and out of the blue, all the display contents gradually disappear’ Pixel after pixel turns black. But don’t worry – you’ll regain control over your display shortly. shortly.
Everyone can access other X terminal display, and mess with it.

How Does It Work?

This program is a simple one using the GDK library, Gnome’s window management package. Including ‘gdk.h’ will also include:

The Program’s Flow

The main function of the program performs the following steps:
1. Initialize GDK.
2. Create a window whose dimensions are the same as those of the root window.
3. Make the window’s background transparent.
4. Make the window a full-screen window.
5. Add an event handler. to handle Expose events.
The event handler will perform the following steps:
1. Create a list of columns and lengths (number of blackened pixels).
2. Create the Graphics Context for the window.
3. Blacken pixels until all pixels are black.
4. Quit the main loop.

Includes And Structures:

#include <stdio.h>
#include <stdlib.h>  
#include <gdk/gdk.h>

GMainLoop *mainloop;
GList *list;

typedef struct col_and_length_t{
  short col;  // Column number
  short len;  // Number of blackened pixels.
} col_and_length;`

The main function:

int main(int argc, char *argv[]){
  gdk_init(NULL, NULL);
  GdkDisplay *disp=gdk_display_get_default();
  GdkScreen *scr = gdk_display_get_default_screen (disp);
  GdkWindow *root = gdk_screen_get_root_window(scr);
  int rootWidth = gdk_window_get_width(root);
  int rootHeight = gdk_window_get_height(root);
  GdkWindowAttr attr;
  attr.width=rootWidth;
  attr.height=rootHeight;
  attr.x=0;
  attr.y=0;
  attr.window_type = GDK_WINDOW_TOPLEVEL;
  attr.wclass=GDK_INPUT_OUTPUT;

  GdkWindow *newWin=gdk_window_new(root,&attr, GDK_WA_X | GDK_WA_Y);
  gdk_event_handler_set (eventFunc, newWin, NULL);
  GdkRGBA color;
  color.alpha=0;

  gdk_window_set_background_rgba(newWin, &color);
  gdk_window_fullscreen(newWin);
  gdk_event_handler_set (eventFunc, newWin, NULL);
  gdk_window_show(newWin);
  mainloop = g_main_new (TRUE);
  g_main_loop_run (mainloop);
  gdk_display_close(disp);

return 0;
}

The event handler

void start_meltdown(GdkWindow *newWin, int height){
  cairo_t *gc=gdk_cairo_create(newWin);
  cairo_set_line_width(gc,2);
  cairo_set_source_rgb (gc, 0, 0, 0);
  int cell_no,size;
  GList *link;
  col_and_length *link_data;
  size=g_list_length(list);

  while(size>0){
    cell_no=random() % size;
    link = g_list_nth(list,cell_no);
    link_data = (col_and_length *)link->data;
    cairo_move_to(gc, link_data->col, link_data->len);
    cairo_rel_line_to(gc, 0, 1);
    cairo_stroke(gc);
    link_data->len++;
    if (link_data->len >= height){
      list=g_list_remove_link(list, link);
      --size;
    }
  }
  g_main_loop_quit(mainloop);
}

void eventFunc(GdkEvent *evt, gpointer data){
  GdkWindow *newWin = (GdkWindow *)data;
  if (gdk_event_get_event_type(evt) == GDK_EXPOSE && gdk_event_get_window (evt) == newWin){
    int width=gdk_window_get_width(newWin);
    int height=gdk_window_get_height(newWin);
    int i;
    for (i=0; i<width;i++){
      col_and_length *cell=(col_and_length *)calloc(sizeof(col_and_length), 1);
      cell->col=i;
      cell->len=0;
      list = g_list_append(list, cell);
    }
    start_meltdown(newWin,height);
  }

}

Compiling

In linux, compiling a program is easy thanks to the pkg-config command.
Run the following from the command line:

gcc meltdown.c `pkg-config --cflags --libs gdk-3.0` -o meltdown

Now, to run the program type:

./meltdown

Written with StackEdit.

Advertisements
Rotate Your Movie — September 17, 2015

Rotate Your Movie

I have received by e-mail a rotated video in the ‘flv’ format. The video was supposed to be a vertical one, but it turned out to be horizontal, that is ROTATED. So, I wrote a little program to rotate it back using libming.
There are two things to take care of when processing the input FLV:

  • The video stream.
  • The sound stream.

Both can be taken from the FLV file.
The code is written in C++, but can be translated easily into PHP. Following is the code:

#include <iostream>
#include <mingpp.h>

using namespace std;

int main(){
  const char *flvFile ="/path/to/inputVideoFile.flv";

  // Get the video stream from the file. The input file can be in the FLV format.
  SWFVideoStream *stream = new SWFVideoStream(flvFile);

  SWFMovie mov (9);  // Create the movie object.

  // The method 'add' returns a display item.
  // Display items can be rotated, transformed, etc.
  SWFDisplayItem *di=mov.add(stream);  

  // Sound streams are taken from a file object. 
  FILE *soundFD = fopen(flvFile, "rb+");
  SWFSoundStream sound(soundFD);

  // The original dimensions of the video are 426 X 240.
  di->rotate(-90);  // Rotate the item 90 degrees clockwise
  di->move(240, 0);  // The rotation moves point (0,240) to (-240,0).


  mov.setSoundStream(&sound,0);  // Add the sound stream at the beginning
                                 // of the movie.

  // Show the frames one by one.
  int noFrames = stream->getNumFrames();
  for (int i=0; i<noFrames; i++)
      mov.nextFrame();

  mov.setDimension(240, 426); // The new dimensions.
  mov.save("/path/to/outputVideoFile.swf", 9);
  cerr<<"Fin\n";
  return 0;
}

This will create a real vertical movie. Don’t share it on YouTube or anywhere you cannot control your movie dimensions.

Teach Yourself D3.js — July 11, 2015

Teach Yourself D3.js

D3 is a JavaScript framework used for data visualization.
Learning how to work with D3.js is very easy. If you begin with the basics, you’ll see how easy it is to use D3, because:

  • the DOM function names are much shorter than those in the legacy DOM library.
  • the same functions are used for both setting and getting values.
  • setters return a value, so you can keep working with the same element without repeating its name.

If you already know some framework, you probably feel that there’s nothing new under the sun, which is good because it makes learning the new stuff easier.

So, What’s New?

In D3, you can:
* add and remove SVG and HTML elements using the setters and getter.
* set and get the element’s properties, attributes, styles, text and… data

Getting Started

First, download the framework from http://d3js.org
After you include it in your script, you can use selections, that is wrappers for elements.
To get a selection, use one of the functions:

  • d3.select(selector) – to select the first element matching selector.
  • d3.selectAll(selector) – to select the all elements matching selector.

Like the d3 object, selections has their select and selectAll methods to select descendant.

If selection is a selection, it’s easy to understand what selection.text(), selection.attribute(), selection.style(), selection.insert(), and selection.append() do. But, what does selection.data() do?

Data And Update Selection

The selection’s method data() helps you use the HTML DOM as a database.
selection.data() returns an array of all data that belongs to the elements of the selectionץ The data is held in the property __data__ of the element.
selection.data(arr, func) – defines an update selection and distribute the elements of array arr to the elements of selection.
func(d,i)is a function that:

  • receives d an element of arr and its index i.
  • returns a record key.

If func is not passed, the key is the element’s index.

A recommended way to create an update selection is:
var updSelection = selection1.selectAll(selector).data(arr)

Now, updSelection is a selection of existing elements whose data has been changed.
In addition, updSelection has to methods:

  • updSelection.enter() – returns place holders for elements to be created under selection1.
  • updSelection.exit()– returns elements that have lost their data, and are usually to be removed.

Using the data

The methods attr, style, property, text and data can accept a function as a value to set. The function will be called for each element of the selection’s data. And its arguments will be the array element and its index.

Now, let us see it in an example.
The following code arranges data in a donut layout::

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Testing Pie Chart</title>
<script type="text/javascript" src="d3.min.js"></script>

<style type="text/css">
.slice text {
font-size: 12pt;
font-family: Arial;
}
</style>
</head>
<body>
<script type="text/javascript">
var width = 300, 
    height = 300, 
    radius = 100, 
    color = d3.scale.category20c(); //builtin range of colors


// Step 1: creating a container for the donut chart, and attach raw data to it.
var vis = d3.select("body")
            .append("svg")     //create the SVG element inside the <body>
            .datum([{"label":"first", "value":20},
                    {"label":"second", "value":10},
                    {"label":"third", "value":30},
                    {"label":"fourth", "value":25}])       
            .attr({"width": width, "height": height})  
            .append("g")
            .attr("transform", "translate(" + radius + "," + radius + ")") //move the center of the pie chart from 0, 0 to r, r



// Step two: defining the accessors of the layour function. 
//           The function 'pie' will use the 'value' accessor to compute the arc's length.
var pie = d3.layout.pie() 
            .value(function(d) { return d.value; })
            .sort(function(a,b){return a.label<b.label?-1:a.label==b.label?0:1;});

// Step 3: Create the update selection. 
var updateSelection = vis.selectAll("g") 
                         .data(pie);    // This will use the function 'pie' to create arc data from the row data attached to the visualisation element.


// Step 4: Using the data in the update selection to create shape elements.
var arc = d3.svg.arc() 
            .outerRadius(radius)
            .innerRadius(radius / 2)
;
updateSelection.enter()
               .append('g')
               .attr('class','slice')
               .append("path")
               .style("fill", function(d, i) { return color(i); } ) //set the color for each slice to be chosen from the color function defined above
               .attr("d", arc);                                     // Create the arc from the arc data attached to each element.

updateSelection.append("text") 
               .attr("transform", 
                     function(d) { 
                       return "translate(" + arc.centroid(d) + ")"; 
                     })
               .attr("text-anchor", "middle")                  
               .text(function(d, i) { return d.data.label; }); 


</script>
</body>
</html> 

And following is the chart:
enter image description here

For more funcions, see the API Reference.

The Proof That 2=4 — July 2, 2015
Bézier Curves — June 25, 2015

Bézier Curves

The Bézier curve is a popular way to draw curves in graphic editors such as GIMP and Inkscape. A curve of degree n is defined using n+1 points, where the first and last are the start and end points of the curve, respectively, and the rest are control points.
For example:
fff
The curve in the image above is a cubic Bézier curve. It has start and end points (filled with blue) and two control points (with no fill).
Each control point is attached by a straight line to a start or an end point, for a reason:

  • The control points allows the user to control the curve intuitively.
  • The straight line between the start(or end) point and its control point is tangent to the curve at the start(or end) point.

The Definition

A Bézier curve is defined as the collection of points that are the result of the function
B(t) for every t in [0,1].
A linear Bézier is simply a straight line between to points P0 and P1. The function is:
(1 – t)BP0 + tBP1

For n>1, Be P0, P1 … Pn the list of the curve’s points. Then the curve’s function is defined as
BP0P1…Pn(t) = (t – 1)BP0P1…Pn-1(t) + tBP1P2…Pn(t)

Or, in its explicit form:

(Not a very precise definition because 00 is not a number, so use the value 1 instead.)

This equation can be proved easily using the Pascal triangle.
From the explicit definition, you can see that the translation is done by adding the same coordinates to which of the curves start, end and control points.
because:
Rotations and translations are done by a transform matrix. So, if T is a transform matrix:
TBP1,P2,…Pn = BTP1,TP2,…TPn

About Tangents

Now, in a Bézier curve, BP0P1…Pn(t), The line P0 – P1 is tangent to the curve at point P0, and Pn – Pn-1 is tangent to the curve at point Pn

To prove this we’ll have to show that the derivative of a Bézier curve of degree n at the start and end points is a non-zero scalar multiplied by the difference between P1 and P0, and between Pn and Pn-1.
That scalar is n.

For n=1;
BP0,P1 = (1 – t)P0 + tP1
Let’s derive:
B’P0,P1 = -P0 + P1

Good!

Let’s assume it’s correct for n, and prove for n+1
BP0,P1…,Pn+1(t) = (1 – t)BP0,P1…,Pn(t) + tBP1,P2…,Pn+1(t)
Let’s derive:
B’P0,P1…,Pn+1(t) = -BP0,P1…,Pn(t) + (1-t)B’P0,P1…,Pn(t) + BP1,P2…,Pn+1(t) + tB’P1,P2…,Pn+1(t)

Now, to get the tangent to the curve at p0, let;s assign t=0:
B’P0,P1…,Pn+1(0) = -BP0,P1…,Pn(0) + B’P0,P1…,Pn(0) + BP1,P2…,Pn+1(0) =
= – P0 + n(P1 – P0) + P1 = (n+1)(P1 – P0)

Good!
Now, to get the tangent to the curve at p0, let;s assign t=1:
B’P0,P1…,Pn+1(1) = -BP0,P1…,Pn(1) + BP1,P2…,Pn+1(1) + B’P1,P2…,Pn+1(1) =
= – Pn + Pn+1 + n(Pn+1 – Pn) + P1 = (n+1)(Pn+1 – Pn)

QED

SVG supports Bézier curves of up to the third degree. A path consisting of such curves are good approximations of shapes provided that you have enough points.

Tower Of Hanoi Without Recursion — May 12, 2015

Tower Of Hanoi Without Recursion

If you’ve taken courses in computer sciences, you probably know the Tower Of Hanoi algorithm. The task is to move a tower of discs from the source rod the the destination using an auxiliary rod. Each disc should be placed on a bigger one all the time.
The solution is to move all discs on top of the biggest one to the auxiliary rod, then move the biggest disc to the destination rod and then move all the rest to the destination (according to the rules of course, and one disc at a time).

The Recursive (and Naive) Solution

The function that moves n discs from src to dst using aux looks like:

function moveDiscs(n, src, dst, aux){
  if (n > 1)
    moveDiscs(n-1, src, aux, dst);
  print("Move from " + src + " to " + dst);
  if (n>1)
    moveDiscs(n-1, aux, dst, src);
}

We’ll use that function later to prove that the non-recursive algorithm does the same.

The Iterative Solution

A naive iterative solution is to use a binary search and find for each move of a disc, the parameters passed to moveDiscs when n=1. This is crazy! We don’t want time complexity o(n) just to move the first disc.
Let’s look at a better solution:
Repeat the 3 steps in table 1 until all discs are moved, depending on the value of n:

Table 1:

If n is even If n is odd
perform a legal move between src and aux perform a legal move between src and dst
perform a legal move between src and dst perform a legal move between src and aux
perform a legal move between aux and dst perform a legal move between aux and dst

Note: perform no more step after all discs have been moved to the destination.

Proof

For n = 1, just move a disc from src to dst
For n = 2, take a look at the recursive function.
For n ≥ 3:
The total number of moves is 2n – 1
Let’s assume our algorithm works for any natural number n and prove for n+1:

Steps 1 thru 2n – 1

Let’s look at the first call to moveDiscs inside itself:

moveDiscs(n-1, src, aux, dst); // Remember that we prove for `n+1`, so `n-1` in the function actually means `n`

Let’s look how it is performed:
Per our assumption, the sequence for steps 1 thru 2n – 1 is

If n is even If n is odd
perform a legal move between src and dst perform a legal move between src and aux
perform a legal move between src and aux perform a legal move between src and dst
perform a legal move between aux and dst perform a legal move between aux and dst

Because if n is odd, n+1 is even and vice versa, we get that the first steps are performed correctly by the iterative algorithm

Step 2n

This is when we move a disc from src to dst
If n is even, 2n≡1 mod 3, thus it matches step 1 in Table 1 for odd n+1.
If n is odd, 2n≡2 mod 3, thus it matches step 2 in Table 1 for even n+1.
Thus, our iterative algorithm is still correct.

Steps 2n + 1 Thru 2n+1 – 1

Those steps are performed by the second call to moveDiscs inside itself:

moveDiscs(n-1, aux, dst, src); // Remember that we prove for `n+1`, so `n-1` in the function actually means `n`
If n is even If n is odd
perform a legal move between aux and src
(step 2 for odd n+1)
perform a legal move between aux and dst
(step 3 for even n+1)
perform a legal move between aux and dst
(step 3 for odd n+1)
perform a legal move between src and aux
(step 1 for even n+1)
perform a legal move between src and dst
(step 1 for odd n+1)
perform a legal move between src and dst step 2 for even n+1)

In this table we see the steps that follow step 2n.
Thus, the algorithm works correctly for the last part, and thus our whole algorithm is correct.

You can now watch a working Hanoi animation here.

Blogging with StackEdit — April 26, 2015

Blogging with StackEdit

Table Of Contents:

Would you like to add posts to your blog with a cool editor? Do you want to publish in Blogger, WordPress, Tumblr, etc.?
Try StackEdit Click the link you’ve just seen, and start editing a markdown document. Forget about switching from WYSIWYG to HTML and back. Enjoy a split-screen instead: one side is where you type in markdown format, and the other is the WYSIWYG result.

Editing the Post

Editing a post is simpler than editing an HTML page, and sometimes even simpler than working with the text editor provided by the blogging site. For example, if you add code to your post, just write it between two lines starting with three back-ticks (back-quotes).
For example:
‘‘‘
var j=3;
‘‘‘
will be displayed as:

var j=3;
  • To display headers of level H1 or H2, type a line of equal-signs or dashes respectively under tho header text.
  • For H1 thru H6, begin the lines with number of pounds equal to the level (#, ##, …, ######).
  • Place your bold text between two pairs of asterisks (**bold text**).
  • Place your italic text between single asterisks or underscores. (_italic_).
  • Hyperlinks: there are two ways to add them, one is to simply type the URL, for example ‘http://example.com, the other is to type the text in brackets, and the link in parentheses, for example: [Example Site](http://example.com).

You can learn more about markdown syntax, by clicking the syntax icon in from the floating menu at the bottom:
Floating Menu

Publishing Your Post

Before publishing, let’s set variables, such as tags. Type your variables, between two lines, consisting of three dashes as follows:

variable: value

For example:

tags: tag1, tag2, tag3

You can see which variables you can set, when you decide where to publish your post.
To publish a post, click on the ‘#’ menu, and choose publish as shown in the following image:
Publish

After choosing the site to which you want to publish, click OK or Cancel (if you want to set the interpreted variables, for example.)
Publish

NOTE: It is recommended to upload images to the site before including it in your document.

Now, you can use StackEdit to update your post.
Enjoy!

Written with StackEdit.

Static Variables in JavaScript — April 14, 2015

Static Variables in JavaScript

How do you declare a static variable in a JavaScript function?
Not with the word “static“.
In JavaScript “function” is a variable type similar to “object“.
The difference is that the reference to a function inside itself is not this but arguments.callee.
An example of using arguments.callee is the following function that returns itself:

function func(){
    return arguments.callee;
}

Adding Static Variables

You can add arguments to arguments.callee. To initialize it the first time, check first if it is not defined. For example:

if (typeof(arguments.callee.myStaticVar)!="undefined")
    arguments.callee.myStaticVar=0;

Following is an example function in [rhino(http://rhino.org) JavaScript(run from the command line):

    function _example(){
        var thisFunction = arguments.callee;
        if (!thisFunction.static){
            thisFunction.static=0;
        }
        ++thisFunction.static;
        print("This function has been called: " + thisFunction.static + " times");
    };

In this example, you can change the static variable’s value without calling the function using _example.static = "some value";.

To prevent this, encapsulate your function using a function called once, for example:

(function(){
    function _example(){
        var thisFunction = arguments.callee;
        if (!thisFunction.static){
            thisFunction.static=0;
        }
        ++thisFunction.static;
        print("This function has been called: " + thisFunction.static + " times");
    };

    example=function(){
        _example();
    }
})();

Now, each time example() is called, it will increment the variablestatic, but the variable cannot be incremented without calling example because _example is private.

Written with StackEdit.

StackEdit: Markdown Editor — April 7, 2015

StackEdit: Markdown Editor

Hello, World!

I am a blog post written in Markdown, and sent from the StackEdit editor.

Do you know those files with suffix ‘.md’? They are markdown documents, and they are easy to write and easy to read because they don’t have to contain HTML tags!

Here’s an example of how to add a link:

Type “[The Example Site](http://example.com)” to get the following link:

The Example Site

This tool can export your document as HTML. sponsors can use this tool to export documents as PDF..

Written with StackEdit.

HTML5 Canvases & Transforms — April 4, 2015

HTML5 Canvases & Transforms

Browsers supporting HTML5 allow you to draw on the browser’s screen without preparing an image file before. Drawing on a canvas is done using the wonderful Javascript language. If you want to draw a 2-dimensional image on canvas element ‘cnv’, get the drawing context using:

var ctx = cnv.getContext("2d")

And use that context to draw everything using the standard functions:

moveTo, lineTo, arc, fillRect, etc.

Learn more about drawing here.

You can use the functions to create more complicated shapes easily thanks to transform functions:

Transformations: Linear Algebra Made Easy

The origin(0,0) of the canvas is defined to be the top-left pixel of the canvas element. And the coordinates are given in number of pixels. This can change by using transforms.

The transformation functions are:

  • scale(x,y): this will make every shape x times wider and y time taller.
  • translate(x,y): now coordinate (0,0) will be shifted x units to the right, and y units down.
  • rotate(angle): will rotete the axes by given angle in radians.
  • transform(a,b,c,d,e,f): If you want to use a transformation matrix
  • setTransfrom(a,b,c,d,e,f): reset all transform, and perform transform(a,b,c,d,e,f).

a,b,c,d,e,f are values in the matrix:

Transform Matrix
The values a,b,c,d are used for rotating and scaling. e,f for translating.

Other useful methods of the context are:

  • ctx.save() – to save current transform in a stack (Last In First Out).
  • ctx.restore() – to retrieve the trnasform from the top of the stack.

An Example – The Koch Snowflake

The algorithm for drawing the Koch Snowflake can be found in the post Drawing The Koch Snowflake Fractal With GIMP.

Here’s an example in Javascript:

        function drawSide(ctx, len){
          if (len > 1) {
            var thirdOfLen = len / 3.;

            var rotationAngles = [0, -Math.PI / 3, 2 * Math.PI / 3., -Math.PI / 3];

            rotationAngles.forEach(function(val){
              
              if (val != 0){
                ctx.translate(thirdOfLen, 0);
                ctx.rotate(val);
              }
              ctx.save();
              drawSide(ctx, thirdOfLen);
              ctx.restore();
            });

          } else {
            ctx.moveTo(0,0);
            ctx.lineTo(len,0);
            //ctx.stroke();
          } 
        }

        ctx.translate(startX, startY);
        for (i=0; i<3; i++){
          ctx.save();
          drawSide(ctx, sideLength);
          ctx.restore();
          ctx.translate(sideLength,0);
          ctx.rotate(2*Math.PI/3);
        }
        ctx.stroke();
      }

Warning: using ctx.stroke() after every little line you draw might make your code inefficient, and slow down your browser.

Transformation functions are also part of the Processing language.