Skip to content

Commit 7d9298c

Browse files
committed
Fix: Initialize shape with vertex properties in arc() to match ellipse() pattern
1 parent 20b191f commit 7d9298c

1 file changed

Lines changed: 53 additions & 37 deletions

File tree

src/shape/custom_shapes.js

Lines changed: 53 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)