如何获得宽度和宽度;HTML5画布中绘制的弧的高度?

如何获得宽度和宽度;HTML5画布中绘制的弧的高度?,html,canvas,html5-canvas,kineticjs,konvajs,Html,Canvas,Html5 Canvas,Kineticjs,Konvajs,我使用库绘制了一些圆弧,但在绘制对象后无法获得其宽度和高度,我如何才能做到这一点? 要快速读取代码: function drawSurface(idnumber, radius, x, y, startAngleParam, endAngleParam) { var borderbold = 5; var surface; if (typeof startAngleParam !== 'undefined') { surface = new Konva.Shape({ x

我使用库绘制了一些圆弧,但在绘制对象后无法获得其宽度和高度,我如何才能做到这一点? 要快速读取代码:

function drawSurface(idnumber, radius, x, y, startAngleParam, endAngleParam) {
var borderbold = 5;
var surface;
if (typeof startAngleParam !== 'undefined') {
    surface = new Konva.Shape({
        x: x,
        y: y,
        fill: '#ccc',
        stroke: "#ccc",
        strokeWidth: 8,
        id: idnumber,
        opacity: 1,
        drawFunc: function (context) {
            var startAngle = startAngleParam * Math.PI;
            var endAngle = (startAngleParam + 0.5 + endAngleParam) * Math.PI;
            var counterClockwise = false;
            context.beginPath();
            context.arc(0, 0, radius, startAngle, endAngle, counterClockwise);
            context.setAttr("lineWidth", borderbold);
            context.stroke();
            context.fillStrokeShape(this);
        }
    });
}
else {
    surface = new Konva.Circle({
        x: x,
        y: y,
        radius: radius,
        fill: '#ccc',
        strokeWidth: 3,
        id: idnumber,
        opacity: 1
    });
}
return surface;
}

请用代码示例支持您的答案。

找到圆弧的边界框,然后从边界框计算宽度和高度

几何上,仅有5个可能的边界框角点是:

  • 圆弧中心点
  • 圆弧上0度(0弧度)的点(如果有)
  • 圆弧上90度(π/2弧度)的点(如有)
  • 圆弧上180度(π弧度)的点(如有)
  • 圆弧上270度(PI*3/2弧度)的点(如有)
从这些可能的边界框点中,找到最小X、最小Y、最大X和最大Y。[minX,minY]将是边界框的左上角。[maxX,maxY]将位于边界框的右下角

您的弧宽将为maxX minX,高度将为maxY minY

下面是示例代码和演示:

var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
var cw=画布宽度;
var ch=画布高度;
var-PI=Math.PI;
var-cx=150;
var-cy=150;
var半径=75;
var startAngle=-PI/4;
var端角=PI/3;
ctx.beginPath();
ctx.moveTo(cx,cy);
ctx.弧(cx、cy、半径、星形、端角);
ctx.closePath();
ctx.fillStyle='skyblue';
ctx.fill();
ctx.strokeStyle='lightgray';
ctx.线宽=3;
ctx.stroke();
var bb=弧边界(cx、cy、半径、星形缠结、端角);
ctx.strokeStyle='red';
ctx.线宽=1;
ctx.冲程(bb.x,bb.y,bb.宽度,bb.高度);
函数arcBounds(cx、cy、半径、startAngle、endAngle){
var minX=1000000;
var minY=1000000;
var maxX=-1000000;
var maxY=-1000000;
var possibleBoundingPoints=[]
//中心点
push({x:cx,y:cy});
//起始角
可能的结合点。推(弧点(cx,cy,半径,startAngle));
//终止角
可能的结合点。推力(弧点(cx,cy,半径,端角));
//0弧度

如果(0>=startAngle&&0=startAngle&&angle=startAngle&&angle=startAngle&&angle,这里有一种不同的方法从Javascript中获取并移植到Javascript:

const PI = Math.PI;
const HALF_PI = Math.PI / 2;
const TWO_PI = Math.PI * 2;
const DEG_TO_RAD = Math.PI / 180;
const RAD_TO_DEG = 180 / Math.PI;

const getQuadrant = (_angle) => {
    const angle = _angle % (TWO_PI);

    if (angle > 0.0 && angle < HALF_PI) return 0;
    if (angle >= HALF_PI && angle < PI) return 1;
    if (angle >= PI && angle < PI + HALF_PI) return 2;
    return 3;
};

// https://stackoverflow.com/a/35977476/461048
const getArcBoundingBox = (ini, end, radius, margin = 0) => {
    const iniQuad = getQuadrant(ini);
    const endQuad = getQuadrant(end);

    const ix = Math.cos(ini) * radius;
    const iy = Math.sin(ini) * radius;
    const ex = Math.cos(end) * radius;
    const ey = Math.sin(end) * radius;

    const minX = Math.min(ix, ex);
    const minY = Math.min(iy, ey);
    const maxX = Math.max(ix, ex);
    const maxY = Math.max(iy, ey);

    const r = radius;
    const xMax = [[maxX, r, r, r], [maxX, maxX, r, r], [maxX, maxX, maxX, r], [maxX, maxX, maxX, maxX]];
    const yMax = [[maxY, maxY, maxY, maxY], [r, maxY, r, r], [r, maxY, maxY, r], [r, maxY, maxY, maxY]];
    const xMin = [[minX, -r, minX, minX], [minX, minX, minX, minX], [-r, -r, minX, -r], [-r, -r, minX, minX]];
    const yMin = [[minY, -r, -r, minY], [minY, minY, -r, minY], [minY, minY, minY, minY], [-r, -r, -r, minY]];

    const x1 = xMin[endQuad][iniQuad];
    const y1 = yMin[endQuad][iniQuad];
    const x2 = xMax[endQuad][iniQuad];
    const y2 = yMax[endQuad][iniQuad];

    const x = x1 - margin;
    const y = y1 - margin;
    const w = x2 - x1 + margin * 2;
    const h = y2 - y1 + margin * 2;

    return { x, y, w, h };
};
const PI=Math.PI;
常数HALF_PI=Math.PI/2;
常数2_PI=Math.PI*2;
const DEG_至_RAD=Math.PI/180;
const RAD_至_DEG=180/Math.PI;
恒象限=(_角度)=>{
常数角=_角%(2_π);
如果(角度>0.0&&angle=HALF_PI&&angle=PI&&angle{
const-iniQuad=getQuadrant(ini);
const-endQuad=getQuadrant(结束);
常数ix=数学cos(ini)*半径;
常数iy=数学sin(ini)*半径;
常数ex=数学cos(end)*半径;
常数ey=数学sin(结束)*半径;
const minX=数学最小值(ix,ex);
const minY=Math.min(iy,ey);
const maxX=数学最大值(ix,ex);
const maxY=Math.max(iy,ey);
常数r=半径;
常数xMax=[[maxX,r,r,r],[maxX,maxX,r,r],[maxX,maxX,r],[maxX,maxX,maxX,r];
常量yMax=[[maxY,maxY,maxY,maxY],[r,maxY,r,r],[r,maxY,maxY,r],[r,maxY,maxY,maxY];
常数xMin=[[minX,-r,minX,minX],[minX,minX,minX],-r,-r,minX,-r],-r,-r,minX,minX];
常数yMin=[[minY,-r,-r,minY],[minY,minY,-r,minY],[minY,minY,minY,minY],-r,-r,minY];
常数x1=xMin[endQuad][iniQuad];
常数y1=yMin[endQuad][iniQuad];
常数x2=xMax[endQuad][iniQuad];
常数y2=yMax[endQuad][iniQuad];
常数x=x1-裕度;
常数y=y1——裕度;
常数w=x2-x1+裕度*2;
常数h=y2-y1+裕度*2;
返回{x,y,w,h};
};

jsFIDLE:

您的解释非常详细,非常棒,我非常感谢您的努力,我已经尝试将您的代码应用到我的弧上,并调整了所有参数,但边界框显示在不同的位置,具有不同的宽度和高度!!@MahdiAlkhatib在某些角度下无法正常工作: