以度python旋转关于另一个点的点

时间:2015-12-19 15:42:28

标签: python math degrees

如果你有一个点(在2d),你怎么能在python的另一个点(原点)周围旋转那个点?

例如,您可以将原点周围的第一个点倾斜10度。

基本上你有一个PointA和它旋转的原点。 代码看起来像这样:

{
  "text":[
    {
      "text":"TOGETHER WITH THIER FAMILIES",
      "font":{
        "name":"Adamina",
        "size":"12",
        "spacing":"10",
        "alignment":"center",
        "color":"#F8E4C8"
      },
      "style":{
        "left":"180",
        "top":"250"
      }
    },
    {
      "text":"BRIDE NAME HERE",
      "font":{
        "name":"Monsieur La Doulaise Regular",
        "size":"34",
        "spacing":"10",
        "alignment":"center",
        "color":"#F8E4C8"
      },
      "style":{
        "left":"180",
        "top":"280"
      }
    },
    {
      "text":"TO",
      "font":{
        "name":"Adamina",
        "size":"14",
        "spacing":"10",
        "alignment":"center",
        "color":"#F8E4C8"
      },
      "style":{
        "left":"180",
        "top":"300"
      }
    },
    {
      "text":"GRROM NAME HERE",
      "font":{
        "name":"Adamina",
        "size":"34",
        "spacing":"10",
        "alignment":"center",
        "color":"#F8E4C8"
      },
      "style":{
        "left":"180",
        "top":"320"
      }
    },
    {
      "text":"CHURCH NAME HERE",
      "font":{
        "name":"Monsieur La Doulaise Regular",
        "size":"24",
        "spacing":"10",
        "alignment":"center",
        "color":"#F8E4C8"
      },
      "style":{
        "left":"180",
        "top":"340"
      }
    },
    {
      "text":"SATURDAY,  NOVEMBER 15TH, 2015",
      "font":{
        "name":"Monsieur La Doulaise Regular",
        "size":"24",
        "spacing":"10",
        "alignment":"center",
        "color":"#F8E4C8"
      },
      "style":{
        "left":"180",
        "top":"360"
      }
    },
    {
      "text":"6:30 PM",
      "font":{
        "name":"Adamina",
        "size":"15",
        "spacing":"10",
        "alignment":"center",
        "color":"#F8E4C8"
      },
      "style":{
        "left":"180",
        "top":"380"
      }
    }
  ]
}

5 个答案:

答案 0 :(得分:43)

以下rotate函数将点point的旋转角度angle(逆时针,以弧度表示)围绕origin在笛卡尔平面内旋转,通常的轴惯例:x从左到右增加,y从垂直向上增加。所有点都表示为(x_coord, y_coord)形式的长度为2的元组。

import math

def rotate(origin, point, angle):
    """
    Rotate a point counterclockwise by a given angle around a given origin.

    The angle should be given in radians.
    """
    ox, oy = origin
    px, py = point

    qx = ox + math.cos(angle) * (px - ox) - math.sin(angle) * (py - oy)
    qy = oy + math.sin(angle) * (px - ox) + math.cos(angle) * (py - oy)
    return qx, qy

如果角度以度为单位指定,则可以使用math.radians将其转换为弧度。对于顺时针旋转,否定角度。

示例:将点(3, 4)(2, 2)原点逆时针旋转10度:

>>> point = (3, 4)
>>> origin = (2, 2)
>>> rotate(origin, point, math.radians(10))
(2.6375113976783475, 4.143263683691346)

请注意rotate函数中有一些明显的重复计算:math.cos(angle)math.sin(angle)每次计算两次,px - ox和{{1} }}。如果有必要,我会留给你考虑。

答案 1 :(得分:4)

import math

def rotate(x,y,xo,yo,theta): #rotate x,y around xo,yo by theta (rad)
    xr=math.cos(theta)*(x-xo)-math.sin(theta)*(y-yo)   + xo
    yr=math.sin(theta)*(x-xo)+math.cos(theta)*(y-yo)  + yo
    return [xr,yr]

答案 2 :(得分:1)

经过大量的代码和存储库之后。此功能最适合我。此外,由于只计算一次正弦和余弦值,因此效率很高。

import numpy as np
def rotate(point, origin, degrees):
    radians = np.deg2rad(degrees)
    x,y = point
    offset_x, offset_y = origin
    adjusted_x = (x - offset_x)
    adjusted_y = (y - offset_y)
    cos_rad = np.cos(radians)
    sin_rad = np.sin(radians)
    qx = offset_x + cos_rad * adjusted_x + sin_rad * adjusted_y
    qy = offset_y + -sin_rad * adjusted_x + cos_rad * adjusted_y
    return qx, qy

答案 3 :(得分:0)

将一个点围绕另一个点旋转一定程度的选项是使用#pragma once #include <vector> #include <unordered_map> #include "../Entity.h" #include "ComponentBase.h" class ECSManager { private: std::unordered_map<unsigned int, std::vector<ComponentBase>> m_Components; std::unordered_map<unsigned int, Entity> m_Entities; private: ECSManager(); public: const Entity& CreateEntity() { Entity e; m_Entities.emplace(e.GetID(), std::move(e)); return m_Entities[e.GetID()]; } template <typename TComponent, typename... Args> void AddComponent(unsigned int entityId, Args&&... args) { unsigned int componentID = TComponent::ID; if (m_Components[componentID] == m_Components.end()) m_Components[componentID] = std::vector<TComponent>(); m_Components[componentID].push_back(T(std::forward<Args>(args)...)); m_Entities[entityId].AddComponent(componentID, m_Components[componentID].size() - 1); if (m_Signatures[m_Entities[entityId].GetSignature()] == m_Signatures.end()) m_Signatures[m_Entities[entityId].GetSignature()] = std::vector<unsigned int>(); m_Signatures[m_Entities[entityId].GetSignature()].push_back(entityId); } template <typename TComponent> TComponent& GetComponent(Entity& entity) { return m_Components[TComponent::ID][entity.GetComponentsIndex()[TComponent::ID]]; } template <typename TComponent> std::vector<TComponent>& GetComponents() { unsigned int componentID = TComponent::ID; return m_Components[componentID]; } std::vector<Entity&> GetEntities(std::vector<bool> componentIDs) { std::vector<Entity&> entities; for (auto& entity : m_Entities) { const auto& entitySignature = entity.second.GetSignature(); if (componentIDs.size() > entitySignature.size()) continue; bool equal = true; for (std::size_t i = 0; i != componentIDs.size(); i++) { if (componentIDs[i] & entitySignature[i] == 0) { equal = false; break; } } if (!equal) continue; entities.push_back(entity.second); } return entities; } }; 而不是numpy。这允许轻松地泛化该函数以将任意数量的点作为输入,例如旋转多边形时非常有用。

math

答案 4 :(得分:0)

如果您将点表示为复数并使用带虚参数的 exp 函数(这相当于其他答案中显示的 cos/sin 运算,但更容易编写和记住),这很容易。这是一个函数,可以围绕所选原点旋转任意数量的点:

import numpy as np

def rotate(points, origin, angle):
    return (points - origin) * np.exp(complex(0, angle)) + origin

要绕原点 (x0,y0) 旋转单个点 (x1,y1) 并以度数为单位,您可以使用以下参数调用该函数:

points = complex(x1,y1)
origin = complex(x0,y0)
angle = np.deg2rad(degrees)

要旋转多个点 (x1,y1), (x2,y2), ...,请使用:

points = np.array([complex(x1,y1), complex(x2,y2), ...])

单个点 (200,300) 围绕 (100,100) 旋转 10 度的示例:

>>> new_point = rotate(complex(200,300), complex(100,100), np.deg2rad(10))
>>> new_point
(163.75113976783473+314.3263683691346j)
>>> (new_point.real, new_point.imag)
(163.75113976783473, 314.3263683691346)