JS如何使用Math.atan2获取两点之间角度的实践案例

本文详细介绍了一种手动控制网页元素旋转的技术实现,通过计算两点间连线的倾斜角,利用Math.atan2()函数高效获取旋转角度,并结合角度与弧度转换及组件中心点计算,实现了组件的360度无缝旋转。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主要介绍使用如何实现手动拖拽旋转元素的效果。

1、简述

最近在研究如何实现手动控制元素的旋转效果,在网上找了很多,都没有找出类似的实现,因此经过一些调研和计算,最终完美实现效果,在这里记录下来。

2、效果展示

通过手动旋转的方式,实现组件的360度无缝旋转。图示是实现结果的几个截图:

  • 0deg
    1414921-20180925161018996-1397506909.png

  • 顺时针转到 66deg
    1414921-20180925161027296-1339387242.png

  • 逆时针转到 315deg
    1414921-20180925161035239-569509983.png

  • 转到 180deg
    1414921-20180925161045525-2067128868.png

3、实现分析

如图所示,实现难点在于计算出两点间连线的倾斜角 angle
1414921-20180925161125384-1000619686.png

这里需要掌握的几个知识点:

3.1 获取转动的角度

使用 Math.atan2() 函数可以非常高效的实现之,它是返回点与原点之间的倾斜角,如图所示,如果想计算出点 (x1,y1) 与 原点 (cx,cy) 与X轴的角度,只需要执行:

Math.atan2(y1 - cy, x1 - cx)

需要注意的是,它的取值范围是[-PI, PI]。
当 (x1, y1) 在第一象限, 0 < θ < PI/2

当 (x1, y1) 在第二象限 PI/2 < θ≤PI

当 (x1, y1) 在第三象限, -PI < θ < -PI/2

当 (x1, y1) 在第四象限, -PI/2 < θ < 0

3.2 角度与弧度之间的转换
角度 = 弧度 * 180 / Math.PI;
弧度= 角度 * Math.PI / 180;
3.3 组件中心点位置计算

使用getBoundingClientRect() 的方法可以获取出容器的位置信息,用当前位置减去宽/高的一半,即可获取中心点位置。
1414921-20180925161142268-1129913331.png

  //中心点
  cx = x + width / 2;
  cy = y + height / 2;

4、最终代码

/**
 * 获得旋转夹角
 * @param {*} x1 旋转点1
 * @param {*} y1 
 * @param {*} x2 旋转点2
 * @param {*} y2 
 */
function getAngle(x1, y1, x2, y2) {
  // 获取组件的位置信息
  let rect = document.getElementsByClassName('active-ele')[0].getBoundingClientRect();
  let {
    x,
    y,
    width,
    height
  } = rect;

  //中心点
  let cx = x + width / 2;
  let cy = y + height / 2;

  //2个点之间的角度获取
  let c1 = Math.atan2(y1 - cy, x1 - cx) * 180 / (Math.PI);
  let c2 = Math.atan2(y2 - cy, x2 - cx) * 180 / (Math.PI);
  let angle;
  c1 = c1 <= -90 ? (360 + c1) : c1;
  c2 = c2 <= -90 ? (360 + c2) : c2;

  //夹角获取
  angle = Math.floor(c2 - c1);
  angle = angle < 0 ? angle + 360 : angle;
  return angle;
}
    /**
     * 获得旋转夹角
     * @param startPos.x 指的是初始位置的x坐标
     * @param startPos.y 指的是初始位置的y坐标
     * @param startPos.r 指的是初始的旋转角度
     */
    let angle = getAngle(startPos.x, startPos.y, e.x, e.y);
    let startAngle = startPos.r;
    let deg;

    // 赋值的旋转角度
    let rotate;

    // 顺时针旋转
    if (e.x - startX > 0) {
      deg = startAngle + angle;
      rotate = deg > 360 ? deg - 360 : deg;
    } else {
    // 逆时针旋转
      angle = 360 - angle;
      deg = startAngle - angle;
      rotate = deg < 0 ? deg + 360 : deg;
    }

转载于:https://www.cnblogs.com/webhmy/p/9700079.html

### math.atan 与 atan2 的区别及用法 #### 1. **math.atan 的定义和用法** `math.atan` 是 Python 中的数学库函数,用于计算一个数值的反正切值。它的输入是一个单一的浮点数或整数,返回值为弧度制的结果[^3]。 **特点:** - 输入参数只有一个(即 tan 的值)。 - 返回值范围是 `[-π/2, π/2]`。 - 无法区分象限信息,仅适用于一维坐标系下的反正切计算。 **示例代码:** ```python import math # 示例 1: 计算单个值的反正切 value = 1 result = math.atan(value) print(f"atan({value}) = {result} 弧度") ``` 输出结果: ``` atan(1) = 0.7853981633974483 弧度 ``` --- #### 2. **math.atan2 的定义和用法** `math.atan2(y, x)` 是 Python 中的另一个数学库函数,用于计算二维平面上点 `(x, y)` 到原点 `(0, 0)` 的角度。它接受两个参数:`y` 和 `x`,分别表示点的纵坐标和横坐标[^5]。 **特点:** - 输入参数有两个(即 y 和 x)。 - 返回值范围是 `[-π, π]`,能够自动处理所有象限。 - 能够区分象限信息,避免了普通 `atan` 函数无法区分象限的问题。 **示例代码:** ```python import math # 示例 1: 计算不同点的角度 points = [(1, 1), (-1, 1), (-1, -1), (1, -1)] for x, y in points: angle_radians = math.atan2(y, x) angle_degrees = math.degrees(angle_radians) print(f"点 ({x}, {y}): 弧度 = {angle_radians:.4f}, 角度 = {angle_degrees:.2f}°") ``` 输出结果: ``` 点 (1, 1): 弧度 = 0.7854, 角度 = 45.00° 点 (-1, 1): 弧度 = 2.3562, 角度 = 135.00° 点 (-1, -1): 弧度 = -2.3562, 角度 = -135.00° 点 (1, -1): 弧度 = -0.7854, 角度 = -45.00° ``` --- #### 3. **JavaScript 中的 Math.atan 和 Math.atan2** 在 JavaScript 中,`Math.atan` 和 `Math.atan2` 的功能与 Python 中的 `math.atan` 和 `math.atan2` 类似[^4]。 - `Math.atan` 接受一个参数,返回值范围为 `[-π/2, π/2]`。 - `Math.atan2` 接受两个参数(y 和 x),返回值范围为 `[-π, π]`。 **示例代码:** ```javascript // 示例 1: Math.atan 示例 console.log(Math.atan(1)); // 输出 0.7853981633974483 // 示例 2: Math.atan2 示例 console.log(Math.atan2(1, 1)); // 输出 0.7853981633974483 (第一象限) console.log(Math.atan2(-1, 1)); // 输出 -0.7853981633974483 (第四象限) console.log(Math.atan2(-1, -1)); // 输出 -2.356194490192345 (第三象限) console.log(Math.atan2(1, -1)); // 输出 2.356194490192345 (第二象限) ``` --- #### 4. **主要区别总结** | 特性 | `math.atan` 或 `Math.atan` | `math.atan2` 或 `Math.atan2` | |---------------------|------------------------------------|-----------------------------------------| | 输入参数数量 | 单一参数 | 两个参数(y 和 x) | | 返回值范围 | `[-π/2, π/2]` | `[-π, π]` | | 是否区分象限 | 否 | 是 | | 使用场景 | 一维坐标系下的反正切计算 | 二维坐标系下的角度计算 | --- #### 5. **常见问题及注意事项** - 如果只提供一个参数(如 tan 值),使用 `math.atan` 或 `Math.atan`。 - 如果需要根据二维坐标计算角度,并区分象限,使用 `math.atan2` 或 `Math.atan2`。 - 在 JavaScript 中,`Math.atan` 和 `Math.atan2` 的行为与 Python 中的对应函数一致。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值