2013-02-12 66 views
8

Tôi đã cố gắng xoay một loạt các đường thẳng 90 độ (với nhau tạo thành một polyline). Mỗi dòng chứa hai đỉnh, nói (x1, y1) và (x2, y2). Những gì tôi đang cố gắng làm là xoay quanh điểm trung tâm của đường thẳng, cho điểm trung tâm | x1 - x2 | và | y1 - y2 |. Đối với một số lý do (tôi không phải là rất hiểu biết về toán học) Tôi không thể có được các dòng để xoay chính xác.Xoay đường quanh điểm trung tâm cho hai đỉnh

Ai đó có thể xác minh rằng toán học ở đây là chính xác? Tôi nghĩ rằng nó có thể là chính xác, tuy nhiên, khi tôi thiết lập các đỉnh của các dòng để các đỉnh xoay mới, dòng tiếp theo có thể không nắm lấy đỉnh mới (x2, y2) từ dòng trước đó, làm cho các đường quay không chính xác .

Dưới đây là những gì tôi đã viết:

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

'p2y' công thức sai cho dấu trừ thứ hai. – didierc

+0

Tốt, cảm ơn bạn. Là một lỗi đánh máy! – adchilds

+0

nevermind rồi. – didierc

Trả lời

17

Các tọa độ của điểm trung tâm của một đoạn thẳng giữa các điểm (x1, y1) và (x2, y2) là:

center_x = (x1 + x2)/2 
center_y = (y1 + y2)/2 

Nói cách khác, nó chỉ là trung bình, hoặc trung bình số học của các cặp giá trị toạ độ x và y.

Đối với đường có nhiều đoạn hoặc đường đa giác, toạ độ x và y của điểm trung tâm hợp lý chỉ là giá trị trung bình tương ứng của các giá trị x và y của tất cả các điểm. Trung bình chỉ là tổng của các giá trị chia cho số của chúng.

Để xoay polyline về bất kỳ điểm tùy ý nào, bao gồm trung tâm riêng, trừ giá trị x và y của điểm quay từ mỗi tọa độ của nó, sau đó xoay kết quả trung gian theo góc mong muốn và cuối cùng thêm giá trị x và y của điểm quay trở lại x và y của mỗi toạ độ. Trong thuật ngữ hình học: Dịch → Xoay → Không dịch.

Kết quả số của ba bộ tính toán có thể được kết hợp và thể hiện bằng một cặp công thức toán học thực hiện tất cả cùng một lúc. Vì vậy, một điểm mới (x ', y') có thể thu được bằng cách quay một điểm tồn tại (x, y) θ   radian xung quanh điểm (cx, cy) bằng cách sử dụng:

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

Kết hợp này toán học/hình học khái niệm về chức năng của bạn tạo ra những điều sau đây:

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

Mã của bạn sai - bạn cần thêm _length_ trung bình vào tọa độ ban đầu. – sdasdadas

+0

@martineau: Lấy các điểm (1, 1) và (4, 4), thuật toán của bạn sẽ cung cấp cho một trung tâm tại (1,5, 1,5). – sdasdadas

+0

Bỏ phiếu cho dịch/xoay vòng. : D – sdasdadas

2

điểm trung tâm của bạn sẽ là:

centerX = (x2 - x1)/2 + x1 
centerY = (y2 - y1)/2 + y1 

vì bạn mất một nửa chiều dài (x2 - x1)/2 và thêm nó vào nơi dòng của bạn bắt đầu để có được đến giữa.

Như một bài tập, mất hai dòng:

line1 = (0, 0) -> (5, 5) 
then: |x1 - x2| = 5, when the center x value is at 2.5. 

line2 = (2, 2) -> (7, 7) 
then: |x1 - x2| = 5, which can't be right because that's the center for 
the line that's parallel to it but shifted downwards and to the left 
+0

Cảm ơn, điều này dường như đã khắc phục vấn đề xoay vòng; tuy nhiên, tôi vẫn phải kết nối từng dòng riêng với nhau một cách chính xác (chúng tự xoay quanh vị trí hiện tại). Mặc dù vậy, điều này khắc phục được sự cố mà tôi quan tâm nhất. Cảm ơn bạn. – adchilds

+0

@adchilds: Nếu bạn muốn xoay tất cả các dòng cùng một lúc (tôi giả sử một polyline giống như một đa giác?) Thì bạn cần phải tìm trung tâm khối lượng của polyline và xoay tất cả các điểm của các đường xung quanh trung tâm đó . – sdasdadas

+1

không thấy cái đó! – didierc

Các vấn đề liên quan