Xoay trong python

Chào các bạn, mọi người có khỏe không, hôm nay mình muốn bàn một chút về việc xoay vector trong không gian 2 chiều và 3 chiều. Không phải dân chuyên Toán nên các thuật ngữ như Euler, Quaternions,. Mình cũng chả có cách nào giải thích cho các bạn, nhưng đưa ra vài ví dụ trong lập trình chắc vẫn được nên hôm nay mình viết bài này cũng muốn tham khảo ý kiến ​​một chút

Xoay vector trong không gian 2D

Như các bạn đã biết, không gian 2D chỉ chứa trục x và trục y nên ta nhìn qua là một mặt phẳng không có chiều sâu. To Unknown, I will MINH MINH Một vector được tạo thành từ 2 điểm bất kỳ bằng thư viện matplotlib

from matplotlib import pyplot as plt
import math
import numpy as np
p1 = [0, 0]
p2 = [40, 40]

plt.axis([-50, 50, -50, 50])
plt.plot([p1[0], p2[0]], [p1[1], p2[1]], label = "line 1")

Nếu code theo python thì ta có

newX = v[0] * math.cos(angle) - v[1] * math.sin(angle)
newY = v[0] * math.sin(angle) + v[1] * math.cos(angle)

Nhưng như thế vector sẽ bị xoay ngược chiều kim đồng hồ nên tôi phải thay đổi một chút

newX = v[0] * math.cos(angle) + v[1] * math.sin(angle)
newY = -v[0] * math.sin(angle) + v[1] * math.cos(angle)

Minh họa dựa trên matplotlib

p1 = [0, 0]
p2 = [40, 40]

plt.axis([-50, 50, -50, 50])
plt.plot([p1[0], p2[0]], [p1[1], p2[1]], label = "line 1")

v = [p2[0] - p1[0], p2[1] - p1[1]]

angle = np.deg2rad(90)

newX = v[0] * math.cos(angle) + v[1] * math.sin(angle)
newY = -v[0] * math.sin(angle) + v[1] * math.cos(angle)

p3 = [p1[0] + newX, p1[1] + newY]

plt.axis([-50, 50, -50, 50])
plt.plot([p1[0], p3[0]], [p1[1], p3[1]], label = "line 2")

plt.xlabel('x')
plt.ylabel('y')
plt.show()

  • Xoay sân

    • Xoay vòng

      • Ma trận xoay theo góc và trục định sẵn (ux, uy, uz). Với u là vectơ đơn vị
      from math import pi ,sin, cos
      
      def R(theta, u):
          return [[cos(theta) + u[0]**2 * (1-cos(theta)), 
                   u[0] * u[1] * (1-cos(theta)) - u[2] * sin(theta), 
                   u[0] * u[2] * (1 - cos(theta)) + u[1] * sin(theta)],
                  [u[0] * u[1] * (1-cos(theta)) + u[2] * sin(theta),
                   cos(theta) + u[1]**2 * (1-cos(theta)),
                   u[1] * u[2] * (1 - cos(theta)) - u[0] * sin(theta)],
                  [u[0] * u[2] * (1-cos(theta)) - u[1] * sin(theta),
                   u[1] * u[2] * (1-cos(theta)) + u[0] * sin(theta),
                   cos(theta) + u[2]**2 * (1-cos(theta))]]
      
      def Rotate(pointToRotate, point1, point2, theta):
          u= []
          squaredSum = 0
          for i,f in zip(point1, point2):
              u.append(f-i)
              squaredSum += (f-i) **2
      
          u = [i/squaredSum for i in u]
      
          r = R(theta, u)
          rotated = []
      
          for i in range(3):
              rotated.append(round(sum([r[j][i] * pointToRotate[j] for j in range(3)])))
      
          return rotated
      
      point = [1,0,0]
      p1 = [0,0,0]
      p2 = [0,1,0]
      
      print Rotate(point, p1, p2, pi)
      

      Công thức Euler–Rodrigues

      định nghĩa. một phương pháp tính toán vị trí của điểm xoay

      Phép xoay quanh trục gốc được biểu diễn bởi 4 tham số a, b, c, d

      Khi áp dụng công thức này, một vị trí có tọa độ x sẽ xoay về một vị trí mới có tọa độ x'

      mã trăn. rotate_matrix() function trả về một ma trận xoay ngược chiều kim đồng hồ theo trục và góc

      import numpy as np
      import math
      
      def rotation_matrix(axis, theta):
          """
          Return the rotation matrix associated with counterclockwise rotation about
          the given axis by theta radians.
          """
          axis = np.asarray(axis)
          axis = axis / math.sqrt(np.dot(axis, axis))
          a = math.cos(theta / 2.0)
          b, c, d = -axis * math.sin(theta / 2.0) # bỏ dấu trừ nếu muốn thuận chiều kim đồng hồ
          aa, bb, cc, dd = a * a, b * b, c * c, d * d
          bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d
          return np.array([[aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac)],
                           [2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab)],
                           [2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc]])
      
      v = [3, 5, 0]
      axis = [4, 4, 1]
      theta = 1.2 
      
      print(np.dot(rotation_matrix(axis, theta), v)) 
      # [ 2.74911638  4.77180932  1.91629719]
      

      Đệ tứ

      Cũng như Euler-Rodrigues, quaternion is a vector has 4 section tử dùng để tính toán vị trí của điểm được xoay. Ta cũng có thể biến đổi các tham số Euler a, b, c, d trên các hệ số của quaternion

      Một phần tư có thể được tính như sau

      def angle_axis_quat(theta, axis):
          """
          Given an angle and an axis, it returns a quaternion.
          """
          axis = np.array(axis) / np.linalg.norm(axis)
          return np.append([np.cos(theta/2)],np.sin(theta/2) * axis)
      

      Rotor vector by quaternions by công thức

      Một véc tơ xoay là tích của một quaternion nghịch đảo của nó. Bậc bốn này lại là tích của véc tơ đơn vị với liên kết của nó

      q1.

      q2.

      Tích hợp của 2 quaternions

      p1 = [0, 0]
      p2 = [40, 40]
      
      plt.axis([-50, 50, -50, 50])
      plt.plot([p1[0], p2[0]], [p1[1], p2[1]], label = "line 1")
      
      0

      Sau khi có các bậc bốn được xoay, áp dụng vào véc tơ cần xoay sẽ sinh ra một véc tơ mới

      p1 = [0, 0]
      p2 = [40, 40]
      
      plt.axis([-50, 50, -50, 50])
      plt.plot([p1[0], p2[0]], [p1[1], p2[1]], label = "line 1")
      
      1Lời kết

      Như các bạn đã thấy thì cả bài hầu này như là một bài tổng hợp các cách xoay vector trong không gian hai chiều và ba chiều, do đó còn nhiều sót và không đầy đủ, mong các cao nhân có thể giúp đỡ thêm thắt lưng

      Người giới thiệu

      .

      .

      https. //ý chính. github. com/LyleScott/e36e08bfb23b1f87af68c9051f985302

      https. // stackoverflow. com/câu hỏi/17763655/xoay-of-a-point-in-3d-about-an-arbitrary-axis-using-python