You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对带旋转角的矩形数据结构执行水平/垂直翻转?

旋转矩形的水平/垂直翻转实现

矩形数据结构说明

我们使用如下结构描述带旋转的矩形:

{ 
  x: number,  // 左上角x坐标
  y: number,  // 左上角y坐标
  w: number,  // 矩形宽度
  h: number,  // 矩形高度
  a: number   // 绕自身中心的旋转角度(弧度)
}

需求概述

需要通过修改上述矩形的参数,实现水平翻转和垂直翻转的视觉效果:

  • 水平翻转:旋转后的矩形左右镜像(例如向右倾斜的矩形变为向左倾斜,整体关于垂直轴对称)
  • 垂直翻转:旋转后的矩形上下镜像(例如向上倾斜的矩形变为向下倾斜,整体关于水平轴对称)

翻转的参数计算逻辑

水平翻转

水平翻转的核心是让矩形关于垂直轴对称,只需修改两个参数:

  1. 旋转角度取反:原角度 a 变为 -a,保证翻转后的旋转方向与原方向镜像
  2. 调整左上角x坐标:以矩形中心为基准,将原矩形的右下角x坐标映射为新的左上角x坐标,公式为:newX = 2*(x + w/2) - (x + w)

封装成函数:

function flipHorizontally(rect) {
  const centerX = rect.x + rect.w / 2;
  return {
    ...rect,
    x: 2 * centerX - (rect.x + rect.w),
    a: -rect.a
  };
}

垂直翻转

垂直翻转的核心是让矩形关于水平轴对称,同样修改两个参数:

  1. 旋转角度取反:原角度 a 变为 -a,保证翻转后的旋转方向与原方向镜像
  2. 调整左上角y坐标:以矩形中心为基准,将原矩形的右下角y坐标映射为新的左上角y坐标,公式为:newY = 2*(y + h/2) - (y + h)

封装成函数:

function flipVertically(rect) {
  const centerY = rect.y + rect.h / 2;
  return {
    ...rect,
    y: 2 * centerY - (rect.y + rect.h),
    a: -rect.a
  };
}

测试验证代码

结合提供的绘制代码,添加翻转函数并测试效果:

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
canvas.width = 400;
canvas.height = 200;

// 画布旋转辅助函数
function rotateCanvas(ctx, x, y, a) {
  ctx.translate(x, y);
  ctx.rotate(a);
  ctx.translate(-x, -y);
}

// 绘制旋转矩形
function drawRotatedRectangle(ctx, rX, rY, rW, rH, rA) {
  rotateCanvas(ctx, rX + rW / 2, rY + rH / 2, rA);
  ctx.beginPath();
  ctx.rect(rX, rY, rW, rH);
  ctx.stroke();
  rotateCanvas(ctx, rX + rW / 2, rY + rH / 2, -rA);
}

// 水平翻转函数
function flipHorizontally(rect) {
  const centerX = rect.x + rect.w / 2;
  return {
    ...rect,
    x: 2 * centerX - (rect.x + rect.w),
    a: -rect.a
  };
}

// 垂直翻转函数
function flipVertically(rect) {
  const centerY = rect.y + rect.h / 2;
  return {
    ...rect,
    y: 2 * centerY - (rect.y + rect.h),
    a: -rect.a
  };
}

// 原矩形
const original = { x: 30, y: 30, w: 100, h: 50, a: 0.5 };
// 水平翻转后的矩形(偏移x轴避免重叠)
const flippedHoriz = flipHorizontally(original);
flippedHoriz.x += 150;
// 垂直翻转后的矩形(偏移y轴避免重叠)
const flippedVert = flipVertically(original);
flippedVert.y += 100;

// 绘制原矩形(黑色)
ctx.strokeStyle = "#000";
drawRotatedRectangle(ctx, original.x, original.y, original.w, original.h, original.a);

// 绘制水平翻转矩形(红色)
ctx.strokeStyle = "#ff0000";
drawRotatedRectangle(ctx, flippedHoriz.x, flippedHoriz.y, flippedHoriz.w, flippedHoriz.h, flippedHoriz.a);

// 绘制垂直翻转矩形(蓝色)
ctx.strokeStyle = "#0000ff";
drawRotatedRectangle(ctx, flippedVert.x, flippedVert.y, flippedVert.w, flippedVert.h, flippedVert.a);
<canvas></canvas>

内容的提问来源于stack exchange,提问作者Ryan Peschel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 02:05:26