Instructables universum i Three.js (3 / 13 steg)

Steg 3: Kinetic.js: suggestiva konstellationer



När du Kisa, en konstellation ser ut som något.

Min strategi här var, återigen, att titta igenom stjärnbilderna. Konstellationerna såg jag sällan såg ut vissa saker (det föreföll mig att en persons lion kan vara en annan persons mus, eller bara en kvadrat med några rader som kommer ut av det), men de verkar dela en suggestiv kvalitet härledda från några enkla och konsekventa

Geometriska regler:

-Det finns ingen passage linjer
-Poäng (stjärnor) ansluta mestadels med angränsande eller nära intill stjärnor. Det är ovanligt att ha märkbart längre köer.
-Det tenderar att vara en (ibland noll, ibland två) sluten polygon... ett "organ" av något slag
-Poäng har en, två, tre eller fyra anslutningar. Det finns nästan aldrig fem anslutningar till en enda punkt.
-Konstellationerna består av cirka 3-20 stjärnor

I pseudo-kod är det ungefär så här:

Först passera:
-Börja med en random stjärna
-Föreslå en linje till den närmaste un-bifogade star
-Test att denna linje inte korsar någon befintliga linjer
-Dra denna linje om den passerar, inte om det inte
-Flytta till nästa närmaste stjärna
-Upprepa

Andra Pass:
-Hitta stjärnor med inga anslutningar
-Hitta åtminstone en icke-korsning rad att dra av dessa stjärnor att ansluta dem.

Tredje Pass:
-Lägg till en handfull icke-anslutande linjer

Och slutligen, den faktiska koden jag slutade med:

funktion ConstellationMaker3D(options) {
om (_.isUndefined(THREE) || _.isUndefined(Galaxy) || _.isUndefined(Galaxy.Utilities) || _.isUndefined(Galaxy.TopScene)) {
nya fel ("saknade beroenden för ConstellationMaker3D");
}

ConstellationMaker3D är en funktion av en kamera objekt för 2-dimensionella reglerna behöver en särskild projektion att arbeta från
This.init(options);
}

ConstellationMaker3D.prototype.init = function(options) {
var kamera = options.camera || Galaxy.Utilities.makeTemporaryCamera();
var noder = options.nodes;

_.bindAll (här, ' getConnections');

This.Camera = kamera; Three.js kamera objekt
This.Nodes = this.projectPoints(nodes); Vector2's (math--tillplattad representation av XYZ poäng)
This.segments = []; Line3's (math). Observera dessa är 2D linjesegment; de 3d som återges, men inte en del av stjärnbilden byggandet
This.Connections = []; Matris över anslutna instructable ids. dvs, [[id1, id2], [id2, id3]]
this.disconnectedNodes = [] ;// Vector3's ännu inte behandlat
this.lineObject = null; TRE. Line() objekt

this.calculateConstellation();

om (options.hidden! == true) this.displayConstellation();
};

ConstellationMaker3D.prototype.projectPoints = function(vector3List) {
var det =.
återgå _.map(vector3List,function(vec) {
var position = Galaxy.Utilities.vectorWorldToScreenXY(vec,that.camera),
vec2 = nya tre. Vector2(position.x,position.y);
vec2.instructableId = vec.instructableId;
återvända vec2;
});
};

ConstellationMaker3D.prototype.spatialPointsForConnections = function(connectionList) {
återgå _.map(connectionList,function(connectionPair) {
återvända Galaxy.Utilities.worldPointsFromIbleIds(connectionPair);
});
};

ConstellationMaker3D.prototype.displayConstellation = function(callback) {
Placera tre. JS objekt motsvarar de beräknade objekt i scenen
var connectedPoints3d = this.spatialPointsForConnections(this.connections);
var det =.

om (! _.isEmpty(connectedPoints3d)) {
Initiera geometri, lägga till första punkten
var lineGeometry = nya tre. Geometry();

Anslut följande punkter längs kedjan anslutna poäng
_.each(connectedPoints3d,function(pair) {
var closerPair = par;
lineGeometry.vertices.push (closerPair [0]);
lineGeometry.vertices.push (closerPair [1]);
});

Visa raden
var materialet = nya tre. LineBasicMaterial({
LineCap: "rund",
färg: 0xffffff,
LineWidth: 2,
öppet: sant,
opacitet: 0,5
});
this.lineObject = nya tre. Linje (lineGeometry, material, tre. LinePieces);
this.lineObject.name = "konstellation";
Galaxy.TopScene.add (this.lineObject);
}

om (typeof motringning === "funktion") {
callback();
}
};

ConstellationMaker3D.prototype.movePointsCloser = function(pair) {
del av visar stjärnbilden raderna förkorta segmenten för grafisk effekt.
var end1 = pair[0].clone();
var end2 = pair[1].clone();

flytta varje punkt lite mot andra
var diff = end2.clone().sub(end1.clone());
diff.multiplyScalar(0.08);

återkomst [end1.add(diff.clone()), end2.sub(diff.clone())];
};

ConstellationMaker3D.prototype.clear = function() {
om (! _.isNull(this.lineObject)) {
Galaxy.TopScene.remove(this.lineObject);
}
};

ConstellationMaker3D.prototype.calculateConstellation = function() {
var currentNode = this.nodes.shift(), som = detta.
samtidigt (this.nodes.length > 0) {
currentNode = this.addSegmentFromNode(currentNode);
}
};

ConstellationMaker3D.prototype.closestNodeToNodeFromNodeSet = function(testNode,nodesToTest) {
_.each(nodesToTest,function(potentialNextNode) {
potentialNextNode.distance = testNode.distanceTo(potentialNextNode);
});

var sorterade = _.sortBy(nodesToTest,"distance");
återvända sorterade, eller
}

ConstellationMaker3D.prototype.findLineLineIntersection = function(line1,line2) {
var eqn1, eqn2, intx, inty;

om de två linjerna som delar ett slut (dvs, de dras från samma nod), passera
om (this.shareEndpoint (line1, rad2) === sant) return false;

eqn1 = this.equationForLine(line1);
eqn2 = this.equationForLine(line2);

samma lutning = ingen korsning
om (eqn1.m == eqn2.m) return false;

x-värde på skärningspunkten
intx = (eqn2.b - eqn1.b) / (eqn1.m - eqn2.m);

y-värdet i skärningspunkten
Inty = eqn1.m * intx + eqn1.b;

om x eller y är utanför räckvidden för antingen linje, det finns ingen korsning
var intervall = {
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),
Jesper: Math.max(line1.start.y,line1.end.y)
};
om (intx < range.minx || intx > range.maxx) return false;
om (inty < range.miny || inty > range.maxy) return false;

rad = {
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),
Jesper: Math.max(line2.start.y,line2.end.y)
};

om (intx < range.minx || intx > range.maxx) return false;
om (inty < range.miny || inty > range.maxy) return false;

return true;
}

ConstellationMaker3D.prototype.equationForLine = function(line) {
eqn's lagra m & b från y = mx + b
var m, b;

lutning
m = (line.end.y - line.start.y) / (line.end.x - line.start.x);

y-axeln: b = y-mx. Sub i värden från en känd punkt.
b = line.end.y - m * line.end.x;
returnera {m: m, b: b};
}
ConstellationMaker3D.prototype.shareEndpoint = function(line1,line2) {
om (line1.start.x == line2.end.x & & line1.start.y == line2.end.y) return true;
om (line1.end.x == line2.start.x & & line1.end.y == line2.start.y) return true;
om (line1.end.x == line2.end.x & & line1.end.y == line2.end.y) return true;
om (line1.start.x == line2.start.x & & line1.start.y == line2.start.y) return true;
returnera false;
}

ConstellationMaker3D.prototype.addSegmentFromNode = function(node) {
var nextNodeList = this.closestNodeToNodeFromNodeSet(node,this.nodes);
var proposedLine = this.lineConnectingNodes2D(node,nextNodeList[0]);

om (this.lineIntersectsPriorLines(proposedLine) == true) {
this.disconnectedNodes.push(node);
} annat {
This.Connections.push([Node.instructableId,nextNodeList[0].instructableId]);
This.segments.push(proposedLine);
}

This.Nodes = _.without(this.nodes,nextNodeList[0]);
återgå nextNodeList [0];
}

ConstellationMaker3D.prototype.connectNodeMultipleTimes = function(node,times) {
var närmast = this.closestNodeToNodeFromNodeSet(node,this.allNodes),
lineCount = 0;
för (var jag = 2; jag < closest.length & & lineCount < gånger; i ++) {
var proposedLine = this.lineConnectingNodes2D(node,closest[i]);
om (! this.lineIntersectsPriorLines(proposedLine)) {
This.segments.push(proposedLine);
this.constellationLayer.add(proposedLine);
lineCount ++;
}
}
}

ConstellationMaker3D.prototype.lineIntersectsPriorLines = function(proposedLine) {
var som = denna, intersectionFound = false;
_.each(this.segments,function(testSegment) {
var skär = that.findLineLineIntersection.apply (, [testSegment, proposedLine]);
om (skär === sant) {
intersectionFound = sant;
}
});
återvända intersectionFound;
}

ConstellationMaker3D.prototype.lineConnectingNodes2D = function(node1,node2) {
returnera nya tre. Line3 (nya tre. Vector3 (node1.x,node1.y,0), nya tre. Vector3(node2.x,node2.y,0));
}

ConstellationMaker3D.prototype.getConnections = function(instructableId) {
Returnerar en matris med instructable id's som medföljande id har anslutningar.
var platt = _.uniq(_.flatten(this.connections));
var index = _.indexOf(flat,instructableId);

Switch(index) {
fall -1:
tillbaka [];
fall 0:
återkomst [platt [1]];
ärende flat.length-1:
återvändande platt [flat.length-2].
standard:
tillbaka [platta [index-1], platt [index + 1]];
}
Console.log (instructableId + "hittade på" + index + ' i ' + platt);
}

Övergången från KineticJS till ThreeJS avgjort komplicerar saker. Konstellationerna är fundamentalt 2d i naturen: de är anslutningar mellan punkter i 3 dimensioner (även om du frågar Ptolemy), men stjärnbilden sig biases ett särskilt perspektiv från jorden. Linjer som visas till oss inte att korsa kan faktiskt korsa när du visar dem från sidan, som de gör i den interaktiva demon.

Eftersom ThreeJS fungerar på 3d-objekt, blev en metod för att komprimera data till ett kamera plan nödvändigt. Jag införde några metoder för att få skärmen XY-koordinater för en världen XYZ punkt, med tanke på en kameraposition:

vectorWorldToScreenXY: function(vector,camera) {
Vector antas vara i världen xyz-koordinater kommer in.
var widthHalf = fönster. Galaxy.Settings.width / 2,
heightHalf = fönster. Galaxy.Settings.height / 2,
projektor = nya tre. Projector(),
screenPosition;

projector.projectVector (vektor, kamera);
screenPosition = {
x: (vector.x * widthHalf) + widthHalf,
y: - (vector.y * heightHalf) + heightHalf
};
återvända screenPosition;
},

Se Steg
Relaterade Ämnen

Hur man skapar ett Instructables konto

ansluter till den största sak sedan uppfinningen av T.V. glasögon!Och allt du behöver är:[] En fungerande dator med internet-anslutning (du använder en just nu.)[A] senaste versionen av Java (rekommenderas, men krävs inte.)[] En senare version av Fla...

Tidigare projekt/Pre Instructables...

I wish I would have found Instructables two or three years ago. Jag kunde ha bidragit en fan av mycket mer. Med mina senaste flytta oundvikliga har jag beslutat att samla lite bilder på tidigare projekt på mitt nuvarande hus och bokför dem.Lista över...

Den Tweeting Intercom: (Dörren Strike) relä övervakning med Raspberry Pi

Detta instructable handlar om uppföljning av reläer med en Raspberry Pi. I det särskilda fallet får vi en titt på en sofistikerad Telegärtner DoorLine Pro intercom som innehar två potentialfria reläer. Normalt de används för att utlösa en elektriska...

DIY vinkel slipmaskin handtag

Hej Instructables universum! Jag är en lång tid betraktaren och maker men detta är min första faktiska "vänners kompatibla. Jag fann mig själv behöva göra några hardcore slipning och min palm slipmaskin har mystiskt försvunnit! Lösning: Anslut bara e...

Att vara en konstnär i bostad på Instructables

jag är Samuel Bernier, känd som Patenteux du Nord. Jag är en industridesigner, en maker, en bonde, en resenär och en hård arbetstagare. Jag tillbringade de sista tre veckorna på Instructables som "artist in residence". (Jag älskar denna titel)....

DIY själv aktiverat eget universum

detta är min första någonsin Instructables ladda upp så snälla, var försiktig med mig.Jag gjorde detta för ett litet galleriutrymme på en ARI kallas Constance i Hobart, Tasmanien, Australien, och var särskilt utformade för att aktiveras när människor...

3D skriva ut universum inuti en marmor

Detta instructable kommer att guida dig genom processen att 3D utskrift suspenderade partiklar i en tydlig marmor. Det täcker partikel simulering, konvertera partiklar till polygoner, exportera församlingar och multi-material utskrift.Vad du behöver...

Universum simulering gjorts på din bärbara dator

Hey!Välkommen till detta awesome instructable där vi kommer att göra en simulering från början av universum på din enkel laptop. Det program som vi använder är Adobe After Effects, och du easilly kan överför den fri versionen av den.Vi använder Cosmi...

Hur till: konstruera ditt alldeles egna universum

Detta instructable är en snabb övning att komma igång i branschen att universum konstruktion.Krävs leveranser:-tid (s)-utrymme (m)Steg 1: Definiera rumtidFörst måste du definiera förhållandet mellan tid och rum med en enkel ekvation:tid kubik (s ^ 3)...

Överleva i det vilda-den mest unika instructable hittills

du just har vaknat för att hitta dig själv på plats i naturen. Innan jag går från din ryggläge inser du att, förutom att inte vara i din egen varm bekväm säng, du har vaknat i snårskog under tak av vad kanske en skog. Lyckligtvis är temperaturen mild...

Bädda in en Fusion 360 (3D) modell i din Instructable

Här är en cool nya sätt att förbättra din Instructables med detaljerade interaktiv 3D modeller skapats med Autodesk Fusion 360. Jag tar dig steg för steg genom processen att publicera din Fusion 360 modell på Fusion 360 Galleri och bädda in det i din...

Instructables Robot klockan

Detta är en awesome Instructables Robot klockan som är perfekt för alla skrivbord, natt stannande, fönsterbrädan, Soffbord, etc... Den är liten och trådlösa, vilket gör det perfekt för resor. Att aktivera det bara trycka roboten och titta på honom ly...

Lägga till Video i Instructables DIY

Följ de tre stegen för att lära sig att ladda upp en video i projektet Instructable.Steg 1: PhotoboothSpela in en video i Photobooth. När du är klar inspelningen, dra videon till skrivbordet och döp om den.(Du kan även maila mig en video och vi kan s...

2D tecknad Animation av Instructable Robot

Den bekant instructable robot som vi alla har vuxit till kärlek har nu modelleras i Synfig Studios fantastiska 2D-animation programvara och publiceras på dessa sidor för alla att använda. Fullt fungerande robot modellfilen ingår och allt är gratis. D...

Detaljerad vävda Duct Tape plånböcker Instructable

Ja, ja, det är en annan silvertejp plånbok instructable.Hur tråkigt, rätt?Anledningen jag gör här är att jag ska försöka kornagglomerat kunskap om att bygga alla typer av silvertejp plånböcker och gå in i detalj på många aspekter så att du kommer att...

ANIMATION STATION: En Instructables tävling kurs

Välkommen till ANIMATION STATION, där idéer komma till liv en bildruta i taget. Studenter i kursen arbeta för att utveckla färdigheter i STOP MOTION ANIMATION, medan dokumentera utvecklingen av sina egna kort film genom slutförandet av sina egna INST...

Utbildarhandledning - med Instructables med dina elever

Varför använda Instructables med dina elever:Instructables är ett bra ställe för dina elever att dokumentera en projekt-baserat-lärande verksamhet. Det finns inget bättre sätt för studenter att visa att de lärt sig något genom ett projekt än för dem...

Elektrisk motorcykel på Instructables/hantverkare erfarenhet Webcast

det senaste fredag fick jag gå till Chicago för att möta upp med andra Instructables författare för en direktsänd webbsändning på hantverkare upplevelsen att visa upp våra DIY projekt! Jag tog ut min DIY elektrisk motorcykel!...

Virkade fyrkantig hatt - Instructable Robot, Sponge Bob & WALL-E

En av de projekt som har simmat runt i mitt huvud var denna "fyrkantig" stil hatt, även kallad en jester hatt. Jag kunde inte motstå att ange Instructable Robot tävlingen så detta Instructable är en produkt av två.Medan jag var att skapa robot h...