Quick Tips: Kollisjon reaksjon mellom en sirkel og linjesegmenter
Del
Del
3
Del
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: Kollisjon Detection Mellom en sirkel og en linje SegmentPixel-Level Collision Detection for Forvandlet Graphics
I forrige Hurtig Tips, vi har sett på kollisjons deteksjon Bilde: hovedsak, oppdager at to figurer har overlappet. Nå er vi klar til å se på kollisjons reaksjon Bilde: gjør noe skje på grunn av en kollisjon. I denne hurtig Tip, vil vi se på reaksjonene til refleksjon og skli. La oss se på sluttresultatet vil vi oppnå ved slutten av dette opplæringen. Hver Flash demo har en restart-knappen; Klikk på den for å nullstille posisjonen sirklene på toppen av scenen Den første demoen viser av refleksjon Bilde:. Den andre viser skyve Anmeldelser : Jeg har kjørt gjennom dette emnet flere runder med elevene, og erfaring har lært meg at det head-on tilnærming til å forklare vektor matematikk for å Freshers resulterer i tomme ansikter og forvirrede sinn. Så i stedet for å sette opp en Math foredrag her, skal jeg henvise de som er interessert i å undersøke dette temaet videre til Wolfram side på refleksjon. Her skal jeg forenkle mine forklaringer med diagrammet nedenfor. Recall vektor tillegg: Nå observere diagrammet nedenfor. En er sirkelens hastighet før en kollisjon, og A 'er dens hastighet etter kollisjonen. Det er åpenbart at A' = A + 2 V (A p), der V (A p) representerer vektoren med en styrke på A p, i retning av den venstre normale. (Du kan se dette ved å følge de stiplede linjene.) For å oppnå V (A p), skal vi prosjektet A på venstre normal. Her kommer Action gjennomføring av refleksjon. Jeg har uthevet de viktigste delene. Ledning 67 - 69 på er å beregne V (A p) (v_leftNormSeg2) og linje 70 implementerer formelen. Du kan referere til full Action henhold Reaction1.as (du bør kjenne igjen de fleste av koden fra forrige Quick Tips.) Ta oppmerksom på at denne refleksjonen formelen gjelder for linje i alle fall. Faktisk kan du programmere din linje å være justerbar under kjøring og se det reflekterende sirkler som Flash presentasjon under. Bare klikk og dra nær den nedre enden av å omdefinere det Begrepet skyve langs linjen er nesten identisk med refleksjon. Observere diagrammet nedenfor. vektor av lysbildet er A '= A + V (A p) med V (A p) som representerer en vektor med størrelse fra A p. Igjen, for å få A p vi skal projisere A på venstre normal. Legg merke til at så sirkelen glir langs linjen, er det kolliderer med linjen. Of course, kollisjonspunkter varierer blant sirkler som kolliderer på linje, så noen overlappe linjen som de beveger seg langs den. Dette ser ikke bra ut, så vi må omplassere dem Nå, la oss flytte sirkler på linjen samtidig opprettholde sin kontakt med linje . Se diagrammet nedenfor. En viktig variabel for å beregne er projeksjonen av A langs linjen. Radiusen til sirkelen er lett tilgjengelig, og vi har allerede B, slik at vi kan danne vektorer av B og C. Legge de to vil gi oss en, den nøyaktige plasseringen å omplassere sirkel. Simple! Flash presentasjon nedenfor er kodet i henhold til nevnte ideen. Men det er ett problem. Den sirkler jitter langs linjen Det finnes en siste detalj vi savnet. Diagrammet over viser omfanget av C bør være tilsvarende radius av sirkelen. Men dette vil posisjonere sirkel tilbake over linjen. Siden det er ingen kollisjon oppdaget det, vil sirkelen falle ned på linjen igjen, som igjen vil flagge dueller og forårsake sirkelen som skal flyttes. Denne syklusen vil gjenta til det er forbi slutten av linjestykke; det visuelle resultatet av denne syklusen er jittering effekten Løsningen på dette problemet er å angi størrelsen av C til litt mindre enn radien til sirkelen: (radius sirkel - 1), si.. Observere Flash demo nedenfor som bruker denne ideen: Så her er det viktig Actionbiten for å skyve langs linjen. Jeg har uthevet de viktigste delene Håper dette er nyttig. Takk for lesing. Spør meg hvis det er spørsmål, og jeg ser deg neste Quick Tips.
Endelig resultat Forhåndsvisning
Trinn 1: Refleksjon Formula
Trinn 2: Gjennomføring
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); Var c1_circle_onLine: Number = c1_circle.projectionOn (linje); //hvis kollisjonen skjedde, angre bevegelse if (Math.abs (c1_circle_onNormal) < = sirkler [i] .radius & & line.dotProduct (c1_circle) > 0 & & c1_circle_onLine < line.getMagnitude () ) {//omdefinere hastighet Var v_leftNormSeg2: Vector2D = leftNormal.clone (); Var leftNormSeg2_mag: Number = Math.abs (velos [i] .projectionOn (leftNormal)) v_leftNormSeg2.setMagnitude (leftNormSeg2_mag); velos [i] = velos [i] .Legg (v_leftNormSeg2.multiply (2)); } Sirkler [i] .x + = velos [i] .x; kretser [i] .Y + = velos [i] .Y; }}
Trinn 3: En interaktiv versjon
Trinn 4:. Sliding langs linjen
Trinn 5:. Omdefiner Beliggenhet
Trinn 6: Implementering
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); Var c1_circle_onLine: Number = c1_circle.projectionOn (linje); //se etter kollisjon if (Math.abs (c1_circle_onNormal) < = sirkler [i] .radius) {//sjekke om innenfor segmentet //hvis innen segmentet, omplassere og beregne hastighet if (line.dotProduct (c1_circle) > 0 & & c1_circle_onLine < line.getMagnitude ()) {//repostion sirkel Var v_lineSeg: Vector2D = line.clone (); v_lineSeg.setMagnitude (c1_circle_onLine); Var v_leftNormSeg1: Vector2D = leftNormal.clone (); v_leftNormSeg1.setMagnitude (sirkler [i] .radius - 1); //v_leftNormSeg1.setMagnitude(circles[i].radius); //uncomment dette til å sjekke ut feilen: jittering effekt Var omplassere: Vector2D = v_lineSeg.add (v_leftNormSeg1) sirkler [i] .x = x1 + reposition.x; sirkler [i] .Y = y1 + reposition.y; //omdefinere hastighet Var v_leftNormSeg2: Vector2D = leftNormal.clone (); Var leftNormSeg2_mag: Number = Math.abs (velos [i] .projectionOn (leftNormal)) v_leftNormSeg2.setMagnitude (leftNormSeg2_mag); Var veloAlongLine: Vector2D = velos [i] .Legg (v_leftNormSeg2); sirkler [i] .x + = veloAlongLine.x; sirkler [i] .Y + = veloAlongLine.y; } //Hvis ikke i segment (f.eks gli ut av segment), fortsetter å falle ned else {sirkler [i] .x + = velos [i] .x; kretser [i] .Y + = velos [i] .Y; }} //Ingen kollisjon i første omgang, faller ned else {sirkler [i] .x + = velos [i] .x; kretser [i] .Y + = velos [i] .Y; }}}
Konklusjon