zoukankan      html  css  js  c++  java
  • HTML5 canvas transform与矩阵

    HTML5 canvas transform与矩阵

    首先,我们看一下w3school上的例子:

     

    Javascript语法:context.transform( a , b , c , d , e , f );

    定义与用法:画布上的每个对象都拥有一个当前的变换矩阵。而transform则是用来定义一个新的矩阵,来替换原来的变换矩阵。

    六个参数,对应的矩阵就是:

    在这里,我说一下变换矩阵要用到的关于矩阵的知识,一个图形,在画布上无非是移动,缩小放大,还有旋转,斜切,等等。

    PS告诉我们,无论多复杂的图形,都是由一个个点组成的,变换矩阵要做的,无非是应用一定的算法,把一个图形上的一个点,映射到另一个点上。

    那么,我们就可以得出以下公式:

    根据中间那个矩阵的不同,我们就可以得到不同的变换效果。

    矩阵乘法是这样定义的:假设有两个矩阵A和B,如果要通过A*B得到C,那么矩阵A的列数必须与矩阵B的行数相同,方才能进行运算。得到的新的矩阵的第 i 行 ,第 j 列的值 就是A的第 i 行 与 B 的第 j 列相对应的值相乘,然后相加的结果。

    首先,我们来看看图形在画布上的移动。

    算法很简单:

                       X’ = X + a

                       Y’ = Y + b

    这样就把点(X,Y)移动到了(X’,Y’)。

    对应的变换的矩阵就是

    X’    1  0  a      X

    Y’    0  1  b  *   Y

    1    0  0  1      1

    X’ = 1*X + 0*Y + a*1;

    Y’ = 0*X + 1*Y + b*1;

    1 = 0*X + 0*Y + 1*1;

    那么,对应的JS代码就是context.transform(1,0,0,1,a,b);

    再看缩小放大,算法也很简单:

             X’ = X*a;

             Y’ = Y*b;

    Canvas是按照一定的算法来画图的,也就是说,Canvas画出来的图都是矢量图,不会因为放大与缩小而失真,那么,Canvas是如何实现放大与缩小的呢?

    其实,无非是对X轴,Y轴乘以各相对应的缩放因子,然后进行路径的描写,填充。

    对应的变换矩阵就是:

    X’      a    0    0      X

    Y’      0    b    0      Y

    1      0    0    1      1

    X’ = 1*X + 0 * Y + 0*1;

    Y’ = 0*X + b*Y + 0*1;

    1 = 0*X + 0*Y + 1*1;

    对应的JS代码就是 context.transform(a,0,0,b,0,0);

    再看看旋转,算法

     

    通过图可以看出来,B点是通过把A点旋转θ度得来的,即

    X’ = cos(a +θ) * r

    Y’ = sin(a +θ) * r

    根据三角函数公式:cos(α+β)=cosαcosβ-sinαsinβ

    可得 X’ = r*cosa*cosθ–r* sina * sinθ=  X * cosθ – Y * sinθ;

    同理可得 Y’ =  x*sinθ+y*cosθ;

    X’      cosθ    -sinθ   0      X

    Y’      sinθ    cosθ    0      Y

    1        0       0     1      1

    对应的JS代码就是 context.transform(Math.cos(θ * Math.PI/180) , Math.sin(θ*Math.PI/180) , - Math.sin(θ*Math.PI/180) , Math.cos(θ * Math.PI/180) , 0 , 0 );

    矩阵的好处就是用6个参数就可以表达出不同的算法来,虽然麻烦了点,但这样做是值得的。

    以此类推,斜切也是一样的,只是算法要复杂一些。

    记住,在canvas中先确定坐标系,再画图,其实,平移,放大缩小,斜切,旋转,都是针对坐标系的,应用不同的坐标系,就可以画出不同的图形来。

  • 相关阅读:
    ExpandoObject与DynamicObject的使用
    ManualResetEvent 线程通信
    CancellationTokenSource 取消任务
    SQL Server 每日一题--老二解析
    说说 C# 8 using 新特性
    SQL Server 每日一题--老二
    C#中的坑--浮点类型
    开胃菜解析
    开胃菜
    快速入门 Arrow 日期处理库
  • 原文地址:https://www.cnblogs.com/hemei/p/4252817.html
Copyright © 2011-2022 走看看