使用過前端的css3,canva,svg的小夥伴應該對平移,旋轉,縮放,剪切這些效果變換應該很熟悉了,但應該大部分小夥伴應該不清楚其中的原理,在二維圖形方面若是能熟練使用圖形學的基礎算法,結合canva,svg會有意想不到的驚喜。css
計算機圖形學中的應用很是普遍的變換是一種稱爲仿射變換的特殊變換,在仿射變換中的基本變換包括平移、旋轉、縮放、剪切這幾種。前端
設某點向x方向移動dx,y方向移動dy ,[x,y]爲變換前座標,[X,Y]爲變換後坐標。
則css3
X = x+dx; Y = y+dy;
以矩陣表示:
算法
首先要明確旋轉在二維中是繞着某一個點進行旋轉,三維中是繞着某一個軸進行旋轉。二維旋轉中最簡單的場景是繞着座標原點進行的旋轉,以下圖所示:canvas
如圖所示點v 繞 原點旋轉θ角,獲得點v’,假設 v點的座標是(x, y) ,那麼能夠推導獲得 v’點的座標(x’, y’),設原點到v的距離是r,原點到v點的向量與x軸的夾角是ϕsvg
x=rcosϕy=rsinϕ x′=rcos(θ+ϕ)y′=rsin(θ+ϕ)
經過三角函數展開獲得函數
x′=rcosθcosϕ−rsinθsinϕ y′=rsinθcosϕ+rcosθsinϕ
帶入x和y表達式獲得spa
x′=xcosθ−ysinθ y′=xsinθ+ycosθ
寫成矩陣的形式是:
code
儘管圖示中僅僅表示的是旋轉一個銳角θ的情形,可是咱們推導中使用的是三角函數的基本定義來計算座標的,所以當旋轉的角度是任意角度(例如大於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 = x1 y2 = y1 - x1 * tanθ
只貼上旋轉的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();