diff --git a/packages/g-base/src/bbox/path.ts b/packages/g-base/src/bbox/path.ts index 227054296..245e738ac 100644 --- a/packages/g-base/src/bbox/path.ts +++ b/packages/g-base/src/bbox/path.ts @@ -1,9 +1,11 @@ -import { SimpleBBox } from '../types'; -import { IShape } from '../interfaces'; import QuadUtil from '@antv/g-math/lib/quadratic'; import CubicUtil from '@antv/g-math/lib/cubic'; import EllipseArcUtil from '@antv/g-math/lib/arc'; import path2Segments from '@antv/path-util/lib/path-2-segments'; +import isNumberEqual from '@antv/util/lib/is-number-equal'; +import { SimpleBBox } from '../types'; +import { IShape } from '../interfaces'; + function getPathBox(segments, lineWidth) { let xArr = []; let yArr = []; @@ -98,7 +100,8 @@ function getExtraFromSegmentWithAngle(segment, lineWidth) { (currentAndPre + currentAndNext - preAndNext) / (2 * Math.sqrt(currentAndPre) * Math.sqrt(currentAndNext)) ); // 夹角为空、 0 或 PI 时,不需要计算夹角处的额外宽度 - if (!currentAngle || Math.sin(currentAngle) === 0) { + // 注意: 由于计算精度问题,夹角为 0 的情况计算出来的角度可能是一个很小的值,还需要判断其与 0 是否近似相等 + if (!currentAngle || Math.sin(currentAngle) === 0 || isNumberEqual(currentAngle, 0)) { return { xExtra: 0, yExtra: 0, diff --git a/packages/g-canvas/tests/bugs/issue-436-spec.js b/packages/g-canvas/tests/bugs/issue-436-spec.js new file mode 100644 index 000000000..b78ac9e16 --- /dev/null +++ b/packages/g-canvas/tests/bugs/issue-436-spec.js @@ -0,0 +1,37 @@ +const expect = require('chai').expect; +import Canvas from '../../src/canvas'; + +const dom = document.createElement('div'); +document.body.appendChild(dom); +dom.id = 'c1'; + +describe('#436', () => { + const canvas = new Canvas({ + container: dom, + width: 1000, + height: 400, + }); + + it('should consider precision of angle calculation for Path', () => { + const path = canvas.addShape('path', { + attrs: { + stroke: 'red', + lineWidth: 2, + path: [ + ['M', 54.88829007174579, 78.53153216848064], + ['L', 729.5, 78.53153216848064], + ['L', 729.5, 121.46846783151936], + ['L', 869.5, 121.46846783151936], + ['L', 175.11170992825421, 121.46846783151936], + ], + endArrow: true, + }, + }); + + const bbox = path.getBBox(); + expect(bbox.minX).eqls(53.88829007174579); + expect(bbox.minY).eqls(77.53153216848064); + expect(bbox.maxX).eqls(870.5); + expect(bbox.maxY).eqls(122.46846783151936); + }); +});