2012-05-01 28 views
19

Về cơ bản tôi đang hỏi câu hỏi này cho JavaScript: Calculate Bounding box coordinates from a rotated rectangleTính X bounding hộp của, Y, chiều cao và chiều rộng của một yếu tố xoay qua JavaScript

Diagram

Trong trường hợp này:

  • iX = Chiều rộng của phần tử HTML được xoay (màu xanh)
  • iY = Chiều cao của phần tử HTML được xoay (xanh dương)
  • bx = Chiều rộng của Boundin g Box (màu đỏ)
  • by = Chiều cao của Bounding Box (màu đỏ)
  • x = X coord của Bounding Box (màu đỏ)
  • y = Y coord của Bounding Box (màu đỏ)
  • iAngle/t = Góc quay của phần tử HTML (màu xanh; không được hiển thị nhưng sử dụng trong mã dưới đây), FYI: Đó là 37 độ trong ví dụ này (không phải là nó quan trọng đối với ví dụ)

Làm sao người ta tính toán X, Y, chiều cao và chiều rộng của một hộp bounding (tất cả các số màu đỏ) xung quanh một phần tử HTML xoay (được cho chiều rộng, chiều cao và Góc quay) thông qua JavaScript? Một bit dính vào điều này sẽ nhận được các hợp âm X/Y ban đầu của phần tử HTML (hộp màu xanh) để sử dụng như một bù đắp bằng cách nào đó (điều này không được biểu diễn trong đoạn mã dưới đây). Điều này cũng có thể phải xem xét CSS3's transform-origin để xác định điểm trung tâm.

Tôi đã có một giải pháp một phần, nhưng tính toán của coords X/Y không hoạt động đúng ...

var boundingBox = function (iX, iY, iAngle) { 
    var x, y, bx, by, t; 

    //# Allow for negetive iAngle's that rotate counter clockwise while always ensuring iAngle's < 360 
    t = ((iAngle < 0 ? 360 - iAngle : iAngle) % 360); 

    //# Calculate the width (bx) and height (by) of the .boundingBox 
    //#  NOTE: See https://stackoverflow.com/questions/3231176/how-to-get-size-of-a-rotated-rectangle 
    bx = (iX * Math.sin(iAngle) + iY * Math.cos(iAngle)); 
    by = (iX * Math.cos(iAngle) + iY * Math.sin(iAngle)); 

    //# This part is wrong, as it's re-calculating the iX/iY of the rotated element (blue) 
    //# we want the x/y of the bounding box (red) 
    //#  NOTE: See https://stackoverflow.com/questions/9971230/calculate-rotated-rectangle-size-from-known-bounding-box-coordinates 
    x = (1/(Math.pow(Math.cos(t), 2) - Math.pow(Math.sin(t), 2))) * (bx * Math.cos(t) - by * Math.sin(t)); 
    y = (1/(Math.pow(Math.cos(t), 2) - Math.pow(Math.sin(t), 2))) * (-bx * Math.sin(t) + by * Math.cos(t)); 

    //# Return an object to the caller representing the x/y and width/height of the calculated .boundingBox 
    return { 
     x: parseInt(x), width: parseInt(bx), 
     y: parseInt(y), height: parseInt(by) 
    } 
}; 

tôi cảm thấy như tôi rất chặt chẽ, nhưng cho đến nay ...

Rất cám ơn vì bất kỳ trợ giúp nào bạn có thể cung cấp!

để giúp NON-JAVASCRIPTERS ...

Khi các yếu tố HTML được luân chuyển, trình duyệt trả về một "ma trận chuyển hóa" hay "ma trận xoay" mà có vẻ là đây: rotate(Xdeg) = matrix(cos(X), sin(X), -sin(X), cos(X), 0, 0);See this page for more info.

Tôi có cảm giác điều này sẽ soi sáng cho chúng tôi cách lấy X, Y của hộp giới hạn (màu đỏ) chỉ dựa trên Chiều rộng, Chiều cao và Góc của phần tử xoay (xanh lam).

New Info

Humm ... thú vị ...

enter image description here

Mỗi trình duyệt dường như để xử lý vòng quay khác nhau từ một X/quan điểm Y! FF bỏ qua nó hoàn toàn, IE & Opera vẽ hộp giới hạn (nhưng các thuộc tính của nó không bị lộ ra, tức là: bx & bởi) và Chrome & Safari xoay hình chữ nhật! Tất cả đều báo cáo đúng X/Y trừ FF. Vì vậy ... vấn đề X/Y dường như chỉ tồn tại đối với FF! Thật kỳ quặc!

Ngoài ra lưu ý, có vẻ như là $(document).ready(function() {...}); kích hoạt quá sớm để X/Y xoay được ghi nhận (là một phần của vấn đề ban đầu của tôi!). Tôi đang xoay các yếu tố trực tiếp trước khi các cuộc gọi thẩm vấn X/Y trong $(document).ready(function() {...}); nhưng chúng dường như không cập nhật cho đến một thời gian sau (!?).

Khi tôi có thêm chút thời gian, tôi sẽ tung ra một jFiddle với ví dụ này, nhưng tôi đang sử dụng dạng sửa đổi "jquery-css-transform.js" để tôi có một chút tinkering trước khi jFiddle ...

Vậy ... chuyện gì vậy, FireFox? Đó không phải là người đàn ông tuyệt vời!

Các âm mưu dày ...

Vâng, FF12 dường như khắc phục vấn đề với FF11, và bây giờ hoạt động như IE và Opera. Nhưng bây giờ tôi trở lại hình vuông với X/Y, nhưng ít nhất tôi nghĩ rằng tôi biết tại sao bây giờ ...

Dường như X/Y đang được báo cáo chính xác bởi các trình duyệt cho đối tượng xoay , X/Y "ma" vẫn tồn tại trên phiên bản không xoay. Có vẻ như đây là thứ tự của các hoạt động:

  • Bắt đầu với một yếu tố un-xoay tại một X, Y của 20,20
  • Xoay cho biết yếu tố, kết quả báo cáo của X, Y là 15 , 35
  • Di chuyển phần tử đã nói qua JavaScript/CSS tới X, Y 10,10
  • Trình duyệt không xoay vòng thành phần 20,20, di chuyển đến 10,10 rồi quay lại, dẫn đến X, Y của 5,25

Vì vậy ... Tôi muốn phần tử kết thúc ở 10,10 bài xoay ion, nhưng nhờ vào thực tế là nguyên tố là (dường như) chuyển động quay lại, kết quả X, Y khác với tập X, Y.

Đây là vấn đề của tôi! Vì vậy, những gì tôi thực sự cần là một chức năng để lấy các coords đích mong muốn (10,10), và làm việc ngược từ đó để bắt đầu X, Y coords mà sẽ dẫn đến yếu tố được quay thành 10,10. Ít nhất tôi biết vấn đề của tôi là gì, nhờ vào các hoạt động bên trong của các trình duyệt, có vẻ như với một phần tử xoay 10 = 5!

+1

Bạn có thể gửi một sơ đồ về những gì bạn muốn? Hình ảnh nói một ngàn chữ và tất cả. –

+0

Tôi thứ hai một bức ảnh, đặc biệt để * bạn * có thể thấy những gì bạn đang làm. –

+0

Cảm ơn! Sơ đồ thực sự là cần thiết (thay vì dựa vào hình ảnh của bức ảnh được tham chiếu). – Campbeln

Trả lời

1

Biến bốn góc thành vectơ từ tâm, xoay chúng và nhận chiều rộng/chiều cao tối thiểu/tối mới từ chúng.

EDIT:

tôi nhìn thấy nơi bạn đang gặp vấn đề bây giờ. Bạn đang thực hiện các phép tính sử dụng toàn bộ bên khi bạn cần thực hiện chúng với các độ lệch từ tâm quay. Có, kết quả này trong bốn điểm xoay (trong đó, kỳ lạ đủ, chính xác là nhiều điểm khi bạn bắt đầu với). Giữa chúng sẽ có một mức tối thiểu X, một X tối đa, một Y tối thiểu và một Y tối đa. Đó là giới hạn của bạn.

+0

Cảm ơn bạn, nhưng tôi rất ngu ngốc toán học (nó không bao giờ thích tôi và tôi hiếm khi thích nó =) Tôi chắc chắn bạn là chính xác, nhưng tôi yêu cầu cầm tay. – Campbeln

+1

Bạn không thể chỉ xoay những thứ mà không cần phải chạy vào một số trig. ;) 'SOH CAH TOA! SOH CAH TOA! SOH ... 'Dễ học hơn nhiều khi bạn cần nó để giải quyết một vấn đề thực sự mà bạn quan tâm, trái ngược với các vấn đề trong lớp học không quan trọng. (* "Nông dân Jones có một cột cờ chiều cao 5 và mặt trời ở một góc 36 độ ... bao lâu là bóng?" *) –

5

Bạn đã thử sử dụng getBoundingClientRect()?

Phương pháp này trả về một đối tượng với giá trị hiện tại của "đáy, chiều cao, trái, phải, trên, chiều rộng" xem xét quay

+2

Chức năng đó không biến đổi trong hầu hết các trình duyệt. Xem https://developer.mozilla.org/en-US/docs/DOM/element.getBoundingClientRect – Hoffmann

13

Tôi biết điều này là hơi muộn, nhưng tôi đã viết một fiddle cho chính xác vấn đề này, trên canvas HTML5:

http://jsfiddle.net/oscarpalacious/ZdQKg/

Tôi hy vọng ai đó thấy hữu ích!

Tôi thực sự không tính x, y của bạn cho góc trên bên trái của vùng chứa. Nó được tính như một kết quả của sự bù đắp (mã từ ví dụ fiddle):

this.w = Math.sin(this.angulo) * rotador.h + Math.cos(this.angulo) * rotador.w; 
this.h = Math.sin(this.angulo) * rotador.w + Math.cos(this.angulo) * rotador.h; 
// The offset on a canvas for the upper left corner (x, y) is 
// given by the first two parameters for the rect() method: 
contexto.rect(-(this.w/2), -(this.h/2), this.w, this.h); 

Cheers

+0

Điều này thật tuyệt vời! Chỉ cần những gì tôi đang tìm kiếm: D – docodemore

+0

hi, khá mát mẻ, làm thế nào u sẽ thích ứng với nó để xử lý một hình dạng mà không xoay quanh trung tâm của nó? – winthers

+0

Vì mục đích hoàn chỉnh, phép tính này hoạt động nếu bạn có một góc giữa 0 và 2 * PI, ** VÀ ** áp dụng hiệu chỉnh này (từ fiddle): 'this.angulo = ((rotador.angulo> Math.PI * 0.5 && rotador.angulo Math.PI * 1.5 && rotador.angulo rixo

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