o3d模型变换 (转)

这一章比较简单,主要讲如何移动和旋转3D 空间中的物体,主要用到transform 对象其中的一些函数,在介绍这些函数之前,先介绍世界坐标系和局部坐标系。世界坐标系顾名思义就是以整个世界为坐标系,而局部坐标系则是以要变换的物体为中心的坐标系,其中物体绘制时各个顶点的坐标都是以这个局部坐标系为参照的,而进行移动变换时,则是以世界坐标系为参照,然后移动这个局部坐标系。进行旋转时也是绕着局部坐标系转的。

 


    下面介绍一下几个常用的变换函数,最后再改动一下上一章的例子,加入一些变换

   


     1.(transformObject).translate(X,       // 在X 轴上移动的距离

                                        Y ,    // 在Y 轴上移动的距离

                                  Z ,    // 在Z 轴上移动的距离)

       这个函数就是用来平移局部坐标系(即你要移动的物体),注意每次移动都是相对于上一次的 。

   


    2. (transformObject).rotateX(degree)      // 绕X 轴旋转degree 个角度

   


    3. (transformObject).rotateY(degree)      // 绕Y 轴旋转degree 个角度

   


    4. (transformObject).rotateZ(degree)      // 绕Z 轴旋转degree 个角度

       这三个函数是用来旋转物体的,注意物体旋转是绕着局部坐标系的X,Y,Z 轴来旋转地,而不是世界坐标系。

 


5.  (transformObject).identity();

    这个函数是把所有变换都重置,其实就是把所有变换的矩阵单位化,因为前面的不管是旋转还是移动的变换就是一个矩阵,这个物体的所有顶点坐标都乘以这个矩阵,就实现了变换,而矩阵单位化后,就相当于没有乘以这个矩阵,也就是没有做变换。

 

 

下面来讲一下一个物体被投到视口上时到底要乘多少次矩阵(非常感慨当初线性代数没学好),首先是模型变换,即上面讲到的物体的移动和旋转,进行模型变换后再是视图变换,何谓视图变换,因为O3d 中lookat 这个函数,你的眼睛可以在不同位置通过不同角度看这个物体,为了达到这种效果,这些坐标还得进行一次变换。从而形成错觉让人感觉是从那个位置看出去的,其实视图变换时模型变换的逆变换,视图变换能达到的模型变换逆着来后都能达到,最后就是投影变换了,把一个三维的世界投到一个二维的屏幕上。

 


下面就实战一下。让上一章那个立方体能够旋转起来。这个都写在renderCallBack 函数里面吧,这个函数是一个回调函数,每次重绘都要调用这个函数,这里重绘并不是说在改动一个物体才需要重新绘制,而是每隔一个很短的时间都需要重新绘制,也就是说每隔一个很短的时间就要调用这个函数,所以把旋转的变换放在这个函数里面,每次旋转角度递增,就能达到让立方体旋转起来的效果,话不多说,下面看这个函数。

function renderCallback(renderEvent) {

  g_clock += renderEvent.elapsedTime;

  // Rotate the cube around the Y axis.

  g_cubeTransform.identity();

  g_cubeTransform.rotateY(2.0 * g_clock);

}

    (g_cubeTransform 由于是在initStep2 里定义的,所以得声明成全局变量。)

很精简,g_clock 是一个全局变量,初始值为零,一直递增,而立方体的变换则是先摆回原来样子,然后转动2*g_clock 个角度,由于g_clock 一直增大,所以给人错觉就是立方体一直在转。

 


    当然有更简单的方法,可以不用g_clock ,因为上面提到过每次旋转都是相对于上一次的,所以每次都不重置,而是相对于上一次转动一个固定的值;

function renderCallback ( renderEvent ) {

  g_cubeTransform . rotateY ( 2 );

}

     然后在initStep2 中设置这个回调函数

  g_client.setRenderCallback(renderCallback);

  

 

### 使用 Open3D 对 OBJ 模型进行旋转 为了使用 Open3D 对 OBJ 模型执行旋转操作,首先需要安装并导入必要的库。确保已经按照官方文档完成 Open3D 的安装[^1]。 接着定义一个函数来加载 OBJ 文件: ```python import open3d as o3d def load_obj(file_path): mesh = o3d.io.read_triangle_mesh(file_path) return mesh ``` 对于旋转功能而言,Open3D 提供了一个简单的方法 `rotate` 来改变几何体的姿态。此方法接受两个参数:一个是表示旋转角度的四元数或者是变换矩阵;另一个是指定绕哪个轴旋转以及旋转中心的位置向量。下面是一个具体的例子说明如何围绕指定轴线旋转对象: ```python import numpy as np def rotate_around_axis(mesh, rotation_angle_degrees=45, axis='z'): R = mesh.get_rotation_matrix_from_xyz((0, 0, np.deg2rad(rotation_angle_degrees))) if axis.lower() == 'x': R = mesh.get_rotation_matrix_from_xyz((np.deg2rad(rotation_angle_degrees), 0, 0)) elif axis.lower() == 'y': R = mesh.get_rotation_matrix_from_xyz((0, np.deg2rad(rotation_angle_degrees), 0)) center = mesh.get_center() mesh.rotate(R, center=center) return mesh ``` 上述代码片段展示了如何创建一个名为 `rotate_around_axis` 函数,它接收三个输入参数——要被旋转的对象(`mesh`)、期望的角度(默认设置为45度)以及希望沿其旋转的具体坐标轴('x', 'y' 或者 'z')。这里采用了欧拉角的方式构建了相应的旋转变换矩阵,并将其应用于给定的网格模型上。 最后一步就是调用这个新建立起来的功能来进行实际的操作了: ```python if __name__ == "__main__": obj_file = "path_to_your_model.obj" loaded_mesh = load_obj(obj_file) rotated_mesh = rotate_around_axis(loaded_mesh, 90, 'x') o3d.visualization.draw_geometries([rotated_mesh]) ``` 这段脚本会先载入指定路径下的OBJ文件,再对该物体实施一次沿着X轴方向顺时针动90°的动作,最终利用内置绘图工具显示出处理后的效果[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值