2009-02-24 66 views
13

Với tham chiếu đến this programming game Tôi hiện đang xây dựng.WPF: Nhận tọa độ mới sau khi xoay vòng

alt text http://img12.imageshack.us/img12/2089/shapetransformationf.jpg

Để dịch một Canvas trong WPF, tôi đang sử dụng hai hình thức: TranslateTransform (để di chuyển nó), và RotateTransform (để xoay nó) [con cái của cùng mộtTransformationGroup]

Tôi có thể dễ dàng nhận được các tọa độ x, y trên cùng của canvas khi không xoay (hoặc xoay ở 90deg, vì nó sẽ giống nhau), nhưng vấn đề tôi đang gặp phải là ở trên cùng bên trái (và 3 điểm còn lại) tọa độ.

này bởi vì khi một RotateTransform được áp dụng, các 's XY tính TranslateTransform không bị thay đổi (và do đó vẫn chỉ ra rằng phía trên bên trái của hình vuông là giống như các chấm vuông (từ hình ảnh)

các Canvas đang được luân chuyển từ trung tâm của nó, vì vậy đó là nguồn gốc của nó.

vì vậy làm thế nào tôi có thể nhận được "mới" tọa độ x và y của 4 điểm sau vòng xoay?

[UPDATE]

alt text http://img25.imageshack.us/img25/8676/shaperotationaltransfor.jpg

Tôi đã tìm thấy một cách để tìm ra phía trên bên trái phối sau khi vòng xoay (như bạn có thể nhìn thấy từ hình ảnh mới) bằng cách thêm OffsetX và OffsetY từ vòng xoay với các tọa độ X và Y bắt đầu.

Nhưng hiện tại tôi đang gặp khó khăn trong việc tìm ra phần còn lại của tọa độ (3 còn lại).

Với hình dạng xoay này, làm cách nào tôi có thể tìm ra tọa độ x và y của 3 góc còn lại?

[EDIT]

Những điểm trong hình ảnh thứ 2 KHÔNG ĐIỂM CHÍNH XÁC VÀ CHÍNH XÁC. Tôi đã chỉ ra những điểm ước tính trong đầu.

[UPDATE] Giải pháp:

Trước hết, tôi xin cảm ơn Jason S cho rằng bài dài và rất nhiều thông tin, trong đó ông mô tả toán học đằng sau toàn bộ quá trình; Tôi chắc chắn đã học được rất nhiều bằng cách đọc bài viết của bạn và thử các giá trị.

Nhưng bây giờ tôi đã tìm thấy một đoạn mã (nhờ EugeneZ 's nhắc đến TransformBounds) thực hiện chính xác những gì tôi muốn:

public Rect GetBounds(FrameworkElement of, FrameworkElement from) 
{ 
    // Might throw an exception if of and from are not in the same visual tree 
    GeneralTransform transform = of.TransformToVisual(from); 

    return transform.TransformBounds(new Rect(0, 0, of.ActualWidth, of.ActualHeight)); 
} 

tham khảo: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/86350f19-6457-470e-bde9-66e8970f7059/

+0

Ở đây bạn có thể tìm thấy dễ dàng nhất tìm cách http://stackoverflow.com/a/22511805/2106820 –

Trả lời

13

Nếu tôi hiểu đúng câu hỏi của bạn:

given: 
shape has corner (x1,y1), center (xc,yc) 
rotated shape has corner (x1',y1') after being rotated about center 

desired: 
how to map any point of the shape (x,y) -> (x',y') by that same rotation 

Dưới đây là các phương trình có liên quan:

(x'-xc) = Kc*(x-xc) - Ks*(y-yc) 
(y'-yc) = Ks*(x-xc) + Kc*(y-yc) 

nơi Kc=cos(theta)Ks=sin(theta)theta là góc quay ngược chiều kim đồng. (để xác minh: nếu theta = 0 này rời khỏi tọa độ không thay đổi, nếu không nếu xc = yc = 0, nó ánh xạ (1,0) đến (cos (theta), sin (theta)) và (0,1) đến (- caveat (theta), cos (theta)) Caveat: đây là cho các hệ tọa độ, trong đó (x, y) = (1,1) nằm ở góc phần tư phía trên bên phải, đối với vị trí của bạn ở góc dưới bên phải, theta sẽ là góc của chiều kim đồng hồ thay vì quay ngược chiều kim đồng hồ.)

Nếu bạn biết tọa độ của hình chữ nhật của bạn được căn chỉnh với trục xy, xc sẽ là trung bình của hai tọa độ x và yc sẽ là trung bình của hai toạ độ y. (trong trường hợp của bạn, nó là xc = 75, yc = 85.)

Nếu bạn biết theta, bây giờ bạn có đủ thông tin để tính tọa độ mới. Nếu bạn không biết theta, bạn có thể giải quyết cho Kc, Ks. Dưới đây là các tính toán có liên quan ví dụ của bạn:

(62-75) = Kc*(50-75) - Ks*(50-85) 
(40-85) = Ks*(50-75) + Kc*(50-85) 

-13 = -25*Kc + 35*Ks = -25*Kc + 35*Ks 
-45 = -25*Ks - 35*Kc = -35*Kc - 25*Ks 

mà là một system of linear equations có thể được giải quyết (tập thể dục cho người đọc: trong MATLAB đó là:

[-25 35;-35 -25]\[-13;-45] 

đến năng suất, trong trường hợp này, Kc = 1,027 , Ks = 0.3622 không có ý nghĩa (K = Kc + Ks được cho là bằng 1 cho quay thuần; trong trường hợp này là K = 1.089) nên không phải là vòng quay thuần túy về hình chữ nhật trung tâm, đó là những gì bản vẽ của bạn chỉ ates. Nó cũng không phải là một vòng quay thuần túy về nguồn gốc. Để kiểm tra, so sánh khoảng cách từ tâm xoay trước và sau khi xoay theo định lý Pythagore, d = deltax + deltay . (đối với quay khoảng xc = 75, yc = 85, khoảng cách trước là 43,01, khoảng cách sau là 46,84, tỷ lệ là K = 1,089; đối với quay về gốc, khoảng cách trước là 70,71, khoảng cách sau là 73,78, tỷ lệ là 1,043. có thể tin rằng tỷ lệ 1,01 hoặc ít hơn sẽ phát sinh từ phối hợp làm tròn số nguyên, nhưng điều này rõ ràng là lớn hơn lỗi vòng tròn)

Vì vậy, có một số thông tin còn thiếu ở đây. Làm thế nào bạn có được những con số (6240)?

Đó là ý chính cơ bản của toán học đằng sau phép quay, tuy nhiên.

chỉnh sửa: aha, tôi không nhận ra chúng là ước tính. (khá gần với thực tế, mặc dù!)

+0

Tôi nhận được các số đó bằng cách thêm các tọa độ X và Y bắt đầu vào OffsetX và OffsetY được lấy từ Rotation Matrix. Vì vậy, nếu OffsetX là 12, và X "không được bảo vệ" của hình dạng là 50, X mới (sau khi quay) là 62. Tương tự với tọa độ Y –

+0

Btw, chỉ cần làm rõ: Các điểm tôi đưa vào hình ảnh không điểm thực, và thậm chí không bù đắp là có thật; Tôi chỉ làm cho chúng lên cho hình ảnh –

+0

Tôi nghĩ rằng các giá trị là một ước tính sơ bộ, ông đã cho thấy minh họa làm ví dụ. – Drahcir

1

Tôi không chắc chắn , nhưng đây là những gì bạn đang tìm kiếm - xoay vòng một điểm trong hệ tọa độ Descartes: link

+0

sẽ có một cái nhìn vào nó. Cảm ơn. –

1

Bạn ca n sử dụng phương thức Transform.Transform() trên Point của bạn với các phép biến đổi tương tự để có được một điểm mới mà các biến đổi này đã được áp dụng.

+0

Transform() chấp nhận một biến Point. Điều gì sẽ là x và y của điểm đó? –

+0

Bên trái và trên cùng của khung hình –

+0

Trong câu hỏi cập nhật của bạn, phương thức Transform() sẽ thực hiện chính xác những gì bạn cần với bất kỳ điểm nào (bao gồm các góc khác của hình vuông). –

2

Nhìn vào phương thức GeneralTransform.TransformBounds().

6

tôi sử dụng phương pháp này:

Point newPoint = rotateTransform.Transform(new Point(oldX, oldY)); 

nơi RotateTransform là ví dụ mà tôi làm việc và thiết lập Angle ... vv.

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