Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Autres questions


Index du Forum » Autres questions » Les espaces 3D (coder)
Disperseur Hors ligne Membre Points: 1830 Défis: 1 Message

Les espaces 3D (coder)

Posté le 13/02/2017 19:18

Bonjour,
Je suis disperseur, cela fait un petit bout de temps que je me suis intéressé à la programmation et comme tout programmeur je me suis penché sur la question de la 3D. J'ai récemment commencer un petit programme en 3D (voir SEE 3D sur planete casio dans la rubrique projets pour graph35+ )(simple couloir à visualiser sous tous les angles ou presque ) et je me demandais comment on pouvais coder une pièce en 3D sachant qu'il faut penser à chaque posibilité d'angle de vues (+que 9 dans une pièce de 3x3...). Est ce qu'il n'y aurai pas une alternative à coder tous ces côtés par exemple avec une ou des matrices...?
Si quelqu'un a une bonne idée pour cela est ce qu'il pourrait m'en faire part. ..?! Svp

Salut.
DISPERSEUR


Dark storm En ligne Labélisateur Points: 11631 Défis: 176 Message

Citer : Posté le 04/12/2017 10:20 | #


Alors juste. La liste de points dans l'espace, faut jamais y toucher x)
Tu l'exploite, mais jamais n'écris dessus. Donc tu créé une liste qui contient 0 si les points sont derrière l'écran, et si tu bouge tu la recréé en fonction
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Disperseur Hors ligne Membre Points: 1830 Défis: 1 Message

Citer : Posté le 04/12/2017 10:49 | #


Excuse, je ne voyais pas comme ça.. j'y réfléchis ok Merci !
Disperseur Hors ligne Membre Points: 1830 Défis: 1 Message

Citer : Posté le 07/12/2017 18:43 | # | Fichier joint


Voila, j'ai modifié le programme et je vous le met en lien. Si quelqu'un peut me dire ce qu'il en pense s.v.p...

PS: là, j'affiche une pièce qui comporte donc un peut beaucoup de points pour ce moteur donc ça rame un peut...si vous voulez, pour tester, je peut remettre l'affichage de base : une plateforme. Et a la fin du programme il y a une autre version de l'algorithme d'affichage. Il permet juste de choisir le type d'affichage (dot, ...).
Zezombye Hors ligne Rédacteur Points: 1756 Défis: 13 Message

Citer : Posté le 07/12/2017 18:56 | #


D'après ce que je vois, au lieu de déplacer la caméra, tu déplaces toute la map. Certes ça fait le même effet, mais déplacer la map est très long (ce qui explique le lag).

A l'avenir poste ton code dans ton message (dans un spoiler) comme ça on n'a pas à DL le fichier joint
Divers jeux : Puissance 4 - Chariot Wars - Sokoban
Ecrivez vos programmes basic sur PC avec BIDE
Disperseur Hors ligne Membre Points: 1830 Défis: 1 Message

Citer : Posté le 07/12/2017 19:09 | #


Oui, je le mets..la prochaine fois

Mais c'était LephénixNoir qui me disait plus tôt dans ce topic que je ne devais pas déplacer la vision mais plutôt la map..(si je ne me trompe pas..)


Ninestars Hors ligne Membre Points: 2461 Défis: 24 Message

Citer : Posté le 07/12/2017 20:32 | #


Salut, cette question à fait l'objet de beaucoup de fantaisie autour de GTA. Comme quoi c'était le monde qui se déplacait sous les pieds du personnages et non l'inverse
En vérité, les deux sont tout à fait justes. Dans ton calcul de projection, tu dois soustraire aux coordonnées des points celle de la caméra.
Concrètement : x' = (x_objet - x_camera) / z et y' = (y_objet - y_camera) / z

Ensuite la question vient de comment gérer cette différence objet-camera...
Vaut-il mieux incrémenter toutes les coordonées des points où modifier les coordonées (uniques) de la camera ?
La réponse va de soit ! La caméra, encore faut-il que les coordonnées de la caméra soient pris en compte dans la projection des points
Désolé si ça te rajoute un calcul en plus et ralenti... Mais tu auras encore d'autres surprises je te l'assure, j'ai du vécu avec Windmill

Ps : stp, "je peux" avec un x
Lephenixnoir En ligne Administrateur Points: 24146 Défis: 170 Message

Citer : Posté le 08/12/2017 06:14 | #


Le principe est de toute façon de calculer un mouvement relatif entre la caméra et la map. Conceptuellement, je crois plus intéressant de se figurer qu'on déplace la map pour comprendre le principe. Dans l'implémentation, les deux sont pareils ; evidemment il faut déplacer les coordonnées de la caméra en mémoire. (Je n'ai jamais envisagé le contraire)
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Disperseur Hors ligne Membre Points: 1830 Défis: 1 Message

Citer : Posté le 09/12/2017 08:18 | #


Merci pour ces deux reponses,
mais il me semble que c'est ce que je fais dans mon programme (cf mon programme a télécharger deux messages plus haut). J'aurais aimé le mettre dans ce message mais je suis sur mon phone...
Zezombye Hors ligne Rédacteur Points: 1756 Défis: 13 Message

Citer : Posté le 09/12/2017 08:43 | #


Code
Cliquer pour enrouler
#Program name: 3D-1~MOT
#Password: <no password>


{ - 5, 5, 5, -5, -5, -5, -5, -5, -5, -5, -5, 5, 5, -5, 5, 5, 5, 5, 5, 5} -> List 1
{ - 2, -2, 2, 2, -2, -2, -2, -2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -2, 2, 2} -> List 2
{1, 1, 1, 1, 1, 3, 3, 5, 5, 1, 5, 5, 5, 5, 5, 3, 3, 1, 1, 5} -> List 3

List 3 -> List 4
For 1 -> P To Dim List 4
    If List 4[P] < 0 :Then
        0 -> List 4[P]
    IfEnd
Next
0 -> A~Z
S-L-Normal
BG-None
AxesOff
GridOff
CoordOn
G-Connect
S-WindMan
ViewWindow -2, 2, 1, -2, 2, 1, 1, Dim List 1, 1
BG-None
Lbl 1
Graph(X,Y)=(List 1[T] / List 4[T], List 2[T] / List 4[T])
Do
    Text 1, 1, List 3[1
    Text 10, 1, List 4[1
    For 1 -> P To Dim List 3
        If List 3[P] < 0 :Then
            0 -> List 4[P]
        IfEnd
        If List 3[P] > 0 :Then
            List 3[P] -> List 4[P]
        IfEnd
    Next
    If GetKey = 78 :Then
        
        For 1 -> P To Dim List 3
            List 3[P] - 1 -> List 3[P
        Next
        Cls
        Goto 1
    IfEnd
    If GetKey = 77 :Then
        
        For 1 -> P To Dim List 3
            List 3[P] + 1 -> List 3[P
        Next
        Cls
        Goto 1
    IfEnd
    If GetKey = 27 :Then
        
        For 1 -> P To Dim List 1
            List 1[P] - 1 -> List 1[P
        Next
        Cls
        Goto 1
    IfEnd
    If GetKey = 38 :Then
        
        For 1 -> P To Dim List 1
            List 1[P] + 1 -> List 1[P
        Next
        Cls
        Goto 1
    IfEnd
    If GetKey = 28 :Then
        
        For 1 -> P To Dim List 2
            List 2[P] - 1 -> List 2[P
        Next
        Cls
        Goto 1
    IfEnd
    If GetKey = 37 :Then
        
        For 1 -> P To Dim List 2
            List 2[P] + 1 -> List 2[P
        Next
        Cls
        Goto 1
    IfEnd
LpWhile GetKey != 47
Stop
For 1 -> P To Dim List 1 - 1
    F-Line List 1[P] / List 3[P], List 2[P] / List 3[P], List 1[P + 1] / List 3[P + 1], List 2[P + 1] / List 3[P + 1]
Next


Et par exemple, le
If GetKey = 38 :Then
        
        For 1 -> P To Dim List 1
            List 1[P] + 1 -> List 1[P
        Next
        Cls
        Goto 1
    IfEnd

incrémente la liste 1, donc déplace la map.
Divers jeux : Puissance 4 - Chariot Wars - Sokoban
Ecrivez vos programmes basic sur PC avec BIDE
Disperseur Hors ligne Membre Points: 1830 Défis: 1 Message

Citer : Posté le 09/12/2017 08:52 | #


Eh bien, c'est ce que l'on disait non.. ? je deplace la map (conseillé par LephenixNoir)
Lephenixnoir En ligne Administrateur Points: 24146 Défis: 170 Message

Citer : Posté le 09/12/2017 09:00 | #


N'oublie pas que ce que tu fais en fin de compte c'est ramener chaque point du monde sur la caméra en lui soustrayant les coordonnées de la caméra. Cependant, ce calcul n'est nécessaire qu'au moment de faire ta transformation (essentiellement des rotations) et tu le fais point par point. Tu ne déplaces pas toute la map d'un coup.

Surtout, au moment où tu ramènes le point à transformer sur la caméra (en lui soustrayant les coordonnées de la caméra), tu peux te convaincre que le résultat de la soustraction dépend de façon symétrique du point à bouger et de la position de la caméra. Tout effet obtenu en changeant les coordonnées du point peut être obtenu aussi en changeant (de façon opposée) la position de la caméra.

Pour résumer, ta map ne bouge pas, dans le sens où ton grand tableau de points est toujours le même. Par contre, à chaque fois que tu veux faire le rendu d'un point à l'écran, tu fais divers calculs dessus, et entre autres tu soustrais les coordonnées de la caméra, ce qui a pour effet philosophique de déplacer le point. Mais tu ne le fais que pour un seul point à la fois (conceptuellement). Et une fois que le rendu est fini, tu oublies le calcul et tu reviens à ta map d'origine.
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Disperseur Hors ligne Membre Points: 1830 Défis: 1 Message

Citer : Posté le 09/12/2017 09:06 | #


Tu m'excuse mais je n'ai pas tout suivit, je mets de matrices du coup... c'est pas clair..

(je fais de mon mieux pour comprendre)

Ajouté le 09/12/2017 à 09:13 :
moi j'ai utilisé la fonction d'affichage graph(x,y)=() je peut la garder..?
Lephenixnoir En ligne Administrateur Points: 24146 Défis: 170 Message

Citer : Posté le 09/12/2017 09:15 | #


Voici le processus conceptuel du rendu : (Parfois des optimisations pourront faire que ton programme ne procède pas exactement comme ça, mais philosophiquement il faut que tu penses de cette manière.)

1. Tu possèdes un monde fixe, dont les coordonnées sont dans un repère absolu et ne changent jamais.
2. Pour chaque point du monde :
3. Calculer les coordonnées de ce point dans le repère défini par la caméra.
4. Projeter le point transformé sur l'écran.
5. Dessiner le point/la ligne/etc.

Maintenant, où se produit le fait de « déplacer le monde » dont il est question depuis un moment ? C'est à l'étape 3. Car le centre du nouveau repère (c'est-à-dire la caméra) a toutes les chances de ne pas être au centre de l'ancien repère (qui est un point précis de la map, toujours le même, de coordonnées (0, 0, 0) dans le repère absolu).

Or les transformations matricielles (quand on parle de matrices 3 × 3) ne marchent que si les centres sont au même endroit. Il faut des notions d'algèbre linéaire pour l'expliquer complètement, mais imagine-toi qu'une matrice c'est comme une fonction linéaire (f(x) = ax) : ça transforme toujours le 0 en 0 donc le centre ne peut pas bouger tout seul. Il faut donc le déplacer nous-même. (NB. Les matrices 4 × 4 intègrent cette notion de déplacer le centre, c'est pour ça qu'on les utilise.)

Le déplacement du centre, au moment où on soustrait les coordonnées de la caméra donc, ne se produit que lorsqu'on veut transformer un point du repère absolu vers le repère de la caméra. C'est un calcul intermédiaire qu'on oublie très vite. Surtout que, dès que le joueur aura bougé, le calcul sera à refaire de zéro. Ça ne sert donc à rien de mémoriser le résultat, et en particulier ça ne sert à rien de le stocker dans la liste des points du monde. Au frame suivant, tu veux que le repère absolu soit toujours le même, donc il ne faut pas modifier les coordonnées des points dans les listes.

Edit : Pour le rendu à l'écran tu es libre de faire ce que tu veux. Par contre si tu veux faire du Super DrawStat il faut calculer tous les points puis afficher tous les points au lieu de calculer/afficher/calculer/afficher. Mais tu peux.
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Disperseur Hors ligne Membre Points: 1830 Défis: 1 Message

Citer : Posté le 09/12/2017 09:28 | #


Mais par rapport à mon programme, je vois pas trop la différence :
Je calcule les points en même temps de les afficher.. j'y pense.. comment je peut utiliser mon monde en m'y déplaçant sans modifier les points qui sont enregistrés dans mes 3listes ? Je pourrais utiliser les fonctions mais après je vois pas trop comment je peux afficher mes points après..? Et puis je ne m'imagine même pas à quoi pourrait ressembler une fonction qui modifierais mes points pour l'affichage..
Lephenixnoir En ligne Administrateur Points: 24146 Défis: 170 Message

Citer : Posté le 09/12/2017 09:54 | #


comment je peut utiliser mon monde en m'y déplaçant sans modifier les points qui sont enregistrés dans mes 3listes ?

Les calculs de l'étape 3 dépendent de la position de la caméra. Si le joueur bouge, le résultat change.

Et puis je ne m'imagine même pas à quoi pourrait ressembler une fonction qui modifierais mes points pour l'affichage..

Des matrices et des projections, bien sûr. On en a parlé pendant plusieurs pages !
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Disperseur Hors ligne Membre Points: 1830 Défis: 1 Message

Citer : Posté le 09/12/2017 12:37 | #


J'ai relu ces pages...

Il y a un modèle sur lequel on construit ces propres matrices de transformation des coordonnées (par exemple pour incrémenter sur l'axe des abscisses) ..? Parce que la seule chose que je sais la dessus c'est qu'il faut quelquepart dans ces matrices des 0 et des 1 pour les multiplications. Et ce n'est pas suffisant pour que je puisse les faire moi même...
Lephenixnoir En ligne Administrateur Points: 24146 Défis: 170 Message

Citer : Posté le 09/12/2017 15:07 | #


Ouais, il y a un modèle ! C'est l'algèbre linéaire en fait, mais ça te prendrait de longues heures de maths pour apprendre à les construire toi-même si tu ne connais pas ce domaine.

Après il n'y a pas beaucoup de matrices à employer. Je pense que deux te suffiront pour la plupart de tes opérations. Ce sont des matrices de rotation qui « compensent » des rotations du monde pour le redresser. Pour rappel, on sait afficher facilement un monde quand on en est le centre, quand on regarde devant nous et qu'on a la tête à l'horizontale. Ces transformations ramènent le monde à une position naturelle depuis une position exotique.

En gros tu as besoin de faire les opérations suivantes pour effectuer la transformation d'un point :
1. Soustraire à ton point les coordonnées de la caméra (translation)
2. Lui appliquer la matrice de rotation verticale qui fixe sa position verticale
3. Lui appliquer la matrice de rotation horizontale qui fixe sa position horizontale

C'est tout ! Ensuite tu peux le projeter sur l'écran en divisant deux des coordonnées par la troisième. Les matrices dont il est question sont données dans mon message #149033 deux pages en arrière.

Allons-y progressivement pour les explications. J'ai mentionné tout à l'heure que les matrices 3D ne peuvent pas faire translater les points d'un espace à trois dimensions. Comme elles ne le peuvent pas, on utilise des matrices 4D. Les matrices 4D ne peuvent pas faire translater les points d'un espace à quatre dimensions, par contre elles peuvent le faire dans un espace à trois dimensions. La quatrième colonne et la quatrième ligne représentant la quatrième dimension qui permet de faire les translations.

Comme tu peux le voir, la matrice de translation utilise la quatrième colonne pour effectuer la translation. Les autres ont leurs quatrièmes ligne et colonne « neutres » : elles ne font que tourner le monde autour de son centre. Ce sont, philosophiquement, des matrices 3D qu'on a juste un peu agrandies.

La deuxième matrice est une matrice de rotation, qui tourne autour de la verticale. Elle compense le fait que la caméra regarde le monde à un angle horizontal θ au lieu de regarder dans une direction fixe (par exemple le Nord). La troisième est une autre matrice de rotation, qui tourne autour d'un axe horizontal. Elle compense le fait que la caméra regarde le monde à un angle vertical φ au lieu de regarder dans une direction fixe (par exemple l'horizon).

So far so good? Tu n'as pas besoin d'autres matrices. Tout ce que tu as à faire c'est sortir de ton programmes les paramètres (xc, yc, zc) (position de la caméra), θ (angle horizontal) et φ (angle vertical), et calculer les matrices en utilisant les formules dans mon message.

La suite du message explique comment t'en servir, mais assez brièvement. Pour transformer un point de ton repère absolu vers le repère de la caméra, tu dois d'abord créer un vecteur à quatre coordonnées (parce qu'on fait nos calculs en 4D !) qui représente le point. Le point (x, y, z) s'écrira sous la forme d'une matrice colonne de coefficients (de haut en bas) x, y, z et 1. Ensuite, en multipliant une des matrices précédentes par le vecteur (dans ce sens !), tu appliqueras la transformation indiquée par la matrice sur le vecteur.

Tu dois appliquer trois transformations : translation, rotation verticale, rotation horizontale. L'ordre dans lequel tu fais les rotations n'est pas important, mais tu dois faire la translation en premier. Ton calcul va donc ressembler à:

Mt : matrice de translation
Mθ : matrice de rotation horizontale
Mφ : matrice de rotation verticale
xa : point de l'espace dans le repère absolu
xc : transformé de xa dans le repère de la caméra
cx = Mφ × (Mθ × (Mt × xa))
cx = (Mφ × Mθ × Mt) × xa

Comme tu peux le voir sur la première ligne cx = ..., on calcule d'abord Mt × xa pour effectuer la translation, puis Mθ × (...) pour appliquer la rotation horizontale au résultat, puis encore Mφ × (...) pour appliquer la rotation verticale. On enchaîne les trois transformations, en somme. Ce qui est pratique, c'est que le produit de matrices est associatif, donc ça donne le même résultat que si on multiplie d'abord les trois matrices entre elles et qu'on applique le résultat au vecteur. Mφ × Mθ × Mt est une matrice qui effectue les trois transformations d'un coup !

Un petit coup de résumé pour conclure. Comment se passe le rendu d'un monde quand la caméra est à la position (xc, yc, zc) et orientée horizontalement de θ, verticalement de φ ?

1. On calcule Mt, et en utilisant les formules que j'ai données
2. On calcule M = Mφ × Mθ × Mt comme ça on aura moins de multiplications à faire plus tard
3. Pour chaque point de l'espace, donné par ses coordonnées absolues (qui ne changent jamais) :
4. On crée un vecteur xa représentant ce point dans l'espace à quatre dimensions
5. On calcule xc = M × xa le vecteur représentant ce point dans le repère de la caméra
6. On projette xc sur l'écran en divisant deux de ses coordonnées par la troisième
7. On affiche le point avec PlotOn ou n'importe quelle méthode appropriée

N'hésite pas à poser des questions sur les vieux messages s'il y a des choses que tu n'as pas comprises.
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Disperseur Hors ligne Membre Points: 1830 Défis: 1 Message

Citer : Posté le 10/12/2017 08:19 | #


Super explications ! maerci...
il y a quand même un point qui m'embète :
quand tu me parle du repere a 4 coordonnées.. comment on peut représenter ça dans un programme ? Moi pour mon repere j'ai utilisé le WiewWindow.. comment on peut faire du coup pour ces 4 coordonnées ?
Lephenixnoir En ligne Administrateur Points: 24146 Défis: 170 Message

Citer : Posté le 10/12/2017 09:04 | #


Ah ben ViewWindow c'est pas une bonne idée ! Rappelle-toi que c'est un paramètre sensible de l'écran. Toi tu fais des calculs, tu n'affiches rien tant que tu n'es pas arrivé au bout.

Pour représenter des vecteyrs en 4D, on utilise des matrices d'une colonne et quatre lignes. Pour représenter des transformations en 4D, on utilise... des matrices carrées 4×4

Petit goût de déjà vu ?
Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Disperseur Hors ligne Membre Points: 1830 Défis: 1 Message

Citer : Posté le 10/12/2017 09:36 | #


Ok mais j'ai refais un programme en utilisant les matrices mais dans ton ancien post sur les rotations tu me parle de points xc,yc,zc, et ue tu les mets dans une matrice (celle qui ramène le centre du monde à l'endroit où se trouve la camera), ces trois points (plus le 1) ils correspondent à mon vecteur... Ou a autrès chose ?
Lephenixnoir En ligne Administrateur Points: 24146 Défis: 170 Message

Citer : Posté le 10/12/2017 09:38 | #


Il y a deux indices qui te montrent que ça ne peut pas être les coordonnées de ton point !

2. On calcule M = Mφ × Mθ × Mt comme ça on aura moins de multiplications à faire plus tard
3. Pour chaque point de l'espace [...]

Si je peux calculer M avant de commencer à boucler, c'est que M est la même pour tous les points.

Et :

On définit les matrices correspondant aux trois transformations à appliquer pour passer du repère absolu au repère de la caméra, située en (xc, yc, zc), orientée de θ par rapport à l'horizontale et φ par rapport à la verticale [...]

Mon graphe (24 Mars): (gint#27 ; (Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 114 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd