Unexpected outcomes when using three.js getWorldPosition method

Please check out the gist I put together over at

https://gist.github.com/sparkbuzz/f1f8d0d8bbc7757b679f

In this gist, you'll find a TypeScript class named OrbitControls. I've been delving into 3D and three.js to explore creating orbit-style controls. Drawing inspiration from MrDoob's JS OrbitControls, I have managed to create my version of these controls.

My implementation involves utilizing the mousedown, mousemove, and mouseup events to maneuver a camera around the world origin. Upon receiving the mousedown event, the initial position of the camera is captured using the following code snippet:

this.subjectPositionStart = this.subject.getWorldPosition();

This initial position serves as the reference for calculating the angles required to adjust the camera's position during a mousemove event when the mouse is moved across the canvas.

Throughout the mousemove event, calculations are performed to determine theta and phi angles based on the distance covered by the mouse. These values are then used to reposition the camera as follows:

this.subject.position.x = rho * Math.cos(theta) * Math.sin(phi);
this.subject.position.y = rho * Math.sin(theta) * Math.sin(phi);
this.subject.position.z = rho * Math.cos(phi);

While everything functions correctly, an issue arises when the rotation angle around the z-axis exceeds 90° or drops below -90° during the subsequent mousedown. In such cases, the camera position appears mirrored instead of aligning as intended.

The observed behavior indicates that the camera flips upon surpassing the 90° limit, resulting in its orientation being reversed although the degrees remain accurate.

As long as the 90° threshold isn't crossed, the navigation operates smoothly during the next mousedown, indicating that the problem lies within the mousedown handler function. When only mousemove events occur, there are no issues with exceeding the angle limits, and navigation proceeds without any hindrances.

Any insights on identifying the root cause of this anomaly?

UPDATE:

I suspect that my method of calculating baseTheta may be incorrect:

var baseTheta:number = Math.asin(this.subjectPositionStart.y / rho / Math.sin(basePhi));

After attempting the following calculation:

var baseTheta:number = Math.acos(this.subjectPositionStart.x / rho / Math.sin(basePhi));

The same issue persists, where the flip occurs between 180° and 360°. This recurring pattern suggests there might be a crucial clue hidden within...

Answer №1

Upon closer examination, I discovered that the calculations for baseTheta and basePhi were incorrect, leading me to realize that the issue stemmed from a previous question I had posed.

Determine θ and ø angles between origin and x,y,z coordinate

Following the guidance provided by Paul.S in the aforementioned link, I made the following changes to the code:

var basePhi:number = Math.acos(this.subjectPositionStart.z / rho);
var baseTheta:number = Math.atan2(this.subjectPositionStart.y, this.subjectPositionStart.x);

This adjustment effectively resolved the problem at hand, eliminating any further issues related to unexpected flipping behavior.

Answer №2

It appears that your issue may be related to how Three.js attempts to maintain the camera facing upwards

You might find some helpful information in this resource: rotating-camera-around-the-x-axis-three-js

The source code for Orbit controls includes constraints on rotation angles. Implementing these constraints in your code could potentially resolve your problem.

// ensure theta remains within specified limits
theta = Math.max( this.minAzimuthAngle, Math.min( this.maxAzimuthAngle, theta ) );

// ensure phi remains within specified limits
phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );

// keep phi between EPS and PI-EPS
phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );

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

Exploring ways to personalize the parsing of url query parameters in express.js

When using req.query, the hash of query parameters is returned. Additionally, if a parameter consists of a JSON object, it is automatically parsed into JSON format, which is quite impressive. However, I am curious about customizing this parsing process. I ...

Obtain the characteristics of a property from an object

Can we extract the type type Values = [number, boolean, string] from the given object? const o = { fst: 1, snd: true, trd: '', } I attempted this approach, but I am looking for types in an array format rather than a union type. type O = t ...

"Troubleshooting callback errors and viewing statistics in multi-configuration setups

Is it possible to utilize multiple Webpack configs while in watch mode? I have noticed that the compilation callback behaves differently when using build versus watch. I couldn't find any references to this behavior and was curious if anyone else has ...

What could be the reason for not just removing the pseudo-class, but instead deleting the entire CSS document altogether?

var style = document.styleSheets[1] style.deleteRule(`.block__header::after`) console.log(`.block__header::after`) What is preventing it from being removed from the CSS document? The pseudo-class is still found in the console, and when trying to dele ...

AJAX has caused the webpage to freeze, prompting a warning about potentially slowing down the browser

My website features an AJAX call to the Alpha Vantage API, which retrieves JSON data on stock symbols and tickers as users type in the search box. function handleKeyPress() { var keywords = document.getElementById("TextBox89 ...

Automated pagination in Jquery running seamlessly

I have successfully created pagination using jQuery. Although the script is functioning properly, I now want it to automatically switch between different pages: <script> $(document).ready(function(){ $("#article_load_favourites").load("indexer_favo ...

How to include a javascript file in a different file and compile it using Node.js

For running my practice JS files, I rely on Node. As an example, I use node bts.js. In order to implement a queue, I decided to install Collections by using the command npm install collections --save. You can also see this reflected in the hierarchy shown ...

Ensuring the validation of JSON schemas with dynamically generated keys using Typescript

I have a directory called 'schemas' that holds various JSON files containing different schemas. For instance, /schemas/banana-schema.json { "$schema": "http://json-schema.org/draft-06/schema", "type": "object", "properties": { "banan ...

Utilizing SPServices and jQuery for seamless CORS functionality

Trying to access a SharePoint list from a different domain on a mobile device. Below is the code snippet for a simple get request: $.support.cors = true; $(function() { $().SPServices({ operation: "GetListItems", webURL: "http://myurl.com/project ...

What is the best way to determine the height of an element after new content has been added through AJAX?

I have been working with a Jquery Mobile page and I am facing an issue when loading a form via AJAX. The plugin I am using to set the page dimensions calculates them after the AJAX call has completed and the layout has been updated. However, the height of ...

Why is it that a specific variable is only undefined in one specific location within the entire component?

import React from 'react'; import { Formik, Form } from "formik"; import { InputField } from "./formui/InputField"; import { applyGharwapasi } from "../../appollo/applyGharwapasi/applyGharwapasi"; import { useMutatio ...

Having trouble getting the code for sending HTML input fields with an attachment field to work in PHP, jQuery, and Ajax

When a button is clicked, I want to send an email with an optional attachment and display the results above the form fields. I've written the code below, but it's not functioning as expected (no action upon clicking the submit button; unable to c ...

Express is capable of running on dual ports simultaneously, irrespective of the specified port

When launching my express app, I typically use app.listen(PORTNO). The app usually runs on 127.0.0.1:PORTNO, but oddly enough it also seems to run on 127.0.0.1:3000. As far as I know, 3000 is the default port for express applications. Does anyone unders ...

center a horizontal line using StyledSheets in your project

After drawing a horizontal line, I noticed that it is positioned towards the left side of the screen. I am hesitant to increase its width. Are there any other methods to move it to the center? I attempted wrapping it with another view and using alignConten ...

The pagination feature of the material-ui data grid is experiencing issues with double clicks because of its compatibility with the react-grid-layout library for

I am currently using the react-grid-layout library to manage the resizing of both charts and a material-ui data grid table. However, I am encountering an issue where when clicking on the table pagination arrow, it does not work properly. I have to click tw ...

What prevents Popper from functioning on its own when I incorporate bootstrap.bundle.js?

Upon my understanding, Bootstrap 4 relies on Popper for its functionalities. When utilizing bootstrap.bundle.js, Bootstrap can smoothly access Popper for various operations. Nevertheless, when attempting to use Popper independently, an error message is enc ...

Tips for delaying the rendering of a directive in AngularJS until the data from a tsv file has been fully loaded

I am trying to integrate d3.js with angularjs to create a line graph using data loaded from a tsv file. However, I am facing an issue where the graph is being rendered before the data is fully loaded. I want the graph to be rendered only after the data has ...

Is there a way to upload numerous images from my local disk onto a canvas using Fabric.js?

I'm currently working on an innovative Image Collage application using the power of HTML5 canvas and Fabric.js. One of the key features I want to implement is the ability for users to simply drag and drop files into the designated 'File Drag and ...

It is not possible to include a new property to an object while inside a function

Looking to add a property to an object? Check out the code below: import React from 'react'; import { Link } from 'react-router-dom'; const Question = () => { let active; const handleClick = (iconName) => { active = {}; ...

Navigating through layers of nested data in Vue.js and assigning values to a multi-layer JSON object can be tricky

In my Vue component childEle, there is a complex form structure stored in the data: data:{ form:{ root1:Number, root2:{ child1:[], child2:{}, child3:String }, root3:[], root4:{ child4:string, child5:[] ...