@@ -495,6 +495,8 @@ class ArcPrimitive extends ShapePrimitive {
495495 get start ( ) { return this . #start; }
496496 get stop ( ) { return this . #stop; }
497497 get mode ( ) { return this . #mode; }
498+ get startVertex ( ) { return this . vertices [ 0 ] ; }
499+ get endVertex ( ) { return this . vertices [ 1 ] ; }
498500
499501 get vertexCapacity ( ) {
500502 return this . #vertexCapacity;
@@ -976,20 +978,23 @@ class Shape {
976978
977979
978980 arcPrimitive ( x , y , w , h , start , stop , mode ) {
981+ this . beginShape ( ) ;
979982 const centerX = x + w / 2 ;
980983 const centerY = y + h / 2 ;
984+ const radiusX = w / 2 ;
985+ const radiusY = h / 2 ;
981986
982987 const startVertex = this . #createVertex(
983988 new Vector (
984- centerX + ( w / 2 ) * Math . cos ( start ) ,
985- centerY + ( h / 2 ) * Math . sin ( start )
989+ centerX + radiusX * Math . cos ( start ) ,
990+ centerY + radiusY * Math . sin ( start )
986991 )
987992 ) ;
988993
989994 const endVertex = this . #createVertex(
990995 new Vector (
991- centerX + ( w / 2 ) * Math . cos ( stop ) ,
992- centerY + ( h / 2 ) * Math . sin ( stop )
996+ centerX + radiusX * Math . cos ( stop ) ,
997+ centerY + radiusY * Math . sin ( stop )
993998 )
994999 ) ;
9951000
@@ -1001,7 +1006,9 @@ class Shape {
10011006 stop ,
10021007 mode
10031008 ) ;
1004- return primitive . addToShape ( this ) ;
1009+ primitive . addToShape ( this ) ;
1010+ this . endShape ( ) ;
1011+ return this ;
10051012
10061013 }
10071014
@@ -1419,44 +1426,47 @@ class PrimitiveToVerticesConverter extends PrimitiveVisitor {
14191426 this . contours . push ( quadStrip . vertices . slice ( ) ) ;
14201427 }
14211428 visitArcPrimitive ( arc ) {
1429+ const startVertex = arc . startVertex ;
1430+ const endVertex = arc . endVertex ;
14221431 const centerX = arc . x + arc . w / 2 ;
14231432 const centerY = arc . y + arc . h / 2 ;
14241433 const radiusX = arc . w / 2 ;
14251434 const radiusY = arc . h / 2 ;
1426- const avgRadius = ( radiusX + radiusY ) / 2 ;
1435+ const avgRadius = ( radiusX + radiusY ) / 2 ;
14271436
1428- const arcLength = avgRadius * Math . abs ( arc . stop - arc . start ) ;
1437+ const arcLength = avgRadius * Math . abs ( arc . stop - arc . start ) ;
14291438
1430- const numPoints = Math . max ( 3 , Math . ceil ( this . curveDetail * arcLength ) ) ;
1439+ const numPoints = Math . max ( 3 , Math . ceil ( this . curveDetail * arcLength ) ) ;
14311440 const verts = [ ] ;
1432-
1441+ const interpolateVertexProps = ( v1 , v2 , t ) => {
1442+ const props = { } ;
1443+ for ( const [ key , value ] of Object . entries ( v1 ) ) {
1444+ if ( key === 'position' ) continue ;
1445+ if ( typeof value === 'number' && typeof v2 [ key ] === 'number' ) {
1446+ props [ key ] = value * ( 1 - t ) + v2 [ key ] * t ;
1447+ } else {
1448+ props [ key ] = value ;
1449+ }
1450+ }
1451+ return props ;
1452+ } ;
14331453 if ( arc . mode === constants . PIE ) {
1434- verts . push ( new Vertex ( { position : new Vector ( centerX , centerY ) } ) ) ;
1454+ const centerProps = interpolateVertexProps ( startVertex , endVertex , 0.5 ) ;
1455+ centerProps . position = new Vector ( centerX , centerY ) ;
1456+ verts . push ( new Vertex ( centerProps ) ) ;
14351457 }
14361458
14371459 for ( let i = 0 ; i <= numPoints ; i ++ ) {
1438- const angle = arc . start + ( arc . stop - arc . start ) * ( i / numPoints ) ;
1439- const startVertex = arc . vertices [ 0 ] ;
1440- const endVertex = arc . vertices [ 1 ] ;
1441- const t = i / numPoints ;
1442- const props = { } ;
1443- for ( const key in startVertex ) {
1444- if ( key === 'position' ) continue ;
1445- if ( typeof startVertex [ key ] === 'number'
1446- && typeof endVertex [ key ] === 'number' ) {
1447- props [ key ] = startVertex [ key ] * ( 1 - t ) + endVertex [ key ] * t ;
1448- }
1449- else {
1450- props [ key ] = startVertex [ key ] ;
1451- }
1452- }
1460+ const t = i / numPoints ;
1461+ const angle = arc . start + ( arc . stop - arc . start ) * t ;
1462+ const vertexProps = interpolateVertexProps ( startVertex , endVertex , t ) ;
14531463
1454- props . position = new Vector (
1455- centerX + radiusX * Math . cos ( angle ) ,
1456- centerY + radiusY * Math . sin ( angle )
1464+ vertexProps . position = new Vector (
1465+ centerX + radiusX * Math . cos ( angle ) ,
1466+ centerY + radiusY * Math . sin ( angle )
14571467 ) ;
14581468
1459- verts . push ( new Vertex ( props ) ) ;
1469+ verts . push ( new Vertex ( vertexProps ) ) ;
14601470 }
14611471
14621472 this . contours . push ( verts ) ;
@@ -1466,17 +1476,23 @@ class PrimitiveToVerticesConverter extends PrimitiveVisitor {
14661476 const centerY = ellipse . y + ellipse . h / 2 ;
14671477 const radiusX = ellipse . w / 2 ;
14681478 const radiusY = ellipse . h / 2 ;
1469- const numPoints = Math . max ( 3 , this . curveDetail ) ;
1479+ const avgRadius = ( radiusX + radiusY ) / 2 ;
1480+ const perimeter = 2 * Math . PI * avgRadius ;
1481+ const numPoints = Math . max ( 3 , Math . ceil ( this . curveDetail * perimeter ) ) ;
14701482 const verts = [ ] ;
1471-
1483+ const centerVertex = ellipse . vertices [ 0 ] ;
14721484 for ( let i = 0 ; i <= numPoints ; i ++ ) {
14731485 const angle = ( 2 * Math . PI * i ) / numPoints ;
1474- verts . push ( new Vertex ( {
1475- position : new Vector (
1476- centerX + radiusX * Math . cos ( angle ) ,
1477- centerY + radiusY * Math . sin ( angle )
1478- )
1479- } ) ) ;
1486+ const vertexProps = { } ;
1487+ for ( const [ key , value ] of Object . entries ( centerVertex ) ) {
1488+ if ( key === 'position' ) continue ;
1489+ vertexProps [ key ] = value ;
1490+ }
1491+ vertexProps . position = new Vector (
1492+ centerX + radiusX * Math . cos ( angle ) ,
1493+ centerY + radiusY * Math . sin ( angle )
1494+ ) ;
1495+ verts . push ( new Vertex ( vertexProps ) ) ;
14801496 }
14811497
14821498 this . contours . push ( verts ) ;
0 commit comments