Calculating the angle formed by three vectors in three-dimensional space

According to the solution(s) provided in this post Angle between 3 points in 3d space, there is a JavaScipt function that calculates the angles between three vectors in 3D space. The function calculates the angles as if each vector is a vertex on a surface, taking the second argument to calculate the angle between the other two vectors (1 & 3). The function is run three times with different orders of the input vectors to obtain three angles, which works correctly. The input vectors in the program are positions on the surface of a sphere that can be positioned anywhere with latitude and longitude sliders. These vectors are connected by lines (arcs) to create a spherical triangle. However, the function assumes the vectors are coplanar, which is not the case on a sphere. The function always adds up the three angles to 180 degrees, but on a sphere, it should be at least 180 and up to just under 540 degrees. I need the excess angle. It seems that the function needs to consider the z-components of the input vectors as the normal to the sphere's surface, and the x and y components as the tangent plane. Here is the function:

function ang3D2(v1, v2, v3) {
      // Copy and normalize the input vectors
      let V1 = v1.copy().normalize();
      let V2 = v2.copy().normalize();
      let V3 = v3.copy().normalize();
  
      let Va = p5.Vector.sub(V1,V2).normalize();
      let Vb = p5.Vector.sub(V3,V2).normalize();
  
      let dots = p5.Vector.dot(Va,Vb);
  
      let crosses = p5.Vector.cross(Va,Vb);
      let crossesMag = crosses.mag();// / V2.z; ?
  
      let angle = (Math.acos(dots) * 180.0) / Math.PI; 
      //let angle2 = (Math.atan2(crossesMag,dots) * 180.0) / Math.PI;
  
      return Math.round(angle * 1000) / 1000; // here I'm just changing //between returning acos(angle) & atan(angle2) to test. angle2 seems //close its just that the "1st" angle is wrong. acos(angle) is what //works for coplanar

    }//ang3d2()  

    //based off of //https://gist.github.com/andfaulkner/c4ad12a72d29bcd653eb4b8cca2ae476 

    //& its usage:

    function angs() {
      if (cyl1V && cyl2V && cyl3V) {
        //let angs;
        ang1 = ang3D2(cyl2V, cyl1V, cyl3V);
        ang2 = ang3D2(cyl1V, cyl2V, cyl3V);
        ang3 = ang3D2(cyl1V, cyl3V, cyl2V);
        angS = ang1 + ang2 + ang3;
        console.log(angS);
      } //fi
    } //angs  

Although the function works almost as needed, the input vectors are not coplanar in this case. I have been trying to adjust it by using the atan(cross product) instead of just acos(dot) etc. I am not a professional programmer, and I have not found much information on this specific issue. Can someone please guide me in the right direction? Thank you in advance.

Answer №1

After receiving no responses to my initial question posted over a month ago, I dedicated many sleepless nights to finding a solution. Through perseverance, I discovered that utilizing the "triple product" (similar to a cross of cross products) can be extremely beneficial in this scenario. The methodology remains consistent with the one previously mentioned. It's possible that my initial question was not articulated effectively, but I am sharing my solution in the hope that it may assist others in similar situations down the line.

  function find3DAngles(v1, v2, v3) {
  //execute in 3 different sequences with v2 as the central reference
  // Start by copying and normalizing the input vectors, even though static methods will be attempted
  let V1 = v1.copy().normalize();
  let V2 = v2.copy().normalize();
  let V3 = v3.copy().normalize();

  // Deduct 1 from 2 then 3 from 2 to obtain the main vertex vectors of the working triangle
  let Va = p5.Vector.sub(V1, V2).normalize(); //for acos
  let Vb = p5.Vector.sub(V3, V2).normalize(); //not normalized if atan

  // Determine the cross products
  let a = p5.Vector.cross(Va, V2);
  let b = p5.Vector.cross(Vb, V2);

  // Utilize the dot product and magnitudes of a and b
  let dot = p5.Vector.dot(a, b);
  let mag = a.mag() * b.mag();

  let angle = (Math.acos(dot / mag) * 180.0) / Math.PI;

  return Math.round(angle * 1000) / 1000;
} //find3DAngles()

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

Comparison of Fabric JS Filters and CSS Filters

We are currently in the process of transitioning a project from HTML and CSS to Fabric JS. This project allows users to manipulate images by moving them around and applying filters. In our current HTML/CSS implementation, we handle image positioning with C ...

Stop procrastinating and take action before the JavaScript function concludes

Currently, I am experimenting with onkeydown events to capture the input value in a textarea, process it through a PHP file using Ajax post method, and display the result in an external div. However, the issue is that whenever a key is pressed, I am unable ...

Show the image on top of the div block as the AJAX content loads

Implementing this task may seem easy and common, but I am struggling to figure it out! What should take five minutes has turned into an hour of frustration. Please lend me your expertise in getting this done. I have a div container block: <div cla ...

The marriage of Vue 2.0 and Rails 5: Shifting from Reactive to Declarative Rendering

As I make my way through the Vue guide with a Rails 5 app, I've noticed that although I am able to update my Vue js object, the DOM doesn't behave as described in the Declarative Rendering section. The data and the DOM are supposed to be linke ...

Angularjs directive: independent scope and encapsulated elements

Why aren't the contained/child elements rendering when using an isolated scope? I suspect that the parent is not rendered yet. I tried adding a $timeout, but still no luck. If I remove the isolated scope by commenting out scope: {}, it works. How c ...

Using MomentJS along with Timezones to accurately display Datetime while accounting for offsets

I am utilizing moment.js along with timezones to generate a datetime linked to a specific timezone: var datetime = moment.tz("2016-08-16 21:51:28","Europe/London"); Due to the recognition of DST (daylight saving time) by this constructor, moment.js will ...

Loading GLTF model via XHR may take an infinite amount of time to reach full completion

I am attempting to load a GLTF model of a piano using XHR and showcase the loading progress on a webpage. The model is being loaded utilizing the Three.js library. On a local server, everything works perfectly - the loading percentage is shown accurately, ...

getStaticProps will not return any data

I'm experiencing an issue with my getStaticProps where only one of the two db queries is returning correct data while the other returns null. What could be causing this problem? const Dash = (props) => { const config = props.config; useEffect(() ...

The problem with the first item title in the Jquery slider is causing

I've been working on setting up a Jquery slider (caroufredsel) in which I want certain elements to be displayed above the slider itself, outside of the wrapper. Everything is working fine except for the first slide! After spending several days trying ...

Different conversations are taking place concurrently. How can we determine which one is currently being attended to

In my application, multiple dialogs are open simultaneously, each with its own set of shortcuts. It is important to ensure that these shortcuts work correctly based on the focused dialog. Is there a way to determine which dialog is currently in focus? Ed ...

AngularJS enables box to smoothly slide up and down when hovered over

I am attempting to create a div that will overlay an image on hover with a slide up and slide down effect. Can anyone provide guidance on how to achieve this without relying on jQuery? I would prefer to utilize only AngularJS in my application. Here is a ...

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 ...

Referencing an object by using a variable containing its name

I need a way to reference an object using a variable with its name in it. I've figured out how to do this for properties and sub-properties: var req = {body: {jobID: 12}}; console.log(req.body.jobID); //12 var subProperty = "jobID"; cons ...

Discovering hospitals in the vicinity with the help of Google Maps API and JavaScript

var MapApiApplication = { myCurrentPosition : "", mapOptions : "", marker : "", initialize : function(){ MapApiApplication.myCurrentPosition = new google.maps.LatLng(10.112293000000000000, 76.352684500000010000); M ...

Send a request to the uClassify API using the Node request module

I'm currently working on integrating the uClassify API into my Node project, but I'm encountering some issues with my code. Here's what I have so far: const req = JSON.stringify('Hello, my love!'); const options = { body: ...

Handling MySQL insertIds and errors in Node.js using MySQL is a crucial aspect of

I am struggling to handle errors and retrieve the insertId after creating a new row in my database using code from the official page of mysqljs/mysql. How can I modify my code to achieve this? var post = {deviceImei: deviceInformation.deviceImei, created_ ...

Is AjaxMin's EvalTreatment changing the game for JavaScript minification?

While minifying my project using the AjaxMin.dll with the default settings on every build/deployment, I ran into a problem. One of our third-party JavaScript files contains an eval statement that references variables or parameters which, when minified, cau ...

Error message: "Uncaught TypeError in NextJS caused by issues with UseStates and Array

For quite some time now, I've been facing an issue while attempting to map an array in my NextJS project. The particular error that keeps popping up is: ⨯ src\app\delivery\cart\page.tsx (30:9) @ map ⨯ TypeError: Cannot read pr ...

Having trouble deciphering mathematical formulas while editing content on ckeditor

While using math formulas in CKEditor, I noticed that when I insert new content via textarea, the formulas are displayed correctly. However, when I go back to edit the content, the text formulas do not display as before. This is the source code I am using ...

Update a separate React component in response to the interaction with a different React component

Currently, I am working with a react component named Interest Category that showcases an initial set of Interest categories. Another react component called CreateInterestCategoryDialog, which functions as a modal, is responsible for creating a new entity I ...