Update an item's precise orientation in relation to the global axis

Update: Included a jsfiddle for clarification:

JSFiddle

I am working with an object (a cube) in a scene and my objective is to provide it with 3 angles that represent its orientation in the real world. These angles are measured against the X, Y, and Z axes. Unfortunately, I am struggling with how to assign these angles to the object and then update them as new data is received. It seems that when I set initial angles everything works fine, but when I try to set new angles, they seem to be relative to the object's local space rather than the world space. While I have looked at similar questions on this topic, most of them focus on rotating objects around an axis rather than setting explicit angles against the world axis.

Currently, when one of my x, y, or z angles changes, I use the following code:

cube.rotation.set(x, y , z, 'XYZ');

To provide a visual example, here is a screenshot of my cube...without changing X or Y, I rotate it by 90 degrees about Z axis. See the before and after images below:

https://i.sstatic.net/FmJr0.png

and

https://i.sstatic.net/SavFe.png

You can see how the rotation has occurred around the normal direction of the purple face rather than the world Z axis...

This issue has left me puzzled and frustrated. :-(

Answer №1

When using cube.rotation.set(), keep in mind that this creates a rotation along the local axes of the object. Initially, after rotating along the X axis, the local X axis aligns with the world X axis. However, subsequent rotations along Y and Z axes will no longer match the world axes due to changes in local space alignment. To achieve rotations along world axes, you need to translate world axes into the object's local space.

To integrate this concept, consider the following code snippet:

var x = toRadians($("#rotateX").slider("option", "value"));
var y = toRadians($("#rotateY").slider("option", "value"));
var z = toRadians($("#rotateZ").slider("option", "value"));

var rotation = new THREE.Matrix4();
rotation.multiply(new THREE.Matrix4().makeRotationX(x));

var worldYAxis = new THREE.Vector3(0, 1, 0).applyMatrix4(new THREE.Matrix4().getInverse(rotation));
var rotationWorldY = new THREE.Matrix4().makeRotationAxis(worldYAxis, y);
rotation.multiply(rotationWorldY);

var worldZAxis = new THREE.Vector3(0, 0, 1).applyMatrix4(new THREE.Matrix4().getInverse(rotation));
var rotationWorldZ = new THREE.Matrix4().makeRotationAxis(worldZAxis, z);
rotation.multiply(rotationWorldZ);

cube.matrixAutoUpdate = false;
cube.matrix = rotation;

By applying this code, you'll observe rotations happening along the world axes as desired. However, keep in mind that consecutive rotations can distort the intended global axis rotations due to issues with commutative properties of rotations.

If you wish to maintain rotations specifically along world axes regardless of slider movements, you can utilize the function outlined below:

var prevX = 0, prevY = 0, prevZ = 0;
function doRotate() {
    // Code implementation here
}

By binding this function to slider events, you ensure constant rotation along world axes irrespective of object orientation. Just remember that absolute slider values may not directly correspond to specific axis angles but rather represent incremental adjustments relative to the current orientations.

An example demonstrating this behavior is available on this JSFiddle link. Overall, storing the entire transformation matrix instead of individual angle values proves to be a more robust approach for preserving accurate object rotations.

Answer №2

To ensure proper rotations, it is important to include a pivot point within the scene. This pivot point will serve as the central axis for all rotations. The cube mesh should then be attached to the pivot point, allowing for smooth and accurate rotation adjustments.

Feel free to check out the updated jsFiddle link: https://jsfiddle.net/x5w31f33/

var cube = new THREE.Mesh( geometry, material );
cube.position.set(2, 0, 0);

var pivotPoint = new THREE.Object3D();
scene.add( pivotPoint );
pivotPoint.add(cube);

pivotPoint.rotation.set(x, y , z, 'XYZ');

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Incorporating a Custom CKEditor5 Build into an Angular Application

I am currently in the process of developing an article editor, utilizing the Angular Integration for CKEditor5. By following the provided documentation, I have successfully implemented the ClassicEditor build with the ckeditor component. Below are the ess ...

Retrieve a result by utilizing a nested function in conjunction with the request NPM module

Hello there! I'm currently working on scraping data from the ghost blogging platform using the request package. However, I've run into a bit of a roadblock when trying to return a value of a nested request. I've pinpointed the area that seem ...

Ways to ensure your Javascript code only runs based on the specific browser

I need a Javascript code to run depending on the browser version. Specifically, if the browser is not IE or is IE 9+, one piece of Javascript should be executed. If the browser is IE8 or lower, another piece of Javascript should be executed. My attempt to ...

What is the process of transforming the content of a file into an array using JavaScript?

I have a file named "temperatures.txt" that contains the following text: 22, 21, 23 Is there a way to transfer the contents of this file into a JavaScript array? const weatherData = [22, 21, 23]; ...

Converting Greek text to UTF-8 using Javascript

Currently, I am working on a project with my teacher to digitalize a Greek textbook by transforming it into an online application. This process involves the conversion of a Shapefile, which draws polygons on maps along with polygon descriptions, and mappin ...

Adjusting Text Size Depending on Width

I recently used an online converter to transform a PDF into HTML. Check out the result here: http://www.example.com/pdf-to-html-converted-file The conversion did a decent job, but I'm wondering if it's feasible to have the content scale to 100% ...

Do form validations affect the values assigned to ng-model objects?

If a form has the structure below: <form> <input type="text" required ng-model='myValue' ng-maxlength='5'></input> {{myValue}} {{myValue.length}} </form> Is there a way to prevent the model from b ...

the conditional operator used without assigning the result to a variable

Exploring conditional operators on html canvas, I am seeking a streamlined approach to dynamically change stroke color based on conditions. Online examples have not provided a satisfactory solution in a single line of code. Currently, without using a cond ...

Close any open alerts using Protractor

While using protractor and cucumber, I have encountered an issue where some tests may result in displaying an alert box. In order to handle this, I want to check for the presence of an alert box at the start of each test and close/dismiss it if it exists. ...

Retrieve information from a JSON file containing multiple JSON objects for viewing purposes

Looking for a solution to access and display specific elements from a JSON object containing multiple JSON objects. The elements needed are: 1) CampaignName 2) Start date 3) End date An attempt has been made with code that resulted in an error displayed ...

Having trouble with PHP Storm and Vue component not working? Or encountering issues with unresolved function or method in your

I have been struggling with this issue for days and cannot seem to find a solution online. Being new to Vue.js, I am currently working on a TDD Laravel project: My goal is to add the standard Vue example-component to my app.blade.php as follows: app.bla ...

Searching for the closest jQuery value associated with a label input

As a beginner in JQuery, I am looking to locate an inputted value within multiple labels by using a Find button. Below is the HTML snippet. Check out the screenshot here. The JQuery code I've attempted doesn't seem to give me the desired output, ...

PhantomJS Karma encountering SyntaxError when trying to export variables

I've encountered an issue while running Karma and PhantomJS. When I attempt to run, the console displays the following message: 22 03 2016 14:58:47.865:WARN [karma]: No captured browser, open http://localhost:9876/ 22 03 2016 14:58:47.875:INFO [karm ...

using recursion within callback functions

In my JavaScript function with a callback, I am utilizing the "listTables" method of DynamoDB. This method returns only 100 table names initially. If there are more tables, it provides another field called "LastEvaluatedTableName", which can be used in a n ...

Error: The value of _This.props is not defined

Hey there, I am new to working with React Native and could really use some assistance with this issue: TypeError: _props.goToScreen is not a function. Any help would be greatly appreciated, thank you in advance! In my Profile.js file, I am trying to click ...

Creating head tags that are less bouncy

After running my code, I noticed that the headlines didn't transition smoothly - they seemed to jump rather than flow seamlessly. To address this issue, I attempted to incorporate fadeIn and fadeOut functions which did improve the smoothness slightly. ...

Printing HTML to a VueJS page is simple and efficient

I have a situation where one of my attributes in a property contains an HTML string. Instead of rendering the HTML as expected, when I output it within my template, the browser displays the raw HTML code with tags intact. It doesn't interpret it as a ...

Exploring the CSS scale transformation alongside the Javascript offsetHeight attribute

After combining offsetHeight with scale transformation, I experienced a strange result. Below is my simple HTML code: <body> <div id="id01"> Some Text </div> <div id="id02" style="transform-origin: left top; transf ...

Can someone guide me on how to locate and access the port number?

In my Reactjs project root directory, I've created a .env file. This is what's inside my .env file: PORT = 30001 ... In my App.tsx file, I'm trying to access the port like this: const PORT_NUMBER = process.env.PORT; When I run yarn start ...

Creating a unique Angular filter involves combining different techniques and functionalities to tailor

Hey there! I'm just diving into the world of Angular JS and I'm looking to filter any Twitter text that comes back containing a hashtag, and turn that word into a clickable link. For example: If the returned twitter text is "The quick brown #f ...