如何根据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
相关产品推荐
相关产品推荐

