2010-09-28 44 views
13

Tôi biết xoay vòng 3D được ghi lại trên SO và nhiều trang web khác, nhưng mặc dù đọc vô số lời giải thích tôi vẫn chưa tìm ra nơi tôi đang đi sai. Nền tảng của tôi là về nghệ thuật và thiết kế, không phải là toán học và lập trình, và tôi không bao giờ thực sự chắc chắn nếu góc tấn công của tôi (không có ý định chơi chữ) là điều đúng đắn. Thay vì dán một mảnh chắp vá của mã ảm đạm của tôi, tôi bao gồm một hình ảnh mô tả vấn đề của tôi. Điều tôi thực sự thích là một sự phân tích từng bước về cách giải quyết nó. Mã giả là hữu ích, nhưng tôi sẽ tìm hiểu thêm nếu ai đó sẽ chỉ hướng tôi đi đúng hướng hoặc chỉ ra những cạm bẫy phổ biến.Xoay 3D với Axis & Angle


alt text

Đỏ = X-Axis, Green = Y-Axis, Blue = Z-Axis

Magenta vectơ = gốc -> một số X, Y, Z điểm

Khối màu đỏ tươi = trung bình của các điểm cuối của hai vec-tơ đỏ tươi (có tên tốt hơn cho điều này không?)

Vectơ trắng = vectơ chéo của hai vec tơ đỏ tươi (được mở rộng để dịch chuyển ay, vector thực tế là bình thường)

đối tượng khối Cyan = luân chuyển không


trước đây tôi đã sử dụng Away3D và Papervision; trong các thư viện này, việc áp dụng các góc Euler cho các thuộc tính rotationX, rotationY hoặc rotationZ của đối tượng sẽ xoay đối tượng cục bộ, như thể nó ở gốc bất kể vị trí thực tế của nó. Với Three.js, đây không phải là trường hợp. Sửa đổi các thuộc tính rotation.x và rotation.y của đối tượng tạo ra một hiệu ứng kì lạ khi đối tượng dường như nghiêng một chút trên trục Z. Thậm chí còn khó hiểu hơn là điều này xảy ra khi đối tượng nằm ở gốc. Tôi nghĩ rằng có thể sử dụng Quaternion -> Matrix hoặc Axis/Angle -> chức năng Matrix sẽ giải quyết vấn đề của tôi, nhưng không có con xúc xắc. Có vẻ như có một khái niệm cốt lõi mà tôi không nhận được.

Dù sao, những gì tôi muốn làm là định hướng khối lập phương cho vectơ sản phẩm chéo (màu trắng), sao cho đầu khối lập phương quay về hướng của vectơ đó. Sau đó, tôi muốn xoay khối lập phương dọc theo cùng một trục. Hình ảnh tôi đã đính kèm cho thấy kết quả của nhiều giờ hơn tôi muốn thừa nhận cố gắng đạt được kết quả này. Mã của tôi lỏng lẻo trông như thế này:

axis = Vector3.cross(a, b) 
axis.normalize() 
angle = 45 * TO_RADIANS; 
quat = AxisAngle2Quaternion(axis, angle) 
rot = Quaternion2Matrix(quat) 
cube.matrix = rot 

Cảm ơn trước,

Casey


Edit: Bắt đầu một bounty

Có lẽ tôi đang hiểu lầm thế nào điều này có nghĩa vụ phải công việc. Dưới đây là hình ảnh khác:

alt text

Am tôi không chính xác trong suy nghĩ rằng vector magenta đây là trục, và các mũi tên màu cam chỉ xoay xung quanh trục này dựa trên các góc? Bằng cách này hay cách khác, tôi muốn định hướng khối lập phương lục lam dựa trên một số vector hướng và xoay nó. Tôi đang làm gì vậy !?

+0

Không ai phản ứng, nhưng tôi thực sự nghĩ rằng câu hỏi của bạn là một trong những của những công thức tốt nhất tôi đã thấy ở đây cho đến nay. Có lẽ không ai biết? Tôi cũng tò mò muốn xem câu trả lời ở đây. – erikbwork

+0

Có lẽ họ đang tránh xa khỏi khía cạnh Three.js ... Tôi cho rằng đây là một vấn đề khá cơ bản – Casey

+0

Tôi đã có thể tiến gần hơn với phương thức "Utils3D.pointTowards()" trong Flash: http: // help. adobe.com/en_US/AS3LCR/Flash_10.0/flash/geom/Utils3D.html Nhưng tôi không biết cách áp dụng xoay vòng trục và tôi không thể tìm thấy bất kỳ hàm OSS nào có thể so sánh được – Casey

Trả lời

4

Cách tiếp cận của bạn có vẻ chính xác nhưng bạn không thể hiện được a, b vectơ là gì và góc không đổi, tôi đoán, chỉ để thử nghiệm. Tôi đã làm điều này trước vì vậy tôi đào lên mã của tôi và đây là môn toán tôi thấy ...

đưa ra:
originalVec = đơn vị vector hướng lên trục Y (chỉ đạo của khối đầu/bình thường)
targetVec = trắng vector

Bây giờ bạn muốn trục và góc sẽ xoay originalVec để căn chỉnh với targetVec. Trục quay trực tiếp nhất là vuông góc với cả hai vectơ đầu vào, vì vậy hãy lấy sản phẩm chéo của chúng. Trục đó không phải là một vectơ đơn vị vì vậy cũng chuẩn hóa nó. Góc quay (theo radian) là nghịch đảo cosin của sản phẩm chấm.

axis = Vector3.cross(originalVec, targetVec) 
axis.normalise 
angle = inversecos(Vector3.dot(originalVec, targetVec)) 

quat = AxisAngle2Quaternion(axis, angle) 
rot = Quaternion2Matrix(quat) 
cube.matrix = rot 

Thay vì thay thế ma trận của khối Tôi nghĩ rằng bạn muốn soạn nó với mới chuyển đổi ...

cube.matrix.multiplyBy(rot) 

... nhưng tôi không chắc chắn 100% về điều đó. Ngoài ra, tôi đã thấy các triển khai mà AxisAngle2Quaternion lấy một góc theo độ. Khi các vectơ đầu vào song song hoặc đối diện với trục là < 0,0,0> do đó cần được kiểm tra. Nếu khối lập phương quay sai đường thì các tham số vectơ chéo sản phẩm theo thứ tự sai, tôi không bao giờ nhớ cái nào và chỉ thử cả hai. hth.

Sửa
Tôi đã có một cơ hội để chơi với Three.js và hack một trong những ví dụ để định hướng một khối lập phương. Nhận xét cho thấy nơi tôi đã thêm công cụ và tất cả các phép toán định hướng xảy ra trong alignCube().
Align and Spin example
Di chuyển lên/xuống sẽ di chuyển đường đích. Xoay trái/phải quay trên dòng.

Đối tượng cảnh trong Three.js dường như tất cả được kế thừa từ Object3D có thuộc tính autoUpdateMatrix được đặt theo mặc định. Điều này cần phải được thiết lập sai nếu không hàm updateMatrix được gọi là tính toán lại ma trận từ các vị trí đối tượng, các thuộc tính scale và rotation. Hoặc bạn có thể gán một hàm updateMatrix khác.

Thật tuyệt nếu Three.js đã có một số tài liệu hướng dẫn :)

+0

Cảm ơn - thật tuyệt khi biết rằng tôi đang đi đúng hướng. Thật không may tôi đã không nhận được nó để làm việc. Tôi đang thay thế ma trận của khối lập phương bởi vì tôi đang cố gắng đơn giản hóa mọi thứ ngay bây giờ và làm việc này tại nguồn gốc. Đây có phải là ok, hoặc là nó chỉ giới thiệu các vấn đề? – Casey

+0

Ví dụ này thật tuyệt vời! Tôi không có thời gian để đi qua nó ngay thứ hai này, nhưng tôi nghi ngờ bạn sẽ nhận được tiền thưởng :) Cảm ơn! – Casey

+0

Đó là công trình, ngọt ngào. Tôi hiểu lầm cách các ma trận trục/góc hoạt động như thế nào. Tôi đã cố gắng làm tất cả với một ma trận duy nhất. Tôi đang đăng chức năng căn chỉnh bên dưới cho bất kỳ ai quan tâm. – Casey

0

Vì không ai có giải pháp thực sự tốt, tôi có thể khuyên bạn nên làm cách nào để tiến gần hơn.

Có 3 vấn đề có thể và bạn có một trong số họ:

  1. Toán học là không đúng, hoặc bạn không hiểu nó. (Không nên quá nhiều vấn đề ở đây)
  2. Điểm nổi arithmetics luôn là vấn đề đối với máy tính (cũng không phải là vấn đề, bởi vì nó là một vấn đề cơ bản. Nếu khung của bạn không thể đưa ra giải pháp thì khung làm việc không có giá trị ở tất cả cho lập trình 3d)
  3. Bạn không sử dụng khuôn khổ ngay

Bởi vì nó là khá khả năng là vị trí thứ 3 là trường hợp, hãy thử tìm một danh sách gửi thư hoặc diễn đàn hỗ trợ hoặc bất cứ điều gì cho khuôn khổ và nói chuyện với mọi người ở đó. Họ sẽ có thể giải thích cho bạn, những gì bạn làm sai với khuôn khổ của họ. Sau đó quay lại và đăng giải pháp ở đây!

+0

Cảm ơn đề xuất - Tôi đã liên hệ với tác giả của khung và tôi sẽ xem liệu mã tương tự có mang lại kết quả tương tự trong Away3D – Casey

+0

Tôi đang làm điều gì đó không đúng - tôi không thể làm cho nó hoạt động trong Flash . – Casey

+0

Kiểm tra liên kết ví dụ từ Trochoid, nó hoạt động tốt! – Casey

3

Từ ví dụ Trochoid của, đây là chức năng mà tôi sử dụng để đạt được sự liên kết và quay từ hình ảnh thứ hai:

//object, normalized direction vector, rotation in radians 
function align(target, dir, rot) { 
    //Three.js uses a Y up coordinate system, so the cube inits with this vector 
    var up = new THREE.Vector3(0, 1, 0); 

    //euler angle between direction vector and up vector 
    var angle = Math.acos(up.dot(dir)); 

    //cross product of the up vector and direction vector 
    var axis = new THREE.Vector3(); 
    axis.cross(up, dir); 
    axis.normalize(); 

    //rotation to aligns the target with the direction vector 
    var rotate = THREE.Matrix4.rotationAxisAngleMatrix(axis, angle); 

    //rotation around direction vector 
    var revolve = THREE.Matrix4.rotationAxisAngleMatrix(dir, rot); 

    //compose the rotations (order matters, can be done other ways) 
    revolve.multiplySelf(rotate); 

    //assign matrix (autoUpdateMatrix = false) 
    target.matrix = revolve; 
} 
+0

Tôi hạnh phúc bạn cuối cùng đã tìm thấy một số cách để làm cho nó hoạt động! – erikbwork

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