3D Kolmemõõtmeliste lahenduste loomiseks on mitmeid raamistikke loodud, kus kasutajal võimalus kujundid ja kaamera sobivasse kohta sättida ning sealtkaudu meeldivat ruumilist pilti vaadata. Veebigraafika üks abiline näiteks three.js nime all. Samas lihtsamat ruumilisuse efekti kannatab täiesti ka harilike kahemõõtmeliste joonistusvahendite abil tekitada Kaugemal väiksemaks Arvutijooniste puhul tuleb ikka eristada ekraani- ja maailmakoordinaate. Päris lihtsate jooniste korral võib ette kujutada, et üks piksel ekraanil on üks meeter looduses. Või siis üks piksel vastab inimese pikkuse ühele sentimeetrile. Kõiksugu muude suurenduste puhul aga peab väärtused sobiva koefitsiendiga läbi korrutama. Samuti ei pruugi me tahta arve lugeda joonistusala vasakust ülanurgast, vaid mugavam võib olla arvutada mõnest rohkem joonise keskel olevast punktist - selle väärtuse saab arvutuste juures juurde liita. Matemaatikaõpikus oleme harjunud, et y-telg suundub üles, arvutiekraanil suundub see esmalt alla. Ka selle saab märgimuutusega paika sättida. Kolmanda mõõtme juures tuleb maailmakoordinaatidest ekraanikoordinaatideks arvutades lihtsalt üks tehe juurde - x ja y tuleb kaugusega (z) läbi jagada. Ehk siis sama suur asi kaks korda kaugemal näeb kaks korda väiksem välja. Sobivaks nägemiseks tulevad arvud suurenduskordajaga läbi korrutada. Siin puhul selleks valitud kümme. Muutujad keskx ja kesky tähistavad koordinaatide alguspunkti joonisel. Funktsioone ex ja ey kasutatakse ekraani x-i ja y-i arvutamiseks vastavalt maailmakoordinaatides punkti kolme mõõtme väärtustele. var keskx=200; var kesky=150; var suurendus=10; function ex(px, py, pz){ //x ekraanil return keskx+suurendus*px/pz; } function ey(px, py, pz){ return kesky-suurendus*py/pz; } Joonistamise puhul tuleb siis iga kord sobivas kohas lihtsalt vastavad funktsioonid välja kutsuda g.lineTo(ex(x, y, z), ey(x, y, z)); Ehk siis leitakse kolmemõõtmelistele algandmetele vastavad kahemõõtmelised punktid ekraanil. Joonisele tehakse tsükli abil postirida. Posti alumise otsa y on 0, ülemise oma 40 ühikut. Kaugused viiest viiekümne ühikuni. 3D Väikese ettekujutuse tulemusena võib lehel täiesti viisakat postirida näha. Ülesandeid Pane näide tööle Katseta postide mitmesuguste kõrguste ja vahedega Loo sarnane postirida ka vaatajast paremale Paiguta postide otsa väikesed ringid nagu tänavalaternad Kasutaja asukoha muutmine Kolmemõõtmelises graafikas võivad liikuda kujundid, võib liikuda ka aga kaamera ehk vaataja ise. Kui vaatesuund jääb otse ette, siis polegi arvutamisel muud muret, kui tuleb ainult kasutaja asukoht kujundite asukohast maha lahutada. Ekraani x-koordinaadi arvutamine siis: function ex(px, py, pz){ //x ekraanil return keskx+suurendus*(px-vaatajax)/(pz-vaatajaz); } Ehk siis nii x- kui z- koordinaadi puhul on vastav tehe tehtud. Mida ettepoole ise liikuda, seda lähemale tulevad kujundid. Mida ülespoole minna, seda enam paistavad kujundid allpool. Vaataja sammu muutuja näitab, kui pikkade hüpetega ta liigub. Juurde nupuriba vaataja andmete muutmiseks ning tekibki juba julgem ruumilise vaatamise tunne. 3D
Vaade eest ning vaade pärast mõningast üles- ja vasakule poole liikumist. Ülesandeid Pane näide tööle Koosta kujundiks nelinurkse varjualuse sõrestik - postid ja katusepüramiid. Vaata seda mitmest asukohast Koosta kujundiks kuuenurkse varjualuse sõrestik, vaata Koosta kujundiks kasutaja määratud nurkade arvuga varjualuse sõrestik Kolmemõõtmeliste andmete objekt Üksikuid punkte ja jooni arvutada ja kuvada saab täiesti tavaliste muutujatega. Kui aga vaja koos hakata liigutama hulgast punktidest koosnevaid kujundeid, siis tekib üksikuid punkte tülikalt suurel hulgal. Objektitüüpide ja objektide abil aga on võimalik neid mugavamalt hallata, neile ühekorraga käsklusi jagada. Samuti saab niimoodi mitmemõõtmelised arvutustehted nõnda koodi sisse ära peita, et hilisema töö juures ei pea nii palju arvutusvigade pärast muretsema, kui kood algul korralikult üle kontrollitud sai. Vektor Punkt ja vektor mõnevõrra sarnased nähtused. Esimesega küll oleme ehk enam harjunud tähistama asukohta ning teisega liikumist. Aga iseenesest mõlemal on vajalik arv mõõtmeid ning saab külge panna arvutusteks vajalikud käsud, nii et otsest põhjust eraldi tüüpide loomiseks ei ole. Mõistet asukohavektor ka täiesti kasutatakse, nii et las siis siingi piirdutakse ühe tüübiga kolme koordinaadiga määratud suuruse tähistamiseks. Juurde levinud funktsioonid liitmise ja lahutamise kohta. Samuti sisu tekstina väljastamiseks. Kusjuures tähele tasub panna, et praeguse kahe vektori liitmisel tekib uus, kolmas vektor, esialsete vektorite koordinaadid ei muutu. Objektidest andmete tekstina välja küsimiseks on Javaskriptil olemas mugav JSON (JavaScript Object Notation) - vorming. Andmed paigutatakse looksulgude vahele. Sinna sisse järgemööda tunnuse nimi(võti) ning kooloni taga järgnev väärtus. Nagu näiteks siin algandmed {"x":2,"y":4,"z":6} Käsklus JSON.stringify() teeb objektist sarnase andmetega stringi. Kui mõnikord on vaja andmeid tekstist tagasi terviklikuks objektiks muuta, siis selleks sobib käsklus JSON.parse(). Nüüd aga kolmemõõtmelise vektori kood 3D
Töö tulemus kihil: {"x":2,"y":5,"z":6} Ülesandeid Pane näide tööle Lisa vektorile käsklus korruta(arv), mis väljastab uue vektori, kus kõik esialgse vektori koordinaadid on selle arvuga korrutatud. Veendu, et tulemus toimib. Kahest punktist joon Vektor hoiab ühe punkti kolm koordinaati ilusti koos. Kui tahta, et joone andmeid saaks ühe tervikuna käsitleda, siis tuleb omakorda joone kaks otspunkti üheks tervikuks siduda. Siin seda ka tehakse. Joonele luuakse punktide jaoks massiiv, kus kohal 0 on üks otspunkt ning kohal 1 teine. Arvestades varasemat näidet vaataja asukoha liigutamise kohta, lisatakse eraldi tüüp ja objekt ka vaataja asukoha meelespidamiseks ning vastavalt sellele Joone joonistuskäskluses ekraanikoordinaatide arvutamiseks. Valemid sarnased kui enne, lihtsalt nüüd on need funktsioonide sisse pandud ja funktsioonid omakorda objektiks kapseldatud, et juhtkoodis tekkida võivat segadust vähemaks saada. Kui tükid olemas, siis nende ühendamine võiks juba üsna lihtsalt minna. Praegu luuakse kõigepealt uus Joon, mille otspunktide koordinaatideks saavad kaks Vektor3D-d oma väärtustega. Muud toimetused pandi alusta-funktsiooni sisse, sest tahvlile pole võimalik lehe päises avanemise ajal ligi saada. Küll aga on tahvel kättesaadav pärast lehe laadimist body onload-sündmuse peale käivitatava funktsiooni alusta() sees. Vaatajale määratakse asukoht (hetkel nullpunkt), joonistamise graafiline kontekst ning koordinaatide nullkoha asukoht ekraanil (hetkel tahvli keskkoht). Pärast joonistuskäsklust võikski joon ekraanil näha olla. var j1=new Joon(new Vektor3D(-20, 0, 5), new Vektor3D(-20, 40, 5)); var vaataja; function alusta(){ var tahvel=document.getElementById("tahvel1"); vaataja=new Vaataja(new Vektor3D(0, 0, 0), tahvel.getContext("2d"), tahvel.width/2, tahvel.height/2); j1.joonista(vaataja); } Edasi töötav kood tervikuna. 3D Ülesandeid Pane näide tööle Joonista nõnda ekraanile kaks Joont Lisa Joonele värvi omadus Joonista ekraanile kaks eri värvi joont Muuda Vaataja asukohta Joonte kogum Üksikut joont on tõenäoliselt lihtsam ilma igasuguste objektideta joonistada. Kui mitu joont aga moodustavad uue terviku, siis on see mõistlik uude kesta panna - nii on võimalik seda hiljem korraga joonistada, liigutada või värvida. Kogumi juurde tuleb massiiv millesse andmeid lisada. Kogumile antud joonistuskäsklus käib läbi kõik kogumis olevad jooned ning kutsub välja neist igaühe joonistuskäskluse. Praegu siin juures ka käsklus vaataja tahvli puhastamiseks, aga selle saab mujale panna, kui tekib soov mitu kujundit järjestikku samale tahvlile joonistada. function KujundiKogum(){ this.kujundid=new Array(); this.lisaKujund=function(k){this.kujundid.push(k);} this.joonista=function(vaataja){ vaataja.g.clearRect(0, 0, 400, 300); for(var i=0; i Edasi juba kood tervikuna. 3D
Lehel saab nõnda vaatajaga ringi liikuda. Ülesandeid Pane näide tööle Koosta joontest kaks kogumit: kahest joonest T-täht ning kuuest joonest tetraeeder (kolmnurkne püstprisma). Kuva mõlemad ekraanile. Vaata neid kaamera liigutamise abil mitmelt poolt. Lisa kogumile omaduseks toon. Kuva kumbki kogum vastava värviga ekraanile. Lisa kogumile käsklus teeSamm, mis siis kogumis olevaid kujundeid etteantud vektori jagu edasi liigutab. Lisa lehele nupp ühe ekraanil oleva kogumi liigutamiseks. Lisa kogumile muutuja liikumissammu vektorina hoidmiseks. Pane kumbki kujund ühtlase kiirusega tema küljes olevas suunas liikuma. Reaalse mõõtkava arvestamine Siiani tehtud näidetes jagati kaugustunnetuse saamiseks x ja y-koordinaat lihtsalt kaugusega läbi ning vajadusel korrutati suurenduskordajaga, et pilt enamvähem sobivas suuruses oleks. Tõsielulise olukorra järele tegemisel aga saab andmed ka täpsemalt näiteks meetrites välja arvestada ning siis vaateaval mõttelisel kaugusel olevale kilele projitseerida. Ning edasi otsustada, millise suurendusega projektsioonikile punktid arvutiekraani piksliteks ümber arvutada. Kolmnurga valemite järgi on vaadeldava punkti ühe (nt. x) mõõtme koordinaadi ja silmast kauguse suhe sama kui selle punktini viiva joone lõikekoha kilel ja kile kauguse suhe. Sellise arvutuse järgi õnnestub leida koht kilel (px-vaatajax)*kilekaugus/(pz-vaatajaz) Kuna vaataja ei pruugi olla koordinaatide nullpunktis ning tavajuhul on vaatekile mõõtmed pigem võrreldav ekraanipikslite arvuga sentimeetrites, siis saab kolmemõõtmelised koordinaadid kahemõõtmelisteks arvutada järgnevalt. var suurendus=100; //sentimeetrit meetri kohta function ex(px, py, pz){ //x ekraanil return keskx+suurendus*(px-vaatajax)*kilekaugus/(pz-vaatajaz); } Edasi juba programmikood tervikuna 3D
Samuti kaheksanurkse telgi vaated mitmest asukohast.