Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

Goniometrie: Hoek van reflectie op X/Y as

Pagina: 1
Acties:

  • Gamebuster
  • Registratie: Juli 2007
  • Laatst online: 23-10 08:50
JavaScript:
1
2
3
4
5
SomeThing.prototype.updateBall = function(delta) {
    this.ball.x += delta / 1000 * this.ball.speed * Math.cos(this.ball.angle);
    this.ball.y += delta / 1000 * this.ball.speed * Math.sin(this.ball.angle);
    // ???
};


Ik heb een balletje genaamd this.ball met de (enigszins vanzelfsprekende) eigenschappen x, y, speed en angle. Dit balletje verplaatst zich binnen een vierkante "kamer" van x -1 tot 1 en y -1 tot 1. Ik wil dat als het balletje één van de muren raakt (aka zijn x/y coords vallen buiten -1 en 1) de bal "afkaatst": De hoek moet dan veranderen in een gespiegelde versie ten opzichte van de muur die-ie geraakt heeft.

Ik zoek een makkelijke manier om de hoek na het afkaatsen te berekenen.

Ik heb zelf ongeveer deze berekening bedacht: (voor het gemak in graden ipv radians)
JavaScript:
1
2
3
4
5
// `angle` is bijv. 80, waarbij de bal snel omhoog en lichtelijk naar rechts verplaatst
var TOP_WALL_ANGLE = 270; // de hoek haaks op de bovenste muur
var mirroredAngle = (angle + 180) % 360; // 260
var angleDifference = TOP_WALL_ANGLE - mirroredAngle;
var newAngle = mirroredAngle + angleDifference * 2;


Alleen zou ik deze berekening dan voor alle 4 "muren" apart moeten maken. Ik twijfel sterk of dit niet makkelijker kan, dus daarom vraag ik het hier.

Let op: Mijn post bevat meningen, aannames of onwaarheden


  • epic007
  • Registratie: Februari 2004
  • Laatst online: 17-11 15:31
Je zou speed als vector kunnen definiëren:

JavaScript:
1
2
3
4
5
6
7
speed.x = 0.06
speed.y = 0.12

// of

speed.x = speed * Math.cos(angle)
speed.y = speed * Math.sin(angle)


update
JavaScript:
1
2
x += delta / 1000 * speed.x
y += delta / 1000 * speed.y



en de check voor muren:
JavaScript:
1
2
if ( x < -1.0 || x > 1.0 ) speed.x = -speed.x;
if ( y < -1.0 || y > 1.0 ) speed.y = -speed.y;

[ Voor 25% gewijzigd door epic007 op 12-02-2013 21:33 ]


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Kort:
For a given incident vector I and surface normal N reflect returns the reflection direction calculated as:

I - 2.0 * dot(N, I) * N.

(N should be normalized in order to achieve the desired result.)
Langer:

Stel je hebt een inkomende vector I, en een normaal van een vlak N, en je wilt I in N reflecteren (hoek van inval is hoek van uitval)

Dan is dot(N, I) de geprojecteerde lengte op de normaal, de vector in de richting van de normaal is dan dot(N,I)*N, twee keer dat spiegelt in het vlak waar de normaal loodrecht op staat, die 1x van I aftrekken geeft een punt op het vlak, die nog een keer daarvan aftrekken geeft de gespiegeld vector. Dus: I - 2*dot(N, I) * N.

Afbeeldingslocatie: http://www.cs.uaf.edu/2006/fall/cs381/lecture/10_03_specular/reflect.png

'e' als fractie van 'N' is hier dot(N,L). 'e' als vector is dot(N,L)*N en dat dan twee keer van de 'negative L' aftrekken geeft de reflectie R.

[ Voor 64% gewijzigd door Zoijar op 12-02-2013 22:29 ]


  • TJHeuvel
  • Registratie: Mei 2008
  • Niet online
Is het niet mogelijk om geen "angle" bij te houden, maar een velocity vector. Deze kan je gewoon omdraaien.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
var pos = { x : 0, y : 0 };
var vel = { x : 0, y : 0 };

function update()
{
 var newPos = { x : pos.x + vel.x, y : pos.y + vel.y };

 if(newPos.y < 0 || newPos.y > Screen.Height) //outside bounds
   vel.y = -vel.y;

 pos = newPos;

}


Edit: Ah, wat Epic007 zegt idd

[ Voor 4% gewijzigd door TJHeuvel op 12-02-2013 23:56 ]

Freelance Unity3D developer


Verwijderd

Inderdaad: definieer een snelheid en beweging als vectoren in de X, y en eventuele Z as.

Ik ben ooit dagen bezig geweest om balletjes met elkaar te laten botsen op de natuurkundige manier met sinusen en cosinussen, totdat ik me opeens de formule voor de refractie van licht herinnerde en het geheel opschreef in enkele regels.

Zorg er wel voor dat je op de juiste plaats eenheidsvectoren gebruikt. Dat is een vector met een lengte van 1.

  • Gamebuster
  • Registratie: Juli 2007
  • Laatst online: 23-10 08:50
Het is inderdaad geen slecht idee om gewoon de snelheid bij te houden in vorm van x/y ipv speed/angle. Dat maakt het inderdaad wat makkelijker :)

Bedankt :)
Verwijderd schreef op woensdag 13 februari 2013 @ 00:11:
Zorg er wel voor dat je op de juiste plaats eenheidsvectoren gebruikt. Dat is een vector met een lengte van 1.
Ik heb geen idee wat dit betekend.

Let op: Mijn post bevat meningen, aannames of onwaarheden


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Maakt ook niet uit. Het is een volstrekt loze opmerking. Natuurkundig bestaan ze niet eens. Een vector met lengte 1 is gelijk aan een vector met lengte 100 (meter en centimeter respectievelijk)

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

MSalters schreef op woensdag 13 februari 2013 @ 14:04:
Maakt ook niet uit. Het is een volstrekt loze opmerking. Natuurkundig bestaan ze niet eens. Een vector met lengte 1 is gelijk aan een vector met lengte 100 (meter en centimeter respectievelijk)
Alleen moet je wel anders schalen. Zo geeft het inproduct van twee vectoren van 100cm bijvoorbeeld niet de cosinus van de hoek tussen de twee, daar dat bij twee vectoren van 1m wel zo is.

Verwijderd

Zeer handig (gratis) boek over physics en programmeertalen: http://natureofcode.com/

De eerste paar pagina's van chapter 1 geven een uitleg hoe je dit het best kunt doen.

  • SaphuA
  • Registratie: September 2005
  • Laatst online: 02-11 19:58
.

[ Voor 99% gewijzigd door SaphuA op 31-01-2022 15:01 ]


  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Afhankelijk van je delta-time van je simulatie, moet je ook nog rekening houden met tijd.
Als ie kort genoeg is (je hebt genoeg frames/seconde) dan kan je gewoon je snelheid vector spiegelen in de muren.

Zoijar geeft de makkelijkste optie. Dat natuurkundigen vectoren misschien geen lengte "hebben" is echt 100% niet van toepassing op computer-simulaties. Persoonlijk vind ik vectoren echt veel beter te begrijpen dan hoeken in ruimtelijke situaties (en bij de onderliggende berekeningen hoef je niet telkens om te rekenen met goniometrische functies).

-niks-


  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
MSalters schreef op woensdag 13 februari 2013 @ 14:04:
Maakt ook niet uit. Het is een volstrekt loze opmerking. Natuurkundig bestaan ze niet eens. Een vector met lengte 1 is gelijk aan een vector met lengte 100 (meter en centimeter respectievelijk)
Euh, nee. Een eenheidsvector heeft geen eenheden (of eenheid 1, hoe je het ook wilt definiëren). Het gaat er juist om dat je je eenheden er uitdeelt, zodat Afbeeldingslocatie: http://upload.wikimedia.org/math/f/f/2/ff2f7b1c77aeb2c1569c3f414e48d213.png. v-hat is een eenheidsvector (eenheden 1), |v| is een scalar (eenheid meter, of cm, whatever), en die geven samen een vector v (met dezelfde eenheden).
Zoijar schreef op woensdag 13 februari 2013 @ 15:34:
Alleen moet je wel anders schalen. Zo geeft het inproduct van twee vectoren van 100cm bijvoorbeeld niet de cosinus van de hoek tussen de twee, daar dat bij twee vectoren van 1m wel zo is.
Nee. Het inproduct van twee vectoren van 100cm is (cos θ) (100 cm)², en het inproduct van twee vectoren van 1m is (cos θ) (1 m)². Dat (cos θ)(1 m)² als je alles in eenheden van meters opslaat toevallig getalsmatig hetzelfde is als cos θ betekent nog niet je het als hetzelfde moet behandelen.

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

ValHallASW schreef op zaterdag 16 februari 2013 @ 09:59:
Nee. Het inproduct van twee vectoren van 100cm is (cos θ) (100 cm)², en het inproduct van twee vectoren van 1m is (cos θ) (1 m)². Dat (cos θ)(1 m)² als je alles in eenheden van meters opslaat toevallig getalsmatig hetzelfde is als cos θ betekent nog niet je het als hetzelfde moet behandelen.
Dus omdat het hetzelfde is... moeten we het vooral niet als hetzelfde behandelen? ;) Ik kan je vertellen dat zo'n beetje elk spel dat je ooit gespeeld hebt dat wel doet :)

Wat een zinloze discussie dit verder; echt zeuren om het zeuren... ja, ik heb ook wiskunde gestudeerd en werk al iets van 15 jaar aan 3d code... ik weet wel wat een vector is... (maakt het ook lekker makkelijk voor de TS zo; net of het heel ingewikkeld is)

[ Voor 4% gewijzigd door Zoijar op 16-02-2013 12:07 ]


  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
Zoijar schreef op zaterdag 16 februari 2013 @ 12:05:
Dus omdat het hetzelfde is... moeten we het vooral niet als hetzelfde behandelen? ;) Ik kan je vertellen dat zo'n beetje elk spel dat je ooit gespeeld hebt dat wel doet :)
Dat lijkt me sterk, want je voorbeeld werkt alleen maar als beide vectoren precies lengte '1' (in welke eenheden je ook gebruikt) zijn. Als je een hoek wilt berekeken dan moet je /altijd/ de lengte er eerst uitschalen (waardoor je dus het inproduct tussen twee eenheidsvectoren berekent, wat inderdaad cos θ geeft).
Zoijar schreef op zaterdag 16 februari 2013 @ 12:05:
Wat een zinloze discussie dit verder; echt zeuren om het zeuren... ja, ik heb ook wiskunde gestudeerd en werk al iets van 15 jaar aan 3d code... ik weet wel wat een vector is... (maakt het ook lekker makkelijk voor de TS zo; net of het heel ingewikkeld is)
Dat ben ik niet met je eens. Je opmerking is een beetje te vergelijken met iemand die niets van encodings snapt vertellen 'gewoon altijd utf-8-functies gebruiken'. Dat zal vaak goed gaan, maar je verliest wel alle sanity checks ('heb je bytes of character? als het bytes zijn, in welke encoding staan je characters dan?' vs 'wat zijn je eenheden?').

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

ValHallASW schreef op zaterdag 16 februari 2013 @ 14:24:
Dat lijkt me sterk, want je voorbeeld werkt alleen maar als beide vectoren precies lengte '1' (in welke eenheden je ook gebruikt) zijn. Als je een hoek wilt berekeken dan moet je /altijd/ de lengte er eerst uitschalen (waardoor je dus het inproduct tussen twee eenheidsvectoren berekent, wat inderdaad cos θ geeft).
Ja, en daarom staat er ook " (N should be normalized in order to achieve the desired result.)" en zegt Darkstone " Zorg er wel voor dat je op de juiste plaats eenheidsvectoren gebruikt. Dat is een vector met een lengte van 1." Waarna er een vreemde discussie ontstaat over eenheidsvectoren bestaan niet oid en dingen met eenheden eruit schalen :S

In de computer graphics is het heel normaal (heh-heh) dat je weet dat bepaalde vectoren altijd lengte 1 hebben (1 'wat' maakt echt helemaal niets uit.) Je hoeft dan als optimalisatie dus niet /altijd/ te schalen maar slechts een keer. Het is een beetje zonde om steeds door 1 te delen. En richtingsvectoren worden doorgaans als eenheidsvectoren opgeslagen in software.

Ik ben het ook niet helemaal eens met je stelling over "eenheden eruit schalen", dat een vector altijd een richting is en een enkele scalaire eenheid. Doe dat bv maar eens bij een rgb kleur. De richting in RGB space zegt niets, en de lengte van je RGB vector ook niet heel veel. Ja, je kan een vector zo representeren (elke vorm van drie gecombineerde vrijheidsgraden werkt) maar het hoeft niet zinnig te zijn. Kijk ook bv naar support vector machines waar je met vectoren rekent die compleet andere grootheden en eenheden hebben in de verschillende dimensies.
Pagina: 1