2010-08-19 5 views
0

Pour une simulation d'un capteur laser que je suis en train de concevoir, je veux vérifier comment quatre points projetés sur une surface apparaîtraient à partir d'une caméra. Et donc j'ai entrepris d'implémenter une visualisation Graphics3D.Comment orienter précisément une caméra dans Graphics3D?

La visualisation place 4 lasers dans un arrangement de type pyramidal avec une caméra de 20 centimètres deux d'un côté regardant les projections du laser. Le code de mon ordinateur portable produit deux vues: une à l'extérieur d'une pièce où le capteur fonctionnerait et un deuxième point de vue qui représente la caméra qui est tournée avec les lasers. Les angles d'Euler et les coordonnées x, y, z de l'ensemble caméra-laser peuvent être contrôlés à l'aide de curseurs.

Mon problème est que dans la simulation, la caméra est orientée automatiquement. Ainsi, la vue d'une vraie caméra physique n'est pas reproduite car Mathematica ajuste le point de vue. Si la caméra et le laser tournaient ensemble que les rotations dans Psi, la caméra tournerait en même temps que le laser et la vue devrait rester inchangée. De même, les décalages de x et y ne doivent pas faire trembler la caméra.

Comment puis-je contrôler l'orientation de la caméra pour produire une simulation plus cohérente?

Le code portable est:

\[Delta] = N[(38*Degree)/2]; 
PointPlaneIntersection[{{x1_, y1_, z1_}, 
     {x2_, y2_, z2_}, {x3_, y3_, z3_}}, 
    {{x4_, y4_, z4_}, {x5_, y5_, z5_}}] := 
    Module[{t = -Det[{{1, 1, 1, 1}, {x1, x2, x3, x4}, 
      {y1, y2, y3, y4}, {z1, z2, z3, z4}}]/ 
     Det[{{1, 1, 1, 0}, {x1, x2, x3, x5 - x4}, 
      {y1, y2, y3, y5 - y4}, {z1, z2, z3, 
      z5 - z4}}]}, Point[{x4 + t*(x5 - x4), 
     y4 + t*(y5 - y4), z4 + t*(z5 - z4)}]]; 
UnitSpherePoint[azimuth_, polar_] := 
    {Cos[azimuth]*Sin[polar], Sin[azimuth]*Sin[polar], 
    Cos[polar]}; 
Manipulate[rx := RotationMatrix[\[Theta], {1, 0, 0}]; 
    ry := RotationMatrix[\[Phi], {0, 1, 0}]; 
    rz := RotationMatrix[\[Psi], {0, 0, 1}]; 
    line1 = {{x, y, z}, rx . ry . rz . UnitSpherePoint[0, 
     Pi + \[Delta]] + {x, y, z}}; 
    line2 = {{x, y, z}, rx . ry . rz . UnitSpherePoint[ 
     Pi/2, Pi + \[Delta]] + {x, y, z}}; 
    line3 = {{x, y, z}, rx . ry . rz . UnitSpherePoint[ 
     Pi, Pi + \[Delta]] + {x, y, z}}; 
    line4 = {{x, y, z}, rx . ry . rz . UnitSpherePoint[ 
     3*(Pi/2), Pi + \[Delta]] + {x, y, z}}; 
    cline = {{x + 0.2, y, z}, 
     rx . ry . rz . UnitSpherePoint[0, Pi] + 
     {x + 0.2, y, z}}; roomplane := 
    {{0, 0, 0}, {30, 0, 0}, {0, 15, 0}}; 
    Scene := Graphics3D[{Red, Opacity[1], 
     PointPlaneIntersection[roomplane, line1], 
     PointPlaneIntersection[roomplane, line2], 
     PointPlaneIntersection[roomplane, line3], 
     PointPlaneIntersection[roomplane, line4], White, 
     Opacity[0.1], Cuboid[{0, 0, 0}, {30, 15, 6}]}, 
     Boxed -> False, Lighting -> "Neutral"]; 
    Grid[{{Show[Scene], Show[Scene, ViewVector -> cline, 
     ViewAngle -> 64*Degree, RotationAction -> 
     "Clip"]}}], {{x, 15}, 0, 30}, {{y, 7.5}, 0, 15}, 
    {{z, 3}, 0, 6}, {{\[Theta], Pi}, 0, 2*Pi}, 
    {{\[Phi], Pi}, 0, 2*Pi}, {{\[Psi], Pi}, 0, 2*Pi}] 

Répondre

3

Comme vous le savez, vous devez spécifier la position, l'orientation et l'angle de vue de la caméra. En mode Mathematica classique, vous pouvez le faire en spécifiant un million de sous-ensembles différents d'options interdépendantes. Voici comment je le ferais:

Premièrement, la position de la caméra. Cela peut être spécifié dans les coordonnées graphiques (ViewVector) ou par rapport au cadre de délimitation (ViewPoint). L'un ou l'autre devrait fonctionner. Lorsque vous spécifiez la position de la caméra, n'oubliez pas que les effets de perspective diminuent lorsque vous vous éloignez de ViewCenter. L'orientation de la caméra est définie par ViewCenter (en spécifiant 2 degrés de l'orientation de la caméra) et ViewVertical (la direction qui sera verticale dans la projection 2D). ViewCenter est généralement bien par défaut si vous avez spécifié un PlotRange.

Enfin, Automatic est le plus souvent très bien pour ViewAngle si vous avez un bien défini PlotRange, mais vous devrez peut-être mettre SphericalRegion à true si vous vous déplacez autour de votre sujet.

Toutes les options de géométrie d'affichage sont listées here, mais je suppose que ViewRange est à peu près le seul que je n'ai pas mentionné ci-dessus :). Pour autant que je peux dire, vous avez juste besoin de spécifier ViewVertical?

0

Je pense que tout ce que vous devez faire est au lieu d'utiliser l'option ViewVector, définissez

ViewPoint -> {x, y, z} 

Certains des jiggling est due au laser/Les points d'intersection des avions s'éloignent trop de la pièce. Il pourrait être préférable de les tronquer d'une manière ou d'une autre. A côté: votre code calcule rx . ry . rz cinq fois, il est probablement préférable de le calculer une fois et de le stocker.

+0

Vous avez raison concernant la redondance de rx. ry. calcul de rz (ne savez pas à quel point Mathematica est astucieux pour optimiser de telles répétitions). Cependant, comme pour ViewPoint, je ne trouve aucune amélioration avec l'utilisation de ViewPoint. Un point de vue -> {x, y, z} place la caméra bien à l'extérieur de la pièce par opposition à un emplacement précis à côté des lasers et tournant avec les lasers. Mon argument est que la position est correctement définie par ViewVector, mais l'orientation de la caméra (ses angles d'Euler) est automatiquement déterminée par Mathematica. – speciousfool

+0

OK, je pense que si vous voulez changer la rotation de la caméra, alors vous devez utiliser ViewMatrix. Ici vous spécifiez une matrice 4x4 qui représente une transformation IO (3) ... – Simon

Questions connexes