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

如何根据X/Y偏移量反向计算阴影的长度与角度

反向推导阴影角度与长度的实现方法

已知从角度和长度计算偏移量的正向公式:

shadowX = Math.sin(angle * Math.PI / 180) * length;
shadowY = Math.cos(angle * Math.PI / 180) * length;

要从offsetX(即shadowX)和offsetY(即shadowY)反向计算长度和角度,可按以下步骤实现:

1. 计算长度(偏移量的模长)

长度是偏移量在坐标系中的斜边长度,用勾股定理计算:

function getLength(offsetX, offsetY) {
  return Math.sqrt(Math.pow(offsetX, 2) + Math.pow(offsetY, 2));
}

2. 计算角度

根据正向公式的三角函数关系,用Math.atan2()求解弧度后转换为角度。注意这里参数顺序是(offsetX, offsetY)——因为正向公式中shadowX对应正弦值、shadowY对应余弦值,和常规atan2(y, x)的参数顺序不同:

function getAngle(offsetX, offsetY) {
  // 计算弧度
  const radians = Math.atan2(offsetX, offsetY);
  // 转换为角度并修正为0-360范围
  let angle = radians * 180 / Math.PI;
  if (angle < 0) {
    angle += 360;
  }
  return angle;
}

验证示例

用你提供的测试值验证:

  • offsetX = 1.41421356237309,offsetY = -1.4142135623731
  • 长度计算:√(1.4142² + (-1.4142)²) = √4 = 2,和正向代码的length=2一致
  • 角度计算:atan2(1.4142, -1.4142)得到3π/4弧度,转换为角度是135°,和正向代码的angle=135完全匹配

完整解析代码

结合格式解析(从radius|{offsetX, offsetY}字符串提取值),完整实现如下:

function parseShadowParams(str) {
  // 分割半径与偏移量部分
  const [radiusStr, offsetStr] = str.split('|');
  // 提取并转换offsetX、offsetY为数值
  const [offsetX, offsetY] = offsetStr.replace(/[{}]/g, '').split(',').map(Number);
  // 计算长度与角度
  const length = Math.sqrt(Math.pow(offsetX, 2) + Math.pow(offsetY, 2));
  let angle = Math.atan2(offsetX, offsetY) * 180 / Math.PI;
  if (angle < 0) angle += 360;
  
  return {
    radius: Number(radiusStr),
    length: parseFloat(length.toFixed(15)), // 匹配示例精度
    angle: parseFloat(angle.toFixed(15))
  };
}

// 测试输入
const input = "10|{1.41421356237309, -1.4142135623731}";
console.log(parseShadowParams(input));
// 输出:{ radius: 10, length: 2, angle: 135 }

内容的提问来源于stack exchange,提问作者Chris Barr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 11:27:32