tags:

views:

53

answers:

2

For a simulation of a laser-based sensor I am designing, I want to verify how four points projected on a surface would appear from a camera. And so I have undertaken to implement a Graphics3D visualization.

The visualization places 4 lasers in a pyramid-like arrangement with a camera 20 centimeters two one side viewing the laser's projections. My notebook code produces two views: one outside a room the sensor would operate within and a second view point which represents the camera which is rotated with the lasers. The Euler angles and x,y,z coordinates of the camera-laser ensemble can be controlled using sliders.

My problem is that in the simulation the camera is be being automatically oriented. And so the view from a real physical camera is not reproduced because Mathematica is adjusting the viewpoint. If the camera and laser rotated together than rotations in Psi would cause the camera to rotate in lockstep with the laser and the view should be unchanged. Likewise shifts in x and y shouldn't make the camera jiggle so.

How can I control the camera orientation to produce a more coherent simulation?

The notebook code is:

 \[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}]
A: 

I think that all you need to do is instead of using the ViewVector option, set

ViewPoint -> {x, y, z}

Some of the jiggling is due to the laser/plane intersection points moving too far out of the room. It might be best to truncate these somehow.

Aside: your code calculates rx . ry . rz five times, it's probably best to calculate it once and store it.

Simon
You are right about the redundancy of rx . ry . rz computation (not sure how clever Mathematica is at optimizing such repetitions).However as for ViewPoint, I don't find any improvement with the use of ViewPoint. A ViewPoint -> {x,y,z} places the camera well outside of the room as opposed to a precise location next to the lasers and rotating with the lasers. My contention is that the position is being correctly set by ViewVector, but the camera's orientation (its Euler angles) are being automatically decided by Mathematica.
speciousfool
OK, I think that if you want to change the rotation of the camera, then you have to use ViewMatrix. Here you specify a 4x4 matrix that represents an IO(3) transformation...
Simon
+1  A: 

As I guess you are fully aware, you need to somehow specify the camera position, orientation and angle of view. In typical Mathematica fashion, you can do this by specifying a million different subsets of interrelated options. The following is how I would do it:

Firstly, the camera position. This can be specified in graphics coordinates (ViewVector) or relative to the bounding box (ViewPoint). Either of these should work. While specifying the camera position, remember that the perspective effects diminish when you move further away from ViewCenter.

The camera orientation is defined by the ViewCenter (specifying 2 degrees of the camera orientation) and ViewVertical (the direction that will end up being vertical in the 2D projection). ViewCenter is usually fine by default if you have specified a PlotRange.

Finally, Automatic is most often fine for ViewAngle if you have a well defined PlotRange, but you might need to set SphericalRegion to true if you are moving around your subject.

All the view geometry options are listed here, but I guess ViewRange is about the only one I haven't mentioned above :). As far as I can tell, you just need to specify ViewVertical?

Janus