Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: 3D ohjelmoinnin alkeita, ongelma

Sivun loppuun

PetriKeckman [03.07.2022 18:10:23]

#

3D ohjelmointikykyni ovat alkeelliset. Tiedän kuinka x,y,z koordinaatta projisoidaan screenin kaksiulotteiselle pinnalle:

;projisoi
jakaja:  maxx - (z + origz)
if jakaja = 0 [jakaja: 0.000000001]
temp: maxx / jakaja
xscreen: x0 + ((x + origx) * temp)
yscreen: y0 - ((y + origy) * temp)

... ja jotenkuten kuinka pisteitä kierretään x,y ja z-akselin ympäri. Siihen se jääkin.

https://youtu.be/0jGaEJhxHRM

Nyt pitäisi saada tietää, että miten otetaan selville koska jokin tasainen pinta näytetään. Intuitio sanoo jotain, että "silloin kun pinnasta piirretty kohtisuorainen jana osoittaa katsojan suuntaan", tai jotain muuta ehkä liian monimutkaista minulle - kuitenkin muistan joskus 80-luvulla lukeneeni Pelin tekijän oppaasta, että ongelmaan on hyvin yksinkertainen testikin, missä käytetään pelkästään yhteen- ja kertolaskuja.

Kuten tuosta pyörivästä kuutio videosta näette, niin kuution takaseinäkin, mikä osoittaa katsojasta poispäin, aina näytetään, mikä siis on se ongelmani.

Ja ei: REBOL:ssa ei ole mitään 3D kirjastoja, vaan kaikki on ohjelmoitava itse alusta loppuun.

Metabolix [03.07.2022 18:54:13]

#

Kannattanee tutustua vektorien piste- ja ristituloon ja vektorin normalisointiin, joita yhdistelemällä onnistuu suurin osa kaikesta 3d-grafiikkaan tarvittavasta matematiikasta. En anna suoraa kaavaa, koska jos et opi itse laskemaan ja soveltamaan, olet huomenna taas uuden samanlaisen kysymyksen kanssa täällä.

jalski [03.07.2022 19:08:38]

#

Täältä kannatusta Metabolixin neuvolle. Ottamalla ristitulon kahdesta vektorista mitkä muodostavat polygonin kaksi sivua saat laskettua polygonille normaalin ja tiedät, että polygoni on näkyvä, jos se osoittaa katsojaa kohti. Tämä metodi on yksinkertainen, mutta asettaa joitain rajoituksia polygonille joihin kannattaa tutustua ettei tule yllätystä.

PetriKeckman [03.07.2022 21:07:14]

#

Metabolix kirjoitti:

Kannattanee tutustua vektorien piste- ja ristituloon ja vektorin normalisointiin,...

Sivu käsittelee blankkoja sillä tavalla, että en voi esittää viestiäni täällä, mutta esitän sen kuvana:

https://petke.info/viesti.png

Viestissä on linkki, tämä: https://petke.info/nelio.png

Metabolix [03.07.2022 21:44:28]

#

Koetapa Petri käyttää kooditagia tasalevyisen tekstin esittämiseen. Teksti kuvassa on aika kelju tapa esittää "viesti".

Tekemäsi laskutoimitukset näyttävät vilkaisten oikeilta ja noista voi lähteä liikkeelle, eli kulmien koordinaateista voi muodostaa vähennyslaskulla vektorit, näiden ristitulona sitten saa kohtisuoran eli tasosta ulospäin osoittavan vektorin, josta katseen suuntavektorin kanssa laskettavan pistetulon etumerkistä selviää, onko tason etupuoli katsojaan päin.

Yksi laskuissa huomioitava asia on vielä, onko koordinaatisto oikea- vai vasenkätinen ja onko kulmion kulmat lueteltu myötäpäivään vai vastapäivään. Valitsemalla jonkin näistä väärin voi saada laskuissa vastakkaisen etumerkin.

PetriKeckman [03.07.2022 21:52:16]

#

Metabolix kirjoitti:

Koetapa Petri käyttää kooditagia

No tässä kooditägeilla (joiden niidenkään käyttö ei niin kätevää ole, kun rivit jatkuvat reunan yli).

Mod. korjasi kooditagien järkevän käytön.

Hienoa Metabolix, että kannustat itseopiskeluun. Googlailu johti mm. tänne Ohjelmointiputkaan. Kuvittelisin, että osasin muodostaa kahden vektorin ristitulon:

kohta 1):

[x1}   [x2]       [(y1 * z2) - (z1 * y2)]
[y1} * [y2]   =   [(z1 * x2) - (x1 * z2)]
[z1}   [z2]       [(x1 * y2) - (y1 * x2)]

Siinä siis vektoreiden alkupisteet ovat origossa, siksi yhden vektorin
määrittää kolme lukua eli x,y ja z koordinaatta, mikä matriisein merkitään:

[x]
[y]
[z]

Kuvittelisin myös, että osaan ottaa kahden vektorin pistetulon:

kohta 2):

[x1]   [x2]
[y1] * [y2] = (x1 * x2) + (y1 * y2) + (z1 * z2)
[z1]   [z2]

Pistetulo ei siis ole vektori vaan luku.

Vektorin x,y,z normalisointi taas tarkoittanee sitä, että vektori
jaetaan sen pituudella eli kun pituus:

pituus=Squre-Root((x*x)+(y*y)+(z*z))

kohta 3):
Niin vektorin (x,y,z) normalisoitu vektori on (x/pituus,y/pituus,z/pituus))

Ennen kuin alan pureskelemaan sitä vaikeaa pähkinää, että miten näillä laskutoimituksilla saadaan selville osoittaako neliö katsojaa kohti, niin kysyn, että ovatko nuo laskutoimitukset oikein?

kohta 4)
Ja lopuksi kysyn, että onko siis kyseessä siis tällainen neliö: https://petke.info/nelio.png

Ei tarvitse neuvoa pidemmääle kunhan sanotte ei tai kyllä, että onko oikein vai väärin ja mikä kohta 1, 2, 3 tai 4, jos jokin on väärin.

PetriKeckman [04.07.2022 19:51:25]

#

Eipä kuutiohommasta tunnu paljo mitään tulevan, ainakaan vielä. En hallitse teoriasta käytäntöön vääntämistä enkä näköjään osaa edes tuolla -> https://retro64.altervista.org/blog/another-look-at-3d-graphics-fast-hidden-faces-removal-back-face-culling/ olevasta hyvästä oppaasta apinoida. Mulla oli enkku 5 lukiossa, että sekin vaikeuttaa luetun ymmärtämistä.

Tätä en ymmärrä sieltä:

'Please note that x(9) must be rotated along with the other points.'

Minä lasken sen aina uudestaan kun en ymmärrä miten sitä voitaisiin rotatoida? Kierroilla x,y,z-akseleiden ympärikö?

Apinointia hankaloitti tosi paljon myös se, että mulla on kulmapisteet numeroitu eri tavalla: https://petke.info/munnumerointi.png

Enkä osannut/ruvennut/jaksanut ajatella edes aliohjelman tekoa vaan manuaalisesti kopsasin koodia jokaiselle kuudelle tahkolle erikseen.

Ainahan tosin voin perustella aikaansaannostani sillä, että en ole koodari, vaan olen taiteilija ja tämän tuotoksen voi tulkita hyvinkin taiteellisena:

https://youtu.be/igQv1QTUCtE

(on error...)

PS: Ei välttämättä tarvitse neuvoa, kun en kerta teidän aiemmistakaan hyvistä neuvoista huolimatta osannut. Toivottavasti mulla on huomenna tai ylihuomenna parempi koodauspäivä. Olen näissä koodausharrastuksissani oppinut, että päätä kannattaa seinään lyödä. Voi se Aurinko lopulta risukasaankin paistaa.

rebol[]
maxx: 1880 ;kuvan leveys
maxy: 1080 ; ja korkeus
alfax: 1 ;monta astetta x-akselin ympäri pyöritään framejen välillä?
alfay: 2 ;    -,,-      y     -,,-
alfaz: 3 ;    -,,-      z     -,,-
x0: 0
y0: 0
z0: 0

kuva1: load %kuva1.png ;jokaiseen kuuteen tahkoon tulee oma kuva
kuva2: load %kuva2.png
kuva3: load %kuva3.png
kuva4: load %kuva4.png
kuva5: load %kuva5.png
kuva6: load %kuva6.png

origx: 0
origy: 0
origz: -10

x: copy[] ;blockki (on niinkuin taulukko) kuution kulmien x koordinaataoille
y: copy[]
z: copy[]
xp: copy[] ;3D avaruuden x,y,z:sta saatu 2D tason koordinaatta
yp: copy[]
apux: copy[]
apuy: copy[]
apuz: copy[]

for i 1 8 1 [ ;asetetaan blockkiin 0-alkiot, jotta alkioon voidaan
	append x 0 ;viitata indeksillä.
	append y 0
	append z 0
	append xp 0
	append yp 0
	append apuz 0
	append apuy 0
	append apux 0
]
pituus: 300
x/1: x0 - pituus ;Asetetaan kuution kahdeksan kulman koordinaatat.
x/2: x0 + pituus
x/3: x/2
x/4: x/1

x/5: x/1
x/6: x/2
x/7: x/3
x/8: x/4

y/1: y0 - pituus
y/2: y/1
y/3: y0 + pituus
y/4: y/3

y/5: y/1
y/6: y/2
y/7: y/3
y/8: y/4

z/1: pituus
z/2: z/1
z/3: z/1
z/4: z/1

z/5: - pituus
z/6: z/5
z/7: z/5
z/8: z/5

for kuvaind 1 600 1 [ ;tuotetaan 600 framea
	plot: copy[]
	;projisoi. Lasketaan pisteen x,y,z screenikoordinaatat xp,yp
	for i 1 8 1 [
		jakaja: (maxx - (z/(i) + origz))
		if jakaja = 0 [jakaja: 0.00000000001] ;nollalla ei saa jakaa
		temp: maxx / jakaja
		xp/(i): x0 + ((x/(i) + origx) * temp)
		xp/(i): xp/(i) + (maxx / 2)
		yp/(i): y0 - ((y/(i) + origy) * temp)
		yp/(i): yp/(i) + (maxy / 2)
	]

	x1: x/2 - x/3
	y1: y/2 - y/3
	z1: z/2 - z/3

	x2: x/2 - x/6
	y2: y/2 - y/6
	z2: z/2 - z/6

	xn: (y1 * z2) - (y2 * z1)
	yn: -1 * ((x1 * x2) - (x2 * z1))
	zn: (x1 * y2) - (x2 * y1)
	scale2: 0.01

	x9: (xn * scale2) + x/1
	y9: (yn * scale2) + y/1
	z9: (zn * scale2) + z/1

	k2: (((x/2 * x/2) - x/4) + (y/2 * (y/2 - y/4)) + (z/2 - z/4)) / origz
	vis2: k2 - z/2 + z9
	;oikereuna
	if vis2 < 0 [
		append plot compose [
			image (as-pair xp/2 yp/2) (as-pair xp/6 yp/6) (as-pair xp/7 yp/7) (as-pair xp/3 yp/3) (as-pair xp/2 yp/2) (kuva2) ;oikereuna
		]
	]

	x1: x/6 - x/7
	y1: y/6 - y/7
	z1: z/6 - z/7

	x2: x/6 - x/5
	y2: y/6 - y/5
	z2: z/6 - z/5

	xn: (y1 * z2) - (y2 * z1)
	yn: -1 * ((x1 * x2) - (x2 * z1))
	zn: (x1 * y2) - (x2 * y1)
	scale1: 0.01
	x9: (xn * scale1) + x/6
	y9: (yn * scale1) + y/6
	z9: (zn * scale1) + z/6

	k3: (((x/4 * x/4) - x9) + (y/4 * (y/4 - y9)) + (z/4 - z9)) / origz

	vis3: k3 - z/6 + z9

;Takaseinä
	if vis3 < 0 [
		append plot compose [
			image (as-pair xp/5 yp/5) (as-pair xp/6 yp/6) (as-pair xp/7 yp/7) (as-pair xp/8 yp/8) (as-pair xp/5 yp/5) (kuva3) ;takaseinä
		]
	]

	x1: x/2 - x/6
	y1: y/2 - y/6
	z1: z/2 - z/6

	x2: x/2 - x/1
	y2: y/2 - y/1
	z2: z/2 - z/1

	xn: (y1 * z2) - (y2 * z1)
	yn: -1 * ((x1 * x2) - (x2 * z1))
	zn: (x1 * y2) - (x2 * y1)
	scale1: 0.01
	x9: (xn * scale1) + x/2
	y9: (yn * scale1) + y/2
	z9: (zn * scale1) + z/2

	k4: (((x/2 * x/2) - x9) + (y/2 * (y/2 - y9)) + (z/2 - z9)) / origz

	vis4: k4 - z/2 + z9
	;yläpuoli
	if vis4 < 0 [
		append plot compose [
			image (as-pair xp/1 yp/1) (as-pair xp/2 yp/2) (as-pair xp/6 yp/6) (as-pair xp/5 yp/5) (as-pair xp/1 yp/1) (kuva5) ;yläpuoli
		]
	]

	x1: x/3 - x/7
	y1: y/3 - y/7
	z1: z/3 - z/7

	x2: x/3 - x/4
	y2: y/3 - y/4
	z2: z/3 - z/4

	xn: (y1 * z2) - (y2 * z1)
	yn: -1 * ((x1 * x2) - (x2 * z1))
	zn: (x1 * y2) - (x2 * y1)
	scale1: 0.01
	x9: (xn * scale1) + x/3
	y9: (yn * scale1) + y/3
	z9: (zn * scale1) + z/3

	k5: (((x/3 * x/3) - x9) + (y/3 * (y/3 - y9)) + (z/3 - z9)) / origz

	vis5: k5 - z/3 + z9
	;alapuoli
	if vis5 < 0 [
		append plot compose [
			image (as-pair xp/4 yp/4) (as-pair xp/3 yp/3) (as-pair xp/7 yp/7) (as-pair xp/8 yp/8) (as-pair xp/4 yp/4) (kuva6) ;alapuoli
		]
	]

	x1: x/5 - x/8
	y1: y/5 - y/8
	z1: z/5 - z/8

	x2: x/5 - x/1
	y2: y/5 - y/1
	z2: z/5 - z/1

	xn: (y1 * z2) - (y2 * z1)
	yn: -1 * ((x1 * x2) - (x2 * z1))
	zn: (x1 * y2) - (x2 * y1)
	scale1: 0.01
	x9: (xn * scale1) + x/5
	y9: (yn * scale1) + y/5
	z9: (zn * scale1) + z/5

	k6: (((x/5 * x/5) - x9) + (y/5 * (y/5 - y9)) + (z/5 - z9)) / origz
	vis6: k6 - z/5 + z9
	 ;vasenreuna
	if vis6 < 0 [

		append plot compose [
			image (as-pair xp/1 yp/1) (as-pair xp/5 yp/5) (as-pair xp/8 yp/8) (as-pair xp/4 yp/4) (as-pair xp/1 yp/1) (kuva4) ;vasenreuna
		]
	]

	x1: x/1 - x/4
	y1: y/1 - y/4
	z1: z/1 - z/4

	x2: x/1 - x/2
	y2: y/1 - y/2
	z2: z/1 - z/2

	xn: (y1 * z2) - (y2 * z1)
	yn: -1 * ((x1 * x2) - (x2 * z1))
	zn: (x1 * y2) - (x2 * y1)
	scale1: 0.01
	x9: (xn * scale1) + x/1
	y9: (yn * scale1) + y/1
	z9: (zn * scale1) + z/1

	k1: (((x/1 * x/1) - x9) + (y/1 * (y/1 - y9)) + (z/1 - z9)) / origz

	vis1: k1 - z/1 + z9
	 ;etuseinä
	if vis1 < 0 [
		append plot compose [
			image (as-pair xp/1 yp/1) (as-pair xp/2 yp/2) (as-pair xp/3 yp/3) (as-pair xp/4 yp/4)  (as-pair xp/1 yp/1) (kuva1) ;etuseinä
		]
	]



	;kierto y-akselin ympäri
	for i 1 8 1 [
		apu: y/(i)
		y/(i): ((cosine alfay) * y/(i)) + ((sine alfaz) * z/(i))
		z/(i): (- (sine alfay) * apu) + ((cosine alfaz) * z/(i))
	]


	;kierrot x-akselin ympäri
	for i 1 8 1 [
		apu: x/(i)
		x/(i): ((cosine alfax) * x/(i)) + (- (sine alfaz) * z/(i))
		z/(i): (((sine alfax)) * apu) + ((cosine alfaz) * z/(i))
	]

	;kierrot z-akselin ympäri
	for i 1 8 1 [
		apu: x/(i)
		x/(i): ((cosine alfax) * x/(i)) + ((sine alfay) * y/(i))
		y/(i): ((- (sine alfax)) * apu) + ((cosine alfay) * y/(i))
	]

	main: layout [
		box (as-pair (maxx) (maxy)) white effect reduce ['draw plot]
	]
	kuv: copy/part skip to-image main 20x20 (as-pair maxx maxy)
	save/png to-file rejoin ["kuutio" kuvaind ".png"] kuv
	print kuvaind
]
halt

PetriKeckman [05.07.2022 07:08:21]

#

Minulla oli skaalaustekijänä vakio 0.01 Unohdin, että skalaaritulolla saatu vektori (xn,yn,zn) piti normalisoida siten, että sen komponentit jaetaan sen pituudella - näin saadaan vektori, minkä pituus on yksi. Mutta tulee ongelmia:

** Math Error: Math or number overflow
** Where: do-body
** Near: xn * xn
>>

Yritin kaiken näköistä, jotta tuosta ongelmasta päästäisiin, mutta en ole vielä onnistunut ratkomaan sitä...palaan asiaan huomenna. EDIT: silee, että xn,yn ja zn kerrotaan 1.0:lla päästään ongelmasta.

PetriKeckman [29.01.2023 13:19:18]

#

Hei piiiitkästä aikaa! Sain kuution pyörimään ja sain aikaiseksi tällaisen videon Maamme laulusta: https://youtu.be/BjpkPuhLiyo

Ärsyttävä väärintoiminto siinä on: se tahko, mikä aluksi on alatahko tulee kolme framea liian aikaisin näkyviin ja lähtee kolme framea myöhässä. Ja näyttää muutakin pientä häikkää välillä olevan... Olen kokeillut kaikenlaista, mutta virhe ei ole korjaantunut. Johtuukohan se jotenkin siitä, että olen luetellut kärkipisteitä väärässä järjestyksessä aliohjelmalle, joka tahkon piirtämisestä huolehtii? Kokeilin kyllä monelaisia järjestyksiä, mutta se ei auttanut :( Ongelma ei ratkonnut edes sillä tavalla, että piirrän tahkon ensimäisenä! Muitten tahkojenhan pitäisi itsestään selvästi silloin peittää se. En tosiaan tajua! Tarkoitus olisi ehdottaa tuota videota Yö ry:n videomakasiiniin, joten tuo virhe pitäisi saada korjattua, eli olisin todella kiitollinen neuvoista.

Koska kärkipisteiden numerointini on ehkä vähän outo, niin tässä kuva: https://petke.info/boxi.jpg siinä siis etutahko on väritetty violetilla ja sen kärkipisteiden numerointi myötäpäivään on 1, 2, 3 ja 4.

Koska video on 48 fps, niin melko tarkasti kuutiota saa tarkkailla, että virheen huomaa, mutta kyllä se pienenä ajoittaisena vilkkumisena ilmenee.

Vaikka tämä on ohjelmointiputka, niin teoksen taitelliseen laatuun/laaduttomuuteenkin saa ottaa kantaa, ellei YP:llä ole toista mielipidettä.

Vaikka animaation framet tuottanut koodi on pitkä, niin laitan sen tänne näkyville. Jos joku tosiaan löytäisi siitä selityksen tuolle virheelliselle toiminnolle. Toisaalta alkoi nyt teoksen läpikatsottuani tuntumaan, että miksi nähdä vaivaa - ja nukutun yön jälkeen teos tuntunee melko surkealta...Tosin hauskaa itse teoksen ohjelmointi oli!!

rebol[]
maxx: 1920 ;kuvan leveys
maxy: 1080 ; ja korkeus -> FullHD
x000: maxx / 2
y000: maxy / 2
alfax: 2 ;monta astetta x-akselin ympäri pyöritään framejen välillä?
alfay: 0 ;              y
alfaz: 0 ;              z
x0: 0
y0: 0
z0: 0
print "odota"
images: copy[]
for i 1 50 1 [ ;ladataan 50 kuvaa
	pic: load to-file rejoin ["x" i ".png"]
	append images pic
]
ki: 0
origx: 1
origy: 1
origz: 1

x: copy[] ;blockki (on niinkuin taulukko) kuution kulmien x koordinaataoille
y: copy[]
z: copy[]
xp: copy[] ;3D avaruuden x,y,z:sta saatu 2D tason koordinaatta
yp: copy[]
pituus: 200
for i 1 8 1 [ ;asetetaan blockkiin 0-alkiot, jotta alkioon voidaan
	append x 0 ;viitata indeksillä.
	append y 0
	append z 0
	append xp 0
	append yp 0
]
x/1: x0 - pituus ;aSetetaan manuaalisesti kuution kulmien koordinaatat.
x/2: x0 + pituus ;kulmia on kahdeksan. Tämä on siis alkutilanne.
x/3: x/2
x/4: x/1

x/5: x/1
x/6: x/2
x/7: x/3
x/8: x/4

y/1: y0 - pituus
y/2: y/1
y/3: y0 + pituus
y/4: y/3

y/5: y/1
y/6: y/2
y/7: y/3
y/8: y/4

z/1: 100
z/2: 100
z/3: 100
z/4: 100

z/5: z/1 - (2 * pituus)
z/6: z/2 - (2 * pituus)
z/7: z/3 - (2 * pituus)
z/8: z/4 - (2 * pituus)

värit: copy[]
for i 255 0 5 [
	append värit to-tuple compose [(255) (255) (i)]
]

for i 255 0 -5 [
	append värit to-tuple compose [(i) (i) (255)]
]

color: 1
dc: 1
maxcolor: length? värit
substr: func [string start length][
  copy/part at string start length
]
font-obj2: make face/font [name: "Arial" size: 80]
print "odota"
sanat: [
"Oi maamme, Suomi, synnyinmaa, "
"soi, sana kultainen! "
"Ei laaksoa, ei kukkulaa, "
"ei vettä rantaa rakkaampaa, "
"kuin kotimaa tää pohjoinen, "
"maa kallis isien! "
"On maamme köyhä, siksi jää, "
"jos kultaa kaivannet "
"Sen vieras kyllä hylkäjää, "
"mut meille kallein maa on tää, "
"sen salot, saaret, manteret, "
"ne meist on kultaiset. "
"Ovatpa meille rakkahat "
"koskemme kuohuineen, "
"ikuisten honkain huminat, "
"täht'yömme, kesät kirkkahat, "
"kaikk'kuvineen ja lauluineen "
"mi painui sydämeen. "
"Täss auroin, miekoin, miettehin "
"isämme sotivat, "
"kun päivä piili pilvihin "
"tai loisti onnen paistehin, "
"täss Suomen kansan vaikeimmat "
"he vaivat kokivat. "
"Tään kansan taistelut ken voi "
"ne kertoella, ken? "
"Kun sota laaksoissamme soi, "
"ja halla näläntuskan toi, "
"ken mittasi sen hurmehen "
"ja kärsimykset sen? "
"Täss on sen veri virrannut "
"hyväksi meidänkin, "
"täss iloaan on nauttinut "
"ja murheitansa huokaillut "
"se kansa, jolle muinaisin "
"kuormamme pantihin. "
"Tääll' olo meill on verraton "
"ja kaikki suotuisaa, "
"vaikk onni mikä tulkohon, "
"maa isänmaa se meillä on. "
"Mi maailmass on armaampaa "
"ja mikä kalliimpaa? "
"Ja tässä, täss' on tämä maa, "
"sen näkee silmämme. "
"me kättä voimme ojentaa "
"ja vettä rantaa osoittaa "
"ja sanoa: kas tuoss' on se, "
"maa armas isäimme. "
"Jos loistoon meitä saatettais "
"vaikk' kultapilvihin, "
"mis itkien ei huoattais, "
"vaan tärkein riemun sielu sais, "
"ois tähän köyhään kotihin "
"halumme kuitenkin. "
"Totuuden, runon kotimaa "
"maa tuhatjärvinen "
"miss' elämämme suojan saa, "
"sa muistojen, sa toivon maa, "
"ain ollos, onnees tyytyen, "
"vapaa ja iloinen. "
"Sun kukoistukses kuorestaan "
"kerrankin puhkeaa, "
"viel lempemme saa nousemaan "
"sun toivos, riemus loistossaan, "
"ja kerran, laulus synnyinmaa "
"korkeemman kaiun saa. "
]
sanat2: copy[]
foreach s sanat [
	append sanat2 s
]
sanat: ""
for i 1 length? sanat2 1 [
	for j 1 length? sanat2/(i) 1 [
		sanat: join sanat substr sanat2/(i) j 1
	]
]
print length? sanat
frameja: (length? sanat) * 6
print rejoin ["frameja yhteensä " frameja] ;9876
sek: frameja / 40
minuutit: round/down sek / 60
seksek: sek - (60  * minuutit)
print rejoin ["Video kestää siis "  sek " sekuntia, eli " minuutit " minuuttia ja " seksek "sekuntia."]
merkit: copy[]
for i 1 length? sanat 1 [
	append merkit substr sanat i 1
]
merkit: unique/case merkit
print "Teen kuvia..."
tehty: ""
merkki: 1
kuvaind: 1
dkuvaind: (maxx * 0.74) / (40 * 6) ;paljon merkkijonoa siirretään vasemmalle...
ku: copy[]
for i 1 50 1 [
	append ku i
]
apukuvaind: 20
rand: func [][ ;palauttaa arvon satunnaislukuarvon -3...3
	return -3 + random 7 - 1
]
piirrä: func [n1 n2 n3 n4 kuva][ ;tutkii näytetäänkö tahko...
	x1: x/(n1) - x/(n2)
	y1: y/(n1) - y/(n2)
	z1: z/(n1) - z/(n2)

	x2: x/(n1) - x/(n3)
	y2: y/(n1) - y/(n3)
	z2: z/(n1) - z/(n3)

	xn: (y1 * z2) - (y2 * z1)
	yn: -1 * ((x1 * x2) - (x2 * z1))
	zn: (x1 * y2) - (x2 * y1)

	xn: 1.0 * xn
	yn: 1.0 * yn
	zn: 1.0 * zn

	npituus: square-root ((xn * xn) + (yn * yn) + (zn * zn)) + 1.0E-99

	xn2: xn / npituus
	yn2: yn / npituus
	zn2: zn / npituus

	npituus2: square-root ((xn2 * xn2) + (yn2 * yn2) + (zn2 * zn2))  + 1.0E-99

	scale: npituus / npituus2

	x9: (xn * scale) + x/(n1)
	y9: (yn * scale) + y/(n1)
	z9: (zn * scale) + z/(n1)

	k: (x/(n1) * (x/(n1) - x/(n2))) + (y/(n1) * (y/(n1) - y/(n2))) + (z/(n1) * (z/(n1) - z/(n2))) / origz

	vis: k - z/(n1) + z9
	if vis < 0 [
		append plot compose [
			image (as-pair (a + xp/(n1)) (b + yp/(n1))) (as-pair (a + xp/(n3)) (b + yp/(n3))) (as-pair (a + xp/(n4)) (b + yp/(n4))) (as-pair (a + xp/(n2)) (b + yp/(n2)))  (images/(ku/(kuva)))
		]
	]
	if (vis > 0) and ((mod  kuvaind 197) = 0) [ ;jos tahko on piilossa ja kuvaind on jaollinen 197:lla vaihdetaan kuvaa
		ku/(kuva): maxkuva + 1
		maxkuva: maxkuva + 1
		if maxkuva = length? images [
			maxkuva: 1
			ku/(kuva): maxkuva
		]
	]
]
maxkuva: 6
halkaisija: square-root ((maxx * maxx) + (maxx * maxx))
kk: 0
sx1: x000 + (-0.5 * halkaisija)
sx2: x000 + (0.5 * halkaisija)

sy1: y000 + (-0.5 * halkaisija)
sy2: y000 + (0.5 * halkaisija)

salfa: 0
for i 1 length? sanat 1 [ ; käydään läpi kaikki Maamme laulun sanojen kirjaimet
	kirjain: substr sanat i 1
	tehty: join tehty kirjain
	indexi: index? find merkit kirjain
	dkorkeus: 1.5 * indexi
	korkeus: 0
	for apuri 1 6 1 [ ;jokaisen kirjaimen kohdalla 6 framea
		plot: copy[]
		color: 1
		prin kirjain
		append plot compose [
			font (font-obj2)
			line-width 4
		]
		for siniy sy1 sy2  2 [
			append plot compose [
				pen (värit/(color))
				line
			]
			for sinix sx1 sx2 4 [
				py: siniy + (korkeus  * cosine sinix)
				;siirrot
				sinix: sinix - x000
				py:	py - y000
				apu: sinix
				sinix: (sinix * cosine salfa) - (py * sine salfa)
				py: (apu * sine salfa) + (py * cosine salfa)
				;siirrot takaisin
				sinix: sinix + x000
				py:	py + y000
				append plot compose [
					(as-pair sinix py)
				]
			]


			color: color + dc
			if (color = maxcolor) or (color = 0) [dc: - dc color: color + dc]
		]
	;projisoi. Lasketaan pisteen x,y,z screenikoordinaatat xp,yp
	for i 1 8 1 [
		jakaja: (maxx - (z/(i) + origz))
		if jakaja = 0 [jakaja: 0.00000000001] ;nollalla ei saa jakaa
		temp: maxx / jakaja
		xp/(i): x0 + ((x/(i) + origx) * temp)
		xp/(i): xp/(i) + (maxx / 2)
		yp/(i): y0 - ((y/(i) + origy) * temp)
		yp/(i): yp/(i) + (maxy / 2)
	]

	a: 0
	b: 70
	piirrä 4 8 3 7 ku/5 ;alapuoli
	piirrä 1 4 2 3 ku/1 ;etu puoli
	piirrä 8 5 7 6 ku/2 ;taka puoli
	piirrä 2 3 6 7 ku/3 ;vasen puoli
	piirrä 5 8 1 4 ku/4 ;oikea puoli
	piirrä 1 2 5 6 ku/6 ; yläpuoli

	;siirrot
	for i 1 8 1 [
		x/(i): x/(i) - x0
		y/(i): y/(i) - y0
		z/(i): z/(i) - z0
	]

	;kierrot x-akseli
	for i 1 8 1 [
		apu: y/(i)
		y/(i): ((cosine alfax) * y/(i)) + ((sine alfax) * z/(i))
		z/(i): ((- sine alfax) * apu) + ((cosine alfax) * z/(i))
	]

	;kierrot y-akseli
	for i 1 8 1 [
		apu: x/(i)
		x/(i): ((cosine alfay) * x/(i)) + ((- sine alfay) * z/(i))
		z/(i): ((sine alfay) * apu) + ((cosine alfay) * z/(i))
	]

	;kierrot z-akseli
	for i 1 8 1 [
		apu: x/(i)
		x/(i): ((cosine alfaz) * x/(i)) + ((sine alfaz) * y/(i))
		y/(i): ((- (sine alfaz)) * apu) + ((cosine alfaz) * y/(i))
	]

	;siirrot
	for i 1 8 1 [
		x/(i): x/(i) + x0
		y/(i): y/(i) + y0
		z/(i): z/(i) + z0
	]

	append plot compose [
		pen black
		text (as-pair (20 - ((kuvaind - 1) * dkuvaind)) 10) (substr sanat 1 length? sanat)
		pen white
		text (as-pair (20 - ((kuvaind - 1) * dkuvaind) + 4) 14) (substr sanat 1 length? sanat)
	]

	main: layout [
		box (as-pair (maxx) (maxy)) black effect reduce ['draw plot]
	]
	kuv: copy/part skip to-image main 20x20 (as-pair maxx maxy)
	save/png to-file rejoin ["_testi" kuvaind ".png"] kuv
	print kuvaind
	kuvaind: kuvaind + 1
	salfa: salfa + 0.4
	if apuri = 4 [dkorkeus: - dkorkeus]
	korkeus: korkeus + dkorkeus

	if (mod kuvaind (40 * 5)) = 0 [ ;vaihdetaan kiertokulmia 5 sekunnin välein kun .fps on 40
		alfax: rand
		alfay: rand
		alfaz: rand
	]
	]
]
halt

Metabolix [31.01.2023 07:50:32]

#

Koodi ei ole selvimmästä päästä, mutta tuo näkyvyyden laskenta ei ihan minulle aukea. Voisit laskea pistetulon tahkon normaalista ja tahkon ja katsojan välisestä vektorista, niin saisit tuloksen, onko tahko näkyvään suuntaan. Videossa näyttää, että laskisit tämän suhteessa vaakasuoraan (etkä katsojaan), jolloin perspektiivi jää huomiotta.

PetriKeckman [31.01.2023 10:26:28]

#

Metabolix kirjoitti:

Koodi ei ole selvimmästä päästä

Juu, sori. Koodi ei ole selvimmästä päästä, kun se oli apinoitu modifioiden tuolta: https://retro64.altervista.org/blog/another-look-at-3d-graphics-fast-hidden-faces-removal-back-face-culling/

Teoriasta ja ehkäkin melko helposta ja yksinkertaisesta sellaisesta huolimatta, en osannut itse koodata :) ... ei sittenkään :) vaan :( Eli ei paljo hymyilytäkään. Kun en tiedä ees mitkä ovat katsojan koordinaatit!

Onko ne nää:

origx: 1
origy: 1
origz: 1

?

Lähetin kyllä jo videon, että liian myöhäistä alkaa korjaaamaan. MakeAvilla kesti noin 10 tuntia tehdä 9876:sta framesta video eli ei ehkä huvittaisikaan - en jaksaisi kärsimättömänä taas odottaa. EDIT: MakeAvi teki nopeasti videon! Mutta framejen teko kesti yli 10 tuntia. Oon taas yö valvonnut liikaaa - pää on piimää.

Metabolix [31.01.2023 21:46:53]

#

PetriKeckman kirjoitti:

Onko ne [katsojan koordinaatit] nää:

Tuosta en äkkiseltään saa selvää, tätä olisi kannattanut miettiä jo muuttujia nimetessä. :)

Onneksi voit väistää ongelman. Projektio toimii, joten back face culling onnistuu helposti myös 2D-kuvaan projisoiduista koordinaateista. Jos ristitulon etumerkki (eli kulmien kiertosuunta) on väärä, kulmio näyttää takapuolta ja se pitää jättää piirtämättä.

Eli koodissasi arvot k ja vis ovat jotain minulle käsittämätöntä, mutta niiden tilalla voisi olla jotain tämmöistä:

; vektorit kulmasta 1 kulmiin 2 ja 3 (kulmion 2D-projektiossa)
dx2: xp/(n2) - xp/(n1)
dy2: yp/(n2) - yp/(n1)
dx3: xp/(n3) - xp/(n1)
dy3: yp/(n3) - yp/(n1)
; ristitulo kertoo kiertosuunnan; tarkista itse, kuuluuko + vai - olla näkyvä.
vis: dx2 * dy3 - dx3 * dy2

Jos tämän jälkeen osa tahkoista näkyy väärin, tarkista tahkojen kulmien järjestys noilla piirrä-riveillä.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta