2009-09-24 36 views
6

Xin chào các bạn, tôi đang cố tính các đỉnh của hình chữ nhật xoay (2D).Tính các đỉnh của hình chữ nhật xoay

Thật dễ dàng nếu hình chữ nhật không được xoay, tôi đã tìm ra phần đó.

Nếu hình chữ nhật đã được xoay, tôi nghĩ về hai cách có thể để tính toán các đỉnh. 1) Tìm hiểu cách chuyển đổi các đỉnh từ không gian địa phương/đối tượng/mô hình (những cái tôi đã tìm ra bên dưới) thành không gian thế giới. Tôi thành thật không có đầu mối, và nếu đó là cách tốt nhất thì tôi cảm thấy như tôi sẽ học được rất nhiều từ nó nếu tôi có thể tìm ra nó ...

2) Sử dụng trig để tìm ra điểm cuối của hình chữ nhật có liên quan đến vị trí của hình chữ nhật trong không gian thế giới. Đây là cách tôi đã cố gắng để làm cho đến bây giờ, tôi chỉ không tìm ra cách.

Đây là chức năng cho phép tính đỉnh vậy, đến nay, nhờ sự giúp đỡ nào

void Rect::calculateVertices() 
{ 
    if(m_orientation == 0) // if no rotation 
    { 
     setVertices(
     &Vertex((m_position.x - (m_width/2) * m_scaleX), (m_position.y + (m_height/2) * m_scaleY), m_position.z), 
     &Vertex((m_position.x + (m_width/2) * m_scaleX), (m_position.y + (m_height/2) * m_scaleY), m_position.z), 
     &Vertex((m_position.x + (m_width/2) * m_scaleX), (m_position.y - (m_height/2) * m_scaleY), m_position.z), 
     &Vertex((m_position.x - (m_width/2) * m_scaleX), (m_position.y - (m_height/2) * m_scaleY), m_position.z)); 
    } 
    else 
    { 
     // if the rectangle has been rotated.. 
    } 

    //GLfloat theta = RAD_TO_DEG(atan(((m_width/2) * m_scaleX)/((m_height/2) * m_scaleY))); 
    //LOG->writeLn(&theta); 

} 

Trả lời

16

tôi sẽ chỉ chuyển mỗi điểm, áp dụng ma trận xoay cùng cho mỗi người. Nếu đó là một vòng xoay phẳng 2D, nó sẽ trông như thế này:

x' = x*cos(t) - y*sin(t) 
y' = x*sin(t) + y*cos(t) 

nơi (x, y) là những điểm ban đầu, (x 'y') là tọa độ xoay, và t là góc đo bằng radian từ trục x. Vòng quay ngược chiều kim đồng hồ như được viết.

Đề xuất của tôi sẽ được thực hiện trên giấy một lần. Vẽ một hình chữ nhật, tính toán các tọa độ mới và vẽ lại hình chữ nhật để thỏa mãn bản thân rằng nó chính xác trước khi bạn viết mã. Sau đó, sử dụng ví dụ này như một bài kiểm tra đơn vị để đảm bảo rằng bạn đã mã hóa nó đúng cách.

+1

+1 - Tôi có xu hướng thích quay lại và sau đó thực hiện bất kỳ công việc nào, giúp cuộc sống đơn giản hơn. –

+2

Bằng cách này bạn có thể nhận được bằng cách chỉ thực hiện 2 thao tác trig (nếu bạn lưu trữ kết quả của 'cos (t)' và 'sin (t)' trước khi tính toán bất kỳ đỉnh nào được xoay). – jnylen

+0

Công thức này sẽ xoay theo chiều kim đồng hồ như thế nào? –

2

Tôi nghĩ bạn đã đi đúng hướng bằng cách sử dụng atan() để trả về một góc. Tuy nhiên, bạn muốn vượt qua height chia cho width thay vì theo cách khác. Điều đó sẽ cho bạn góc mặc định (không được bảo vệ) đến đỉnh trên bên phải của hình chữ nhật. Bạn có thể thực hiện phần còn lại như thế này:

// Get the original/default vertex angles 
GLfloat vertex1_theta = RAD_TO_DEG(atan(
      (m_height/2 * m_scaleY) 
      /(m_width/2 * m_scaleX))); 
GLfloat vertex2_theta = -vertex1_theta; // lower right vertex 
GLfloat vertex3_theta = vertex1_theta - 180; // lower left vertex 
GLfloat vertex4_theta = 180 - vertex1_theta; // upper left vertex 

// Now get the rotated vertex angles 
vertex1_theta += rotation_angle; 
vertex2_theta += rotation_angle; 
vertex3_theta += rotation_angle; 
vertex4_theta += rotation_angle; 

//Calculate the distance from the center (same for each vertex) 
GLfloat r = sqrt(pow(m_width/2*m_scaleX, 2) + pow(m_height/2*m_scaleY, 2)); 

/* Calculate each vertex (I'm not familiar with OpenGL, DEG_TO_RAD 
* might be a constant instead of a macro) 
*/ 
vertexN_x = m_position.x + cos(DEG_TO_RAD(vertexN_theta)) * r; 
vertexN_y = m_position.y + sin(DEG_TO_RAD(vertexN_theta)) * r; 

// Now you would draw the rectangle, proceeding from vertex1 to vertex4. 

Rõ ràng là dài hơn mức cần thiết, vì mục đích rõ ràng. Tất nhiên, giải pháp của duffymo bằng ma trận biến đổi có lẽ thanh lịch và hiệu quả hơn :)

EDIT: Bây giờ mã của tôi thực sự hoạt động. Tôi đã thay đổi (width/height) thành (height/width) và sử dụng bán kính không đổi từ tâm của hình chữ nhật để tính các đỉnh. Mã Python hoạt động (rùa) tại http://pastebin.com/f1c76308c

+0

DEG_TO_RAD là một macro mà tôi đã viết. –

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