Hankala kysymys...
Hankala kysymys...
Noh, tarttisin apua sellaaseen funktioon joka tarkastaisi nopeasti onko pallo mennyt viivan yli, samoin kuin LineIntersect:issä tarkistetaan onko viiva mennyt
toisen yli... LineIntersectistä sain tehtyä sellaasen, että onko pikseli mennyt viivaan, mutta en sellaasta, että onko pallo osunut viivaan...
Apua ja funktiota kaivataan!
toisen yli... LineIntersectistä sain tehtyä sellaasen, että onko pikseli mennyt viivaan, mutta en sellaasta, että onko pallo osunut viivaan...
Apua ja funktiota kaivataan!
Solar Eclipse
We're in a simulation, and God is trying to debug us.
Re: Hankala kysymys...
Siis haluatko tarkistaa jos pallo on mennyt viivan yli vai jos see on osunut siihen?
Jos haluat tarkistaa onko pallo on mennyt viivan yli, niin se hän on periaatteessa sama asia kuin jos pallon vanhojen ja uusien kordinaattien välinen viiva on ylittänyt kyseisen viivan yli.
Jos haluat tarkistaa onko pallo on mennyt viivan yli, niin se hän on periaatteessa sama asia kuin jos pallon vanhojen ja uusien kordinaattien välinen viiva on ylittänyt kyseisen viivan yli.
-
- Tech Developer
- Posts: 650
- Joined: Mon Aug 27, 2007 9:51 pm
- Location: Helsinki, Finland
- Contact:
Re: Hankala kysymys...
Jos ympyrä on kulkenut janan yli, jana, joka on piirretty ympyrän (keskipisteen) entisestä sijainnista nykyiseen, leikkaa alkuperäisen janan.programmer of DSG wrote:Noh, tarttisin apua sellaaseen funktioon joka tarkastaisi nopeasti onko pallo mennyt viivan yli, samoin kuin LineIntersect:issä tarkistetaan onko viiva mennyt
toisen yli... LineIntersectistä sain tehtyä sellaasen, että onko pikseli mennyt viivaan, mutta en sellaasta, että onko pallo osunut viivaan...
Apua ja funktiota kaivataan!
Jos taas haluat tietää, leikkaako ympyrä janan, siihen täytyy soveltaa kaavaa, joka kertoo pisteen etäisyyden suorasta, kun piste ja suoran yhtälö tunnetaan. Kerro ensin tarkoititko tätä, niin autan sitten vasta, koska en nyt jaksa alkaa turhan takia yhtälöitä pyörittelemaan
EDIT:
Njahah.. NorthBurns muisti vielä sen, että kyseessä oli jana. Epäilen vaan suuresti, onnistuuko tuon kääntäminen funktioksikaan, jos on vaikeuksia realisoida se, mitä funktion pitäisi tehdä. Lisäksi vektorit ja janan yhtälö eivät ole mitään ihan yläastekamaa..
Last edited by SPuntte on Fri Feb 22, 2008 11:47 pm, edited 2 times in total.
CoolBasic henkilökuntaa
Tech-kehittäjä
CoolBasic Classic, Cool VES
CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
Tech-kehittäjä
CoolBasic Classic, Cool VES
CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
-
- Newcomer
- Posts: 7
- Joined: Tue Aug 28, 2007 5:49 pm
Re: Hankala kysymys...
Joo, tuollaisen ympyrä-jana-leikkaus -funktion tekeminen ei ole ihan pala kakkua, olettaen että siitä haluaa tehokkaan. Mutta pienellä vektorien pyörittelyllä pystyy tekemään funktion, joka ei turvaudu trigonometriaan, tai muuhunkaan hömppään.
En viitsi kirjoittaa valmista funktiota sinulle, mutta sen sijaan kirjoitin pienen tekstin, jonka kun lukaiset, saat tehtyä itse funktiosi ja saatat jopa tajuta mitä se tekee
Helpotan kuitenkin luku-urakkaasi merkitsemällä tähdellä rivit, jotka saapuvat funktioosi asti.
En viitsi kirjoittaa valmista funktiota sinulle, mutta sen sijaan kirjoitin pienen tekstin, jonka kun lukaiset, saat tehtyä itse funktiosi ja saatat jopa tajuta mitä se tekee
Helpotan kuitenkin luku-urakkaasi merkitsemällä tähdellä rivit, jotka saapuvat funktioosi asti.
Code: Select all
*Jos käsiteltävänä on jana (pisteestä P1 pisteeseen P3) ja ympyrä (keskipiste P3, säde r), mieti seuraavaa:
Ympyrää lähin piste janalla on [u]janan[/u] ja [u]janaa kohtisuorassa olevan ja P3:n läpi kulkeva suoran[/u] leikkauspiste. Merkitään leikkauspistettä P:llä.
Otetaan jana P3-P (suorasta pätkä) ja "alku-"jana P2-P1. Näiden vektorien pistetulo on nolla, jos ne ovat kohtisuorassa:
(P3-P) dot (P2-P1) = 0
Kun tähän sijoitetaan janan yhtälö, P = P1 + u*(P2-P1), saadaan:
(P3-P1-u*(P2-P1)) dot (P2-P1) = 0
Kun tästä ratkaistaan u (janan yhtälön parametri), saadaan:
(x3-x1)(x2-x1)+(y3-y1)(y2-y1)
* u = -----------------------------
(x2-x1)(x2-x1)+(y2-y1)(y2-y1)
*Jos u on jotain 0:n ja 1:n välillä, on ympyrää lähinnä oleva piste janalla!
*Seuraavaksi täytyy selvittää, onko piste P alle säteen päässä ympyrän keskipisteestä. Tosi: törmäys, Epätosi: ei tormäystä.
Tiedämme jo pisteen P, parametrin u avulla:
P = P1 + u*(P2-P1)
Ja tiedämme ympyrän keskipisteen P3. Törmäysehto saadaan muotoon:
| P3-P | < r
Komponentit auki:
sqrt( (x3-x1-u*x2+u*x1)^2 + (y3-y1-u*y2+u*y1)^2 ) < r
Korotetaan epäyhtälö toiseen potenssiin (koska neliöjuuret ovat hitaita) ja järjestellään termit nätimmin:
* (x3-x1+u*(x1-x2))^2 + (y3-y1+u*(y1-y2))^2 < r^2
Leikkauspisteen/leikkauspisteiden ratkaiseminen jätetään harjoitukseksi lukijalle.
Referenssinä käytetty: Laskin ja http://local.wasp.uwa.edu.au/~pbourke/geometry/sphereline/
-
- Tech Developer
- Posts: 650
- Joined: Mon Aug 27, 2007 9:51 pm
- Location: Helsinki, Finland
- Contact:
Re: Hankala kysymys...
BUHHAHHAH.
Nyt olen kerrassaan ilkeä ihminen. Kiinnostuin jostain kumman syystä itse tästä aiheesta ja käytin siihen aikaa, joten en voi vastustaa kiusausta hieman egottaa, että osaanpahan minäkin matikkaa. Ensinnäkin teen Northburns'n vaivannäön turhaksi ja toiseksi pilaan programmer of DSG'n oppimisen ilon sekä sekoitan samalla hänen päätänsä vähän lisää.
Anteeksi jo etukäteen.
Tarvitsin tähän ainoastaan MAOL'a sekä kynän ja paperia, jotta sain vähän purettua kaavoja koodikelpoisiksi. Jostain syystä kommentoin kaiken englanniksi.. Lineekö siitä mitään hyötyä, kun ei täällä juuri muita kuin suomalaisia liiku.
Funktiot toimivat seuraavasti:
PointInLineSegArea:
Tarkistaa onko annettu piste janan päätepisteiden kautta kulkevien normaalien rajaaman alueen sisäpuolella.
Matemaattisesti tämä toimii siten, että se tarkistaa, ovatko janavektorin ja sen vastavektorin sekä pisteen ja janan päätepisteiden välisten vektoreiden pistetulojen merkit samat. Jos ovat, piste on alueen sisällä.
PointToLineDist:
Laskee pisteen etäisyyden suorasta.
Ts. annetun pisteen ja sitä lähinnä suoralla sijaitsevan pisteen välisen vektorin/janan pituuden. Johdettu MAOL'n kaavoista (kahdeen pisteen kautta kulkevan suoran yhtälö, pisteen etäisyys suorasta; s. 43).
CircleToLineSegIsect:
Tarkistaa leikkaako ympyrä janan.
Jos ympyrän keskipiste toteuttaa ensimäisen funktion ja keskipisteen etäisyys janan päätepisteiden kautta kulkevasta suorasta on pienempi tai yhtäsuuri kuin ympyrän säde, tai vaihtoehtoisesti ympyrän keskipisteen etäisyys ainakin toisesta janan päätepisteestä on pienempi tai yhtäsuuri kuin ympyrän säde, leikkaus on tosi.
Khoodia(esimerkki sisältyy):
Nyt olen kerrassaan ilkeä ihminen. Kiinnostuin jostain kumman syystä itse tästä aiheesta ja käytin siihen aikaa, joten en voi vastustaa kiusausta hieman egottaa, että osaanpahan minäkin matikkaa. Ensinnäkin teen Northburns'n vaivannäön turhaksi ja toiseksi pilaan programmer of DSG'n oppimisen ilon sekä sekoitan samalla hänen päätänsä vähän lisää.
Anteeksi jo etukäteen.
Tarvitsin tähän ainoastaan MAOL'a sekä kynän ja paperia, jotta sain vähän purettua kaavoja koodikelpoisiksi. Jostain syystä kommentoin kaiken englanniksi.. Lineekö siitä mitään hyötyä, kun ei täällä juuri muita kuin suomalaisia liiku.
Funktiot toimivat seuraavasti:
PointInLineSegArea:
Tarkistaa onko annettu piste janan päätepisteiden kautta kulkevien normaalien rajaaman alueen sisäpuolella.
Matemaattisesti tämä toimii siten, että se tarkistaa, ovatko janavektorin ja sen vastavektorin sekä pisteen ja janan päätepisteiden välisten vektoreiden pistetulojen merkit samat. Jos ovat, piste on alueen sisällä.
PointToLineDist:
Laskee pisteen etäisyyden suorasta.
Ts. annetun pisteen ja sitä lähinnä suoralla sijaitsevan pisteen välisen vektorin/janan pituuden. Johdettu MAOL'n kaavoista (kahdeen pisteen kautta kulkevan suoran yhtälö, pisteen etäisyys suorasta; s. 43).
CircleToLineSegIsect:
Tarkistaa leikkaako ympyrä janan.
Jos ympyrän keskipiste toteuttaa ensimäisen funktion ja keskipisteen etäisyys janan päätepisteiden kautta kulkevasta suorasta on pienempi tai yhtäsuuri kuin ympyrän säde, tai vaihtoehtoisesti ympyrän keskipisteen etäisyys ainakin toisesta janan päätepisteestä on pienempi tai yhtäsuuri kuin ympyrän säde, leikkaus on tosi.
Khoodia(esimerkki sisältyy):
Code: Select all
Randomize Timer()
x1 = Rand(50, 350)
y1 = Rand(50, 250)
x2 = Rand(50, 350)
y2 = Rand(50, 250)
rad = Rand(20, 50)
ShowMouse OFF
Repeat
Color 255, 255, 255
Text 5, 5, "Mouse in 'segment area': " + PointInLineSegArea(MouseX(), MouseY(), x1, y1, x2, y2)
Text 5, 17, "Point to Line -distance: " + PointToLineDist(MouseX(), MouseY(), x1, y1, x2, y2)
Text 5, 29, "Circle to line segment intersection: " + CircleToLineSegIsect(MouseX(), MouseY(), rad, x1, y1, x2, y2)
Text 5, 40, "Press space to re-randomize values"
Line x1, y1, x2, y2
Color 255, 0, 0
Dot MouseX(), MouseY()
Circle2(MouseX(), MouseY(), rad, OFF)
If KeyHit(CBkeySpace) Then
x1 = Rand(50, 350)
y1 = Rand(50, 250)
x2 = Rand(50, 350)
y2 = Rand(50, 250)
rad = Rand(10, 50)
EndIf
DrawScreen
Forever
//CircleToLineSegIsect
//
//Returns:
// TRUE (1) when:
// Circle [center=point (cx, cy); radius=r]
// intersects Line through points (l1x, l1y) & (l2x, l2y)
// FALSE (0) in every other cases
Function CircleToLineSegIsect(cx#, cy#, r#, l1x#, l1y#, l2x#, l2y#)
//Circle center inside 'line segment area'
If PointInLineSegArea(cx, cy, l1x, l1y, l2x, l2y) = True And PointToLineDist(cx, cy, l1x, l1y, l2x, l2y) <= r Then
Return True
//Circle center outside 'line segment area'
ElseIf Distance(cx, cy, l1x, l1y) <= r Or Distance(cx, cy, l2x, l2y) <= r Then
Return True
Else
Return False
EndIf
EndFunction
//PointToLineDist
//
//Returns:
// Distance between
// Point (px, py)
// and
// Line through points (l1x, l1y) & (l2x, l2y)
Function PointToLineDist(px#, py#, l1x#, l1y#, l2x#, l2y#)
//'Formula' of the line
a# = (l2y - l1y) / (l2x - l1x)
b# = -1
c# = -(l2y - l1y) / (l2x - l1x) * l1x + l1y
//Distance
d# = Abs(a * px + b * py + c) / Sqrt(a * a + b * b)
Return d
EndFunction
//PointInLineSegArea
//
//Returns:
// TRUE (1) when:
// point(px, py) appears in area
// restricted by the normals of the line segment
// drawn through the end points of the line segment
//
// FALSE (0) in every other cases
Function PointInLineSegArea(px#, py#, l1x#, l1y#, l2x#, l2y#)
//Vectors
SegVecX# = l2x - l1x
SegVecY# = l2y - l1y
PntVec1X# = px - l1x
PntVec1Y# = py - l1y
PntVec2X# = px - l2x
PntVec2Y# = py - l2y
//Dot products
dp1# = SegVecX * PntVec1X + SegVecY * PntVec1Y
dp2# = -SegVecX * PntVec2X - SegVecY * PntVec2Y
//Checks if DPs' signs are same
If dp1 = 0 Or dp2 = 0 Then
Return True
ElseIf Sign(dp1) = Sign(dp2) Then
Return True
Else
Return False
EndIf
EndFunction
Function Sign(val)
If val > 0 Then
Return 1
ElseIf val < 0 Then
Return -1
Else
Return 0
EndIf
EndFunction
Function Circle2(x, y, r, fill=0)
Circle x-r,y-r,r*2,fill
EndFunction
CoolBasic henkilökuntaa
Tech-kehittäjä
CoolBasic Classic, Cool VES
CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
Tech-kehittäjä
CoolBasic Classic, Cool VES
CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
Re: Hankala kysymys...
No huhhuh mitä soopaa (Minulle. Hyvä kun osaan laskea potensseja jotenkin.) ei millää pahalla.
Solar Eclipse
We're in a simulation, and God is trying to debug us.
-
- Tech Developer
- Posts: 650
- Joined: Mon Aug 27, 2007 9:51 pm
- Location: Helsinki, Finland
- Contact:
Re: Hankala kysymys...
Vähän sitä pelkäsin Jos tuosta funktioväkerryksestäni on jotain hyötyä, hyvä niin. Voisin yhdistää nuo kaikki yhdeksi funktioksi (joka siis tarkastaa, leikkaavatko ympyrä ja jana) mikä säästäisi CB:n funktiorajan ylittymistä ja selventäisi, kun tietäisit, että on yksi funktio ja se tarkastaa juuri sitä ja sitä.
Eihän yläasteella käytetä edes MAOL'a tai mitään muutakaan apuvälinettä funktiolaskimen lisäksi, vaan kaikki 'kaavat' opetellaan ulkoa
Eihän yläasteella käytetä edes MAOL'a tai mitään muutakaan apuvälinettä funktiolaskimen lisäksi, vaan kaikki 'kaavat' opetellaan ulkoa
CoolBasic henkilökuntaa
Tech-kehittäjä
CoolBasic Classic, Cool VES
CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
Tech-kehittäjä
CoolBasic Classic, Cool VES
CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
Re: Hankala kysymys...
Sain itse tehtyy tallaase:
Code: Select all
Function CircleIntersect(Ax#, Ay#, Bx#, By#, Cx#, Cy#,size = 40)
For I = 0 To 72
If PixelIntersect(Ax#, Ay#, Bx#, By#,Cx#+Cos(i*5)*size,Cy#+Sin(i*5)*size) Then Return 1
Next i
EndFunction
Function PixelIntersect(Ax#, Ay#, Bx#, By#, Cx#, Cy#)
Rn# = (Ay#-Cy#) - (Ax#-Cx#)
Rd# = (Bx#-Ax#)- (By#-Ay#)
If Rd# = 0
Return False
Else
Sn# = (Ay#-Cy#)*(Bx#-Ax#) - (Ax#-Cx#)*(By#-Ay#)
Intersection_AB# = Rn# / Rd#
Intersection_CD# = Sn# / Rd#
If Intersection_AB# > 1 Or Intersection_CD# > 1 Or Intersection_AB# < 0 Or Intersection_CD# < 0 Then Return False
IntersX = Ax# + Intersection_AB#*(Bx#-Ax#)
IntersY = Ay# + Intersection_AB#*(By#-Ay#)
Return True
EndIf
End Function
EDIT:
Se on harmi, ettei gosub:ia voi käyttää function sisällä.
Solar Eclipse
We're in a simulation, and God is trying to debug us.
Re: Hankala kysymys...
Anteeksi kaksois postaus, mutta piti vähän saada tänne taas eloa, koska toi Spunten Funktio on ihan toimiva. Eli voit Spuntte Pistää ne kaikki yhdeksi ja postata ne tänne. Jos on aikaa ja halua.
Solar Eclipse
We're in a simulation, and God is trying to debug us.
-
- Tech Developer
- Posts: 650
- Joined: Mon Aug 27, 2007 9:51 pm
- Location: Helsinki, Finland
- Contact:
Re: Hankala kysymys...
Thäsää hän ois. Katsoin suunnilleen, että tuossa ei suoriteta mitään turhaan, eli järjestin tarkistukset yksinkertaisimmasta monimutkaisimpaan nin, että ensin tulevat sulkevat kaikki jälkimmäiset pois, mutta saatta sieltä vielä optimoinnin varaa löytyä. Tuo 2/3 tyhjä If..Elseif..Else rakenne jäi vähän vaivaamaan..
Code: Select all
//CircleToLineSegIsect2
//
//Returns:
// TRUE (1) when:
// Circle [center=point (cx, cy); radius=r]
// intersects Line through points (l1x, l1y) & (l2x, l2y)
// FALSE (0) in every other cases
Function CircleToLineSegIsect2(cx#, cy#, r#, l1x#, l1y#, l2x#, l2y#)
//Circle center Near enough the end points
If Distance(cx, cy, l1x, l1y) <= r Or Distance(cx, cy, l2x, l2y) <= r Then Return True
//Vectors
SegVecX# = l2x - l1x
SegVecY# = l2y - l1y
PntVec1X# = cx - l1x
PntVec1Y# = cy - l1y
PntVec2X# = cx - l2x
PntVec2Y# = cy - l2y
//Dot products
dp1# = SegVecX * PntVec1X + SegVecY * PntVec1Y
dp2# = -SegVecX * PntVec2X - SegVecY * PntVec2Y
//Check's whether one of the DPs is zero.
//or signs are same
If dp1 = 0 Or dp2 = 0 Then
ElseIf Sign(dp1) = Sign(dp2) Then
Else
Return False
EndIf
//'Formula' of the line
a# = (l2y - l1y) / (l2x - l1x)
b# = -1
c# = -(l2y - l1y) / (l2x - l1x) * l1x + l1y
//Distance
d# = Abs(a * cx + b * cy + c) / Sqrt(a * a + b * b)
//Circle is too far
If d > r Then Return False
//If function reaches this point, circle and line segment DO intersect each other
Return True
EndFunction
CoolBasic henkilökuntaa
Tech-kehittäjä
CoolBasic Classic, Cool VES
CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
Tech-kehittäjä
CoolBasic Classic, Cool VES
CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
Re: Hankala kysymys...
Aika pro viritys, hyöty on suuri varsinkin piirtokomennoilla toteutetuissa peleissä.
Itse tulen tätä luultavasti käyttämään.
Edit: Tämän voisikin melkein laittaa ihan selkeyden nimissä tuonne esimerkkikoodit alueelle.
Itse tulen tätä luultavasti käyttämään.
Edit: Tämän voisikin melkein laittaa ihan selkeyden nimissä tuonne esimerkkikoodit alueelle.
-
- Tech Developer
- Posts: 650
- Joined: Mon Aug 27, 2007 9:51 pm
- Location: Helsinki, Finland
- Contact:
Re: Hankala kysymys...
Lisäsin esimerkkikoodeihin. Samalla muutin kommentit suomeksi ja siistin koko hommaa vielä vähän lisää -> viewtopic.php?f=12&t=574
CoolBasic henkilökuntaa
Tech-kehittäjä
CoolBasic Classic, Cool VES
CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX
Tech-kehittäjä
CoolBasic Classic, Cool VES
CoolPhysicsEngine | MissileSystem | Jana-ympyrä -törmäys | cbSimpleTexture | CoolCPLX