Archives par étiquette : javascript

WebGL Paris 2014

eiffel_tower_-_render_04WebGL Paris 2014 est un événement ouvert à tous, gratuit, francophone, framework agnostic consacré au WebGL sous toutes ses formes. Il aura lieu à le Lundi 13 Octobre 2014 de 13h à 22h à l’Institut des Systèmes Complexes, au 11 Place Nationale, dans le 13ème arrondissement de Paris.

Les inscriptions sont déjà ouvertes, accompagnées d’un petit questionnaire car cet événement sera ce que l’on en fera. Toutes les bonnes volontés pour donner des conférences, participer à l’organisation, à des ateliers sont les bienvenues.

Plus d’informations sont disponibles sur le site internet du meetup : http://www.webglparis.com

Floating News

html2canvas est une librairie javascript permettant de rendre du code HTML avec des CSS dans un canvas. Elle est disponible ici : http://html2canvas.hertzen.com/ .

Afin de prendre en main cette librairie, voici une petite démonstration développée en quelques heures. Elle affiche le contenu de Google News ( http://news.google.com ) avec un effet ondulant. C’est essentiellement un exercice de style, cet effet ne facilitant pas trop la lecture… Techniquement, le canvas contenant le rendu de la page est récupéré par webgl, qui rajoute l’effet d’ondulation via le Fragment shader. Le canvas webgl contient l’attribut CSS pointer-events: none , qui a pour effet de rediriger tous les évènements souris et clavier vers la page web originale toujours affichée derrière. Grâce à cette astuce, les liens hypertextes de la page fonctionnent toujours.

La démonstration est disponible ici : http://www.spacegoo.com/floatingNews

Vidéo capture d’écran :

Floating news
Runtime
0:21
Compteur de vues
253

 

Pavages de Penrose

Pour notre future démo, nous nous sommes intéressés aux pavages de Penrose.
Il s’agit de pavages non-périodiques du plan construits à partir de règles locales. Ainsi, contrairement aux pavages classiques périodiques qu’on peut voir par exemple dans les mosaïques de l’Alhambra, ceux-ci ne possèdent aucune règle qui permet de déduire l’ensemble du dessin par une suite finie de rotations/translations.
En résultent des motifs surprenants et très beaux.
D’un point de vue scientifique, ils servent à étudier les quasi-cristaux, notamment pour déterminer leurs figures de diffraction. Alain connes s’en sert également comme d’un exemple privilégié pour illustrer sa géométrie non-commutative.

Nous allons décrire un algorithme pour construire de tels pavages à partir de triangles d’or. Un triangle d’or est un triangle isocèle dont le grand côté est \varphi fois plus long que le petit côté. Il n’en existe que deux types :
On définit alors une procédure de découpage de ces triangles. Partant de l’un ou l’autre cas, on le coupe en deux suivant la méthode suivante :

  • A gauche :  \lVert SR\rVert = \lVert RQ \rVert ou de manière équivalente : S = (2-\varphi)*P + (\varphi - 1)*Q
  • A droite :  \lVert RP\rVert = \lVert RS \rVert   ou de manière équivalente : S = (\varphi - 1)*Q + (2-\varphi)*R

Les triangles générés par un tel découpage sont également des triangles d’or, ce qui permet de réiterer la procédure. Il faut noter qu’à chaque subdivision, on a le choix entre une division « à gauche » ou « à droite », ce qui permet de générer autant de façon de paver le plan que nécéssaire.
Nous avons fait le choix d’une méthode particulière, qui génère de beaux pavages, et en voici l’algorithme, en pseudo-code de type javascript, avec une gestion manuelle de la pile de récursion, pour éviter de la faire exploser à l’éxécution :

// lvl donne le nombre de subdivisions
penrose = function(lvl) {
var Q = [100, 100];
var R = [100, 500];
var P = [716, 300];
// lvl désigne la distance qui sépare le triangle de la subdivision maximale autorisée
var root = Triangle(P, Q, R, "aigu", lvl);
var stack = [];

stack.push(root);
// Tant que la pile de triangle non-subdivisés est non-vide :
while (stack.length > 0) {
var zde = stack.pop ();
if (zde.prof <= 1) { // cas terminal
zde.draw ();
}
else {
// split renvoie le point S suivant la procédure décrite plus haut
var S = zde.split ();
if (zde.style === "aigu") {
stack.push(Triangle(zde.R, S, zde.Q, "aigu", zde.prof-2));
stack.push(Triangle(S, zde.P, zde.R, "obtus", zde.prof-1));
}
else {
stack.push(Triangle(zde.R, zde.P, S, "aigu", zde.prof-1));
stack.push(Triangle(S, zde.P, zde.Q, "obtus", zde.prof-2));
}
}
}
}

Ce code termine puisqu’à chaque étape, on ne génère que des triangles dont la profondeur est strictement inférieure au triangle courant et que le cas terminal ne renvoie rien.

Nous l’avons utilisé en javascript en dessinant un tel triangle découpé avec 16 niveaux de profondeurs :

La démo est disponible ici :http://www.spacegoo.com/penrose

Héritage en Javascript

Le javascript est aujourd’hui largement utilisé sur le Web. Tous les navigateurs implémentent leur moteur javascript, et il est évidemment le langage incontournable quand il s’agit d’utiliser WebGL ou WebCL.

Il est présenté comme un langage objet, mais ses capacités à ce niveau restent nativement limitées. Notamment, l’héritage n’est pas prévu. Lorsqu’on développe une application conséquente, l’héritage est pourtant un facteur indispensable pour réduire la quantité de code et donc les coûts de développement d’une application.

Il existe plusieurs méthodes pour contourner cette faiblesse du langage, et nous allons vous en présenter une, qui est à notre avis la plus souple et la plus élégante. Selon la terminologie de Douglas Crockford, il s’agit d’un pattern d’héritage « fonctionnel ». Rien ne vaut un exemple, alors en voici un :


var motherClass = function (spec) {
var that = {}; // création de l'objet retourné
that.get_name = function () { // "virtual" method
}
return that;
}

var daughterClass = function (spec) {
spec.name = spec.name || "";
var that = motherClass(spec); // l'héritage est ici : on initialise l'objet retourné en utilisant le constructeur de la classe mère
that.get_name = function () { // on spécifie le code de la méthode "virtuelle" mère
return "daughterClass : " + spec.name;
}
return that;
}

var instance = daughterClass({name: "daughter"}); // instanciation
console.log(instance.get_name ());

daughterClass : daughter 

On peut alors spécifier plusieurs classes héritant de « motherClass ».
Une autre classe pourrait par exemple être :

var daughterClass2 = function (spec) {
spec.name = spec.name || "";
var that = motherClass(spec); //héritage ici!
that.get_name = function () { // et respecification de l'interface
return "daughterClass2 : " + spec.name;
}
that.special_to_this_class = function () { // methode specifique à la classe daughterClass2
return "special";
}
return that;
}

Et on peut alors utiliser cela dans un même tableau (c’est un avantage du non-typage javascript) :


var tab = [];
tab[0] = daughterClass({name: "1"});
tab[1] = daughterClass2({name: "2"});

for (var i = 0 ; i < 2 ; ++i) { console.log(tab[i].get_name ()); }

daughterClass : 1
daughterClass2: 2

Après cela il ne tient qu’à vous d’enrichir les méthodes pour obtenir ce que vous voulez!

PS : notez que dans ces classes, on ne peut accéder aux attributs autrement qu’avec la méthode get. C’est un forme d’encapsulation des données!