给定两个顶点,围绕中心点旋转线 [英] Rotate line around center point given two vertices

查看:59
本文介绍了给定两个顶点,围绕中心点旋转线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试将一堆线旋转 90 度(它们一起形成多段线).每条线包含两个顶点,例如 (x1, y1) 和 (x2, y2).我目前想做的是围绕线的中心点旋转,给定中心点 |x1 - x2|和 |y1 - y2|.出于某种原因(我不是很懂数学)我无法正确旋转线条.

I've been trying to rotate a bunch of lines by 90 degrees (that together form a polyline). Each line contains two vertices, say (x1, y1) and (x2, y2). What I'm currently trying to do is rotate around the center point of the line, given center points |x1 - x2| and |y1 - y2|. For some reason (I'm not very mathematically savvy) I can't get the lines to rotate correctly.

有人可以验证这里的数学是正确的吗?我认为它可能是正确的,但是,当我将线的顶点设置为新的旋转顶点时,下一行可能不会从上一行抓取新的 (x2, y2) 顶点,从而导致线旋转不正确.

Could someone verify that the math here is correct? I'm thinking that it could be correct, however, when I set the line's vertices to the new rotated vertices, the next line may not be grabbing the new (x2, y2) vertex from the previous line, causing the lines to rotate incorrectly.

这是我写的:

def rotate_lines(self, deg=-90):
    # Convert from degrees to radians
    theta = math.radians(deg)

    for pl in self.polylines:
        self.curr_pl = pl
        for line in pl.lines:
            # Get the vertices of the line
            # (px, py) = first vertex
            # (ox, oy) = second vertex
            px, ox = line.get_xdata()
            py, oy = line.get_ydata()

            # Get the center of the line
            cx = math.fabs(px-ox)
            cy = math.fabs(py-oy)

            # Rotate line around center point
            p1x = cx - ((px-cx) * math.cos(theta)) - ((py-cy) * math.sin(theta))
            p1y = cy - ((px-cx) * math.sin(theta)) + ((py-cy) * math.cos(theta))

            p2x = cx - ((ox-cx) * math.cos(theta)) - ((oy-cy) * math.sin(theta))
            p2y = cy - ((ox-cx) * math.sin(theta)) + ((oy-cy) * math.cos(theta))

            self.curr_pl.set_line(line, [p1x, p2x], [p1y, p2y])

推荐答案

点(x1,y1)和(x2,y2)之间的线段的中心点(cx,cy)坐标为:

The coordinates of the center point (cx,cy) of a line segment between points (x1,y1) and (x2,y2) are:

    cx = (x1 + x2) / 2
    cy = (y1 + y2) / 2

换句话说,它只是两对 x 和 y 坐标值的平均值或算术平均值.

In other words it's just the average, or arithmetic mean, of the two pairs of x and y coordinate values.

对于多段线或折线,其逻辑中心点的 x 和 y 坐标只是所有点的 x 和 y 值的对应平均值.平均值只是值的总和除以它们的数量.

For a multi-segmented line, or polyline, its logical center point's x and y coordinates are just the corresponding average of x and y values of all the points. An average is just the sum of the values divided by the number of them.

旋转二维点 (x,y) θ 弧度的一般公式围绕原点 (0,0) 是:

The general formulas to rotate a 2D point (x,y) θ radians around the origin (0,0) are:

    x′ = x * cos(θ) - y * sin(θ)
    y′ = x * sin(θ) + y * cos(θ)

要绕不同的中心(cx,cy)进行旋转,需要先从点的坐标中减去所需旋转中心的坐标来调整点的x和y值,其效果是移动(在几何学中称为 translating)它在数学上是这样表达的:>

To perform a rotation about a different center (cx, cy), the x and y values of the point need to be adjusted by first subtracting the coordinate of the desired center of rotation from the point's coordinate, which has the effect of moving (known in geometry as translating) it is expressed mathematically like this:

    tx = x - cx
    ty = y - cy

然后将这个中间点旋转所需的角度,最后将旋转点的 x 和 y 值 返回 添加到每个坐标的 x 和 y.在几何术语中,它是以下操作序列:Tʀᴀɴsʟᴀᴛᴇ ─►Rᴏᴛᴀᴛᴇ ─► Uɴᴛʀᴀɴsʟᴀᴛᴇ.

then rotating this intermediate point by the angle desired, and finally adding the x and y values of the point of rotation back to the x and y of each coordinate. In geometric terms, it's the following sequence of operations:  Tʀᴀɴsʟᴀᴛᴇ ─► Rᴏᴛᴀᴛᴇ ─► Uɴᴛʀᴀɴsʟᴀᴛᴇ.

这个概念可以扩展到允许围绕任意点(例如它自己的逻辑中心)旋转整条多段线,只需将描述的数学应用于其中每个线段的每个点.

This concept can be extended to allow rotating a whole polyline about any arbitrary point—such as its own logical center—by just applying the math described to each point of each line segment within it.

为了简化此计算的实现,可以将所有三组计算的数值结果组合起来,并用一对同时执行它们的数学公式表示.因此,可以通过使用以下方法旋转现有点 (x,y),围绕点 (cx, cy) 旋转 θ 弧度来获得新点 (x',y'):

To simplify implementation of this computation, the numerical result of all three sets of calculations can be combined and expressed with a pair of mathematical formulas which perform them all simultaneously. So a new point (x′,y′) can be obtained by rotating an existing point (x,y), θ radians around the point (cx, cy) by using:

    x′ = (  (x - cx) * cos(θ) + (y - cy) * sin(θ) ) + cx
    y′ = ( -(x - cx) * sin(θ) + (y - cy) * cos(θ) ) + cy

将此数学/几何概念结合到您的函数中会产生以下结果:

Incorporating this mathematical/geometrical concept into your function produces the following:

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])

这篇关于给定两个顶点,围绕中心点旋转线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆