source: Dev/branches/rest-dojo-ui/client/dojox/gfx/arc.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 4.2 KB
Line 
1define(["./_base", "dojo/_base/lang", "./matrix"],
2  function(g, lang, m){
3/*=====
4        g = dojox.gfx;
5        dojox.gfx.arc = {
6                // summary:
7                //              This module contains the core graphics Arc functions.
8        };
9  =====*/
10
11        var twoPI = 2 * Math.PI, pi4 = Math.PI / 4, pi8 = Math.PI / 8,
12                pi48 = pi4 + pi8, curvePI4 = unitArcAsBezier(pi8);
13
14        function unitArcAsBezier(alpha){
15                // summary: return a start point, 1st and 2nd control points, and an end point of
16                //              a an arc, which is reflected on the x axis
17                // alpha: Number
18                //              angle in radians, the arc will be 2 * angle size
19                var cosa  = Math.cos(alpha), sina  = Math.sin(alpha),
20                        p2 = {x: cosa + (4 / 3) * (1 - cosa), y: sina - (4 / 3) * cosa * (1 - cosa) / sina};
21                return {        // Object
22                        s:  {x: cosa, y: -sina},
23                        c1: {x: p2.x, y: -p2.y},
24                        c2: p2,
25                        e:  {x: cosa, y: sina}
26                };
27        }
28
29        var arc = g.arc = {
30                unitArcAsBezier: unitArcAsBezier,
31                /*=====
32                        unitArcAsBezier: function(alpha) {
33                        // summary: return a start point, 1st and 2nd control points, and an end point of
34                        //              a an arc, which is reflected on the x axis
35                        // alpha: Number
36                        //              angle in radians, the arc will be 2 * angle size
37                        },
38                =====*/
39                curvePI4: curvePI4,
40                        // curvePI4: Object
41                        //              an object with properties of an arc around a unit circle from 0 to pi/4
42                arcAsBezier: function(last, rx, ry, xRotg, large, sweep, x, y){
43                        // summary: calculates an arc as a series of Bezier curves
44                        //      given the last point and a standard set of SVG arc parameters,
45                        //      it returns an array of arrays of parameters to form a series of
46                        //      absolute Bezier curves.
47                        // last: Object
48                        //              a point-like object as a start of the arc
49                        // rx: Number
50                        //              a horizontal radius for the virtual ellipse
51                        // ry: Number
52                        //              a vertical radius for the virtual ellipse
53                        // xRotg: Number
54                        //              a rotation of an x axis of the virtual ellipse in degrees
55                        // large: Boolean
56                        //              which part of the ellipse will be used (the larger arc if true)
57                        // sweep: Boolean
58                        //              direction of the arc (CW if true)
59                        // x: Number
60                        //              the x coordinate of the end point of the arc
61                        // y: Number
62                        //              the y coordinate of the end point of the arc
63
64                        // calculate parameters
65                        large = Boolean(large);
66                        sweep = Boolean(sweep);
67                        var xRot = m._degToRad(xRotg),
68                                rx2 = rx * rx, ry2 = ry * ry,
69                                pa = m.multiplyPoint(
70                                        m.rotate(-xRot),
71                                        {x: (last.x - x) / 2, y: (last.y - y) / 2}
72                                ),
73                                pax2 = pa.x * pa.x, pay2 = pa.y * pa.y,
74                                c1 = Math.sqrt((rx2 * ry2 - rx2 * pay2 - ry2 * pax2) / (rx2 * pay2 + ry2 * pax2));
75                        if(isNaN(c1)){ c1 = 0; }
76                        var     ca = {
77                                        x:  c1 * rx * pa.y / ry,
78                                        y: -c1 * ry * pa.x / rx
79                                };
80                        if(large == sweep){
81                                ca = {x: -ca.x, y: -ca.y};
82                        }
83                        // the center
84                        var c = m.multiplyPoint(
85                                [
86                                        m.translate(
87                                                (last.x + x) / 2,
88                                                (last.y + y) / 2
89                                        ),
90                                        m.rotate(xRot)
91                                ],
92                                ca
93                        );
94                        // calculate the elliptic transformation
95                        var elliptic_transform = m.normalize([
96                                m.translate(c.x, c.y),
97                                m.rotate(xRot),
98                                m.scale(rx, ry)
99                        ]);
100                        // start, end, and size of our arc
101                        var inversed = m.invert(elliptic_transform),
102                                sp = m.multiplyPoint(inversed, last),
103                                ep = m.multiplyPoint(inversed, x, y),
104                                startAngle = Math.atan2(sp.y, sp.x),
105                                endAngle   = Math.atan2(ep.y, ep.x),
106                                theta = startAngle - endAngle;  // size of our arc in radians
107                        if(sweep){ theta = -theta; }
108                        if(theta < 0){
109                                theta += twoPI;
110                        }else if(theta > twoPI){
111                                theta -= twoPI;
112                        }
113
114                        // draw curve chunks
115                        var alpha = pi8, curve = curvePI4, step  = sweep ? alpha : -alpha,
116                                result = [];
117                        for(var angle = theta; angle > 0; angle -= pi4){
118                                if(angle < pi48){
119                                        alpha = angle / 2;
120                                        curve = unitArcAsBezier(alpha);
121                                        step  = sweep ? alpha : -alpha;
122                                        angle = 0;      // stop the loop
123                                }
124                                var c2, e, M = m.normalize([elliptic_transform, m.rotate(startAngle + step)]);
125                                if(sweep){
126                                        c1 = m.multiplyPoint(M, curve.c1);
127                                        c2 = m.multiplyPoint(M, curve.c2);
128                                        e  = m.multiplyPoint(M, curve.e );
129                                }else{
130                                        c1 = m.multiplyPoint(M, curve.c2);
131                                        c2 = m.multiplyPoint(M, curve.c1);
132                                        e  = m.multiplyPoint(M, curve.s );
133                                }
134                                // draw the curve
135                                result.push([c1.x, c1.y, c2.x, c2.y, e.x, e.y]);
136                                startAngle += 2 * step;
137                        }
138                        return result;  // Array
139                }
140        };
141       
142        return arc;
143});
Note: See TracBrowser for help on using the repository browser.