我用taichi写矩阵变换,产生的几个疑问。

1~2问题我查api docs没找到,3问题是我使用之后的疑问。

  1. 是ti.Matrix能否可以获取某行,某列然后变成ti.Vector呢?
  2. ti.Matrix能否可以想numpy那样 m[0:2, 0:2],这样使用?我需要m[0, 0] … m[2, 2]去赋值
  3. ti.Matrix.Identity 为什么不能在python-score里面用呢?我必须自己写一个
@ti.pyfunc
def identity():
    return ti.Matrix([
        [1.0, 0.0, 0.0, 0.0],
        [0.0, 1.0, 0.0, 0.0],
        [0.0, 0.0, 1.0, 0.0],
        [0.0, 0.0, 0.0, 1.0],
    ])
  1. 我自己写的taichi代码,这里还有优化空间吗?
# refer to GLM
# Right-Handed Coordinate System
import taichi as ti


@ti.pyfunc
def radians(degrees):
    return degrees * 0.01745329251994329576923690768489


@ti.pyfunc
def degrees(radians):
    return radians * 57.295779513082320876798154814105


@ti.pyfunc
def identity():
    return ti.Matrix([
        [1.0, 0.0, 0.0, 0.0],
        [0.0, 1.0, 0.0, 0.0],
        [0.0, 0.0, 1.0, 0.0],
        [0.0, 0.0, 0.0, 1.0],
    ])


@ti.pyfunc
def translate(m, v):
    return ti.Matrix([
        [
            m[0, 0], m[0, 1], m[0, 2],
            m[0, 0] * v[0] + m[0, 1] * v[1] + m[0, 2] * v[2] + m[0, 3],
        ],
        [
            m[1, 0], m[1, 1], m[1, 2],
            m[1, 0] * v[0] + m[1, 1] * v[1] + m[1, 2] * v[2] + m[1, 3],
        ],
        [
            m[2, 0], m[2, 1], m[2, 2],
            m[2, 0] * v[0] + m[2, 1] * v[1] + m[2, 2] * v[2] + m[2, 3],
        ],
        [
            m[3, 0], m[3, 1], m[3, 2],
            m[3, 0] * v[0] + m[3, 1] * v[1] + m[3, 2] * v[2] + m[3, 3],
        ],
    ])


@ti.pyfunc
def rotate(m, angle, v):
    c = ti.cos(angle)
    s = ti.sin(angle)

    axis = v.normalized()
    temp = (1.0 - c) * axis

    Rotate = ti.Matrix([
        [
            temp[0] * axis[0] + c,
            temp[0] * axis[1] - axis[2] * s,
            temp[0] * axis[2] + axis[1] * s,
            0.0,
        ],
        [
            temp[1] * axis[0] + axis[2] * s,
            temp[1] * axis[1] + c,
            temp[1] * axis[2] - axis[0] * s,
            0.0,
        ],
        [
            temp[2] * axis[0] - axis[1] * s,
            temp[2] * axis[1] + axis[0] * s,
            temp[2] * axis[2] + c,
            0.0,
        ],
        [0.0, 0.0, 0.0, 1.0],
    ])
    return Rotate @ m


@ti.pyfunc
def scale(m, v):
    return ti.Matrix([
        [m[0, 0] * v[0], m[0, 1] * v[1], m[0, 2] * v[2], m[0, 3]],
        [m[1, 0] * v[0], m[1, 1] * v[1], m[1, 2] * v[2], m[1, 3]],
        [m[2, 0] * v[0], m[2, 1] * v[1], m[2, 2] * v[2], m[2, 3]],
        [m[3, 0] * v[0], m[3, 1] * v[1], m[3, 2] * v[2], m[3, 3]],
    ])


@ti.pyfunc
def lookAt(eye, center, up):
    f = (center - eye).normalized()
    s = (f.cross(up)).normalized()
    u = s.cross(f)

    return ti.Matrix([
        [s.x, s.y, s.z, -s.dot(eye)],
        [u.x, u.y, u.z, -u.dot(eye)],
        [-f.x, -f.y, -f.z, f.dot(eye)],
        [0.0, 0.0, 0.0, 1.0],
    ])


@ti.pyfunc
def ortho(left, right, bottom, top, zNear, zFar):
    return ti.Matrix([
        [2.0 / (right - left), 0.0, 0.0, -(right + left) / (right - left)],
        [0.0, 2.0 / (top - bottom), 0.0, -(top + bottom) / (top - bottom)],
        [0.0, 0.0, -2.0 / (zFar - zNear), -(zFar + zNear) / (zFar - zNear)],
        [0.0, 0.0, 0.0, 1.0],
    ])


@ti.pyfunc
def perspective(fovy, aspect, zNear, zFar):
    tanHalfFovy = ti.tan(fovy / 2.0)

    return ti.Matrix([
        [1.0 / (aspect * tanHalfFovy), 0.0, 0.0, 0.0],
        [0.0, 1.0 / tanHalfFovy, 0.0, 0.0],
        [
            0.0, 0.0,
            -(zFar + zNear) / (zFar - zNear),
            -(2.0 * zFar * zNear) / (zFar - zNear),
        ],
        [0.0, 0.0, -1.0, 0.0],
    ])

Hi @virgilwjj,

  1. 目前还不支持直接获取矩阵的某一行或者列再赋值给ti.Vector
  2. 目前taichi还不支持slice操作
  3. ti.Matrix.Identity 是在taichi scope构造的矩阵所以只能在 ti.kernel, ti.func修饰的函数里使用。
  4. 目前没看出来什么需要优化的地方。
1 个赞

感谢助教老师。

其实,第四个疑问是,
我感觉在python scope也可以有一个identity;zeros,ones同理。
因为有时候需要在python scope使用Matrix。
但是Matrix不想Vector那样写2~4个参数就ok了。而且Matrix往往只要单位矩阵和零矩阵。

嗯,是个好的建议。你能在github上提个issue么?

好的。