Decide whether an angular rotation is within the camera's field of vision inside a spherical object

Seeking assistance with a three.js project. I have set up a camera inside a SphereGeometry at position (0,0,0) and am projecting an image on the sphere's wall.

My goal is to create interactive JS elements outside of the threejs framework that respond to the direction in which the camera is facing. Given theta & phi as parameters representing the rotation angles around x & z, and y & z, respectively, I aim to trigger JS events when those specific points are within the camera's view. These points are not physical objects but rather defined by rotation angles. The camera itself is controlled by mouse or device orientation, so I need the JS events to be triggered only when manually rotating the camera.

I initially tried using Frustums.containsPoint method but realized it may not fit my needs since I'm looking for camera angles, not physical points in space. I then attempted to use camera.getWorldDirection() or camera.rotation but haven't made much progress.

If anyone has insights or solutions, I would greatly appreciate your help.

Answer №1

To achieve interactive regions, consider defining them as cones utilizing a direction vector and angle. Then, during camera rotation, validate if the camera's forward direction lies within the cone.

Answer №2

It appears that the latitude and longitude angles are already being captured and saved with each mousemove event in the following way:

function onDocumentMouseMove( event )
{
    if ( isUserInteracting === true && !isControlInteraction )
    {
        lon = (( onPointerDownPointerX - event.clientX ) * 0.1 + onPointerDownLon) % 360;
        lat = (( event.clientY - onPointerDownPointerY ) * 0.1 + onPointerDownLat) % 360;
    }
}

With the lat/lon variables, I can then calculate a theta/phi offset from a point p. If the offset is within a specified radius, such as 30 degrees, it is considered in range.

var v_theta = THREE.Math.degToRad(lat);
var v_phi = THREE.Math.degToRad(lon);
var p_theta = THREE.Math.degToRad(p[0]);
var p_phi = THREE.Math.degToRad(p[1]);

v_theta = Math.atan2(Math.sin(v_theta), Math.cos(v_theta));
v_phi = Math.atan2(Math.sin(v_phi), Math.cos(v_phi));
p_theta = Math.atan2(Math.sin(p_theta), Math.cos(p_theta));
p_phi = Math.atan2(Math.sin(p_phi), Math.cos(p_phi));

var theta_offset = Math.abs(v_theta - p_theta) * 180 / Math.PI;
var phi_offset = Math.abs(v_phi - p_phi) * 180 / Math.PI;
if ( theta_offset <= radius && phi_offset <= radius ) 
{
   // execute some code here
}

However, this method does not account for device orientation control events which operate independently. My current challenge lies in determining how to calculate lat/lon values from device orientation data. While I can obtain the camera's rotation and position, deriving lat/lon from the camera's rotation vectors remains unclear to me.

Answer №3

Ah-ha! I finally cracked the code on trigonometry. By incorporating an event listener for device orientation, I can now accurately update the latitude and longitude based on the direction of the world.

window.addEventListener('deviceorientation', function(e) {
    e.preventDefault();

    var angle = window.orientation;
    if (angle == null) return;

    var direction = camera.getWorldDirection();
    var phi = Math.acos(direction.y);
    var theta = Math.atan2(direction.x, direction.z);
    theta = Math.atan2(Math.sin(theta), Math.cos(theta));

    // Update latitude / longitude
    lon = 90 - THREE.Math.radToDeg(phi);
    lat = THREE.Math.radToDeg(theta);
});

Now, the challenge lies in compensating for the rotation of the camera, which has been a bit tricky for me. In threejs, it appears that on iOS, the world direction vector aligns with the camera's initial rotation upon page load, with only the window.orientation angle changing. Thus, the original orientation impacts the position and rotation. To set the image center at (0,0), I've found the following approach seems to work on iOS, but I'm uncertain if it's the correct method:

var theta = Math.atan2(direction.x, direction.z);
if (init_orientation === 0) theta = Math.PI - theta;
else if (init_orientation === -90) theta = -Math.PI/2 - theta;
else if (init_orientation === 90) theta = Math.PI/2 - theta;
theta = Math.atan2(Math.sin(theta), Math.cos(theta));

Regrettably, this method doesn't offer consistent results on Android devices. I would appreciate any insights on how best to tackle this issue.

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

Creating a Login Form with Node.js and MongoDB

Currently, I am working on a node.js application that is connected to a remote mongoDB server. Inside the database are specific custom codes that have been created and shared with selected users. The main objective is to restrict access to the rest of the ...

After closing, the position of the qtip2 is being altered

I've successfully integrated the qtip2 with fullcalendar jQuery plugin, which are both amazing tools. However, I'm encountering an issue with the positioning of the qtip. Here's the code snippet I'm using: $(window).load(function() { ...

The imported package in Node.js cannot be located

I'm encountering an issue when trying to deploy my project on the server. Everything runs smoothly on my PC with no import problems. Thank you for your assistance! Error Message: Error [ERR_MODULE_NOT_FOUND]: Module '/home/igor/backend/alina_edu ...

I encountered the following error: Failed to parse due to the module '@babel/preset-react' being missing

Encountering a parsing error: Module '@babel/preset-react' cannot be found. Upon creating schema.js, tweetSchema.js, userSchema.js, issues arose with import, export, and export from all three files showing red lines. schema.js: import createSche ...

Tips for displaying a loading indicator above a form

I've been struggling to figure out how to display a loading indicator on top of my form without messing up the styling... https://i.sstatic.net/FFCRW.png My goal is to show the loading indicator when any action, like deleting an item or changing qua ...

Creating seamless transitions between pages using hyperlinks

On the homepage, there are cards that list various policies with a "details" button above them. Clicking on this button should take me to the specific details page for that policy. However, each product can only have one type assigned to it. For instance: ...

Avoid displaying null values in SELECT and GET operations when using node-postgres

Within my Express API functionality, I aim to offer the client flexibility in providing their contact details, namely phone number or website address, with the option of leaving them blank. The SELECT queries in use are as follows: -- Retrieve all users S ...

Troubleshooting: Why is $watch failing to track changes on factory variables in Angular

I have created a factory named SharedService as shown below: angular.module('Fms').factory('SharedService', function() { var userdetails=false; return userdetails; }) Below controllers utilize this factory: angular.mod ...

jQuery and CSS3 for importing and customizing text files

I successfully customized the file input utilizing jQuery and CSS3. However, there is one aspect I couldn't quite figure out. After the user selects an image or file, I want to display the selected file's text at the very bottom of the text like ...

Utilizing Page Objects to select dropdown list items in JavaScript for Protractor testing

I'm struggling with a particular issue during my testing process. The task requires selecting an item from a list as part of a form to create a new user. However, the test does not select an item from the list even though Protractor does not report an ...

Is it possible to blur all elements of a form except for the submit button?

Can someone help me with a form issue I am facing? <form> <input type="text>' <input type="submit">' </form>'' After submitting the form, I would like to blur the entire form: $(this).closest('form') ...

Preventing access to drives and desktop until the mandatory HTML form is completed

Looking to develop a webpage in JSP that will automatically open whenever my system is started. Users will be required to fill out a form on this page before proceeding further. If they attempt to bypass filling out the form, they should not have access ...

Tips for populating input fields with retrieved data when the fields are generated dynamically

Sharing some context: I've been working on implementing an edit button for a Content Management System, facing a few challenges along the way. I've taken over from another developer who initiated the CMS project, and I'm now tasked with com ...

Exploring the art of div transitions and animations using React and Tailwind CSS

I successfully implemented the sidebar to appear upon clicking the hamburger icon with a transition. However, I am now facing the challenge of triggering the transition when the close button is clicked instead. I have attempted using conditional operations ...

Implement concrete actions on the right-click context menu

I am exploring the functionality of this right-click context menu. Visually, it appears as expected, but I am unsure how to implement actual actions when the menu items are clicked. Currently, it only displays a message like "Back menu item was clicked - t ...

Would you suggest using angularjs for authentication in large-scale applications?

As I continue to learn and utilize the AngularJS framework, I have noticed that while some of its features are impressive, some key aspects make it challenging for authentication-based applications. For example, let's consider a scenario where a webs ...

JavaScript can be used to open several tabs simultaneously within a single browser window

Looking to open multiple tabs in the main browser? Check out this code snippet: function openSM() { window.open("http://www.google.com","_blank"); window.open("http://www.yahoo.com","_blank"); window.open("http://www.bing.c ...

Screening data entries

.js "rpsCommonWord": [ { "addressWeightPct": "60", "charSubstituteWeightPct": "15", "nameWeightPct": "40", "oIdNumber": "21", "shortWordMinLthWeightPct": "100", "substituteWeightPct": "5", ...

Steps to deactivate a JavaScript function once the page has undergone a Page.IsPostBack event

My current setup involves a simple div with the display set to none. Upon page load, I use $("#MyDiv").show(); to display the div after a delay, allowing users to enter information into the form and submit it using an asp.net button. After submitting the ...

Ways to identify the active anchor within an li element

Below is the code snippet I am currently working with: <li> <a href="<?php echo base_url()?>home/promos/call" class="promo-call active-call"></a> </li> <li> <a href="<?php echo base_url()?>home/promos/text ...