Skip to content

Commit

Permalink
fix(g-canvas): bbox calculation should be correct for path with arc, c…
Browse files Browse the repository at this point in the history
…lose #222
  • Loading branch information
dengfuping committed Oct 22, 2019
1 parent 688057a commit 82eb88c
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 5 deletions.
2 changes: 1 addition & 1 deletion packages/g-canvas/__tests__/bugs/issue-202-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('#202', () => {
height: 500,
});

it.only('the transformation from canvas coordinates to relative coordinates should be effective', (done) => {
it('the transformation from canvas coordinates to relative coordinates should be effective', (done) => {
const group = canvas.addGroup();
const circle = group.addShape('circle', {
attrs: {
Expand Down
54 changes: 54 additions & 0 deletions packages/g-canvas/tests/bugs/issue-222-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const expect = require('chai').expect;
import Canvas from '../../src/canvas';

const dom = document.createElement('div');
document.body.appendChild(dom);
dom.id = 'c1';

describe('#187', () => {
const canvas = new Canvas({
container: dom,
width: 600,
height: 600,
localRefresh: true, // 由于局部刷新依赖于图形的包围盒计算,因此测试时 localRefresh 需要为 true
});

it('bbox calculation should be correct for path with arc', () => {
const shape1 = canvas.addShape('path', {
attrs: {
fill: '#1890ff',
path: [
['M', 227.31794680557064, 200.00000266808433],
['L', 87.61525298763183, 98.50004569833794],
['A', 172.6820363488079, 172.6820363488079, 0, 0, 0, 63.08757910043951, 253.36168385505405],
['L', 227.31794680557064, 200.00000266808433],
['Z'],
],
},
});
const shape2 = canvas.addShape('path', {
attrs: {
fill: '#5D7092',
fillOpacity: 0.85,
lineWidth: 0,
path: [
['M', 227.31796092753956, 200.00000629398966],
['L', 63.08757910043951, 253.36168385505405],
['A', 172.68203634880794, 172.68203634880794, 0, 0, 0, 345.526943245539, 325.8797870175248],
['L', 227.31796092753956, 200.00000629398966],
['z'],
],
},
});
const bbox1 = shape1.getBBox();
const bbox2 = shape2.getBBox();
expect(bbox1.minX).eqls(54.63591866828193);
expect(bbox1.minY).eqls(98.50004569833794);
expect(bbox1.maxX).eqls(227.31794680557064);
expect(bbox1.maxY).eqls(253.36168385505414);
expect(bbox2.minX).eqls(63.087579100439484);
expect(bbox2.minY).eqls(200.00000629398966);
expect(bbox2.maxX).eqls(345.526943245539);
expect(bbox2.maxY).eqls(372.68203634880797);
});
});
20 changes: 16 additions & 4 deletions packages/g-math/src/arc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,14 @@ export default {
const xs = [startAngle, endAngle];
for (let i = -Math.PI * 2; i <= Math.PI * 2; i += Math.PI) {
const xAngle = xDim + i;
if (startAngle < xAngle && xAngle < endAngle) {
xs.push(xAngle);
if (startAngle < endAngle) {
if (startAngle < xAngle && xAngle < endAngle) {
xs.push(xAngle);
}
} else {
if (endAngle < xAngle && xAngle < startAngle) {
xs.push(xAngle);
}
}
}

Expand All @@ -93,8 +99,14 @@ export default {
const ys = [startAngle, endAngle];
for (let i = -Math.PI * 2; i <= Math.PI * 2; i += Math.PI) {
const yAngle = yDim + i;
if (startAngle < yAngle && yAngle < endAngle) {
ys.push(yAngle);
if (startAngle < endAngle) {
if (startAngle < yAngle && yAngle < endAngle) {
ys.push(yAngle);
}
} else {
if (endAngle < yAngle && yAngle < startAngle) {
ys.push(yAngle);
}
}
}

Expand Down
42 changes: 42 additions & 0 deletions packages/g-math/tests/unit/ellipse-arc-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,48 @@ describe('ellipse arc test', () => {
expect(box.width).eqls(p11.x - p21.x);
});

it('box, ellipse 0 when startAngle > endAngle', () => {
// 1 / 2 圆弧,旋转 0
const xRotation = 0;
const box = arc.box(100, 100, 20, 10, xRotation, Math.PI, 0);
const p1 = arc.pointAt(100, 100, 20, 10, 0, Math.PI, 0, 0);
const p2 = arc.pointAt(100, 100, 20, 10, 0, Math.PI, 0, 1);
const p11 = rotation({ x: 100, y: 100 }, p1, xRotation);
const p21 = rotation({ x: 100, y: 100 }, p2, xRotation);

ctx.beginPath();
ctx.ellipse(100, 100, 20, 10, xRotation, 0, Math.PI);
ctx.stroke();

ctx.beginPath();
ctx.strokeRect(box.x, box.y, box.width, box.height);
expect(box.x).eqls(p11.x);
expect(box.y).eqls(p11.y);
expect(box.width).eqls(p21.x - p11.x);
expect(box.height).eqls(10);
});

it('box, ellipse 90 when startAngle > endAngle', () => {
// 1 / 2 圆弧,旋转 90
const xRotation = Math.PI / 2;
const box = arc.box(100, 100, 20, 10, xRotation, Math.PI, 0);
const p1 = arc.pointAt(100, 100, 20, 10, 0, Math.PI, 0, 0);
const p2 = arc.pointAt(100, 100, 20, 10, 0, Math.PI, 0, 1);
const p11 = rotation({ x: 100, y: 100 }, p1, xRotation);
const p21 = rotation({ x: 100, y: 100 }, p2, xRotation);

ctx.beginPath();
ctx.ellipse(100, 100, 20, 10, xRotation, 0, Math.PI);
ctx.stroke();

ctx.beginPath();
ctx.strokeRect(box.x, box.y, box.width, box.height);
expect(box.x).eqls(p21.x - 10);
expect(box.y).eqls(p11.y);
expect(box.width).eqls(10);
expect(box.height).eqls(40);
});

it('tangent angle', () => {
expect(arc.tangentAngle(0, 0, 10, 10, 0, 0, Math.PI, 0)).eqls(Math.PI / 2);
expect(arc.tangentAngle(0, 0, 10, 10, 0, 0, Math.PI, 1)).eqls(Math.PI / 2 + Math.PI);
Expand Down

0 comments on commit 82eb88c

Please sign in to comment.