当前位置:   article > 正文

使用python实现旋转矩形并沿指定方向延伸_numpy 矩形旋转

numpy 矩形旋转

在群里看到一个群友问的问题,举手之劳,稍微做了一下

题目

请添加图片描述

解题过程

思路很清晰,先计算要延伸的方向(CD),然后选一个起点(A、D)在该方向上延伸指定距离即可。
建立坐标系:
在这里插入图片描述

C D → = O D → − O C → = ( x d − x c , y d − y c ) O D 1 = O D → + D D → 1 = O D → + λ ⋅ C D → = ( x d + λ ( x d − x c ) , y d + λ ( y d − y c ) ) .

CD=ODOC=(xdxc,ydyc)OD1=OD+DD1=OD+λCD=(xd+λ(xdxc),yd+λ(ydyc)).
CD =OD OC =(xdxc,ydyc)OD1=OD +DD 1=OD +λCD =(xd+λ(xdxc),yd+λ(ydyc)).
其中 λ \lambda λ 决定了延伸的长度为CD长度的倍数。

代码

生成旋转矩形

使用正矩形四个顶点坐标乘以旋转矩阵即可:
[ x a y a x b y b x c y c x d y d ] [ cos ⁡ θ − sin ⁡ θ sin ⁡ θ cos ⁡ θ ] = [ x r a y r a x r b y r b x r c y r c x r d y r d ] \left[

xayaxbybxcycxdyd
\right]\left[
cosθsinθsinθcosθ
\right]=\left[
xrayraxrbyrbxrcyrcxrdyrd
\right] xaxbxcxdyaybycyd[cosθsinθsinθcosθ]=xraxrbxrcxrdyrayrbyrcyrd

θ \theta θ为旋转角度
除此之外,需要注意旋转中心和相对坐标。

def rota_rect(box, theta, x, y):
    """
    :param box: 正矩形的四个顶点
    :param theta: 旋转角度
    :param x: 旋转中心(x,y)
    :param y: 旋转中心(x,y)
    :return: 旋转矩形的四个顶点坐标
    """
    # 旋转矩形
    box_matrix = np.array(box) - np.repeat(np.array([[x, y]]), len(box), 0)
    theta = theta / 180. * np.pi
    rota_matrix = np.array([[np.cos(theta), -np.sin(theta)],
                            [np.sin(theta), np.cos(theta)]], np.float)

    new_box = box_matrix.dot(rota_matrix) + np.repeat(np.array([[x, y]]), len(box), 0)
    return new_box
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

效果:
在这里插入图片描述

完整代码

import numpy as np
import matplotlib.pyplot as plt
import cv2 as cv
import matplotlib.lines as lines


def rota_rect(box, theta, x, y):
    """
    :param box: 正矩形的四个顶点
    :param theta: 旋转角度
    :param x: 旋转中心(x,y)
    :param y: 旋转中心(x,y)
    :return: 旋转矩形的四个顶点坐标
    """
    # 旋转矩形
    box_matrix = np.array(box) - np.repeat(np.array([[x, y]]), len(box), 0)
    theta = theta / 180. * np.pi
    rota_matrix = np.array([[np.cos(theta), -np.sin(theta)],
                            [np.sin(theta), np.cos(theta)]], np.float)

    new_box = box_matrix.dot(rota_matrix) + np.repeat(np.array([[x, y]]), len(box), 0)
    return new_box


if __name__ == '__main__':
    data = np.zeros((100, 100), np.float)
    x, y = 50, 50
    w, h = 20, 10

    box = [(x, y), (x + w, y), (x + w, y + h), (x, y + h)]

    # 旋转矩形
    new_box = rota_rect(box, -30, x+w//2, y+h//2)
    # 反向延长
    length = 0.5
    CD = new_box[3] - new_box[2]
    extend1 = new_box[0] + CD*length
    extend2 = new_box[3] + CD*length

    fig, (ax0) = plt.subplots(nrows=1, ncols=1)
    ax0.imshow(data, cmap='gray')

    s = ['A', 'B', 'C', 'D']
    for i in range(4):
        # ax0.add_artist(
        #     lines.Line2D([box[i % 4][0], box[(i + 1) % 4][0]], [box[i % 4][1], box[(i + 1) % 4][1]], color='g'))
        ax0.add_artist(
            lines.Line2D([new_box[i % 4][0], new_box[(i + 1) % 4][0]], [new_box[i % 4][1], new_box[(i + 1) % 4][1]],
                         color='b'))
        ax0.text(new_box[i % 4][0], new_box[i % 4][1], s[i], color='g', )
    ax0.add_artist(
        lines.Line2D([new_box[0][0], extend1[0]], [new_box[0][1], extend1[1]],
                     color='r'))
    ax0.add_artist(
        lines.Line2D([new_box[3][0], extend2[0]], [new_box[3][1], extend2[1]],
                     color='r'))

    ax0.axis('off')
    fig.tight_layout()
    plt.show()
    plt.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

最终效果

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/742885
推荐阅读
相关标签
  

闽ICP备14008679号