Matemaattisia ongelmia...

Voit pyytää apua ohjelmointiongelmiin täältä.
Post Reply
regalis
Advanced Member
Posts: 268
Joined: Mon Aug 27, 2007 9:44 pm

Matemaattisia ongelmia...

Post by regalis »

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?
Harakka
Advanced Member
Posts: 430
Joined: Mon Aug 27, 2007 9:08 pm
Location: Salo
Contact:

Re: Matemaattisia ongelmia...

Post by Harakka »

Esimmäiseen kysymykseen:

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
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. :)
Peli piirtokomennoilla - voittaja, Virtuaalilemmikkipeli - voittaja,
Sukellusvenepeli - voittaja, Paras tileset - voittaja
Vaihtuva päähenkilö - voittaja, Autopeli - voittaja sekä
Hiirellä ohjattava peli - voittaja B)
Kassu
Newcomer
Posts: 22
Joined: Wed Aug 29, 2007 5:32 pm

Re: Matemaattisia ongelmia...

Post by Kassu »

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).
atomimalli
Moderator
Moderator
Posts: 227
Joined: Wed Aug 29, 2007 3:55 pm

Re: Matemaattisia ongelmia...

Post by atomimalli »

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ä.
Last edited by atomimalli on Tue Jan 08, 2008 8:14 am, edited 1 time in total.
Marcor
Newcomer
Posts: 10
Joined: Thu Oct 18, 2007 3:03 pm

Re: Matemaattisia ongelmia...

Post by Marcor »

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:

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
    
Guest

Re: Matemaattisia ongelmia...

Post by Guest »

Niinpä tietenkin, en tullut ajatelleeksi että kulman voisi tarkistaa GetAnglella... :) Pitää sitten seuraavaksi yrittää saada noiden atomimallin ohjeiden avulla bottien ampuminen toimimaan.
atomimalli wrote:Itseasiassa oikeassa maailmassa painpovoima on vakio(maanpinnalla), joten sitä ei pitäisi olla kaikille erikseen, se fysikaalinen ominaisuus, mikä vaihtelee, on kimpoamisherkkyys...
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
Moderator
Moderator
Posts: 227
Joined: Wed Aug 29, 2007 3:55 pm

Re: Matemaattisia ongelmia...

Post by atomimalli »

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.
Astigma
Moderator
Moderator
Posts: 195
Joined: Sun Aug 26, 2007 5:56 pm
Location: Kuopio, Finland
Contact:

Re: Matemaattisia ongelmia...

Post by Astigma »

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?
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ä.

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).
Kassu
Newcomer
Posts: 22
Joined: Wed Aug 29, 2007 5:32 pm

Re: Matemaattisia ongelmia...

Post by Kassu »

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?
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

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
Toivottavasti saatte selvää koodista. Kysykää jos on jotain epäselvää :)

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.
BulletStorm

Re: Matemaattisia ongelmia...

Post by BulletStorm »

Kassu wrote:
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?
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

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
Toivottavasti saatte selvää koodista. Kysykää jos on jotain epäselvää :)
Tollasella systeemillähän saisi aikaan jonkinlaisen pelin, jossa pitää ampua tykillä. Niice :D
Astigma
Moderator
Moderator
Posts: 195
Joined: Sun Aug 26, 2007 5:56 pm
Location: Kuopio, Finland
Contact:

Re: Matemaattisia ongelmia...

Post by Astigma »

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
Hommahan toimii tosiaan näin, jos objektit ovat samalla tasolla y-suunnassa. Mutta käsitin, että pelissä ne ei välttämättä ole.
regalis
Advanced Member
Posts: 268
Joined: Mon Aug 27, 2007 9:44 pm

Re: Matemaattisia ongelmia...

Post by regalis »

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.
Post Reply