Gosh it has been a long time. From the last time I wrote something I’ve moved from Brazil to Ireland and I now work at LMI Ericsson Athlone. I’m still a java Engineer, but lately I’m having lots of fun in my spare time with Javascript, JQuery, HTML5 and other languages. After all, Oracle acquired Sun, and I belive it is time to move on …
So, I’m facing some visualization challenges at work, which made me find Raphael which is the best SVG library I could ever find.
After lots of fun, the docs are really easy to understand, I’ve started a few projects of my own. So for the introduction of Raphael, I wanna show a really useful function I’ve created.
The idea is to draw any regular polygon with it. Raphael uses the SVG Path notation, which gives lots of flexibility, but for a normal human being would be hard to code.
Remembering my trigonometry lessons from high school, I recall that one of my math teachers used to draw perfect shapes using a choke attached to a string. After creating a circle he would put points on it and connect through lines, and voilá, perfect triangles, hexagons, octagons and etc…
And that was the inspiration for my function
. Given that I have a center (x,y), a radius, and the number of points, I could find any of the points, and them reconnect them using Raphael simple path function.
The path function takes a SVG path string. Looking like this:
“M x y L a b”
This basically says: Move to x,y and draw a line to a,b. Simple huh?
Now, our function to draw the polygon relies on a simple triangle principle to find the a,b points for every single point entered:
a = x + (radius * cos(angle))
b = y + (radius * sin(angle));
All we have to do is vary the angle according to the number of faces, so angle would be:
angle = startAngle + (i * (1 / faces) * 2 * Math.PI);
So, if we start at angle 0 for a triangle (3 faces) we would create points at 0,120,360. You’ll see that to rotate the triangle with this function all you have to do is change the start angle of it.
This function takes a data argument that has:
data.x: X center of your circle
data.y: Y center of your circle
data.r: radius of circle
data.n: number of faces of the polygon
data.s: start angle
It also relies on 2 global vars:
points: Array
paper: Raphael instance
function shape(data) {
for (var i = 0; i < data.n; i++) {
var point = new Object;
var angle = data.s + (i * (1 / data.n) * 2 * Math.PI);
point.x = Math.round(data.x + (data.r * Math.cos(angle)));
point.y = Math.round(data.y + (data.r * Math.sin(angle)));
points.push(point);
}
var strp = "M" + points[0].x + " " + points[0].y;
for (var i = 1; i < data.n; i++) {
strp += "L" + points[i].x + " " + points[i].y;
}
strp += "L" + points[0].x + " " + points[0].y;
var comb = paper.path(strp).attr({fill:"rgb(255,255,193)"});
comb.mouseover(function(event){
this.attr({fill:"rgb(255,128,64)"});
});
comb.mouseout(function(event){
this.animate({fill:"rgb(255,255,193)"},500);
});
points = new Array();
}
You can play around with the function with the code bellow, just provide x,y,r, and faces to draw your shape. Mark draw inner circle if you want to see the shape inside the original circle.
Have fun: