已知坐标求角度

已知javascript canvas 的一个点二维坐标(x, y),由点(0,0)到点(x, y) 记为向量 a, 求向量 a 与 x 轴的夹角。
其中约定从一个向量 (1, 0) 从旋转到 (0, 1) 为正的90度旋转,而任意一个向量从y轴到x轴为负的90度旋转。

直接用反正切函数,或者反余弦函数来做比较方便,
注意这两个反三角函数的值域与定义域,一般来说用反余弦函数来做更简单,因为不用考虑除零异常。
这里写图片描述
反 正切函数是奇函数,关于原点中心对称,既 tan(a) = tan(a + π)

function getAngle(x, y) {
        if (x === 0) {
            return y > 0 ? 90 : 270;
        }
        var a = Math.atan(y/x);
        var ret = a * 180 / Math.PI; //弧度转角度,方便调试
        if (x < 0) {
            ret = 180 + ret;
        }
        if (ret > 360) {
            ret -= 360;
        }
        if (ret < 0) {
            ret += 360;
        }
        return ret;
    }

更加简单Math.atan2() 实现

function getAngle(x, y) {
        var a = Math.atan2(y, x);
        var ret = a * 180 / Math.PI; //弧度转角度,方便调试
        if (ret > 360) {
            ret -= 360;
        }
        if (ret < 0) {
            ret += 360;
        }
        return ret;
    }

这里写图片描述

反余弦函数关于x轴对称,既cos(a) = cos (2π - a)
反余弦函数关于y轴有,cos(a) = - cos (π - a)

function getAngle(x, y) {
        var l = Math.sqrt(x*x + y*y);
        var a = Math.acos(x/l);
        var ret = a * 180 / Math.PI; //弧度转角度,方便调试
        if (y < 0) {
            return 360 - ret;
        }
        return ret;
    }

测试代码

var a = Math.sqrt(3);
    console.log(getAngle(1, a));
    console.log(getAngle(1, -a));
    console.log(getAngle(-1, -a));
    console.log(getAngle(-1, a));
    console.log(getAngle(1, 0));
    console.log(getAngle(0, 1));
    console.log(getAngle(-1, 0));
    console.log(getAngle(0, -1));
### 已知坐标计算旋转矩阵的方法 为了从已知坐标系转换关系中构建旋转矩阵,可以通过以下方法实现: #### 方法一:基于正交基向量的关系 如果给定两个坐标系 \( \{A\} \) 和 \( \{B\} \),其中 \( \{A\} \) 的标准基向量为 \( (i_A, j_A, k_A) \),而 \( \{B\} \) 的基向量表示为相对于 \( \{A\} \) 的单位向量 \( (u_B, v_B, w_B) \)[^1]。那么旋转矩阵 \( R_{AB} \) 可以通过如下公式定义: \[ R_{AB} = \begin{bmatrix} u_B & v_B & w_B \end{bmatrix}, \] 这里每一列分别是 \( \{B\} \) 中三个基向量在 \( \{A\} \) 下的分量。 具体来说,假设 \( u_B=(a_1,b_1,c_1)^T \), \( v_B=(a_2,b_2,c_2)^T \), \( w_B=(a_3,b_3,c_3)^T \),则有: ```python import numpy as np def compute_rotation_matrix(u_b, v_b, w_b): """ 计算旋转矩阵。 :param u_b: 新坐标系的第一个基向量,在旧坐标系下的表示形式 :param v_b: 新坐标系的第二个基向量,在旧坐标系下的表示形式 :param w_b: 新坐标系的第三个基向量,在旧坐标系下的表示形式 :return: 旋转矩阵 """ rotation_matrix = np.column_stack((np.array(u_b).reshape(-1, 1), np.array(v_b).reshape(-1, 1), np.array(w_b).reshape(-1, 1))) return rotation_matrix # 示例输入 u_b = [1/np.sqrt(3), 1/np.sqrt(3), 1/np.sqrt(3)] v_b = [-1/np.sqrt(2), 1/np.sqrt(2), 0] w_b = [1/np.sqrt(6), 1/np.sqrt(6), -2/np.sqrt(6)] rotation_matrix = compute_rotation_matrix(u_b, v_b, w_b) print(rotation_matrix) ``` #### 方法二:基于欧拉角的旋转矩阵构造 当知道绕特定轴的一系列旋转角度时(例如按照 XYZ 轴顺序),可以利用欧拉角来构造旋转矩阵。设依次围绕 X、Y、Z 轴旋转的角度分别为 γ、β、α,则总的旋转矩阵可通过连乘的方式获得[^2]: \[ R_z(\alpha)= \begin{bmatrix} \cos\alpha &-\sin\alpha & 0 \\ \sin\alpha &\cos\alpha & 0 \\ 0 & 0 & 1 \end{bmatrix}, \quad R_y(\beta)= \begin{bmatrix} \cos\beta & 0 & \sin\beta \\ 0 & 1 & 0 \\ -\sin\beta & 0 & \cos\beta \end{bmatrix}, \quad R_x(\gamma)= \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos\gamma & -\sin\gamma \\ 0 & \sin\gamma & \cos\gamma \end{bmatrix}. \] 总旋转矩阵为: \[ R=R_z(\alpha)\cdot R_y(\beta)\cdot R_x(\gamma). \] 以下是 Python 实现代码示例: ```python def euler_angles_to_rotation_matrix(alpha, beta, gamma): """ 使用欧拉角生成旋转矩阵。 :param alpha: 绕 Z 轴旋转角度(弧度制) :param beta: 绕 Y 轴旋转角度(弧度制) :param gamma: 绕 X 轴旋转角度(弧度制) :return: 总体旋转矩阵 """ Rx = np.array([[1, 0, 0], [0, np.cos(gamma), -np.sin(gamma)], [0, np.sin(gamma), np.cos(gamma)]]) Ry = np.array([[np.cos(beta), 0, np.sin(beta)], [0, 1, 0], [-np.sin(beta), 0, np.cos(beta)]]) Rz = np.array([[np.cos(alpha), -np.sin(alpha), 0], [np.sin(alpha), np.cos(alpha), 0], [0, 0, 1]]) total_rotation_matrix = Rz @ Ry @ Rx return total_rotation_matrix # 示例输入 alpha = np.pi / 4 beta = np.pi / 3 gamma = np.pi / 6 total_rotation_matrix = euler_angles_to_rotation_matrix(alpha, beta, gamma) print(total_rotation_matrix) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值