The Math og Action av Curves: Roots
to
Del
11
Del
Dette Cyber Monday Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av
Dette innlegget er en del av en serie som heter You Do The Math.The Math og Action av Curves. Tegne Annen- og tredje Curves
I den første opplæringen av denne serien, tok vi en titt på tegne kurver ved hjelp av likninger og AS3. Nå skal vi takle løse disse ligningene for å finne røttene til en kurve - det vil si de stedene der kurven krysser en gitt rett linje. Vi kan bruke dette til å forutsi kollisjoner med buede overflater, og for å unngå "tunneling" i Flash spill
Trinn 1:. Kvadratisk Roots
Først tid for noen raske matematikk revisjon. I denne opplæringen, vil vi bare akseptere og anvende de metoder vi skal bruke, men interesserte lesere kan referere til Wikipedias side om kvadratiske likninger for informasjon om de matematiske deriviations.
Så \\ (f (x) \\ ) er en kvadratisk funksjon. Hvis \\ (f (x) \\) er lik 0, \\ (x \\) kan oppnås ved følgende formel:
\\ [Gitt \\ f (x) \\ = \\ ax ^ 2 + bx + c \\ \\]
\\ [f (a) \\ = \\ 0, \\ x = \\ frac {-b \\ pm \\ sqrt {b ^ 2 - 4ac}} {2a} \\]
\\ (b ^ 2 - 4ac \\) kalles diskriminant Så hva er røtter? Vel i vår sammenheng er de noe mer enn skjæringspunkter mellom den kvadratiske kurve og en linje. For eksempel at vi er interessert i å finne skjæringspunktet (e) av følgende sett av likninger: \\ ( Dette er et typisk scenario av å lete etter skjæringspunkt (er) mellom en kvadratisk kurven og x-aksen (fordi x-aksen er linjen der y == 0). Siden per definisjon skjæringspunkt (e) er delt av \\ (f (x) \\), og \\ (g (x) \\), kan vi konkludere med at \\ (f (x) = g (x) \\) for verdiene av x som vi er ute etter. Det er da en triviell operasjon der du bare erstatte funksjonene og deretter bruke formelen fra trinn 1 for å få røttene. Nå er det vi kan forutse som vist under flere muligheter. (Som du kan se, "imaginære røtter" betyr, for vårt formål, at kurven ikke noen gang krysser x-aksen.) La oss nå vurdere saken der \\ (g (x) \\) er mer enn bare en verdslig horisontal linje. La oss si det er en skråstilt linje, \\ (g (x) \\ = \\ mx \\ + \\ d \\). Nå når vi likestille begge funksjonene, må vi gjøre litt precalculation før formel kan brukes effektivt. \\ [ Jeg har tatt med en interaktiv Flash presentasjon under så gjerne dra de røde og blå prikker. Gule prikkene indikerer skjæringspunkter. Du må kanskje plassere kurven og linjen til krysser hverandre for at de gule prikker vises Den fulle skript kan bli funnet i Demo1.as; her vil jeg bare forklare en avgjørende ekstrakt av koden. La oss se på AS3 for å tegne kurven og linjen: Hovedtyngden av Actionscript for å trekke kurven fra linje 80 ~ 104 er i stor grad hentet fra den forrige tutorial, så jeg skal bare forklare litt om koden for å tegne en linje I Flash presentasjon ovenfor, er det to interaktive blå prikker. Hver av disse har koordinater, og med begge prikker, er dannet en linje. Siden begge punkter ligger på samme linje, de deler en felles skråningen og y-aksen for å danne én generell linje ligning: \\ [ Vi kan bruke litt algebra til å løse for de to ukjente, \\ (m \\) og \\ (d \\) . Gitt koordinatene til de to blå prikker som \\ ((x_1, \\ y_1) \\) og \\ ((x_2, \\ y_2) \\): [latex] [latex] [latex] Anmeldelser \\ begin {bmatrix} x_1 & 1 \\\\ x_2 & 1 \\ end {bmatrix} ^ {- 1} [latex] Anmeldelser \\ begin {bmatrix} x_1 & 1 \\\\ x_2 & 1 \\ end {bmatrix} ^ {- 1} (Merk at en matrise med hevet skrift -1 refererer til inverse av at matrisen.) Så bruker dette, \\ (m \\ ) og \\ (d \\) beregnes. Vi kan nå trekke linjen ved å bli med koordinatene \\ ((0, y_3) \\) og \\ ((stage.stageWidth, y_4) \\). Hvordan finner du \\ (y_3 \\) og \\ (y_4 \\)? Vel nå som \\ (m \\), \\ (x \\) og \\ (d \\) er kjent, kan vi bare sette alle disse verdiene inn i linjen generell ligning, etter \\ (y \\ = \\ mx \\ + \\ d \\) .. å få disse \\ (y \\) s For å beregne posisjonen de kryssende punkter, skal vi bruke formelen fra trinn 1. Dette gjøres i EqQuadratic.as som funksjonene vist nedenfor: Twitter /** Beskyttet * diskriminant av ligningen * /offentlig funksjon får diskriminant (): Antall { //B * B-4 * A * C avkastning _B * _B - 4 * _A * _C;} /** * Utfører beregning for å få røtter * /public funksjons calcRoots (): void {var plate: Number = this.discriminant //håndtere imaginære røtter if (disc < 0) {plate * = 1; Var component_real: Number = -_B /(2 * _A); Var component_imaginary: Number = Math.sqrt (disc) /(2 * _A); _root_i [0] = (component_real + "+ i" + component_imaginary) .toString (); _root_i [1] = (component_real + "- i" + component_imaginary) .toString (); } //Håndtere reelle røtter annet {var sqrt: Number = Math.sqrt (disc); _root_R [0] = (-_B + sqrt) /(2 * _A); _root_R [1] = (-_B - sqrt) /(2 * _A); }} Ytterligere detaljer EqQuadratic.as: Et eksempel på bruk av denne EqQuadratic.as er i Demo1.as. Etter initiering av EqQuadratic, skal vi bruke den til å beregne røttene. Så, etter å validere tilstedeværelsen av reelle røtter, vil vi bruke dem til å plotte de gule prikkene. Nå røttene refererer til bare \\ (x \\) komponent av koordinatene. For å oppnå de \\ (y \\) s, gjett hva? Igjen, vi legger verdiene av \\ (m \\), \\ (d \\) (beregnet tidligere i trinn 3) og \\ (x \\) (fra røttene) i linjen generell ligning, \\ (y \\ = \\ mx \\ + \\ d \\). Sjekk ut tilsvarende kode på linje 135 og 136. Cubic røtter, ikke overraskende, er skjæringspunktene mellom en kubikk Bildet nedenfor viser en kubisk kurve skjærer med x-aksen. Igjen, her er en liten Flash presentasjon for deg å eksperimentere med. Røde og blå prikker kan dras mens de gule bare angir skjæringspunkter Den generelle formelen for å finne en kubisk kurve ble oppdaget av Cardano. Selv om jeg er forledet til å utdype detaljene, vil jeg bare påpeke interesserte lesere til følgende linker: Uansett, implementerer EqCubic.as klassen denne formelen til å løse røtter kubikk funksjoner sammen med andre matematiske nyttefunksjoner. Vanligvis alle attributtene og metoder for EqCubic.as følge desciption som fremmet i trinn 4, fordi begge klasser EqQuadratic.as og EqCubic.as gjennomføre ett felles grensesnitt, IEquation.as, med unntak av opplysninger som er oppført nedenfor. Her er den Action gjennomføring for Flash presentasjon fra trinn 5. fulle kode er i Demo3.as Igjen, kommanderer Action å tegne en kubisk kurve er nøyaktig det samme som forklart i min forrige artikkel, mens Actionscript-kommandoer til å trekke linjen er allerede forklart i trinn 3 i denne ene . Nå la oss gå videre til å beregne og plassere de kubikkrøtter: Etter Instantiating cubic_equation i konstruktøren vi går videre på å definere sine koeffisienter, beregne røttene, og lagre røttene i en variabel En liten merknad på røttene. Det er maksimalt tre reelle røtter for en kubisk ligning, men ikke alle reelle røtter er til stede i alle situasjon som noen røtter kan være innbilt. Så hva skjer når det er bare én reell rot, for eksempel? Vel, en av rekken av røttene kalles fra cubic_equation.roots_R vil være et reelt tall, mens alle de andre vil være Not a Number (NaN). Sjekk ut det markerte Action for dette Et flott program for beregning røtter projiserer en kollisjonspunktet på buet overflate, som vist nedenfor. Bruk venstre og høyre piltaster for å styre flytte skipet, og trykk opp til å akselerere. Du vil merke at kollisjonspunkter som ville ha skjedd i det siste er litt nedtonet Tanken er lik som i min tutorial om forutsi kollisjonspunkter. Men i stedet for å kollidere med en rett linje, er vi nå bruker en buet biten nedenfor kalles hver ramme. Kjernen koden ligger i å tegne og beregne. La oss først se hva som er i tegning. Det er det samme som vi hadde brukt i tidligere demoer. En liten merknad på tegning linjen. Vi så i tidligere demoer som to prikker for å tegne få ligningen. Vel, her har vi bare ett skip. Så for å få det andre punktet, bare legge skipets hastighet til sin nåværende stilling. Jeg har uthevet koden for bekvemmelighet Nå for Beregn på nytt, jeg har gjort litt vektor beregning for å sjekke om poenget er bak eller foran på skipet. Sjekk ut det markerte kode: En annen stor søknad er ikke fullt så opplagt som den første. For å utføre en mer nøyaktig dueller, i stedet for å basere vår konklusjon på avstanden mellom to objekter, vil vi UAE sin tid til å påvirke Vurdere en kollisjon algoritme som er basert på avstand i to sirkler. Av de fire rammer vist, bare ramme 2,15 hell oppdaget kollisjon mellom to sirkler. Hvorfor? Fordi gjeldende avstanden mellom grå og røde sirkler sentre er mindre enn summen av begge sirklene 'radier. (Readers interesserte på flere detaljer om dette temaet kan du se i denne artikkelen.) Problemet er forårsaket av hvordan Flash provenyet av en diskret bilde om gangen, noe som betyr at det kun rammer 1, 2 og 3 vil bli vellykket fanget, og ikke øyeblikkene i mellom Thos snapshots av gangen. Nå de grå og røde sirkler ikke kolliderer i disse rammene i henhold til en distansebasert beregning, så den røde sirkelen tunneler rett gjennom den grå! For å fikse dette, trenger vi en måte å se kollisjonen som inntraff mellom \\ [if \\ tid \\ til \\ innvirkning, \\ t, \\ oppfyller \\ 0 \\ Spørsmålet er, hvordan kan vi beregne denne gangen I vil prøve å vise min metode så enkelt som mulig. Gitt scenariet ovenfor, er de to grå og røde sirkler for tiden ligger på \\ ((X_ {grå}, \\ y_ {grå}) \\) og \\ ((X_ {red}, \\ y_ {red}) \\). De beveger seg på \\ (V_ {grå} \\) og \\ (V_ {red} \\) henholdsvis, og satt på kollisjons bane. Vi er interessert i å beregne tiden tatt, \\ (t \\), for dem å nå posisjoner \\ ((x '_ {grå}, \\ y' _ {grå}) \\) og \\ ((x '_ {red} \\ y '_ {red}) \\), angitt med gjennomskinnelig grå og røde sirkler, der kollisjonen inntraff. \\ [ Merk at jeg har utledet horisontale og vertikale komponenter av \\ (V_ {grå} \\) til \\ (V_ {gray_x} \\) og \\ (V_ {gray_y} \\). Samme gjelder med hastigheten til den røde sirkelen; sjekk ut denne Quick Tips for å få vite hvordan disse komponentene er utledet. Vi mangler fortsatt en forhold til å binde alle disse ligningene sammen. La oss se på bildet nedenfor. Det andre forholdet går tilbake til Pythagoras. Når begge sirklene møtes, er avstanden mellom de to sentrene nøyaktig \\ (rad_ {grå} \\) pluss \\ (rad_ {red} \\). \\ [ Det er der du erstatte ligninger 1 ~ 4 i ligningen 5. Jeg forstår sin ganske skremmende matematisk, så jeg har skilt den ut i Trinn 13. Føl deg fri til å hoppe over det å komme fram til resultatet ved Trinn 14. Først må vi etablere følgende identiteter. \\ [ På alle tider, husk at alle matematiske symboler representerer en konstant med unntak av tid, \\ (t \\), som er gjenstand for interesse. \\ (X_ {grå}, \\ V_ {gray_x}, \\ y_ {red} \\) og så videre er alle definert i scenariet. Neste, vi skal prøve å bryte vårt problem ned sikt ved term: \\[ Nå på et øyeblikk, kan vi lett se den høyeste makt \\ (t \\) er 2. Så vi har oss selv en kvadratisk likning. La oss samle alle koeffisientene bidratt med disse tre vilkårene i henhold til deres powers. Let's analysere koeffisientene med \\ (t ^ 2 \\) og \\ (t ^ 0 \\). \\ [product: (V_ {gray_x}) ^ 2-2 (V_ {gray_x}) (V_ { red_x}) + (V_ {red_x}) ^ 2, \\ tilbakekalling \\ id. \\ 2 \\\\ plakater (V_ {gray_x}) ^ 2-2 (V_ {gray_x}) (V_ {red_x}) + (V_ {red_x}) ^ 2 = (V_ {gray_x} -v_ {red_x}) ^ 2 Og det av \\ (t \\). \\ [ ,,,0], La oss oppsummere på sikt av \\((x'_{gray}-x'_{red})^2\\) \\[ Merk at dette bare henvender for ett semester i \\ (ekv. \\ 5 \\). Vi må utføre den samme prosessen for en ny periode \\ ((y '_ {grå} y' _ {red}) ^ 2 \\). Siden de har samme algebraiske form, bør den også være resultatet same. Dermed etter omorganisering i form av \\ (t \\), \\ (ekv. \\ 5 \\) bør være så follow. \\[ Så fra forrige trinn, gjennom rigourous algebra vi kommet frem til følgende formula: \\[ Nå er dette en stor kvadratisk formel. Vi skal prøve å gruppere koeffisientene inn som aksepteres av EqQuadratic. Sammenligne de to former: \\ [ Så her er en Flash-presentasjon for å demonstrere ideen. Du vil se to partikler på scenen, en grå og den andre rødt. Begge er forbundet med en pil som angir størrelsen og retningen av hastigheten. For å endre hastigheten av partiklene, trykk:. Til slutt, for å veksle synligheten av pilene, trykk på "V" Det er to røtter til den kvadratiske ligningen. I denne sammenheng er vi interessert i de virkelige røtter. Men hvis de to partiklene ikke er satt på kollisjonsbanen (begge baner er parallelle med hverandre), og imaginære røtter vil bli produsert i stedet for reelle røtter. I dette tilfellet vil både reelle røtter forbli NaN. Hvis begge partikler blir satt på en kollisjonsbane, vil vi få to reelle røtter. Men hva gjør representere disse to røtter? Recall i trinn 12 som vi gjorde brukes av Pythagoras teorem å binde \\ ((x '_ {grå}, \\ y' _ {grå}) \\) og \\ ( (x '_ {red}, \\ y' _ {red}) \\) sammen til en likning. Vel, det er to situasjoner hvor avstanden mellom to sirkler sentre er nøyaktig summen av begge radiene: en før kollisjonen og en etter kollisjon. Ta en titt på dette bildet: Så hvilken velger vi? Tydeligvis det første fordi vi ikke er interessert i forekomsten etter kollisjonen. Så vi bør alltid velge det minste verdien av både røtter og evaluere den. Hvis verdien er positiv og mindre enn 1, vil en kollisjon skje i løpet av neste ramme. Hvis verdien er negativ, kollisjonen skjedde i fortiden La oss se på Action implementert for dette eksemplet. . Først, etter //c1 er variablene den grå sirkelen //c2 er den røde circleprivate Var c1: Circle, c2: Circle; //v1 er den grå sirkelen hastighet //v2 er den røde sirkelen er velocityprivate Var v1: Vector2D, v2: Vector2D, veksle: Boolean = sant, usingV1: Boolean = true; //tri1 vil danne pilspissen av v1 //tri2 vil danne pilspissen av v2private Var tri1: Triangle, tri2: Triangle, private Var container : Sprite, private Var eq: EqQuadratic; Så beregning av røtter. Det kan være lurt å krysse sjekke følgende Action med variablene ovenfor Her er hvordan du skal tolke røttene: Så nå har vi studert kvadratiske og kubiske røtter i Actionscript, samt å ta en nærmere titt på to eksempler på hvordan vi kan bruke den kvadratiske røtter. Takk for at du tok deg tid til å lese denne opplæringen. Har igjen en kommentar hvis du ser andre anvendelser av kvadratiske røtter (eller eventuelle feil!) Anmeldelser
av formelen. Hvis diskriminant er negativ, vil kvadratroten av diskriminant produsere imaginære røtter
, som vi ikke kan plot. Derimot, hvis discriminat er positive, vil du ha reelle tall røtter, og du vil være i stand til å plotte dem inn på skjermen
Trinn 2:. Visualisering Kvadratiske Roots
f (x) \\ = \\ ax ^ 2 + bx + c \\\\
g (x) \\ = \\ 0
\\)
ax ^ 2 \\ + \\ bx + c \\ = \\ mx \\ + \\ d \\\\
ax ^ 2 \\ + \\ (\\ b \\ - m) \\ x + (c \\ - \\ d) \\ = \\ 0
\\]
Trinn 3:. Plotting dette med Action
privat funksjon tegne (): void {var cmd: Vector < int >. = New Vector. ≪ int >; . Var coord: Vector < Number > Antall >;; = new Vector <. //tegne kurve; m1 = nye Matrix3d (curve_points [0] .x * curve_points [0] .x, curve_points [0] .x, 1, 0, curve_points [1] .x * curve_points [1] .x, curve_points [1] .x , 1, 0, curve_points [2] .x * curve_points [2] .x, curve_points [2] .x, 1, 0, 0,0,0,1); m2 = new Matrix3d (curve_points [0] .Y, 0, 0, 0, curve_points [1] .Y, 0, 0, 0, curve_points [2] .Y, 0, 0, 0, 0,0,0, 1) m1.invert (); m2.append (m1); quadratic_equation.define (m2.n11, m2.n21, m2.n31); for (var i: int = 0; i < stage.stageWidth; i + = 2) {if (i == 0) cmd.push (1); annet cmd.push (2); coord.push (i, quadratic_equation.fx_of (i)); } //Uavgjort linje n1 = new Matrix (); n1.a = line_points [0] .x; n1.c = 1; n1.b = line_points [1] .x; n1.d = 1; n2 = new Matrix (); n2.a = line_points [0] .Y; n2.c = 0; n2.b = line_points [1] .Y; n2.d = 0; n1.invert (); n2.concat (n1); var x: Number = stage.stageWidth //y = mx + c cmd.push (1); coord.push (0, n2.a * 0 + n2.b); cmd.push (2); coord.push (x, n2.a * x + n2.b); graphics.clear (); graphics.lineStyle (1); graphics.drawPath (cmd, koord);.}
y \\ = \\ mx \\ + \\ d, \\\\
m \\ = \\ skråning, \\ d \\ = \\ y-skjærings
\\]
y_1 = mx_1 + d \\\\
y_2 = mx_2 + d \\\\ product: [/latex]
\\ begin {bmatrix} y_1 \\\\ y_2 \\ end {bmatrix} =
\\ begin {bmatrix} x_1 & 1 \\\\ x_2 & 1 \\ end {bmatrix}
\\ begin {bmatrix} m \\\\ d \\ end {bmatrix} \\\\ product: [/latex] Hotell
\\ begin {bmatrix} y_1 \\\\ y_2 \\ end {bmatrix} =
\\ begin {bmatrix} x_1 & 1 \\\\ x_2 & 1 \\ end {bmatrix} ^ {- 1}
\\ begin {bmatrix} x_1 & 1 \\\\ x_2 & 1 \\ end {bmatrix}
\\ begin {bmatrix} m \\\\ d \\ end {bmatrix} \\\\ product: [/latex] Hotell
\\ begin {bmatrix} y_1 \\\\ y_2 \\ end {bmatrix} =
jeg
\\ begin {bmatrix} m \\\\ d \\ end {bmatrix} product: [/latex]
Trinn 4:. Beregn Kvadratiske Roots
FunctionTypeInput ParameterFunctionalityEqQuadraticMethodNilClass constructordefineMethodCoefficients a, b og c kvadratisk equationInstantiate koeffisienten valuesfx_ofMethodValue av xReturns \\ (f (x) \\) for gitt \\ (x \\) input.calcRootsMethodNilPerforms beregning for å oppnå kvadratisk rootdiff1Method \\ (x \\) koordinat for første grad differentiationDifferentiated \\ (f (x) \\) av gitt \\ (x \\) ved den første degree.diff2Method \\ (x \\) koordinaten for den andre grad differentiationDifferentiated \\ (f (x) \\) for gitt \\ (x \\) på andre degree.discriminatProperty, lese onlyNilReturns verdien av diskriminant, \\ (b ^ 2 - 4ac \\) roots_RProperty, lese onlyNilReturns et nummer vektor for røttene til reelt tall. Elements er NaN hvis ingen reell røtter exist.roots_iProperty, lese onlyNilReturns en String vektor for røtter av imaginære tall. Elements er null hvis ingen imaginære røtter finnes
Trinn 5:. Plotting dette med Action
privat funksjon recalculate_reposition (): void {quadratic_equation.define (m2.n11, m2.n21 - n2.a, m2.n31 - n2.b); quadratic_equation.calcRoots (); Var røtter. Vector < Number > = Quadratic_equation.roots_R; if (isNaN (røtter [0]) &! &! isNaN (røtter [1])) {intersec_points [0] .x = røtter [0]; intersec_points [0] .Y = n2.a * røtter [0] + n2.b intersec_points [1] .x = røtter [1]; intersec_points [1] .Y = n2.a * røtter [1] + n2.b} else {intersec_points [0] .x = -100; intersec_points [0] .Y = -100; intersec_points [1] .x = -100; intersec_points [1] .Y = -100; }}
Trinn 6: Cubic Roots
kurve og en linje. Men en kubisk kurve er litt annerledes enn en kvadratisk kurve, og i denne sammenheng muligheter der kryss kan være lokalisert er forskjellige
Trinn 7:. Generell formel for Cubic Roots
Wikipedia
Wolfram, og Selge
En annen userful PDF-fil.
FunctionDifferencedefineA total av fire koeffisienter (a, b, c, d) til input for kubisk ligning; bare tre for kvadratisk equation.roots_R, er root_iThe totalt reelle og imaginære røtter tre for en kubisk ligning, men to for en kvadratisk likning
Trinn 8:. Plotting dette med Action
privat funksjon tegne (): void {var cmd:.. Vector < int > = New Vector. ≪ int >; . Var coord: Vector < Number > Antall >;; = new Vector <. //tegne kurve; m1 = nye Matrix3d (curve_points [0] .x * curve_points [0] .x * curve_points [0] .x, curve_points [0] .x * curve_points [0] .x, curve_points [0] .x, 1, curve_points [1] .x * curve_points [1] .x * curve_points [1] .x, curve_points [1] .x * curve_points [1] .x, curve_points [1] .x, 1, curve_points [2] .x * curve_points [2] .x * curve_points [2] .x, curve_points [2] .x * curve_points [2] .x, curve_points [2] .x, 1, curve_points [3] .x * curve_points [3] .x * curve_points [3] .x, curve_points [3] .x * curve_points [3] .x, curve_points [3] .x, 1); m2 = nye Matrix3d (curve_points [0] .Y, 0, 0, 0, curve_points [1] .Y, 0, 0, 0, curve_points [2] .Y, 0, 0, 0, curve_points [3] .Y , 0, 0, 0) m1.invert (); m2.append (m1); cubic_equation.define (m2.n11, m2.n21, m2.n31, m2.n41); for (var i: int = 0; i < stage.stageWidth; i + = 2) {if (i == 0) cmd.push (1); annet cmd.push (2); coord.push (i, cubic_equation.fx_of (i)); } //Uavgjort linje n1 = new Matrix (); n1.a = line_points [0] .x; n1.c = 1; n1.b = line_points [1] .x; n1.d = 1; n2 = new Matrix (); n2.a = line_points [0] .Y; n2.c = 0; n2.b = line_points [1] .Y; n2.d = 0; n1.invert (); n2.concat (n1); var x: Number = stage.stageWidth //y = mx + c cmd.push (1); coord.push (0, n2.a * 0 + n2.b); cmd.push (2); coord.push (x, n2.a * x + n2.b); graphics.clear (); graphics.lineStyle (1); graphics.drawPath (cmd, koord);}
privat funksjon recalculate_reposition (): void {cubic_equation.define (m2.n11, m2.n21, m2.n31 - n2.a, m2.n41 - n2.b); cubic_equation.calcRoots (); Var røtter. Vector < Number > = Cubic_equation.roots_R; for (var i: int = 0; i < roots.length, jeg ++) (! isNaN (røtter [i])) {if {intersec_points [i] .x = røtter [i]; intersec_points [i] .Y = n2.a * røtter [i] + n2.b} else {intersec_points [i] .x = -100; intersec_points [i] .Y = -100; }}}
Trinn 9:. Forutsi hvor et objekt vil kollidere med buet Surface
Trinn 10:. Implementering
linje. La oss sjekke ut koden
Privat funksjon oppdateringen (e: Hendelses): void {//Steering venstre og høyre hvis (kontroll == 1) velo = velo .rotate (Math2.radianOf (-5)); else if (kontroll == 2) velo = velo.rotate (Math2.radianOf (5)); //manipulere hastighet Var currVelo: Number = velo.getMagnitude (); if (økning == 0) {currVelo - = 0,5; currVelo = Math.max (currVelo, 1); //nedre grense for hastighet} else if (økning == 1) {currVelo + = 0,5; currVelo = Math.min (currVelo, 5); //øvre grense for hastighet} velo.setMagnitude (currVelo); //oppdatering hastighet ship.x + = velo.x; ship.y + = velo.y; ship.rotation = Math2.degreeOf (velo.getAngle ()); //reflektere når skipet er ute av scenen if (ship.x < 0 || ship.x > stage.stageWidth) velo.x * = 1; if (ship.y < 0 || ship.y > stage.stageHeight) velo.y * = 1; tegne (); omberegne ();}
privat funksjon tegne (): void {var cmd:.. Vector < int > = New Vector. ≪ int >; . Var coord: Vector < Number > Antall >;; = new Vector <. //tegne kurve; m1 = new Matrix3d (w1.x * w1.x, w1.x, 1, 0, w2.x * w2.x, w2.x, 1, 0, w3.x * w3.x, w3.x, en , 0, 0,0,0,1); m2 = new Matrix3d (w1.y, 0, 0, 0, w2.y, 0, 0, 0, w3.y, 0, 0, 0, 0,0,0,1) m1.invert (); m2.append (m1); quadratic_equation.define (m2.n11, m2.n21, m2.n31); minX = Math.min (w1.x, w2.x, w3.x); maxX = Math.max (w1.x, w2.x, w3.x); for (var i: int = minX; i < maxX; i + = 2) {if (i == minX) cmd.push (1); annet cmd.push (2); coord.push (i, quadratic_equation.fx_of (i)); } N1 = ny Matrix (); n1.a = ship.x; n1.c = 1; n1.b = ship.x + velo.x; n1.d = 1; n2 = new Matrix (); n2.a = ship.y; n2.c = 0; n2.b = ship.y + velo.y; n2.d = 0; n1.invert (); n2.concat (n1); var x: Number = stage.stageWidth //y = mx + c cmd.push (1); coord.push (0, n2.a * 0 + n2.b); cmd.push (2); coord.push (x, n2.a * x + n2.b); graphics.clear (); graphics.lineStyle (1); graphics.drawPath (cmd, koord);}
privat funksjon Beregn på nytt (): void {quadratic_equation.define (m2.n11, m2.n21 - n2.a, m2.n31 - n2.b); quadratic_equation.calcRoots (); Var røtter. Vector < Number > = Quadratic_equation.roots_R; for (var i: int = 0; i < roots.length, jeg ++) {var omplassere: Sprite = getChildByName ("c" + i) som Sprite //betingelser: //reell rot, verdien av x innenfor området dersom (isNaN (røtter [i]) &! & røtter [i] > minX & & røtter [i] < maxX) {reposition.x = røtter [i]; reposition.y = n2.a * røtter [i] + n2.b; //diskriminere mellom fremtid og allerede skjedd kollisjonspunktet Var vec: Vector2D = new Vector2D (reposition.x - ship.x, reposition.y - ship.y); if (velo.dotProduct (vec) < 0) reposition.alpha = 0,4; annet reposition.alpha = 1} else {reposition.x = -100; reposition.y = -100; }}}
Trinn 11: Time-Based Collision Detection
. Hvorfor? Fordi "tunneling" kan skje hvis vi bruker avstand basert dueller:
< p> \\ [avstand \\ mellom \\ sirkler \\
rammer 2 og 3. Vi må beregne tid til å påvirke mellom to sirkler. For eksempel, når vi sjekker den tiden til å påvirke er mindre enn en ramme på ramme 2, dette betyr at når Flash fortsetter 1 bilde fremover kollisjon eller tunneling vil ha definitivt hadde funnet sted.
Trinn 12:? Precalculations
displacement_ {fremtid} = displacement_ {stede} + hastighet * tid \\\\
x '_ {grå} = X_ {grå} + V_ {gray_x} * t \\ ... (ekv. \\ 1) \\\\
y' _ {grå} = y_ {grå} + V_ {gray_y} * t \\ ... (ekv. \\ 2) \\\\
x '_ {red} = X_ {red} + V_ {red_x} * t \\ ... (ekv. \\ 3) \\ \\
y '_ {red} = y_ {red} + V_ {red_y} * t \\ ... (ekv. \\ 4)
\\]
Pythagoras '\\ Theorem, \\ z ^ 2 = x ^ 2 + y ^ 2 \\\\ plakater (rad_ {grå} + rad_ {red}) ^ 2 = (x '_ {grå} -x' _ {red}) ^ 2 + (y '_ { grå} y '_ {red}) ^ 2 \\ ... (ekv. \\ 5) \\\\
\\]
Trinn 13 (valgfritt): Mathematical METODISK NØYAKTIGHET
Identity, \\\\ product: (a + b) ^ 2 = a ^ 2 + 2ab + b ^ 2 \\ ... (id. \\ 1) \\\\ product: (ab) ^ 2 = a ^ 2-2ab + b ^ 2 \\ ... (id. \\ 2) \\\\
\\]
(rad_{gray}+rad_{red})^2=(x'_{gray}-x'_{red})^2+(y'_{gray}-y'_{red})^2\\\\
Consider\\ Begrepet \\ (x '_ {grå} -x' _ {red}) ^ 2 \\ og \\ utnytte \\ id. \\ 2 \\\\ product: (x '_ {grå} -x' _ {red}) ^ 2 = (x '_ {grå}) ^ 2-2 (x' _ {grå}) (x '_ {red}) + (x' _ {red}) ^ 2 \\\\
\\]
\\ [
Tenk \\ term \\ (x '_ {grå}) ^ 2 \\\\ product: (x' _ {grå}) ^ 2 \\\\
= (X_ {grå} + V_ {gray_x} * t) ^ 2, \\ utnytte \\ id. \\ 1 \\\\
= (X_ {grå}) ^ 2 + 2 (X_ {grå}) (V_ {gray_x} * t) + (V_ {gray_x} * t) ^ 2
\\]
\\ [
Tenk \\ term \\ -2(x'_{gray})(x'_{red})\\\\
-2(x'_{gray})(x'_{red})\\\\
=-2(x_{gray}+v_{gray_x}*t)(x_{red}+v_{red_x}*t)\\\\
=-2[(x_{gray})(x_{red})+(x_{gray})(v_{red_x}*t)+(v_{gray_x}*t)(x_{red})+(v_{gray_x}*t)(v_{red_x}*t)]\\\\
=-2(x_{gray})(x_{red})-2(x_{gray})(v_{red_x}*t)-2(v_{gray_x}*t)(x_{red})-2(v_{gray_x}*t)(v_{red_x}*t)
\\]
\\[
Consider\\ Begrepet \\ (x '_ {red}) ^ 2 \\\\ product: (x' _ {red}) ^ 2 \\\\
= (X_ {red} + V_ {red_x} * t) ^ 2, \\ utnytte \\ id. \\ 1 \\\\
= (X_ {red}) ^ 2 + 2 (X_ {red}) (V_ {red_x} * t) + (V_ {red_x} * t) ^ 2
\\]
\\(t^2\\)\\(t\\)\\(t^0=1\\)\\((v_{gray_x})^2\\)\\(2(x_{gray})(v_{gray_x})\\)\\((x_{gray})^2\\)\\(-2(v_{gray_x})(v_{red_x})\\)\\(-2(x_{gray})(v_{red_x})-2(v_{gray_x})(x_{red})\\)\\(-2(x_{gray})(x_{red})\\)\\((v_{red_x})^2\\)\\(2(x_{red})(v_{red_x})\\)\\((x_{red})^2\\)
\\]
\\ [product: (X_ {grå}) ^ 2-2 (X_ {grå}) ( X_ {red}) + (X_ {red}) ^ 2, \\ tilbakekalling \\ id. \\ 2 \\\\ plakater (X_ {grå}) ^ 2-2 (X_ {grå}) (X_ {red}) + (X_ {red}) ^ 2 = (X_ {grå} -x_ {red}) ^ 2
\\]
Simplify \\\\
a = (X_ {grå}), \\ b = (V_ {gray_x}) \\\\
c = (V_ {red_x}), \\ d=(x_{red})\\\\
2ab-2ac-2bd+2dc\\\\
=2[ab-ac-bd+dc]\\\\
=2[a(b-c)-d(b-c)]\\\\
=2[(b-c)(a-d)]\\\\
Resubstitute\\\\
2[(b-c)(a-d)] = 2 (V_ {gray_x} -v_ {red_x}) (X_ {grå} -x_ {red})
\\]
(x'_{gray}-x'_{red})^2\\\\
=(v_{gray_x}-v_{red_x})^2*t^2+2(v_{gray_x}-v_{red_x})(x_{gray}-x_{red})*t + (X_ {grå} -x_ {red}) ^ 2
\\]
\\[
(y'_{gray}-y'_{red})^2\\\\
=(v_{gray_y}-v_{red_y})^2*t^2+2(v_{gray_y}-v_{red_y})(y_{gray}-y_{red})*t + (y_ {grå} -y_ {red}) ^ 2
\\]
(rad_{gray}+rad_{red})^2=(x'_{gray}-x'_{red})^2+(y'_{gray}-y'_{red})^2\\\\
p=v_{gray_x}-v_{red_x}\\\\
q=x_{gray}-x_{red}\\\\
r=v_{gray_y}-v_{red_y}\\\\
s=y_{gray}-y_{red}\\\\
(p^2+r^2)*t^2+2(pq+rs)*t+(q^2+s^2-(rad_{gray}+rad_{red})^2) = 0
\\]
Trinn 14: Resultat
p=v_{gray_x}-v_{red_x}\\\\
q=x_{gray}-x_{red}\\\\
r=v_{gray_y}-v_{red_y}\\\\
s=y_{gray}-y_{red}\\\\
(p^2+r^2)*t^2+2(pq+rs)*t+(q^2+s^2-(rad_{gray}+rad_{red})^2) = 0
\\]
ax ^ 2 + bx + c = 0 \\\\ product: (p ^ 2 + r ^ 2) * t ^ 2 + 2 (pq + rs) * t + (q ^ 2 + s ^ 2- (rad_ {grå} + rad_ {red}) ^ 2) = 0 \\\\
a = p ^ 2 + r ^ 2) \\\\
b = 2 (PQ + rs) \\\\
c = (q ^ 2 + s ^ 2- (rad_ {grå} + rad_ {red}) ^ 2)
\\]
Step 15: Prøve Implementering
Klikk på "Next" for å gå opp ett bilde i tid.
Klikk på "Tilbake" -knappen for å gå tilbake ett bilde i tid
"Up" og "ned" for å øke og redusere hastigheten magnitude, hhv.
"Venstre" og "rett" til å rotere hastighet.
"N" for å bytte hvilken sirkel du styrer
Trinn 16.: Et notat på kvadratisk Roots
Trinn 17:. Den Action Forklart
Var p: Number = v1.x - v2.x, Div. Spørsmål: Number = c1.x - c2.x, var r: Number = v1. y - v2.y; Var s: Number = c1.y - c2.y, Var en: Number = p * p + r * r; Var b: Number = 2 * (p * q + r * s); Var c: Number = q * q + s * s - (c1.radius + c2.radius) * (c1.radius + c2.radius); eq.define (a, b, c), eq.calcRoots (); Var . røttene: Vector < Number > = Eq.roots_R;
//hvis ingen reelle røtter er tilgjengelige, så de er på ikke er på kollisjons pathif (isNaN (røtter [0]) & & isNaN ( røtter [1])) {t.text = ". partikler som ikke er på kollisjons banen"} else {var tid: Number = Math.min (røtter [0], røtter [1]) Var int_time: int = tid * tusen; time = int_time /1000; t.text = "Rammer til å påvirke:" + time.toString () + "\\ n"; if (tid > 1) t.appendText ("Partikler er avsluttende ...") else if (tid > 0 & & tid < 1) t.appendText ("partikler vil kollidere neste ramme!") else if (tid < 0) t.appendText ("Collision hadde allerede skjedd.");}
Konklusjon