简体   繁体   中英

How to divide an ellipse to equal angle segments?

the following code is creating svg paths to split a circle into 8 or 24 sections with the same angle at the center of the circle. The factor is only used to create paths that end at the border of the outer rectangle so we end up having a rectangle around the end of all paths.

function get8Or24PiePath(is24Pie, pieChartKind, width, height, customAngle) {
    let resultPath = '';
    const maxIndex = is24Pie ? 12 : 4;
    const circleAngleStep = (2 * Math.PI) / (maxIndex * 2);
    const additionalIndexValue = (customAngle / 360) * (maxIndex * 2);

    for (let index = 0; index < maxIndex; index++) {
        if (!is24Pie || (index + 2) % 3 !== 0) {
            const fromIndex = index + 0.5 + additionalIndexValue;
            const toIndex = fromIndex + maxIndex;
            const factorFrom =
                pieChartKind === 'S' || pieChartKind === 'R'
                    ? Math.sqrt(1.0) /
                      Math.max(
                            Math.abs(Math.cos(circleAngleStep * fromIndex)),
                            Math.abs(Math.sin(circleAngleStep * fromIndex)),
                      )
                    : 1;
            const factorTo =
                pieChartKind === 'S' || pieChartKind === 'R'
                    ? Math.sqrt(1.0) /
                      Math.max(
                            Math.abs(Math.cos(circleAngleStep * toIndex)),
                            Math.abs(Math.sin(circleAngleStep * toIndex)),
                      )
                    : 1;
            const xFrom =
                factorFrom * Math.cos(circleAngleStep * fromIndex) * (width * 0.5) + width * 0.5;
            const yFrom =
                factorFrom * Math.sin(circleAngleStep * fromIndex) * (height * 0.5) + height * 0.5;
            const xTo =
                factorTo * Math.cos(circleAngleStep * toIndex) * (width * 0.5) + width * 0.5;
            const yTo =
                factorTo * Math.sin(circleAngleStep * toIndex) * (height * 0.5) + height * 0.5;

            resultPath += `M ${xFrom} ${yFrom} L ${xTo} ${yTo} `;
        }
    }

    return resultPath;
}

Circle Example

But if I use the same calculation for an ellipse it will stretch the lines and the angles at the center of the ellipse arent equal anymore. What do I need to change to get the desired behaviour?

Ellipse Example

Seems you calculate circle circumference points, then squeeze coordinates - yes, in this case angles become wrong.

Instead calculate points at ellipse ( Polar form relative to center here )

在此处输入图像描述

在此处输入图像描述

ro(theta) = a * b / sqrt(a^2*sin^2(theta) + b^2*cos^2(theta))   
x(theta) = ro * cos(theta)
y(theta) = ro * sin(theta)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM