Quick Tips: Kollisjon Detection Mellom en sirkel og en linje
Del
Del
7
Share < .no> Dette Cyber mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av
Dette innlegget er en del av en serie som heter Collision Detection og Reaction.Quick. Tips: Collision Detection Mellom CirclesQuick Tips: Kollisjon Detection Mellom en sirkel og linjesegmenter
I min forrige Quick Tips, vi sett på ideen om dueller generelt, og spesielt på å oppdage kollisjoner mellom et par sirkler. I denne hurtig Tip, vil vi se på å oppdage en kollisjon mellom en sirkel og en linje.
Dette er et resultat som vi vil jobbe med. Klikk på Restart-knappen for å flytte alle kretser på toppen av scenen og se dem falle ned.
Merk at sirklene kolliderer med linjen selv utenfor det segmentet som er trukket. Min neste Quick Tips vil vise hvordan du kan fikse dette
Trinn 1:. The General Idea
For å sjekke om noen sirkel har kollidert med en linje, må vi sjekke vinkel lengde Det er klart fra diagrammet over at saker 3 og 4 skal oppdage en kollisjon mellom sirkelen og linjen. Så vi konkludere med at hvis vinkel lengde (markert med rødt) er lik eller mindre enn sirkelens radius, en kollisjon skjedde på grunn av sirkelen berører eller overlapper linjen. Spørsmålet er, hvordan beregner vi denne vinkel lengden? Vel, vektorer kan bidra til å forenkle vårt problem For å trekke en linje på scenen, vi trenger to koordinater (c1 og c2). Linjen trukket fra c1 til c2 vil danne en vektor som peker til c2 (Merk retning av pilen). Deretter må vi finne linjens normal Den venstre normal brukes i våre forsøk på å beregne vinkel lengde mellom sirkelen og linjen. Detaljer finner du i figuren nedenfor. En Den enkleste metoden er å gjøre bruk av vektoroperasjoner, spesielt prikk-produktet. Starter fra ligningen av dot produkt, omorganisere vi begrepene slik at vi kommer til andre uttrykk vist nedenfor. Legg merke til at høyre side av den andre ligningen er anslaget at vi ønsket å beregne! Legg også merke på venstre og høyre side av ligningen til slutt vil gi samme resultat, selv om forskjellige i sine tilnærminger. Så i stedet for å bruke den høyre siden av ligningen, kan vi velge den venstre side av ligningen. For enkelt å komme frem til det endelige resultatet, er det gunstig å bruke venstre fordi variablene kan lett løses. Hvis vi insisterer på å bruke riktig av ligningen, ville vi måtte presse Action gjennom rigourous Mathematical arbeid i beregning av vinkelen theta. Vi konkluderer med diagrammet nedenfor . (* Ekstra tips: Om sirkelen faller under linje vektor, vinkelrett lengde beregnes fra formelen i diagrammet over vil gi en negativ verdi.) Nå som vi har forstått tilnærming matematisk, la oss fortsette å implementere den i Actionscript. I denne første delen, merk linjens vektoren blir rotert -90 ° å danne venstre normal I denne andre delen, har jeg uthevet beregningene nevnt og tilstanden for å se etter kollisjon mellom sirkel og linje For de som ønsker å se nærmere på saken, følgende er utdrag av metoder som brukes i Vector.as Twitter /*** Metode for å få projeksjonen av dagens vektor på en gitt akse *param aksen en akse hvor vektoren projiseres på *return Anslaget lengden på strømvektor på gitt akse * /public funksjon projectionOn (akse: Vector2D): Antall {return this.dotProduct (axis.normalise ())} /*** Metode til utføre dot produkt med en annen vektor *param Vektor2 En vektor for å utføre dot produkt med strømvektor *return En skalar antall dot produktet * /public funksjon dotProduct (Vektor2: Vector2D): Antall {var componentX: Number = this._vecX * vector2.x; Var componentY: Number = this._vecY * vector2.y; returnere componentX + componentY;} /*** Metode for å oppnå vektor enhet strømvektor *return En kopi av normalisert vektor * /public funksjon normalize (): Vector2D {return new Vector2D (this._vecX /this.getMagnitude () this._vecY /this.getMagnitude ())} /*** Metode for å oppnå dagens omfang av vektor *return Magnitude av type Number * /public funksjon getMagnitude (): Antall {return Math.sqrt (_vecX * _vecX + _vecY * _vecY);} Trykk på Restart-knappen for å flytte alle kretser på toppen av scenen. Merk at kollisjonen er mellom hele Takk for lesing. Stay tuned for neste tips. Anmeldelser
fra linjen til sirkelen. Observere diagrammet nedenfor.
Trinn 2:. Linje Normal
. Linjens normale er en annen linje som gjør 90 ° med den opprinnelige linjen, og skjærer den i et punkt. Til tross for den linjen normale være enda en linje, kan det normale er vektorform bli ytterligere identifisert som forlot
eller høyre
normal i forhold til linjens vektor. Den venstre normale er linjen vektoren selv, roteres -90 °. Høyre normal er den samme, men rotert 90 °. Husk at y-aksen i Flash koordinatsystem plass er invertert i forhold til y-aksen på en typisk graf - så positiv rotasjon er klokken og negative rotasjon er mot urviseren
Trinn 3: Projection på. Venstre Normal
refererer til en vektor som peker fra c1
til sirkelen. Normalen lengde faktisk refererer til vektor A projeksjon
på venstre normal. Vi utlede dette anslaget ved hjelp av trigonometri: det er | A | Cosinus (theta), hvor | A | viser til størrelsen på vektoren A
.
Trinn 4: Implementering Circle Line Collision Detection
//erklære coordinatesx1 = 50.; y1 = 100; x2 = 250; y2 = 150; //tegning linegraphics.lineStyle (3); graphics.moveTo (x1, y1); graphics.lineTo (x2, y2) //forming linje vectorsline = new Vector2D (x2 - x1, y2 - y1); leftNormal = line.rotate (Math.PI * -0,5);
privat funksjon refresh (e: Hendelses): void {for (var i: int = 0; i < circles.length; i ++). {//beregning linjen vinkelrett avstand til ballen Var c1_circle: Vector2D = nye Vector2D (sirkler [i] .x - x1, sirkler [i] .Y - y1); Var c1_circle_onNormal: Number = c1_circle.projectionOn (leftNormal); sirkler [i] .Y + = 2; //hvis kollisjonen skjedde, angre bevegelse if (Math.abs (c1_circle_onNormal) < = kretser [i] .radius) {sirkler [i] .Y - = 2; }}}
Trinn 5: Resultat
linje (inkludert delen ikke trukket) og sirklene. For å begrense kollisjon til linjesegmentet bare, følg med for neste Quick Tips.
Konklusjon