2013-02-26 6 views
1

J'essaie de tracer des points 3D sur une surface 2D (je travaille actuellement avec SDL.NET comme «moteur de jeu»). La surface aura une taille de 800x400 pixels et les coordonnées 3d vont de -4000 à 4000. Mon point de vue sera toujours une vue de haut en bas et il n'y aura aucun mouvement de caméra. Quelqu'un pourrait-il fournir un C# natif, un pseudo-code ou une explication simple pour convertir les coordonnées de l'espace 3D en surface 2D?Conversion de points 3D à 2D

Pendant ce temps Im commande this book que les gens me disent qu'il abordera beaucoup de mes lacunes en mathématiques .... :) espérons-

+0

sont vos coordonnées 3D tout -4000 à 4000? Voulez-vous afficher la carte entière sur la grille 800x400 ou est-ce une fenêtre mobile? –

+0

Je viens juste de convertir une coordonnée 3D en une surface 2D et je voudrais partager mon approche car elle varie de manière significative par rapport aux réponses ci-dessous. Mes compétences en mathématiques ne sont pas les meilleures, donc je crois que ma solution, bien que simpliste, pourrait aider quelqu'un à comprendre cette conversion (en utilisant des maths de 10e année.) – CramerTV

Répondre

8

NOTE: Ce est un grand mur de texte et je glaçure complètement sur beaucoup de choses importantes - mais mon intention est ici juste une vue d'ensemble ... je espère que certains des termes/concepts ici vous dirigeront de mieux googler pour les morceaux appropriés sur le web.

Il aide si vous marchez votre chemin à travers « La vie comme point »:

Ici, nous sommes, un joli petit point 3 dimensions:

var happyPoint = new Point(0, 0, 0); 

Et voici son ami, défini dans par rapport à son ami:

var friendlyPoint = new Point(1, 0, 0); 

pour l'instant, nous allons appeler ces deux points de notre « modèle » - nous allons utiliser le terme « espace modèle » pour parler sur les points au sein une structure tridimensionnelle unique (comme une maison, un monstre, etc.). Les modèles ne vivent pas dans le vide, cependant ... il est généralement plus facile de séparer l'espace du modèle et l'espace du monde pour faciliter le modelage des modèles (sinon, tous vos modèles devraient être en la même échelle, ont la même orientation, etc, etc, plus essayer de travailler sur eux dans un programme de modélisation 3D serait friggin impossible)

Nous allons donc définir une "World Transform" pour notre "Modèle" (ok , 2 points est un modèle boiteux, mais un modèle il reste).

Qu'est-ce qu'un "World Transform"? Il suffit de mettre:

  • Un monde transformation W = T X R X S, où
  • T = traduction - qui est, en le faisant glisser le long du X, Y ou Z axes
  • R = rotation - tourner le modèle par rapport à un axe
  • S = mise à l'échelle - le redimensionnement d'un modèle (en maintenant tous les points par rapport à l'intérieur), le long d'un axe

Nous allons prendre le facile ici, et juste définir notre monde à transformer comme la matrice d'identité - en gros, cela signifie que nous ne voulons pas de traduire, faites pivoter ou à l'échelle:

world = [ 
      1 0 0 0 
      0 1 0 0 
      0 0 1 0 
      0 0 0 1 
     ]; 

Je vous recommande fortement de vous rafraîchir sur vos mathématiques Matrix, en particulier la multiplication et les opérations Vector-> Matrix son utilisé TOUT LE TEMPS DE FREAKING dans les graphiques 3D. Donc, si je saute habilement la multiplication de la matrice, je vais vous dire que multiplier notre «transformation du monde» et nos points modèles se retrouvent avec nos points modèles (bien que dans cette nouvelle représentation vectorielle amusante en 4 dimensions, que je ne toucherai pas ici).

Donc, nous avons nos points, et nous les avons absolument repérés dans "l'espace" ... et maintenant?

Eh bien, d'où le regardons-nous? Cela conduit au concept de View Transformations ou Camera Projection - essentiellement, il est juste une autre multiplication matricielle - observer:

dire que nous avons un point X, à ... oh, (4 2) ou si:

| 
| 
| 
|  
| X 
| 
------------------------ 

Du point de vue de l'origine (0 0), X est à (4 2) - mais disons que nous mettons notre caméra à droite?

| 
| 
| 
|  
| X   >-camera 
| 
------------------------ 

Quelle est la "position" de X par rapport à la caméra? Probablement quelque chose de plus proche de (0 9) ou (9 0), selon ce que sont les directions "haut" et "droite" de votre caméra. C'est ce que les transformations de View consistent à: - mapper un ensemble de points 3D à un autre ensemble de points 3D de sorte qu'ils soient «corrects» du point de vue d'un observateur. Dans le cas d'une caméra fixe de haut en bas, votre observateur aurait une position fixe dans le ciel, et tous les modèles seraient transformés en conséquence.

Alors dessinons!

Malheureusement, notre écran n'est pas 3D (encore), nous devons d'abord "projeter" ce point sur une surface 2D. La projection est ...bien, son fondamentalement une cartographie qui ressemble à:

(x, y, z) => (x, y) 

Le nombre de projections possibles est proche infini: par exemple, nous pourrions passer sur les X et Y coordonnées par Z:

func(x, y, z) => new point2d(x + z, y + z); 

habituellement, vous voulez que cette projection pour mimer la projection de la rétine humaine ne quand on regarde les scènes 3D, cependant, si nous introduisons les concepts d'un Voir projection. Il existe plusieurs projections de vue différentes, telles que orthographique, défini par YawPitchRoll et défini en perspective/FOV; chacun d'entre eux a quelques bits de données clés dont vous avez besoin pour construire correctement la projection.

Une projection basée perspective/FOV, par exemple, a besoin:

  • La position de votre "globe oculaire" (c.-à l'écran)
  • À quelle distance dans la distance de votre "globe oculaire" est capable de mise au point (le "plan de coupure éloigné")
  • Votre champ de vision angulaire (c'est-à-dire les bras ouverts, juste au bord de votre vision périphérique)
  • Le rapport de la largeur à la hauteur pour le "verre" re regardant à travers (généralement votre résolution d'écran)

Une fois que vous avez ces chiffres, vous créez quelque chose appelé un « bondissant frustum », qui ressemble un peu à une pyramide avec le haut trancha:

\-----------------/ 
\    /
    \   /
    \   /
    \  /
    \-------/ 

Ou de l'avant:

___________________ 
| _____________ | 
| |    | | 
| |    | | 
| |    | | 
| |    | | 
| |    | | 
| |_____________| | 
|___________________| 

Je ne vais pas faire les calculs de la matrice ici, puisque c'est tout bien défini ailleurs - en fait, la plupart des bibliothèques ont des méthodes d'aide qui généreront les matrices correspondantes pour vous - mais est ici à peu près comment cela fonctionne:

Disons que votre petit point heureux est dans ce tronc de cône:

\-----------------/ 
\    /
    \ o<-pt  /
    \   /
    \  /
    \-------/ 

___________________ 
| _____________ | 
| |    | | 
| |    | | 
|o |    | | 
|^---- pt  | | 
| |    | | 
| |_____________| | 
|___________________| 

avis qu'il est loin de côté, jusqu'à présent qu'il est hors du rectangle « plan près clip » - Que faudrait-il ressembler si vous " regardé dans "la plus petite extrémité de la pyramide?

Tout comme regarder dans un prisme (ou une lentille), le point serait « plié » en vue:

___________________ 
| _____________ | 
| |    | | 
| |    | | 
|>>>o <- pt is | | 
| | shifted | | 
| |    | | 
| |_____________| | 
|___________________| 

Autrement dit, si vous aviez une lumière vive derrière tronc de cône, où Est-ce que les ombres de vos points seraient «jetées» sur le champ de coupure proche? (Le rectangle plus petit) C'est tout projection - une cartographie d'un point à un autre, dans ce cas, la suppression de la composante Z et modifiant le X et Y en conséquence d'une manière qui « fait sens » à nos yeux.

+0

Wow quelle réponse, merci beaucoup J'ai vraiment une meilleure compréhension de la théorie à présent. Je vais commencer à construire mon 'convertisseur' et afficher le code ici plus tard aujourd'hui pour savoir si j'ai bien fait, acclamations m8! –

+1

Cela mérite bien plus d'upvotes !! – Nissim

2

Vous devez prendre en considération la perspective. Selon votre perspective, les points de l'intrigue seraient différents. Si vous voulez une perspective orthographiques (pas de perspective essentiellement) vous exécuter une transformation de la matrice comme ceci:

enter image description here

un représente vos points 3D et b représente le résultat de points 2D. vecteur s est un facteur d'échelle arbitraire, et c est un décalage arbitraire

Voici un autre poste semblable à cela avec une bonne réponse:

Basic render 3D perspective projection onto 2D screen with camera (without opengl)

Voici quelques informations supplémentaires

http://en.wikipedia.org/wiki/3D_projection