如何在 Graphics3D 中精确定位相机?
对于我正在设计的基于激光的传感器的模拟,我想验证投影在表面上的四个点在相机中的显示效果。因此我开始实施 Graphics3D 可视化。
该可视化将 4 个激光器排列成金字塔状,并用 20 厘米的摄像机在一侧观察激光器的投影。我的笔记本代码生成两个视图:一个视图位于传感器将在其中运行的房间外,第二个视图代表随激光旋转的相机。相机-激光整体的欧拉角和 x、y、z 坐标可以使用滑块进行控制。
我的问题是在模拟中相机会自动定向。因此,由于 Mathematica 正在调整视点,因此不会再现真实物理相机的视图。如果相机和激光一起旋转,则 Psi 中的旋转将导致相机与激光同步旋转,并且视图应该保持不变。同样,x 和 y 的变化也不应该使相机晃动。
如何控制相机方向以产生更连贯的模拟?
笔记本代码是:
\[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}]
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}]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我想您完全清楚,您需要以某种方式指定相机位置、方向和视角。在典型的 Mathematica 方式中,您可以通过指定一百万个不同的相互关联选项子集来完成此操作。以下是我的做法:
首先,相机位置。这可以在图形坐标 (
ViewVector
) 中指定或相对于边界框 (ViewPoint
) 指定。其中任何一个都应该有效。指定相机位置时,请记住,当您远离ViewCenter
时,透视效果会减弱。相机方向由
ViewCenter
(指定相机方向的 2 度)和ViewVertical
(最终在 2D 投影中垂直的方向)定义。如果您指定了PlotRange
,则默认情况下ViewCenter
通常就可以。最后,如果您有明确定义的
PlotRange
,则Automatic
通常最适合ViewAngle
,但您可能需要设置SphericalRegion
如果您正在围绕主题移动,则将 code> 设置为 true。所有视图几何选项都列在此处,但我猜
ViewRange
是我上面唯一没有提到的一个:)。据我所知,您只需要指定ViewVertical
即可?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 fromViewCenter
.The camera orientation is defined by the
ViewCenter
(specifying 2 degrees of the camera orientation) andViewVertical
(the direction that will end up being vertical in the 2D projection).ViewCenter
is usually fine by default if you have specified aPlotRange
.Finally,
Automatic
is most often fine forViewAngle
if you have a well definedPlotRange
, but you might need to setSphericalRegion
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 specifyViewVertical
?我认为您需要做的就是不要使用 ViewVector 选项,而是设置
一些抖动是由于激光/平面交叉点移出房间太远。最好以某种方式截断它们。
另外:您的代码计算
rx 。瑞。 rz
五次,最好计算一次并存储它。I think that all you need to do is instead of using the
ViewVector
option, setSome 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.视点和视图中心一起使用时不起作用。或者,它们有时会起作用,但通常不起作用。例如,mathematica 只会将视图中心更改为图形的中心,而忽略指定的内容。这确实是一种讽刺,没有记录下来。
但无论如何,当您指定相机位置和视图方向时,viewvector 选项似乎确实有效。
viewpoint and viewcenter when used together don't work. Or, they work some of the time, but often don't. For example, mathematica will just change the viewcenter to the center of the graphics, ignoring what is specified. It's really a travesty that this isn't documented.
But in any case, the viewvector option does seem to work when you specify both the camera position and view direction.