@@ -115,6 +115,118 @@ function isPtInsideSector(r, a, rRng, sector) {
115
115
return r >= r0 && r <= r1 ;
116
116
}
117
117
118
+ // common to pathArc, pathSector and pathAnnulus
119
+ function _path ( r0 , r1 , a0 , a1 , cx , cy , isClosed ) {
120
+ cx = cx || 0 ;
121
+ cy = cy || 0 ;
122
+
123
+ var isCircle = isFullCircle ( [ a0 , a1 ] . map ( rad2deg ) ) ;
124
+ var aStart , aMid , aEnd ;
125
+ var rStart , rEnd ;
126
+
127
+ if ( isCircle ) {
128
+ aStart = 0 ;
129
+ aMid = PI ;
130
+ aEnd = 2 * PI ;
131
+ } else {
132
+ if ( a0 < a1 ) {
133
+ aStart = a0 ;
134
+ aEnd = a1 ;
135
+ } else {
136
+ aStart = a1 ;
137
+ aEnd = a0 ;
138
+ }
139
+ }
140
+
141
+ if ( r0 < r1 ) {
142
+ rStart = r0 ;
143
+ rEnd = r1 ;
144
+ } else {
145
+ rStart = r1 ;
146
+ rEnd = r0 ;
147
+ }
148
+
149
+ // N.B. svg coordinates here, where y increases downward
150
+ function pt ( r , a ) {
151
+ return [ r * Math . cos ( a ) + cx , cy - r * Math . sin ( a ) ] ;
152
+ }
153
+
154
+ var largeArc = Math . abs ( aEnd - aStart ) <= PI ? 0 : 1 ;
155
+ function arc ( r , a , cw ) {
156
+ return 'A' + [ r , r ] + ' ' + [ 0 , largeArc , cw ] + ' ' + pt ( r , a ) ;
157
+ }
158
+
159
+ var p ;
160
+
161
+ if ( isCircle ) {
162
+ if ( rStart === null ) {
163
+ p = 'M' + pt ( rEnd , aStart ) +
164
+ arc ( rEnd , aMid , 0 ) +
165
+ arc ( rEnd , aEnd , 0 ) + 'Z' ;
166
+ } else {
167
+ p = 'M' + pt ( rStart , aStart ) +
168
+ arc ( rStart , aMid , 0 ) +
169
+ arc ( rStart , aEnd , 0 ) + 'Z' +
170
+ 'M' + pt ( rEnd , aStart ) +
171
+ arc ( rEnd , aMid , 1 ) +
172
+ arc ( rEnd , aEnd , 1 ) + 'Z' ;
173
+ }
174
+ } else {
175
+ if ( rStart === null ) {
176
+ p = 'M' + pt ( rEnd , aStart ) + arc ( rEnd , aEnd , 0 ) ;
177
+ if ( isClosed ) p += 'L0,0Z' ;
178
+ } else {
179
+ p = 'M' + pt ( rStart , aStart ) +
180
+ 'L' + pt ( rEnd , aStart ) +
181
+ arc ( rEnd , aEnd , 0 ) +
182
+ 'L' + pt ( rStart , aEnd ) +
183
+ arc ( rStart , aStart , 1 ) + 'Z' ;
184
+ }
185
+ }
186
+
187
+ return p ;
188
+ }
189
+
190
+ /* path an arc
191
+ *
192
+ * @param {number } r : radius
193
+ * @param {number } a0 : first angular coordinate
194
+ * @param {number } a1 : second angular coordinate
195
+ * @param {number (optional) } cx : x coordinate of center
196
+ * @param {number (optional) } cy : y coordinate of center
197
+ * @return {string } svg path
198
+ */
199
+ function pathArc ( r , a0 , a1 , cx , cy ) {
200
+ return _path ( null , r , a0 , a1 , cx , cy , 0 ) ;
201
+ }
202
+
203
+ /* path a sector
204
+ *
205
+ * @param {number } r : radius
206
+ * @param {number } a0 : first angular coordinate
207
+ * @param {number } a1 : second angular coordinate
208
+ * @param {number (optional) } cx : x coordinate of center
209
+ * @param {number (optional) } cy : y coordinate of center
210
+ * @return {string } svg path
211
+ */
212
+ function pathSector ( r , a0 , a1 , cx , cy ) {
213
+ return _path ( null , r , a0 , a1 , cx , cy , 1 ) ;
214
+ }
215
+
216
+ /* path an annulus
217
+ *
218
+ * @param {number } r0 : first radial coordinate
219
+ * @param {number } r1 : second radial coordinate
220
+ * @param {number } a0 : first angular coordinate
221
+ * @param {number } a1 : second angular coordinate
222
+ * @param {number (optional) } cx : x coordinate of center
223
+ * @param {number (optional) } cy : y coordinate of center
224
+ * @return {string } svg path
225
+ */
226
+ function pathAnnulus ( r0 , r1 , a0 , a1 , cx , cy ) {
227
+ return _path ( r0 , r1 , a0 , a1 , cx , cy , 1 ) ;
228
+ }
229
+
118
230
module . exports = {
119
231
deg2rad : deg2rad ,
120
232
rad2deg : rad2deg ,
@@ -124,5 +236,8 @@ module.exports = {
124
236
angleDist : angleDist ,
125
237
isFullCircle : isFullCircle ,
126
238
isAngleInsideSector : isAngleInsideSector ,
127
- isPtInsideSector : isPtInsideSector
239
+ isPtInsideSector : isPtInsideSector ,
240
+ pathArc : pathArc ,
241
+ pathSector : pathSector ,
242
+ pathAnnulus : pathAnnulus
128
243
} ;
0 commit comments