on master help sign in
Add `groupTransform` function.

Add public Matrix library. Clean up and debug matrix implementation.

commit893e4691e6ebcc13914eb3ca2ccf0148edd54471 authorevancz <info@elm-lang.org> dateSat 23 Mar 2013, 23:54 (14 years ago) parent26bcdd2
4 files changed+78−23
libraries/Graphics/Collage.elm+9−6 libraries/Graphics/Matrix.elm+18 libraries/Native/Graphics/Matrix.js+44−16 runtime/Render/Collage.js+7−1
libraries/Graphics/Collage.elm+9−6
@@ -26,7 +26,7 @@ data BasicForm
2626 | FShape (Either LineStyle FillStyle) Shape
2727 | FImage Int Int (Int,Int) String
2828 | FElement Element
29− | FGroup [Form]
29+ | FGroup Matrix [Form]
3030
3131form f = { theta = 0, scale = 1, x = 0, y = 0, form = f }
3232
@@ -41,11 +41,11 @@ textured src shape = fill (Texture src) shape
4141gradient : Gradient -> Shape -> Form
4242gradient grad shape = fill (Gradient grad) shape
4343
44−outline : LineStyle -> Shape -> Form
45−outline style shape = form (FShape (Left style) shape)
44+outlined : LineStyle -> Shape -> Form
45+outlined style shape = form (FShape (Left style) shape)
4646
47−trace : LineStyle -> Path -> Form
48−trace style path = form (FPath style path)
47+traced : LineStyle -> Path -> Form
48+traced style path = form (FPath style path)
4949
5050sprite : Int -> Int -> (Int,Int) -> String -> Form
5151sprite w h pos src = form (FImage w h pos src)
@@ -54,7 +54,10 @@ toForm : Element -> Form
5454toForm e = form (FElement e)
5555
5656group : [Form] -> Form
57−group fs = form (FGroup fs)
57+group fs = form (FGroup Matrix.identity fs)
58+
59+groupTransform : Matrix -> [Form] -> Form
60+groupTransform matrix fs = form (FGroup matrix fs)
5861
5962rotate : Float -> Form -> Form
6063rotate t f = { f | theta <- f.theta + t }
libraries/Graphics/Matrix.elmnew file+18
@@ -0,0 +1,18 @@
1+
2+module Graphics.Matrix where
3+
4+import Native.Graphics.Matrix as M
5+
6+identity : Matrix
7+
8+transform : Float -> Float -> Float -> Float -> Float -> Float -> Matrix -> Matrix
9+rotate : Float -> Matrix -> Matrix
10+move : Float -> Float -> Matrix -> Matrix
11+scale : Float -> Matrix -> Matrix
12+scaleX : Float -> Matrix -> Matrix
13+scaleY : Float -> Matrix -> Matrix
14+reflectX : Matrix -> Matrix
15+reflectY : Matrix -> Matrix
16+
17+multiply : Matrix -> Matrix -> Matrix
18+matrix : Float -> Float -> Float -> Float -> Float -> Float -> Matrix
libraries/Native/Graphics/Matrix.js+44−16
@@ -9,36 +9,64 @@ Elm.Native.Graphics.Matrix = function(elm) {
99 try { Float32Array; } catch(e) { Float32Array = Array; }
1010 var A = Float32Array;
1111
12+ // layout of matrix in an array is
13+ //
14+ // | m11 m12 dx |
15+ // | m21 m22 dy |
16+ // | 0 0 1 |
17+ //
18+ // new A([ m11, m12, dx, m21, m22, dy ])
19+
1220 var identity = new A([1,0,0,0,1,0]);
21+ function matrix(m11, m21, m12, m22, dx, dy) {
22+ return new A([m11, m12, dx, m21, m22, dy]);
23+ }
1324
1425 function rotate(t,m) {
1526 var c = Math.cos(t);
1627 var s = Math.sin(t);
17− var m0 = m[0], m1 = m[1], m3 = m[3], m4 = m[4];
18− return new A([m0*c + m1*-s, m0*s + m1*c, m[2],
19− m3*c + m4*-s, m3*s + m4*c, m[5]]);
20− }
21− function scale(x,y,m) {
22− return new A([m[0]*x, m[1]*y, m[2],
23− m[3]*x, m[4]*y, m[5]]);
28+ var m11 = m[0], m12 = m[1], m21 = m[3], m22 = m[4];
29+ return new A([m11*c + m12*s, -m11*s + m12*c, m[2],
30+ m21*c + m22*s, -m21*s + m22*c, m[5]]);
2431 }
2532 function move(x,y,m) {
26− var m0 = m[0], m1 = m[1], m3 = m[3], m4 = m[4];
27− return new A([m0, m1, m0*x + m1*y + m[2],
28− m3, m4, m3*x + m4*y + m[5]]);
33+ var m11 = m[0], m12 = m[1], m21 = m[3], m22 = m[4];
34+ return new A([m11, m12, m11*x + m12*y + m[2],
35+ m21, m22, m21*x + m22*y + m[5]]);
2936 }
30− function matrix(n11, n12, n21, n22, dx, dy, m) {
31− var m0 = m[0], m1 = m[1], m3 = m[3], m4 = m[4];
32− return new A([m0*n11 + m1*n12, m0*n21 + m1*n22, m0*dx + m1*dy + m[2],
33− m3*n11 + m4*n12, m3*n21 + m4*n22, m3*dx + m4*dy + m[5]]);
37+ function scale(s,m) { return new A([m[0]*s, m[1]*s, m[2], m[3]*s, m[4]*s, m[5]]); }
38+ function scaleX(x,m) { return new A([m[0]*x, m[1], m[2], m[3]*x, m[4], m[5]]); }
39+ function scaleY(y,m) { return new A([m[0], m[1]*y, m[2], m[3], m[4]*y, m[5]]); }
40+ function reflectX(m) { return new A([-m[0], m[1], m[2], -m[3], m[4], m[5]]); }
41+ function reflectY(m) { return new A([m[0], -m[1], m[2], m[3], -m[4], m[5]]); }
42+
43+ function transform(m11, m21, m12, m22, mdx, mdy, n) {
44+ var n11 = n[0], n12 = n[1], n21 = n[3], n22 = n[4], ndx = n[2], ndy = n[5];
45+ return new A([m11*n11 + m12*n21,
46+ m11*n12 + m12*n22,
47+ m11*ndx + m12*ndy + mdx,
48+ m21*n11 + m22*n21,
49+ m21*n12 + m22*n22,
50+ m21*ndx + m22*ndy + mdy]);
51+ }
52+
53+ function multiply(m, n) {
54+ return transform(m[0], m[3], m[1], m[4], m[2], m[5], n);
3455 }
3556
3657 return elm.Native.Graphics.Matrix = {
3758 identity:identity,
59+ matrix:F6(matrix),
60+ multiply:F2(multiply),
61+
62+ transform:F7(transform),
3863 rotate:F2(rotate),
39− scale:F3(scale),
4064 move:F3(move),
41− matrix:F7(matrix)
65+ scale:F2(scale),
66+ scaleX:F2(scaleX),
67+ scaleY:F2(scaleY),
68+ reflectX:reflectX,
69+ reflectY:reflectY
4270 };
4371
4472};
runtime/Render/Collage.js+7−1
@@ -128,7 +128,13 @@ function renderForm(redo,ctx,form) {
128128 }
129129 break;
130130 case 'FImage': drawImage(redo, ctx, f); break;
131− case 'FGroup': renderForms(redo, ctx, f._0); break;
131+ case 'FGroup':
132+ ctx.save();
133+ var m = f._0;
134+ ctx.transform(m[0], m[3], m[1], m[4], m[2], m[5]);
135+ renderForms(redo, ctx, f._1);
136+ ctx.restore();
137+ break;
132138 }
133139 ctx.restore();
134140}