博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【JS图形学基础】二维图形学的变换
阅读量:6703 次
发布时间:2019-06-25

本文共 1866 字,大约阅读时间需要 6 分钟。

二维图形学的变换

使用过前端的css3,canva,svg的小伙伴应该对平移,旋转,缩放,剪切这些效果变换应该很熟悉了,但应该大部分小伙伴应该不清楚其中的原理,在二维图形方面如果能熟练使用图形学的基础算法,结合canva,svg会有意想不到的惊喜。

计算机图形学中的应用非常广泛的变换是一种称为仿射变换的特殊变换,在仿射变换中的基本变换包括平移、旋转、缩放、剪切这几种。

平移

设某点向x方向移动dx,y方向移动dy ,[x,y]为变换前坐标,[X,Y]为变换后坐标。

X = x+dx;  Y = y+dy;

以矩阵表示:

图片描述

旋转

首先要明确旋转在二维中是绕着某一个点进行旋转,三维中是绕着某一个轴进行旋转。二维旋转中最简单的场景是绕着坐标原点进行的旋转,如下图所示:

图片描述

如图所示点v 绕 原点旋转θ角,得到点v’,假设 v点的坐标是(x, y) ,那么可以推导得到 v’点的坐标(x’, y’),设原点到v的距离是r,原点到v点的向量与x轴的夹角是ϕ

x=rcosϕy=rsinϕ x′=rcos(θ+ϕ)y′=rsin(θ+ϕ)

通过三角函数展开得到

x′=rcosθcosϕ−rsinθsinϕ y′=rsinθcosϕ+rcosθsinϕ

带入x和y表达式得到

x′=xcosθ−ysinθ y′=xsinθ+ycosθ

写成矩阵的形式是:

图片描述

尽管图示中仅仅表示的是旋转一个锐角θ的情形,但是我们推导中使用的是三角函数的基本定义来计算坐标的,因此当旋转的角度是任意角度(例如大于180度,导致v’点进入到第四象限)结论仍然是成立的。

绕任意点的二维旋转

图片描述

图片描述

缩放

简单缩放

简单缩放可以直接通过将缩放系数sx,sy与对应x,y坐标相乘:

x’=x*sx,y’=y*sy

基于一个固定点缩放

图片描述

x’ = x * sx + sy(1-sx)y’ = y * sy + yf(1-sy)

其中sx,sy属于缩放系数。0~1表示缩小,>1表示放大

错切

图像错切变换在图像几何形变方面非常有用,常见的错切变换分为X方向与Y方向的错切变换。对应的数学矩阵分别如下:

图片描述
根据上述矩阵假设P(x1, y1)为错切变换之前的像素点,则错切变换以后对应的像素

P’(x2, y2)当X方向错切变换时:

x2 = x1 - y1 * tanθy2 = y1

当Y方向错切变换时:

x2 = x1y2 = y1 - x1 * tanθ

实例

svg

canvas

只贴上旋转的demo,其他都可以仿照套用

旋转

橘色的点围绕蓝色旋转

图片描述

var canvas = document.getElementById("canvas");    var context = canvas.getContext('2d');    context.beginPath();    context.fillStyle = "#3399ff";    context.arc(100, 75, 5, 0, 2 * Math.PI);    context.fill();    //点a围绕(100,75) 顺时针90度旋转    var a = { x: 150, y: 75 }    //套用上文公式    //- 0.5 * Math.PI 因为canvas的0    var x = 100 + (a.x - 100) * Math.cos(Math.PI / 2) - (a.y - 75) * Math.sin(Math.PI / 2);    //y为简化后    var y = 75 + (a.x - 100) * Math.sin(Math.PI / 2);    context.beginPath();    context.fillStyle = "#fe9901";    context.arc(x, y, 5, 0, 2 * Math.PI);    context.fill();    //围绕100,75 60度旋转    var x = 100 + 50 * Math.cos(Math.PI / 3);    var y = 75 + 50 * Math.sin(Math.PI / 3);    context.beginPath();    context.fillStyle = "#fe9901";    context.arc(x, y, 5, 0, 2 * Math.PI);    context.fill();

转载地址:http://acblo.baihongyu.com/

你可能感兴趣的文章
eclipse 配置Android开发环境
查看>>
django 1.8 官方文档翻译: 1-2-6 编写你的第一个Django应用,第6部分
查看>>
JavaScript 复杂判断的更优雅写法
查看>>
MeasureOverride 和 ArrangeOverride
查看>>
Salesforce如何在人工智能领域“杀出一条血路”?
查看>>
Redisson实现Redis分布式锁的N种姿势
查看>>
kafka-storm 详细
查看>>
WebStorm 2019.1 正式发布,为 JS 和 TS 提供更好的智能感知
查看>>
Docker 常用命令总结
查看>>
使用Python请求http/https时设置失败重试次数
查看>>
系统中信息的表示和处理 --《深入理解计算机系统》第二章读书笔记
查看>>
把模块有关联的放在一个文件夹中 在python2中调用文件夹名会直接失败 在python3中调用会成功,但是调用不能成功的解决方案...
查看>>
创新项目从来都是在负债之下做架构取舍
查看>>
搞懂分布式技术14:Spring Boot使用注解集成Redis缓存
查看>>
分布式系列三: 对象序列化
查看>>
iOS面试题·自整理·One
查看>>
C语言-结构体
查看>>
iOS-《编写高质量代码》笔记-第一章
查看>>
P4:编程网络的转发平面
查看>>
百度web前端--2015笔试
查看>>