Vecteurs euclidiens en flash

Deux fois par mois, nous relisons certaines des publications favorites de nos lecteurs dans Activetuts + history. Le didacticiel rétro-actif de cette semaine, publié pour la première fois en avril, est un guide des vecteurs euclidiens: leur nature, leur utilisation, et leur implémentation en Flash avec AS3.

Les vecteurs euclidiens sont des objets en géométrie avec certaines propriétés qui sont très utiles pour développer des jeux. Ils peuvent être vus comme des points, mais ils ont aussi une magnitude et une direction. Elles sont représentées par des flèches allant du point initial au point final, et nous allons les dessiner dans cet article..

Les vecteurs euclidiens sont couramment utilisés en mathématiques et en physique pour un grand nombre de choses: ils peuvent représenter la vitesse, l'accélération et les forces en physique, ou aider à prouver de nombreux théorèmes importants en mathématiques. Dans ce tutoriel, vous allez apprendre à connaître les vecteurs euclidiens et à construire une classe que vous pourrez utiliser dans vos propres projets Flash..

Veuillez noter que les vecteurs euclidiens sont différents de la classe Vector d'ActionScript et également différents du dessin vectoriel..

Les vecteurs peuvent être utilisés dans l'environnement Flash pour vous aider à réaliser des tâches complexes qui, autrement, demanderaient beaucoup d'efforts si elles étaient effectuées sans eux. Dans cet article, vous apprendrez à les utiliser en Flash, ainsi qu’à apprendre beaucoup de trucs sympas avec des vecteurs.


Étape 1: Coordonnées cartésiennes et coordonnées de Flash

Avant de sauter dans les vecteurs, introduisons le système de coordonnées de Flash. Vous connaissez probablement le système de coordonnées cartésien (même si vous ne le connaissez pas par son nom):

Le système de Flash est très similaire. La seule différence est que l'axe des ordonnées est à l'envers:

Lorsque nous commençons à travailler avec des vecteurs en flash, nous devons nous en souvenir. Cependant, bonne nouvelle: ce système différent ne fait pas beaucoup de différence. Travailler avec des vecteurs dedans sera fondamentalement comme travailler avec des vecteurs dans le système cartésien.


Étape 2: Définir un vecteur

Pour les besoins de ce didacticiel, nous allons définir et utiliser les points initiaux de tous les vecteurs comme étant le point d’enregistrement de la scène, comme ils sont couramment utilisés en mathématiques. Un vecteur sera alors défini comme un point commun, mais il aura des propriétés de magnitude et d’angle. Jetez un coup d’œil à quelques exemples de vecteurs définis dans la scène:

Comme vous pouvez le constater, un vecteur est représenté par une flèche et chaque vecteur a une certaine longueur (ou ordre de grandeur) et pointe le long d'un certain angle. La queue de chaque vecteur est au point d'enregistrement (0, 0).

Nous allons créer une classe EuclideanVector simple pour ce tutoriel, en utilisant la classe Point pour contenir les coordonnées du vecteur. Créons maintenant la classe de vecteur de base:

 package import flash.geom.Point; public class EuclideanVector public var position: Point; public var magnitude: Number; angle var public: Nombre; fonction publique EuclideanVector (endPoint: Point) position = endPoint; 

Au cours de ce tutoriel, nous parlerons de la sens et le direction d'un vecteur. Notez que la direction définit simplement une ligne qui "contient" le vecteur. Le sens est ce qui définit le sens du vecteur le long de cette ligne.


Étape 3: Inverse d'un vecteur

Dans ce tutoriel, nous utiliserons l'expression "inverse d'un vecteur". L'inverse d'un vecteur est un autre vecteur de même amplitude et direction, mais ayant un sens contraire. Cela se traduit par un vecteur avec le signal opposé aux coordonnées du premier vecteur. Donc, un vecteur avec un point final de (x, y) aurait un vecteur inverse avec un point final de (-x, -y).

Ajoutons une fonction à notre classe EuclideanVector pour renvoyer le vecteur inverse:

 fonction publique inverse (): EuclideanVector retourne un nouveau EuclideanVector (nouveau Point (-position.x, -position.y)); 

Étape 4: Ajout d'opérations de base

Maintenant que nous avons appris à définir un vecteur, apprenons à ajouter deux vecteurs: il suffit d’ajouter leurs coordonnées séparément. Regardez cette image:

Si vous remarquez dans l'image, le résultat de l'ajout de deux vecteurs est un autre vecteur et vous pouvez voir que ses coordonnées sont la somme des coordonnées des deux autres vecteurs. En code, cela ressemblerait à ceci:

 fonction publique sum (otherVector: EuclideanVector): EuclideanVector position.x + = otherVector.position.x; position.y + = otherVector.position.y; retournez ceci; 

On peut donc dire que:

 vecR == vec1.sum (vec2);

Étape 5: Opérations de base Soustraction

La soustraction fonctionne presque comme l’addition, mais nous ajouterons le inverse du second vecteur au premier vecteur.

On sait déjà comment additionner deux vecteurs, voici donc le code de soustraction:

 fonction publique soustraire (otherVector: EuclideanVector): EuclideanVector position.x - = otherVector.position.x; position.y - = otherVector.position.y; retournez ceci; 

Ce code est extrêmement utile pour obtenir un vecteur qui va du point d’un vecteur à un autre. Regardez encore l'image et vous verrez que c'est vrai. Il sera beaucoup utilisé dans les derniers exemples.


Étape 6: Opérations de base Multiplication par un nombre

La multiplication entre un vecteur et un nombre (les nombres normaux sont appelés "scalaires" en mathématiques vectorielles) donne un vecteur dont la magnitude a été multipliée par ce nombre, mais qui pointe toujours dans la même direction; il est "étiré" si le scalaire est supérieur à 1 et écrasé si le scalaire est compris entre 0 et 1. Le sens du nouveau vecteur sera le même que celui du vecteur d'origine si le scalaire est positif, ou l'inverse s'il est négatif. Fondamentalement, ce nombre "met à l'échelle" le vecteur. Regarde l'image:

Dans le code, nous ne multiplions que les coordonnées d'un vecteur par le nombre, ce qui redimensionnera ensuite le vecteur:

 fonction publique multiplier (nombre: nombre): EuclideanVector position.x * = nombre; position.y * = nombre; retournez ceci; 

Étape 7: Obtenir la magnitude d'un vecteur

Afin d'obtenir la magnitude d'un vecteur, nous allons utiliser le théorème de Pythagore. Si vous avez oublié de quoi il s'agit, voici un bref rappel:

(Plus d'infos ici.)

Le code est très simple:

 fonction publique magnitude (): Number return Math.sqrt ((position.x * position.x) + (position.y * position.y)); 

Vous devriez également supprimer la ligne public var magnitude: Number, comme c'est ce que nous allons utiliser à partir de maintenant.

La magnitude d'un vecteur sera toujours positive, car c'est la racine carrée de la somme de deux nombres positifs.


Étape 8: Obtenir l'angle d'un vecteur

L'angle d'un vecteur est l'angle entre l'axe des x et la ligne directrice du vecteur. L'angle est mesuré en partant de l'axe des x et en tournant dans le sens inverse des aiguilles d'une montre jusqu'à la ligne directrice dans le système cartésien:

Cependant, dans le système de coordonnées de Flash, l'axe des y étant orienté à l'envers, cet angle est mesuré en rotation dans le sens des aiguilles d'une montre:

Ceci peut être facilement calculé en utilisant le code suivant. L'angle sera renvoyé en radians, dans une plage allant de 0 à 2pi. Si vous ne savez pas ce que sont les radians ni comment les utiliser, ce tutoriel de Michael James Williams vous aidera beaucoup.

 fonction publique angle (): Number var angle: Number = Math.atan2 (position.y, position.x); si (angle < 0)  angle += Math.PI * 2;  return angle; 

Étape 9: Produit ponctuel

Le produit scalaire entre deux vecteurs est un nombre apparemment vide de sens, mais il a deux utilisations utiles. Voyons d'abord comment le produit scalaire peut être calculé:

Mais il peut aussi être obtenu par les coordonnées de chaque vecteur:

Le produit scalaire peut nous en dire beaucoup sur l'angle entre les vecteurs: s'il est positif, l'angle varie de 0 à 90 degrés. Si c'est négatif, l'angle va de 90 à 180 degrés. Si c'est zéro, l'angle est de 90 degrés. Cela se produit car, dans la première formule, seul le cosinus est chargé de donner un "signal" au produit scalaire: les grandeurs sont toujours positives. Mais nous savons qu'un cosinus positif signifie que l'angle varie de 0 à 90 degrés, et ainsi de suite pour les cosinus négatifs et zéro.

Le produit scalaire peut également être utilisé pour représenter la longueur d'un vecteur dans la direction de l'autre vecteur. Pensez-y comme une projection. Cela s'avère extrêmement utile dans des domaines comme le SAT (Separation of Axis Theorem) et son implémentation dans AS3 pour la détection de collision et la réponse dans les jeux..

Voici le code pratique pour obtenir le produit scalaire entre deux vecteurs:

 fonction publique point (otherVector: EuclideanVector): Number return (position.x * autreVector.position.x) + (position.y * autreVector.position.y); 

Étape 10: Plus petit angle entre les vecteurs

L'angle entre les vecteurs, comme indiqué à l'étape 9, peut être donné par le produit scalaire. Voici comment le calculer:

 fonction publique angleBetween (otherVector: EuclideanVector): Number return Math.acos (dot (otherVector) / / magnitude () * otherVector.magnitude ())); 

Étape 11: Angle à distance entre les vecteurs

Il existe également un autre moyen de calculer l'angle, qui donne des résultats entre -pi et pi et calcule toujours l'angle qui va du premier vecteur au deuxième vecteur; Ceci est utile lorsque vous souhaitez intégrer facilement la rotation d'un objet d'affichage (qui va de -180 à 180)..

La méthode fonctionne en obtenant l'angle des deux vecteurs, puis en soustrayant les angles et en travaillant sur le résultat..

Le code:

 fonction publique rangedAngleBetween (otherVector: EuclideanVector): Number var firstAngle: Number; var secondAngle: Number; angle var: nombre; firstAngle = Math.atan2 (otherVector.position.y, otherVector.position.x); secondAngle = Math.atan2 (position.y, position.x); angle = secondAngle - firstAngle; while (angle> Math.PI) angle - = Math.PI * 2; tandis que (angle < -Math.PI) angle += Math.PI * 2; return angle; 

Notez que cet angle est positif si secondAngle est plus élevé que premierAngle, de sorte que l'ordre dans lequel vous obtenez l'angle à distance affectera le résultat!


Étape 12: normaliser un vecteur

Normaliser un vecteur signifie que sa magnitude soit égale à 1, tout en préservant la direction et le sens du vecteur. Pour ce faire, nous multiplions le vecteur par 1 / magnitude. De cette façon, son ampleur sera réduite ou augmentée à 1.

 fonction publique normalize (): EuclideanVector var m: Number = magnitude (); position.x / = m; position.y / = m; retournez ceci; 

Étape 13: Obtenir la normale d'un vecteur

le Ordinaire d’un vecteur est un autre vecteur qui fait un angle de 90 degrés avec le premier. Il peut être calculé avec les formules suivantes:

Les formules reposent sur le fait que, puisque la normale est toujours perpendiculaire à un vecteur, il suffit de changer l’ordre des coordonnées x et y et d’en inverser une pour obtenir une normale. L'image suivante montre le processus:

Dans l'image, Vec est le vecteur d'origine, Vec2 est le vecteur avec Vecest échangé des coordonnées, et Vec3 est un vecteur avec Vec2La coordonnée y est négative. Ang et Ang2 sont variables, mais l'angle entre Vec et Vec3 est toujours à 90 degrés.

Et le code est simple

 public function normalRight (): EuclideanVector retourne un nouveau EuclideanVector (nouveau Point (-position.y, position.x));  public function normalLeft (): EuclideanVector retourne un nouveau EuclideanVector (nouveau Point (position.y, -position.x)); 

Étape 14: Rotation d'un vecteur

Pour faire pivoter un vecteur, nous supposons que la position (0, 0) (son point initial) sera le centre de rotation. Le point pivoté est donné par la formule:

Cette formule est obtenue en appliquant une matrice de rotation à ce vecteur. Nous irions au-delà de la portée de ce didacticiel si nous examinions la matrice et son fonctionnement. Je vais donc laisser la formule ici..

Le code est à peu près le même:

 fonction publique rotation (angleInRadians: Number): EuclideanVector var newPosX: Number = (position.x * Math.cos (angleInRadians)) - - (position.y * Math.sin (angleInRadians)); var newPosY: Number = (position.x * Math.sin (angleInRadians)) + (position.y * Math.cos (angleInRadians)); position.x = newPosX; position.y = newPosY; retournez ceci; 

C'est la fin de nos opérations vectorielles de base. Vous verrez ensuite comment utiliser cette classe pour faire des choses intéressantes. Voici notre cours jusqu'à présent:

 package import flash.geom.Point; public class EuclideanVector public var position: Point; angle var public: Nombre; fonction publique EuclideanVector (endPoint: Point) position = endPoint;  fonction publique inverse (): EuclideanVector retour new EuclideanVector (new Point (nouveauPosition (xposition.x, -position.y)));  public function sum (otherVector: EuclideanVector): EuclideanVector position.x + = otherVector.position.x; position.y + = otherVector.position.y; retournez ceci;  fonction publique soustraction (otherVector: EuclideanVector): EuclideanVector position.x - = otherVector.position.x; position.y - = otherVector.position.y; retournez ceci;  fonction publique multiplier (nombre: nombre): EuclideanVector position.x * = nombre; position.y * = nombre; retournez ceci;  fonction publique magnitude (): Number return Math.sqrt ((position.x * position.x) + (position.y * position.y));  fonction publique angle (): Number var angle: Number = Math.atan2 (position.y, position.x); si (angle < 0)  angle += Math.PI * 2;  return angle;  public function dot(otherVector:EuclideanVector):Number  return (position.x * otherVector.position.x) + (position.y * otherVector.position.y);  public function angleBetween(otherVector:EuclideanVector):Number  return Math.acos(dot(otherVector) / (magnitude() * otherVector.magnitude()));  public function rangedAngleBetween(otherVector:EuclideanVector):Number  var firstAngle:Number; var secondAngle:Number; var angle:Number; firstAngle = Math.atan2(otherVector.position.y, otherVector.position.x); secondAngle = Math.atan2(position.y, position.x); angle = secondAngle - firstAngle; while (angle > Math.PI) angle - = Math.PI * 2; tandis que (angle < -Math.PI) angle += Math.PI * 2; return angle;  public function normalize():EuclideanVector  position.x /= magnitude(); position.y /= magnitude(); return this;  public function normalRight():EuclideanVector  return new EuclideanVector(new Point(-position.y, position.x));  public function normalLeft():EuclideanVector  return new EuclideanVector(new Point(position.y, -position.x));  public function rotate(angleInRadians:Number):EuclideanVector  var newPosX:Number = (position.x * Math.cos(angleInRadians)) - (position.y * Math.sin(angleInRadians)); var newPosY:Number = (position.x * Math.sin(angleInRadians)) + (position.y * Math.cos(angleInRadians)); position.x = newPosX; position.y = newPosY; return this;   

OK, nous avons couvert la construction de la classe de vecteurs, prenons maintenant une prise pour l'utiliser.


Étape 15: Déterminer si un point est à l'intérieur d'un polygone

L'action commence ici. Déterminer si un point se trouve ou non dans un polygone est un sujet très intéressant, et il existe de nombreuses méthodes pour le réaliser. Dans cet article, je présenterai les trois méthodes généralement utilisées:

  • le numéro de passage ou algorithme de règle pair-impair, qui détermine si un point est à l'intérieur d'un polygone à partir du nombre d'arêtes qu'un rayon traverse d'un point à l'infini.
  • le algorithme du nombre d'enroulement, qui donne la réponse basée sur la somme de tous les angles formés entre les sommets consécutifs d'un polygone et le point à vérifier.
  • le algorithme de polygone convexe, qui, comme son nom l'indique, ne fonctionne que pour les polygones convexes et est basé sur le fait qu'un point se trouve ou non sur un certain "côté" de chaque bord du polygone.

Tous ces algorithmes reposent sur le fait que vous connaissez les coordonnées des sommets (coins) qui définissent le polygone.


Étape 16: Algorithme de numéro de croisement ou de règle pair-impair

Cet algorithme peut être utilisé pour n'importe quelle forme. Voici ce que vous lisez: n'importe quelle forme, qu'elle soit perforée ou non, qu'elle soit convexe ou non. Il est basé sur le fait que tout rayon lancé du point que vous souhaitez vérifier à l'infini traversera un nombre pair d'arêtes si le point se trouve en dehors de la forme, ou un nombre impair d'arêtes si le point se trouve à l'intérieur de la forme. Cela peut être prouvé par le théorème de la courbe de Jordan, ce qui implique que vous devrez traverser une frontière entre certaines régions pour pouvoir passer d’une région à l’autre. Dans notre cas, nos régions sont "dans la forme" et "hors de la forme".

Le code de cet algorithme est le suivant:

 fonction publique isPointInsideShape1 (point: EuclideanVector, shapeVertices: Vector.): Boolean var numberOfSides: int = shapeVertices.length; var i: int = 0; var j: int = numberOfSides - 1; var oddNodes: Boolean = false; alors que je < numberOfSides)  if ((shapeVertices[i].position.y < point.position.y && shapeVertices[j].position.y >= point.position.y) || (shapeVertices [j] .position.y < point.position.y && shapeVertices[i].position.y >= point.position.y)) if (shapeVertices [i] .position.x + (((point.position.y - shapeVertices [i] .position.y) / / shapeVertices [j] .position.y - shapeVertices [i] .position.y)) * (shapeVertices [j] .position.x - shapeVertices [i] .position.x)) < point.position.x)  oddNodes = !oddNodes;   j = i; i++;  return oddNodes; 

Il reviendra faux si le point n'est pas à l'intérieur de la forme, ou vrai si le point est à l'intérieur de la forme.


Étape 17: L'algorithme du nombre d'enroulement

le algorithme du nombre d'enroulement utilisez la somme de tous les angles faits entre le point à vérifier et chaque paire de points définissant le polygone. Si la somme est proche de 2pi, le point en cours de vérification se trouve à l'intérieur du vecteur. S'il est proche de 0 alors le point est en dehors.

 fonction publique isPointInsideShape2 (point: EuclideanVector, shapeVertices: Vector.): Boolean var numberOfSides: int = shapeVertices.length; var i: int = 0; angle var: Nombre = 0; var rawAngle: Number = 0; var firstVector: EuclideanVector; var secondVector: EuclideanVector; alors que je < numberOfSides)  firstVector = new EuclideanVector(new Point(shapeVertices[i].position.x - point.position.x, shapeVertices[i].position.y - point.position.y)); secondVector = new EuclideanVector(new Point(shapeVertices[(i + 1) % numberOfSides].position.x - point.position.x, shapeVertices[(i + 1) % numberOfSides].position.y - point.position.y)); angle += secondVector.rangedAngleBetween(firstVector); i++;  if(Math.abs(angle) < Math.PI) return false; else return true; 

Le code utilise l'angle à distance entre les vecteurs et laisse de la place pour les imprécisions: remarquez comment nous vérifions les résultats de la somme de tous les angles. Nous ne vérifions pas si l'angle est exactement nul ou 2pi. Au lieu de cela, nous vérifions si elle est inférieure à pi et supérieure à pi, une valeur médiane considérable.


Étape 18: L'algorithme de polygone concave

le algorithme de polygone concave repose sur le fait que, pour un polygone concave, un point à l'intérieur se trouve toujours à gauche des arêtes (si nous les parcourons dans le sens inverse des aiguilles d'une montre) ou à droite des arêtes (si nous parcourons dans le sens des aiguilles d'une montre).

Imaginez-vous debout dans une pièce ayant la forme de l'image ci-dessus et marchant sur ses bords avec votre main gauche traînant le long du mur. Au point le long du mur où vous vous trouvez le plus près du point qui vous intéresse, s'il est à votre droite, il doit se trouver à l'intérieur de la pièce; si c'est sur votre gauche alors il doit être à l'extérieur.

Le problème consiste à déterminer si un point se trouve à gauche ou à droite d'un bord (qui est essentiellement un vecteur). Ceci est fait par la formule suivante:

Cette formule renvoie un nombre inférieur à 0 pour les points situés à droite du bord et supérieur à 0 pour les points situés à gauche. Si le nombre est égal à 0, le point se trouve sur le bord et est considéré à l'intérieur de la forme. Le code est le suivant:

 fonction publique isPointInsideShape3 (point: EuclideanVector, shapeVertices: Vector.): Boolean var numberOfSides: int = shapeVertices.length; var i: int = 0; var firstEdgePoint: EuclideanVector; var secondEdgePoint: EuclideanVector; var leftOrRightSide: Boolean; alors que je < numberOfSides)  firstEdgePoint = shapeVertices[i]; secondEdgePoint = shapeVertices[(i + 1) % numberOfSides]; if(i == 0)  // Determining if the point is to the left or to the right of first edge // true for left, false for right leftOrRightSide = ((point.position.y - firstEdgePoint.position.y) * (secondEdgePoint.position.x - firstEdgePoint.position.x)) - ((point.position.x - firstEdgePoint.position.x) * (secondEdgePoint.position.y - firstEdgePoint.position.y)) > 0;  else // Tous les bords doivent maintenant se trouver du même côté si (leftOrRightSide && ((point.position.y - firstEdgePoint.position.y) *) (secondEdgePoint.position.x - firstEdgePoint.position.x)) - ( point.position.x - firstEdgePoint.position.x) * (secondEdgePoint.position.y - firstEdgePoint.position.y)) < 0)  // Not all edges are on the same side! return false;  else if(!leftOrRightSide && ((point.position.y - firstEdgePoint.position.y) * (secondEdgePoint.position.x - firstEdgePoint.position.x)) - ((point.position.x - firstEdgePoint.position.x) * (secondEdgePoint.position.y - firstEdgePoint.position.y)) > 0) // Tous les bords ne sont pas du même côté! retourne faux;  i ++;  // Nous avons parcouru tous les sommets et n'avons pas détecté les différents côtés qui retournent la valeur true; 

Ce code fonctionne que vous ayez défini les sommets de la forme dans le sens des aiguilles d'une montre ou dans le sens inverse..


Étape 19: Ray casting

Le lancer de rayons est une technique souvent utilisée pour la détection et le rendu des collisions. Il consiste en un rayon qui est projeté d'un point à un autre (ou à l'infini). Ce rayon est constitué de points ou de vecteurs et s’arrête généralement quand il frappe un objet ou le bord de l’écran. De la même manière que les algorithmes de point-en-forme, il existe de nombreuses manières de lancer des rayons, et nous en verrons deux dans ce post:

  • L'algorithme de ligne de Bresenham, qui est un moyen très rapide de déterminer des points rapprochés qui donneraient une approximation d'une ligne entre eux.
  • La méthode DDA (Digital Differential Analyzer), également utilisée pour créer une ligne.

Dans les deux prochaines étapes, nous examinerons les deux méthodes. Après cela, nous verrons comment faire en sorte que notre rayon s’arrête quand il frappe un objet. Ceci est très utile lorsque vous devez détecter une collision avec des objets se déplaçant rapidement..


Étape 20: l'algorithme de ligne de Bresenham

Cet algorithme est très souvent utilisé en infographie et dépend de la convention selon laquelle la ligne sera toujours créée pointant vers la droite et vers le bas. (Si une ligne doit être créée en haut et à gauche, tout est inversé par la suite.) Entrons dans le code:

 Fonction publique createLineBresenham (startVector: EuclideanVector, endVector: EuclideanVector): Vector. points var: vecteur. = nouveau vecteur.(); var steep: Boolean = Math.abs (endVector.position.y - startVector.position.y)> Math.abs (endVector.position.x - startVector.position.x); var échangé: Boolean = false; if (raide) startVector = new EuclideanVector (new Point (startVector.position.y, startVector.position.x)); endVector = new EuclideanVector (new Point (endVector.position.y, endVector.position.x));  // Faire descendre la ligne si (startVector.position.x> endVector.position.x) var temporaire: Number = startVector.position.x; startVector.position.x = endVector.position.x; endVector.position.x = temporaire; temporaire = startVector.position.y; startVector.position.y = endVector.position.y endVector.position.y = temporaire; permuté = vrai;  var deltaX: Number = endVector.position.x - startVector.position.x; var deltaY: Number = Math.abs (endVector.position.y - startVector.position.y); erreur var: Number = deltaX / 2; var currentY: Number = startVector.position.y; var step: int; si (startVector.position.y < endVector.position.y)  step = 1;  else  step = -1;  var iterator:int = startVector.position.x; while (iterator < endVector.position.x)  if (steep)  points.push(new EuclideanVector(new Point(currentY, iterator)));  else  points.push(new EuclideanVector(new Point(iterator, currentY)));  error -= deltaY; if (error < 0)  currentY += step; error += deltaX;  iterator++;  if (swapped)  points.reverse();  return points; 

Le code produira un vecteur AS3 de vecteurs euclidiens qui feront la ligne. Avec ce vecteur, nous pouvons plus tard vérifier les collisions.


Étape 21: La méthode DDA

Une mise en œuvre de la Analyseur différentiel numérique est utilisé pour interpoler des variables entre deux points. Contrairement à l'algorithme de ligne de Bresenham, cette méthode ne créera que des vecteurs avec des positions entières par souci de simplicité. Voici le code:

 Fonction publique createLineDDA (startVector: EuclideanVector, endVector: EuclideanVector): Vector. points var: vecteur. = nouveau vecteur.(); var dx: nombre; var dy: nombre; var _x: Number = startPoint.position.x; var _y: Number = startPoint.position.y; var m: nombre; var i: int; dx = endPoint.position.x - startPoint.position.x; dy = endPoint.position.y - startPoint.position.y; if (Math.abs (dx)> = Math.abs (dy)) m = Math.abs (dx); sinon m = Math.abs (dy); points.push (nouveau EuclideanVector (nouveau Point (int (_x), int (_y))))); i = 1; alors que je <= m)  _x += dx / m; _y += dy / m; points.push(new EuclideanVector(new Point(int(_x), int(_y)))); i++;  return points; 

Ce code renverra également un vecteur AS3 de vecteurs euclidiens.


Étape 22: Vérification des collisions à l'aide de rayons

Vérifier les collisions par rayons est très simple. Comme un rayon est composé de plusieurs vecteurs, nous vérifierons les collisions entre chaque vecteur et une forme jusqu'à ce que l'un soit détecté ou que la fin du rayon soit atteinte. Dans le code suivant, forme pour vérifier sera une forme semblable à celles que nous avons utilisées aux étapes 13 à 16. Voici le code:

 fonction publique checkRayCollision (ray: Vector., forme: vecteur.): Boolean var rayLength: int = ray.length; var i: int = 0; alors que je < rayLength)  if(isPointInsideShape1(ray[i], shape))  return true;  i++;  return false; 

Vous pouvez utiliser n'importe quelle fonction point-dedans-forme avec laquelle vous vous sentez à l'aise, mais faites attention aux limites de la dernière.!


Conclusion

Vous êtes prêt à utiliser cette connaissance partout maintenant! Cela vous sera utile plusieurs fois et vous évitera beaucoup de calculs supplémentaires lorsque vous tenterez de faire des tâches plus complexes dans Flash..