如何计算多边形绕锚点旋转后的新中心点及等效中心旋转参数
解决方案:绕外部锚点旋转的等效平移与中心旋转计算
绕外部锚点旋转的效果,完全可以通过保持顶点相对中心(0,0)的定义不变,只调整图形的中心坐标(x_pos/y_pos)和绕中心的旋转角度来实现,不需要修改顶点数据。
核心推导逻辑
假设:
- 图形当前中心的Canvas坐标:
(cx, cy) = (this.x_pos, this.y_pos) - 外部锚点的Canvas坐标:
(ax, ay) - 目标旋转角度:
θ(弧度制)
绕锚点旋转后,图形的新中心坐标是原中心绕锚点旋转θ角后的位置,计算公式为:
cx' = ax + (cx - ax) * cosθ - (cy - ay) * sinθ cy' = ay + (cx - ax) * sinθ + (cy - ay) * cosθ
图形自身的旋转角度直接设置为θ(如果是增量旋转,就累加θ到当前rotation值上)。
代码实现
1. 简化绕中心旋转顶点的方法
因为顶点是相对中心(0,0)定义的,绕中心旋转的逻辑可以简化:
getRotatedVertices(angle: number): [number, number][] { return this.vertices.map(([x, y]) => [ x * Math.cos(angle) - y * Math.sin(angle), x * Math.sin(angle) + y * Math.cos(angle) ]); }
2. 添加绕外部锚点旋转的方法
直接计算新的中心坐标并更新旋转角度:
rotateAroundAnchor(angle: number, anchorX: number, anchorY: number): void { const cosθ = Math.cos(angle); const sinθ = Math.sin(angle); const dx = this.x_pos - anchorX; const dy = this.y_pos - anchorY; // 计算旋转后的新中心坐标 this.x_pos = anchorX + dx * cosθ - dy * sinθ; this.y_pos = anchorY + dx * sinθ + dy * cosθ; // 若为增量旋转,改为 this.rotation += angle this.rotation = angle; }
3. 调整绘制方法
使用绕中心旋转后的顶点,叠加新的中心坐标完成绘制:
draw(ctx: CanvasRenderingContext2D): void { const verts = this.getRotatedVertices(this.rotation); this.applyStyle(ctx); ctx.beginPath(); verts.forEach(([x, y]) => { ctx.lineTo(this.x_pos + x, this.y_pos + y); }); ctx.closePath(); ctx.stroke(); ctx.fill(); }
原理说明
绕外部锚点旋转图形,本质是让图形的每个顶点都绕锚点转θ角。通过将图形中心移到「原中心绕锚点旋转后的位置」,再让图形绕自身中心转θ角,最终每个顶点的Canvas坐标和直接绕锚点旋转的结果完全一致,同时顶点始终保持相对中心(0,0)的定义。
内容的提问来源于stack exchange,提问作者David Ferguson
相关产品推荐
相关产品推荐

