2010-09-05 5 views
1

Je développe un logiciel de navigation tour par tour et j'utilise la solution suivante pour faire mes lignes de routes en 2.5D ou 3DProblème avec vue plongeante ou le rendu 2.5D de carte

Draw 2.5D or 3D Map with C# from lines

Cependant, au-dessus de la solution est tout à fait acceptable pour des lignes au sein de l'orifice de visualisation qui est 0 x largeur < < et 0 < y < hauteur. Cependant, il y a des lignes que ses points peuvent avoir 0 ou 0 x < 0 ou x < 0 ou y> hauteur ou x> largeur et puis la solution ci-dessus est devenu fou. Quelqu'un pourrait-il m'aider à comprendre comment résoudre le problème?

vvvv Avec algorithme 3D vvvv

alt text

.

vvvv Sans algorithme 3D vvvv

alt text

mise à jour :: Après avoir utilisé ce code

double x = p->x(); 
double y = p->y(); 

double t = -0.5; 
x = x - w/2; 
y = y - h/2; 
double a = h/(h + y* sin(t)); 
double u = a * x + w/2; 
double v = a * y * cos(t) + h/2; 

p->setX(u); 
p->setY(v); 
return p; 

La carte devient comme suit alt text

Je pense qu'il ya quelque chose de mal avec Y calculs quand ils vont chemin au-delà des valeurs négatives. J'utilise Qt et des fissures à la ligne semble bug avec Qt renderer, pas lié à notre problème d'origine.

Répondre

4

Le problème est que la transformation que vous utilisez ne mappe pas les lignes droites aux lignes droites. Au contraire, les lignes droites vont généralement aux paraboles. Vous pouvez voir cela dans les images d'exemple, où la route principale plus ou moins droite allant de haut en bas dans la vue 2D est transformée en une route incurvée dans la vue 2.5D. Vous verriez la même chose pour les lignes qui "deviennent folles" dans votre exemple si vous les avez divisées en segments plus courts.

Mathématiquement, vous pouvez voir ce qui se passe en remontant à la vous transformer utilisez:

x_ = (x - w/2)*(t1+(y/h)*(t2-t1)) + w/2 
y_ = y 

Si nous exprimons une ligne droite comme x = ay+b, un point (ay+b,y) sur cette ligne cartes à (ay+b - w/2)*(t1+(y/h)*(t2-t1)) + w/2,y) . Cette expression semble compliquée, mais vous pouvez voir qu'elle évalue à quelque chose comme (c*y^2+d*y+e,y), pour des valeurs appropriées de c,d,e, qui est une parabole.

Donc, votre meilleur pari est d'abandonner cette transformation et de passer à perspective transform.

Dans votre question initiale, vous avez mentionné qu'une transformation non affine d'une image rendue était trop lente.Il semble que vous ayez maintenant changé pour transformer les lignes avant de les rendre, et c'est assez rapide. La seule chose que vous devez faire maintenant est de changer la transformation.

Voici une suggestion de transformation. C'est un couple d'étapes, et prend vos coordonnées 2D (x, y) à quelques coordonnées 2.5D (u, v). Je suppose que vous utilisez C#.

t = 0.3 // tilt angle - try different values  
X = x - w/2 ; 
Y = y - h/2 ; 
a = h/(h + Y*Math.Sin(t)) ; 
u = a*X + w/2 ; 
v = a*Y*Math.Cos(t) + h/2 ; 

Il y a un paramètre t ici qui définit le degré d'inclinaison, exprimée en radians. Je suggère de jouer avec une valeur d'environ 0,3, plus ou moins.

Je l'ai travaillé avec un crayon et du papier, mais ne l'exécutez pas, alors laissez-moi savoir si cela ne fonctionne pas .. il est toujours possible qu'il y ait eu une erreur de transcription.

Mise à jour: Vous voulez éviter de dessiner toute entité (ligne, polygone, peu importe) qui a un point tel que (x,y)a est non-positif. Mieux encore, pour éviter les débordements, vous devriez éviter de dessiner quand a<epsilon, où epsilon est une petite valeur positive comme 0.05 ou 0.1.

+0

Oui, aussi, au lieu de tracer une ligne d'épaisseur constante, déterminez le polygone correspondant (rectangle) dans les coordonnées de la carte source. Mappez ces 4 sommets en utilisant la transformation pour faire un polygone à dessiner (au lieu d'une simple ligne). Cela fera en sorte que les routes plus éloignées seront plus petites, comme il se doit. –

+0

@Tom, merci pour l'entrée. @brainjam, pourriez-vous s'il vous plaît fournir une équation comme x = ****** ou un extrait de code pour moi? Mes faibles maths me rendent incapable d'obtenir un code de travail à partir d'un article wiki. Merci beaucoup – VOX

+0

@VOX, j'ai ajouté une suggestion de transformation. – brainjam

0

Le problème de l'équation est qu'elle permet à la valeur x projetée de traverser la ligne médiane (w/2). Ce n'est pas souhaitable lorsqu'on essaie de modéliser une transformation de perspective puisque les lignes doivent s'approcher, mais ne pas traverser, un point de fuite. En outre, en raison de la façon dont l'équation est écrite, cette intersection se produit devant la caméra au lieu de derrière, ce qui conduit à des artefacts inutiles. Essayez plutôt quelque chose comme ceci:

 
halfW = w/2 
dx = (x - halfW) 
dy = (h - y) // y increases downwards 
// tune these constants to taste. 
top = 1.25 
bottom = 0.75 
lowerBound = 0.1 // Avoids divide by zero and perspective lines crossing midline 
x_ = (dx/max(lowerBound, (bottom + ((dy/h) * (top - bottom))))) + w/2