zondag 16 oktober 2016

Adapting the bounding box of an SVG to scale to content

<!doctype HTML>
<html>
 <body>
 <div style="width: 50px; height: 50px; padding:0px; background-color: #eee;">
 <svg width="100%" height="100%" id="test">
  <circle cx="50" cy="1" r="10" stroke="green" stroke-width="4" fill="yellow" />
  <circle cx="5" cy="20" r="15" stroke="blue" stroke-width="4" fill="red" />
</svg>
</div>
<script>
var svg=document.getElementById("test");
setViewboxToContent(svg);

function setViewboxToContent(svg)
{
 var bb=svg.getBBox();
 var w=bb.width;
 var h=bb.height;
 var l=bb.x;
 var t=bb.y;
 svg.setAttribute("viewBox", (l-2)+" "+(t-2)+" "+(w+4)+" "+(h+4)); 
}
</script>

 </body>
</html>

The bounding box of the SVG can be anything

Just try and move the circles around..
I give 2 pixels margin for fatter lines, when your circles get real small or close together.
It's not perfect, because line-thickness is not taken into account by SVG.getBBox(). but it's quite good. nonetheless

dinsdag 11 oktober 2016

Evolutie in MuziekEditor

Evolutie is het zich aanpassen van een organisme aan zijn omgeving door het maken van verschillende varianten van zichzelf, waarvan er een aantal sterven en een aantal overleven.

Dit principe vind ik al geruime tijd interessant om te vertalen naar computers en ik heb het met succes toegepast voor Building Dragons in navolging van Theo Janssen.

Maar nu dringt zich een systeem aan mij op, dat bij uitstek geschikt is voor zo'n systeem.
Muziek..

  • Een melodielijn zou je kunnen zien als een organisme. Het leeft, vraagt interageert en groeit en verandert.
  • De akkoorden waardoor een melodielijn zich beweegt bepalen zijn 'succes'. 
  • Succes is in dit geval hoe het in het oor ligt.
Door componisten worden akkoorden meestal afgeleid van de melodielijn, maar bij een expert-systeem dat melodielijnen ontwerpt werk je andersom. (Note to self: Ik heb daar nog ergens een boekje over, ligt naast de printer, kon wel eens interessant zijn).

Stel nu, dat we een akkoordprogressie vast stellen, dan zouden we een melodielijn kunnen laten evolueren, waarbij we een gebruiker een aantal varianten laten horen en hieruit laten kiezen in een aantal generaties.

  • In principe kan een volgend akkoord in een progressie ook zo worden gezien: als een systeem van pitches, die zo weinig mogelijk van zichzelf veranderen. 9/10 van de muziek zit zo in elkaar.
  • Als deze melodielijn dan weer het volgende akkoord bepaalt (eventueel met hetzelfde principe van evolutionair de gebruiker laten kiezen) kan een volslagen leek muziek maken op midi-niveau.
  • Andere partijen zoals de bas, maar ook principes als het ritme kunnen ook op deze manier ontstaan en toegepast worden op het hele of een deel van de compositie.


vrijdag 30 september 2016

Point In Polygon Algorithme

Ik heb lang gezocht naar een GOED point in polygon algorithme.
In mijn geval betekent GOED, dat je geen rekening hoeft te houden met winding-rules, dat het snel is en makkelijk in gebruik voor de developer.

Ook moet het ALLEEN point in polygon doen en geen grote berekeningen, dat doe ik daarna wel op eigen houtje.

Nou, daar is hij dan:
var point={x:10,y:10};
var plgn=[{x:5,y:5},{x:55,y:5},{x:55,y:55},{x:5,y:55}];
console.log(PointInPolygon(point,plgn));

function PointInPolygon(p,pgn)
{
 var i,j,c=false;
 for(i=0,j=pgn.length-1;ip.y)!=(pgn[j].y>p.y))&&
  (p.x<(pgn[j].x-pgn[i].x)*(p.y-pgn[i].y)/(pgn[j].y-pgn[i].y)+pgn[i].x))
  {
   c=!c;
  }
 }
 return c;
};

Test het hier: https://jsfiddle.net/uvr9wt5j/

woensdag 9 maart 2016

Illusion with AnimGif encoder Javascript

There have been some implementations lately to create gif89a with the new webworkers.
I didn't get round to it, because I wanted a clean version (with a workaround for older browsers), and frankly because I have been a bit under the weather and had other things to think about.

But yesterday I said to myself I had to get back in the saddle. So this is the first thing I tackled.
I wanted to have a nice application, where you can convert game-footage into animated gifs smoothly. And to test it, I generated this small illusion. Enjoy.
If you stare at the middle a while, things will start growing when you look at them.
Also, I just like the confusion around the stripe.. If you look at a single wind of the spiral, you'll see it appears not actually to be moving to the middle, it jumps back.. The animation seems not to be smooth.
However, when you look at the middle, the spiral seems to be continuously moving inward
and the animation is smooth again..


In fact, for a good test, I wanted to render something with a lot of color. (gif89a being a 256 color format) So here is another one, but with changing colors. It makes the illusion less effective, but it's better for testing..



zaterdag 6 februari 2016

Mother of pearl illusion



Ik ben bezig met een aantal nieuwe illusies. Dit is er een van.
Gek genoeg doet hij het niet, als ik hem film, wel als ik hem animeer.
Wie weet waarom?

zondag 17 januari 2016

7 Principles of Programming - 2

Principle 2

After seeing principle 1, most people are astounded how easy programming has become.
It has allready exceeded their expecations of what they are capable of. That is a nice moment to go on to something slightly more complex.

Conditions and expressions.
var b=1;
var a=2;
if(b>0) a=a+1;

This needs a line by line explanation. b=1, a=2, we know those.
the if statement is new. It means: if b is bigger than 0 do whatever comes next.

b>0 (b is bigger than 0)
b>=0 (b is bigger than or equal to zero)
b<0 (b is smaller than 0)
b<=0 (b is smaller than or equal to zero)
b==0 (b is exactly zero)

Stick to integer math and you'll be fine.

The next thing you might want to know is the else statement.
var b=1;
var a=2;
if(b<0) a=a+1;
else a=a-1;

This means, if the statement or 'expression' in between the ( ) is true, do the first thing after if. If it is NOT true, do the first thing after else.


This is very handy. In a flow chart it is presented as such:
If you are not familiar with flow-charts, never mind. If you are, this might help you 'translate'
It is good to consider how a program reads a program at this point.
It always moves from the top, to the left. When it reaches the end of the line, it will go to the next line.
But...
If it encounters certain statements, like if this behaviour briefly changes. It can jump and the jump back.
In the case we presented only for one instruction.
So what if you want to have a couple of things happen if the statement is true?
You make a block with { and  }
Everything inside the block is considered the 'thing' after if and will be executed as a whole before moving on.
var b=1;
var a=2;
if(b>0)
{
a=a+1;
        a=a*a+1;
}
else a=a-1;

So because B>0 the block is executed, a becomes 3 and then it becomes 3*3+1=10.


Here we see indenting for the first time. There are several schools of thought on this. This is mine.
The idea is, that you find the { on the same indent-height as it's } counterpart. Not everybody agrees this is the 'right' way to do it.
You will also see this:

var b=1;
var a=2;
if(b>0){
a=a+1;
        a=a*a+1;
}else a=a-1;

It means exactly the same thing.

Ok, in the same way we might make a block for anything after else.
This is your work. Test it, change it, hit run, see what happens.
Get into the habit of forming a hypothesis and testing every bit of it.
For instance try to predict what:
var b=1;
var a=2;
if(b>0)
a=a+1;
a=a*a+1;

would do and test it.

HOW TO TEST YOURSELF AND YOUR PROGRAM!

Form a idea of what will happen. Make sure you can see it happening by some output or feedback.
Always test your hypothesis by changing something from a working example (which you have tested yourself!) and then testing the change.
If it still works, that tells you something, if it doesn't that tells you something too.
Try to think of what both cases will tell you, before you test it.
Don't change a whole bunch of things before testing.
If you find it doesn't work at that point, it will be hard trying to find the problem.
If you change one thing, test and it doesn't work, the problem is ALWAYS with the last thing you changed.
Don't disregard unexpected results. They are a learning oportunity.
If you do this always, you will NEVER be unable to solve a bug, unless it is in some part of the program, that you don't have access to. (In this case, either Javascript or JSFiddle, both are quite stable)

Ok, so we learned about:
-expressions
-conditions
-branching (doing a bit of code in a differnt place before continuing with the flow of the program)
-code blocks
-testing.

This is a lot to take in. If you feel you need a break, take 10 minutes before coming back.

7 Principles of programming - 1


Principle 1

Variables.. I explain them like this:
A variable is like a little flat box. It has a label, that has the name of the variable.
You can put things in there.
You can make a box with "var";
You can put three kinds of things in there: numberscharacterstrings (not the same as words, because it can contain spaces and numbers and even linebreaks! Think of it as TEXT, if you will but call it a string) and objects.


The box can only contain one thing at a time.
If I put "hello world" in and then 1.547 the box will ONLY contain 1.547. "hello world" pops out and is lost in nothingness.



If you click the link, you will be redirected to a place on the web called jsFiddle.
Here you can play around with short bits of code to test a principle.

It is ideal for getting to understand a piece of code, because you can change it and hit run. You will see the result immeadeatly.
JSFiddle is NOT good for debugging. You need different tools for that.

I explain how a computer deals with numbers and character strings by showing the results of
var a=1+1;


and
var a=1-1;



Then I show the result of
var a="hello "+"world"


and of
var a="hello "-"world".



After that I ask what the difference is between var a="1"+"1" and var a=1+1.
Can you answer that? Why is the result of the last jsfiddle: NaN (meaning Not A Number)

Then I do this:
var b=1;
var a=2;
var c=a+b;



and I ask what C is. Most people get that. It's a good point to check if you are still with me.

Then we will start having some fun.
var a=5;
a=a+1;

If you are one of the rare people who find this exciting, we'd move on to things like.
a=a*a/2;
or even
a=a%4;
which will give you a little kick then. But most people don't like to go that far.
I think I've spent about a week in this stadium, imagining how I could get the computer to do ALL my homework. (I was 9 at the time)

Somewhere inbetween I will start putting comments in. They are color coded, which means people ignore them anyway.. But it's a nice moment to explain comments. It's not really a principle of

You will notice that I haven't touched objects yet, I just mention them. If you want to know why, read the red part. Else you can skip it for now.
In order to show the result in HTML I put it in a div, to create the div on JSFIDDLE
HTML: <div id="result"></div>

So I need to do this in Javascript:
  var result_box=document.getElementById("result");
and I use 
result_box.innerHTML=....
to show them the result when the page is loaded.

If anyone asks if document.getElementById("result") is a string or a number, I need a good answer.
The answer is that document.getElementById produces an object. And I leave a little mystery hanging there.
(Strictly speaking numbers and strings are a kind of built in object-instance, but hey.. We're just starting. That would only confuse you. I might mention it's a bit of a simplification, but it's not wrong! And it certainly helps you understand the concept of a variable, which was the idea.)



woensdag 6 januari 2016

Math problem - Circles

http://www.roytanck.com/2016/01/04/math-problem-why-does-this-work/

Roy states the following problem The length of the white area, which composes the outer shape if for each circle: d= (360/number_of_circles_in_graph)*2 , where d = degrees.
This is more or less correct.

Now let's look at that.
For 0 circles it would be (360/0)*2=infinity degrees. You go around endlessly.. ok..
For 1 circle it would be (360/1)*2=720 degrees. You go around twice.
For 2 circles it would be (360/2)*2=360 degrees. You go around once.
For 3 circles it would be (360/3)*2=240 degrees. You go around 2 thirds.
For 4 circles it would be (360/4)*2=180 degrees. You go around half a circle
For 5 circles it would be (360/5)*2=144 degrees. you go around 2 fifths of a circle.
If you don't look too hard at the first cases with one circle and zero circles it works.
Why?

The circle are rotated around a point, let's call that x:0,y:0 or o. (dark red)
In the case of four circles, we create the first circle at 0,0, at an angle of 0 degrees.
And place the midpoint away from o.
How far: exactly the radius of the circle.
The previous circle will be at 360/4= -90 degrees. Also placed a distance of the radius away from o.
To get to the 'outline' we have to look at the next circle as well at 90 degrees.


The green point is at the beginning of the arc along the current circle, that together with the arcs on the other circles form the 'outline'. (The red bit)
The startpoint of this arc must be on both the next (top) and current circle (left).
There are only two points, that qualify. o (dark red), which is by definition 'inside' and the green point.

Because the point is on both circles, the angle from the midpoint of the current circle to the green point is 90 degrees. This angle echos the creation of the circles: It's a repetition of the circle's original rotation.
The same must be true for the previous circle at 90 degrees. To get the total angle of the arc: from -90 to 90 = 180 degrees.
This is true for 4 circles, but it works for any amount of circles higher that 2. (2 itself is a bit mind-bending, but I think the same principle applies)

To show you this is true, we look at the situation for 5 circles. The angle to get the next circle is -72
 -(360/5) and the angle to get the previous one is 72 (360/5). (or the other way around, depending in which direction you draw your circles)
If you set up the lines again, you see that the 'outer' arc must be those two angles combined, so 2* 360/5= 2*72=144
Your formula is implied in the problem.

NOW>>>
If the circles did NOT intersect at the origin this formula wouldn't work.
The formula would then be d=(360/nr_of_circles+a)*2
Where 'a' would be a function of the (distance to the origin of the midpoint - radius of circle) or the distance to the closest point on the circle and having a range, because at some point the circles would stop touching at all. This range would be zero to zero for two circles and slightly bigger for each additional circle, with a limit at a zero to triple the circle radius (where no circles would ever touch).