如何在JavaScript中获取正多边形最大宽度并适配边界框?
正多边形适配正方形边界框的实现问题
我一直在用数学公式绘制正多边形(各边长度和角度均相等的多边形),但尚未实现让多边形基于其最长尺寸适配指定宽度的正方形边界框,确保不会超出边界。
示例场景:粉色多边形的横向宽度(黑色线条标注)短于蓝色多边形的横向宽度(橙色线条标注),黄色正方形边界框内,粉色多边形需居中放置,蓝色多边形的边角则要贴合边界框边缘。
我尝试了以下两个距离公式来测量多边形的"最大距离",但未达到预期效果:
export function calculatePolygonHeight( sides: number, radius: number, ): number { // 确保边数合法 if (sides < 3) { throw new Error('Number of sides must be at least 3') } // 计算多边形高度 const height = radius * (1 + Math.cos(Math.PI / sides)) return height } export function distanceBetweenVertices({ sides, radius, distance, }: { sides: number radius: number distance: number }): number { if (sides < 3) { throw new Error('A polygon must have at least 3 sides.') } if (distance < 1 || distance >= sides) { throw new Error('distance must be between 1 and sides-1.') } const angle = (distance * Math.PI) / sides return 2 * radius * Math.sin(angle) }
我使用以下代码计算SVG多边形路径:
function computePolygonPoints({ width, height, sides, strokeWidth, rotation = 0, }: { width: number height: number sides: number strokeWidth: number rotation?: number }) { const centerX = width / 2 const centerY = height / 2 const radiusX = width / 2 const radiusY = height / 2 const offsetX = strokeWidth / 2 const offsetY = strokeWidth / 2 const rotationRad = (rotation * Math.PI) / 180 const points = Array.from({ length: sides }, (_, i) => { const angle = (i * 2 * Math.PI) / sides + ANGLE const x = centerX + radiusX * Math.cos(angle) const y = centerY + radiusY * Math.sin(angle) // 围绕中心旋转 const rotatedX = centerX + (x - centerX) * Math.cos(rotationRad) - (y - centerY) * Math.sin(rotationRad) const rotatedY = centerY + (x - centerX) * Math.sin(rotationRad) + (y - centerY) * Math.cos(rotationRad) return { x: rotatedX, y: rotatedY } }) const minX = Math.min(...points.map(p => p.x)) const minY = Math.min(...points.map(p => p.y)) const adjustedPoints = points.map(p => ({ x: offsetX + p.x - minX, y: offsetY + p.y - minY, })) return adjustedPoints }
这段代码能正确绘制多边形,但在处理描边宽度时存在问题:描边以边缘为中心,一半在多边形区域外,一半在内部。
我的思路是:
- 获取多边形的最大距离;
- 偏移
strokeWidth/2(避免描边被截断); - 将最大距离(宽度)缩小
strokeWidth,使绘制的多边形略小于要求尺寸,添加描边后视觉效果符合预期。
例如,我需要绘制宽度为256px、描边宽度为8px的多边形,如何实现任意旋转时都能在256x256的边界框内居中并尽可能填满?
内容的提问来源于stack exchange,提问作者Lance Pollard
相关产品推荐
相关产品推荐

