Manage the orientation of an object circling a sphere using quaternions

My latest game features an airplane being controlled by the user from a top-down perspective, flying over a spherical earth object. The airplane has the ability to rotate left or right by using the arrow keys on the keyboard, and can accelerate by pressing the UP arrow key. The airplane's direction and speed are determined by the user input, which is stored in the vx and vy variables.

In order to create the illusion of the airplane flying over the earth, the render loop utilizes the vx and vy variables to rotate the globe instead of moving the airplane itself.

However, a problem arises when the player reaches the opposite side of the globe; when the user flies to the right of the screen, the globe also rotates to the right, making it appear as though the airplane is flying backwards. This issue stems from attempting to incorporate old 2D code from a previous airplane game into this 3D game.

I believe that using quaternions may solve this problem, but I lack a full understanding of how to implement them. I think that my vx and vy variables could play a role in creating a "new location" vector. I have read about normalizing vectors, obtaining an axis and angle, but I am unsure of the specifics on how to achieve this. Any assistance on this matter would be greatly appreciated!


Below, you can find the code responsible for rotating the earth when the user flies in a specific x/y direction, along with an image to provide a better understanding of the game scenario.

// AIRPLANE VARIABLES
var friction = 0.85;
var vr = 7.5; // Rotation velocity
var thrust = 0.5;
var max_speed = 20;
var vx = 0; // X-velocity
var vy = 0; // Y-velocity

// RENDER LOOP
function render() {

    // Check states

    if (rotate_left) {
        player.rotation.y = player.rotation.y + (vr * (Math.PI / 180));
    } else if (rotate_right) {
        player.rotation.y = player.rotation.y - (vr * (Math.PI / 180));
    }

    if(throttle){
        var radians = player.rotation.y;
        var ax = (Math.cos(radians) * thrust);
        var ay = (Math.sin(radians) * thrust);

        vx = vx + ax;
        vy = vy + ay;
    } else {
        vx = vx * friction;
        vy = vy * friction;
    }

    // Rotate the globe in the opposite direction of the airplane movement
    globe.rotation.x = globe.rotation.x - (-vx/100);
    globe.rotation.y = globe.rotation.y - (vy/100);
}

Answer №1

Your chosen implementation framework seems to be three.js based on the tags you have used. It is not entirely clear how the 'turn' controls impact the player, especially without knowing how the axes of the plane are defined. While I may not have all the answers, I can offer some helpful starting points.

Begin by educating yourself on the structure of quaternions and how they are implemented in three.js by visiting this resource. In some sources, quaternions are represented as q = [w, x, y, z], but in three.js they are defined as q = [x, y, z, w]. The numbers themselves may seem confusing at first glance, but don't let that deter you.

There are multiple approaches to rotate the quaternion in relation to your velocity.

One suggestion is to rotate the quaternion using the derivative equation outlined here, by determining the angular velocity of the plane around the earth (and vice versa). The 3D particle equation here provides insights into this calculation. By adding the time-scaled derivative (dt*dqdt) to the quaternion q and then normalizing it, you can animate the rotation effectively.

Alternatively, you can select a quaternion rotation that you wish to achieve and utilize the slerp operation available in three.js.

If you provide additional information on how your sphere, plane, and global frames are defined, I may be able to offer further assistance.

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

Is it Possible to Insert Function from a For... in Loop?

Question: How is a function being attached to a variable's memory space without being explicitly assigned? Situation: I have developed a script to eliminate duplicate objects by comparing the values of object keys. However, after initializing the che ...

ExpressJS, defining routes, locating controllers, and documenting APIs

Utilizing expressJS 4.X and nodeJS 6.x In the past, I was defining my routes in this manner : /** * @api {get} /users/:userId Get a user * @apiName GetUser * @apiGroup User * * @apiParam {Integer} userId Users unique ID. * * @apiSuccess (Success 2 ...

Uploading a screenshot to a server using Ionic 4

I have encountered an issue while trying to take a screenshot and upload it to a server using the spring-boot. I utilized a native library for taking the screenshot and an Angular service to obtain the image URI. I converted the image URI to a blob and sen ...

Retrieve nested JSON data from an AJAX request

Currently, I am working with an API that provides JSON data back to me. The challenge I'm facing is figuring out how to access this data and showcase it on my HTML webpage since the results are stored in server memory rather than a file. Below is an e ...

Having trouble with AJAX integration when adding two products to the cart? Looking for a solution to resolve this issue?

In the cart view page, I have noticed that when there is only one product in the cart, I am able to increase and decrease the quantity by clicking on the + and - buttons. However, if I add more than one product to the cart, these buttons do not work for an ...

The size of the Webpack bundle grows with each subsequent build

For my project, I am utilizing webpack to package it as a library. The project consists of a components library, and for each component residing in its own directory under src/ui, I am creating small bundles. Here is an example component structure: src/ ...

Saving numerous files with Promises

There is a Node URL (created using Express) that enables users to download static images of addresses. The calling application sends a request to the /download URL with multiple addresses in JSON format. The download service then calls Google Maps to save ...

Issues with hover functionality in React Material Design Icons have been identified

I'm facing an issue with the mdi-react icons where the hovering behavior is inconsistent. It seems to work sometimes and other times it doesn't. import MagnifyPlusOutline from "mdi-react/MagnifyPlusOutlineIcon"; import MagnifyMinusOutli ...

Retrieve Element By Class Name in JavaScript

How can I modify the border color at the bottom of the .arrow_box:after? Javascript Solution document.getElementsByClassName("arrow_box:after")[0].style.borderBottomColor = "blue"; Despite trying this solution, it seems to be ineffective! For a closer ...

displaying a Google Map within a designated container

I'm currently working on a basic website layout that consists of a full-width banner, a left menu (200px), and right content (600px). I have a simple jQuery script set up to load the content on the right-hand side when any of the five menu items are c ...

Ways to define a variable based on a CSS class attribute?

I need help figuring out how to create a variable in my script that is defined by the width attribute of a CSS class. The snippet I have currently doesn't seem to work as expected. var dist = $('.nav').css(width()); The goal of my script i ...

Is JSON required to transmit an object using socket.io?

I have an object on the frontend that I want to broadcast to all connected clients. Can I send it as is, in its original form? Or do I always have to convert it into a JSON string before sending? Here is my object: var myBox = { x: 400, ...

The click detection on loaded 3DObjects using threejs raycast is not functioning properly

After loading a .obj file using the following code: var loader = new THREE.OBJMTLLoader(); loader.load( "../obj/machine.obj", '../obj/machine.mtl', this.loadObject); I attempt to detect a click on it with the following code: click: function( ...

Move items between two tree views using Javascript and jQuery drag and drop functionality

Recently, I have been on a quest to find drag and drop functionality for moving tree listing items between two separate tree views. While I did come across some solutions that work within a single tree, I have yet to find one that specifically caters to tr ...

Display and conceal various elements in Vue.js using a data list

I'm a beginner in Vue.js, currently using Vue+Webpack. I am trying to make each link display data based on their respective ids when clicked, and match with the show attribute. I have created this functionality in a .vue file. export default { el ...

What are some strategies for efficiently displaying a large amount of data on a screen using Javascript and HTML without sacrificing performance?

Imagine having a hefty 520 page book with over 6,200 lines of text ranging from 5 to 300 characters each. The challenge lies in efficiently displaying this content on the screen for users to read without causing lag or performance issues. Attempting to re ...

Is there a way to upload web page (js) files without submitting a form using a servlet?

I am trying to develop a webpage that enables users to upload one or more files to a servlet without the need for a form submission. I am open to utilizing jQuery and/or Ajax for this purpose and prefer not to rely on any other third-party libraries. I c ...

Update the contents of a div element with JavaScript and PHP combo

When I click on the following div, I want to replace it with a similar one from file.php. The div tag in question is: <div style="display: none;" id="extra" class="container2" xml:id="page"> <div class="title"> <h2>Stuff to check out< ...

When downloading text using Angular, the file may not display new line characters correctly when opened in Notepad

When downloading text data as a .txt file in my Angular application using JavaScript code, I encountered an issue. Below is the code snippet: function download_text_as_file(data: string) { var element = document.createElement('a') eleme ...

Parent window encountering issue while calling child window function

Recently, I have been encountering issues with using an iframe inside a thickbox and calling the function within the iframe. The code snippet I'm currently using is window.frames[0].test();, which seems to be working inconsistently across different br ...