点 (x1,y1) 和 (x2,y2) 之间的线段的中心点 (cx,cy) 坐标为:
cx = (x1 + x2) / 2
cy = (y1 + y2) / 2
换句话说,它只是两对 x 和 y 坐标值的平均值或算术平均值。
对于多段线或多段线,其逻辑中心点的 x 和 y 坐标只是所有点的 x 和 y 值的相应平均值。平均值只是值的总和除以它们的数量。
一般公式为旋转 2D 点 https://en.wikipedia.org/wiki/Rotation_matrix#In_two_dimensions(x,y) θ 弧度围绕原点(0,0) 是:
x′ = x * cos(θ) - y * sin(θ)
y′ = x * sin(θ) + y * cos(θ)
要绕不同的中心(cx,cy)执行旋转,需要通过首先从该点的坐标中减去所需旋转中心的坐标来调整该点的x和y值,这具有移动的效果(已知在几何学中为翻译 https://en.wikipedia.org/wiki/Translation_(geometry))它的数学表达如下:
tx = x - cx
ty = y - cy
然后将该中间点旋转所需的角度,最后添加旋转点的 x 和 y 值back每个坐标的 x 和 y。用几何术语来说,它是以下操作序列:Tʀᴀɴsʟᴀᴛᴇ ─►Rᴏᴛᴀᴛᴇ ─►Uɴᴛʀᴀɴsʟᴀᴛᴇ。
这个概念可以扩展到允许围绕任何任意点(例如其自己的逻辑中心)旋转整个多段线,只需将描述的数学应用到其中每个线段的每个点即可。
为了简化该计算的实现,可以将所有三组计算的数值结果组合起来并用一对同时执行它们的数学公式来表示。因此,可以通过使用以下方法将现有点 (x,y) 绕点 (cx, cy) 旋转 θ 弧度来获得新点 (x′,y′):
x′ = ( (x - cx) * cos(θ) + (y - cy) * sin(θ) ) + cx
y′ = ( -(x - cx) * sin(θ) + (y - cy) * cos(θ) ) + cy
将此数学/几何概念合并到您的函数中会产生以下结果:
from math import sin, cos, radians
def rotate_lines(self, deg=-90):
""" Rotate self.polylines the given angle about their centers. """
theta = radians(deg) # Convert angle from degrees to radians
cosang, sinang = cos(theta), sin(theta)
for pl in self.polylines:
# Find logical center (avg x and avg y) of entire polyline
n = len(pl.lines)*2 # Total number of points in polyline
cx = sum(sum(line.get_xdata()) for line in pl.lines) / n
cy = sum(sum(line.get_ydata()) for line in pl.lines) / n
for line in pl.lines:
# Retrieve vertices of the line
x1, x2 = line.get_xdata()
y1, y2 = line.get_ydata()
# Rotate each around whole polyline's center point
tx1, ty1 = x1-cx, y1-cy
p1x = ( tx1*cosang + ty1*sinang) + cx
p1y = (-tx1*sinang + ty1*cosang) + cy
tx2, ty2 = x2-cx, y2-cy
p2x = ( tx2*cosang + ty2*sinang) + cx
p2y = (-tx2*sinang + ty2*cosang) + cy
# Replace vertices with updated values
pl.set_line(line, [p1x, p2x], [p1y, p2y])