Difficulties arising when trying to convert latitude and longitude coordinates to xyz for camera rotation within Three.js

Currently, I am working on a JavaScript application that allows users to design their own closet. My goal is to enable smooth rotation of the closet without changing the distance from the camera to the closet. While it would be simple to rotate the object itself, this is not feasible due to the different origins of the meshes. Instead, I have concluded that rotating the camera around the closet as if on a sphere is the solution. Therefore, my aim is to calculate the exact position the camera must be in based on any longitude and latitude provided by the user. The result, however, is a rather peculiar rotation effect. You can view the current version of the application here (please note that it does not work with IE at the moment). The relevant code snippet is provided below. It's worth mentioning that I found similar formulas online, checked and verified them multiple times. One thing that remains consistent is the constant distance (radius) to the offset point (xOffset, yOffset, zOffset), yet the rotation appears quite odd. I came across a similar question on Stack Overflow, but adopting their formulas did not improve the situation either.

Pseudo Code:

x = xOffset + radius * cos(longitude) * cos(latitude)
y = yOffset + radius * cos(longitude) * sin(latitude)
z = zOffset + radius * sin(longitude)
camera.lookAt(xOffset, yOffset, zOffset)

Relevant Code (note: degrees are converted to radians):

var lon = 30;
var lat = -90;
var cameraRadius = 400;

function cameraReposition() {   
var lon = dimensions.lon;
var lat = dimensions.lat;
camera.position.x = cameraX + cameraRadius * Math.cos(Math.PI * lon / 180) * Math.cos(Math.PI * lat / 180);
camera.position.y = cameraY + cameraRadius * Math.cos(Math.PI * lon / 180) * Math.sin(Math.PI * lat / 180);
camera.position.z = cameraZ + cameraRadius * Math.sin(Math.PI * lon / 180); 
camera.lookAt(new THREE.Vector3(cameraX, cameraY, cameraZ));
}


$('#visiblecanvas').mousemove(function(e){
    if(mousedown || rightMousedown) {
        var clickX = e.pageX - this.offsetLeft;    
        var clickY = e.pageY - this.offsetLeft;
        lon += (clickY - lastY) / 10;
        lat -= (clickX - lastX) / 10;
        lastY = clickY;
        lastX = clickX;
        if (lon > 360)
            lon -= 360;
        if (lon < -360)
            lon += 360;
        if (lat > 360)
            lat -= 180;
        if (lat < -360)
            lat += 360;
    }
});

It's important to note that the adjustment made to lon and lat when they exceed 360 is currently irrelevant as both values are controlled via the GUI for debugging purposes.

EDIT: Fixed the incorrect link to the application!

Answer №1

    calculateVectorFromCoordinates: function(latitude, longitude, radius, height) {
      var phi = (latitude)*Math.PI/180;
      var theta = (longitude-180)*Math.PI/180;

      var xCoordinate = -(radius+height) * Math.cos(phi) * Math.cos(theta);
      var yCoordinate = (radius+height) * Math.sin(phi);
      var zCoordinate = (radius+height) * Math.cos(phi) * Math.sin(theta);

      return new THREE.Vector3(xCoordinate, yCoordinate, zCoordinate);
    }

Answer №2

The camera seems to be positioned correctly, adjusting properly when latitude or longitude changes while the other remains constant. However, what appears off is the camera's orientation -- without specifying a clear "up," it might choose any orientation, potentially leading to an upside-down view even if the focal point is correct.

Although I haven't experimented with Three.js myself, the documentation does not seem to provide a straightforward way to define the camera's additional information. It may be necessary to manually set and adjust the projectionMatrix along with its inverse for more control over the camera's orientation.

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

Finding and retrieving specific information from nested arrays within a JSON object can be done by implementing a method that filters the data

I have an array of objects where each object contains a list of users. I need to be able to search for specific users without altering the existing structure. Check out the code on StackBlitz I've tried implementing this functionality, but it's ...

Please explain the concept of the Node.js event loop

I've spent countless hours poring over guides and resources on the event loop, yet I still can't grasp its essence. It's common knowledge that the libuv library is responsible for implementing the event loop, but what exactly is this entity ...

The Vue.js checkbox linked to a v-model with a value set to false is currently marked as

I'm attempting to create a to-do list resembling the Eisenhower matrix, but I'm encountering an issue with v-bind and v-model being triggered incorrectly. How can I resolve this bug? https://i.sstatic.net/iIhqR.png Code inspiration from Vue.js T ...

Incorporate a new class for every date within the range of start and end

I have incorporated a JQuery event calendar plugin into my project, sourced from this specific website. Within my events, there are distinct start and end dates. Currently, I have managed to display green squares on the calendar for both the start and end ...

Methods for breaking down a number into individual elements within an array

Suppose there is a number given: let num = 969 The goal is to separate this number into an array of digits. The first two techniques fail, but the third one succeeds. What makes the third method different from the first two? num + ''.split(&ap ...

javascriptEmbed youtube video thumbnail dynamically as users input a URL

I am currently working on a React frontend for my web app. One of the features I want to implement is a URL input box, with an image display panel below it. The goal is that when a user enters a YouTube URL into the input box, the thumbnail of the correspo ...

What is the best way to generate a hyperlink that will open a raphael graph in my own browser?

If I have a web page that includes a raphael.js drawing in <div id='my-canvas'></div> <body> <div id='part_one'>...</div> <div id='my-canvas'></div> <div id='part_thre ...

Fetching a JSON object from an external URL using JavaScript

Currently, I am working on a project using JavaScript and have an API that provides me with a JSON Object. You can access this JSON object by clicking on the following link: . Within this JSON object, there is a specific element located at JSONOBJECT.posi ...

When trying to convert to JSON in node, the process fails. However, the data can still be

I am currently working on converting an array to JSON in order to send it to a client. The data I see in the console is as follows: [ NL: [ true, true, true, true, true, true, true, true, true, true, true, true ], ...

Retrieve the concealed method's name within the immediately invoked function expression (IIFE

This Meteor sever code has a private method called printFuncName within an IIFE. However, when this method is invoked from a public method, it results in the following error: TypeError: Cannot read property 'name' of null I am curious to unde ...

Challenges arise when utilizing the foundation 6 grid for image overlays within a React application

Having some trouble using the foundation 6 xy grid for the first time and aligning three images with text overlays at the bottom of each image. I am struggling to make the background of the text fill the full width of the image while also ensuring it is re ...

Creating a route provider tailored to specific user roles

I have a rather straightforward requirement. There are 3 different User Roles: CATUSER LICUSER ALLUSER The User Role value is stored in the $rootScope.userRole variable. The User Role is predefined before the AngularJS application starts as the Angula ...

The operation of 'val' is not supported by HTMLInputElement

While working with a table row, I am iterating through each cell. Inside every cell lies a text box containing some value that I need to store in an array. function dothing() { var tds = $('#'+selected+' td'); var submi ...

The <Link> component in NextJS is not functioning as anticipated

I am currently developing a Next.js application and I'm facing an issue with creating dynamic routes upon clicking a card component. Even after wrapping my Cards with the <Link> from Next.js, the page doesn't navigate when clicked. I experi ...

Navigating through React Native with TypeScript can be made easier by using the proper method to pass parameters to the NavigationDialog function

How can I effectively pass the parameters to the NavigationDialog function for flexible usage? I attempted to pass the parameters in my code, but it seems like there might be an issue with the isVisible parameter. import React, { useState } from 'rea ...

Unable to hide the mobile menu button

https://i.sstatic.net/5rdYY.pngI am currently working on a fun website project . I am facing an issue with the mobile menu button not disappearing using display:none in Safari on my iPhone when in landscape mode, even though it works fine in Chrome. My g ...

Unable to view the image in browsers other than Internet Explorer

On a webpage, there is a feature where clicking on the "Add More" link should display an input box and a "Delete" button image. Surprisingly, this functionality works perfectly on IE browsers, but not on Mozilla or Chrome. In non-IE browsers, only the text ...

I am attempting to draw a correlation between two numerical variables

I'm struggling to compare two scores in my game. When they match, I want it to display "You won", but I can't get it to work. I've attempted using the parseInt method and .val method, but no luck so far. var numberFour = Math.floor(Math.ra ...

What is the reason behind my resizer bar not changing color to green?

Whenever I resize the bar between the West and Inner Center areas, it turns green. However, the bar between the Inner Center and Inner South areas does not change color. How can I make it turn green when resizing, including adding the orange highlight for ...

Utilizing the setState method within an 'async function with arguments' for handling onClick events

In my next.js app, I have a file named "temp.js" located in the /pages directory. This is the code inside temp.js: import React from 'react'; import {Button} from '@mui/material'; class SomeClass extends React.Component{ state={ ...