Univers de Instructables dans Three.js (3 / 13 étapes)

Étape 3: Kinetic.js : Constellations Suggestive

Quand vous plisser les yeux, une constellation ressemble à quelque chose.

Ici, mon approche a été, encore une fois, de regarder à travers des constellations. Les constellations, j’ai vu rarement ressemblait à des choses précises (il me semblait que lion une personne pourrait être souris d’une autre personne, ou même juste un carré avec quelques lignes venant hors de lui), mais ils ne semblent pas partager une qualité suggestive provenant de quelques simples et cohérente

Règles géométriques :

-Il n’y a pas de lignes de croisement
-Points (étoiles) connecter surtout avec étoiles adjacents ou près adjacente. Il est rare d’avoir des lignes nettement plus longs.
-Il a tendance à être un (parfois zéro, parfois deux) polygone fermé... un « corps » d’un certain type
-Points ont un, deux, trois ou quatre connexions. Il y a presque jamais de cinq connexions à un seul point.
-Constellations se composent d’environ 20-3 étoiles

En pseudo-code, c’est quelque chose comme ceci :

D’abord passer :
-Commencez par une star au hasard
-Proposer une ligne à la plus proche étoile non attaché
-Test que cette ligne ne franchit pas les lignes existantes
-Tracer cette ligne si elle passe, pas si ce n’est pas
-Passer à la prochaine étoile la plus proche
-Répéter

Deuxième passage :
-Trouver les étoiles avec aucune connexion
-Trouver au moins une ligne de non franchissement de tirer de ces étoiles pour les relier

Troisième passage :
-Ajouter une poignée de lignes non-connexion

Et enfin, le code réel avec que je me suis retrouvé :

function ConstellationMaker3D(options) {si (_.isUndefined(THREE) || _.isUndefined(Galaxy) || _.isUndefined(Galaxy.Utilities) || _.isUndefined(Galaxy.TopScene)) {throw new Error ("dépendances manquantes pour ConstellationMaker3D");} / / ConstellationMaker3D est une fonction d’un objet de la caméra, parce que les règles 2 dimensions besoin une projection particulière au travail de la this.init(options);} ConstellationMaker3D.prototype.init = function(options) {var caméra = options.camera || Galaxy.Utilities.makeTemporaryCamera() ; nœuds de var = options.nodes ; _.bindAll (thises, ' getConnections') ; This.Camera = caméra ; Three.js caméra objet this.nodes = this.projectPoints(nodes) ; De Vector2 (math--représentation aplatie de points XYZ) this.segments = [] ; De la ligne 3 (mathématiques). Notez que ce sont des segments de ligne 2D ; les 3d sont rendus, mais ne fait pas partie de la constellation de la construction this.connections = [] ; Tableau d’ID instructable connectés. C’est à dire, [[id1, id2], [id2, id3]] this.disconnectedNodes = [];// de Vector3 pas encore traités, this.lineObject = null ; TROIS. Line() objet this.calculateConstellation() ; Si (options.hidden! == true) this.displayConstellation() ; }; ConstellationMaker3D.prototype.projectPoints = function(vector3List) {var qui = cela ; return _.map(vector3List,function(vec) {position var = Galaxy.Utilities.vectorWorldToScreenXY(vec,that.camera), vec2 = trois nouvelles. Vector2(position.x,position.y) ; vec2.instructableId = vec.instructableId ; retour vec2 ; }); }; ConstellationMaker3D.prototype.spatialPointsForConnections = function(connectionList) {return _.map(connectionList,function(connectionPair) {return Galaxy.Utilities.worldPointsFromIbleIds(connectionPair);});} ; ConstellationMaker3D.prototype.displayConstellation = function(callback) {/ / Place trois. Les objets JS correspondant aux objets calculés dans la scène var connectedPoints3d = this.spatialPointsForConnections(this.connections) ; var qui = cela ; Si (! _.isEmpty(connectedPoints3d)) {/ / initialiser la géométrie, ajouter la première lineGeometry var point = trois nouvelles. Geometry() ; relier les points suivants le long de la chaîne de points connectés _.each(connectedPoints3d,function(pair) {var closerPair = paire ; lineGeometry.vertices.push (closerPair [0]); lineGeometry.vertices.push (closerPair [1]);}) ; afficher la ligne var matériel = trois nouvelles. LineBasicMaterial ({linecap: « ronds », couleur : 0xffffff, largeur: 2, transparent : true, opacité : 0.5}) ; this.lineObject = trois nouvelles. Ligne (lineGeometry, matériel, trois. LinePieces) ; this.lineObject.name = « constellation » ; Galaxy.TopScene.add (this.lineObject) ; {Si (rappel typeof === "fonction") {callback();}} ; ConstellationMaker3D.prototype.movePointsCloser = function(pair) {/ / partie d’afficher les lignes de la constellation est raccourcir les segments pour var end1 graphique effet. = pair[0].clone() ; var end2 = pair[1].clone(); / / déplacer chaque point légèrement vers l’autre diff var = end2.clone().sub(end1.clone()) ; diff.multiplyScalar(0.08) ; return [end1.add(diff.clone()), end2.sub(diff.clone())];} ; ConstellationMaker3D.prototype.clear = function() {si ()
! _.isNull(this.lineObject)) {Galaxy.TopScene.remove(this.lineObject);}} ; ConstellationMaker3D.prototype.calculateConstellation = function() {var currentNode = this.nodes.shift(), qui = cela ; while (this.nodes.length > 0) {currentNode = this.addSegmentFromNode(currentNode);}} ; ConstellationMaker3D.prototype.closestNodeToNodeFromNodeSet = function(testNode,nodesToTest) {_.each(nodesToTest,function(potentialNextNode) {potentialNextNode.distance = testNode.distanceTo(potentialNextNode);}); var tri = _.sortBy(nodesToTest,"distance") ; return triés;} ConstellationMaker3D.prototype.findLineLineIntersection = function(line1,line2) {var eqn1, eqn2, intx, inty; / / si les deux lignes partagent une extrémité (c’est à dire, ils sont tirés du même nœud), passer si (this.shareEndpoint (ligne1, ligne2) === vrai) return false ; eqn1 = this.equationForLine(line1) ; eqn2 = this.equationForLine(line2); / / la même pente ne = aucune intersection si (eqn1.m == eqn2.m) retournent false; / / valeur x d’intersection point intx = (eqn2.b - eqn1.b) / (eqn1.m - eqn2.m); / / la valeur y d’intersection point inty = eqn1.m * intx + eqn1.b; / / si x ou y sont hors de portée pour chaque ligne , il n’y a aucune gamme de var intersection = {minx : Math.min(line1.start.x,line1.end.x), maxx : Math.max(line1.start.x,line1.end.x), miny : Math.min(line1.start.y,line1.end.y), maxy : Math.max(line1.start.y,line1.end.y)} ; Si (intx < range.minx || intx > range.maxx) retournent false ; Si (inty < range.miny || inty > range.maxy) retournent false ; gamme = {minx : Math.min(line2.start.x,line2.end.x), maxx : Math.max(line2.start.x,line2.end.x), miny : Math.min(line2.start.y,line2.end.y), maxy : Math.max(line2.start.y,line2.end.y)} ; Si (intx < range.minx || intx > range.maxx) retournent false ; Si (inty < range.miny || inty > range.maxy) retournent false ; retourne la valeur true ; } ConstellationMaker3D.prototype.equationForLine = function(line) {/ / du eqn magasin de m & b de y = mx + b var m, b; / / pente m = (line.end.y - line.start.y) / (line.end.x - line.start.x); / / ordonnée: b = y-mx. Auxiliaire dans les valeurs d’un point connu. b = line.end.y - m * line.end.x ; Return {m: m, b: b} End Function } ConstellationMaker3D.prototype.shareEndpoint = function(line1,line2) {si (line1.start.x == line2.end.x & & line1.start.y == line2.end.y) renvoie true ; si (line1.end.x == line2.start.x & & line1.end.y == line2.start.y) renvoie true ; si (line1.end.x == line2.end.x & & line1.end.y == line2.end.y) renvoie true ; si (line1.start.x == line2.start.x & & line1.start.y == line2.start.y) retourne true ; return false;} ConstellationMaker3D.prototype.addSegmentFromNode = function(node) {var nextNodeList = this.closestNodeToNodeFromNodeSet(node,this.nodes) ; var proposedLine = this.lineConnectingNodes2D(node,nextNodeList[0]) ; if (this.lineIntersectsPriorLines(proposedLine) == true) {this.disconnectedNodes.push(node);} else {this.connections.push([node.instructableId,nextNodeList[0].instructableId]) ; this.segments.push(proposedLine);} this.nodes = _.without(this.nodes,nextNodeList[0]) ; return nextNodeList [0];} ConstellationMaker3D.prototype.connectNodeMultipleTimes = function(node,times) {var = plus proche this.closestNodeToNodeFromNodeSet(node,this.allNodes), lineCount = 0; pour (var i = 2; J’ai < closest.length & & lineCount < fois; i ++) {var proposedLine = this.lineConnectingNodes2D(node,closest[i]) ; if (! this.lineIntersectsPriorLines(proposedLine)) {this.segments.push(proposedLine) ; this.constellationLayer.add(proposedLine) ; lineCount ++;}}} ConstellationMaker3D.prototype.lineIntersectsPriorLines = function(proposedLine) {var qui = ceci, intersectionFound = false ; _.each(this.segments,function(testSegment) {var se croisent = that.findLineLineIntersection.apply (ce, [testSegment, proposedLine]); if (se croisent === vrai) {intersectionFound = true;}}); return intersectionFound;} ConstellationMaker3D.prototype.lineConnectingNodes2D = function(node1,node2) {return trois nouvelles. Ligne 3 (neuf trois. Vector3 (node1.x,node1.y,0), trois nouveaux. Vector3(Node2.x,Node2.y,0)) ; } ConstellationMaker3D.prototype.getConnections = function(instructableId) {/ / retourne un tableau d’id instructable s auquel l’id fourni a plat, connexions. var = _.uniq(_.flatten(this.connections)) ; var index = _.indexOf(flat,instructableId) ; switch(index) {affaire -1 : return []; case 0: retour [plat [1]]; affaire flat.length-1: retour plate [flat.length-2], la valeur par défaut : retourner [plat [index-1], plat [index + 1]];} console.log (instructableId + "trouvé à" + index + ' en ' + plat);}

Le passage de KineticJS à ThreeJS décidément complique les choses. Constellations sont fondamentalement 2d dans la nature : ils sont les connexions entre les points en 3 dimensions (même si vous demandez à Ptolémée), mais la constellation lui-même biaise une perspective particulière de la terre. Lignes qui nous paraissent ne pas traverser peuvent franchir en fait lorsque vous les consultez depuis le côté, comme ils le font dans la démo interactive.

Étant donné que ThreeJS fonctionne sur les objets 3d, une méthode de rétracter les données à un plan de caméra est devenue nécessaire. J’ai présenté quelques méthodes utilitaires pour obtenir l’écran coordonnées XY d’un point XYZ mondiale, étant donné une position de la caméra :

			
          

Articles Liés

Charger votre Instructables dans Galerie de style google images avec PHP

Charger votre Instructables dans Galerie de style google images avec PHP

Vous avez toujours voulu afficher votre instructables de manière élégante dans une galerie, (y compris les photos de plusieurs étapes dans les galeries minis) - pendant le chargement de tout le contenu de votre alimentation si vous n'avez pas au mett
Instructable-dans-un-Tweet : Comment ignorer complètement la limite de caractères de Twitter

Instructable-dans-un-Tweet : Comment ignorer complètement la limite de caractères de Twitter

parfois, vous voulez dire quelque chose qui dépasse la limite de caractères 140 de Twitter.Vous pourriez poster en ligne quelque part et inclure un lien ou diviser le texte en un nombre de tweets distincts, mais les deux options risquent un manque de
Comment faire votre instructable dans le style manga

Comment faire votre instructable dans le style manga

Il s'agit d'un dessin de style bricolage instructable (nommée INSA-2011) du manga. Maintenant la règle majeure de dessin manga est de commencer avec un schéma de base de la figurine que vous souhaitez dessiner. Hiérarchique est et fait partie intégra
Mettez un ensemble instructable dans un unique fichier pdf.

Mettez un ensemble instructable dans un unique fichier pdf.

Un fichier pdf peut contenir plus de texte et des images. Instructable contiennent souvent des films, des fichiers pdf supplémentaire, etc.. Il est parfois commode de mettre toutes les ressources dans un fichier pdf unique.Etape 1: Film logiciel Cett
Robot jouet - Instructables dans Tinkerplay

Robot jouet - Instructables dans Tinkerplay

Autodesk Tinkerplay est une application gratuite qui vous permet de concevoir et de personnaliser vos propres créatures et personnages sur votre appareil mobile et de rendre réel à l'aide d'une imprimante 3D. Nous concevons Instructables robot.Étape
Comment entrer dans le défi de portefeuille Instructables

Comment entrer dans le défi de portefeuille Instructables

vous nous avez dit encore et encore, et nous avons finalement obtenu le message : DIY portefeuilles sont chauds.Porte-monnaie fabriqué à partir d'un clavier d'ordinateurPochette papierportefeuille de qualité duct tapele portefeuille de bande de condu
Conversion : Instructables tablier dans le sachet

Conversion : Instructables tablier dans le sachet

Un seul mot qui me décrit avec justesse : pratique.Ainsi, alors que j'étais heureux de recevoir un tablier Instructables dans le cadre d'un package, mon esprit flashé à la quantité minime de cuisson (ayant été proclamé un danger dans la cuisine dès s
Vue instructable comme un utilisateur pro avec des fonctionnalités supplémentaires (toutes les étapes dans une page + enregistrer).

Vue instructable comme un utilisateur pro avec des fonctionnalités supplémentaires (toutes les étapes dans une page + enregistrer).

Il s'agit de mon premier instructable. Si vous avez des suggestions, s'il vous plaît laissez-moi savoir. Espérons que vous apprécierez ce. Avez-vous déjà pensé à la visualisation de toutes les étapes d'une instructable dans une page et en l'enregistr
Plasma dans un tube à essai

Plasma dans un tube à essai

Salut tout le monde !Il s'agit de mon deuxième Instructable et anglais n'est pas ma langue maternelle, donc je vous les gars demande peu de patience pour les EVENTUELLES inexactitudes formelles.J'ai décidé d'entrer dans ce Instructable dans le enseig
Comment créer un compte de Instructables

Comment créer un compte de Instructables

comment faire pour rejoindre la plus grande chose depuis l'invention des verres T.V.!!Et tout ce dont vous avez besoin :[] Un ordinateur avec une connexion internet (vous utilisez l'un dès maintenant.)[] A la version récente de Java (recommandé mais
Tirez ensemble de postes de clôture en bois dans le béton avec pas creuser !

Tirez ensemble de postes de clôture en bois dans le béton avec pas creuser !

J'ai voulu faire ce post pour peut-être aider quelqu'un à sauver un peu de temps s'ils ont jamais besoin de remplacer une clôture, qui a des poteaux de bois qui sont définies dans le béton, ne veulent pas avoir à creuser à la main.Voici l'histoire.Ma
Chroma - lumière dans une boîte de

Chroma - lumière dans une boîte de

Chroma.lumière dans une boîte.Chroma est une simple boîte. Il s'allume quand vous le souhaitez. Quelle que soit la couleur que vous voulez, quand vous le voulez.Chroma est une boîte de double bord allumé app contrôlée ; rendue possible par les capaci
Comment intégrer une vidéo sur Instructables

Comment intégrer une vidéo sur Instructables

parfois la meilleure façon de transmettre une idée dans une Instructable doit montrer une vidéo.  Ce tutoriel vous guidera dans le processus de recherche de que code d'intégration de votre vidéo et coller au bon endroit dans votre Instructable.Vous p
Comment écrire une Instructable

Comment écrire une Instructable

Instructables sont la raison pour laquelle que ce site existe.Il existe plusieurs façons de présenter votre travail ici et tout le monde trouve son propre style, mais il y a des choses que bons instructables ont en commun, et c'est le but de ce Instr