zoukankan      html  css  js  c++  java
  • 线性变换

    矩阵的线性变换

    1. 旋转
    2. 缩放
    3. 投影
    4. 镜像
    5. 切变
    
    

    旋转矩阵

    aM = b 向量与一个矩阵相乘得到一个新的向量

    R(theta) = [p, q]^T = [ cosTheta, sinTheta
    -sinTheta, cosTheta
    ]
    

    3D旋转

    确定旋转方向

    1. 左手坐标系
    大拇指指向旋转轴的正向,其他手指向内弯曲,弯曲的方向就是旋转轴的正向
    
    2. 右手坐标系
    

    3D旋转矩阵

    每个轴的基向量的长度都为1
    当前矩阵根据左手坐标系进行旋转
    
      x y z
    [ 1 0 0 ] xaxis
    [ 0 1 0 ] yaxis
    [ 0 0 1 ] zaxis
    
    绕x轴旋转,绕x轴旋转,其他轴变,x轴不变
      x  y   z
    [ 1  0   0 ] xaxis
    [ 0  cos sin] yaxis
    [ 0  -sin cos ] zaxis
    
    绕y轴旋转
      x    y    z
    [ cos  0  -sin ] xaxis
    [ 0    1   0  ] yaxis
    [ sin  0  cos ] zaxis
    
    绕z轴旋转
      x     y     z
    [ cos   sin   0 ] xaxis
    [ -sin  cos   0 ] yaxis
    [ 0     0    1 ] zaxis
    
    class Matrix {
        constructor(...components) {
            this.rows = components
        }
        columns() {
            return this.rows[0].map((_, i) => this.rows.map(row => row[i]))
        }
        mult(other) {
            if (this.rows[0].length !== other.rows.length) {
                throw new Error('该矩阵的列数不等于给定矩阵的行数')
            }
            const sum = arr => arr.reduce((el, next) => el + next, 0)
            // 将矩阵转置
            const columns = other.columns()
            const newRows = this.rows.map(row => (
                columns.map(column => (
                    sum(row.map((element, i) => element * column[i]))
                ))
            ))
    
            return new Matrix(...newRows)
        }
        transpose() {
            return new Matrix(...this.columns())
        }
        scaleMult(number) {
            const newRows = this.rows.map(row => (
                row.map(element => element * number)
            ))
            return new Matrix(...newRows)
        }
    }
    
    const log = console.log
    const toRadians = degress => degress * Math.PI / 180
    
    const angle90 = toRadians(90)
    const one = new Matrix(
        [10, 0, 0],
    )
    // 绕z轴旋转
    const rotateZAxis = new Matrix(
        [Math.cos(angle90), Math.sin(angle90), 0],
        [Math.sin(angle90 * -1), Math.cos(angle90), 0],
        [0, 0, 1]
    )
    // Matrix { rows: [ [ 6.123233995736766e-16, 10, 0 ] ] } 向量旋转90度后与y轴垂直
    log(
        one.mult(rotateZAxis)
    )
    
        
    

    缩放矩阵

     x  y. z
    [kx 0. 0]  xaxis
    [0. ky 0]  yaxis
    [0  0 kz]  zaxis
    
    const one = new Matrix(
        [10, 20, 30],
    )
    
    const scaleMatrix = new Matrix(
        [1,0,0],
        [0,2,0],
        [0,0,3]
    )
    
    log(one.mult(scaleMatrix))
    

    切变矩阵

    // 2D切变矩阵
    Hx(s) = [1 0]
           [s 1] 
    x' = x + sy
    
    // xy被z坐标切变
    Hxy(s,t) = [1 0 0]
              [0 1 0]
              [s t 1]
    // y轴切变
    Hxz(s,t) = [1 0 0]
              [s 1 t]
              [0 0 1]
    
    // x轴切变
    Hyz(s,t) = [1 s t]
              [0 1 0]
              [0 0 1]
    
    const one = new Matrix(
        [10, 20, 30]
    )
    // x轴切变
    const other = new Matrix(
        [1, 1, 2],
        [0, 1, 0],
        [0, 0, 1]
    )
    // y' = y + sx  y' = 20 + 1*10
    // z' = z + sx  z' = 30 + 2*10
    log(one.mult(other))
    
  • 相关阅读:
    Object之总结(一)
    Object之registerNatives
    Object之finalize
    阿里腾讯百度360
    Object之getClass
    Object之clone
    Object之toString
    Object之notify
    Object之wait
    Object之equals与hashCode
  • 原文地址:https://www.cnblogs.com/pluslius/p/13823627.html
Copyright © 2011-2022 走看看