Matemaattisia ongelmia...
Matemaattisia ongelmia...
Kun tiedän kappaleen nopeuden X- ja Y-akseleilla, kuinka saan laskettua missä kulmassa se etenee ja millä nopeudella? Käänteistä kosinia ja siniä varmaankin tarvitaan?
Toinen ongelma on saada sivultakuvatussa räiskintäpelissä botit ampumaan yläviistoon aseilla, joiden ammukseen painovoima vaikuttaa voimakkaasti (esim. kranaatit). Jokaisella aseella on muuttuja, joka kertoo kuinka paljon sen ammuksia pudotetaan alaspäin framen aikana. Eli miten siis saan laskettua kulman, jossa botin on ammuttava osuakseen viholliseen?
Toinen ongelma on saada sivultakuvatussa räiskintäpelissä botit ampumaan yläviistoon aseilla, joiden ammukseen painovoima vaikuttaa voimakkaasti (esim. kranaatit). Jokaisella aseella on muuttuja, joka kertoo kuinka paljon sen ammuksia pudotetaan alaspäin framen aikana. Eli miten siis saan laskettua kulman, jossa botin on ammuttava osuakseen viholliseen?
Re: Matemaattisia ongelmia...
Esimmäiseen kysymykseen:
Nopeus on helppo laskea: xplus ja yplus ovat suorakulmaisen kolmion kateetit ja halutaan tietää hypotenuusan pituus. Koska suorakulmaisessa kolmiossa a^2 + b^2 = c^2, saadaan nopeus laskettua ottamalla neliöjuuri yhteenlasketuista kateeteista toiseen. Kulman voi selvittää helposti ihan GetAngle():llakin. Nyt tosin muistin, että nopeuteen olisi kelvannut myös Distance()-funktio, mutta tulipahan harjoiteltua matematiikkaa.
Code: Select all
xplus# = 0
yplus# = 0
angle# = 0
Repeat
xplus = MouseWX()/10
yplus = MouseWY()/10
DrawToWorld 1
Line 0,0,MouseWX(),MouseWY()
angle# = GetAngle(0.0,0.0,xplus,yplus)
speed# = Sqrt(xplus#^2 + yplus#^2)
DrawToWorld 0
Text 0,0,"Angle: " + angle#
Text 0,13,"Speed: " + speed#
DrawScreen
Forever
Peli piirtokomennoilla - voittaja, Virtuaalilemmikkipeli - voittaja,
Sukellusvenepeli - voittaja, Paras tileset - voittaja
Vaihtuva päähenkilö - voittaja, Autopeli - voittaja sekä
Hiirellä ohjattava peli - voittaja B)
Sukellusvenepeli - voittaja, Paras tileset - voittaja
Vaihtuva päähenkilö - voittaja, Autopeli - voittaja sekä
Hiirellä ohjattava peli - voittaja B)
Re: Matemaattisia ongelmia...
Nopeutta ei oikeastaan tarvitse laskea sillä se on pelkästään välimatka jonka esine kulkee yhden framen aikana. Tämän siis harakka laski pythagoralla. Pyth. on jo sisäänrakennettuna cb:hen eli sitä ei tarvitse laskea. Nopeuden voi siis saada käyttämällä Distancea. Eli Distance(0,0,x_nopeus,y_nopeus).
-
- Moderator
- Posts: 227
- Joined: Wed Aug 29, 2007 3:55 pm
Re: Matemaattisia ongelmia...
Vastaus ensimmäiseen kysymykseen:
Olen alkamassa juuri nukkumaan, niin en ehdi tarkistamaan, mutta kaava taitaa olla atan(x_komponentti/y_komponentti)
Komponentit saattaa olla toisinpäin.
Toinen kysymys:
Itseasiassa oikeassa maailmassa painpovoima on vakio(maanpinnalla), joten sitä ei pitäisi olla kaikille erikseen, se fysikaalinen ominaisuus, mikä vaihtelee, on kimpoamisherkkyys... Ellet tarkoittanut lähtönopeutta, mikä on aika oleellinen seikka.
Minä en nytten ehdi tarkemmin miettimään, miten sen laskun suorittaa, mutta se varmasti auttaa, että lentorata noudattelee aina paraabelia(korjatkaa, jos olen väärässä). On kaksi vaihtoehtoa, joko haet kokeilemalla oikean vaihtoehdon, tai sitten teet kaavan, jolla se selviää.
Hakeminen lienee helppoa, sillä vaihtoehtoja ei ole hirveän monta (vaikka tasa-asteille vain). Toisen asteen yhtälöä pitää silti jokatapauksessa ratkoa.
Tärkeä tieto on huipun sijainti pelaajaan nähden. Pikainen arvaus on voima*suunnan_y_komponentti/(painovoima). Painovoiman pitää olla positiivinen, jos se on negatiivinen, niin miinus eteen. Voima tarkoittaa lähtönopeutta.
Paraabelin kulmakerroin on aina negatiivinen.
ajatuksia ratkaisukaavasta:
-ensin määritellään paraabeli: huippu-k*x^2
-seuraavaksi selvitetään paraabelin nollapisteet ja valitaan niistä se, joka vastaa lähtöpistettä, siitä saa pelaajan etäisyyden origosta(paraabelin huippu on origon kohdalla x-akselilla)
-Seuraavassa vaiheessa ratkaistaan toisen asteen yhtälöt huippu-k*x^2=pelaajany (paraabelin origosta laskien) ja huippu-k*pelaajanx^2=pelaajany (tästä en ole enään ollenkaan varma)(origosta laskien)
-sitten verrataan , tuleeko tulokset tarpeeksi tarpeeksi lähelle pelaajan keskipistettä, ja sitten laukaistaan.
-sama tietenkin joka-asteluvulle, sekä tietenkin vain siltä puolelta, jolla vihollinen on.
Nuoden lausekkeiden kanssa oli pää vähän tyhjä, kun viittomakielen opetuksesta lähtee sen verran meteliä.
Olen alkamassa juuri nukkumaan, niin en ehdi tarkistamaan, mutta kaava taitaa olla atan(x_komponentti/y_komponentti)
Komponentit saattaa olla toisinpäin.
Toinen kysymys:
Itseasiassa oikeassa maailmassa painpovoima on vakio(maanpinnalla), joten sitä ei pitäisi olla kaikille erikseen, se fysikaalinen ominaisuus, mikä vaihtelee, on kimpoamisherkkyys... Ellet tarkoittanut lähtönopeutta, mikä on aika oleellinen seikka.
Minä en nytten ehdi tarkemmin miettimään, miten sen laskun suorittaa, mutta se varmasti auttaa, että lentorata noudattelee aina paraabelia(korjatkaa, jos olen väärässä). On kaksi vaihtoehtoa, joko haet kokeilemalla oikean vaihtoehdon, tai sitten teet kaavan, jolla se selviää.
Hakeminen lienee helppoa, sillä vaihtoehtoja ei ole hirveän monta (vaikka tasa-asteille vain). Toisen asteen yhtälöä pitää silti jokatapauksessa ratkoa.
Tärkeä tieto on huipun sijainti pelaajaan nähden. Pikainen arvaus on voima*suunnan_y_komponentti/(painovoima). Painovoiman pitää olla positiivinen, jos se on negatiivinen, niin miinus eteen. Voima tarkoittaa lähtönopeutta.
Paraabelin kulmakerroin on aina negatiivinen.
ajatuksia ratkaisukaavasta:
-ensin määritellään paraabeli: huippu-k*x^2
-seuraavaksi selvitetään paraabelin nollapisteet ja valitaan niistä se, joka vastaa lähtöpistettä, siitä saa pelaajan etäisyyden origosta(paraabelin huippu on origon kohdalla x-akselilla)
-Seuraavassa vaiheessa ratkaistaan toisen asteen yhtälöt huippu-k*x^2=pelaajany (paraabelin origosta laskien) ja huippu-k*pelaajanx^2=pelaajany (tästä en ole enään ollenkaan varma)(origosta laskien)
-sitten verrataan , tuleeko tulokset tarpeeksi tarpeeksi lähelle pelaajan keskipistettä, ja sitten laukaistaan.
-sama tietenkin joka-asteluvulle, sekä tietenkin vain siltä puolelta, jolla vihollinen on.
Nuoden lausekkeiden kanssa oli pää vähän tyhjä, kun viittomakielen opetuksesta lähtee sen verran meteliä.
Last edited by atomimalli on Tue Jan 08, 2008 8:14 am, edited 1 time in total.
Re: Matemaattisia ongelmia...
Pulla, olen tuon ykköskysymyksen ongelmia (molempia, ja pelkästään niitä kahta) miettinyt itsekkin varmaan pari viikkoa, tuloksetta. Tänään sitten rohkaisin mieleni ja kysyin niitä molempia matikanopelta, siis muutamia tunteja ennen tätä kysymystä täällä.
Vastaukset:
Vastaukset:
Code: Select all
x1=0
y1=0
x2#=0
y2#=0
angle# = 0
DrawToWorld 1
Repeat
x2=MouseWX()
y2=MouseWY()
Line x1,y1,x2,y2
angle# = ATan(x2/y2)
speed# = Sqrt((x2-x1)^2 + (y2-y1)^2)
Text 0,0,"Angle: " + angle#
Text 0,13,"Speed: " + speed#
DrawScreen
Forever
Re: Matemaattisia ongelmia...
Niinpä tietenkin, en tullut ajatelleeksi että kulman voisi tarkistaa GetAnglella... Pitää sitten seuraavaksi yrittää saada noiden atomimallin ohjeiden avulla bottien ampuminen toimimaan.
Totta, mutta esimerkiksi ohjuksen ja heitettävän kranaatin lentoratojen on oltava erilaisia (painovoima ei vaikuta ohjukseen, kranaatti taas putoaa lähes heti maahan), ja se on helpoin mallintaa painovoima-muuttujalla.atomimalli wrote:Itseasiassa oikeassa maailmassa painpovoima on vakio(maanpinnalla), joten sitä ei pitäisi olla kaikille erikseen, se fysikaalinen ominaisuus, mikä vaihtelee, on kimpoamisherkkyys...
-
- Moderator
- Posts: 227
- Joined: Wed Aug 29, 2007 3:55 pm
Re: Matemaattisia ongelmia...
Painovoima on kyllä yhä vakio, ammukseen on painovoiman vaikutus aivan sama, kuin kranaattiinkin, juju on siinä, että lähtönopeus on eri. Kaikkihan tietävät, että fllygeli ja nuppineula tippuvat samaa vauhtia.
Ohjus, tai raketti taitaa olla ainuita poikkeuksia normaaleissa aseissa.
Jos ohjus on hakeutuva, niin sen voi ampua suoraan vihollista kohti, sama homma raketilla, toki kannattaa tarkistaa ettei ammu maata alapuolella.
Siitä jälkimmäisestä lausekkeesta en tosiaankaan ole kovin varma, joten kannattaa sen kuvaajat piirtää paperille ja tarkistaa, että se toimii, jos ei toimi, niin ei ole vaikea saada siitä toimivaa.
Katson tuota varmaan parin päivän sisään uudestaan, jos aikaa järjestyy, toivottavasti auttoi.
Operaatio saattaa kenties kuulostaa monien mielestä raskaalta, mutta uskon nopeuden riittävän.
Paikallinen kello sanoo nytten keskiyötä, joten käympä tästä vihdoin nukkumaan, tuli hieman muita kiireitä...
Edit: Tuosta puuttuu kokonaan huipun korkeuden laskeminen.. ranskalaisilla viivoilla merkityissä kohdissa huippu tarkoittaa korkeutta y akselilla. Se, miksi nollakohdat piti tarkistaa, liittyi paraabelin skaalaamiseen samaan mittakaavaan pelaajan kanssa, jälkeenpäin se ei kuulosta oikein viisaalta, joten siihen pitäisi keksiä joku muu keino... Etäisyys pitää vielä kertoa cos kulmalla.
Itseasiassa etäisyyden laskeminen muotoutui minulla paperilla jotenkin tähän muotoon:
(voima*sin(kulma)/painovoima+1)/2*cos(kulma)' en ole tietokoneella ehtinyt mitään testata, joten laskuvirheet ovat kuitenkin melko todennäköisiä, toivottavasti tuo on nytten oikein.
Ohjus, tai raketti taitaa olla ainuita poikkeuksia normaaleissa aseissa.
Jos ohjus on hakeutuva, niin sen voi ampua suoraan vihollista kohti, sama homma raketilla, toki kannattaa tarkistaa ettei ammu maata alapuolella.
Siitä jälkimmäisestä lausekkeesta en tosiaankaan ole kovin varma, joten kannattaa sen kuvaajat piirtää paperille ja tarkistaa, että se toimii, jos ei toimi, niin ei ole vaikea saada siitä toimivaa.
Katson tuota varmaan parin päivän sisään uudestaan, jos aikaa järjestyy, toivottavasti auttoi.
Operaatio saattaa kenties kuulostaa monien mielestä raskaalta, mutta uskon nopeuden riittävän.
Paikallinen kello sanoo nytten keskiyötä, joten käympä tästä vihdoin nukkumaan, tuli hieman muita kiireitä...
Edit: Tuosta puuttuu kokonaan huipun korkeuden laskeminen.. ranskalaisilla viivoilla merkityissä kohdissa huippu tarkoittaa korkeutta y akselilla. Se, miksi nollakohdat piti tarkistaa, liittyi paraabelin skaalaamiseen samaan mittakaavaan pelaajan kanssa, jälkeenpäin se ei kuulosta oikein viisaalta, joten siihen pitäisi keksiä joku muu keino... Etäisyys pitää vielä kertoa cos kulmalla.
Itseasiassa etäisyyden laskeminen muotoutui minulla paperilla jotenkin tähän muotoon:
(voima*sin(kulma)/painovoima+1)/2*cos(kulma)' en ole tietokoneella ehtinyt mitään testata, joten laskuvirheet ovat kuitenkin melko todennäköisiä, toivottavasti tuo on nytten oikein.
Re: Matemaattisia ongelmia...
Yritin lähteä ratkaisemaan tätä ongelmaa, mutta huomasin, että ei ole helppoa määrittää laskukaavaa kulmalle, jos tiedetään ampumiskoordinaatit, lähtönopeus ja kohteen koordinaatit. Laskut menevät sen verta vaikeaksi, että ne ei kaikkien silmille sovi, kun itse lauseke on kolmirivinen neliöjuurihässäkkä.regalis wrote:Toinen ongelma on saada sivultakuvatussa räiskintäpelissä botit ampumaan yläviistoon aseilla, joiden ammukseen painovoima vaikuttaa voimakkaasti (esim. kranaatit). Jokaisella aseella on muuttuja, joka kertoo kuinka paljon sen ammuksia pudotetaan alaspäin framen aikana. Eli miten siis saan laskettua kulman, jossa botin on ammuttava osuakseen viholliseen?
Joten: suosittelisin melkein tekemään, niin että ensin määräät jonkun kulman, jossa panos lähtee ja sen jälkeen lähtönopeuden laskeminen onkin helpompaa.
Lähtönopeuden saat laskettua seuraavalla kaavalla: v0 = Sqrt(-g*x^2 / ( 2*Cos(a) * (y-Tan(a)*x) ))
Kaavassa g on painovoiman kiihtyvyys (9,8m/s^2), x on kohteen etäisyys x-suunnassa ampujasta, y on kohteen etäisyys y-suunnassa ampujasta ja a on lähtökulma asteina. Tietysti voit laskea nopeuden eri kulmilla ja valita niistä sitten aina parhaimman (jos sinulla on jokin menettelytapa päättämään mikä niistä on paras).
Täytyy tietenkin ottaa huomioon, että lauseke ei anna vastausta jokaiselle kulmalle, eli et voi valita kulmaa mielivaltaisesti. Karkeasti voidaan sanoa, että kun otat kulman GetAnglella lähdepisteestä kohdepisteeseen, kulman täytyy olla itseisarvoltaan sitä suurempi (mielellään paljonkin, riippuen tapauksesta).
Re: Matemaattisia ongelmia...
Tein eilen vähän laskutehtäviä ja sain selville että kulma = ASin((Etäisyys*painovoima)/(lähtönopeus^2))/2 tai kulma = 90-ASin((Etäisyys*painovoima)/(lähtönopeus^2))/2regalis wrote:Toinen ongelma on saada sivultakuvatussa räiskintäpelissä botit ampumaan yläviistoon aseilla, joiden ammukseen painovoima vaikuttaa voimakkaasti (esim. kranaatit). Jokaisella aseella on muuttuja, joka kertoo kuinka paljon sen ammuksia pudotetaan alaspäin framen aikana. Eli miten siis saan laskettua kulman, jossa botin on ammuttava osuakseen viholliseen?
Lopuksi vielä pieni esimerkki, jossa sininen pallo on kohde, punainen pallo kohta johon ammus putoaisi valitsemasi kulman mukaan ja valkoiset pisteet simuloivat lentorataa. Ohjelma kertoo millä kulmilla osut kohteeseen sekä nykyisen kulmasi.
Code: Select all
SCREEN 700,300
FrameLimit 60
gravity#=9.81/60 //painovoima jaettuna FPSällä
Speed#=10
TargetX=Rand(50,((Sin(45)*Speed#)^2/(gravity#/2))) //Arpoo luvun 50 ja maksimi etäisyyden välillä
Repeat
Color 128,128,128
Line 0,300,MouseX(),MouseY()
ang=GetAngle(0,300,MouseX(),MouseY()) //Laskee kulman
XSpeed#=Cos(ang)*Speed# //Laskee nopeuden x-axelilla
YSpeed#=Sin(ang)*Speed# //Laskee nopeuden y-axelilla
x#=0 //X-sijainti
y#=300 //Y-sijainti
Repeat //Lentorata
x#=x#+XSpeed#
y#=y#-YSpeed#
YSpeed#=YSpeed#-gravity#
Color 255,255,255
Dot x#,y#
Until y#>300
If KeyHit(cbkeyspace) Then TargetX=Rand(50,((Sin(45)*Speed#)^2/(gravity#/2))) //Arpoo uuden sijainnin kohteelle (space)
Color 0,0,255
Circle TargetX-5,295,10 //Kohde (sininen)
Color 255,0,0
Circle (Sin(ang)*Speed#)/(gravity#/2)*XSpeed#-3,297,6 //Putoamis piste (punainen)
TargetAngle=ASin((TargetX*gravity#)/(Speed#^2))/2 //Laskee tarvittavan kulman
Color 255,255,255
Text 0,0,Int((Sin(ang)*Speed#)/(gravity#/2)) //Lennon pituus frameissa
Text 0,10,"Your Angle: "+ang
Text 0,20,"X: "+Int((Sin(ang)*Speed#)/(gravity#/2)*XSpeed#) //Putoamis piste (punainen)
Text 150,10,"Target Angle: "+TargetAngle+" or "+(90-TargetAngle)
Text 150,20,"TargetX: "+TargetX //etäisyys
DrawScreen
Forever
Edit: tein pieniä muutoksia koodiin enkä ole vielä kokeillut sen toimivuutta
Last edited by Kassu on Sat Jan 12, 2008 3:20 pm, edited 1 time in total.
Re: Matemaattisia ongelmia...
Tollasella systeemillähän saisi aikaan jonkinlaisen pelin, jossa pitää ampua tykillä. NiiceKassu wrote:Tein eilen vähän laskutehtäviä ja sain selville että kulma = ASin((Etäisyys*painovoima)/(lähtönopeus^2))/2 tai kulma = 90-ASin((Etäisyys*painovoima)/(lähtönopeus^2))/2regalis wrote:Toinen ongelma on saada sivultakuvatussa räiskintäpelissä botit ampumaan yläviistoon aseilla, joiden ammukseen painovoima vaikuttaa voimakkaasti (esim. kranaatit). Jokaisella aseella on muuttuja, joka kertoo kuinka paljon sen ammuksia pudotetaan alaspäin framen aikana. Eli miten siis saan laskettua kulman, jossa botin on ammuttava osuakseen viholliseen?
Lopuksi vielä pieni esimerkki, jossa sininen pallo on kohde, punainen pallo kohta johon ammus putoaisi valitsemasi kulman mukaan ja valkoiset pisteet simuloivat lentorataa. Ohjelma kertoo millä kulmilla osut kohteeseen sekä nykyisen kulmasi.Toivottavasti saatte selvää koodista. Kysykää jos on jotain epäselvääCode: Select all
SCREEN 700,300 FrameLimit 60 gravity#=9.81/60 //painovoima jaettuna FPSällä Speed#=10 TargetX=Rand(50,((Sin(45)*Speed#)^2/(gravity#/2))) //Arpoo luvun 50 ja maksimi etäisyyden välillä Repeat Color 128,128,128 Line 0,300,MouseX(),MouseY() ang=GetAngle(0,300,MouseX(),MouseY()) //Laskee kulman XSpeed#=Cos(ang)*Speed# //Laskee nopeuden x-axelilla YSpeed#=Sin(ang)*Speed# //Laskee nopeuden y-axelilla x#=0 //X-sijainti y#=300 //Y-sijainti Repeat //Lentorata x#=x#+XSpeed# y#=y#-YSpeed# YSpeed#=YSpeed#-gravity# Color 255,255,255 Dot x#,y# Until y#>300 If KeyHit(cbkeyspace) Then TargetX=Rand(50,((Sin(45)*Speed#)^2/(gravity#/2))) //Arpoo uuden sijainnin kohteelle (space) Color 0,0,255 Circle TargetX-5,295,10 //Kohde (sininen) Color 255,0,0 Circle (Sin(ang)*Speed#)/(gravity#/2)*XSpeed#-3,297,6 //Putoamis piste (punainen) TargetAngle=ASin((TargetX*gravity#)/(Speed#^2))/2 //Laskee tarvittavan kulman Color 255,255,255 Text 0,0,Int((Sin(ang)*Speed#)/(gravity#/2)) //Lennon pituus frameissa Text 0,10,"Your Angle: "+ang Text 0,20,"X: "+Int((Sin(ang)*Speed#)/(gravity#/2)*XSpeed#) //Putoamis piste (punainen) Text 150,10,"Target Angle: "+TargetAngle+" or "+(90-TargetAngle) Text 150,20,"TargetX: "+TargetX //etäisyys DrawScreen Forever
Re: Matemaattisia ongelmia...
Hommahan toimii tosiaan näin, jos objektit ovat samalla tasolla y-suunnassa. Mutta käsitin, että pelissä ne ei välttämättä ole.Kassu wrote:Tein eilen vähän laskutehtäviä ja sain selville että kulma = ASin((Etäisyys*painovoima)/(lähtönopeus^2))/2 tai kulma = 90-ASin((Etäisyys*painovoima)/(lähtönopeus^2))/2
Re: Matemaattisia ongelmia...
Kiitoksia neuvoista, mutta päätin toteuttaa ampumisen "hieman" yksinkertaisemmalla, joskin paljon epätarkemmalla tavalla. Lasken ensin kuinka monta pikseliä ammus putoaa matkalla pelaajan kohdalle (pudotus = etäisyys / nopeus * painovoima), ja sitten laitan botin ampumaan tämän saadun luvun verran ylöspäin tähän tapaan:
Kulma = GetAngle(ampujanX, ampujanY, kohdeX, kohdeY + pudotus)
Botti ampuu tietyillä kulmilla ja etäisyyksillä hieman väärin, mutta mielestäni tämä on kuitenkin riittävän tarkka tapa peliini.
Kulma = GetAngle(ampujanX, ampujanY, kohdeX, kohdeY + pudotus)
Botti ampuu tietyillä kulmilla ja etäisyyksillä hieman väärin, mutta mielestäni tämä on kuitenkin riittävän tarkka tapa peliini.