Matematisk og Action av Curves: Roots

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

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:

\\ (
f (x) \\ = \\ ax ^ 2 + bx + c \\\\
g (x) \\ = \\ 0
\\)

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.

\\ [
ax ^ 2 \\ + \\ bx + c \\ = \\ mx \\ + \\ d \\\\
ax ^ 2 \\ + \\ (\\ b \\ - m) \\ x + (c \\ - \\ d) \\ = \\ 0
\\]

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



Trinn 3:. Plotting dette med Action

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:
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);.}

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:

\\ [
y \\ = \\ mx \\ + \\ d, \\\\
m \\ = \\ skråning, \\ d \\ = \\ y-skjærings
\\]

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]
y_1 = mx_1 + d \\\\
y_2 = mx_2 + d \\\\ product: [/latex]


[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


[latex] Anmeldelser \\ begin {bmatrix} x_1 & 1 \\\\ x_2 & 1 \\ end {bmatrix} ^ {- 1}
\\ 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


[latex] Anmeldelser \\ begin {bmatrix} x_1 & 1 \\\\ x_2 & 1 \\ end {bmatrix} ^ {- 1}
\\ begin {bmatrix} y_1 \\\\ y_2 \\ end {bmatrix} =
jeg
\\ begin {bmatrix} m \\\\ d \\ end {bmatrix} product: [/latex]


(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



Trinn 4:. Beregn Kvadratiske Roots

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

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

Cubic røtter, ikke overraskende, er skjæringspunktene mellom en kubikk
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

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



Trinn 7:. Generell formel for Cubic Roots

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:

Wikipedia

Wolfram, og Selge
En annen userful PDF-fil.

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

Her er den Action gjennomføring for Flash presentasjon fra trinn 5. fulle kode er i Demo3.as
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);}

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:
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; }}}

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



Trinn 9:. Forutsi hvor et objekt vil kollidere med buet Surface

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



Trinn 10:. Implementering

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
linje. La oss sjekke ut koden

biten nedenfor kalles hver ramme.
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 ();}

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
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);}

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

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
. Hvorfor? Fordi "tunneling" kan skje hvis vi bruker avstand basert dueller:

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.)
< p> \\ [avstand \\ mellom \\ sirkler \\

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

\\ [if \\ tid \\ til \\ innvirkning, \\ t, \\ oppfyller \\ 0 \\

Spørsmålet er, hvordan kan vi beregne denne gangen



Trinn 12:? Precalculations

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.

\\ [
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)
\\]

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} \\).

\\ [
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) \\\\
\\]

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.



Trinn 13 (valgfritt): Mathematical METODISK NØYAKTIGHET

Først må vi etablere følgende identiteter.

\\ [
Identity, \\\\ product: (a + b) ^ 2 = a ^ 2 + 2ab + b ^ 2 \\ ... (id. \\ 1) \\\\ product: (ab) ^ 2 = a ^ 2-2ab + b ^ 2 \\ ... (id. \\ 2) \\\\
\\]

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:

\\[
(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
\\]

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.
\\(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\\)

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
\\]
\\ [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
\\]

Og det av \\ (t \\).

\\ [ ,,,0],
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})
\\]

La oss oppsummere på sikt av \\((x'_{gray}-x'_{red})^2\\)

\\[
(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
\\]

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.
\\[
(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
\\]

Dermed etter omorganisering i form av \\ (t \\), \\ (ekv. \\ 5 \\) bør være så follow.

\\[
(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

Så fra forrige trinn, gjennom rigourous algebra vi kommet frem til følgende formula:

\\[
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
\\]

Nå er dette en stor kvadratisk formel. Vi skal prøve å gruppere koeffisientene inn som aksepteres av EqQuadratic. Sammenligne de to former:

\\ [
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

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.

Klikk på "Next" for å gå opp ett bilde i tid.

Klikk på "Tilbake" -knappen for å gå tilbake ett bilde i tid

For å endre hastigheten av partiklene, trykk:.

"Up" og "ned" for å øke og redusere hastigheten magnitude, hhv.

"Venstre" og "rett" til å rotere hastighet.

"N" for å bytte hvilken sirkel du styrer

Til slutt, for å veksle synligheten av pilene, trykk på "V"



Trinn 16.: Et notat på kvadratisk Roots

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



Trinn 17:. Den Action Forklart

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

Her er hvordan du skal tolke røttene:
//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

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